Mesh.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. #include "Mesh.h"
  2. //#include <Arduino.h>
  3. namespace mesh {
  4. void Mesh::begin() {
  5. Dispatcher::begin();
  6. }
  7. void Mesh::loop() {
  8. Dispatcher::loop();
  9. }
  10. bool Mesh::allowPacketForward(const mesh::Packet* packet) {
  11. return false; // by default, Transport NOT enabled
  12. }
  13. uint32_t Mesh::getRetransmitDelay(const mesh::Packet* packet) {
  14. uint32_t t = (_radio->getEstAirtimeFor(packet->getRawLength()) * 52 / 50) / 2;
  15. return _rng->nextInt(0, 5)*t;
  16. }
  17. uint32_t Mesh::getDirectRetransmitDelay(const Packet* packet) {
  18. return 0; // by default, no delay
  19. }
  20. uint8_t Mesh::getExtraAckTransmitCount() const {
  21. return 0;
  22. }
  23. uint32_t Mesh::getCADFailRetryDelay() const {
  24. return _rng->nextInt(1, 4)*120;
  25. }
  26. int Mesh::searchPeersByHash(const uint8_t* hash) {
  27. return 0; // not found
  28. }
  29. int Mesh::searchChannelsByHash(const uint8_t* hash, GroupChannel channels[], int max_matches) {
  30. return 0; // not found
  31. }
  32. DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
  33. if (pkt->isRouteDirect() && pkt->getPayloadType() == PAYLOAD_TYPE_TRACE) {
  34. if (pkt->path_len < MAX_PATH_SIZE) {
  35. uint8_t i = 0;
  36. uint32_t trace_tag;
  37. memcpy(&trace_tag, &pkt->payload[i], 4); i += 4;
  38. uint32_t auth_code;
  39. memcpy(&auth_code, &pkt->payload[i], 4); i += 4;
  40. uint8_t flags = pkt->payload[i++];
  41. uint8_t path_sz = flags & 0x03; // NEW v1.11+: lower 2 bits is path hash size
  42. uint8_t len = pkt->payload_len - i;
  43. // path_len*entry_size can exceed 255 (path_len up to 63, entry_size up to 8);
  44. // a uint8_t offset would wrap and steer the isHashMatch() read to the wrong place.
  45. uint16_t offset = (uint16_t)pkt->path_len << path_sz;
  46. if (offset >= len) { // TRACE has reached end of given path
  47. onTraceRecv(pkt, trace_tag, auth_code, flags, pkt->path, &pkt->payload[i], len);
  48. } else if (self_id.isHashMatch(&pkt->payload[i + offset], 1 << path_sz) && allowPacketForward(pkt) && !_tables->hasSeen(pkt)) {
  49. // append SNR (Not hash!)
  50. pkt->path[pkt->path_len++] = (int8_t) (pkt->getSNR()*4);
  51. uint32_t d = getDirectRetransmitDelay(pkt);
  52. return ACTION_RETRANSMIT_DELAYED(5, d); // schedule with priority 5 (for now), maybe make configurable?
  53. }
  54. }
  55. return ACTION_RELEASE;
  56. }
  57. if (pkt->isRouteDirect() && pkt->getPayloadType() == PAYLOAD_TYPE_CONTROL && (pkt->payload[0] & 0x80) != 0) {
  58. if (pkt->getPathHashCount() == 0) {
  59. onControlDataRecv(pkt);
  60. }
  61. // just zero-hop control packets allowed (for this subset of payloads)
  62. return ACTION_RELEASE;
  63. }
  64. if (pkt->isRouteDirect() && pkt->getPathHashCount() > 0) {
  65. // check for 'early received' ACK
  66. if (pkt->getPayloadType() == PAYLOAD_TYPE_ACK) {
  67. int i = 0;
  68. uint32_t ack_crc;
  69. memcpy(&ack_crc, &pkt->payload[i], 4); i += 4;
  70. if (i <= pkt->payload_len) {
  71. onAckRecv(pkt, ack_crc);
  72. }
  73. }
  74. if (self_id.isHashMatch(pkt->path, pkt->getPathHashSize()) && allowPacketForward(pkt)) {
  75. if (pkt->getPayloadType() == PAYLOAD_TYPE_MULTIPART) {
  76. return forwardMultipartDirect(pkt);
  77. } else if (pkt->getPayloadType() == PAYLOAD_TYPE_ACK) {
  78. if (!_tables->hasSeen(pkt)) { // don't retransmit!
  79. removeSelfFromPath(pkt);
  80. routeDirectRecvAcks(pkt, 0);
  81. }
  82. return ACTION_RELEASE;
  83. }
  84. if (!_tables->hasSeen(pkt)) {
  85. removeSelfFromPath(pkt);
  86. uint32_t d = getDirectRetransmitDelay(pkt);
  87. return ACTION_RETRANSMIT_DELAYED(0, d); // Routed traffic is HIGHEST priority
  88. }
  89. }
  90. return ACTION_RELEASE; // this node is NOT the next hop (OR this packet has already been forwarded), so discard.
  91. }
  92. if (pkt->isRouteFlood() && filterRecvFloodPacket(pkt)) return ACTION_RELEASE;
  93. DispatcherAction action = ACTION_RELEASE;
  94. switch (pkt->getPayloadType()) {
  95. case PAYLOAD_TYPE_ACK: {
  96. int i = 0;
  97. uint32_t ack_crc;
  98. memcpy(&ack_crc, &pkt->payload[i], 4); i += 4;
  99. if (i > pkt->payload_len) {
  100. MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): incomplete ACK packet", getLogDateTime());
  101. } else if (!_tables->hasSeen(pkt)) {
  102. onAckRecv(pkt, ack_crc);
  103. action = routeRecvPacket(pkt);
  104. }
  105. break;
  106. }
  107. case PAYLOAD_TYPE_PATH:
  108. case PAYLOAD_TYPE_REQ:
  109. case PAYLOAD_TYPE_RESPONSE:
  110. case PAYLOAD_TYPE_TXT_MSG: {
  111. int i = 0;
  112. uint8_t dest_hash = pkt->payload[i++];
  113. uint8_t src_hash = pkt->payload[i++];
  114. uint8_t* macAndData = &pkt->payload[i]; // MAC + encrypted data
  115. if (i + CIPHER_MAC_SIZE >= pkt->payload_len) {
  116. MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): incomplete data packet", getLogDateTime());
  117. } else if (!_tables->hasSeen(pkt)) {
  118. // NOTE: this is a 'first packet wins' impl. When receiving from multiple paths, the first to arrive wins.
  119. // For flood mode, the path may not be the 'best' in terms of hops.
  120. // FUTURE: could send back multiple paths, using createPathReturn(), and let sender choose which to use(?)
  121. if (self_id.isHashMatch(&dest_hash)) {
  122. // scan contacts DB, for all matching hashes of 'src_hash' (max 4 matches supported ATM)
  123. int num = searchPeersByHash(&src_hash);
  124. // for each matching contact, try to decrypt data
  125. bool found = false;
  126. for (int j = 0; j < num; j++) {
  127. uint8_t secret[PUB_KEY_SIZE];
  128. getPeerSharedSecret(secret, j);
  129. // decrypt, checking MAC is valid
  130. uint8_t data[MAX_PACKET_PAYLOAD];
  131. int len = Utils::MACThenDecrypt(secret, data, macAndData, pkt->payload_len - i);
  132. if (len > 0) { // success!
  133. if (pkt->getPayloadType() == PAYLOAD_TYPE_PATH) {
  134. int k = 0;
  135. uint8_t path_len = data[k++];
  136. uint8_t hash_size = (path_len >> 6) + 1;
  137. uint8_t hash_count = path_len & 63;
  138. uint8_t* path = &data[k]; k += hash_size*hash_count;
  139. uint8_t extra_type = data[k++] & 0x0F; // upper 4 bits reserved for future use
  140. uint8_t* extra = &data[k];
  141. uint8_t extra_len = len - k; // remainder of packet (may be padded with zeroes!)
  142. if (onPeerPathRecv(pkt, j, secret, path, path_len, extra_type, extra, extra_len)) {
  143. if (pkt->isRouteFlood()) {
  144. // send a reciprocal return path to sender, but send DIRECTLY!
  145. mesh::Packet* rpath = createPathReturn(&src_hash, secret, pkt->path, pkt->path_len, 0, NULL, 0);
  146. if (rpath) sendDirect(rpath, path, path_len, 500);
  147. }
  148. }
  149. } else {
  150. onPeerDataRecv(pkt, pkt->getPayloadType(), j, secret, data, len);
  151. }
  152. found = true;
  153. break;
  154. }
  155. }
  156. if (found) {
  157. pkt->markDoNotRetransmit(); // packet was for this node, so don't retransmit
  158. } else {
  159. MESH_DEBUG_PRINTLN("%s recv matches no peers, src_hash=%02X", getLogDateTime(), (uint32_t)src_hash);
  160. }
  161. }
  162. action = routeRecvPacket(pkt);
  163. }
  164. break;
  165. }
  166. case PAYLOAD_TYPE_ANON_REQ: {
  167. int i = 0;
  168. uint8_t dest_hash = pkt->payload[i++];
  169. uint8_t* sender_pub_key = &pkt->payload[i]; i += PUB_KEY_SIZE;
  170. uint8_t* macAndData = &pkt->payload[i]; // MAC + encrypted data
  171. if (i + 2 >= pkt->payload_len) {
  172. MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): incomplete data packet", getLogDateTime());
  173. } else if (!_tables->hasSeen(pkt)) {
  174. if (self_id.isHashMatch(&dest_hash)) {
  175. Identity sender(sender_pub_key);
  176. uint8_t secret[PUB_KEY_SIZE];
  177. self_id.calcSharedSecret(secret, sender);
  178. // decrypt, checking MAC is valid
  179. uint8_t data[MAX_PACKET_PAYLOAD];
  180. int len = Utils::MACThenDecrypt(secret, data, macAndData, pkt->payload_len - i);
  181. if (len > 0) { // success!
  182. onAnonDataRecv(pkt, secret, sender, data, len);
  183. pkt->markDoNotRetransmit();
  184. }
  185. }
  186. action = routeRecvPacket(pkt);
  187. }
  188. break;
  189. }
  190. case PAYLOAD_TYPE_GRP_DATA:
  191. case PAYLOAD_TYPE_GRP_TXT: {
  192. int i = 0;
  193. uint8_t channel_hash = pkt->payload[i++];
  194. uint8_t* macAndData = &pkt->payload[i]; // MAC + encrypted data
  195. if (i + 2 >= pkt->payload_len) {
  196. MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): incomplete data packet", getLogDateTime());
  197. } else if (!_tables->hasSeen(pkt)) {
  198. // scan channels DB, for all matching hashes of 'channel_hash' (max 4 matches supported ATM)
  199. GroupChannel channels[4];
  200. int num = searchChannelsByHash(&channel_hash, channels, 4);
  201. // for each matching channel, try to decrypt data
  202. for (int j = 0; j < num; j++) {
  203. // decrypt, checking MAC is valid
  204. uint8_t data[MAX_PACKET_PAYLOAD];
  205. int len = Utils::MACThenDecrypt(channels[j].secret, data, macAndData, pkt->payload_len - i);
  206. if (len > 0) { // success!
  207. onGroupDataRecv(pkt, pkt->getPayloadType(), channels[j], data, len);
  208. break;
  209. }
  210. }
  211. action = routeRecvPacket(pkt);
  212. }
  213. break;
  214. }
  215. case PAYLOAD_TYPE_ADVERT: {
  216. int i = 0;
  217. Identity id;
  218. memcpy(id.pub_key, &pkt->payload[i], PUB_KEY_SIZE); i += PUB_KEY_SIZE;
  219. uint32_t timestamp;
  220. memcpy(&timestamp, &pkt->payload[i], 4); i += 4;
  221. const uint8_t* signature = &pkt->payload[i]; i += SIGNATURE_SIZE;
  222. if (i > pkt->payload_len) {
  223. MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): incomplete advertisement packet", getLogDateTime());
  224. } else if (self_id.matches(id.pub_key)) {
  225. MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): receiving SELF advert packet", getLogDateTime());
  226. } else if (!_tables->hasSeen(pkt)) {
  227. uint8_t* app_data = &pkt->payload[i];
  228. int app_data_len = pkt->payload_len - i;
  229. if (app_data_len > MAX_ADVERT_DATA_SIZE) { app_data_len = MAX_ADVERT_DATA_SIZE; }
  230. // check that signature is valid
  231. bool is_ok;
  232. {
  233. uint8_t message[PUB_KEY_SIZE + 4 + MAX_ADVERT_DATA_SIZE];
  234. int msg_len = 0;
  235. memcpy(&message[msg_len], id.pub_key, PUB_KEY_SIZE); msg_len += PUB_KEY_SIZE;
  236. memcpy(&message[msg_len], &timestamp, 4); msg_len += 4;
  237. memcpy(&message[msg_len], app_data, app_data_len); msg_len += app_data_len;
  238. is_ok = id.verify(signature, message, msg_len);
  239. }
  240. if (is_ok) {
  241. MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): valid advertisement received!", getLogDateTime());
  242. onAdvertRecv(pkt, id, timestamp, app_data, app_data_len);
  243. action = routeRecvPacket(pkt);
  244. } else {
  245. MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): received advertisement with forged signature! (app_data_len=%d)", getLogDateTime(), app_data_len);
  246. }
  247. }
  248. break;
  249. }
  250. case PAYLOAD_TYPE_RAW_CUSTOM: {
  251. if (pkt->isRouteDirect() && !_tables->hasSeen(pkt)) {
  252. onRawDataRecv(pkt);
  253. //action = routeRecvPacket(pkt); don't flood route these (yet)
  254. }
  255. break;
  256. }
  257. case PAYLOAD_TYPE_MULTIPART:
  258. if (pkt->payload_len > 2) {
  259. uint8_t remaining = pkt->payload[0] >> 4; // num of packets in this multipart sequence still to be sent
  260. uint8_t type = pkt->payload[0] & 0x0F;
  261. if (type == PAYLOAD_TYPE_ACK && pkt->payload_len >= 5) { // a multipart ACK
  262. Packet tmp;
  263. tmp.header = pkt->header;
  264. tmp.path_len = Packet::copyPath(tmp.path, pkt->path, pkt->path_len);
  265. tmp.payload_len = pkt->payload_len - 1;
  266. memcpy(tmp.payload, &pkt->payload[1], tmp.payload_len);
  267. if (!_tables->hasSeen(&tmp)) {
  268. uint32_t ack_crc;
  269. memcpy(&ack_crc, tmp.payload, 4);
  270. onAckRecv(&tmp, ack_crc);
  271. //action = routeRecvPacket(&tmp); // NOTE: currently not needed, as multipart ACKs not sent Flood
  272. }
  273. } else {
  274. // FUTURE: other multipart types??
  275. }
  276. }
  277. break;
  278. default:
  279. MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): unknown payload type, header: %d", getLogDateTime(), (int) pkt->header);
  280. // Don't flood route unknown packet types! action = routeRecvPacket(pkt);
  281. break;
  282. }
  283. return action;
  284. }
  285. void Mesh::removeSelfFromPath(Packet* pkt) {
  286. // remove our hash from 'path'
  287. pkt->setPathHashCount(pkt->getPathHashCount() - 1); // decrement the count
  288. uint8_t sz = pkt->getPathHashSize();
  289. for (int k = 0; k < pkt->getPathHashCount()*sz; k += sz) { // shuffle path by 1 'entry'
  290. memcpy(&pkt->path[k], &pkt->path[k + sz], sz);
  291. }
  292. }
  293. DispatcherAction Mesh::routeRecvPacket(Packet* packet) {
  294. uint8_t n = packet->getPathHashCount();
  295. if (packet->isRouteFlood() && !packet->isMarkedDoNotRetransmit()
  296. && (n + 1)*packet->getPathHashSize() <= MAX_PATH_SIZE && allowPacketForward(packet)) {
  297. // append this node's hash to 'path'
  298. self_id.copyHashTo(&packet->path[n * packet->getPathHashSize()], packet->getPathHashSize());
  299. packet->setPathHashCount(n + 1);
  300. uint32_t d = getRetransmitDelay(packet);
  301. // as this propagates outwards, give it lower and lower priority
  302. return ACTION_RETRANSMIT_DELAYED(packet->getPathHashCount(), d); // give priority to closer sources, than ones further away
  303. }
  304. return ACTION_RELEASE;
  305. }
  306. DispatcherAction Mesh::forwardMultipartDirect(Packet* pkt) {
  307. uint8_t remaining = pkt->payload[0] >> 4; // num of packets in this multipart sequence still to be sent
  308. uint8_t type = pkt->payload[0] & 0x0F;
  309. if (type == PAYLOAD_TYPE_ACK && pkt->payload_len >= 5) { // a multipart ACK
  310. Packet tmp;
  311. tmp.header = pkt->header;
  312. tmp.path_len = Packet::copyPath(tmp.path, pkt->path, pkt->path_len);
  313. tmp.payload_len = pkt->payload_len - 1;
  314. memcpy(tmp.payload, &pkt->payload[1], tmp.payload_len);
  315. if (!_tables->hasSeen(&tmp)) { // don't retransmit!
  316. removeSelfFromPath(&tmp);
  317. routeDirectRecvAcks(&tmp, ((uint32_t)remaining + 1) * 300); // expect multipart ACKs 300ms apart (x2)
  318. }
  319. }
  320. return ACTION_RELEASE;
  321. }
  322. void Mesh::routeDirectRecvAcks(Packet* packet, uint32_t delay_millis) {
  323. if (!packet->isMarkedDoNotRetransmit()) {
  324. uint32_t crc;
  325. memcpy(&crc, packet->payload, 4);
  326. uint8_t extra = getExtraAckTransmitCount();
  327. while (extra > 0) {
  328. delay_millis += getDirectRetransmitDelay(packet) + 300;
  329. auto a1 = createMultiAck(crc, extra);
  330. if (a1) {
  331. a1->path_len = Packet::copyPath(a1->path, packet->path, packet->path_len);
  332. a1->header &= ~PH_ROUTE_MASK;
  333. a1->header |= ROUTE_TYPE_DIRECT;
  334. sendPacket(a1, 0, delay_millis);
  335. }
  336. extra--;
  337. }
  338. auto a2 = createAck(crc);
  339. if (a2) {
  340. a2->path_len = Packet::copyPath(a2->path, packet->path, packet->path_len);
  341. a2->header &= ~PH_ROUTE_MASK;
  342. a2->header |= ROUTE_TYPE_DIRECT;
  343. sendPacket(a2, 0, delay_millis);
  344. }
  345. }
  346. }
  347. Packet* Mesh::createAdvert(const LocalIdentity& id, const uint8_t* app_data, size_t app_data_len) {
  348. if (app_data_len > MAX_ADVERT_DATA_SIZE) return NULL;
  349. Packet* packet = obtainNewPacket();
  350. if (packet == NULL) {
  351. MESH_DEBUG_PRINTLN("%s Mesh::createAdvert(): error, packet pool empty", getLogDateTime());
  352. return NULL;
  353. }
  354. packet->header = (PAYLOAD_TYPE_ADVERT << PH_TYPE_SHIFT); // ROUTE_TYPE_* is set later
  355. int len = 0;
  356. memcpy(&packet->payload[len], id.pub_key, PUB_KEY_SIZE); len += PUB_KEY_SIZE;
  357. uint32_t emitted_timestamp = _rtc->getCurrentTime();
  358. memcpy(&packet->payload[len], &emitted_timestamp, 4); len += 4;
  359. uint8_t* signature = &packet->payload[len]; len += SIGNATURE_SIZE; // will fill this in later
  360. memcpy(&packet->payload[len], app_data, app_data_len); len += app_data_len;
  361. packet->payload_len = len;
  362. {
  363. uint8_t message[PUB_KEY_SIZE + 4 + MAX_ADVERT_DATA_SIZE];
  364. int msg_len = 0;
  365. memcpy(&message[msg_len], id.pub_key, PUB_KEY_SIZE); msg_len += PUB_KEY_SIZE;
  366. memcpy(&message[msg_len], &emitted_timestamp, 4); msg_len += 4;
  367. memcpy(&message[msg_len], app_data, app_data_len); msg_len += app_data_len;
  368. id.sign(signature, message, msg_len);
  369. }
  370. return packet;
  371. }
  372. #define MAX_COMBINED_PATH (MAX_PACKET_PAYLOAD - 2 - CIPHER_BLOCK_SIZE)
  373. Packet* Mesh::createPathReturn(const Identity& dest, const uint8_t* secret, const uint8_t* path, uint8_t path_len, uint8_t extra_type, const uint8_t*extra, size_t extra_len) {
  374. uint8_t dest_hash[PATH_HASH_SIZE];
  375. dest.copyHashTo(dest_hash);
  376. return createPathReturn(dest_hash, secret, path, path_len, extra_type, extra, extra_len);
  377. }
  378. Packet* Mesh::createPathReturn(const uint8_t* dest_hash, const uint8_t* secret, const uint8_t* path, uint8_t path_len, uint8_t extra_type, const uint8_t*extra, size_t extra_len) {
  379. uint8_t path_hash_size = (path_len >> 6) + 1;
  380. uint8_t path_hash_count = path_len & 63;
  381. if (path_hash_count*path_hash_size + extra_len + 5 > MAX_COMBINED_PATH) return NULL; // too long!!
  382. Packet* packet = obtainNewPacket();
  383. if (packet == NULL) {
  384. MESH_DEBUG_PRINTLN("%s Mesh::createPathReturn(): error, packet pool empty", getLogDateTime());
  385. return NULL;
  386. }
  387. packet->header = (PAYLOAD_TYPE_PATH << PH_TYPE_SHIFT); // ROUTE_TYPE_* set later
  388. int len = 0;
  389. memcpy(&packet->payload[len], dest_hash, PATH_HASH_SIZE); len += PATH_HASH_SIZE; // dest hash
  390. len += self_id.copyHashTo(&packet->payload[len]); // src hash
  391. {
  392. int data_len = 0;
  393. uint8_t data[MAX_PACKET_PAYLOAD];
  394. data[data_len++] = path_len;
  395. memcpy(&data[data_len], path, path_hash_count*path_hash_size); data_len += path_hash_count*path_hash_size;
  396. if (extra_len > 0) {
  397. data[data_len++] = extra_type;
  398. memcpy(&data[data_len], extra, extra_len); data_len += extra_len;
  399. } else {
  400. // append a timestamp, or random blob (to make packet_hash unique)
  401. data[data_len++] = 0xFF; // dummy payload type
  402. getRNG()->random(&data[data_len], 4); data_len += 4;
  403. }
  404. len += Utils::encryptThenMAC(secret, &packet->payload[len], data, data_len);
  405. }
  406. packet->payload_len = len;
  407. return packet;
  408. }
  409. Packet* Mesh::createDatagram(uint8_t type, const Identity& dest, const uint8_t* secret, const uint8_t* data, size_t data_len) {
  410. if (type == PAYLOAD_TYPE_TXT_MSG || type == PAYLOAD_TYPE_REQ || type == PAYLOAD_TYPE_RESPONSE) {
  411. if (data_len + CIPHER_MAC_SIZE + CIPHER_BLOCK_SIZE-1 > MAX_PACKET_PAYLOAD) return NULL;
  412. } else {
  413. return NULL; // invalid type
  414. }
  415. Packet* packet = obtainNewPacket();
  416. if (packet == NULL) {
  417. MESH_DEBUG_PRINTLN("%s Mesh::createDatagram(): error, packet pool empty", getLogDateTime());
  418. return NULL;
  419. }
  420. packet->header = (type << PH_TYPE_SHIFT); // ROUTE_TYPE_* set later
  421. int len = 0;
  422. len += dest.copyHashTo(&packet->payload[len]); // dest hash
  423. len += self_id.copyHashTo(&packet->payload[len]); // src hash
  424. len += Utils::encryptThenMAC(secret, &packet->payload[len], data, data_len);
  425. packet->payload_len = len;
  426. return packet;
  427. }
  428. Packet* Mesh::createAnonDatagram(uint8_t type, const LocalIdentity& sender, const Identity& dest, const uint8_t* secret, const uint8_t* data, size_t data_len) {
  429. if (type == PAYLOAD_TYPE_ANON_REQ) {
  430. if (data_len + 1 + PUB_KEY_SIZE + CIPHER_BLOCK_SIZE-1 > MAX_PACKET_PAYLOAD) return NULL;
  431. } else {
  432. return NULL; // invalid type
  433. }
  434. Packet* packet = obtainNewPacket();
  435. if (packet == NULL) {
  436. MESH_DEBUG_PRINTLN("%s Mesh::createAnonDatagram(): error, packet pool empty", getLogDateTime());
  437. return NULL;
  438. }
  439. packet->header = (type << PH_TYPE_SHIFT); // ROUTE_TYPE_* set later
  440. int len = 0;
  441. if (type == PAYLOAD_TYPE_ANON_REQ) {
  442. len += dest.copyHashTo(&packet->payload[len]); // dest hash
  443. memcpy(&packet->payload[len], sender.pub_key, PUB_KEY_SIZE); len += PUB_KEY_SIZE; // sender pub_key
  444. } else {
  445. // FUTURE:
  446. }
  447. len += Utils::encryptThenMAC(secret, &packet->payload[len], data, data_len);
  448. packet->payload_len = len;
  449. return packet;
  450. }
  451. Packet* Mesh::createGroupDatagram(uint8_t type, const GroupChannel& channel, const uint8_t* data, size_t data_len) {
  452. if (!(type == PAYLOAD_TYPE_GRP_TXT || type == PAYLOAD_TYPE_GRP_DATA)) return NULL; // invalid type
  453. if (data_len + 1 + CIPHER_BLOCK_SIZE-1 > MAX_PACKET_PAYLOAD) return NULL; // too long
  454. Packet* packet = obtainNewPacket();
  455. if (packet == NULL) {
  456. MESH_DEBUG_PRINTLN("%s Mesh::createGroupDatagram(): error, packet pool empty", getLogDateTime());
  457. return NULL;
  458. }
  459. packet->header = (type << PH_TYPE_SHIFT); // ROUTE_TYPE_* set later
  460. int len = 0;
  461. memcpy(&packet->payload[len], channel.hash, PATH_HASH_SIZE); len += PATH_HASH_SIZE;
  462. len += Utils::encryptThenMAC(channel.secret, &packet->payload[len], data, data_len);
  463. packet->payload_len = len;
  464. return packet;
  465. }
  466. Packet* Mesh::createAck(uint32_t ack_crc) {
  467. Packet* packet = obtainNewPacket();
  468. if (packet == NULL) {
  469. MESH_DEBUG_PRINTLN("%s Mesh::createAck(): error, packet pool empty", getLogDateTime());
  470. return NULL;
  471. }
  472. packet->header = (PAYLOAD_TYPE_ACK << PH_TYPE_SHIFT); // ROUTE_TYPE_* set later
  473. memcpy(packet->payload, &ack_crc, 4);
  474. packet->payload_len = 4;
  475. return packet;
  476. }
  477. Packet* Mesh::createMultiAck(uint32_t ack_crc, uint8_t remaining) {
  478. Packet* packet = obtainNewPacket();
  479. if (packet == NULL) {
  480. MESH_DEBUG_PRINTLN("%s Mesh::createMultiAck(): error, packet pool empty", getLogDateTime());
  481. return NULL;
  482. }
  483. packet->header = (PAYLOAD_TYPE_MULTIPART << PH_TYPE_SHIFT); // ROUTE_TYPE_* set later
  484. packet->payload[0] = (remaining << 4) | PAYLOAD_TYPE_ACK;
  485. memcpy(&packet->payload[1], &ack_crc, 4);
  486. packet->payload_len = 5;
  487. return packet;
  488. }
  489. Packet* Mesh::createRawData(const uint8_t* data, size_t len) {
  490. if (len > sizeof(Packet::payload)) return NULL; // invalid arg
  491. Packet* packet = obtainNewPacket();
  492. if (packet == NULL) {
  493. MESH_DEBUG_PRINTLN("%s Mesh::createRawData(): error, packet pool empty", getLogDateTime());
  494. return NULL;
  495. }
  496. packet->header = (PAYLOAD_TYPE_RAW_CUSTOM << PH_TYPE_SHIFT); // ROUTE_TYPE_* set later
  497. memcpy(packet->payload, data, len);
  498. packet->payload_len = len;
  499. return packet;
  500. }
  501. Packet* Mesh::createTrace(uint32_t tag, uint32_t auth_code, uint8_t flags) {
  502. Packet* packet = obtainNewPacket();
  503. if (packet == NULL) {
  504. MESH_DEBUG_PRINTLN("%s Mesh::createTrace(): error, packet pool empty", getLogDateTime());
  505. return NULL;
  506. }
  507. packet->header = (PAYLOAD_TYPE_TRACE << PH_TYPE_SHIFT); // ROUTE_TYPE_* set later
  508. memcpy(packet->payload, &tag, 4);
  509. memcpy(&packet->payload[4], &auth_code, 4);
  510. packet->payload[8] = flags;
  511. packet->payload_len = 9; // NOTE: path will be appended to payload[] later
  512. return packet;
  513. }
  514. Packet* Mesh::createControlData(const uint8_t* data, size_t len) {
  515. if (len > sizeof(Packet::payload)) return NULL; // invalid arg
  516. Packet* packet = obtainNewPacket();
  517. if (packet == NULL) {
  518. MESH_DEBUG_PRINTLN("%s Mesh::createControlData(): error, packet pool empty", getLogDateTime());
  519. return NULL;
  520. }
  521. packet->header = (PAYLOAD_TYPE_CONTROL << PH_TYPE_SHIFT); // ROUTE_TYPE_* set later
  522. memcpy(packet->payload, data, len);
  523. packet->payload_len = len;
  524. return packet;
  525. }
  526. void Mesh::sendFlood(Packet* packet, uint32_t delay_millis, uint8_t path_hash_size) {
  527. if (packet->getPayloadType() == PAYLOAD_TYPE_TRACE) {
  528. MESH_DEBUG_PRINTLN("%s Mesh::sendFlood(): TRACE type not suspported", getLogDateTime());
  529. return;
  530. }
  531. if (path_hash_size == 0 || path_hash_size > 3) {
  532. MESH_DEBUG_PRINTLN("%s Mesh::sendFlood(): invalid path_hash_size", getLogDateTime());
  533. return;
  534. }
  535. packet->header &= ~PH_ROUTE_MASK;
  536. packet->header |= ROUTE_TYPE_FLOOD;
  537. packet->setPathHashSizeAndCount(path_hash_size, 0);
  538. _tables->hasSeen(packet); // mark this packet as already sent in case it is rebroadcast back to us
  539. uint8_t pri;
  540. if (packet->getPayloadType() == PAYLOAD_TYPE_PATH) {
  541. pri = 2;
  542. } else if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT) {
  543. pri = 3; // de-prioritie these
  544. } else {
  545. pri = 1;
  546. }
  547. sendPacket(packet, pri, delay_millis);
  548. }
  549. void Mesh::sendFlood(Packet* packet, uint16_t* transport_codes, uint32_t delay_millis, uint8_t path_hash_size) {
  550. if (packet->getPayloadType() == PAYLOAD_TYPE_TRACE) {
  551. MESH_DEBUG_PRINTLN("%s Mesh::sendFlood(): TRACE type not suspported", getLogDateTime());
  552. return;
  553. }
  554. if (path_hash_size == 0 || path_hash_size > 3) {
  555. MESH_DEBUG_PRINTLN("%s Mesh::sendFlood(): invalid path_hash_size", getLogDateTime());
  556. return;
  557. }
  558. packet->header &= ~PH_ROUTE_MASK;
  559. packet->header |= ROUTE_TYPE_TRANSPORT_FLOOD;
  560. packet->transport_codes[0] = transport_codes[0];
  561. packet->transport_codes[1] = transport_codes[1];
  562. packet->setPathHashSizeAndCount(path_hash_size, 0);
  563. _tables->hasSeen(packet); // mark this packet as already sent in case it is rebroadcast back to us
  564. uint8_t pri;
  565. if (packet->getPayloadType() == PAYLOAD_TYPE_PATH) {
  566. pri = 2;
  567. } else if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT) {
  568. pri = 3; // de-prioritie these
  569. } else {
  570. pri = 1;
  571. }
  572. sendPacket(packet, pri, delay_millis);
  573. }
  574. void Mesh::sendDirect(Packet* packet, const uint8_t* path, uint8_t path_len, uint32_t delay_millis) {
  575. packet->header &= ~PH_ROUTE_MASK;
  576. packet->header |= ROUTE_TYPE_DIRECT;
  577. uint8_t pri;
  578. if (packet->getPayloadType() == PAYLOAD_TYPE_TRACE) { // TRACE packets are different
  579. // for TRACE packets, path is appended to end of PAYLOAD. (path is used for SNR's)
  580. memcpy(&packet->payload[packet->payload_len], path, path_len); // NOTE: path_len here can be > 64, and NOT in the new scheme
  581. packet->payload_len += path_len;
  582. packet->path_len = 0;
  583. pri = 5; // maybe make this configurable
  584. } else {
  585. packet->path_len = Packet::copyPath(packet->path, path, path_len);
  586. if (packet->getPayloadType() == PAYLOAD_TYPE_PATH) {
  587. pri = 1; // slightly less priority
  588. } else {
  589. pri = 0;
  590. }
  591. }
  592. _tables->hasSeen(packet); // mark this packet as already sent in case it is rebroadcast back to us
  593. sendPacket(packet, pri, delay_millis);
  594. }
  595. void Mesh::sendZeroHop(Packet* packet, uint32_t delay_millis) {
  596. packet->header &= ~PH_ROUTE_MASK;
  597. packet->header |= ROUTE_TYPE_DIRECT;
  598. packet->path_len = 0; // path_len of zero means Zero Hop
  599. _tables->hasSeen(packet); // mark this packet as already sent in case it is rebroadcast back to us
  600. sendPacket(packet, 0, delay_millis);
  601. }
  602. void Mesh::sendZeroHop(Packet* packet, uint16_t* transport_codes, uint32_t delay_millis) {
  603. packet->header &= ~PH_ROUTE_MASK;
  604. packet->header |= ROUTE_TYPE_TRANSPORT_DIRECT;
  605. packet->transport_codes[0] = transport_codes[0];
  606. packet->transport_codes[1] = transport_codes[1];
  607. packet->path_len = 0; // path_len of zero means Zero Hop
  608. _tables->hasSeen(packet); // mark this packet as already sent in case it is rebroadcast back to us
  609. sendPacket(packet, 0, delay_millis);
  610. }
  611. }