/** \brief Free all the packet buffers owned by a specific module. \param owner The identifier of the component, taken in COMPONENT_*. */ void openqueue_removeAllOwnedBy(uint8_t owner) { uint8_t i; uint8_t count=0; INTERRUPT_DECLARATION(); DISABLE_INTERRUPTS(); for (i=0;i<QUEUELENGTH;i++){ if (openqueue_vars.queue[i].owner==owner) { count++; openqueue_reset_entry(&(openqueue_vars.queue[i])); } } ENABLE_INTERRUPTS(); #if ((ENABLE_DEBUG_RFF ==1) && (DBG_OPENQUEUE == 1)) { uint8_t pos=0; rffbuf[pos++]= RFF_OPENQUEUE_FREE; rffbuf[pos++]= 0x03; rffbuf[pos++]= owner; rffbuf[pos++]= count; openserial_printStatus(STATUS_RFF,(uint8_t*)&rffbuf,pos); } #endif }
bool debugPrint_neighbors() { debugNeighborEntry_t temp; neighbors_vars.debugRow=(neighbors_vars.debugRow+1)%MAXNUMNEIGHBORS; temp.row=neighbors_vars.debugRow; temp.neighborEntry=neighbors_vars.neighbors[neighbors_vars.debugRow]; openserial_printStatus(STATUS_NEIGHBORS,(uint8_t*)&temp,sizeof(debugNeighborEntry_t)); return TRUE; }
/** \brief Trigger this module to print status information, over serial. debugPrint_* functions are used by the openserial module to continuously print status information about several modules in the OpenWSN stack. \returns TRUE if this function printed something, FALSE otherwise. */ bool debugPrint_myDAGrank() { uint16_t output; output = 0; output = neighbors_getMyDAGrank(); openserial_printStatus(STATUS_DAGRANK,(uint8_t*)&output,sizeof(uint16_t)); return TRUE; }
/** \brief Trigger this module to print status information, over serial. debugPrint_* functions are used by the openserial module to continuously print status information about several modules in the OpenWSN stack. \returns TRUE if this function printed something, FALSE otherwise. */ bool debugPrint_backoff() { uint8_t temp[2]; temp[0] = schedule_vars.backoffExponent; temp[1] = schedule_vars.backoff; openserial_printStatus(STATUS_BACKOFF, (uint8_t*)&temp, sizeof(temp)); return TRUE; }
bool openserial_debugPrint(){ uint16_t temp_buffer[2]; __disable_interrupt(); temp_buffer[0] = openserial_output_buffer_index_write; temp_buffer[1] = openserial_output_buffer_index_read; __enable_interrupt(); openserial_printStatus(STATUS_SERIALIOP_OUTPUTBUFFERINDEXES,(uint8_t*)temp_buffer,sizeof(temp_buffer)); return TRUE; }
bool debugPrint_outBufferIndexes() { uint16_t temp_buffer[2]; INTERRUPT_DECLARATION(); DISABLE_INTERRUPTS(); temp_buffer[0] = openserial_vars.output_buffer_index_write; temp_buffer[1] = openserial_vars.output_buffer_index_read; ENABLE_INTERRUPTS(); openserial_printStatus(STATUS_OUTBUFFERINDEXES,(uint8_t*)temp_buffer,sizeof(temp_buffer)); return TRUE; }
bool debugPrint_schedule() { debugScheduleEntry_t temp; schedule_vars.debugPrintRow = (schedule_vars.debugPrintRow+1)%MAXACTIVESLOTS; temp.row = schedule_vars.debugPrintRow; temp.scheduleEntry = schedule_vars.scheduleBuf[schedule_vars.debugPrintRow]; openserial_printStatus(STATUS_SCHEDULE, (uint8_t*)&temp, sizeof(debugScheduleEntry_t)); return TRUE; }
/** \brief Trigger this module to print status information, over serial. debugPrint_* functions are used by the openserial module to continuously print status information about several modules in the OpenWSN stack. \returns TRUE if this function printed something, FALSE otherwise. */ bool debugPrint_queue() { debugOpenQueueEntry_t output[QUEUELENGTH]; uint8_t i; for (i=0;i<QUEUELENGTH;i++) { output[i].creator = openqueue_vars.queue[i].creator; output[i].owner = openqueue_vars.queue[i].owner; } openserial_printStatus(STATUS_QUEUE,(uint8_t*)&output,QUEUELENGTH*sizeof(debugOpenQueueEntry_t)); return TRUE; }
/** \brief Trigger this module to print status information, over serial. debugPrint_* functions are used by the openserial module to continuously print status information about several modules in the OpenWSN stack. \returns TRUE if this function printed something, FALSE otherwise. */ bool debugPrint_id() { debugIDManagerEntry_t output; output.isDAGroot = idmanager_vars.isDAGroot; output.isBridge = idmanager_vars.isBridge; output.my16bID = idmanager_vars.my16bID; output.my64bID = idmanager_vars.my64bID; output.myPANID = idmanager_vars.myPANID; output.myPrefix = idmanager_vars.myPrefix; openserial_printStatus(STATUS_ID,(uint8_t*)&output,sizeof(debugIDManagerEntry_t)); return TRUE; }
/** \brief Trigger this module to print status information, over serial. debugPrint_* functions are used by the openserial module to continuously print status information about several modules in the OpenWSN stack. \returns TRUE if this function printed something, FALSE otherwise. */ bool debugPrint_id() { debugIDManagerEntry_t output; output.isDAGroot = idmanager_vars.isDAGroot; memcpy(output.myPANID,idmanager_vars.myPANID.panid,2); memcpy(output.my16bID,idmanager_vars.my16bID.addr_16b,2); memcpy(output.my64bID,idmanager_vars.my64bID.addr_64b,8); memcpy(output.myPrefix,idmanager_vars.myPrefix.prefix,8); openserial_printStatus(STATUS_ID,(uint8_t*)&output,sizeof(debugIDManagerEntry_t)); return TRUE; }
/** \brief Trigger this module to print status information, over serial. debugPrint_* functions are used by the openserial module to continuously print status information about several modules in the OpenWSN stack. \returns TRUE if this function printed something, FALSE otherwise. */ bool debugPrint_kaPeriod() { uint16_t output; output = sixtop_vars.kaPeriod; openserial_printStatus( STATUS_KAPERIOD, (uint8_t*)&output, sizeof(output) ); return TRUE; }
owerror_t cwellknown_receive(OpenQueueEntry_t* msg, coap_header_iht* coap_header, coap_option_iht* coap_incomingOptions, coap_option_iht* coap_outgoingOptions, uint8_t* coap_outgoingOptionsLen) { owerror_t outcome; switch(coap_header->Code) { case COAP_CODE_REQ_GET: // reset packet payload msg->payload = &(msg->packet[127]); msg->length = 0; // have CoAP module write links to all resources opencoap_writeLinks(msg,COMPONENT_CWELLKNOWN); // add return option cwellknown_vars.medType = COAP_MEDTYPE_APPLINKFORMAT; coap_outgoingOptions[0].type = COAP_OPTION_NUM_CONTENTFORMAT; coap_outgoingOptions[0].length = 1; coap_outgoingOptions[0].pValue = &cwellknown_vars.medType; *coap_outgoingOptionsLen = 1; #if ENABLE_DEBUG_RFF { uint8_t pos=0; rffbuf[pos++]= RFF_COMPONENT_OPENCOAP_TX; rffbuf[pos++]= RFF_COMPONENT_OPENCOAP_TX; rffbuf[pos++]= RFF_COMPONENT_OPENCOAP_TX; rffbuf[pos++]= RFF_COMPONENT_OPENCOAP_TX; rffbuf[pos++]= coap_outgoingOptions[0].length; rffbuf[pos++]= coap_outgoingOptions[0].type; rffbuf[pos++]= COAP_CODE_RESP_CONTENT; openserial_printStatus(STATUS_RFF,(uint8_t*)&rffbuf,pos); } #endif // set the CoAP header coap_header->Code = COAP_CODE_RESP_CONTENT; outcome = E_SUCCESS; break; default: outcome = E_FAIL; break; } return outcome; }
/** \brief Free a previously-allocated packet buffer. \param pkt A pointer to the previsouly-allocated packet buffer. \returns E_SUCCESS when the freeing was succeful. \returns E_FAIL when the module could not find the specified packet buffer. */ owerror_t openqueue_freePacketBuffer(OpenQueueEntry_t* pkt) { uint8_t i; uint8_t *pucAux = (uint8_t *) pkt; uint8_t creator; INTERRUPT_DECLARATION(); DISABLE_INTERRUPTS(); for (i=0;i<QUEUELENGTH;i++) { if (&openqueue_vars.queue[i]==pkt) { if (openqueue_vars.queue[i].owner==COMPONENT_NULL) { // log the error openserial_printCritical(COMPONENT_OPENQUEUE,ERR_FREEING_UNUSED, (errorparameter_t)0, (errorparameter_t)0); } creator = openqueue_vars.queue[i].creator; openqueue_reset_entry(&(openqueue_vars.queue[i])); ENABLE_INTERRUPTS(); #if ((ENABLE_DEBUG_RFF ==1) && (DBG_OPENQUEUE == 1)) { uint8_t pos=0; rffbuf[pos++]= RFF_OPENQUEUE_FREE; rffbuf[pos++]= 0x01; rffbuf[pos++]= creator; rffbuf[pos++]= i; rffbuf[pos++]= pucAux++; rffbuf[pos++]= pucAux++; rffbuf[pos++]= pucAux++; rffbuf[pos++]= pucAux; openserial_printStatus(STATUS_RFF,(uint8_t*)&rffbuf,pos); } #endif return E_SUCCESS; } } // log the error openserial_printCritical(COMPONENT_OPENQUEUE,ERR_FREEING_ERROR, (errorparameter_t)0, (errorparameter_t)0); ENABLE_INTERRUPTS(); return E_FAIL; }
/** \brief Request a new (free) packet buffer. Component throughout the protocol stack can call this function is they want to get a new packet buffer to start creating a new packet. \note Once a packet has been allocated, it is up to the creator of the packet to free it using the openqueue_freePacketBuffer() function. \returns A pointer to the queue entry when it could be allocated, or NULL when it could not be allocated (buffer full or not synchronized). */ OpenQueueEntry_t* openqueue_getFreePacketBuffer(uint8_t creator) { uint8_t i; INTERRUPT_DECLARATION(); DISABLE_INTERRUPTS(); // refuse to allocate if we're not in sync if (ieee154e_isSynch()==FALSE && creator > COMPONENT_IEEE802154E){ ENABLE_INTERRUPTS(); return NULL; } // if you get here, I will try to allocate a buffer for you // walk through queue and find free entry for (i=0;i<QUEUELENGTH;i++) { if (openqueue_vars.queue[i].owner==COMPONENT_NULL) { openqueue_vars.queue[i].creator=creator; openqueue_vars.queue[i].owner=COMPONENT_OPENQUEUE; ENABLE_INTERRUPTS(); #if ((ENABLE_DEBUG_RFF ==1) && (DBG_OPENQUEUE == 1)) { uint8_t *pucAux = (uint8_t *) &openqueue_vars.queue[i]; uint8_t pos=0; rffbuf[pos++]= RFF_OPENQUEUE_ALLOC; rffbuf[pos++]= 0x01; rffbuf[pos++]= creator; rffbuf[pos++]= i; rffbuf[pos++]= pucAux++; rffbuf[pos++]= pucAux++; rffbuf[pos++]= pucAux++; rffbuf[pos++]= pucAux; openserial_printStatus(STATUS_RFF,(uint8_t*)&rffbuf,pos); } #endif return &openqueue_vars.queue[i]; } } ENABLE_INTERRUPTS(); return NULL; }
/** \brief Trigger this module to print status information, over serial. debugPrint_* functions are used by the openserial module to continuously print status information about several modules in the OpenWSN stack. \returns TRUE if this function printed something, FALSE otherwise. */ bool debugPrint_outBufferIndexes(void) { uint16_t temp_buffer[2]; INTERRUPT_DECLARATION(); //<<<<<<<<<<<<<<<<<<<<<<< DISABLE_INTERRUPTS(); temp_buffer[0] = openserial_vars.outputBufIdxW; temp_buffer[1] = openserial_vars.outputBufIdxR; ENABLE_INTERRUPTS(); //>>>>>>>>>>>>>>>>>>>>>>> openserial_printStatus( STATUS_OUTBUFFERINDEXES, (uint8_t*)temp_buffer, sizeof(temp_buffer) ); return TRUE; }
/** \brief Trigger this module to print status information, over serial. debugPrint_* functions are used by the openserial module to continuously print status information about several modules in the OpenWSN stack. \returns TRUE if this function printed something, FALSE otherwise. */ bool debugPrint_schedule() { debugScheduleEntry_t temp; schedule_vars.debugPrintRow = (schedule_vars.debugPrintRow+1)%MAXACTIVESLOTS; temp.row = schedule_vars.debugPrintRow; //copy element by element to the struct that will be serialized. we don't want to sent the pointer through the serial port. temp.scheduleEntry.channelOffset = schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].channelOffset; temp.scheduleEntry.numRx = schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].numRx; temp.scheduleEntry.numTx=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].numTx; temp.scheduleEntry.numTxACK=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].numTxACK; temp.scheduleEntry.lastUsedAsn=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].lastUsedAsn; temp.scheduleEntry.neighbor=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].neighbor; temp.scheduleEntry.shared=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].shared; temp.scheduleEntry.slotOffset=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].slotOffset; temp.scheduleEntry.type=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].type; openserial_printStatus(STATUS_SCHEDULE, (uint8_t*)&temp, sizeof(debugScheduleEntry_t)); return TRUE; }
owerror_t osens_frm_receive(OpenQueueEntry_t* msg, coap_header_iht* coap_header, coap_option_iht* coap_options) { owerror_t outcome = E_FAIL; //uint8_t n = 0; uint8_t buf[50]; uint8_t *pucbuf; uint8_t *pucAux; uint8_t optnum = 0; uint8_t optidx = 2; uint8_t index=0; uint8_t len=0; uint8_t type=0; uint8_t j=0; switch (coap_header->Code) { case COAP_CODE_REQ_GET: // reset packet payload msg->payload = &(msg->packet[127]); msg->length = 0; //=== prepare CoAP response - esta resposta eh retirada do comando info if (((coap_options[1].pValue[0] == 'i') || (coap_options[1].pValue[0] == 'I')) && (coap_options[1].type == COAP_OPTION_NUM_URIPATH)) { // stack name and version packetfunctions_reserveHeaderSize(msg,1); msg->payload[0] = '\n'; packetfunctions_reserveHeaderSize(msg,sizeof(infoStackName)-1+5); memcpy(&msg->payload[0],&infoStackName,sizeof(infoStackName)-1); msg->payload[sizeof(infoStackName)-1+5-5] = '0'+OPENWSN_VERSION_MAJOR; msg->payload[sizeof(infoStackName)-1+5-4] = '.'; msg->payload[sizeof(infoStackName)-1+5-3] = '0'+OPENWSN_VERSION_MINOR; msg->payload[sizeof(infoStackName)-1+5-2] = '.'; msg->payload[sizeof(infoStackName)-1+5-1] = '0'+OPENWSN_VERSION_PATCH; // set the CoAP header coap_header->Code = COAP_CODE_RESP_CONTENT; outcome = E_SUCCESS; } else if (((coap_options[1].pValue[0] == 'd') || (coap_options[1].pValue[0] == 'd')) && (coap_options[1].type == COAP_OPTION_NUM_URIPATH)) { uint8_t *pucaux = (uint8_t *) &osens_frm.frameID; // stack name and version packetfunctions_reserveHeaderSize(msg,4); /* msg->payload[0] = '0' + *(pucaux+1); msg->payload[1] = '0' + *(pucaux+0); msg->payload[2] = '0' + osens_frm.header; msg->payload[3] = '0' + osens_frm.framestatus; */ msg->payload[0] = *(pucaux+1); msg->payload[1] = *(pucaux+0); msg->payload[2] = osens_frm.header; msg->payload[3] = osens_frm.framestatus; // set the CoAP header coap_header->Code = COAP_CODE_RESP_CONTENT; outcome = E_SUCCESS; } break; case COAP_CODE_REQ_PUT: // reset packet payload msg->payload = &(msg->packet[127]); msg->length = 0; if (((coap_options[1].pValue[0] == 'e') || (coap_options[1].pValue[0] == 'E')) && (coap_options[1].type == COAP_OPTION_NUM_URIPATH)) { //erase the flash firmware new area osens_frm.flashnewcmd = iFlashErase; coap_header->Code = COAP_CODE_RESP_VALID; outcome = E_SUCCESS; #if ENABLE_DEBUG_RFF { uint8_t pos=0; rffbuf[pos++]= RFF_COMPONENT_OPENCOAP_TX; rffbuf[pos++]= 0x81; rffbuf[pos++]= COAP_CODE_RESP_VALID; openserial_printStatus(STATUS_RFF,(uint8_t*)&rffbuf,pos); } #endif } else { //get number of sections optnum = (coap_options[1].pValue[0] - 0x30) + 2; if ( (coap_options[1].length == 1) && (coap_options[1].type == COAP_OPTION_NUM_URIPATH) && (optnum > 0)) { osens_frm.frameLen = 0; //Leitura do buffer da mensagem...o restante da mensagem é codificado 2bytes hexadecimal (AA BB 01 03...) if (optnum < 10) { //read payload pucbuf = &buf[0]; for (optidx=2;optidx<(optnum+2); optidx++){ pucbuf = decode_framehexa(coap_options[optidx].pValue,coap_options[optidx].length,pucbuf); } } #if ENABLE_DEBUG_RFF { uint8_t pos=0; uint8_t j=0; rffbuf[pos++]= RFF_COMPONENT_OPENCOAP_TX; rffbuf[pos++]= 0x82; rffbuf[pos++]= 0x82; rffbuf[pos++]= 0x82; rffbuf[pos++]= optnum; for (j=0;j<(osens_frm.frameLen);j++){ rffbuf[pos++] = buf[j]; } openserial_printStatus(STATUS_RFF,(uint8_t*)&rffbuf,pos); } #endif osens_frame_parser(buf); } // set the CoAP header coap_header->Code = COAP_CODE_RESP_VALID; outcome = E_SUCCESS; } break; default: outcome = E_FAIL; break; } return outcome; }
owerror_t osens_val_receive( OpenQueueEntry_t* msg, coap_header_iht* coap_header, coap_option_iht* coap_options ) { owerror_t outcome = E_FAIL; uint8_t n; static uint8_t buf[128]; uint8_t *pbuf = &buf[0]; uint8_t index; switch (coap_header->Code) { case COAP_CODE_REQ_GET: // reset packet payload msg->payload = &(msg->packet[127]); msg->length = 0; // /s if (((coap_options[1].length == 0) && (coap_options[1].type == COAP_OPTION_NUM_URIPATH)) || (coap_options[1].type != COAP_OPTION_NUM_URIPATH)) { } // /s/1 or /s/12 else if(((coap_options[1].length == 1 || coap_options[1].length == 2)) && (coap_options[1].type == COAP_OPTION_NUM_URIPATH)) { osens_point_t pt; #if (MYLINKXS_LIGHT_CONTROL == 0) if(coap_options[1].length == 2) index = (coap_options[1].pValue[0] - 0x30) * 10 + (coap_options[1].pValue[1] - 0x30); else index = coap_options[1].pValue[0] - 0x30; if(osens_get_point(index,&pt)) { pbuf = insert_str(pbuf,(uint8_t*)"{\"v\":",5,0); pbuf = insert_point_val(pbuf,&pt); pbuf = insert_str(pbuf,(uint8_t*)"}",1,0); #if (ENABLE_DEBUG_RFF == 1) && (DBG_APP_1 == 1) uint8_t pos=0; uint8_t *paux; rffbuf[pos++]= 0x85; rffbuf[pos++]= index; paux = (uint8_t*) &pt.value.fp32; rffbuf[pos++]= *paux++; rffbuf[pos++]= *paux++; rffbuf[pos++]= *paux++; rffbuf[pos++]= *paux++; paux = (uint8_t*) &pbuf[0]; rffbuf[pos++]= *paux++; rffbuf[pos++]= *paux++; rffbuf[pos++]= *paux++; rffbuf[pos++]= *paux++; openserial_printStatus(STATUS_RFF,(uint8_t*)&rffbuf,pos); #endif } else pbuf = insert_str(pbuf,(uint8_t*)"{}",2,0); #else //QUANDO TRABALHANDO COM A LAMPADA ESTAVA ESTE OUTRO CODIGO //TODO!!! DEIXAR O CODIGO UNICO pt.type = OSENS_DT_U8; pt.value.u8 = light_get_value(); pbuf = insert_str(pbuf,(uint8_t*)"{\"v\":",5,0); pbuf = insert_point_val(pbuf,&pt); pbuf = insert_str(pbuf,(uint8_t*)"}",1,0); #endif outcome = E_SUCCESS; } if(outcome == E_SUCCESS) { n = ((uint32_t)pbuf - (uint32_t)buf); packetfunctions_reserveHeaderSize(msg, 1 + n); msg->payload[0] = COAP_PAYLOAD_MARKER; memcpy(&msg->payload[1], buf, n); coap_header->Code = COAP_CODE_RESP_CONTENT; } break; case COAP_CODE_REQ_PUT: // reset packet payload msg->payload = &(msg->packet[127]); msg->length = 0; #if (DEBUG_LOG_RIT == 1) { uint8_t pos=0; rffbuf[pos++]= RFF_COMPONENT_STORMCOAP_TX; rffbuf[pos++]= 0x01; rffbuf[pos++]= coap_options[1].length; rffbuf[pos++]= coap_options[2].length; rffbuf[pos++]= coap_options[1].type; rffbuf[pos++]= coap_options[2].type; //rffbuf[pos++]= sensor_points.points[0].value.value.u8; openserial_printStatus(STATUS_RFF,(uint8_t*)&rffbuf,pos); } #endif // /s/2/-12.45 or /s/12/12.45 if((coap_options[1].length == 1 || coap_options[1].length == 2) && (coap_options[2].length > 0) && (coap_options[1].type == COAP_OPTION_NUM_URIPATH) && (coap_options[2].type == COAP_OPTION_NUM_URIPATH)) { #if 0 uint8_t index; double number; osens_point_t pt; if(coap_options[1].length == 2) index = (coap_options[1].pValue[0] - 0x30) * 10 + (coap_options[1].pValue[1] - 0x30); else index = coap_options[1].pValue[0] - 0x30; number = decode_number(coap_options[2].pValue,coap_options[2].length); pt.type = osens_get_ptype(index); if(pt.type >= 0) { set_point_val(&pt,number); if(osens_set_pvalue(index,&pt)) { // set the CoAP header coap_header->Code = COAP_CODE_RESP_CHANGED; outcome = E_SUCCESS; } } #else // switch on the light pulse (50 ms) light_on(); opentimers_start(1000,TIMER_ONESHOT,TIME_MS,light_timer); #endif } break; default: outcome = E_FAIL; break; } return outcome; }