// mesh callback when sending command chunks static void leadCommandChunkConfirm(NWK_DataReq_t *req) { if (hqVerboseOutput) { Serial.print(F(" Message confirmation - ")); } if (req->status == NWK_SUCCESS_STATUS) { if (hqVerboseOutput) { Serial.println(F("success")); } if (leadCommandChunks.length() - leadCommandChunksAt > 100) { leadCommandChunksAt += 100; leadCommandChunk(); return; // don't free yet } } else { leadCommandRetries++; if (leadCommandRetries > 3) { if (hqVerboseOutput) { Serial.print(F("error: ")); Serial.println(req->status); } leadCommandError(leadCommandTo, leadAnswerID, "no response"); } else { if (hqVerboseOutput) { Serial.println(F("RETRY")); } NWK_DataReq(req); return; // don't free yet } } leadCommandTo = 0; leadCommandChunks = (char*)NULL; }
// mesh callback when sending command chunks static void leadCommandChunkConfirm(NWK_DataReq_t *req) { if (hqVerboseOutput) { sp(" Message confirmation - "); } if (req->status == NWK_SUCCESS_STATUS) { if (hqVerboseOutput) { speol("success"); } if (strlen(leadCommandChunks+leadCommandChunksAt) > 100) { leadCommandChunksAt += 100; leadCommandChunk(); return; // don't free yet } } else { leadCommandRetries++; if (leadCommandRetries > 3) { if (hqVerboseOutput) { sp("error: "); speol(req->status); } leadCommandError(leadCommandTo, leadAnswerID, "no response"); } else { if (hqVerboseOutput) { speol("RETRY"); } NWK_DataReq(req); return; // don't free yet } } leadCommandTo = 0; free(leadCommandChunks); }
// process a packet from HQ void leadIncoming(const char *packet, size_t len, unsigned short *index) { char *type, *command, *buffer; buffer = (char*)malloc(len); memcpy(buffer, packet, len); uint16_t to; unsigned long id; type = j0g_str("type", buffer, index); if (hqVerboseOutput) { Serial.println(type); } if (strcmp(type, "online") == 0) { Shell.allReportHQ(); } if (strcmp(type, "command") == 0) { to = atoi(j0g_str("to", buffer, index)); id = strtoul(j0g_str("id", buffer, index), NULL, 10); command = j0g_str("command", buffer, index); if (strlen(j0g_str("to", buffer, index)) == 0 || !id || !command) { if (hqVerboseOutput) { Serial.println(F("invalid command, requires to, id, command")); Serial.print(F("to: ")); Serial.println(to); Serial.print(F("id: ")); Serial.println(id); Serial.print(F("command: ")); Serial.println(command); } free(buffer); return; } // handle internal ones first if (to == Scout.getAddress()) { setOutputHandler(&printToString<&leadCommandOutput>); doCommand(command); resetOutputHandler(); StringBuffer report; report.appendSprintf("{\"type\":\"reply\",\"from\":%d,\"id\":%lu,\"end\":true,\"reply\":", to, id); report.appendJsonString(leadCommandOutput, true); report += "}\n"; leadSignal(report); leadCommandOutput = (char*)NULL; free(buffer); return; } // we can only send one command at a time if (leadCommandTo) { // TODO we could stop reading the HQ socket in this mode and then never get a busy? free(buffer); return leadCommandError(to,id,"busy"); } // send over mesh to recipient and cache id for any replies leadAnswerID = id; leadCommandTo = to; leadCommandChunks = command; leadCommandChunksAt = 0; leadCommandRetries = 0; leadCommandChunk(); } free(buffer); }
// process a packet from HQ void leadIncoming(char *packet, unsigned short *index) { char *type, *command; uint16_t to; unsigned long id; type = j0g_str("type", packet, index); if (hqVerboseOutput) { speol(type); } if (strcmp(type, "online") == 0) { Shell.allReportHQ(); } if (strcmp(type, "command") == 0) { to = atoi(j0g_str("to", packet, index)); id = strtoul(j0g_str("id", packet, index), NULL, 10); command = j0g_str("command", packet, index); if (strlen(j0g_str("to", packet, index)) == 0 || !id || !command) { if (hqVerboseOutput) { speol("invalid command, requires to, id, command"); sp("to: "); speol(to); sp("id: "); speol(id); sp("command: "); speol(command); } return; } // handle internal ones first if (to == Scout.getAddress()) { Shell.bitlashOutput = (char*)malloc(255); sprintf(Shell.bitlashOutput,"{\"type\":\"reply\",\"from\":%d,\"id\":%lu,\"end\":true,\"reply\":\"", to, id); setOutputHandler(&bitlashBuffer); doCommand(command); strcpy(Shell.bitlashOutput + strlen(Shell.bitlashOutput), "\"}\n"); setOutputHandler(&bitlashFilter); leadSignal(Shell.bitlashOutput); free(Shell.bitlashOutput); return; } // we can only send one command at a time if (leadCommandTo) { // TODO we could stop reading the HQ socket in this mode and then never get a busy? return leadCommandError(to,id,"busy"); } // send over mesh to recipient and cache id for any replies leadAnswerID = id; leadCommandTo = to; leadCommandChunks = (char*)malloc(strlen(command) + 1); strcpy(leadCommandChunks, command); leadCommandChunksAt = 0; leadCommandRetries = 0; leadCommandChunk(); } }