diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index b1d47ee72..e5ccfebda 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -805,6 +805,10 @@ typedef struct _meshtastic_StoreForwardPlusPlus { /* */ meshtastic_StoreForwardPlusPlus_root_hash_t root_hash; /* encapsulated message to share (may be split in half) */ meshtastic_StoreForwardPlusPlus_message_t message; + uint32_t encapsulated_id; + uint32_t encapsulated_to; + uint32_t encapsulated_from; + uint32_t encapsulated_rxtime; } meshtastic_StoreForwardPlusPlus; /* Waypoint message, used to share arbitrary locations across the mesh */ @@ -1411,7 +1415,7 @@ extern "C" { #define meshtastic_Routing_init_default {0, {meshtastic_RouteDiscovery_init_default}} #define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0} #define meshtastic_KeyVerification_init_default {0, {0, {0}}, {0, {0}}} -#define meshtastic_StoreForwardPlusPlus_init_default {_meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}} +#define meshtastic_StoreForwardPlusPlus_init_default {_meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, 0, 0, 0, 0} #define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0} #define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0} #define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN} @@ -1443,7 +1447,7 @@ extern "C" { #define meshtastic_Routing_init_zero {0, {meshtastic_RouteDiscovery_init_zero}} #define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0} #define meshtastic_KeyVerification_init_zero {0, {0, {0}}, {0, {0}}} -#define meshtastic_StoreForwardPlusPlus_init_zero {_meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}} +#define meshtastic_StoreForwardPlusPlus_init_zero {_meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, 0, 0, 0, 0} #define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0} #define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0} #define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN} @@ -1527,6 +1531,10 @@ extern "C" { #define meshtastic_StoreForwardPlusPlus_chain_hash_tag 3 #define meshtastic_StoreForwardPlusPlus_root_hash_tag 4 #define meshtastic_StoreForwardPlusPlus_message_tag 5 +#define meshtastic_StoreForwardPlusPlus_encapsulated_id_tag 6 +#define meshtastic_StoreForwardPlusPlus_encapsulated_to_tag 7 +#define meshtastic_StoreForwardPlusPlus_encapsulated_from_tag 8 +#define meshtastic_StoreForwardPlusPlus_encapsulated_rxtime_tag 9 #define meshtastic_Waypoint_id_tag 1 #define meshtastic_Waypoint_latitude_i_tag 2 #define meshtastic_Waypoint_longitude_i_tag 3 @@ -1748,7 +1756,11 @@ X(a, STATIC, SINGULAR, UENUM, sfpp_message_type, 1) \ X(a, STATIC, SINGULAR, BYTES, message_hash, 2) \ X(a, STATIC, SINGULAR, BYTES, chain_hash, 3) \ X(a, STATIC, SINGULAR, BYTES, root_hash, 4) \ -X(a, STATIC, SINGULAR, BYTES, message, 5) +X(a, STATIC, SINGULAR, BYTES, message, 5) \ +X(a, STATIC, SINGULAR, UINT32, encapsulated_id, 6) \ +X(a, STATIC, SINGULAR, UINT32, encapsulated_to, 7) \ +X(a, STATIC, SINGULAR, UINT32, encapsulated_from, 8) \ +X(a, STATIC, SINGULAR, UINT32, encapsulated_rxtime, 9) #define meshtastic_StoreForwardPlusPlus_CALLBACK NULL #define meshtastic_StoreForwardPlusPlus_DEFAULT NULL @@ -2118,7 +2130,7 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg; #define meshtastic_QueueStatus_size 23 #define meshtastic_RouteDiscovery_size 256 #define meshtastic_Routing_size 259 -#define meshtastic_StoreForwardPlusPlus_size 347 +#define meshtastic_StoreForwardPlusPlus_size 371 #define meshtastic_ToRadio_size 504 #define meshtastic_User_size 115 #define meshtastic_Waypoint_size 165 diff --git a/src/modules/Native/StoreForwardPlusPlus.cpp b/src/modules/Native/StoreForwardPlusPlus.cpp index 2fa07dacc..72aa3d7ea 100644 --- a/src/modules/Native/StoreForwardPlusPlus.cpp +++ b/src/modules/Native/StoreForwardPlusPlus.cpp @@ -216,7 +216,20 @@ bool StoreForwardPlusPlusModule::handleReceivedProtobuf(const meshtastic_MeshPac // if not found, request the next message } } else if (t->sfpp_message_type == meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_REQUEST) { + uint8_t next_chain_hash[32] = {0}; + LOG_WARN("Received link request"); + getNextHash(t->root_hash.bytes, t->chain_hash.bytes, next_chain_hash); + printBytes("next chain hash: ", next_chain_hash, 32); + + broadcastLink(next_chain_hash, t->root_hash.bytes); + + // if root and chain hashes are the same, grab the first message on the chain + // if different, get the message directly after. + // check if the root + + } else if (t->sfpp_message_type == meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE) { + LOG_WARN("Link Provide received!"); } return true; @@ -358,6 +371,17 @@ bool StoreForwardPlusPlusModule::getRootFromChannelHash(ChannelHash _ch_hash, ui return found; } +ChannelHash StoreForwardPlusPlusModule::getChannelHashFromRoot(uint8_t *_root_hash) +{ + sqlite3_stmt *getHash; + int rc = sqlite3_prepare_v2(ppDb, "select identifier from mappings where root_hash=?;", -1, &getHash, NULL); + sqlite3_bind_blob(getHash, 1, _root_hash, 32, NULL); + sqlite3_step(getHash); + ChannelHash tmp_hash = (ChannelHash)sqlite3_column_int(getHash, 0); + sqlite3_finalize(getHash); + return tmp_hash; +} + // return code indicates newly created chain bool StoreForwardPlusPlusModule::getOrAddRootFromChannelHash(ChannelHash _ch_hash, uint8_t *_root_hash) { @@ -429,6 +453,7 @@ bool StoreForwardPlusPlusModule::getChainEnd(ChannelHash _ch_hash, uint8_t *_cha } memcpy(_chain_hash, last_message_chain_hash, 32); memcpy(_message_hash, last_message_hash, 32); + sqlite3_finalize(getEntry); return true; } @@ -457,6 +482,96 @@ void StoreForwardPlusPlusModule::requestNextMessage(uint8_t *_root_hash, uint8_t service->sendToMesh(p, RX_SRC_LOCAL, true); } +bool StoreForwardPlusPlusModule::getNextHash(uint8_t *_root_hash, uint8_t *_chain_hash, uint8_t *next_chain_hash) +{ + LOG_WARN("getNextHash"); + + ChannelHash _channel_hash = getChannelHashFromRoot(_root_hash); + LOG_WARN("_channel_hash %u", _channel_hash); + + sqlite3_stmt *getHash; + int rc = sqlite3_prepare_v2(ppDb, "select commit_hash from channel_messages where channel_hash=? order by rowid ASC;", -1, + &getHash, NULL); + + LOG_WARN("%d", rc); + if (rc != SQLITE_OK) { + LOG_WARN("here2 %u, %s", rc, sqlite3_errmsg(ppDb)); + } + sqlite3_bind_int(getHash, 1, _channel_hash); + sqlite3_step(getHash); + bool found_hash = false; + + // asking for the first entry on the chain + if (memcmp(_root_hash, _chain_hash, 32) == 0) { + uint8_t *tmp_chain_hash = (uint8_t *)sqlite3_column_blob(getHash, 0); + memcpy(next_chain_hash, tmp_chain_hash, 32); + found_hash = true; + } else { + uint8_t *tmp_chain_hash; + while (sqlite3_step(getHash) != SQLITE_DONE) { + tmp_chain_hash = (uint8_t *)sqlite3_column_blob(getHash, 0); + if (found_hash) { + memcpy(next_chain_hash, tmp_chain_hash, 32); + break; + } + if (memcmp(tmp_chain_hash, _chain_hash, 32) == 0) + found_hash = true; + } + } + + sqlite3_finalize(getHash); + return found_hash; +} + +bool StoreForwardPlusPlusModule::broadcastLink(uint8_t *_chain_hash, uint8_t *_root_hash) +{ + sqlite3_stmt *getHash; + int rc = sqlite3_prepare_v2(ppDb, "select destination, sender, packet_id, encrypted_bytes, message_hash, rx_time \ + from channel_messages where commit_hash=?;", + -1, &getHash, NULL); + + LOG_WARN("%d", rc); + if (rc != SQLITE_OK) { + LOG_WARN("here2 %u, %s", rc, sqlite3_errmsg(ppDb)); + } + sqlite3_bind_blob(getHash, 1, _chain_hash, 32, NULL); + sqlite3_step(getHash); + + meshtastic_StoreForwardPlusPlus storeforward = meshtastic_StoreForwardPlusPlus_init_zero; + storeforward.sfpp_message_type = meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE; + + storeforward.encapsulated_to = sqlite3_column_int(getHash, 0); + storeforward.encapsulated_from = sqlite3_column_int(getHash, 1); + storeforward.encapsulated_id = sqlite3_column_int(getHash, 2); + + uint8_t *_payload = (uint8_t *)sqlite3_column_blob(getHash, 3); + storeforward.message.size = sqlite3_column_bytes(getHash, 3); + memcpy(storeforward.message.bytes, _payload, storeforward.message.size); + + uint8_t *_message_hash = (uint8_t *)sqlite3_column_blob(getHash, 4); + storeforward.message_hash.size = 32; + memcpy(storeforward.message_hash.bytes, _message_hash, storeforward.message_hash.size); + + storeforward.encapsulated_rxtime = sqlite3_column_int(getHash, 5); + + storeforward.chain_hash.size = 32; + memcpy(storeforward.chain_hash.bytes, _chain_hash, 32); + + storeforward.root_hash.size = 32; + memcpy(storeforward.root_hash.bytes, _root_hash, 32); + + sqlite3_finalize(getHash); + + meshtastic_MeshPacket *p = allocDataProtobuf(storeforward); + p->to = NODENUM_BROADCAST; + p->decoded.want_response = false; + p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; + p->channel = 0; + LOG_INFO("Send link to mesh"); + service->sendToMesh(p, RX_SRC_LOCAL, true); + return true; +} + // announce latest hash // chain_end_announce diff --git a/src/modules/Native/StoreForwardPlusPlus.h b/src/modules/Native/StoreForwardPlusPlus.h index 8df28f094..ebdfa875b 100644 --- a/src/modules/Native/StoreForwardPlusPlus.h +++ b/src/modules/Native/StoreForwardPlusPlus.h @@ -49,6 +49,10 @@ class StoreForwardPlusPlusModule : public ProtobufModule