4545#define  CMD_GET_CUSTOM_VARS            40 
4646#define  CMD_SET_CUSTOM_VAR             41 
4747#define  CMD_GET_ADVERT_PATH            42 
48+ #define  CMD_GET_TUNING_PARAMS          43 
49+ //  NOTE: CMD range 44..49 parked, potentially for WiFi operations
50+ #define  CMD_SEND_BINARY_REQ            50 
51+ #define  CMD_FACTORY_RESET              51 
4852
4953#define  RESP_CODE_OK                   0 
5054#define  RESP_CODE_ERR                  1 
6973#define  RESP_CODE_SIGNATURE            20 
7074#define  RESP_CODE_CUSTOM_VARS          21 
7175#define  RESP_CODE_ADVERT_PATH          22 
76+ #define  RESP_CODE_TUNING_PARAMS        23 
7277
7378#define  SEND_TIMEOUT_BASE_MILLIS         500 
7479#define  FLOOD_SEND_TIMEOUT_FACTOR        16 .0f 
9196#define  PUSH_CODE_TRACE_DATA             0x89 
9297#define  PUSH_CODE_NEW_ADVERT             0x8A 
9398#define  PUSH_CODE_TELEMETRY_RESPONSE     0x8B 
99+ #define  PUSH_CODE_BINARY_RESPONSE        0x8C 
94100
95101#define  ERR_CODE_UNSUPPORTED_CMD         1 
96102#define  ERR_CODE_NOT_FOUND               2 
@@ -319,13 +325,17 @@ void MyMesh::queueMessage(const ContactInfo &from, uint8_t txt_type, mesh::Packe
319325    uint8_t  frame[1 ];
320326    frame[0 ] = PUSH_CODE_MSG_WAITING; //  send push 'tickle'
321327    _serial->writeFrame (frame, 1 );
322-   } else  {
323- #ifdef  DISPLAY_CLASS
324-     ui_task.soundBuzzer (UIEventType::contactMessage);
325- #endif 
326328  }
329+ 
327330#ifdef  DISPLAY_CLASS
328-   ui_task.newMsg (path_len, from.name , text, offline_queue_len);
331+   //  we only want to show text messages on display, not cli data
332+   bool  should_display = txt_type == TXT_TYPE_PLAIN || txt_type == TXT_TYPE_SIGNED_PLAIN;
333+   if  (should_display) {
334+     ui_task.newMsg (path_len, from.name , text, offline_queue_len);
335+     if  (!_serial->isConnected ()) {
336+       ui_task.soundBuzzer (UIEventType::contactMessage);
337+     }
338+   }
329339#endif 
330340}
331341
@@ -462,6 +472,7 @@ void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data,
462472      i += 6 ; //  pub_key_prefix
463473      memcpy (&out_frame[i], &tag, 4 );
464474      i += 4 ; //  NEW: include server timestamp
475+       out_frame[i++] = data[7 ]; //  NEW (v7): ACL permissions
465476    } else  {
466477      out_frame[i++] = PUSH_CODE_LOGIN_FAIL;
467478      out_frame[i++] = 0 ; //  reserved
@@ -484,7 +495,7 @@ void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data,
484495    memcpy (&out_frame[i], &data[4 ], len - 4 );
485496    i += (len - 4 );
486497    _serial->writeFrame (out_frame, i);
487-   } else  if  (len > 4  && tag == pending_telemetry) { //  check for telemetry  response
498+   } else  if  (len > 4  && tag == pending_telemetry) {   //  check for matching  response tag 
488499    pending_telemetry = 0 ;
489500
490501    int  i = 0 ;
@@ -495,6 +506,17 @@ void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data,
495506    memcpy (&out_frame[i], &data[4 ], len - 4 );
496507    i += (len - 4 );
497508    _serial->writeFrame (out_frame, i);
509+   } else  if  (len > 4  && tag == pending_req) {  //  check for matching response tag
510+     pending_req = 0 ;
511+ 
512+     int  i = 0 ;
513+     out_frame[i++] = PUSH_CODE_BINARY_RESPONSE;
514+     out_frame[i++] = 0 ; //  reserved
515+     memcpy (&out_frame[i], &tag, 4 );   //  app needs to match this to RESP_CODE_SENT.tag
516+     i += 4 ;
517+     memcpy (&out_frame[i], &data[4 ], len - 4 );
518+     i += (len - 4 );
519+     _serial->writeFrame (out_frame, i);
498520  }
499521}
500522
@@ -560,7 +582,7 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe
560582  _cli_rescue = false ;
561583  offline_queue_len = 0 ;
562584  app_target_ver = 0 ;
563-   pending_login = pending_status = pending_telemetry = 0 ;
585+   pending_login = pending_status = pending_telemetry = pending_req =  0 ;
564586  next_ack_idx = 0 ;
565587  sign_data = NULL ;
566588  dirty_contacts_expiry = 0 ;
@@ -1012,6 +1034,13 @@ void MyMesh::handleCmdFrame(size_t len) {
10121034    _prefs.airtime_factor  = ((float )af) / 1000 .0f ;
10131035    savePrefs ();
10141036    writeOKFrame ();
1037+   } else  if  (cmd_frame[0 ] == CMD_GET_TUNING_PARAMS) {
1038+     uint32_t  rx = _prefs.rx_delay_base  * 1000 , af = _prefs.airtime_factor  * 1000 ;
1039+     int  i = 0 ;
1040+     out_frame[i++] = RESP_CODE_TUNING_PARAMS;
1041+     memcpy (&out_frame[i], &rx, 4 ); i += 4 ;
1042+     memcpy (&out_frame[i], &af, 4 ); i += 4 ;
1043+     _serial->writeFrame (out_frame, i);
10151044  } else  if  (cmd_frame[0 ] == CMD_SET_OTHER_PARAMS) {
10161045    _prefs.manual_add_contacts  = cmd_frame[1 ];
10171046    if  (len >= 3 ) {
@@ -1090,7 +1119,7 @@ void MyMesh::handleCmdFrame(size_t len) {
10901119      if  (result == MSG_SEND_FAILED) {
10911120        writeErrFrame (ERR_CODE_TABLE_FULL);
10921121      } else  {
1093-         pending_telemetry = pending_status = 0 ;
1122+         pending_req =  pending_telemetry = pending_status = 0 ;
10941123        memcpy (&pending_login, recipient->id .pub_key , 4 ); //  match this to onContactResponse()
10951124        out_frame[0 ] = RESP_CODE_SENT;
10961125        out_frame[1 ] = (result == MSG_SEND_SENT_FLOOD) ? 1  : 0 ;
@@ -1110,7 +1139,7 @@ void MyMesh::handleCmdFrame(size_t len) {
11101139      if  (result == MSG_SEND_FAILED) {
11111140        writeErrFrame (ERR_CODE_TABLE_FULL);
11121141      } else  {
1113-         pending_telemetry = pending_login = 0 ;
1142+         pending_req =  pending_telemetry = pending_login = 0 ;
11141143        //  FUTURE:  pending_status = tag;  // match this in onContactResponse()
11151144        memcpy (&pending_status, recipient->id .pub_key , 4 ); //  legacy matching scheme
11161145        out_frame[0 ] = RESP_CODE_SENT;
@@ -1122,7 +1151,7 @@ void MyMesh::handleCmdFrame(size_t len) {
11221151    } else  {
11231152      writeErrFrame (ERR_CODE_NOT_FOUND); //  contact not found
11241153    }
1125-   } else  if  (cmd_frame[0 ] == CMD_SEND_TELEMETRY_REQ && len >= 4  + PUB_KEY_SIZE) {
1154+   } else  if  (cmd_frame[0 ] == CMD_SEND_TELEMETRY_REQ && len >= 4  + PUB_KEY_SIZE) {   //  can deprecate, in favour of CMD_SEND_BINARY_REQ 
11261155    uint8_t  *pub_key = &cmd_frame[4 ];
11271156    ContactInfo *recipient = lookupContactByPubKey (pub_key, PUB_KEY_SIZE);
11281157    if  (recipient) {
@@ -1131,7 +1160,7 @@ void MyMesh::handleCmdFrame(size_t len) {
11311160      if  (result == MSG_SEND_FAILED) {
11321161        writeErrFrame (ERR_CODE_TABLE_FULL);
11331162      } else  {
1134-         pending_status = pending_login = 0 ;
1163+         pending_status = pending_login = pending_req =  0 ;
11351164        pending_telemetry = tag; //  match this in onContactResponse()
11361165        out_frame[0 ] = RESP_CODE_SENT;
11371166        out_frame[1 ] = (result == MSG_SEND_SENT_FLOOD) ? 1  : 0 ;
@@ -1157,6 +1186,27 @@ void MyMesh::handleCmdFrame(size_t len) {
11571186    memcpy (&out_frame[i], telemetry.getBuffer (), tlen);
11581187    i += tlen;
11591188    _serial->writeFrame (out_frame, i);
1189+   } else  if  (cmd_frame[0 ] == CMD_SEND_BINARY_REQ && len >= 2  + PUB_KEY_SIZE) {
1190+     uint8_t  *pub_key = &cmd_frame[1 ];
1191+     ContactInfo *recipient = lookupContactByPubKey (pub_key, PUB_KEY_SIZE);
1192+     if  (recipient) {
1193+       uint8_t  *req_data = &cmd_frame[1  + PUB_KEY_SIZE];
1194+       uint32_t  tag, est_timeout;
1195+       int  result = sendRequest (*recipient, req_data, len - (1  + PUB_KEY_SIZE), tag, est_timeout);
1196+       if  (result == MSG_SEND_FAILED) {
1197+         writeErrFrame (ERR_CODE_TABLE_FULL);
1198+       } else  {
1199+         pending_status = pending_login = pending_telemetry = 0 ;
1200+         pending_req = tag; //  match this in onContactResponse()
1201+         out_frame[0 ] = RESP_CODE_SENT;
1202+         out_frame[1 ] = (result == MSG_SEND_SENT_FLOOD) ? 1  : 0 ;
1203+         memcpy (&out_frame[2 ], &tag, 4 );
1204+         memcpy (&out_frame[6 ], &est_timeout, 4 );
1205+         _serial->writeFrame (out_frame, 10 );
1206+       }
1207+     } else  {
1208+       writeErrFrame (ERR_CODE_NOT_FOUND); //  contact not found
1209+     }
11601210  } else  if  (cmd_frame[0 ] == CMD_HAS_CONNECTION && len >= 1  + PUB_KEY_SIZE) {
11611211    uint8_t  *pub_key = &cmd_frame[1 ];
11621212    if  (hasConnectionTo (pub_key)) {
@@ -1312,6 +1362,15 @@ void MyMesh::handleCmdFrame(size_t len) {
13121362    } else  {
13131363      writeErrFrame (ERR_CODE_NOT_FOUND);
13141364    }
1365+   } else  if  (cmd_frame[0 ] == CMD_FACTORY_RESET && memcmp (&cmd_frame[1 ], " reset"  , 5 ) == 0 ) {
1366+     bool  success = _store->formatFileSystem ();
1367+     if  (success) {
1368+       writeOKFrame ();
1369+       delay (1000 );
1370+       board.reboot ();  //  doesn't return
1371+     } else  {
1372+       writeErrFrame (ERR_CODE_FILE_IO_ERROR);
1373+     }
13151374  } else  {
13161375    writeErrFrame (ERR_CODE_UNSUPPORTED_CMD);
13171376    MESH_DEBUG_PRINTLN (" ERROR: unknown command: %02X"  , cmd_frame[0 ]);
0 commit comments