void udprand_task(){ OpenQueueEntry_t* pkt; // don't run if not synch if (ieee154e_isSynch() == FALSE) return; // don't run on dagroot if (idmanager_getIsDAGroot()) { opentimers_stop(udprand_vars.timerId); return; } //prepare packet pkt = openqueue_getFreePacketBuffer(COMPONENT_UDPRAND); if (pkt==NULL) { openserial_printError(COMPONENT_UDPRAND,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); return; } pkt->creator = COMPONENT_UDPRAND; pkt->owner = COMPONENT_UDPRAND; pkt->l4_protocol = IANA_UDP; pkt->l4_sourcePortORicmpv6Type = WKP_UDP_RAND; pkt->l4_destination_port = WKP_UDP_RAND; pkt->l3_destinationAdd.type = ADDR_128B; memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_motedata,16); packetfunctions_reserveHeaderSize(pkt,2); ((uint8_t*)pkt->payload)[0] = openrandom_get16b()%0xff; ((uint8_t*)pkt->payload)[1] = openrandom_get16b()%0xff; //send packet if ((openudp_send(pkt))==E_FAIL) { openqueue_freePacketBuffer(pkt); } }
/** \brief Send a CoAP request. This function is called by a CoAP resource when it wants to send some data. This function is NOT called for a response. \param[in] msg The message to be sent. This messages should not contain the CoAP header. \param[in] type The CoAP type of the message. \param[in] code The CoAP code of the message. \param[in] TKL The Token Length of the message. \param[out] descSender A pointer to the description of the calling CoAP resource. \post After returning, this function will have written the messageID and TOKEN used in the descSender parameter. \return The outcome of sending the packet. */ owerror_t opencoap_send( OpenQueueEntry_t* msg, coap_type_t type, coap_code_t code, uint8_t TKL, coap_resource_desc_t* descSender ) { // pick a new (global) messageID opencoap_vars.messageID = openrandom_get16b(); // take ownership over the packet msg->owner = COMPONENT_OPENCOAP; // fill in packet metadata msg->l4_sourcePortORicmpv6Type = WKP_UDP_COAP; // pre-pend CoAP header (version,type,TKL,code,messageID,Token) packetfunctions_reserveHeaderSize(msg,5); msg->payload[0] = (COAP_VERSION << 6) | (type << 4) | (TKL << 0); msg->payload[1] = code; msg->payload[2] = (opencoap_vars.messageID>>8) & 0xff; msg->payload[3] = (opencoap_vars.messageID>>0) & 0xff; msg->payload[4] = COAP_TOKEN; // indicate the messageID used to the sender descSender->messageID = opencoap_vars.messageID; descSender->token = COAP_TOKEN; return openudp_send(msg); }
/** \brief Indicate the transmission of a packet. */ void schedule_indicateTx(asn_t* asnTimestamp, bool succesfullTx) { INTERRUPT_DECLARATION(); DISABLE_INTERRUPTS(); // increment usage statistics if (schedule_vars.currentScheduleEntry->numTx==0xFF) { schedule_vars.currentScheduleEntry->numTx/=2; schedule_vars.currentScheduleEntry->numTxACK/=2; } schedule_vars.currentScheduleEntry->numTx++; if (succesfullTx==TRUE) { schedule_vars.currentScheduleEntry->numTxACK++; } // update last used timestamp memcpy(&schedule_vars.currentScheduleEntry->lastUsedAsn, asnTimestamp, sizeof(asn_t)); // update this slot's backoff parameters if (succesfullTx==TRUE) { // reset backoffExponent schedule_vars.currentScheduleEntry->backoffExponent = MINBE-1; // reset backoff schedule_vars.currentScheduleEntry->backoff = 0; } else { // increase the backoffExponent if (schedule_vars.currentScheduleEntry->backoffExponent<MAXBE) { schedule_vars.currentScheduleEntry->backoffExponent++; } // set the backoff to a random value in [0..2^BE] schedule_vars.currentScheduleEntry->backoff = openrandom_get16b()%(1<<schedule_vars.currentScheduleEntry->backoffExponent); } ENABLE_INTERRUPTS(); }
/** \brief Initialize this module. */ void opencoap_init() { // initialize the resource linked list opencoap_vars.resources = NULL; // initialize the messageID opencoap_vars.messageID = openrandom_get16b(); }
void res_init() { res_vars.periodMaintenance = 1700+(openrandom_get16b()&0xff); // fires every 1 sec on average //res_vars.periodMaintenance = 850+(openrandom_get16b()&0xff); res_vars.busySending = FALSE; res_vars.dsn = 0; res_vars.MacMgtTaskCounter = 0; res_vars.timerId = opentimers_start(res_vars.periodMaintenance, TIMER_PERIODIC,TIME_MS, res_timer_cb); }
/** \brief Called when receiving a CoAP PUT to set a timer. \param[in] period The period used for reporting data. \param[in] id Resource id in sensors array. */ void csensors_setPeriod(uint32_t period, uint8_t id) { uint32_t old_period; old_period = csensors_vars.csensors_resource[id].period; if (period>0) { csensors_vars.csensors_resource[id].period = period; if (opentimers_isRunning(csensors_vars.csensors_resource[id].timerId)) { opentimers_scheduleIn( csensors_vars.csensors_resource[id].timerId, (uint32_t)((period*openrandom_get16b())/0xffff), TIME_MS, TIMER_ONESHOT, csensors_timer_cb ); if (old_period==0) { opentimers_scheduleIn( csensors_vars.csensors_resource[id].timerId, (uint32_t)((period*openrandom_get16b())/0xffff), TIME_MS, TIMER_ONESHOT, csensors_timer_cb ); } } else { csensors_vars.csensors_resource[id].timerId = opentimers_create(TIMER_GENERAL_PURPOSE, TASKPRIO_COAP); opentimers_scheduleIn( csensors_vars.csensors_resource[id].timerId, (uint32_t)((period*openrandom_get16b())/0xffff), TIME_MS, TIMER_ONESHOT, csensors_timer_cb ); } } else { if (opentimers_isRunning(csensors_vars.csensors_resource[id].timerId) && (old_period != 0)) { csensors_vars.csensors_resource[id].period = period; opentimers_cancel(csensors_vars.csensors_resource[id].timerId); } } }
void icmpv6rpl_setDAOPeriod(uint16_t daoPeriod){ uint32_t daoPeriodRandom; icmpv6rpl_vars.daoPeriod = daoPeriod; daoPeriodRandom = icmpv6rpl_vars.daoPeriod - 0x80 + (openrandom_get16b()&0xff); opentimers_setPeriod( icmpv6rpl_vars.timerIdDAO, TIME_MS, daoPeriodRandom ); }
void task_resNotifSendDone() { OpenQueueEntry_t* msg; // get recently-sent packet from openqueue msg = openqueue_resGetSentPacket(); if (msg==NULL) { // log the error openserial_printError(COMPONENT_RES,ERR_NO_SENT_PACKET, (errorparameter_t)0, (errorparameter_t)0); // abort return; } // declare it as mine msg->owner = COMPONENT_RES; // indicate transmission (to update statistics) if (msg->l2_sendDoneError==E_SUCCESS) { neighbors_indicateTx(&(msg->l2_nextORpreviousHop), msg->l2_numTxAttempts, TRUE, &msg->l2_asn); /* piggy502: only apply Rx mask after a RES packet is sent */ switch(msg->creator){ case COMPONENT_RES: applyRxMask(); break; default: break; } } else { neighbors_indicateTx(&(msg->l2_nextORpreviousHop), msg->l2_numTxAttempts, FALSE, &msg->l2_asn); } // send the packet to where it belongs if (msg->creator == COMPONENT_RES) { // discard (ADV or KA) packets this component has created openqueue_freePacketBuffer(msg); // I can send the next ADV or KA res_vars.busySending = FALSE; // restart a random timer res_vars.periodMaintenance = 1700+(openrandom_get16b()&0xff); opentimers_setPeriod(res_vars.timerId, TIME_MS, res_vars.periodMaintenance); } else { // send the rest up the stack iphc_sendDone(msg,msg->l2_sendDoneError); } }
/** \brief Handler for DIO timer event. \note This function is executed in task context, called by the scheduler. */ void icmpv6rpl_timer_DIO_task() { uint32_t dioPeriod; // send DIO sendDIO(); // arm the DIO timer with this new value dioPeriod = icmpv6rpl_vars.dioPeriod - 0x80 + (openrandom_get16b()&0xff); opentimers_setPeriod( icmpv6rpl_vars.timerIdDIO, TIME_MS, dioPeriod ); }
/** \brief Send a CoAP request. This function is called by a CoAP resource when it wants to send some data. This function is NOT called for a response. \param[in] msg The message to be sent. This messages should not contain the CoAP header. \param[in] type The CoAP type of the message. \param[in] code The CoAP code of the message. \param[in] TKL The Token Length of the message, sanitized to a max of COAP_MAX_TKL (8). \param[out] descSender A pointer to the description of the calling CoAP resource. \post After returning, this function will have written the messageID and TOKEN used in the descSender parameter. \return The outcome of sending the packet. */ owerror_t opencoap_send( OpenQueueEntry_t* msg, coap_type_t type, coap_code_t code, uint8_t TKL, coap_resource_desc_t* descSender ) { uint16_t token; uint8_t tokenPos=0; coap_header_iht* request; // increment the (global) messageID if (opencoap_vars.messageID++ == 0xffff) { opencoap_vars.messageID = 0; } // take ownership over the packet msg->owner = COMPONENT_OPENCOAP; // fill in packet metadata msg->l4_sourcePortORicmpv6Type = WKP_UDP_COAP; // update the last_request header request = &descSender->last_request; request->T = type; request->Code = code; request->messageID = opencoap_vars.messageID; request->TKL = TKL<COAP_MAX_TKL ? TKL : COAP_MAX_TKL; while (tokenPos<request->TKL) { token = openrandom_get16b(); memcpy(&request->token[tokenPos],&token,2); tokenPos+=2; } // pre-pend CoAP header (version,type,TKL,code,messageID,Token) packetfunctions_reserveHeaderSize(msg,4+request->TKL); msg->payload[0] = (COAP_VERSION << 6) | (type << 4) | (request->TKL << 0); msg->payload[1] = code; msg->payload[2] = (request->messageID>>8) & 0xff; msg->payload[3] = (request->messageID>>0) & 0xff; memcpy(&msg->payload[4],&token,request->TKL); return openudp_send(msg); }
void rt_init() { // startup the sensor sensitive_accel_temperature_init(); // prepare the resource descriptor for the /temp path rt_vars.desc.path0len = sizeof(rt_path0)-1; rt_vars.desc.path0val = (uint8_t*)(&rt_path0); rt_vars.desc.path1len = 0; rt_vars.desc.path1val = NULL; rt_vars.desc.componentID = COMPONENT_RT; rt_vars.desc.callbackRx = &rt_receive; rt_vars.desc.callbackSendDone = &rt_sendDone; rt_vars.timerId = opentimers_start(openrandom_get16b()%RTPERIOD, TIMER_PERIODIC,TIME_MS, rt_timer); opencoap_register(&rt_vars.desc); }
/** \brief Handler for DAO timer event. \note This function is executed in task context, called by the scheduler. */ void icmpv6rpl_timer_DAO_task() { // update the delayDAO icmpv6rpl_vars.delayDAO = (icmpv6rpl_vars.delayDAO+1)%5; // check whether we need to send DAO if (icmpv6rpl_vars.delayDAO==0) { // send DAO sendDAO(); // pick a new pseudo-random periodDAO icmpv6rpl_vars.periodDAO = TIMER_DAO_TIMEOUT+(openrandom_get16b()&0xff); // arm the DAO timer with this new value opentimers_setPeriod( icmpv6rpl_vars.timerIdDAO, TIME_MS, icmpv6rpl_vars.periodDAO ); } }
void sixtop_init() { sixtop_vars.periodMaintenance = 872 +(openrandom_get16b()&0xff); sixtop_vars.busySendingKA = FALSE; sixtop_vars.busySendingEB = FALSE; sixtop_vars.dsn = 0; sixtop_vars.mgtTaskCounter = 0; sixtop_vars.kaPeriod = MAXKAPERIOD; sixtop_vars.maintenanceTimerId = opentimers_start( sixtop_vars.periodMaintenance, TIMER_PERIODIC, TIME_MS, sixtop_maintenance_timer_cb ); sixtop_vars.timeoutTimerId = opentimers_start( SIX2SIX_TIMEOUT_MS, TIMER_ONESHOT, TIME_MS, sixtop_timeout_timer_cb ); }
void rex_task_cb() { OpenQueueEntry_t* pkt; error_t outcome; uint8_t numOptions; uint8_t i; uint16_t x_int = 0; uint16_t* p_x_int = &x_int; uint16_t sum = 0; uint16_t avg = 0; uint8_t N_avg = 10; for (int i = 0; i < N_avg; i++) { ADC_getvoltage(p_x_int); sum += x_int; } avg = sum/N_avg; // create a CoAP RD packet pkt = openqueue_getFreePacketBuffer(COMPONENT_REX); if (pkt==NULL) { openserial_printError(COMPONENT_REX,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); openqueue_freePacketBuffer(pkt); return; } // take ownership over that packet pkt->creator = COMPONENT_REX; pkt->owner = COMPONENT_REX; // CoAP payload packetfunctions_reserveHeaderSize(pkt,PAYLOADLEN); for (i=0;i<PAYLOADLEN;i++) { pkt->payload[i] = i; } avg = openrandom_get16b(); pkt->payload[0] = (avg>>8)&0xff; pkt->payload[1] = (avg>>0)&0xff; numOptions = 0; // location-path option packetfunctions_reserveHeaderSize(pkt,sizeof(rex_path0)-1); memcpy(&pkt->payload[0],&rex_path0,sizeof(rex_path0)-1); packetfunctions_reserveHeaderSize(pkt,1); pkt->payload[0] = (COAP_OPTION_LOCATIONPATH-COAP_OPTION_CONTENTTYPE) << 4 | sizeof(rex_path0)-1; numOptions++; // content-type option packetfunctions_reserveHeaderSize(pkt,2); pkt->payload[0] = COAP_OPTION_CONTENTTYPE << 4 | 1; pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; numOptions++; // metadata pkt->l4_destination_port = WKP_UDP_COAP; pkt->l3_destinationORsource.type = ADDR_128B; memcpy(&pkt->l3_destinationORsource.addr_128b[0],&ipAddr_motesEecs,16); // send outcome = opencoap_send(pkt, COAP_TYPE_NON, COAP_CODE_REQ_PUT, numOptions, &rex_vars.desc); // avoid overflowing the queue if fails if (outcome==E_FAIL) { openqueue_freePacketBuffer(pkt); } return; }
/** \brief Initialize this module. */ void icmpv6rpl_init() { //===== reset local variables memset(&icmpv6rpl_vars,0,sizeof(icmpv6rpl_vars_t)); //=== admin icmpv6rpl_vars.busySending = FALSE; icmpv6rpl_vars.DODAGIDFlagSet = 0; //=== DIO-related icmpv6rpl_vars.dio.rplinstanceId = 0x00; ///< TODO: put correct value icmpv6rpl_vars.dio.verNumb = 0x00; ///< TODO: put correct value // rank: to be populated upon TX icmpv6rpl_vars.dio.rplOptions = MOP_DIO_A | \ MOP_DIO_B | \ MOP_DIO_C | \ PRF_DIO_A | \ PRF_DIO_B | \ PRF_DIO_C | \ G_DIO ; icmpv6rpl_vars.dio.DTSN = 0x33; ///< TODO: put correct value icmpv6rpl_vars.dio.flags = 0x00; icmpv6rpl_vars.dio.reserved = 0x00; // DODAGID: to be populated upon receiving DIO icmpv6rpl_vars.dioDestination.type = ADDR_128B; memcpy(&icmpv6rpl_vars.dioDestination.addr_128b[0],all_routers_multicast,sizeof(all_routers_multicast)); icmpv6rpl_vars.periodDIO = TIMER_DIO_TIMEOUT+(openrandom_get16b()&0xff); icmpv6rpl_vars.timerIdDIO = opentimers_start( icmpv6rpl_vars.periodDIO, TIMER_PERIODIC, TIME_MS, icmpv6rpl_timer_DIO_cb ); //=== DAO-related icmpv6rpl_vars.dao.rplinstanceId = 0x00; ///< TODO: put correct value icmpv6rpl_vars.dao.K_D_flags = FLAG_DAO_A | \ FLAG_DAO_B | \ FLAG_DAO_C | \ FLAG_DAO_D | \ FLAG_DAO_E | \ PRF_DIO_C | \ FLAG_DAO_F | \ D_DAO | K_DAO; icmpv6rpl_vars.dao.reserved = 0x00; icmpv6rpl_vars.dao.DAOSequence = 0x00; // DODAGID: to be populated upon receiving DIO icmpv6rpl_vars.dao_transit.type = OPTION_TRANSIT_INFORMATION_TYPE; // optionLength: to be populated upon TX icmpv6rpl_vars.dao_transit.E_flags = E_DAO_Transit_Info; icmpv6rpl_vars.dao_transit.PathControl = PC1_A_DAO_Transit_Info | \ PC1_B_DAO_Transit_Info | \ PC2_A_DAO_Transit_Info | \ PC2_B_DAO_Transit_Info | \ PC3_A_DAO_Transit_Info | \ PC3_B_DAO_Transit_Info | \ PC4_A_DAO_Transit_Info | \ PC4_B_DAO_Transit_Info; icmpv6rpl_vars.dao_transit.PathSequence = 0x00; // to be incremented at each TX icmpv6rpl_vars.dao_transit.PathLifetime = 0xAA; //target information icmpv6rpl_vars.dao_target.type = OPTION_TARGET_INFORMATION_TYPE; icmpv6rpl_vars.dao_target.optionLength = 0; icmpv6rpl_vars.dao_target.flags = 0; icmpv6rpl_vars.dao_target.prefixLength = 0; icmpv6rpl_vars.periodDAO = TIMER_DAO_TIMEOUT+(openrandom_get16b()&0xff); icmpv6rpl_vars.timerIdDAO = opentimers_start( icmpv6rpl_vars.periodDAO, TIMER_PERIODIC, TIME_MS, icmpv6rpl_timer_DAO_cb ); }
/** \brief Initialize this module. */ void icmpv6rpl_init() { uint8_t dodagid[16]; uint32_t dioPeriod; uint32_t daoPeriod; // retrieve my prefix and EUI64 memcpy(&dodagid[0],idmanager_getMyID(ADDR_PREFIX)->prefix,8); // prefix memcpy(&dodagid[8],idmanager_getMyID(ADDR_64B)->addr_64b,8); // eui64 //===== reset local variables memset(&icmpv6rpl_vars,0,sizeof(icmpv6rpl_vars_t)); //=== admin icmpv6rpl_vars.busySending = FALSE; icmpv6rpl_vars.fDodagidWritten = 0; //=== DIO icmpv6rpl_vars.dio.rplinstanceId = 0x00; ///< TODO: put correct value icmpv6rpl_vars.dio.verNumb = 0x00; ///< TODO: put correct value // rank: to be populated upon TX icmpv6rpl_vars.dio.rplOptions = MOP_DIO_A | \ MOP_DIO_B | \ MOP_DIO_C | \ PRF_DIO_A | \ PRF_DIO_B | \ PRF_DIO_C | \ G_DIO ; icmpv6rpl_vars.dio.DTSN = 0x33; ///< TODO: put correct value icmpv6rpl_vars.dio.flags = 0x00; icmpv6rpl_vars.dio.reserved = 0x00; memcpy( &(icmpv6rpl_vars.dio.DODAGID[0]), dodagid, sizeof(icmpv6rpl_vars.dio.DODAGID) ); // can be replaced later icmpv6rpl_vars.dioDestination.type = ADDR_128B; memcpy(&icmpv6rpl_vars.dioDestination.addr_128b[0],all_routers_multicast,sizeof(all_routers_multicast)); icmpv6rpl_vars.dioPeriod = TIMER_DIO_TIMEOUT; dioPeriod = icmpv6rpl_vars.dioPeriod - 0x80 + (openrandom_get16b()&0xff); icmpv6rpl_vars.timerIdDIO = opentimers_start( dioPeriod, TIMER_PERIODIC, TIME_MS, icmpv6rpl_timer_DIO_cb ); //=== DAO icmpv6rpl_vars.dao.rplinstanceId = 0x00; ///< TODO: put correct value icmpv6rpl_vars.dao.K_D_flags = FLAG_DAO_A | \ FLAG_DAO_B | \ FLAG_DAO_C | \ FLAG_DAO_D | \ FLAG_DAO_E | \ PRF_DIO_C | \ FLAG_DAO_F | \ D_DAO | K_DAO; icmpv6rpl_vars.dao.reserved = 0x00; icmpv6rpl_vars.dao.DAOSequence = 0x00; memcpy( &(icmpv6rpl_vars.dao.DODAGID[0]), dodagid, sizeof(icmpv6rpl_vars.dao.DODAGID) ); // can be replaced later icmpv6rpl_vars.dao_transit.type = OPTION_TRANSIT_INFORMATION_TYPE; // optionLength: to be populated upon TX icmpv6rpl_vars.dao_transit.E_flags = E_DAO_Transit_Info; icmpv6rpl_vars.dao_transit.PathControl = PC1_A_DAO_Transit_Info | \ PC1_B_DAO_Transit_Info | \ PC2_A_DAO_Transit_Info | \ PC2_B_DAO_Transit_Info | \ PC3_A_DAO_Transit_Info | \ PC3_B_DAO_Transit_Info | \ PC4_A_DAO_Transit_Info | \ PC4_B_DAO_Transit_Info; icmpv6rpl_vars.dao_transit.PathSequence = 0x00; // to be incremented at each TX icmpv6rpl_vars.dao_transit.PathLifetime = 0xAA; //target information icmpv6rpl_vars.dao_target.type = OPTION_TARGET_INFORMATION_TYPE; icmpv6rpl_vars.dao_target.optionLength = 0; icmpv6rpl_vars.dao_target.flags = 0; icmpv6rpl_vars.dao_target.prefixLength = 0; icmpv6rpl_vars.daoPeriod = TIMER_DAO_TIMEOUT; daoPeriod = icmpv6rpl_vars.daoPeriod - 0x80 + (openrandom_get16b()&0xff); icmpv6rpl_vars.timerIdDAO = opentimers_start( daoPeriod, TIMER_PERIODIC, TIME_MS, icmpv6rpl_timer_DAO_cb ); }
void udprand_init() { udprand_vars.timerId = opentimers_start(openrandom_get16b()%UDPRANDPERIOD, TIMER_PERIODIC,TIME_MS, udprand_timer); }
void cexample_task_cb() { OpenQueueEntry_t* pkt; owerror_t outcome; uint8_t numOptions; uint8_t i; uint16_t x_int = 0; uint16_t sum = 0; uint16_t avg = 0; uint8_t N_avg = 10; // don't run if not synch if (ieee154e_isSynch() == FALSE) return; // don't run on dagroot if (idmanager_getIsDAGroot()) { opentimers_stop(cexample_vars.timerId); return; } for (i = 0; i < N_avg; i++) { sum += x_int; } avg = sum/N_avg; // create a CoAP RD packet pkt = openqueue_getFreePacketBuffer(COMPONENT_CEXAMPLE); if (pkt==NULL) { openserial_printError( COMPONENT_CEXAMPLE, ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0 ); openqueue_freePacketBuffer(pkt); return; } // take ownership over that packet pkt->creator = COMPONENT_CEXAMPLE; pkt->owner = COMPONENT_CEXAMPLE; // CoAP payload packetfunctions_reserveHeaderSize(pkt,PAYLOADLEN); for (i=0;i<PAYLOADLEN;i++) { pkt->payload[i] = i; } avg = openrandom_get16b(); pkt->payload[0] = (avg>>8)&0xff; pkt->payload[1] = (avg>>0)&0xff; numOptions = 0; // location-path option packetfunctions_reserveHeaderSize(pkt,sizeof(cexample_path0)-1); memcpy(&pkt->payload[0],&cexample_path0,sizeof(cexample_path0)-1); packetfunctions_reserveHeaderSize(pkt,1); pkt->payload[0] = ((COAP_OPTION_NUM_URIPATH) << 4) | (sizeof(cexample_path0)-1); numOptions++; // content-type option packetfunctions_reserveHeaderSize(pkt,2); pkt->payload[0] = (COAP_OPTION_NUM_CONTENTFORMAT << 4) | 1; pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; numOptions++; // metadata pkt->l4_destination_port = WKP_UDP_COAP; pkt->l3_destinationAdd.type = ADDR_128B; memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_motesEecs,16); // send outcome = opencoap_send( pkt, COAP_TYPE_NON, COAP_CODE_REQ_PUT, numOptions, &cexample_vars.desc ); // avoid overflowing the queue if fails if (outcome==E_FAIL) { openqueue_freePacketBuffer(pkt); } return; }
void task_sixtopNotifSendDone() { OpenQueueEntry_t* msg; // get recently-sent packet from openqueue msg = openqueue_sixtopGetSentPacket(); if (msg==NULL) { openserial_printCritical( COMPONENT_SIXTOP, ERR_NO_SENT_PACKET, (errorparameter_t)0, (errorparameter_t)0 ); return; } // take ownership msg->owner = COMPONENT_SIXTOP; // update neighbor statistics if (msg->l2_sendDoneError==E_SUCCESS) { neighbors_indicateTx( &(msg->l2_nextORpreviousHop), msg->l2_numTxAttempts, TRUE, &msg->l2_asn ); } else { neighbors_indicateTx( &(msg->l2_nextORpreviousHop), msg->l2_numTxAttempts, FALSE, &msg->l2_asn ); } // send the packet to where it belongs switch (msg->creator) { case COMPONENT_SIXTOP: if (msg->l2_frameType==IEEE154_TYPE_BEACON) { // this is a ADV // not busy sending ADV anymore sixtop_vars.busySendingEB = FALSE; } else { // this is a KA // not busy sending KA anymore sixtop_vars.busySendingKA = FALSE; } // discard packets openqueue_freePacketBuffer(msg); // restart a random timer sixtop_vars.periodMaintenance = 872+(openrandom_get16b()&0xff); opentimers_setPeriod( sixtop_vars.maintenanceTimerId, TIME_MS, sixtop_vars.periodMaintenance ); break; case COMPONENT_SIXTOP_RES: sixtop_six2six_sendDone(msg,msg->l2_sendDoneError); break; default: // send the rest up the stack iphc_sendDone(msg,msg->l2_sendDoneError); break; } }