示例#1
0
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;
   }
}
示例#2
0
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);
      }
   }
}
示例#3
0
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)
}
示例#4
0
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);
   }
}
示例#5
0
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);
   }
}
示例#6
0
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);
   }
}
示例#7
0
/**
\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);
   }
}
示例#8
0
/**
\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; 
   }
}
示例#9
0
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;
}
示例#10
0
/**
   \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;
}
示例#11
0
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;
}
示例#12
0
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;
}
示例#13
0
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;   
   }
   
}
示例#14
0
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;
}
示例#15
0
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;
}
示例#16
0
/**
\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;
}
示例#17
0
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);
}
示例#18
0
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;
   }
}
示例#19
0
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;
   }
}