static bool fieldCommands(NWK_DataInd_t *ind) { int ret; if (hqVerboseOutput) { Serial.print(F("Received command")); Serial.print(F("lqi: ")); Serial.print(ind->lqi); Serial.print(F(" ")); Serial.print(F("rssi: ")); Serial.println(ind->rssi); } if (fieldAnswerTo) { if (hqVerboseOutput) { Serial.println(F("can't receive command while sending answer")); } return false; } if (!fieldCommand.concat((const char*)ind->data, ind->size)) { return false; // TODO we need to restart or something, no memory } // when null terminated, do the message if (fieldCommand[fieldCommand.length() - 1] != '\0') { if (hqVerboseOutput) { Serial.println(F("waiting for more")); } return true; } if (hqVerboseOutput) { Serial.print(F("running command ")); Serial.println(fieldCommand); } // run the command and chunk back the results setOutputHandler(&printToString<&fieldCommandOutput>); // TODO: Once bitlash fixes const-correctness, this and similar casts // should be removed. ret = (int)doCommand(const_cast<char *>(fieldCommand.c_str())); fieldCommand = (char*)NULL; resetOutputHandler(); if (hqVerboseOutput) { Serial.print(F("got result ")); Serial.println(ret); } // send data back in chunks fieldAnswerTo = ind->srcAddr; fieldAnswerChunksAt = 0; fieldAnswerRetries = 0; fieldAnswerChunk(); return true; }
////////// // // func_fprintf(): implementation of fprintf() function // // numvar func_fprintf(void) { numvar fetchmark = markparsepoint(); scriptwrite((char *) getarg(1), "", 1); // open the file for append (but append nothing) //serialOutputFunc saved_handler = serial_override_handler; // save previous output handler setOutputHandler(scriptwritebyte); // set file output handler func_printf_handler(2,3); // format=arg(2), optional args start at 3 //setOutputHandler(saved_handler);// restore output handler resetOutputHandler(); returntoparsepoint(fetchmark, 1); }
////////// // // func_fprintf(): implementation of fprintf() function // // numvar func_fprintf(void) { parsepoint fetchmark; markparsepoint(&fetchmark); scriptwrite((char *) getarg(1), "", 1); // open the file for append (but append nothing) //serialOutputFunc saved_handler = serial_override_handler; // save previous output handler void scriptwritebyte(byte); setOutputHandler(scriptwritebyte); // set file output handler func_printf_handler(2,3); // format=arg(2), optional args start at 3 //setOutputHandler(saved_handler);// restore output handler resetOutputHandler(); #ifdef scriptclose scriptclose(); // close and flush the output #endif returntoparsepoint(&fetchmark, 1); }
void PinoccioScoutHandler::setup() { if (Scout.isLeadScout()) { Scout.wifi.setup(); Scout.wifi.autoConnectHq(); Scout.meshListen(3, leadAnswers); Scout.meshJoinGroup(0xBEEF); // our internal reporting channel Scout.meshJoinGroup(0); // reports to HQ } else { Scout.meshListen(2, fieldCommands); } // join a set of groups to listen for announcements for (int i = 1; i < 10; i++) { Scout.meshJoinGroup(i); } Scout.meshListen(4, fieldAnnouncements); setOutputHandler(&bitlashFilter); }
// 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(); } }
static bool fieldCommands(NWK_DataInd_t *ind) { int total, ret; // RgbLed.blinkGreen(200); if (hqVerboseOutput) { sp("Received command"); sp("lqi: "); sp(ind->lqi); sp(" "); sp("rssi: "); speol(ind->rssi); } if (fieldAnswerTo) { if (hqVerboseOutput) { speol("can't receive command while sending answer"); } return false; } // commands may be larger than one packet, copy and buffer up total = fieldCommandLen + ind->size; fieldCommand = (char*)realloc(fieldCommand, total); if (!fieldCommand) { return false; // TODO we need to restart or something, no memory } memcpy(fieldCommand + fieldCommandLen, ind->data, ind->size); fieldCommandLen = total; // when null terminated, do the message if (fieldCommand[fieldCommandLen-1] != 0) { if (hqVerboseOutput) { speol("waiting for more"); } return true; } // run the command and chunk back the results setOutputHandler(&bitlashBuffer); Shell.bitlashOutput = (char*)malloc(1); Shell.bitlashOutput[0] = 0; if (hqVerboseOutput) { sp("running command "); speol(fieldCommand); } ret = (int)doCommand(fieldCommand); if (hqVerboseOutput) { sp("got result "); speol(ret); } setOutputHandler(&bitlashFilter); fieldCommandLen = 0; // send data back in chunks fieldAnswerTo = ind->srcAddr; fieldAnswerChunks = Shell.bitlashOutput; fieldAnswerChunksAt = 0; fieldAnswerRetries = 0; fieldAnswerChunk(); return true; }