diff --git a/include/neocomm.h b/include/neocomm.h index f47135d..f2f19fd 100644 --- a/include/neocomm.h +++ b/include/neocomm.h @@ -47,6 +47,15 @@ struct message { struct user from; ///< Info on the peer who sent the message. }; +/** + * @brief Status of a 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. @@ -137,10 +146,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 55c0310..fa46d07 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; }), @@ -98,7 +100,12 @@ 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()); @@ -108,10 +115,21 @@ int NeoComm_send_message(const char *channel_name, const char *message) { add_error("Not connected to channel"); return 0; } + sent_messages[now] = NC_PENDING; node.putSigned(chan_hash, - dht::ImMessage(rand_id(rand_dev), message, now), [](bool sent) { - // TODO: Figure out what to do here for failed messages. + dht::ImMessage(rand_id(rand_dev), message, now), [&](bool sent) { + sent_messages[now] = sent ? NC_GOOD : NC_BAD; }); - - return 1; + return now; +} + +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; }