diff --git a/CMakeLists.txt b/CMakeLists.txt index 899a84f..c0ae266 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,8 +18,8 @@ cmake_minimum_required(VERSION 3.1) project(NeoComm) set(TARGET_NAME "neocomm") -set(TARGET_VERSION_MAJOR 0) -set(TARGET_VERSION_MINOR 1) +set(TARGET_VERSION_MAJOR 1) +set(TARGET_VERSION_MINOR 0) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "release") @@ -32,7 +32,7 @@ option(BUILD_SHARED_LIB find_package(GnuTLS REQUIRED) find_package(PkgConfig REQUIRED) -pkg_search_module(OPENDHT REQUIRED opendht) +pkg_check_modules(OPENDHT REQUIRED opendht>=1.4.0) include_directories( "include/" @@ -43,7 +43,8 @@ set(SRCS src/error.cpp src/node.cpp) -set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra -Wpedantic -Werror -Wfatal-errors -pedantic-errors -fno-elide-constructors") +set(CMAKE_CXX_FLAGS + "-std=c++11 -Wall -Wextra -Wpedantic -Werror -Wfatal-errors -pedantic-errors -fno-elide-constructors") set(CMAKE_CXX_FLAGS_DEBUG "-g -O0") set(CMAKE_CXX_FLAGS_RELEASE "-O3") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -O3") diff --git a/include/neocomm.h b/include/neocomm.h index 1eee86a..3564cce 100644 --- a/include/neocomm.h +++ b/include/neocomm.h @@ -26,8 +26,10 @@ #ifdef __cplusplus extern "C" { #include +#include #else #include +#include #endif /** @@ -47,6 +49,15 @@ struct message { struct user from; ///< Info on the peer who sent the message. }; +/** + * @brief Status of a sent message. + */ +enum { + NC_PENDING = 1, ///< Status of message is pending. + NC_GOOD = 2, ///< Message was sent properly. + NC_BAD = 3, ///< Message failed to send. +}; + /** * @brief Initialize a local DHT node. If port is 0 then the default port * number will be used. @@ -119,8 +130,8 @@ void NeoComm_leave_channel(const char *channel_name); * * @return A structure of the message. If NULL then there are no new messages. * - * @notice This command will remove the message from the internal list. - * @notice The message must be freed from memory using NeoComm_free_message. + * @warning This command will remove the message from the internal list. + * @warning The message must be freed from memory using NeoComm_free_message. */ struct message *NeoComm_get_next_message(const char *channel_name); @@ -129,7 +140,9 @@ struct message *NeoComm_get_next_message(const char *channel_name); * * @param msg The message to free from memory. */ -void NeoComm_free_message(struct message *msg); +static inline void NeoComm_free_message(struct message *msg) { + free(msg); +} /** * @brief Send a message to a channel. @@ -137,10 +150,23 @@ void NeoComm_free_message(struct message *msg); * @param channel_name Name of the channel to send the message to. * @param message A message to send to the channel. * - * @return 1 upon success, 0 upon failure. Use NeoComm_get_last_error for a - * text description of the error. + * @return Upon success it returns the time that the message was sent which + * can be used as a token to see if the message was sent properly using + * NeoComm_check_message, if the function failed then 0 will be returned. */ -int NeoComm_send_message(const char *channel_name, const char *message); +time_t NeoComm_send_message(const char *channel_name, const char *message); + +/** + * @brief Check the status of a sent message. + * + * @param token The token of a message to check its status. + * + * @return The status of the message (NC_GOOD, NC_BAD, or NC_PENDING). If the + * token does not exist then 0 is returned. + * + * @warning Once checked the token becomes invalid. + */ +int NeoComm_check_message(const time_t token); /** * @brief Get the last error that occurred in text. diff --git a/src/channel.cpp b/src/channel.cpp index da7bfea..bd67dad 100644 --- a/src/channel.cpp +++ b/src/channel.cpp @@ -23,9 +23,11 @@ std::map channels; -static std::mt19937_64 rand_dev {dht::crypto::random_device{}()}; +static std::mt19937_64 rand_dev { dht::crypto::random_device{}() }; static std::uniform_int_distribution rand_id; +static std::map sent_messages; + int NeoComm_join_channel(const char *channel_name) { if(not node.isRunning()) { @@ -54,7 +56,7 @@ int NeoComm_join_channel(const char *channel_name) { channels[s_chan_name] = { /*.hash =*/ chan_hash, /*.token =*/ node.listen(chan_hash, - [=](dht::ImMessage &&msg) { + [&](dht::ImMessage &&msg) { channels[s_chan_name].msgs.push_back(msg); return true; }), @@ -88,28 +90,46 @@ struct message *NeoComm_get_next_message(const char *channel_name) { *msg = { /*.msg =*/ new_msg->msg.c_str(), /*.sent =*/ new_msg->date, - // TODO: add the rest of these + /*.from =*/ { + /*.nick =*/ "DEFAULT", // TODO: Implement this!!! + /*.hash =*/ new_msg->from.to_c_str() + } }; return msg; } -void NeoComm_free_message(struct message *msg) { - free(msg); -} - -int NeoComm_send_message(const char *channel_name, const char *message) { +time_t NeoComm_send_message(const char *channel_name, const char *message) { + if(not node.isRunning()) + { + add_error("NeoComm must be initialized."); + return 0; + } const dht::InfoHash chan_hash = channels[channel_name].hash; - const time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + const time_t now = + std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); if(channels.find(channel_name) == channels.end()) { add_error("Not connected to channel"); return 0; } - node.putSigned(chan_hash, dht::ImMessage(rand_id(rand_dev), message, now), [](bool sent) { - // TODO: Figure out what to do here for failed messages. - }); - - return 1; + sent_messages[now] = NC_PENDING; + node.putSigned(chan_hash, + dht::ImMessage(rand_id(rand_dev), message, now), [&](bool sent) { + sent_messages[now] = sent ? NC_GOOD : NC_BAD; + }); + return now; +} + +// TODO: Devise a way so that the message can be resent. +int NeoComm_check_message(const time_t token) { + if(sent_messages.find(token) == sent_messages.end()) + { + add_error("No message found with that token."); + return 0; + } + const int status = sent_messages[token]; + sent_messages.erase(token); + return status; } diff --git a/src/node.cpp b/src/node.cpp index 9149cf5..7ae15e6 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -65,9 +65,7 @@ int NeoComm_connect(const char *address, const unsigned short port) { return 1; } -// NOTICE: When the new OpenDHT release comes out this code should work. -// Meanwhile just keep it commented out. -/*int NeoComm_import_nodes(const char *node_file) { +int NeoComm_import_nodes(const char *node_file) { if(not node.isRunning()) { add_error("NeoComm must be initialized."); @@ -97,12 +95,13 @@ int NeoComm_connect(const char *address, const unsigned short port) { node.bootstrap(imported_nodes); } return 1; -}*/ +} -/*int NeoComm_export_nodes(const char *node_file) { +int NeoComm_export_nodes(const char *node_file) { if(not node.isRunning()) { add_error("NeoComm must be initialized."); + return 0; } std::ofstream export_file(node_file, std::ios::binary); if(not export_file.is_open()) @@ -111,4 +110,5 @@ int NeoComm_connect(const char *address, const unsigned short port) { return 0; } msgpack::pack(export_file, node.exportNodes()); -}*/ + return 1; +}