void icmpv6echo_receive(OpenQueueEntry_t* msg) { OpenQueueEntry_t* reply; msg->owner = COMPONENT_ICMPv6ECHO; switch(msg->l4_sourcePortORicmpv6Type) { case IANA_ICMPv6_ECHO_REQUEST: openserial_printInfo(COMPONENT_ICMPv6ECHO,ERR_RCVD_ECHO_REQUEST, (errorparameter_t)0, (errorparameter_t)0); // get a new openqueuEntry_t for the echo reply reply = openqueue_getFreePacketBuffer(COMPONENT_ICMPv6ECHO); if (reply==NULL) { openserial_printError(COMPONENT_ICMPv6ECHO,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)1, (errorparameter_t)0); openqueue_freePacketBuffer(msg); return; } // take ownership over reply reply->creator = COMPONENT_ICMPv6ECHO; reply->owner = COMPONENT_ICMPv6ECHO; // copy payload from msg to (end of) reply packetfunctions_reserveHeaderSize(reply,msg->length); memcpy(reply->payload,msg->payload,msg->length); // copy source of msg in destination of reply memcpy(&(reply->l3_destinationAdd),&(msg->l3_sourceAdd),sizeof(open_addr_t)); // free up msg openqueue_freePacketBuffer(msg); msg = NULL; // administrative information for reply reply->l4_protocol = IANA_ICMPv6; reply->l4_sourcePortORicmpv6Type = IANA_ICMPv6_ECHO_REPLY; ((ICMPv6_ht*)(reply->payload))->type = reply->l4_sourcePortORicmpv6Type; packetfunctions_calculateChecksum(reply,(uint8_t*)&(((ICMPv6_ht*)(reply->payload))->checksum));//do last icmpv6echo_vars.busySending = TRUE; if (icmpv6_send(reply)!=E_SUCCESS) { icmpv6echo_vars.busySending = FALSE; openqueue_freePacketBuffer(reply); } break; case IANA_ICMPv6_ECHO_REPLY: openserial_printInfo(COMPONENT_ICMPv6ECHO,ERR_RCVD_ECHO_REPLY, (errorparameter_t)0, (errorparameter_t)0); openqueue_freePacketBuffer(msg); break; default: openserial_printError(COMPONENT_ICMPv6ECHO,ERR_UNSUPPORTED_ICMPV6_TYPE, (errorparameter_t)msg->l4_sourcePortORicmpv6Type, (errorparameter_t)2); openqueue_freePacketBuffer(msg); break; } }
void openbridge_triggerData(void) { uint8_t input_buffer[136];//worst case: 8B of next hop + 128B of data OpenQueueEntry_t* pkt; uint8_t numDataBytes; numDataBytes = openserial_getNumDataBytes(); //poipoi xv //this is a temporal workaround as we are never supposed to get chunks of data //longer than input buffer size.. I assume that HDLC will solve that. // MAC header is 13B + 8 next hop so we cannot accept packets that are longer than 118B if (numDataBytes>(136 - 21) || numDataBytes<8){ //to prevent too short or too long serial frames to kill the stack openserial_printError(COMPONENT_OPENBRIDGE,ERR_INPUTBUFFER_LENGTH, (errorparameter_t)numDataBytes, (errorparameter_t)0); return; } //copying the buffer once we know it is not too big openserial_getInputBuffer(&(input_buffer[0]),numDataBytes); if (idmanager_getIsDAGroot()==TRUE && numDataBytes>0) { pkt = openqueue_getFreePacketBuffer(COMPONENT_OPENBRIDGE); if (pkt==NULL) { openserial_printError(COMPONENT_OPENBRIDGE,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); return; } //admin pkt->creator = COMPONENT_OPENBRIDGE; pkt->owner = COMPONENT_OPENBRIDGE; //l2 pkt->l2_nextORpreviousHop.type = ADDR_64B; memcpy(&(pkt->l2_nextORpreviousHop.addr_64b[0]),&(input_buffer[0]),8); //payload packetfunctions_reserveHeaderSize(pkt,numDataBytes-8); memcpy(pkt->payload,&(input_buffer[8]),numDataBytes-8); //this is to catch the too short packet. remove it after fw-103 is solved. if (numDataBytes<16){ openserial_printError(COMPONENT_OPENBRIDGE,ERR_INVALIDSERIALFRAME, (errorparameter_t)0, (errorparameter_t)0); } //send if ((iphc_sendFromBridge(pkt))==E_FAIL) { openqueue_freePacketBuffer(pkt); } } }
void isr_button() { //prepare packet testRadioPacketToSend = openqueue_getFreePacketBuffer(); //l1 testRadioPacketToSend->l1_channel = DEFAULTCHANNEL; //payload packetfunctions_reserveHeaderSize(testRadioPacketToSend,5); testRadioPacketToSend->payload[0] = 0x01; testRadioPacketToSend->payload[1] = 0x02; testRadioPacketToSend->payload[2] = 0x03; testRadioPacketToSend->payload[3] = 0x04; testRadioPacketToSend->payload[4] = 0x05; packetfunctions_reserveFooterSize(testRadioPacketToSend,2); //space for radio to fill in CRC //send packet radio_send(testRadioPacketToSend); //debug P1OUT ^= 0x02; // toggle P1.1 (for debug) leds_circular_shift(); // circular-shift LEDs (for debug) }
void uinject_task_cb() { OpenQueueEntry_t* pkt; // don't run if not synch if (ieee154e_isSynch() == FALSE) return; // don't run on dagroot if (idmanager_getIsDAGroot()) { opentimers_stop(uinject_vars.timerId); return; } // if you get here, send a packet // get a free packet buffer pkt = openqueue_getFreePacketBuffer(COMPONENT_UINJECT); if (pkt==NULL) { openserial_printError( COMPONENT_UINJECT, ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0 ); return; } pkt->owner = COMPONENT_UINJECT; pkt->creator = COMPONENT_UINJECT; pkt->l4_protocol = IANA_UDP; pkt->l4_destination_port = WKP_UDP_INJECT; pkt->l4_sourcePortORicmpv6Type = WKP_UDP_INJECT; pkt->l3_destinationAdd.type = ADDR_128B; memcpy(&pkt->l3_destinationAdd.addr_128b[0],uinject_dst_addr,16); packetfunctions_reserveHeaderSize(pkt,sizeof(uint16_t)); *((uint16_t*)&pkt->payload[0]) = uinject_vars.counter++; if ((openudp_send(pkt))==E_FAIL) { openqueue_freePacketBuffer(pkt); } }
void udpinject_trigger() { OpenQueueEntry_t* pkt; uint8_t number_bytes_from_input_buffer; uint8_t input_buffer[18]; //get command from OpenSerial (16B IPv6 destination address, 2B destination port) number_bytes_from_input_buffer = openserial_getInputBuffer(&(input_buffer[0]),sizeof(input_buffer)); if (number_bytes_from_input_buffer!=sizeof(input_buffer)) { openserial_printError(COMPONENT_UDPINJECT,ERR_INPUTBUFFER_LENGTH, (errorparameter_t)number_bytes_from_input_buffer, (errorparameter_t)0); return; }; //prepare packet pkt = openqueue_getFreePacketBuffer(COMPONENT_UDPINJECT); if (pkt==NULL) { openserial_printError(COMPONENT_UDPINJECT,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); return; } pkt->creator = COMPONENT_UDPINJECT; pkt->owner = COMPONENT_UDPINJECT; pkt->l4_protocol = IANA_UDP; pkt->l4_sourcePortORicmpv6Type = WKP_UDP_INJECT; pkt->l4_destination_port = packetfunctions_ntohs(&(input_buffer[16])); pkt->l3_destinationAdd.type = ADDR_128B; memcpy(&(pkt->l3_destinationAdd.addr_128b[0]),&(input_buffer[0]),16); packetfunctions_reserveHeaderSize(pkt,6); ((uint8_t*)pkt->payload)[0] = 'p'; ((uint8_t*)pkt->payload)[1] = 'o'; ((uint8_t*)pkt->payload)[2] = 'i'; ((uint8_t*)pkt->payload)[3] = 'p'; ((uint8_t*)pkt->payload)[4] = 'o'; ((uint8_t*)pkt->payload)[5] = 'i'; //send packet if ((openudp_send(pkt))==E_FAIL) { openqueue_freePacketBuffer(pkt); } }
void uecho_receive(OpenMote* self, OpenQueueEntry_t* request) { uint16_t temp_l4_destination_port; OpenQueueEntry_t* reply; reply = openqueue_getFreePacketBuffer(self, COMPONENT_UECHO); if (reply==NULL) { openserial_printError(self, COMPONENT_UECHO, ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0 ); openqueue_freePacketBuffer(self, request); //clear the request packet as well return; } reply->owner = COMPONENT_UECHO; // reply with the same OpenQueueEntry_t reply->creator = COMPONENT_UECHO; reply->l4_protocol = IANA_UDP; temp_l4_destination_port = request->l4_destination_port; reply->l4_destination_port = request->l4_sourcePortORicmpv6Type; reply->l4_sourcePortORicmpv6Type = temp_l4_destination_port; reply->l3_destinationAdd.type = ADDR_128B; // copy source to destination to echo. memcpy(&reply->l3_destinationAdd.addr_128b[0],&request->l3_sourceAdd.addr_128b[0],16); packetfunctions_reserveHeaderSize(self, reply,request->length); memcpy(&reply->payload[0],&request->payload[0],request->length); openqueue_freePacketBuffer(self, request); if (( openudp_send(self, reply))==E_FAIL) { openqueue_freePacketBuffer(self, reply); } }
/** \brief Prepare and a send a RPL DAO. */ void sendDAO() { OpenQueueEntry_t* msg; // pointer to DAO messages uint8_t nbrIdx; // running neighbor index uint8_t numTransitParents,numTargetParents; // the number of parents indicated in transit option open_addr_t address; open_addr_t* prefix; if (ieee154e_isSynch()==FALSE) { // I'm not sync'ed // delete packets genereted by this module (DIO and DAO) from openqueue openqueue_removeAllCreatedBy(COMPONENT_ICMPv6RPL); // I'm not busy sending a DIO/DAO icmpv6rpl_vars.busySending = FALSE; // stop here return; } // dont' send a DAO if you're in bridge mode if (idmanager_getIsBridge()==TRUE) { return; } // dont' send a DAO if you did not acquire a DAGrank if (neighbors_getMyDAGrank()==DEFAULTDAGRANK) { return; } // dont' send a DAO if you're still busy sending the previous one if (icmpv6rpl_vars.busySending==TRUE) { return; } // if you get here, you start construct DAO // reserve a free packet buffer for DAO msg = openqueue_getFreePacketBuffer(COMPONENT_ICMPv6RPL); if (msg==NULL) { openserial_printError(COMPONENT_ICMPv6RPL,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); return; } // take ownership msg->creator = COMPONENT_ICMPv6RPL; msg->owner = COMPONENT_ICMPv6RPL; // set transport information msg->l4_protocol = IANA_ICMPv6; msg->l4_sourcePortORicmpv6Type = IANA_ICMPv6_RPL; // set DAO destination msg->l3_destinationAdd.type=ADDR_128B; memcpy(msg->l3_destinationAdd.addr_128b,icmpv6rpl_vars.dio.DODAGID,sizeof(icmpv6rpl_vars.dio.DODAGID)); //===== fill in packet //NOTE: limit to preferrred parent only the number of DAO transit addresses to send //=== transit option -- from RFC 6550, page 55 - 1 transit information header per parent is required. //getting only preferred parent as transit numTransitParents=0; neighbors_getPreferredParentEui64(&address); packetfunctions_writeAddress(msg,&address,OW_BIG_ENDIAN); prefix=idmanager_getMyID(ADDR_PREFIX); packetfunctions_writeAddress(msg,prefix,OW_BIG_ENDIAN); // update transit info fields // from rfc6550 p.55 -- Variable, depending on whether or not the DODAG ParentAddress subfield is present. // poipoi xv: it is not very clear if this includes all fields in the header. or as target info 2 bytes are removed. // using the same pattern as in target information. icmpv6rpl_vars.dao_transit.optionLength = LENGTH_ADDR128b + sizeof(icmpv6rpl_dao_transit_ht)-2; icmpv6rpl_vars.dao_transit.PathControl=0; //todo. this is to set the preference of this parent. icmpv6rpl_vars.dao_transit.type=OPTION_TRANSIT_INFORMATION_TYPE; // write transit info in packet packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dao_transit_ht)); memcpy( ((icmpv6rpl_dao_transit_ht*)(msg->payload)), &(icmpv6rpl_vars.dao_transit), sizeof(icmpv6rpl_dao_transit_ht) ); numTransitParents++; //target information is required. RFC 6550 page 55. /* One or more Transit Information options MUST be preceded by one or more RPL Target options. */ numTargetParents = 0; for (nbrIdx=0;nbrIdx<MAXNUMNEIGHBORS;nbrIdx++) { if ((neighbors_isNeighborWithHigherDAGrank(nbrIdx))==TRUE) { // this neighbor is of higher DAGrank as I am. so it is my child // write it's address in DAO RFC6550 page 80 check point 1. neighbors_getNeighbor(&address,ADDR_64B,nbrIdx); packetfunctions_writeAddress(msg,&address,OW_BIG_ENDIAN); prefix=idmanager_getMyID(ADDR_PREFIX); packetfunctions_writeAddress(msg,prefix,OW_BIG_ENDIAN); // update target info fields // from rfc6550 p.55 -- Variable, length of the option in octets excluding the Type and Length fields. // poipoi xv: assuming that type and length fields refer to the 2 first bytes of the header icmpv6rpl_vars.dao_target.optionLength = LENGTH_ADDR128b +sizeof(icmpv6rpl_dao_target_ht) - 2; //no header type and length icmpv6rpl_vars.dao_target.type = OPTION_TARGET_INFORMATION_TYPE; icmpv6rpl_vars.dao_target.flags = 0; //must be 0 icmpv6rpl_vars.dao_target.prefixLength = 128; //128 leading bits -- full address. // write transit info in packet packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dao_target_ht)); memcpy( ((icmpv6rpl_dao_target_ht*)(msg->payload)), &(icmpv6rpl_vars.dao_target), sizeof(icmpv6rpl_dao_target_ht) ); // remember I found it numTargetParents++; } //limit to MAX_TARGET_PARENTS the number of DAO target addresses to send //section 8.2.1 pag 67 RFC6550 -- using a subset // poipoi TODO base selection on ETX rather than first X. if (numTargetParents>=MAX_TARGET_PARENTS) break; } // stop here if no parents found if (numTransitParents==0) { openqueue_freePacketBuffer(msg); return; } icmpv6rpl_vars.dao_transit.PathSequence++; //increment path sequence. // if you get here, you will send a DAO //=== DAO header packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dao_ht)); memcpy( ((icmpv6rpl_dao_ht*)(msg->payload)), &(icmpv6rpl_vars.dao), sizeof(icmpv6rpl_dao_ht) ); //=== ICMPv6 header packetfunctions_reserveHeaderSize(msg,sizeof(ICMPv6_ht)); ((ICMPv6_ht*)(msg->payload))->type = msg->l4_sourcePortORicmpv6Type; ((ICMPv6_ht*)(msg->payload))->code = IANA_ICMPv6_RPL_DAO; packetfunctions_calculateChecksum(msg,(uint8_t*)&(((ICMPv6_ht*)(msg->payload))->checksum)); //call last //===== send if (icmpv6_send(msg)==E_SUCCESS) { icmpv6rpl_vars.busySending = TRUE; } else { openqueue_freePacketBuffer(msg); } }
/** \brief Prepare and a send a RPL DIO. */ void sendDIO() { OpenQueueEntry_t* msg; // stop if I'm not sync'ed if (ieee154e_isSynch()==FALSE) { // remove packets genereted by this module (DIO and DAO) from openqueue openqueue_removeAllCreatedBy(COMPONENT_ICMPv6RPL); // I'm not busy sending a DIO/DAO icmpv6rpl_vars.busySending = FALSE; // stop here return; } // do not send DIO if I'm in in bridge mode if (idmanager_getIsBridge()==TRUE) { return; } // do not send DIO if I have the default DAG rank if (neighbors_getMyDAGrank()==DEFAULTDAGRANK) { return; } // do not send DIO if I'm already busy sending if (icmpv6rpl_vars.busySending==TRUE) { return; } // if you get here, all good to send a DIO // I'm now busy sending icmpv6rpl_vars.busySending = TRUE; // reserve a free packet buffer for DIO msg = openqueue_getFreePacketBuffer(COMPONENT_ICMPv6RPL); if (msg==NULL) { openserial_printError(COMPONENT_ICMPv6RPL,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); icmpv6rpl_vars.busySending = FALSE; return; } // take ownership msg->creator = COMPONENT_ICMPv6RPL; msg->owner = COMPONENT_ICMPv6RPL; // set transport information msg->l4_protocol = IANA_ICMPv6; msg->l4_sourcePortORicmpv6Type = IANA_ICMPv6_RPL; // set DIO destination memcpy(&(msg->l3_destinationAdd),&icmpv6rpl_vars.dioDestination,sizeof(open_addr_t)); //===== DIO payload // note: DIO is already mostly populated icmpv6rpl_vars.dio.rank = neighbors_getMyDAGrank(); packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dio_ht)); memcpy( ((icmpv6rpl_dio_ht*)(msg->payload)), &(icmpv6rpl_vars.dio), sizeof(icmpv6rpl_dio_ht) ); //===== ICMPv6 header packetfunctions_reserveHeaderSize(msg,sizeof(ICMPv6_ht)); ((ICMPv6_ht*)(msg->payload))->type = msg->l4_sourcePortORicmpv6Type; ((ICMPv6_ht*)(msg->payload))->code = IANA_ICMPv6_RPL_DIO; packetfunctions_calculateChecksum(msg,(uint8_t*)&(((ICMPv6_ht*)(msg->payload))->checksum));//call last //send if (icmpv6_send(msg)!=E_SUCCESS) { icmpv6rpl_vars.busySending = FALSE; openqueue_freePacketBuffer(msg); } else { icmpv6rpl_vars.busySending = FALSE; } }
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; }
/** \brief Called back from scheduler, when a task must be executed. */ void csensors_task_cb(void) { OpenQueueEntry_t* pkt; owerror_t outcome; uint8_t id; coap_option_iht options[3]; id = csensors_vars.cb_list[csensors_vars.cb_get]; // create a CoAP RD packet pkt = openqueue_getFreePacketBuffer(COMPONENT_CSENSORS); if (pkt==NULL) { openserial_printError( COMPONENT_CSENSORS, ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0 ); return; } // take ownership over that packet pkt->creator = COMPONENT_CSENSORS; pkt->owner = COMPONENT_CSENSORS; // CoAP payload csensors_fillpayload(pkt,id); // location-path0 option options[0].type = COAP_OPTION_NUM_URIPATH; options[0].length = sizeof(csensors_path0) - 1; options[0].pValue = (uint8_t*)csensors_path0; // location-path1 option options[1].type = COAP_OPTION_NUM_URIPATH; options[1].length = csensors_vars.csensors_resource[id].desc.path1len; options[1].pValue = csensors_vars.csensors_resource[id].desc.path1val; // content format option csensors_vars.medType = COAP_MEDTYPE_APPOCTETSTREAM; options[2].type = COAP_OPTION_NUM_CONTENTFORMAT; options[2].length = 1; options[2].pValue = &csensors_vars.medType; // metadata pkt->l4_destination_port = WKP_UDP_COAP; pkt->l3_destinationAdd.type = ADDR_128B; memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_ringmaster,16); // send outcome = opencoap_send( pkt, COAP_TYPE_NON, COAP_CODE_REQ_PUT, 2, // token len options, 3, // options len &csensors_vars.csensors_resource[id].desc ); // avoid overflowing the queue if fails if (outcome==E_FAIL) { openqueue_freePacketBuffer(pkt); } else { csensors_vars.cb_get = (csensors_vars.cb_get+1)%CSENSORSTASKLIST; } return; }
void rreg_timer() { OpenQueueEntry_t* pkt; uint8_t temp8b; error_t outcome; uint8_t numOptions; // create a CoAP RD packet pkt = openqueue_getFreePacketBuffer(COMPONENT_RREG); if (pkt==NULL) { openserial_printError(COMPONENT_RREG,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); openqueue_freePacketBuffer(pkt); return; } // take ownership over that packet pkt->creator = COMPONENT_RREG; pkt->owner = COMPONENT_RREG; // CoAP payload opencoap_writeLinks(pkt); numOptions = 0; // URI-query packetfunctions_reserveHeaderSize(pkt,sizeof(rreg_uriquery)-1+2); memcpy(&pkt->payload[0],&rreg_uriquery,sizeof(rreg_uriquery)-1); temp8b = idmanager_getMyID(ADDR_16B)->addr_16b[1]; pkt->payload[sizeof(rreg_uriquery)-1] = hexToAscii((temp8b>>4) & 0x0f); pkt->payload[sizeof(rreg_uriquery)-0] = hexToAscii((temp8b>>0) & 0x0f); packetfunctions_reserveHeaderSize(pkt,1); pkt->payload[0] = (COAP_OPTION_URIQUERY-COAP_OPTION_URIPATH) << 4 | sizeof(rreg_uriquery)-1+2; numOptions++; // URI-path packetfunctions_reserveHeaderSize(pkt,2); pkt->payload[0] = 'r'; pkt->payload[1] = 'd'; packetfunctions_reserveHeaderSize(pkt,1); pkt->payload[0] = (COAP_OPTION_URIPATH-COAP_OPTION_CONTENTTYPE) << 4 | 2; numOptions++; // add content-type option packetfunctions_reserveHeaderSize(pkt,2); pkt->payload[0] = COAP_OPTION_CONTENTTYPE << 4 | 1; pkt->payload[1] = COAP_MEDTYPE_APPLINKFORMAT; numOptions++; // metadata pkt->l4_destination_port = WKP_UDP_COAP; pkt->l3_destinationORsource.type = ADDR_128B; memcpy(&pkt->l3_destinationORsource.addr_128b[0],&ipAddr_ipsoRD,16); // send outcome = opencoap_send(pkt, COAP_TYPE_CON, COAP_CODE_REQ_POST, numOptions, &rreg_vars.desc); // avoid overflowing the queue if fails if (outcome==E_FAIL) { openqueue_freePacketBuffer(pkt); } return; }
void table_update_task_cb() { OpenQueueEntry_t* pkt; owerror_t outcome; // don't run if not synch if (ieee154e_isSynch() == FALSE ) return; // don't run on dagroot if (idmanager_getIsDAGroot()) { opentimers_stop(table_update_vars.timerId); return; } // create a CoAP RD packet pkt = openqueue_getFreePacketBuffer(COMPONENT_TABLE_UPDATE); if (pkt==NULL) { openserial_printError( COMPONENT_TABLE_UPDATE, ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0 ); openqueue_freePacketBuffer(pkt); return; } // take ownership over that packet pkt->creator = COMPONENT_TABLE_UPDATE; pkt->owner = COMPONENT_TABLE_UPDATE; // CoAP payload packetfunctions_reserveHeaderSize(pkt,PAYLOADLEN); //construct packet int index = 0; pkt->payload[index++] = 255;//1 pkt->payload[index++] = action;//2 //pkt->payload[index++] = count++; pkt->payload[index++] = i;//3 //used pkt->payload[index++] = tableEntry->neighborEntry.used;//4 //parentRef pkt->payload[index++] = tableEntry->neighborEntry.parentPreference;//5 //stableNeighbor pkt->payload[index++] = tableEntry->neighborEntry.stableNeighbor;//6 //switchStability pkt->payload[index++] = tableEntry->neighborEntry.switchStabilityCounter;//7 //address type pkt->payload[index++] = tableEntry->neighborEntry.addr_64b.type;//8 // the address itself open_addr_t addr =tableEntry->neighborEntry.addr_64b;//16 memcpy(&pkt->payload[index],&addr.addr_64b,8); index = index+8; //dagrank pkt->payload[index++] = tableEntry->neighborEntry.DAGrank;//17 //rssi pkt->payload[index] = tableEntry->neighborEntry.rssi;//19 index = index+2; //numRx pkt->payload[index++] = tableEntry->neighborEntry.numRx;//20 //numTx pkt->payload[index++] = tableEntry->neighborEntry.numTx;//21 //numTxACK pkt->payload[index++] = tableEntry->neighborEntry.numTxACK;//22 //numWraps pkt->payload[index++] = tableEntry->neighborEntry.numWraps;//23 //asn pkt->payload[index++] = tableEntry->neighborEntry.asn.byte4;//24 pkt->payload[index] = tableEntry->neighborEntry.asn.bytes2and3;//26 index = index+2; pkt->payload[index] = tableEntry->neighborEntry.asn.bytes0and1;//28 index = index+2; //joinPrio pkt->payload[index] = tableEntry->neighborEntry.joinPrio;//29 // metadata pkt->l4_destination_port = WKP_UDP_COAP; pkt->l3_destinationAdd.type = ADDR_128B; //uint8_t* DODAGID = get_icmpv6rpl_vars()->dio.DODAGID; uint8_t manager_full_address[16]; // retrieve my prefix and EUI64 memcpy(&manager_full_address[0],idmanager_getMyID(ADDR_PREFIX)->prefix,8); // prefix memcpy(&manager_full_address[8],&manager_address,8); // manager address memcpy(&pkt->l3_destinationAdd.addr_128b[0],&manager_full_address,16); //free some memory free(tableEntry); // send outcome = opencoap_send( pkt, COAP_TYPE_NON, COAP_CODE_RESP_CONTENT, 1, &table_update_vars.desc ); // avoid overflowing the queue if fails if (outcome==E_FAIL) { openqueue_freePacketBuffer(pkt); } return; }
void task_application_intersection(uint16_t input) { counter++; P1OUT ^= 0x02; // toggle P1.1 for debug P4OUT ^= 0x20; // toggle P4.5 for debug P1OUT |= 0x04;P1OUT &= ~0x04; // pulse P1.2 for debug if (counter==0) { leds_circular_shift(); // circular shift LEDs for debug } //get RAM space for packet testIntersection = openqueue_getFreePacketBuffer(); //l1 testIntersection->l1_channel = DEFAULTCHANNEL; P1OUT ^= 0x02; // toggle P1.1 for debug magnetometer_get_measurement(mag_reading); mag_X = 0; mag_Y = 0; mag_Z = 0; mag_X |= mag_reading[0]<<8; mag_X |= mag_reading[1]; mag_Y |= mag_reading[2]<<8; mag_Y |= mag_reading[3]; mag_Z |= mag_reading[4]<<8; mag_Z |= mag_reading[5]; //note: in the following I use functions for simple multiplications //and divisions for easy replacements in case the number of //instruction cycles is too large to be acceptable in this application mag_X = div_int(mag_X, 970); mag_Y = div_int(mag_Y, 970); mag_Z = div_int(mag_Z, 970);//970: look in HMC5843 datasheet XX = mul_int(mag_X,mag_X); YY = mul_int(mag_Y,mag_Y); ZZ = mul_int(mag_Z,mag_Z); mag_norm = XX + YY + ZZ; //no sqrt for faster execution filt_norm = LPF(mag_norm); //here we enter the state machine switch (state) { case NOCAR: if (filt_norm>=threshold){ FSMcounter = 1; state = PERHAPS; } break; //else you break case PERHAPS: if (filt_norm >= threshold && FSMcounter < maxCount){ FSMcounter++; } else if (filt_norm < threshold && FSMcounter >minCount) FSMcounter--; else if (filt_norm < threshold && FSMcounter <=minCount){ state = NOCAR; FSMcounter=0; if(seenCar){ seenCar=0; packetfunctions_reserveHeaderSize(testIntersection,1); testIntersection->payload[0] = seenCar; packetfunctions_reserveFooterSize(testIntersection,2);//space for radio to fill in CRC //send packet(noCar) radio_send(testIntersection); } } else if (filt_norm>=threshold && FSMcounter >=maxCount){ state=CAR; if(!seenCar){ seenCar=1; packetfunctions_reserveHeaderSize(testIntersection,1); testIntersection->payload[0] = seenCar; packetfunctions_reserveFooterSize(testIntersection,2);//space for radio to fill in CRC //send packet(Car) radio_send(testIntersection); } } break; case CAR: if (filt_norm < threshold){ FSMcounter--; state = PERHAPS; } break; default: break; } }
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; }
void bbk_task_cb() { OpenQueueEntry_t* pkt; error_t outcome; uint8_t numOptions; demo_t demoPayload; // create a CoAP RD packet pkt = openqueue_getFreePacketBuffer(0xcc); if (pkt==NULL) { openserial_printError(0xcc,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); openqueue_freePacketBuffer(pkt); return; } // take ownership over that packet pkt->creator = COMPONENT_BBK; //just a number randomly picked for this temp app pkt->owner = COMPONENT_BBK; // CoAP payload packetfunctions_reserveHeaderSize(pkt,sizeof(demo_t)); construct_demo(&demoPayload); memcpy((pkt->payload),&demoPayload,sizeof(demo_t)); numOptions = 0; // location-path option packetfunctions_reserveHeaderSize(pkt,sizeof(bbk_path0)-1); memcpy(&pkt->payload[0],&bbk_path0,sizeof(bbk_path0)-1); packetfunctions_reserveHeaderSize(pkt,1); pkt->payload[0] = (COAP_OPTION_LOCATIONPATH-COAP_OPTION_CONTENTTYPE) << 4 | sizeof(bbk_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->l4_destination_port = WKP_UDP_HDL; pkt->l3_destinationORsource.type = ADDR_128B; memcpy(&pkt->l3_destinationORsource.addr_128b[0],&ipAddr_local,16); // send if(bbk_vars.sequence<SAMPLE){ bbk_vars.sequence++; /*outcome = opencoap_send(pkt, COAP_TYPE_NON, COAP_CODE_REQ_PUT, numOptions, &bbk_vars.desc);*/ outcome = openudp_send(pkt); //call UDP directly bypassing CoAP } else{ opentimers_stop(bbk_vars.timerId); bbk_vars.sequence=0; openqueue_freePacketBuffer(pkt); } // avoid overflowing the queue if fails if (outcome==E_FAIL) { openqueue_freePacketBuffer(pkt); } return; }
/** \brief Send an advertisement. This is one of the MAC management tasks. This function inlines in the timers_res_fired() function, but is declared as a separate function for better readability of the code. */ port_INLINE void sixtop_sendEB() { OpenQueueEntry_t* adv; uint8_t len; len = 0; if (ieee154e_isSynch()==FALSE) { // I'm not sync'ed // delete packets genereted by this module (ADV and KA) from openqueue openqueue_removeAllCreatedBy(COMPONENT_SIXTOP); // I'm now busy sending an ADV sixtop_vars.busySendingEB = FALSE; // stop here return; } if (sixtop_vars.busySendingEB==TRUE) { // don't continue if I'm still sending a previous ADV } // if I get here, I will send an ADV // get a free packet buffer adv = openqueue_getFreePacketBuffer(COMPONENT_SIXTOP); if (adv==NULL) { openserial_printError(COMPONENT_SIXTOP,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); return; } // declare ownership over that packet adv->creator = COMPONENT_SIXTOP; adv->owner = COMPONENT_SIXTOP; // reserve space for ADV-specific header // reserving for IEs. len += processIE_prependSlotframeLinkIE(adv); len += processIE_prependSyncIE(adv); //add IE header processIE_prependMLMEIE(adv,len); // some l2 information about this packet adv->l2_frameType = IEEE154_TYPE_BEACON; adv->l2_nextORpreviousHop.type = ADDR_16B; adv->l2_nextORpreviousHop.addr_16b[0] = 0xff; adv->l2_nextORpreviousHop.addr_16b[1] = 0xff; //I has an IE in my payload adv->l2_IEListPresent = IEEE154_IELIST_YES; // put in queue for MAC to handle sixtop_send_internal(adv,IEEE154_IELIST_YES,IEEE154_FRAMEVERSION); // I'm now busy sending an ADV sixtop_vars.busySendingEB = TRUE; }
void sixtop_removeCell(open_addr_t* neighbor){ OpenQueueEntry_t* pkt; bool outcome; uint8_t len; uint8_t type; uint8_t frameID; uint8_t flag; cellInfo_ht cellList[SCHEDULEIEMAXNUMCELLS]; memset(cellList,0,sizeof(cellList)); // filter parameters if (sixtop_vars.six2six_state!=SIX_IDLE){ return; } if (neighbor==NULL){ return; } // generate candidate cell list outcome = sixtop_candidateRemoveCellList( &type, &frameID, &flag, cellList, neighbor ); if(outcome == FALSE){ return; } // get a free packet buffer pkt = openqueue_getFreePacketBuffer(COMPONENT_SIXTOP_RES); if(pkt==NULL) { openserial_printError( COMPONENT_SIXTOP_RES, ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0 ); return; } // update state sixtop_vars.six2six_state = SIX_SENDING_REMOVEREQUEST; // declare ownership over that packet pkt->creator = COMPONENT_SIXTOP_RES; pkt->owner = COMPONENT_SIXTOP_RES; memcpy( &(pkt->l2_nextORpreviousHop), neighbor, sizeof(open_addr_t) ); // create packet len = 0; len += processIE_prependSheduleIE(pkt,type,frameID, flag,cellList); len += processIE_prependOpcodeIE(pkt,SIXTOP_REMOVE_SOFT_CELL_REQUEST); processIE_prependMLMEIE(pkt,len); // indicate IEs present pkt->l2_IEListPresent = IEEE154_IELIST_YES; // send packet sixtop_send(pkt); // update state sixtop_vars.six2six_state = SIX_WAIT_REMOVEREQUEST_SENDDONE; // arm timeout opentimers_setPeriod( sixtop_vars.timeoutTimerId, TIME_MS, SIX2SIX_TIMEOUT_MS ); opentimers_restart(sixtop_vars.timeoutTimerId); }
void opentcp_receive(OpenQueueEntry_t* msg) { OpenQueueEntry_t* tempPkt; bool shouldIlisten; msg->owner = COMPONENT_OPENTCP; msg->l4_protocol = IANA_TCP; msg->l4_payload = msg->payload; msg->l4_length = msg->length; msg->l4_sourcePortORicmpv6Type = packetfunctions_ntohs((uint8_t*)&(((tcp_ht*)msg->payload)->source_port)); msg->l4_destination_port = packetfunctions_ntohs((uint8_t*)&(((tcp_ht*)msg->payload)->destination_port)); if ( tcp_vars.state!=TCP_STATE_CLOSED && ( msg->l4_destination_port != tcp_vars.myPort || msg->l4_sourcePortORicmpv6Type != tcp_vars.hisPort || packetfunctions_sameAddress(&(msg->l3_destinationAdd),&tcp_vars.hisIPv6Address)==FALSE ) ) { openqueue_freePacketBuffer(msg); return; } if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_YES,TCP_SYN_WHATEVER,TCP_FIN_WHATEVER)) { //I receive RST[+*], I reset opentcp_reset(); openqueue_freePacketBuffer(msg); } switch (tcp_vars.state) { case TCP_STATE_CLOSED: //[receive] establishement switch(msg->l4_destination_port) { case WKP_TCP_HTTP: shouldIlisten = ohlone_shouldIlisten(); break; case WKP_TCP_ECHO: shouldIlisten = tcpecho_shouldIlisten(); break; case WKP_TCP_INJECT: shouldIlisten = tcpinject_shouldIlisten(); break; case WKP_TCP_DISCARD: shouldIlisten = tcpprint_shouldIlisten(); break; default: openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, (errorparameter_t)msg->l4_sourcePortORicmpv6Type, (errorparameter_t)2); shouldIlisten = FALSE; break; } if ( containsControlBits(msg,TCP_ACK_NO,TCP_RST_NO,TCP_SYN_YES,TCP_FIN_NO) && shouldIlisten==TRUE ) { tcp_vars.myPort = msg->l4_destination_port; //I receive SYN, I send SYN+ACK tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; tcp_vars.hisPort = msg->l4_sourcePortORicmpv6Type; memcpy(&tcp_vars.hisIPv6Address,&(msg->l3_destinationAdd),sizeof(open_addr_t)); tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); if (tempPkt==NULL) { openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); openqueue_freePacketBuffer(msg); return; } tempPkt->creator = COMPONENT_OPENTCP; tempPkt->owner = COMPONENT_OPENTCP; memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); prependTCPHeader(tempPkt, TCP_ACK_YES, TCP_PSH_NO, TCP_RST_NO, TCP_SYN_YES, TCP_FIN_NO); tcp_vars.mySeqNum++; tcp_change_state(TCP_STATE_ALMOST_SYN_RECEIVED); forwarding_send(tempPkt); } else { opentcp_reset(); openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, (errorparameter_t)tcp_vars.state, (errorparameter_t)0); } openqueue_freePacketBuffer(msg); break; case TCP_STATE_SYN_SENT: //[receive] establishement if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_YES,TCP_FIN_NO)) { //I receive SYN+ACK, I send ACK tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); if (tempPkt==NULL) { openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); openqueue_freePacketBuffer(msg); return; } tempPkt->creator = COMPONENT_OPENTCP; tempPkt->owner = COMPONENT_OPENTCP; memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); prependTCPHeader(tempPkt, TCP_ACK_YES, TCP_PSH_NO, TCP_RST_NO, TCP_SYN_NO, TCP_FIN_NO); tcp_change_state(TCP_STATE_ALMOST_ESTABLISHED); forwarding_send(tempPkt); } else if (containsControlBits(msg,TCP_ACK_NO,TCP_RST_NO,TCP_SYN_YES,TCP_FIN_NO)) { //I receive SYN, I send SYN+ACK tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); if (tempPkt==NULL) { openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); openqueue_freePacketBuffer(msg); return; } tempPkt->creator = COMPONENT_OPENTCP; tempPkt->owner = COMPONENT_OPENTCP; memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); prependTCPHeader(tempPkt, TCP_ACK_YES, TCP_PSH_NO, TCP_RST_NO, TCP_SYN_YES, TCP_FIN_NO); tcp_vars.mySeqNum++; tcp_change_state(TCP_STATE_ALMOST_SYN_RECEIVED); forwarding_send(tempPkt); } else { opentcp_reset(); openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, (errorparameter_t)tcp_vars.state, (errorparameter_t)1); } openqueue_freePacketBuffer(msg); break; case TCP_STATE_SYN_RECEIVED: //[receive] establishement if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { //I receive ACK, the virtual circuit is established tcp_change_state(TCP_STATE_ESTABLISHED); } else { opentcp_reset(); openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, (errorparameter_t)tcp_vars.state, (errorparameter_t)2); } openqueue_freePacketBuffer(msg); break; case TCP_STATE_ESTABLISHED: //[receive] data/teardown if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { //I receive FIN[+ACK], I send ACK tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+msg->length-sizeof(tcp_ht)+1; tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); if (tempPkt==NULL) { openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); openqueue_freePacketBuffer(msg); return; } tempPkt->creator = COMPONENT_OPENTCP; tempPkt->owner = COMPONENT_OPENTCP; memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); prependTCPHeader(tempPkt, TCP_ACK_YES, TCP_PSH_NO, TCP_RST_NO, TCP_SYN_NO, TCP_FIN_NO); forwarding_send(tempPkt); tcp_change_state(TCP_STATE_ALMOST_CLOSE_WAIT); } else if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { //I receive data, I send ACK tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+msg->length-sizeof(tcp_ht); tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); if (tempPkt==NULL) { openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); openqueue_freePacketBuffer(msg); return; } tempPkt->creator = COMPONENT_OPENTCP; tempPkt->owner = COMPONENT_OPENTCP; memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); prependTCPHeader(tempPkt, TCP_ACK_YES, TCP_PSH_NO, TCP_RST_NO, TCP_SYN_NO, TCP_FIN_NO); forwarding_send(tempPkt); packetfunctions_tossHeader(msg,sizeof(tcp_ht)); tcp_vars.dataReceived = msg; tcp_change_state(TCP_STATE_ALMOST_DATA_RECEIVED); } else { opentcp_reset(); openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, (errorparameter_t)tcp_vars.state, (errorparameter_t)3); openqueue_freePacketBuffer(msg); } break; case TCP_STATE_DATA_SENT: //[receive] data if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { //I receive ACK, data message sent switch(tcp_vars.myPort) { case WKP_TCP_HTTP: ohlone_sendDone(tcp_vars.dataToSend,E_SUCCESS); break; case WKP_TCP_ECHO: tcpecho_sendDone(tcp_vars.dataToSend,E_SUCCESS); break; case WKP_TCP_INJECT: tcpinject_sendDone(tcp_vars.dataToSend,E_SUCCESS); break; case WKP_TCP_DISCARD: tcpprint_sendDone(tcp_vars.dataToSend,E_SUCCESS); break; default: openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, (errorparameter_t)tcp_vars.myPort, (errorparameter_t)3); break; } tcp_vars.dataToSend = NULL; tcp_change_state(TCP_STATE_ESTABLISHED); } else if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { //I receive FIN[+ACK], I send ACK switch(tcp_vars.myPort) { case WKP_TCP_HTTP: ohlone_sendDone(tcp_vars.dataToSend,E_SUCCESS); break; case WKP_TCP_ECHO: tcpecho_sendDone(tcp_vars.dataToSend,E_SUCCESS); break; case WKP_TCP_INJECT: tcpinject_sendDone(tcp_vars.dataToSend,E_SUCCESS); break; case WKP_TCP_DISCARD: tcpprint_sendDone(tcp_vars.dataToSend,E_SUCCESS); break; default: openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, (errorparameter_t)tcp_vars.myPort, (errorparameter_t)4); break; } tcp_vars.dataToSend = NULL; tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+msg->length-sizeof(tcp_ht)+1; tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); if (tempPkt==NULL) { openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); openqueue_freePacketBuffer(msg); return; } tempPkt->creator = COMPONENT_OPENTCP; tempPkt->owner = COMPONENT_OPENTCP; memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); prependTCPHeader(tempPkt, TCP_ACK_YES, TCP_PSH_NO, TCP_RST_NO, TCP_SYN_NO, TCP_FIN_NO); forwarding_send(tempPkt); tcp_change_state(TCP_STATE_ALMOST_CLOSE_WAIT); } else { opentcp_reset(); openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, (errorparameter_t)tcp_vars.state, (errorparameter_t)4); } openqueue_freePacketBuffer(msg); break; case TCP_STATE_FIN_WAIT_1: //[receive] teardown if (containsControlBits(msg,TCP_ACK_NO,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { //I receive FIN, I send ACK tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); if (tempPkt==NULL) { openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); openqueue_freePacketBuffer(msg); return; } tempPkt->creator = COMPONENT_OPENTCP; tempPkt->owner = COMPONENT_OPENTCP; memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); prependTCPHeader(tempPkt, TCP_ACK_YES, TCP_PSH_NO, TCP_RST_NO, TCP_SYN_NO, TCP_FIN_NO); forwarding_send(tempPkt); tcp_change_state(TCP_STATE_ALMOST_CLOSING); } else if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { //I receive FIN+ACK, I send ACK tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); if (tempPkt==NULL) { openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); openqueue_freePacketBuffer(msg); return; } tempPkt->creator = COMPONENT_OPENTCP; tempPkt->owner = COMPONENT_OPENTCP; memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); prependTCPHeader(tempPkt, TCP_ACK_YES, TCP_PSH_NO, TCP_RST_NO, TCP_SYN_NO, TCP_FIN_NO); forwarding_send(tempPkt); tcp_change_state(TCP_STATE_ALMOST_TIME_WAIT); } else if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { //I receive ACK, I will receive FIN later tcp_change_state(TCP_STATE_FIN_WAIT_2); } else { opentcp_reset(); openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, (errorparameter_t)tcp_vars.state, (errorparameter_t)5); } openqueue_freePacketBuffer(msg); break; case TCP_STATE_FIN_WAIT_2: //[receive] teardown if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { //I receive FIN[+ACK], I send ACK tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); if (tempPkt==NULL) { openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); openqueue_freePacketBuffer(msg); return; } tempPkt->creator = COMPONENT_OPENTCP; tempPkt->owner = COMPONENT_OPENTCP; memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); prependTCPHeader(tempPkt, TCP_ACK_YES, TCP_PSH_NO, TCP_RST_NO, TCP_SYN_NO, TCP_FIN_NO); forwarding_send(tempPkt); tcp_change_state(TCP_STATE_ALMOST_TIME_WAIT); } openqueue_freePacketBuffer(msg); break; case TCP_STATE_CLOSING: //[receive] teardown if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { //I receive ACK, I do nothing tcp_change_state(TCP_STATE_TIME_WAIT); //TODO implement waiting timer opentcp_reset(); } openqueue_freePacketBuffer(msg); break; case TCP_STATE_LAST_ACK: //[receive] teardown if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { //I receive ACK, I reset opentcp_reset(); } openqueue_freePacketBuffer(msg); break; default: openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, (errorparameter_t)tcp_vars.state, (errorparameter_t)4); break; } }
void opentcp_sendDone(OpenQueueEntry_t* msg, owerror_t error) { OpenQueueEntry_t* tempPkt; msg->owner = COMPONENT_OPENTCP; switch (tcp_vars.state) { case TCP_STATE_ALMOST_SYN_SENT: //[sendDone] establishement openqueue_freePacketBuffer(msg); tcp_change_state(TCP_STATE_SYN_SENT); break; case TCP_STATE_ALMOST_SYN_RECEIVED: //[sendDone] establishement openqueue_freePacketBuffer(msg); tcp_change_state(TCP_STATE_SYN_RECEIVED); break; case TCP_STATE_ALMOST_ESTABLISHED: //[sendDone] establishement openqueue_freePacketBuffer(msg); tcp_change_state(TCP_STATE_ESTABLISHED); switch(tcp_vars.myPort) { case WKP_TCP_HTTP: ohlone_connectDone(E_SUCCESS); break; case WKP_TCP_ECHO: tcpecho_connectDone(E_SUCCESS); break; case WKP_TCP_INJECT: tcpinject_connectDone(E_SUCCESS); break; case WKP_TCP_DISCARD: tcpprint_connectDone(E_SUCCESS); break; default: openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, (errorparameter_t)tcp_vars.myPort, (errorparameter_t)0); break; } break; case TCP_STATE_ALMOST_DATA_SENT: //[sendDone] data tcp_change_state(TCP_STATE_DATA_SENT); break; case TCP_STATE_ALMOST_DATA_RECEIVED: //[sendDone] data openqueue_freePacketBuffer(msg); tcp_change_state(TCP_STATE_ESTABLISHED); switch(tcp_vars.myPort) { case WKP_TCP_HTTP: ohlone_receive(tcp_vars.dataReceived); break; case WKP_TCP_ECHO: tcpecho_receive(tcp_vars.dataReceived); break; case WKP_TCP_INJECT: tcpinject_receive(tcp_vars.dataReceived); break; case WKP_TCP_DISCARD: tcpprint_receive(tcp_vars.dataReceived); break; default: openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, (errorparameter_t)tcp_vars.myPort, (errorparameter_t)1); openqueue_freePacketBuffer(msg); tcp_vars.dataReceived = NULL; break; } break; case TCP_STATE_ALMOST_FIN_WAIT_1: //[sendDone] teardown openqueue_freePacketBuffer(msg); tcp_change_state(TCP_STATE_FIN_WAIT_1); break; case TCP_STATE_ALMOST_CLOSING: //[sendDone] teardown openqueue_freePacketBuffer(msg); tcp_change_state(TCP_STATE_CLOSING); break; case TCP_STATE_ALMOST_TIME_WAIT: //[sendDone] teardown openqueue_freePacketBuffer(msg); tcp_change_state(TCP_STATE_TIME_WAIT); //TODO implement waiting timer opentcp_reset(); break; case TCP_STATE_ALMOST_CLOSE_WAIT: //[sendDone] teardown openqueue_freePacketBuffer(msg); tcp_change_state(TCP_STATE_CLOSE_WAIT); //I send FIN+ACK tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); if (tempPkt==NULL) { openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); openqueue_freePacketBuffer(msg); return; } tempPkt->creator = COMPONENT_OPENTCP; tempPkt->owner = COMPONENT_OPENTCP; memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); prependTCPHeader(tempPkt, TCP_ACK_YES, TCP_PSH_NO, TCP_RST_NO, TCP_SYN_NO, TCP_FIN_YES); forwarding_send(tempPkt); tcp_change_state(TCP_STATE_ALMOST_LAST_ACK); break; case TCP_STATE_ALMOST_LAST_ACK: //[sendDone] teardown openqueue_freePacketBuffer(msg); tcp_change_state(TCP_STATE_LAST_ACK); break; default: openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, (errorparameter_t)tcp_vars.state, (errorparameter_t)3); break; } }