// called to send the first/next chunk of a command to another scout static void leadCommandChunk() { int len = leadCommandChunks.length() - leadCommandChunksAt; if (len > 100) { len = 100; } else { len++; // null terminator at end } leadCommandReq.dstAddr = leadCommandTo; leadCommandReq.dstEndpoint = 2; leadCommandReq.srcEndpoint = 3; leadCommandReq.options = NWK_OPT_ENABLE_SECURITY; leadCommandReq.data = (uint8_t*)leadCommandChunks.c_str() + leadCommandChunksAt; leadCommandReq.size = len; leadCommandReq.confirm = leadCommandChunkConfirm; NWK_DataReq(&leadCommandReq); //RgbLed.blinkCyan(200); if (hqVerboseOutput) { Serial.print(leadCommandTo); Serial.print(F(" len ")); Serial.print(len); Serial.println(F("->chunk")); } }
static void appSendData(void) { #ifdef NWK_ENABLE_ROUTING appMsg.parentShortAddr = NWK_RouteNextHop(0, 0); #else appMsg.parentShortAddr = 0; #endif appMsg.sensors.battery = rand() & 0xffff; appMsg.sensors.temperature = rand() & 0x7f; appMsg.sensors.light = rand() & 0xff; #if APP_COORDINATOR appSendMessage((uint8_t *)&appMsg, sizeof(appMsg)); SYS_TimerStart(&appDataSendingTimer); appState = APP_STATE_WAIT_SEND_TIMER; #else nwkDataReq.dstAddr = 0; nwkDataReq.dstEndpoint = APP_ENDPOINT; nwkDataReq.srcEndpoint = APP_ENDPOINT; nwkDataReq.options = NWK_OPT_ACK_REQUEST | NWK_OPT_ENABLE_SECURITY; nwkDataReq.data = (uint8_t *)&appMsg; nwkDataReq.size = sizeof(appMsg); nwkDataReq.confirm = appDataConf; LED_On(LED_DATA); NWK_DataReq(&nwkDataReq); appState = APP_STATE_WAIT_CONF; #endif }
// 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; }
static void fieldAnswerChunkConfirm(NWK_DataReq_t *req) { if (hqVerboseOutput) { sp(" Message confirmation - "); } if (req->status == NWK_SUCCESS_STATUS) { if (hqVerboseOutput) { speol("success"); } if (strlen(fieldAnswerChunks + fieldAnswerChunksAt) > 100) { fieldAnswerChunksAt += 100; fieldAnswerChunk(); return; // don't free yet } } else { fieldAnswerRetries++; if (fieldAnswerRetries > 3) { if (hqVerboseOutput) { sp("error: "); speol(req->status); } } else { if (hqVerboseOutput) { speol("RETRY"); } NWK_DataReq(req); return; // don't free yet } } fieldAnswerTo = 0; free(fieldAnswerChunks); }
// called to send the first/next chunk of a command to another scout static void leadCommandChunk() { int len = strlen(leadCommandChunks + leadCommandChunksAt); if (len > 100) { len = 100; } else { len++; // null terminator at end } leadCommandReq.dstAddr = leadCommandTo; leadCommandReq.dstEndpoint = 2; leadCommandReq.srcEndpoint = 3; leadCommandReq.options = NWK_OPT_ENABLE_SECURITY; leadCommandReq.data = (uint8_t*)(leadCommandChunks+leadCommandChunksAt); leadCommandReq.size = len; leadCommandReq.confirm = leadCommandChunkConfirm; NWK_DataReq(&leadCommandReq); //RgbLed.blinkCyan(200); if (hqVerboseOutput) { sp(leadCommandTo); sp(" len "); sp(len); speol("->chunk"); } }
void radioSendData(uint8_t *data, uint8_t size) { /* if (appDataReqBusy || 0 == appChannelBufferPtr) { return; } */ if (radioDataReqBusy) { // puts("radio busy"); return; } //memcpy(appDataReqBuffer, appUartBuffer, appUartBufferPtr); radioDataReq.dstAddr = 1 - APP_ADDR; radioDataReq.dstEndpoint = APP_ENDPOINT; radioDataReq.srcEndpoint = APP_ENDPOINT; radioDataReq.options = NWK_OPT_ENABLE_SECURITY; radioDataReq.data = data; //appDataReqBuffer; // radioDataReq.size = size;//sizeof(data); //appUartBufferPtr; // radioDataReq.confirm = radioDataConf; NWK_DataReq(&radioDataReq); printf("sending \n\r channel 0 value = %u\n\r channel 1 value = %u\n\r", data[0],data[1]); //appUartBufferPtr = 0; radioDataReqBusy = true; port_pin_toggle_output_level(LED_0_PIN); }
// 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); }
/*************************************************************************//** *****************************************************************************/ void OTA_ServerSendBlock(uint8_t *data) { uint8_t size; if (OTA_SERVER_STATE_READY != otaServer.state) return; if (otaServer.size > OTA_MAX_BLOCK_SIZE) size = OTA_MAX_BLOCK_SIZE; else size = otaServer.size; otaServer.state = OTA_SERVER_STATE_BLOCK_REQ_SENT; otaServer.size -= size; for (uint8_t i = 0; i < size; i++) otaServer.crc = otaCrcUpdateCcitt(otaServer.crc, data[i]); otaDataReq.dstAddr = otaServer.client; otaDataReq.size = sizeof(OtaBlockReqHeader_t) + size; otaDataReq.options = 0; otaCommand.block.commandId = OTA_BLOCK_REQ_COMMAND_ID; otaCommand.block.sessionId = otaServer.sessionId; otaCommand.block.crc = otaServer.crc; otaCommand.block.size = size; memcpy(otaCommand.block.data, data, size); NWK_DataReq(&otaDataReq); }
static void fieldAnswerChunkConfirm(NWK_DataReq_t *req) { if (hqVerboseOutput) { Serial.print(F(" Message confirmation - ")); } if (req->status == NWK_SUCCESS_STATUS) { if (hqVerboseOutput) { Serial.println(F("success")); } if (fieldCommandOutput.length() - fieldAnswerChunksAt > 100) { fieldAnswerChunksAt += 100; fieldAnswerChunk(); return; // don't free yet } } else { fieldAnswerRetries++; if (fieldAnswerRetries > 3) { if (hqVerboseOutput) { Serial.print(F("error: ")); Serial.println(req->status); } } else { if (hqVerboseOutput) { Serial.println(F("RETRY")); } NWK_DataReq(req); return; // don't free yet } } fieldAnswerTo = 0; // Free memory used by Stringbuffer fieldCommandOutput = (char*)NULL; }
/*************************************************************************//** *****************************************************************************/ static void appCmdDataRequest(AppCmdPendingTableEntry_t *entry) { appCmdInProgress = entry; appCmdDataReq.dstAddr = entry->addr; appCmdDataReq.data = &entry->payload; appCmdDataReq.size = entry->size; NWK_DataReq(&appCmdDataReq); }
static void announceConfirm(NWK_DataReq_t *req) { //if (hqVerboseOutput) speol("announce confirmed"); struct announceQ_t *next = announceQ->next; free(req->data); free(announceQ); announceQ = next; if (next) { NWK_DataReq(&(next->req)); } }
/*************************************************************************//** *****************************************************************************/ static AppStatus_t appProcessDataReq(AppCommandDataReq_t *req) { NWK_DataReq_t *dataReq = NULL; uint8_t size; for (uint8_t i = 0; i < APP_NUMBER_OF_REQUEST_BUFFERS; i++) { if (false == appRequestBuffer[i].busy) { appRequestBuffer[i].busy = true; appRequestBuffer[i].handle = req->handle; dataReq = &appRequestBuffer[i].req; break; } } if (NULL == dataReq) { return APP_STATUS_OUT_OF_MEMORY; } size = NWK_MAX_PAYLOAD_SIZE; #ifdef NWK_ENABLE_SECURITY if (req->options & NWK_OPT_ENABLE_SECURITY) { size -= NWK_SECURITY_MIC_SIZE; } #endif #ifdef NWK_ENABLE_MULTICAST if (req->options & NWK_OPT_MULTICAST) { size -= NWK_MULTICAST_HEADER_SIZE; } #endif if (req->size > size) { return APP_STATUS_INVALID_PARAMETERS; } dataReq->dstAddr = req->dstAddr; dataReq->dstEndpoint = req->dstEndpoint; dataReq->srcEndpoint = req->srcEndpoint; dataReq->options = req->options; #ifdef NWK_ENABLE_MULTICAST dataReq->memberRadius = req->memberRadius; dataReq->nonMemberRadius = req->nonMemberRadius; #endif dataReq->size = req->size; memcpy(dataReq->data, &req->data, req->size); dataReq->confirm = appDataConf; NWK_DataReq(dataReq); return APP_STATUS_SUCESS; }
void announceQSend(void){ if(!announceQ[0]) return; Scout.meshJoinGroup(announceQG[0]); announceReq.dstAddr = announceQG[0]; announceReq.dstEndpoint = 4; announceReq.srcEndpoint = Scout.getAddress(); announceReq.options = NWK_OPT_MULTICAST|NWK_OPT_ENABLE_SECURITY; announceReq.data = (uint8_t*)announceQ[0]; announceReq.size = strlen(announceQ[0]) + 1; // include NUL byte announceReq.confirm = announceConfirm; NWK_DataReq(&announceReq); }
/*************************************************************************//** *****************************************************************************/ static void otaRequestRetry(void) { if (0 == --otaServer.retries) { otaServer.state = OTA_SERVER_STATE_IDLE; OTA_ServerNotification(OTA_NO_RESPONSE_STATUS); } else { otaServer.state &= ~OTA_SERVER_STATE_WAIT_RESP_MASK; NWK_DataReq(&otaDataReq); } }
static void unitDataReq(void) { NWK_DataReq_t nwkDataReq; uint8_t appMsg[10] = "UnitTest\n\r"; nwkDataReq.dstAddr = 0; nwkDataReq.dstEndpoint = APP_ENDPOINT; nwkDataReq.srcEndpoint = APP_ENDPOINT; nwkDataReq.data = (uint8_t *)&appMsg; nwkDataReq.size = sizeof(appMsg); nwkDataReq.confirm = unitDataConf; NWK_DataReq(&nwkDataReq); NetworkStatusTimer.interval = 2000; NetworkStatusTimer.mode = SYS_TIMER_PERIODIC_MODE; NetworkStatusTimer.handler = NetworkStatusTimerHandler; SYS_TimerStart(&NetworkStatusTimer); }
static void appSendData(void) { if (appDataReqBusy) return; appDataReq.dstAddr = 1; appDataReq.dstEndpoint = APP_ENDPOINT; appDataReq.srcEndpoint = APP_ENDPOINT; appDataReq.options = NWK_OPT_ENABLE_SECURITY; appDataReq.data = &appPingCounter; appDataReq.size = sizeof(appPingCounter); appDataReq.confirm = appSendDataConf; NWK_DataReq(&appDataReq); appPingCounter++; appDataReqBusy = true; }
static void appSendData(void){ if (appDataReqBusy || 0 == appUartBufferPtr) return; memcpy(appDataReqBuffer, appUartBuffer, appUartBufferPtr); appDataReq.dstAddr = 1-APP_ADDR; appDataReq.dstEndpoint = APP_ENDPOINT; appDataReq.srcEndpoint = APP_ENDPOINT; appDataReq.options = NWK_OPT_ENABLE_SECURITY; appDataReq.data = appDataReqBuffer; appDataReq.size = appUartBufferPtr; appDataReq.confirm = appDataConf; NWK_DataReq(&appDataReq); appUartBufferPtr = 0; appDataReqBusy = true; }
void PinoccioScoutHandler::announce(uint16_t group, char *message) { if (hqVerboseOutput) { sp("announcing to "); sp(group); sp(" "); speol(message); } // when lead scout, shortcut if (Scout.isLeadScout()) { leadAnnouncementSend(group, Scout.getAddress(), message); } char *data = strdup(message); if (!data) { return; } struct announceQ_t *r = (struct announceQ_t*)malloc(sizeof(struct announceQ_t)); if (!r) { return; } Scout.meshJoinGroup(group); // must be joined to send memset(r, 0, sizeof(struct announceQ_t)); r->req.dstAddr = group; r->req.dstEndpoint = 4; r->req.srcEndpoint = Scout.getAddress(); r->req.options = NWK_OPT_MULTICAST|NWK_OPT_ENABLE_SECURITY; r->req.data = (uint8_t*)data; r->req.size = strlen(data)+1; r->req.confirm = announceConfirm; if (!announceQ) { announceQ = r; NWK_DataReq(&(r->req)); } else { struct announceQ_t *last = announceQ; while(last->next) last = last->next; last->next = r; } }
void timeoutTimerHandler(SYS_Timer_t *timer) { if (!NWK_Busy()) { frame[0] = 0x06; frame[1] = 0xBB; frame[2] = 0xBB; frame[3] = 0xBB; frame[4] = 0xBB; nwkDataReq.dstAddr = 0x389C; nwkDataReq.dstEndpoint = 1; nwkDataReq.srcEndpoint = 1; nwkDataReq.size = sizeof(frame); nwkDataReq.data = frame; nwkDataReq.confirm = appDataConf; NWK_DataReq(&nwkDataReq); } startTimeoutTimer(); }
/*************************************************************************//** *****************************************************************************/ static bool appResponderDataInd(NWK_DataInd_t *ind) { NWK_DataReq_t *dataReq = NULL; uint8_t options = 0; if (ind->data[0] == 0xff) { return true; } for (uint8_t i = 0; i < APP_NUMBER_OF_REQUEST_BUFFERS; i++) { if (false == appRequestBuffer[i].busy) { appRequestBuffer[i].busy = true; dataReq = &appRequestBuffer[i].req; break; } } if (NULL == dataReq) { return false; } options |= (ind->options & NWK_IND_OPT_ACK_REQUESTED) ? NWK_OPT_ACK_REQUEST : 0; options |= (ind->options & NWK_IND_OPT_SECURED) ? NWK_OPT_ENABLE_SECURITY : 0; dataReq->dstAddr = ind->srcAddr; dataReq->dstEndpoint = ind->srcEndpoint; dataReq->srcEndpoint = ind->dstEndpoint; dataReq->options = options; dataReq->size = ind->size; memcpy(dataReq->data, ind->data, ind->size); dataReq->confirm = appResponderDataConf; NWK_DataReq(dataReq); return true; }
/*************************************************************************//** *****************************************************************************/ void OTA_ServerStartUpdrade(uint16_t addr, uint32_t size) { SYS_TimerStop(&otaResponseTimer); SYS_TimerStop(&otaFrameSpacingTimer); otaServer.state = OTA_SERVER_STATE_START_REQ_SENT; otaServer.sessionId = rand(); otaServer.client = addr; otaServer.size = size; otaServer.crc = 0; otaServer.retries = OTA_MAX_RETRIES; otaDataReq.dstAddr = addr; otaDataReq.size = sizeof(OtaStartReqCommand_t); otaDataReq.options = NWK_OPT_ACK_REQUEST; otaCommand.start.commandId = OTA_START_REQ_COMMAND_ID; otaCommand.start.sessionId = otaServer.sessionId; otaCommand.start.size = size; NWK_DataReq(&otaDataReq); }
static void fieldAnswerChunk() { int len = fieldCommandOutput.length() - fieldAnswerChunksAt; if (len > 100) { len = 100; } else { len++; // null terminator at end } fieldAnswerReq.dstAddr = fieldAnswerTo; fieldAnswerReq.dstEndpoint = 3; fieldAnswerReq.srcEndpoint = 2; fieldAnswerReq.options = NWK_OPT_ENABLE_SECURITY; fieldAnswerReq.data = (uint8_t*)fieldCommandOutput.c_str() + fieldAnswerChunksAt; fieldAnswerReq.size = len; fieldAnswerReq.confirm = fieldAnswerChunkConfirm; NWK_DataReq(&fieldAnswerReq); if (hqVerboseOutput) { Serial.print(fieldAnswerTo); Serial.print(F(" len ")); Serial.print(len); Serial.println(F("->chunk")); } }
static void fieldAnswerChunk() { int len = strlen(fieldAnswerChunks+fieldAnswerChunksAt); if (len > 100) { len = 100; } else { len++; // null terminator at end } fieldAnswerReq.dstAddr = fieldAnswerTo; fieldAnswerReq.dstEndpoint = 3; fieldAnswerReq.srcEndpoint = 2; fieldAnswerReq.options = NWK_OPT_ENABLE_SECURITY; fieldAnswerReq.data = (uint8_t*)(fieldAnswerChunks + fieldAnswerChunksAt); fieldAnswerReq.size = len; fieldAnswerReq.confirm = fieldAnswerChunkConfirm; NWK_DataReq(&fieldAnswerReq); if (hqVerboseOutput) { sp(fieldAnswerTo); sp(" len "); sp(len); speol("->chunk"); } }
int main(void) { SYS_Init(); // Init Atmel Lightweight Mesh stack SYS_TaskHandler(); // Call the system task handler once before we configure the radio NWK_SetAddr(eeprom_read_word((uint16_t*)0)); NWK_SetPanId(0); // Default PAN ID will be 0, can be changed using the set PAN command PHY_SetChannel(APP_CHANNEL); //NWK_SetSecurityKey(APP_SECURITY_KEY); PHY_SetRxState(true); NWK_OpenEndpoint(APP_ENDPOINT, rfReceivePacket); PHY_SetTxPower(0); // Seed the pseudorandom number generator srand(eeprom_read_word((uint16_t*)0)); // Read eeprom data eeprom_read_block(&deviceCalibration, (void*)8, sizeof(deviceCalibration)); if (eeprom_read_byte((uint8_t*)26)) { // There is valid data in the network information struct eeprom_read_block(baseStationList, (void*)27, sizeof(struct baseStation)); uint8_t ch = 17; while ((baseStationList[0].name[ch] == ' ') || (baseStationList[0].name[ch] == '\0') || (baseStationList[0].name[ch] == 0xFF)) { baseStationList[0].name[ch] = ' '; ch -= 1; } baseStationList[0].nameLen = ch+1; baseStationListLength += 1; for (int cnt = 0; cnt < BASESTATION_LIST_SIZE; cnt++) { baseStationList[cnt].name[16] = ' '; baseStationList[cnt].name[17] = ' '; } sendConnectionRequest(0, &deviceCalibration); } initDataAck(); initLCD(display_cmd_buffer, 64); initUI(); TCCR0B |= (1<<CS01); TCCR3B |= (1<<CS32) | (1<<CS30); sei(); startDataAck(); while (1) { SYS_TaskHandler(); if (receivedDataRequest) { handleDataRequest(); receivedDataRequest = false; } if (receivedColdStart) { if (connectedBaseStation == -1) sendConnectionRequest(0, &deviceCalibration); else sendConnectionRequest(connectedBaseStation, &deviceCalibration); ui_baseStationDisconnected(); receivedColdStart = false; } updateUI(); if (sampleCount > 40000) { if (dataPacket.sampleCount != 0) removeSamples(&dataPacket); // If the last transmitted data has not been acked then first remove the old data. getData(&dataPacket); // Sample new data ui_updatePowerValues(&dataPacket); // Update display removeSamples(&dataPacket); // Get rid of these samples now } if (TCNT0 > 80) { serviceLCD(); TCNT0 = 0; } TCCR3B &= ~((1<<CS32) | (1<<CS30)); if (TCNT3 != 0) { for (uint8_t cnt = 0; cnt < DATA_REQ_BUFFER_CNT; cnt++) { if (dataReqBusy[cnt] && (retransmit_time[cnt] != 0)) { if (retransmit_time[cnt] <= TCNT3) { NWK_DataReq(&(nwkPacket[cnt])); retransmit_time[cnt] = 0; } else retransmit_time[cnt] -= TCNT3; } } } TCNT3 = 0; TCCR3B |= (1<<CS32) | (1<<CS30); } }