@ -228,6 +228,22 @@ void BaseChatMesh::getPeerSharedSecret(uint8_t* dest_secret, int peer_idx) {
}
}
uint8_t BaseChatMesh : : getPeerFlags ( int peer_idx ) {
int i = matching_peer_indexes [ peer_idx ] ;
if ( i > = 0 & & i < num_contacts ) {
return contacts [ i ] . flags ;
}
return 0 ;
}
uint16_t BaseChatMesh : : getPeerNextAeadNonce ( int peer_idx ) {
int i = matching_peer_indexes [ peer_idx ] ;
if ( i > = 0 & & i < num_contacts ) {
return contacts [ i ] . nextAeadNonce ( ) ;
}
return 0 ;
}
void BaseChatMesh : : onPeerDataRecv ( mesh : : Packet * packet , uint8_t type , int sender_idx , const uint8_t * secret , uint8_t * data , size_t len ) {
int i = matching_peer_indexes [ sender_idx ] ;
if ( i < 0 | | i > = num_contacts ) {
@ -259,7 +275,7 @@ void BaseChatMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender
if ( packet - > isRouteFlood ( ) ) {
// let this sender know path TO here, so they can use sendDirect(), and ALSO encode the ACK
mesh : : Packet * path = createPathReturn ( from . id , secret , packet - > path , packet - > path_len ,
PAYLOAD_TYPE_ACK , ( uint8_t * ) & ack_hash , 6 ) ;
PAYLOAD_TYPE_ACK , ( uint8_t * ) & ack_hash , 6 , from . nextAeadNonce ( ) ) ;
if ( path ) sendFloodScoped ( from , path , TXT_ACK_DELAY ) ;
} else {
sendAckTo ( from , ack_hash , 6 ) ;
@ -270,7 +286,7 @@ void BaseChatMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender
if ( packet - > isRouteFlood ( ) ) {
// let this sender know path TO here, so they can use sendDirect() (NOTE: no ACK as extra)
mesh : : Packet * path = createPathReturn ( from . id , secret , packet - > path , packet - > path_len , 0 , NULL , 0 ) ;
mesh : : Packet * path = createPathReturn ( from . id , secret , packet - > path , packet - > path_len , 0 , NULL , 0 , from . nextAeadNonce ( ) ) ;
if ( path ) sendFloodScoped ( from , path ) ;
}
} else if ( flags = = TXT_TYPE_SIGNED_PLAIN ) {
@ -286,7 +302,7 @@ void BaseChatMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender
if ( packet - > isRouteFlood ( ) ) {
// let this sender know path TO here, so they can use sendDirect(), and ALSO encode the ACK
mesh : : Packet * path = createPathReturn ( from . id , secret , packet - > path , packet - > path_len ,
PAYLOAD_TYPE_ACK , ( uint8_t * ) & ack_hash , 4 ) ;
PAYLOAD_TYPE_ACK , ( uint8_t * ) & ack_hash , 4 , from . nextAeadNonce ( ) ) ;
if ( path ) sendFloodScoped ( from , path , TXT_ACK_DELAY ) ;
} else {
sendAckTo ( from , ( uint8_t * ) & ack_hash ) ;
@ -302,10 +318,10 @@ void BaseChatMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender
if ( packet - > isRouteFlood ( ) ) {
// let this sender know path TO here, so they can use sendDirect(), and ALSO encode the response
mesh : : Packet * path = createPathReturn ( from . id , secret , packet - > path , packet - > path_len ,
PAYLOAD_TYPE_RESPONSE , temp_buf , reply_len ) ;
PAYLOAD_TYPE_RESPONSE , temp_buf , reply_len , from . nextAeadNonce ( ) ) ;
if ( path ) sendFloodScoped ( from , path , SERVER_RESPONSE_DELAY ) ;
} else {
mesh : : Packet * reply = createDatagram ( PAYLOAD_TYPE_RESPONSE , from . id , secret , temp_buf , reply_len ) ;
mesh : : Packet * reply = createDatagram ( PAYLOAD_TYPE_RESPONSE , from . id , secret , temp_buf , reply_len , from . nextAeadNonce ( ) ) ;
if ( reply ) {
if ( from . out_path_len ! = OUT_PATH_UNKNOWN ) { // we have an out_path, so send DIRECT
sendDirect ( reply , from . out_path , from . out_path_len , SERVER_RESPONSE_DELAY ) ;
@ -371,7 +387,7 @@ void BaseChatMesh::onAckRecv(mesh::Packet* packet, uint32_t ack_crc) {
void BaseChatMesh : : handleReturnPathRetry ( const ContactInfo & contact , const uint8_t * path , uint8_t path_len ) {
// NOTE: simplest impl is just to re-send a reciprocal return path to sender (DIRECTLY)
// override this method in various firmwares, if there's a better strategy
mesh : : Packet * rpath = createPathReturn ( contact . id , contact . getSharedSecret ( self_id ) , path , path_len , 0 , NULL , 0 ) ;
mesh : : Packet * rpath = createPathReturn ( contact . id , contact . getSharedSecret ( self_id ) , path , path_len , 0 , NULL , 0 , contact . nextAeadNonce ( ) ) ;
if ( rpath ) sendDirect ( rpath , contact . out_path , contact . out_path_len , 3000 ) ; // 3 second delay
}
@ -447,7 +463,7 @@ mesh::Packet* BaseChatMesh::composeMsgPacket(const ContactInfo& recipient, uint3
temp [ len + + ] = attempt ; // hide attempt number at tail end of payload
}
return createDatagram ( PAYLOAD_TYPE_TXT_MSG , recipient . id , recipient . getSharedSecret ( self_id ) , temp , len ) ;
return createDatagram ( PAYLOAD_TYPE_TXT_MSG , recipient . id , recipient . getSharedSecret ( self_id ) , temp , len , recipient . nextAeadNonce ( ) ) ;
}
int BaseChatMesh : : sendMessage ( const ContactInfo & recipient , uint32_t timestamp , uint8_t attempt , const char * text , uint32_t & expected_ack , uint32_t & est_timeout ) {
@ -478,7 +494,7 @@ int BaseChatMesh::sendCommandData(const ContactInfo& recipient, uint32_t timest
temp [ 4 ] = ( attempt & 3 ) | ( TXT_TYPE_CLI_DATA < < 2 ) ;
memcpy ( & temp [ 5 ] , text , text_len + 1 ) ;
auto pkt = createDatagram ( PAYLOAD_TYPE_TXT_MSG , recipient . id , recipient . getSharedSecret ( self_id ) , temp , 5 + text_len ) ;
auto pkt = createDatagram ( PAYLOAD_TYPE_TXT_MSG , recipient . id , recipient . getSharedSecret ( self_id ) , temp , 5 + text_len , recipient . nextAeadNonce ( ) ) ;
if ( pkt = = NULL ) return MSG_SEND_FAILED ;
uint32_t t = _radio - > getEstAirtimeFor ( pkt - > getRawLength ( ) ) ;
@ -650,7 +666,7 @@ int BaseChatMesh::sendRequest(const ContactInfo& recipient, const uint8_t* req_
memcpy ( temp , & tag , 4 ) ; // mostly an extra blob to help make packet_hash unique
memcpy ( & temp [ 4 ] , req_data , data_len ) ;
pkt = createDatagram ( PAYLOAD_TYPE_REQ , recipient . id , recipient . getSharedSecret ( self_id ) , temp , 4 + data_len ) ;
pkt = createDatagram ( PAYLOAD_TYPE_REQ , recipient . id , recipient . getSharedSecret ( self_id ) , temp , 4 + data_len , recipient . nextAeadNonce ( ) ) ;
}
if ( pkt ) {
uint32_t t = _radio - > getEstAirtimeFor ( pkt - > getRawLength ( ) ) ;
@ -677,7 +693,7 @@ int BaseChatMesh::sendRequest(const ContactInfo& recipient, uint8_t req_type, u
memset ( & temp [ 5 ] , 0 , 4 ) ; // reserved (possibly for 'since' param)
getRNG ( ) - > random ( & temp [ 9 ] , 4 ) ; // random blob to help make packet-hash unique
pkt = createDatagram ( PAYLOAD_TYPE_REQ , recipient . id , recipient . getSharedSecret ( self_id ) , temp , sizeof ( temp ) ) ;
pkt = createDatagram ( PAYLOAD_TYPE_REQ , recipient . id , recipient . getSharedSecret ( self_id ) , temp , sizeof ( temp ) , recipient . nextAeadNonce ( ) ) ;
}
if ( pkt ) {
uint32_t t = _radio - > getEstAirtimeFor ( pkt - > getRawLength ( ) ) ;
@ -800,7 +816,7 @@ void BaseChatMesh::checkConnections() {
// calc expected ACK reply
mesh : : Utils : : sha256 ( ( uint8_t * ) & connections [ i ] . expected_ack , 4 , data , 9 , self_id . pub_key , PUB_KEY_SIZE ) ;
auto pkt = createDatagram ( PAYLOAD_TYPE_REQ , contact - > id , contact - > getSharedSecret ( self_id ) , data , 9 ) ;
auto pkt = createDatagram ( PAYLOAD_TYPE_REQ , contact - > id , contact - > getSharedSecret ( self_id ) , data , 9 , contact - > nextAeadNonce ( ) ) ;
if ( pkt ) {
sendDirect ( pkt , contact - > out_path , contact - > out_path_len ) ;
}