uint8_t keyDescriptorLookup(uint8_t KeyIdMode, open_addr_t* keySource, uint8_t KeyIndex, open_addr_t* DeviceAddress, //open_addr_t* panID, uint8_t frameType){ uint8_t i; if(KeyIdMode == 0){ if(neighbors_haveSomeChild() == TRUE){ DeviceAddress = idmanager_getMyID(ADDR_64B); }else{ DeviceAddress = keySource; } for(i=0; i<MAXNUMKEYS; i++ ){ if(packetfunctions_sameAddress(DeviceAddress,MacKeyTable.KeyDescriptorElement[i].KeyIdLookupList.Address)){ //match = i; return i; } } } //commented to SAVE ROM /*uint8_t j; if (KeyIdMode == 1){ for(i=0; i<MAXNUMKEYS; i++ ){ uint8_t j; for(j=0; j<MAXNUMNEIGHBORS; j++){ if(KeyIndex == macKeyTab.KeyDescriptorElement[i].KeyIdLookupList.KeyIndex && packetfunctions_sameAddress(keySource,macDefaultKeySource)){ return i; } } } }*/ if (KeyIdMode == 3){//even if KeyIdMode == 2, we not explicite this condition to save ROM for(i=0; i<MAXNUMKEYS; i++ ){ if(KeyIndex == MacKeyTable.KeyDescriptorElement[i].KeyIdLookupList.KeyIndex){ if( packetfunctions_sameAddress(keySource,MacKeyTable.KeyDescriptorElement[i].KeyIdLookupList.KeySource) //&& packetfunctions_sameAddress(panID, macKeyTab.KeyDescriptorElement[i].KeyIdLookupList.PANId) ){ return i; } } } } return 25;//no matches }
/** \brief get the information of a spcific slot. \param slotOffset \param neighbor \param info */ void schedule_getSlotInfo( slotOffset_t slotOffset, open_addr_t* neighbor, slotinfo_element_t* info ){ scheduleEntry_t* slotContainer; // find an empty schedule entry container slotContainer = &schedule_vars.scheduleBuf[0]; while (slotContainer->type!=CELLTYPE_OFF && slotContainer<=&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) { //check that this entry for that neighbour and timeslot is not already scheduled. if (packetfunctions_sameAddress(neighbor,&(slotContainer->neighbor))&& (slotContainer->slotOffset==slotOffset)){ //it exists so this is an update. info->link_type = slotContainer->type; info->shared =slotContainer->shared; info->channelOffset = slotContainer->channelOffset; return; //as this is an update. No need to re-insert as it is in the same position on the list. } slotContainer++; } //return cell type off. info->link_type = CELLTYPE_OFF; info->shared = FALSE; info->channelOffset = 0;//set to zero if not set. }
OpenQueueEntry_t* openqueue_macGetDataPacket(open_addr_t* toNeighbor) { uint8_t i; INTERRUPT_DECLARATION(); DISABLE_INTERRUPTS(); if (toNeighbor->type==ADDR_64B) { // a neighbor is specified, look for a packet unicast to that neigbhbor for (i=0;i<QUEUELENGTH;i++) { if (openqueue_vars.queue[i].owner==COMPONENT_RES_TO_IEEE802154E && packetfunctions_sameAddress(toNeighbor,&openqueue_vars.queue[i].l2_nextORpreviousHop)) { ENABLE_INTERRUPTS(); return &openqueue_vars.queue[i]; } } } else if (toNeighbor->type==ADDR_ANYCAST) { // anycast case: look for a packet which is either not created by RES // or an KA (created by RES, but not broadcast) for (i=0;i<QUEUELENGTH;i++) { if (openqueue_vars.queue[i].owner==COMPONENT_RES_TO_IEEE802154E && ( openqueue_vars.queue[i].creator!=COMPONENT_RES || ( openqueue_vars.queue[i].creator==COMPONENT_RES && packetfunctions_isBroadcastMulticast(&(openqueue_vars.queue[i].l2_nextORpreviousHop))==FALSE ) ) ) { ENABLE_INTERRUPTS(); return &openqueue_vars.queue[i]; } } } ENABLE_INTERRUPTS(); return NULL; }
/** \brief Calculated how many slots have elapsed since last synchronized. \param[in] timeCorrection time to be corrected \param[in] timesource The address of neighbor. \return the number of slots */ void adaptive_sync_preprocess(int16_t timeCorrection, open_addr_t timesource){ uint8_t array[5]; // stop calculating compensation period when compensateThreshold exceeds KATIMEOUT and drift is not changed if( adaptive_sync_vars.compensateThreshold > MAXKAPERIOD && adaptive_sync_vars.driftChanged == FALSE ) { if(timeCorrection > LIMITLARGETIMECORRECTION) { //once I get a large time correction, it means previous calcluated drift is not accurate yet. The clock drift is changed. adaptive_sync_driftChanged(); } return; } // check whether I am synchronized and also check whether it's the same neighbor synchronized to last time? if( adaptive_sync_vars.driftChanged == FALSE && ieee154e_isSynch() && packetfunctions_sameAddress(×ource, &(adaptive_sync_vars.compensationInfo_vars.neighborID)) ) { // only calcluate when asnDiff > compensateThresholdThreshold. (this is used for guaranteeing accuracy ) if(ieee154e_asnDiff(&adaptive_sync_vars.oldASN) > adaptive_sync_vars.compensateThreshold) { // calculate compensation interval adaptive_sync_calculateCompensatedSlots(timeCorrection); // reset compensationtTicks and sumOfTC after calculation adaptive_sync_vars.compensateTicks = 0; adaptive_sync_vars.sumOfTC = 0; // update threshold adaptive_sync_vars.compensateThreshold *= 2; sixtop_setKaPeriod(adaptive_sync_vars.compensateThreshold); // update oldASN ieee154e_getAsn(array); adaptive_sync_vars.oldASN.bytes0and1 = ((uint16_t) array[1] << 8) | ((uint16_t) array[0]); adaptive_sync_vars.oldASN.bytes2and3 = ((uint16_t) array[3] << 8) | ((uint16_t) array[2]); adaptive_sync_vars.oldASN.byte4 = array[4]; } else { // record the timeCorrection, if not calculate. adaptive_sync_vars.sumOfTC += timeCorrection; } } else { adaptive_sync_vars.compensateThreshold = BASIC_COMPENSATION_THRESHOLD; sixtop_setKaPeriod(adaptive_sync_vars.compensateThreshold); // when I joined the network, or changed my time parent, reset adaptive_sync relative variables adaptive_sync_vars.clockState = S_NONE; adaptive_sync_vars.elapsedSlots = 0; adaptive_sync_vars.compensationTimeout = 0; adaptive_sync_vars.compensateTicks = 0; adaptive_sync_vars.sumOfTC = 0; // update oldASN ieee154e_getAsn(array); adaptive_sync_vars.oldASN.bytes0and1 = ((uint16_t) array[1] << 8) | ((uint16_t) array[0]); adaptive_sync_vars.oldASN.bytes2and3 = ((uint16_t) array[3] << 8) | ((uint16_t) array[2]); adaptive_sync_vars.oldASN.byte4 = array[4]; // record this neighbor as my time source memcpy(&(adaptive_sync_vars.compensationInfo_vars.neighborID), ×ource, sizeof(open_addr_t)); } }
bool isThisRowMatching(open_addr_t* address, uint8_t rowNumber) { switch (address->type) { case ADDR_64B: return neighbors_vars.neighbors[rowNumber].used && packetfunctions_sameAddress(address,&neighbors_vars.neighbors[rowNumber].addr_64b); default: openserial_printError(COMPONENT_NEIGHBORS,ERR_WRONG_ADDR_TYPE, (errorparameter_t)address->type, (errorparameter_t)3); return FALSE; } }
bool idmanager_isMyAddress(open_addr_t* addr) { open_addr_t temp_my128bID; bool res; INTERRUPT_DECLARATION(); DISABLE_INTERRUPTS(); switch (addr->type) { case ADDR_16B: res= packetfunctions_sameAddress(addr,&idmanager_vars.my16bID); ENABLE_INTERRUPTS(); return res; case ADDR_64B: res= packetfunctions_sameAddress(addr,&idmanager_vars.my64bID); ENABLE_INTERRUPTS(); return res; case ADDR_128B: //build temporary my128bID temp_my128bID.type = ADDR_128B; memcpy(&temp_my128bID.addr_128b[0],&idmanager_vars.myPrefix.prefix,8); memcpy(&temp_my128bID.addr_128b[8],&idmanager_vars.my64bID.addr_64b,8); res= packetfunctions_sameAddress(addr,&temp_my128bID); ENABLE_INTERRUPTS(); return res; case ADDR_PANID: res= packetfunctions_sameAddress(addr,&idmanager_vars.myPANID); ENABLE_INTERRUPTS(); return res; case ADDR_PREFIX: res= packetfunctions_sameAddress(addr,&idmanager_vars.myPrefix); ENABLE_INTERRUPTS(); return res; default: openserial_printCritical(COMPONENT_IDMANAGER,ERR_WRONG_ADDR_TYPE, (errorparameter_t)addr->type, (errorparameter_t)2); ENABLE_INTERRUPTS(); return FALSE; } }
uint8_t deviceDescriptorLookup(open_addr_t* Address, //open_addr_t* PANId, m_keyDescriptor* keydescr){ //commented to save ROM /*open_addr_t* aux; if(Address->type == IEEE154_ADDR_NONE){ //vado a prendere PANID, ShortAddress o Extended Address dal coordinator Address->type = ADDR_PANID; memcpy(Address->panid, (idmanager_getMyID(ADDR_PANID)->panid),sizeof(uint8_t)*2); } aux->addr_16b[1] = 255 ; aux->addr_16b[0] = 254 ; if(Address->type == IEEE154_ADDR_NONE && idmanager_getMyID(ADDR_16B) == aux){//questo significa che il dispositivo sta usando solo il suo extended address Address->type = ADDR_64B; memcpy(Address->addr_64b,(idmanager_getMyID(ADDR_64B)->addr_64b),sizeof(uint8_t)*8); } else{ aux->addr_16b[1] = 255 ; aux->addr_16b[0] = 255 ; if(Address->type == IEEE154_ADDR_NONE && idmanager_getMyID(ADDR_16B) == aux){ return answer; } }*/ uint8_t i; for(i=0; i<MAXNUMNEIGHBORS; i++){ if(packetfunctions_sameAddress(Address,keydescr->DeviceTable->DeviceDescriptorEntry[i].deviceAddress)== TRUE){ return i; } } //return 25; }
owerror_t schedule_removeActiveSlot(slotOffset_t slotOffset, open_addr_t* neighbor){ owerror_t outcome; scheduleEntry_t* slotContainer; scheduleEntry_t* previousSlotWalker; INTERRUPT_DECLARATION(); DISABLE_INTERRUPTS(); // find the schedule entry slotContainer = &schedule_vars.scheduleBuf[0]; while (slotContainer->type!=CELLTYPE_OFF && slotContainer<=&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) { //check that this entry for that neighbour and timeslot is not already scheduled. if (packetfunctions_sameAddress(neighbor,&(slotContainer->neighbor))&& (slotContainer->slotOffset==slotOffset)){ break; } slotContainer++; } if (slotContainer->next==slotContainer) { // this is the last active slot // the next slot of this slot is NULL slotContainer->next = NULL; // current slot points to this slot schedule_vars.currentScheduleEntry = NULL; } else { // this is NOT the last active slot // find the previous in the schedule previousSlotWalker = schedule_vars.currentScheduleEntry; while (1) { if (previousSlotWalker->next=slotContainer){ break; } previousSlotWalker = previousSlotWalker->next; } // remove this element from the linked list previousSlotWalker->next = slotContainer->next;//my next; slotContainer->next = NULL; } // clear that schedule entry slotContainer->slotOffset = 0; slotContainer->type = CELLTYPE_OFF; slotContainer->shared = FALSE; slotContainer->channelOffset = 0; memset(&slotContainer->neighbor,0,sizeof(open_addr_t)); // maintain debug stats schedule_dbg.numActiveSlotsCur--; outcome=E_SUCCESS; ENABLE_INTERRUPTS(); return outcome; }
/** \brief Add a new active slot into the schedule. If udpate param is set then update it in case it exists. \param slotOffset \param type \param shared \param channelOffset \param neighbor \param isUpdate */ owerror_t schedule_addActiveSlot( slotOffset_t slotOffset, cellType_t type, bool shared, channelOffset_t channelOffset, open_addr_t* neighbor, bool isUpdate ) { owerror_t outcome; scheduleEntry_t* slotContainer; scheduleEntry_t* previousSlotWalker; scheduleEntry_t* nextSlotWalker; INTERRUPT_DECLARATION(); DISABLE_INTERRUPTS(); // find an empty schedule entry container slotContainer = &schedule_vars.scheduleBuf[0]; while (slotContainer->type!=CELLTYPE_OFF && slotContainer<=&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) { //check that this entry for that neighbour and timeslot is not already scheduled. if (type!=CELLTYPE_SERIALRX && type!=CELLTYPE_MORESERIALRX && (packetfunctions_sameAddress(neighbor,&(slotContainer->neighbor))|| (slotContainer->neighbor.type==ADDR_ANYCAST && isUpdate==TRUE)) &&(slotContainer->slotOffset==slotOffset)){ //it exists so this is an update. slotContainer->type = type; slotContainer->shared = shared; slotContainer->channelOffset = channelOffset; memcpy(&slotContainer->neighbor,neighbor,sizeof(open_addr_t));//update the address too! schedule_dbg.numUpdatedSlotsCur++; ENABLE_INTERRUPTS(); return E_SUCCESS; //as this is an update. No need to re-insert as it is in the same position on the list. } slotContainer++; } if (isUpdate==TRUE) { //we are trying to update an item that is not in the schedule list. ENABLE_INTERRUPTS(); return E_FAIL; } if (slotContainer>&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) { // schedule has overflown outcome=E_FAIL; openserial_printCritical(COMPONENT_SCHEDULE,ERR_SCHEDULE_OVERFLOWN, (errorparameter_t)0, (errorparameter_t)0); } // fill that schedule entry with parameters passed slotContainer->slotOffset = slotOffset; slotContainer->type = type; slotContainer->shared = shared; slotContainer->channelOffset = channelOffset; memcpy(&slotContainer->neighbor,neighbor,sizeof(open_addr_t)); if (schedule_vars.currentScheduleEntry==NULL) { // this is the first active slot added // the next slot of this slot is this slot slotContainer->next = slotContainer; // current slot points to this slot schedule_vars.currentScheduleEntry = slotContainer; } else { // this is NOT the first active slot added // find position in schedule previousSlotWalker = schedule_vars.currentScheduleEntry; while (1) { nextSlotWalker = previousSlotWalker->next; if ( ( (previousSlotWalker->slotOffset < slotContainer->slotOffset) && (slotContainer->slotOffset < nextSlotWalker->slotOffset) ) || ( (previousSlotWalker->slotOffset < slotContainer->slotOffset) && (nextSlotWalker->slotOffset <= previousSlotWalker->slotOffset) ) || ( (slotContainer->slotOffset < nextSlotWalker->slotOffset) && (nextSlotWalker->slotOffset <= previousSlotWalker->slotOffset) ) ) { break; } previousSlotWalker = nextSlotWalker; } // insert between previousSlotWalker and nextSlotWalker previousSlotWalker->next = slotContainer; slotContainer->next = nextSlotWalker; } // maintain debug stats schedule_dbg.numActiveSlotsCur++; if (schedule_dbg.numActiveSlotsCur>schedule_dbg.numActiveSlotsMax) { schedule_dbg.numActiveSlotsMax = schedule_dbg.numActiveSlotsCur; } outcome=E_SUCCESS; ENABLE_INTERRUPTS(); return outcome; }
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; } }
/** \brief Send a packet originating at this mote. This function is called by an upper layer, and only concerns packets originated at this mote. \param[in,out] msg Packet to send. */ owerror_t forwarding_send(OpenMote* self, OpenQueueEntry_t* msg) { ipv6_header_iht ipv6_outer_header; ipv6_header_iht ipv6_inner_header; rpl_option_ht rpl_option; open_addr_t* myprefix; open_addr_t* myadd64; uint32_t flow_label = 0; open_addr_t temp_dest_prefix; open_addr_t temp_dest_mac64b; open_addr_t* p_dest; open_addr_t* p_src; open_addr_t temp_src_prefix; open_addr_t temp_src_mac64b; uint8_t sam; uint8_t m; uint8_t dam; // take ownership over the packet msg->owner = COMPONENT_FORWARDING; m = IPHC_M_NO; // retrieve my prefix and EUI64 myprefix = idmanager_getMyID(self, ADDR_PREFIX); myadd64 = idmanager_getMyID(self, ADDR_64B); // set source address (me) msg->l3_sourceAdd.type=ADDR_128B; memcpy(&(msg->l3_sourceAdd.addr_128b[0]),myprefix->prefix,8); memcpy(&(msg->l3_sourceAdd.addr_128b[8]),myadd64->addr_64b,8); // initialize IPv6 header memset(&ipv6_outer_header,0,sizeof(ipv6_header_iht)); memset(&ipv6_inner_header,0,sizeof(ipv6_header_iht)); // Set hop limit to the default in-network value as this packet is being // sent from upper layer. This is done here as send_internal() is used by // forwarding of packets as well which carry a hlim. This value is required // to be set to a value as the following function can decrement it. ipv6_inner_header.hop_limit = IPHC_DEFAULT_HOP_LIMIT; // create the RPL hop-by-hop option forwarding_createRplOption(self, &rpl_option, // rpl_option to fill in 0x00 // flags ); packetfunctions_ip128bToMac64b(self, &(msg->l3_destinationAdd),&temp_dest_prefix,&temp_dest_mac64b); //xv poipoi -- get the src prefix as well packetfunctions_ip128bToMac64b(self, &(msg->l3_sourceAdd),&temp_src_prefix,&temp_src_mac64b); //XV -poipoi we want to check if the source address prefix is the same as destination prefix if ( packetfunctions_sameAddress(self, &temp_dest_prefix,&temp_src_prefix)) { // same prefix use 64B address sam = IPHC_SAM_64B; dam = IPHC_DAM_64B; p_dest = &temp_dest_mac64b; p_src = &temp_src_mac64b; } else { //not the same prefix. so the packet travels to another network //check if this is a source routing pkt. in case it is then the DAM is elided as it is in the SrcRouting header. if ( packetfunctions_isBroadcastMulticast(self, &(msg->l3_destinationAdd))==FALSE){ sam = IPHC_SAM_128B; dam = IPHC_DAM_128B; p_dest = &(msg->l3_destinationAdd); p_src = &(msg->l3_sourceAdd); ipv6_outer_header.src.type = ADDR_128B; memcpy(&ipv6_outer_header.src,p_src,sizeof(open_addr_t)); ipv6_outer_header.hop_limit = IPHC_DEFAULT_HOP_LIMIT; } else { // this is DIO, source address elided, multicast bit is set sam = IPHC_SAM_ELIDED; m = IPHC_M_YES; dam = IPHC_DAM_ELIDED; p_dest = &(msg->l3_destinationAdd); p_src = &(msg->l3_sourceAdd); } } //IPHC inner header and NHC IPv6 header will be added at here iphc_prependIPv6Header(self, msg, IPHC_TF_ELIDED, flow_label, // value_flowlabel IPHC_NH_INLINE, msg->l4_protocol, IPHC_HLIM_64, ipv6_outer_header.hop_limit, IPHC_CID_NO, IPHC_SAC_STATELESS, sam, m, IPHC_DAC_STATELESS, dam, p_dest, p_src, PCKTSEND ); // both of them are compressed ipv6_outer_header.next_header_compressed = TRUE; return forwarding_send_internal_RoutingTable(self, msg, &ipv6_outer_header, &ipv6_inner_header, &rpl_option, &flow_label, PCKTSEND ); }
/** \brief Send a packet using the source rout to find the next hop. \note This is always called for packets being forwarded. How to process the routing header is detailed in http://tools.ietf.org/html/rfc6554#page-9. \param[in,out] msg The packet to send. \param[in] ipv6_header The packet's IPv6 header. */ owerror_t forwarding_send_internal_SourceRouting(OpenMote* self, OpenQueueEntry_t* msg, ipv6_header_iht* ipv6_outer_header, ipv6_header_iht* ipv6_inner_header, rpl_option_ht* rpl_option ) { uint8_t temp_8b; uint8_t type; uint8_t next_type; uint8_t size; uint8_t next_size; uint8_t hlen; open_addr_t firstAddr; open_addr_t nextAddr; open_addr_t temp_prefix; open_addr_t temp_addr64; uint8_t rpi_length; uint8_t flags; uint16_t senderRank; uint8_t RH3_copy[127]; uint8_t RH3_length; memset(&RH3_copy[0],0,127); RH3_length = 0; memcpy(&msg->l3_destinationAdd,&ipv6_inner_header->dest,sizeof(open_addr_t)); memcpy(&msg->l3_sourceAdd,&ipv6_inner_header->src,sizeof(open_addr_t)); // initial first Address by compression reference firstAddr.type = ADDR_128B; if (ipv6_outer_header->src.type != ADDR_NONE){ if (rpl_option->rplInstanceID == 0){ icmpv6rpl_getRPLDODAGid(self, &firstAddr.addr_128b[0]); } } else { memcpy(&firstAddr,&ipv6_inner_header->src,sizeof(open_addr_t)); } hlen = 0; temp_8b = *((uint8_t*)(msg->payload)+hlen); type = *((uint8_t*)(msg->payload)+hlen+1); hlen += 2; // get the first address switch(type){ case RH3_6LOTH_TYPE_0: memcpy(&firstAddr.addr_128b[15],msg->payload+hlen,1); hlen += 1; break; case RH3_6LOTH_TYPE_1: memcpy(&firstAddr.addr_128b[14],msg->payload+hlen,2); hlen += 2; break; case RH3_6LOTH_TYPE_2: memcpy(&firstAddr.addr_128b[12],msg->payload+hlen,4); hlen += 4; break; case RH3_6LOTH_TYPE_3: memcpy(&firstAddr.addr_128b[8],msg->payload+hlen,8); hlen += 8; break; case RH3_6LOTH_TYPE_4: memcpy(&firstAddr.addr_128b[0],msg->payload+hlen,16); hlen += 16; break; } packetfunctions_ip128bToMac64b(self, &firstAddr,&temp_prefix,&temp_addr64); if ( packetfunctions_sameAddress(self, &temp_prefix, idmanager_getMyID(self, ADDR_PREFIX)) && packetfunctions_sameAddress(self, &temp_addr64, idmanager_getMyID(self, ADDR_64B)) ){ size = temp_8b & RH3_6LOTH_SIZE_MASK; if (size > 0){ // there are at least 2 entries in the header, // the router removes the first entry and decrements the Size (by 1) size -= 1; packetfunctions_tossHeader(self, msg,hlen); packetfunctions_reserveHeaderSize(self, msg,2); msg->payload[0] = CRITICAL_6LORH | size; msg->payload[1] = type; // get next hop memcpy(&nextAddr,&firstAddr,sizeof(open_addr_t)); switch(type){ case RH3_6LOTH_TYPE_0: memcpy(&nextAddr.addr_128b[15],msg->payload+2,1); break; case RH3_6LOTH_TYPE_1: memcpy(&nextAddr.addr_128b[14],msg->payload+2,2); break; case RH3_6LOTH_TYPE_2: memcpy(&nextAddr.addr_128b[12],msg->payload+2,4); break; case RH3_6LOTH_TYPE_3: memcpy(&nextAddr.addr_128b[8],msg->payload+2,8); break; case RH3_6LOTH_TYPE_4: memcpy(&nextAddr.addr_128b[0],msg->payload+2,16); break; } packetfunctions_ip128bToMac64b(self, &nextAddr, &temp_prefix, &msg->l2_nextORpreviousHop ); } else { temp_8b = *((uint8_t*)(msg->payload)+hlen); next_type = *((uint8_t*)(msg->payload)+hlen+1); if ( (temp_8b & FORMAT_6LORH_MASK) == CRITICAL_6LORH && next_type<=RH3_6LOTH_TYPE_4 ) { // there is another RH3-6LoRH following, check the type if (next_type >= type){ packetfunctions_tossHeader(self, msg,hlen); // get next hop memcpy(&nextAddr,&firstAddr,sizeof(open_addr_t)); switch(next_type){ case RH3_6LOTH_TYPE_0: memcpy(&nextAddr.addr_128b[15],msg->payload+2,1); break; case RH3_6LOTH_TYPE_1: memcpy(&nextAddr.addr_128b[14],msg->payload+2,2); break; case RH3_6LOTH_TYPE_2: memcpy(&nextAddr.addr_128b[12],msg->payload+2,4); break; case RH3_6LOTH_TYPE_3: memcpy(&nextAddr.addr_128b[8],msg->payload+2,8); break; case RH3_6LOTH_TYPE_4: memcpy(&nextAddr.addr_128b[0],msg->payload+2,16); break; } packetfunctions_ip128bToMac64b(self, &nextAddr, &temp_prefix, &msg->l2_nextORpreviousHop ); } else { hlen += 2; switch(next_type){ case RH3_6LOTH_TYPE_0: memcpy(&firstAddr.addr_128b[15],msg->payload+hlen,1); hlen += 1; break; case RH3_6LOTH_TYPE_1: memcpy(&firstAddr.addr_128b[14],msg->payload+hlen,2); hlen += 2; break; case RH3_6LOTH_TYPE_2: memcpy(&firstAddr.addr_128b[12],msg->payload+hlen,4); hlen += 4; break; case RH3_6LOTH_TYPE_3: memcpy(&firstAddr.addr_128b[8],msg->payload+hlen,8); hlen += 8; break; } next_size = temp_8b & RH3_6LOTH_SIZE_MASK; packetfunctions_tossHeader(self, msg,hlen); if (next_size>0){ next_size -= 1; packetfunctions_reserveHeaderSize(self, msg,2); msg->payload[0] = CRITICAL_6LORH | next_size; msg->payload[1] = next_type; } // add first address switch(type){ case RH3_6LOTH_TYPE_0: packetfunctions_reserveHeaderSize(self, msg,1); msg->payload[0] = firstAddr.addr_128b[15]; break; case RH3_6LOTH_TYPE_1: packetfunctions_reserveHeaderSize(self, msg,2); memcpy(&msg->payload[0],&firstAddr.addr_128b[14],2); break; case RH3_6LOTH_TYPE_2: packetfunctions_reserveHeaderSize(self, msg,4); memcpy(&msg->payload[0],&firstAddr.addr_128b[12],4); break; case RH3_6LOTH_TYPE_3: packetfunctions_reserveHeaderSize(self, msg,8); memcpy(&msg->payload[0],&firstAddr.addr_128b[8],8); break; case RH3_6LOTH_TYPE_4: packetfunctions_reserveHeaderSize(self, msg,16); memcpy(&msg->payload[0],&firstAddr.addr_128b[0],16); break; } packetfunctions_reserveHeaderSize(self, msg,2); msg->payload[0] = CRITICAL_6LORH | 0; msg->payload[1] = type; packetfunctions_ip128bToMac64b(self, &firstAddr, &temp_prefix, &msg->l2_nextORpreviousHop ); } } else { // there is no next RH3-6loRH, remove current one packetfunctions_tossHeader(self, msg,hlen); packetfunctions_ip128bToMac64b(self, &msg->l3_destinationAdd, &temp_prefix, &msg->l2_nextORpreviousHop ); } } } else { // log error openserial_printError(self, COMPONENT_IPHC, ERR_6LOWPAN_UNSUPPORTED, (errorparameter_t)16, (errorparameter_t)(temp_addr64.addr_64b[7]) ); } // copy RH3s before toss them if ( ipv6_outer_header->src.type != ADDR_NONE && ipv6_outer_header->hopByhop_option != NULL ){ // check the length of RH3s RH3_length = ipv6_outer_header->hopByhop_option-msg->payload; memcpy(&RH3_copy[0],msg->payload,RH3_length); packetfunctions_tossHeader(self, msg,RH3_length); // retrieve hop-by-hop header (includes RPL option) rpi_length = iphc_retrieveIPv6HopByHopHeader(self, msg, rpl_option ); // toss the headers packetfunctions_tossHeader(self, msg, rpi_length ); flags = rpl_option->flags; senderRank = rpl_option->senderRank; if ((flags & O_FLAG)!=O_FLAG){ // wrong direction // log error openserial_printError(self, COMPONENT_FORWARDING, ERR_WRONG_DIRECTION, (errorparameter_t)flags, (errorparameter_t)senderRank ); } if (senderRank > neighbors_getMyDAGrank(self)){ // loop detected // set flag rpl_option->flags |= R_FLAG; // log error openserial_printError(self, COMPONENT_FORWARDING, ERR_LOOP_DETECTED, (errorparameter_t) senderRank, (errorparameter_t) neighbors_getMyDAGrank(self) ); } forwarding_createRplOption(self, rpl_option, rpl_option->flags); // toss the IP in IP 6LoRH packetfunctions_tossHeader(self, msg, ipv6_outer_header->header_length); } else { RH3_length = 0; } // send to next lower layer return iphc_sendFromForwarding(self, msg, ipv6_outer_header, ipv6_inner_header, rpl_option, &ipv6_outer_header->flow_label, &RH3_copy[0], RH3_length, PCKTFORWARD ); }