Beispiel #1
0
void tcpinject_connectDone(error_t error) {
   if (error==E_SUCCESS) {
      tcpinject_vars.pkt = openqueue_getFreePacketBuffer(COMPONENT_TCPINJECT);
      if (tcpinject_vars.pkt==NULL) {
         openserial_printError(COMPONENT_TCPINJECT,ERR_NO_FREE_PACKET_BUFFER,
                               (errorparameter_t)0,
                               (errorparameter_t)0);
         return;
      }
      tcpinject_vars.pkt->creator                      = COMPONENT_TCPINJECT;
      tcpinject_vars.pkt->owner                        = COMPONENT_TCPINJECT;
      tcpinject_vars.pkt->l4_protocol                  = IANA_UDP;
      tcpinject_vars.pkt->l4_sourcePortORicmpv6Type    = WKP_TCP_INJECT;
      tcpinject_vars.pkt->l4_destination_port          = tcpinject_vars.hisPort;
      memcpy(&(tcpinject_vars.pkt->l3_destinationORsource),&tcpinject_vars.hisAddress,sizeof(open_addr_t));
      packetfunctions_reserveHeaderSize(tcpinject_vars.pkt,6);
      ((uint8_t*)tcpinject_vars.pkt->payload)[0] = 'p';
      ((uint8_t*)tcpinject_vars.pkt->payload)[1] = 'o';
      ((uint8_t*)tcpinject_vars.pkt->payload)[2] = 'i';
      ((uint8_t*)tcpinject_vars.pkt->payload)[3] = 'p';
      ((uint8_t*)tcpinject_vars.pkt->payload)[4] = 'o';
      ((uint8_t*)tcpinject_vars.pkt->payload)[5] = 'i';
      if (opentcp_send(tcpinject_vars.pkt)==E_FAIL) {
         openqueue_freePacketBuffer(tcpinject_vars.pkt);
      }
      return;
   }
}
Beispiel #2
0
void udprand_task(){
    OpenQueueEntry_t* pkt;
   //prepare packet
   pkt = openqueue_getFreePacketBuffer(COMPONENT_UDPRAND);
   if (pkt==NULL) {
      openserial_printError(COMPONENT_UDPRAND,ERR_NO_FREE_PACKET_BUFFER,
                            (errorparameter_t)0,
                            (errorparameter_t)0);
      return;
   }
   pkt->creator                     = COMPONENT_UDPRAND;
   pkt->owner                       = COMPONENT_UDPRAND;
   pkt->l4_protocol                 = IANA_UDP;
   pkt->l4_sourcePortORicmpv6Type   = WKP_UDP_RAND;
   pkt->l4_destination_port         = WKP_UDP_RAND;
   pkt->l3_destinationAdd.type = ADDR_128B;
   memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_motedata,16);
   packetfunctions_reserveHeaderSize(pkt,2);
   ((uint8_t*)pkt->payload)[0]      = openrandom_get16b()%0xff;
   ((uint8_t*)pkt->payload)[1]      = openrandom_get16b()%0xff;
   //send packet
   if ((openudp_send(pkt))==E_FAIL) {
      openqueue_freePacketBuffer(pkt);
   }
}
port_INLINE void light_send_one_packet(uint8_t pktId) {
   OpenQueueEntry_t*    pkt;
   
   // get a free packet buffer
   pkt = openqueue_getFreePacketBuffer(COMPONENT_LIGHT);
   if (pkt==NULL) {
      openserial_printError(COMPONENT_LIGHT,ERR_NO_FREE_PACKET_BUFFER,0,0);
      return;
   }
   
   // take ownership over the packet
   pkt->owner                               = COMPONENT_LIGHT;
   pkt->creator                             = COMPONENT_LIGHT;
   
   // fill payload
   packetfunctions_reserveHeaderSize(pkt,sizeof(light_ht));
   ((light_ht*)(pkt->payload))->type        = LONGTYPE_DATA;
   ((light_ht*)(pkt->payload))->src         = idmanager_getMyShortID();
   ((light_ht*)(pkt->payload))->light_info  = light_get_light_info(pktId);
   
   // send
   if ((sixtop_send(pkt))==E_FAIL) {
      openqueue_freePacketBuffer(pkt);
   }
}
Beispiel #4
0
void ohlone_sendpkt() {
   uint8_t buffer[TCP_DEFAULT_WINDOW_SIZE];
   uint8_t buffer_len;
  
   buffer_len = ohlone_webpage(ohlone_vars.getRequest, ohlone_vars.httpChunk++, buffer);
   
   if (buffer_len == 0) {
      // No more to send
      // close TCP session, but keep listening
      ohlone_vars.getRequest[0] = '/';
      ohlone_vars.getRequest[1] = ' ';
      opentcp_close();
      return;
   }

   ohlone_vars.pkt = openqueue_getFreePacketBuffer(COMPONENT_OHLONE);
   if (ohlone_vars.pkt==NULL) {
      openserial_printError(COMPONENT_OHLONE,ERR_NO_FREE_PACKET_BUFFER,
                            (errorparameter_t)0,
                            (errorparameter_t)0);
      opentcp_close();
      return;
   }
   ohlone_vars.pkt->creator = COMPONENT_OHLONE;
   ohlone_vars.pkt->owner   = COMPONENT_OHLONE;
   
   packetfunctions_reserveHeaderSize(ohlone_vars.pkt, buffer_len);
   memcpy(ohlone_vars.pkt->payload, buffer, buffer_len);
   
   if ((opentcp_send(ohlone_vars.pkt))==E_FAIL) {
      openqueue_freePacketBuffer(ohlone_vars.pkt);
      opentcp_close();
   }

}
Beispiel #5
0
void openbridge_trigger() {
   uint8_t           input_buffer[136];//worst case: 8B of next hop + 128B of data
   OpenQueueEntry_t* pkt;
   uint8_t           numDataBytes;
   numDataBytes = openserial_getNumDataBytes();
   openserial_getInputBuffer(&(input_buffer[0]),numDataBytes);
   if (idmanager_getIsBridge()==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);
      //send
      if ((iphc_sendFromBridge(pkt))==E_FAIL) {
         openqueue_freePacketBuffer(pkt);
      }
   }
}
Beispiel #6
0
/**
\brief Send an advertisement.

This is one of the MAC managament 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 sendAdv() {
   OpenQueueEntry_t* adv;
   // only send a packet if I received a sendDone for the previous.
   // the packet might be stuck in the queue for a long time for
   // example while the mote is synchronizing
   if (res_vars.busySending==FALSE) {
      // get a free packet buffer
      adv = openqueue_getFreePacketBuffer(COMPONENT_RES);
      if (adv==NULL) {
         openserial_printError(COMPONENT_RES,ERR_NO_FREE_PACKET_BUFFER,
                               (errorparameter_t)0,
                               (errorparameter_t)0);
         return;
      }
      
      // declare ownership over that packet
      adv->creator = COMPONENT_RES;
      adv->owner   = COMPONENT_RES;
      
      // reserve space for ADV-specific header
      packetfunctions_reserveHeaderSize(adv, ADV_PAYLOAD_LENGTH);
      // the actual value of the current ASN will be written by the
      // IEEE802.15.4e when transmitting
      
      // 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;
      
      // put in queue for MAC to handle
      res_send_internal(adv);
      res_vars.busySending = TRUE;
   }
}
Beispiel #7
0
/**
\brief Called when a CoAP message is received for this resource.

\param[in] msg          The received message. CoAP header and options already
   parsed.
\param[in] coap_header  The CoAP header contained in the message.
\param[in] coap_options The CoAP options contained in the message.

\return Whether the response is prepared successfully.
*/
owerror_t cleds_receive(
      OpenQueueEntry_t* msg,
      coap_header_iht*  coap_header,
      coap_option_iht*  coap_options
   ) {
   owerror_t outcome;
   
   switch (coap_header->Code) {
      case COAP_CODE_REQ_GET:
         // reset packet payload
         msg->payload                     = &(msg->packet[127]);
         msg->length                      = 0;
         
         // add CoAP payload
         packetfunctions_reserveHeaderSize(msg,2);
         msg->payload[0]                  = COAP_PAYLOAD_MARKER;

         if (leds_error_isOn()==1) {
            msg->payload[1]               = '1';
         } else {
            msg->payload[1]               = '0';
         }
            
         // set the CoAP header
         coap_header->Code                = COAP_CODE_RESP_CONTENT;
         
         outcome                          = E_SUCCESS;
         break;
      
      case COAP_CODE_REQ_PUT:
      
         // change the LED's state
         if (msg->payload[0]=='1') {
            leds_error_on();
         } else if (msg->payload[0]=='2') {
            leds_error_toggle();
         } else {
            leds_error_off();
         }
         
         // reset packet payload
         msg->payload                     = &(msg->packet[127]);
         msg->length                      = 0;
         
         // set the CoAP header
         coap_header->Code                = COAP_CODE_RESP_CHANGED;
         
         outcome                          = E_SUCCESS;
         break;
         
      default:
         outcome                          = E_FAIL;
         break;
   }
   
   return outcome;
}
Beispiel #8
0
error_t openudp_send(OpenQueueEntry_t* msg) {
   msg->owner       = COMPONENT_OPENUDP;
   msg->l4_protocol = IANA_UDP;
   msg->l4_payload  = msg->payload;
   msg->l4_length   = msg->length;
   packetfunctions_reserveHeaderSize(msg,sizeof(udp_ht));
   packetfunctions_htons(msg->l4_sourcePortORicmpv6Type,&(msg->payload[0]));
   packetfunctions_htons(msg->l4_destination_port,&(msg->payload[2]));
   packetfunctions_htons(msg->length,&(msg->payload[4]));
   packetfunctions_calculateChecksum(msg,(uint8_t*)&(((udp_ht*)msg->payload)->checksum));
   return forwarding_send(msg);
}
Beispiel #9
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;
   }
}
Beispiel #10
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);
      }
   }
}
Beispiel #11
0
error_t rt_receive(OpenQueueEntry_t* msg,
                      coap_header_iht* coap_header,
                      coap_option_iht* coap_options) {
   error_t outcome;
   uint8_t rawdata[SENSITIVE_ACCEL_TEMPERATURE_DATALEN];
   
   if (coap_header->Code==COAP_CODE_REQ_POST) {
      // start/stop the data generation to data server
      
      if (msg->payload[0]=='1') {
         opentimers_restart(rt_vars.timerId);
      } else {
         opentimers_stop(rt_vars.timerId);
      }
      
      // reset packet payload
      msg->payload                     = &(msg->packet[127]);
      msg->length                      = 0;
      
      // CoAP header
      coap_header->OC                  = 0;
      coap_header->Code                = COAP_CODE_RESP_VALID;
      
      outcome = E_SUCCESS;
   
   } else if (coap_header->Code==COAP_CODE_REQ_GET) {
      // return current sensor value
      
      // reset packet payload
      msg->payload                     = &(msg->packet[127]);
      msg->length                      = 0;
      
      // CoAP payload (2 bytes of temperature data)
      packetfunctions_reserveHeaderSize(msg,2);
      sensitive_accel_temperature_get_measurement(&rawdata[0]);
      msg->payload[0] = rawdata[8];
      msg->payload[1] = rawdata[9];
         
      // set the CoAP header
      coap_header->OC                  = 0;
      coap_header->Code                = COAP_CODE_RESP_CONTENT;
      
      outcome                          = E_SUCCESS;
   
   } else {
      // return an error message
      outcome = E_FAIL;
   }
   
   return outcome;
}
Beispiel #12
0
/**
\brief Called when a CoAP message has to fill the payload with csensors data.

\param[in] msg          The message to be filled.
\param[in] id           Resource id in sensors array.

*/
void csensors_fillpayload(OpenQueueEntry_t* msg,
      uint8_t id) {

   uint16_t              value;

   value=csensors_vars.csensors_resource[id].opensensors_resource->callbackRead();
   packetfunctions_reserveHeaderSize(msg,2);

   // add value
   msg->payload[0]                  = (value>>8) & 0x00ff;
   msg->payload[1]                  = value & 0x00ff;


}
Beispiel #13
0
owerror_t cwellknown_receive(
      OpenQueueEntry_t* msg,
      coap_header_iht*  coap_header,
      coap_option_iht*  coap_options
   ) {
   owerror_t outcome;
   
   switch(coap_header->Code) {
      case COAP_CODE_REQ_GET:
         // reset packet payload
         msg->payload        = &(msg->packet[127]);
         msg->length         = 0;
         
         // have CoAP module write links to all resources
         opencoap_writeLinks(msg,COMPONENT_CWELLKNOWN);
         
         packetfunctions_reserveHeaderSize(msg,1);
         msg->payload[0]     = COAP_PAYLOAD_MARKER;
            
         // add return option
         packetfunctions_reserveHeaderSize(msg,2);
         msg->payload[0]     = COAP_OPTION_NUM_CONTENTFORMAT << 4 | 1;
         msg->payload[1]     = COAP_MEDTYPE_APPLINKFORMAT;
         
         // set the CoAP header
         coap_header->Code   = COAP_CODE_RESP_CONTENT;
         
         outcome             = E_SUCCESS;
         
         break;
      default:
         outcome             = E_FAIL;
         break;
   }
   
   return outcome;
}
/**
\brief Send a CoAP request.

This function is called by a CoAP resource when it wants to send some data.
This function is NOT called for a response.

\param[in] msg The message to be sent. This messages should not contain the
   CoAP header.
\param[in] type The CoAP type of the message.
\param[in] code The CoAP code of the message.
\param[in] TKL  The Token Length of the message, sanitized to a max of COAP_MAX_TKL (8).
\param[out] descSender A pointer to the description of the calling CoAP
   resource.

\post After returning, this function will have written the messageID and TOKEN
   used in the descSender parameter.

\return The outcome of sending the packet.
*/
owerror_t opencoap_send(
      OpenQueueEntry_t*      msg,
      coap_type_t            type,
      coap_code_t            code,
      uint8_t                TKL,
      coap_resource_desc_t*  descSender
   ) {
   uint16_t token;
   uint8_t tokenPos=0;
   coap_header_iht* request;
   
   // increment the (global) messageID
   if (opencoap_vars.messageID++ == 0xffff) {
      opencoap_vars.messageID = 0;
   }
   
   // take ownership over the packet
   msg->owner                       = COMPONENT_OPENCOAP;
   
   // fill in packet metadata
   msg->l4_sourcePortORicmpv6Type   = WKP_UDP_COAP;
   
   // update the last_request header
   request                          = &descSender->last_request;
   request->T                       = type;
   request->Code                    = code;
   request->messageID               = opencoap_vars.messageID;
   request->TKL                     = TKL<COAP_MAX_TKL ? TKL : COAP_MAX_TKL;
   
   while (tokenPos<request->TKL) {
       token = openrandom_get16b();
       memcpy(&request->token[tokenPos],&token,2);
       tokenPos+=2;
   }
   
   // pre-pend CoAP header (version,type,TKL,code,messageID,Token)
   packetfunctions_reserveHeaderSize(msg,4+request->TKL);
   msg->payload[0]                  = (COAP_VERSION   << 6) |
                                      (type           << 4) |
                                      (request->TKL   << 0);
   msg->payload[1]                  = code;
   msg->payload[2]                  = (request->messageID>>8) & 0xff;
   msg->payload[3]                  = (request->messageID>>0) & 0xff;

   memcpy(&msg->payload[4],&token,request->TKL);
   
   return openudp_send(msg);
}
Beispiel #15
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)
}
Beispiel #16
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);
   }
}
Beispiel #17
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);
   }
}
Beispiel #18
0
/**
\brief Prepend the IEEE802.15.4 MAC header to a (to be transmitted) packet.

Note that we are writing the field from the end of the header to the beginning.

\param[in,out] msg              The message to append the header to.
\param[in]     frameType        Type of IEEE802.15.4 frame.
\param[in]     ielistpresent    Is the IE list present�
\param[in]     frameVersion     IEEE802.15.4 frame version.
\param[in]     securityEnabled  Is security enabled on this frame?
\param[in]     sequenceNumber   Sequence number of this frame.
\param[in]     nextHop          Address of the next hop
*/
void ieee802154_prependHeader(OpenQueueEntry_t* msg,
                              uint8_t           frameType,
                              bool              payloadIEPresent,
                              bool              securityEnabled,
                              uint8_t           sequenceNumber,
                              open_addr_t*      nextHop) {
   uint8_t temp_8b;
   uint8_t ielistpresent = IEEE154_IELIST_NO;
   uint8_t frameVersion;
   
   // General IEs here (those that are carried in all packets)
   // add termination IE accordingly 
   if (payloadIEPresent == TRUE) {
       ielistpresent = IEEE154_IELIST_YES; 
       frameVersion  = IEEE154_FRAMEVERSION;
       //add header termination IE (id=0x7e)
       packetfunctions_reserveHeaderSize(msg,TerminationIE_Length);
       msg->payload[0] = (Header_PayloadIE_TerminationIE >> 8) & 0xFF;
       msg->payload[1] = Header_PayloadIE_TerminationIE        & 0xFF;
       
       
   } else {
Beispiel #19
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);
   }
}
Beispiel #20
0
void prependTCPHeader(OpenQueueEntry_t* msg,
      bool ack,
      bool push,
      bool rst,
      bool syn,
      bool fin) {
   msg->l4_protocol = IANA_TCP;
   packetfunctions_reserveHeaderSize(msg,sizeof(tcp_ht));
   packetfunctions_htons(tcp_vars.myPort        ,(uint8_t*)&(((tcp_ht*)msg->payload)->source_port));
   packetfunctions_htons(tcp_vars.hisPort       ,(uint8_t*)&(((tcp_ht*)msg->payload)->destination_port));
   packetfunctions_htonl(tcp_vars.mySeqNum      ,(uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number));
   packetfunctions_htonl(tcp_vars.hisNextSeqNum ,(uint8_t*)&(((tcp_ht*)msg->payload)->ack_number));
   ((tcp_ht*)msg->payload)->data_offset      = TCP_DEFAULT_DATA_OFFSET;
   ((tcp_ht*)msg->payload)->control_bits     = 0;
   if (ack==TCP_ACK_YES) {
      ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_ACK;
   } else {
      packetfunctions_htonl(0,(uint8_t*)&(((tcp_ht*)msg->payload)->ack_number));
   }
   if (push==TCP_PSH_YES) {
      ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_PSH;
   }
   if (rst==TCP_RST_YES) {
      ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_RST;
   }
   if (syn==TCP_SYN_YES) {
      ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_SYN;
   }
   if (fin==TCP_FIN_YES) {
      ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_FIN;
   }
   packetfunctions_htons(TCP_DEFAULT_WINDOW_SIZE    ,(uint8_t*)&(((tcp_ht*)msg->payload)->window_size));
   packetfunctions_htons(TCP_DEFAULT_URGENT_POINTER ,(uint8_t*)&(((tcp_ht*)msg->payload)->urgent_pointer));
   //calculate checksum last to take all header fields into account
   packetfunctions_calculateChecksum(msg,(uint8_t*)&(((tcp_ht*)msg->payload)->checksum));
}
Beispiel #21
0
/**
\brief Writes the links to all the resources on this mote into the message.

\param[out] msg The messge to write the links to.

\post After this function returns, the msg contains 
*/
void opencoap_writeLinks(OpenQueueEntry_t* msg) {
   coap_resource_desc_t* temp_resource;
   
   // start with the first resource in the linked list
   temp_resource = opencoap_vars.resources;
   
   // iterate through all resources
   while (temp_resource!=NULL) {
      
      // write ending '>'
      packetfunctions_reserveHeaderSize(msg,1);
      msg->payload[0] = '>';
      
      // write path1
      if (temp_resource->path1len>0) {
         packetfunctions_reserveHeaderSize(msg,temp_resource->path1len);
         memcpy(&msg->payload[0],temp_resource->path1val,temp_resource->path1len);
         packetfunctions_reserveHeaderSize(msg,1);
         msg->payload[0] = '/';
      }
      
      // write path0
      packetfunctions_reserveHeaderSize(msg,temp_resource->path0len);
      memcpy(msg->payload,temp_resource->path0val,temp_resource->path0len);
      packetfunctions_reserveHeaderSize(msg,2);
      msg->payload[1] = '/';
      
      // write opening '>'
      msg->payload[0] = '<';
      
      // write separator between links
      if (temp_resource->next!=NULL) {
         packetfunctions_reserveHeaderSize(msg,1);
         msg->payload[0] = ',';
      }
      
      // iterate to next resource
      temp_resource = temp_resource->next;
   }
}
Beispiel #22
0
/**
\brief Indicate a CoAP messages was received.

A "CoAP message" is simply a UDP datagram received on the CoAP UDP port.

This function will call the appropriate resource, and send back its answer. The
received packetbuffer is reused to contain the response (or error code).

\param[in] msg The received CoAP message.
*/
void opencoap_receive(OpenQueueEntry_t* msg) {
   uint16_t                  temp_l4_destination_port;
   uint8_t                   i;
   uint8_t                   index;
   coap_option_t             last_option;
   coap_resource_desc_t*     temp_desc;
   bool                      found;
   owerror_t                 outcome;
   // local variables passed to the handlers (with msg)
   coap_header_iht           coap_header;
   coap_option_iht           coap_options[MAX_COAP_OPTIONS];
   
   // take ownership over the received packet
   msg->owner                = COMPONENT_OPENCOAP;
   
   //=== step 1. parse the packet
   
   // parse the CoAP header and remove from packet
   index = 0;
   coap_header.Ver           = (msg->payload[index] & 0xc0) >> 6;
   coap_header.T             = (coap_type_t)((msg->payload[index] & 0x30) >> 4);
   coap_header.TKL           = (msg->payload[index] & 0x0f);
   index++;
   coap_header.Code          = (coap_code_t)(msg->payload[index]);
   index++;
   coap_header.messageID     = msg->payload[index]*256+msg->payload[index+1];
   index+=2;
   
   // reject unsupported header
   if (coap_header.Ver!=COAP_VERSION || coap_header.TKL>COAP_MAX_TKL) {
      openserial_printError(
         COMPONENT_OPENCOAP,ERR_WRONG_TRAN_PROTOCOL,
         (errorparameter_t)0,
         (errorparameter_t)coap_header.Ver
      );
      openqueue_freePacketBuffer(msg);
      return;
   }
   
   // record the token
   memcpy(&coap_header.token[0], &msg->payload[index], coap_header.TKL);
   index += coap_header.TKL;
   
   // initialize the coap_options
   for (i=0;i<MAX_COAP_OPTIONS;i++) {
      coap_options[i].type = COAP_OPTION_NONE;
   }
   
   // fill in the coap_options
   last_option = COAP_OPTION_NONE;
   for (i=0;i<MAX_COAP_OPTIONS;i++) {
      
      // detect when done parsing options
      if (msg->payload[index]==COAP_PAYLOAD_MARKER){
         // found the payload marker, done parsing options.
         index++; // skip marker and stop parsing options
         break;
      }
      
      // parse this option
      coap_options[i].type        = (coap_option_t)((uint8_t)last_option+(uint8_t)((msg->payload[index] & 0xf0) >> 4));
      last_option                 = coap_options[i].type;
      coap_options[i].length      = (msg->payload[index] & 0x0f);
      index++;
      coap_options[i].pValue      = &(msg->payload[index]);
      index                      += coap_options[i].length; //includes length as well
   }
   
   // remove the CoAP header+options
   packetfunctions_tossHeader(msg,index);
   
   //=== step 2. find the resource to handle the packet
   
   // find the resource this applies to
   found = FALSE;
   
   if (
         coap_header.Code>=COAP_CODE_REQ_GET &&
         coap_header.Code<=COAP_CODE_REQ_DELETE
      ) {
      // this is a request: target resource is indicated as COAP_OPTION_LOCATIONPATH option(s)
      // find the resource which matches
      
      // start with the first resource in the linked list
      temp_desc = opencoap_vars.resources;
      
      // iterate until matching resource found, or no match
      while (found==FALSE) {
         if (
               coap_options[0].type==COAP_OPTION_NUM_URIPATH    &&
               coap_options[1].type==COAP_OPTION_NUM_URIPATH    &&
               temp_desc->path0len>0                            &&
               temp_desc->path0val!=NULL                        &&
               temp_desc->path1len>0                            &&
               temp_desc->path1val!=NULL
            ) {
            // resource has a path of form path0/path1
               
            if (
                  coap_options[0].length==temp_desc->path0len                               &&
                  memcmp(coap_options[0].pValue,temp_desc->path0val,temp_desc->path0len)==0 &&
                  coap_options[1].length==temp_desc->path1len                               &&
                  memcmp(coap_options[1].pValue,temp_desc->path1val,temp_desc->path1len)==0
               ) {
               found = TRUE;
            };
         
         } else if (
               coap_options[0].type==COAP_OPTION_NUM_URIPATH    &&
               temp_desc->path0len>0                            &&
               temp_desc->path0val!=NULL
            ) {
            // resource has a path of form path0
               
            if (
                  coap_options[0].length==temp_desc->path0len                               &&
                  memcmp(coap_options[0].pValue,temp_desc->path0val,temp_desc->path0len)==0
               ) {
               found = TRUE;
            };
         };
         
         // iterate to next resource, if not found
         if (found==FALSE) {
            if (temp_desc->next!=NULL) {
               temp_desc = temp_desc->next;
            } else {
               break;
            }
         }
      }
   
   } else {
      // this is a response: target resource is indicated by message ID
      // find the resource which matches
      
      // start with the first resource in the linked list
      temp_desc = opencoap_vars.resources;
      
      // iterate until matching resource found, or no match
      while (found==FALSE) {
         
         if (coap_header.messageID==temp_desc->messageID) {
            found=TRUE;
            
            // call the resource's callback
            if (temp_desc->callbackRx!=NULL) {
               temp_desc->callbackRx(msg,&coap_header,&coap_options[0]);
            }
         }
         
         // iterate to next resource, if not found
         if (found==FALSE) {
            if (temp_desc->next!=NULL) {
               temp_desc = temp_desc->next;
            } else {
               break;
            }
         }
      };
      
      // free the received packet
      openqueue_freePacketBuffer(msg);
      
      // stop here: will will not respond to a response
      return;
   }
   
   //=== step 3. ask the resource to prepare response
   
   if (found==TRUE) {
      
      // call the resource's callback
      outcome = temp_desc->callbackRx(msg,&coap_header,&coap_options[0]);
   } else {
      // reset packet payload (DO NOT DELETE, we will reuse same buffer for response)
      msg->payload                     = &(msg->packet[127]);
      msg->length                      = 0;
      // set the CoAP header
      coap_header.TKL                  = 0;
      coap_header.Code                 = COAP_CODE_RESP_NOTFOUND;
   }
   
   if (outcome==E_FAIL) {
      // reset packet payload (DO NOT DELETE, we will reuse same buffer for response)
      msg->payload                     = &(msg->packet[127]);
      msg->length                      = 0;
      // set the CoAP header
      coap_header.TKL                  = 0;
      coap_header.Code                 = COAP_CODE_RESP_METHODNOTALLOWED;
   }
   
   //=== step 4. send that packet back
   
   // fill in packet metadata
   if (found==TRUE) {
      msg->creator                     = temp_desc->componentID;
   } else {
      msg->creator                     = COMPONENT_OPENCOAP;
   }
   msg->l4_protocol                    = IANA_UDP;
   temp_l4_destination_port            = msg->l4_destination_port;
   msg->l4_destination_port            = msg->l4_sourcePortORicmpv6Type;
   msg->l4_sourcePortORicmpv6Type      = temp_l4_destination_port;
   
   // set destination address as the current source
   msg->l3_destinationAdd.type         = ADDR_128B;
   memcpy(&msg->l3_destinationAdd.addr_128b[0],&msg->l3_sourceAdd.addr_128b[0],LENGTH_ADDR128b);
   
   // fill in CoAP header
   packetfunctions_reserveHeaderSize(msg,4+coap_header.TKL);
   msg->payload[0]                  = (COAP_VERSION    << 6) |
                                      (COAP_TYPE_ACK   << 4) |
                                      (coap_header.TKL << 0);
   msg->payload[1]                  = coap_header.Code;
   msg->payload[2]                  = coap_header.messageID/256;
   msg->payload[3]                  = coap_header.messageID%256;
   memcpy(&msg->payload[4], &coap_header.token[0], coap_header.TKL);
   
   if ((openudp_send(msg))==E_FAIL) {
      openqueue_freePacketBuffer(msg);
   }
}
Beispiel #23
0
/**
\brief Prepend the IEEE802.15.4 MAC header to a (to be transmitted) packet.

Note that we are writing the field from the end of the header to the beginning.

\param[in,out] msg              The message to append the header to.
\param[in]     frameType        Type of IEEE802.15.4 frame.
\param[in]     ielistpresent    Is the IE list present¿
\param[in]     frameVersion     IEEE802.15.4 frame version.
\param[in]     securityEnabled  Is security enabled on this frame?
\param[in]     sequenceNumber   Sequence number of this frame.
\param[in]     nextHop          Address of the next hop
*/
void ieee802154_prependHeader(OpenQueueEntry_t* msg,
                              uint8_t           frameType,
                              uint8_t           ielistpresent,
                              uint8_t           frameVersion,
                              bool              securityEnabled,
                              uint8_t           sequenceNumber,
                              open_addr_t*      nextHop) {
   uint8_t temp_8b;
   
   //General IEs here (those that are carried in all packets) -- None by now.
   
   // previousHop address (always 64-bit)
   packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_64B),OW_LITTLE_ENDIAN);
   // nextHop address
   if (packetfunctions_isBroadcastMulticast(nextHop)) {
      //broadcast address is always 16-bit
      packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
      *((uint8_t*)(msg->payload)) = 0xFF;
      packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
      *((uint8_t*)(msg->payload)) = 0xFF;
   } else {
      switch (nextHop->type) {
         case ADDR_16B:
         case ADDR_64B:
            packetfunctions_writeAddress(msg,nextHop,OW_LITTLE_ENDIAN);
            break;
         default:
            openserial_printCritical(COMPONENT_IEEE802154,ERR_WRONG_ADDR_TYPE,
                                  (errorparameter_t)nextHop->type,
                                  (errorparameter_t)1);
      }
      
   }
   // destpan
   packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_PANID),OW_LITTLE_ENDIAN);
   //dsn
   packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
   *((uint8_t*)(msg->payload)) = sequenceNumber;
   //fcf (2nd byte)
   packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
   temp_8b              = 0;
   if (packetfunctions_isBroadcastMulticast(nextHop)) {
      temp_8b          |= IEEE154_ADDR_SHORT              << IEEE154_FCF_DEST_ADDR_MODE;
   } else {
      switch (nextHop->type) {
         case ADDR_16B:
            temp_8b    |= IEEE154_ADDR_SHORT              << IEEE154_FCF_DEST_ADDR_MODE;
            break;
         case ADDR_64B:
            temp_8b    |= IEEE154_ADDR_EXT                << IEEE154_FCF_DEST_ADDR_MODE;
            break;
         // no need for a default, since it would have been caught above.
      }
   }
   temp_8b             |= IEEE154_ADDR_EXT                << IEEE154_FCF_SRC_ADDR_MODE;
   //poipoi xv IE list present
   temp_8b             |= ielistpresent                   << IEEE154_FCF_IELIST_PRESENT;
   temp_8b             |= frameVersion                    << IEEE154_FCF_FRAME_VERSION;
     
   *((uint8_t*)(msg->payload)) = temp_8b;
   //fcf (1st byte)
   packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
   temp_8b              = 0;
   temp_8b             |= frameType                       << IEEE154_FCF_FRAME_TYPE;
   temp_8b             |= securityEnabled                 << IEEE154_FCF_SECURITY_ENABLED;
   temp_8b             |= IEEE154_PENDING_NO_FRAMEPENDING << IEEE154_FCF_FRAME_PENDING;
   if (frameType==IEEE154_TYPE_ACK || packetfunctions_isBroadcastMulticast(nextHop)) {
      temp_8b          |= IEEE154_ACK_NO_ACK_REQ          << IEEE154_FCF_ACK_REQ;
   } else {
      temp_8b          |= IEEE154_ACK_YES_ACK_REQ         << IEEE154_FCF_ACK_REQ;
   }
   temp_8b             |= IEEE154_PANID_COMPRESSED        << IEEE154_FCF_INTRAPAN;
   *((uint8_t*)(msg->payload)) = temp_8b;
}
Beispiel #24
0
void ieee802154_prependHeader(OpenQueueEntry_t* msg,
                              uint8_t           frameType,
                              bool              securityEnabled,
                              uint8_t           sequenceNumber,
                              open_addr_t*      nextHop) {
   uint8_t temp_8b;
   //previousHop address (always 64-bit)
   packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_64B),LITTLE_ENDIAN);
   // poipoi: using 16-bit source address
   //packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_16B),LITTLE_ENDIAN);
   //nextHop address
   if (packetfunctions_isBroadcastMulticast(nextHop)) { //broadcast address is always 16-bit
      packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
      *((uint8_t*)(msg->payload)) = 0xFF;
      packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
      *((uint8_t*)(msg->payload)) = 0xFF;
   } else {
      // poipoi: using 16-bit destination address
//      packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
//      *((uint8_t*)(msg->payload)) = nextHop->addr_64b[6];
//      packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
//      *((uint8_t*)(msg->payload)) = nextHop->addr_64b[7];
//      
      switch (nextHop->type) {
         case ADDR_16B:
         case ADDR_64B:
            packetfunctions_writeAddress(msg,nextHop,LITTLE_ENDIAN);
            break;
         default:
            openserial_printError(COMPONENT_IEEE802154,ERR_WRONG_ADDR_TYPE,
                                  (errorparameter_t)nextHop->type,
                                  (errorparameter_t)1);
      }
      
   }
   //destpan
   packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_PANID),LITTLE_ENDIAN);
   //dsn
   packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
   *((uint8_t*)(msg->payload)) = sequenceNumber;
   //fcf (2nd byte)
   temp_8b              = 0;
   // poipoi: 16-bit source/dest addresses
  // temp_8b             |= IEEE154_ADDR_SHORT              << IEEE154_FCF_DEST_ADDR_MODE;
   //temp_8b             |= IEEE154_ADDR_SHORT              << IEEE154_FCF_SRC_ADDR_MODE;
   
   if (packetfunctions_isBroadcastMulticast(nextHop)) {
      temp_8b          |= IEEE154_ADDR_SHORT              << IEEE154_FCF_DEST_ADDR_MODE;
   } else {
      switch (nextHop->type) {
         case ADDR_16B:
            temp_8b    |= IEEE154_ADDR_SHORT              << IEEE154_FCF_DEST_ADDR_MODE;
            break;
         case ADDR_64B:
            temp_8b    |= IEEE154_ADDR_EXT                << IEEE154_FCF_DEST_ADDR_MODE;
            break;
      }
   }
   temp_8b             |= IEEE154_ADDR_EXT                << IEEE154_FCF_SRC_ADDR_MODE;
   
   packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
   *((uint8_t*)(msg->payload)) = temp_8b;
   //fcf (1st byte)
   temp_8b              = 0;
   temp_8b             |= frameType                       << IEEE154_FCF_FRAME_TYPE;
   temp_8b             |= securityEnabled                 << IEEE154_FCF_SECURITY_ENABLED;
   temp_8b             |= IEEE154_PENDING_NO_FRAMEPENDING << IEEE154_FCF_FRAME_PENDING;
   if (frameType==IEEE154_TYPE_ACK || packetfunctions_isBroadcastMulticast(nextHop)) {
      temp_8b          |= IEEE154_ACK_NO_ACK_REQ          << IEEE154_FCF_ACK_REQ;
   } else {
      temp_8b          |= IEEE154_ACK_YES_ACK_REQ         << IEEE154_FCF_ACK_REQ;
   }
   temp_8b             |= IEEE154_PANID_COMPRESSED        << IEEE154_FCF_INTRAPAN;
   packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
   *((uint8_t*)(msg->payload)) = temp_8b;
}
Beispiel #25
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; 
   }
}
Beispiel #26
0
void security_outgoingFrame(OpenQueueEntry_t*   msg,
                            uint8_t             securityLevel,
                            uint8_t             keyIdMode,
                            open_addr_t*        keySource,
                            uint8_t          	keyIndex){

	uint8_t auxlen;
	uint8_t temp8b;
	uint8_t match;

	m_keyDescriptor* keypoint;

	if(m_macFrameCounter == (0xffffffffffffffff)){
		return;
	}

	//max length of MAC frames

	authLengthChecking(securityLevel); // length of auth
	msg->l2_authenticationLength = authlen;
	//auxLengthChecking(keyIdMode, auxlen); //length of Key ID field
	//for us, keyIdMode = 3 and so Auxlen = 9
	auxlen = 9;

	if((msg->length+auxlen+authlen+2) >= 130 ){ //2 bytes of CRC, 130 MaxPHYPacketSize
		return;
	}

	//check if SecurityLevel is not zero
	//in my impl. secLevel may not be zero if i'm here.
	/*if(securityLevel == ASH_SLF_TYPE_NOSEC){
		return;
	}*/

	open_addr_t* nextHop;
	nextHop = &msg->l2_nextORpreviousHop;

	//search for a key
	match = keyDescriptorLookup(keyIdMode,
								keySource,
								keyIndex,
								nextHop,
								//idmanager_getMyID(ADDR_PANID),
								msg->l2_frameType);

	keypoint = &MacKeyTable.KeyDescriptorElement[match];

	//start setting the Auxiliary Security Header
	temp8b = keyIndex; //key index field

	packetfunctions_reserveHeaderSize(msg, sizeof(uint8_t));
	*((uint8_t*)(msg->payload)) = temp8b;

	//Key Identifier Mode
	/*if(keyIdMode != 0){

		switch(keyIdMode){
		case(ASH_KIMF_TYPE_MACDEF):
		break;
		case(ASH_KIMF_TYPE_4OCTKEY):
			packetfunctions_writeAddress(msg, idmanager_getMyID(ADDR_16B) ,OW_LITTLE_ENDIAN);//da rivedere

		break;
		case(ASH_KIMF_TYPE_8OCTKEY):
			packetfunctions_writeAddress(msg,keySource,OW_LITTLE_ENDIAN);
		break;
		}
	}*/
	//in our impl. keyIdMode = 3
	packetfunctions_writeAddress(msg,keySource,OW_LITTLE_ENDIAN);

	//Frame Counter
	uint32_t temp;
	uint8_t i;
	temp = m_macFrameCounter;

	for(i=0;i<3;i++){
		packetfunctions_reserveHeaderSize(msg, sizeof(uint8_t));
		*((uint8_t*)(msg->payload)) = temp;
		temp = temp >>8;
	}

	packetfunctions_reserveHeaderSize(msg, sizeof(uint8_t));
	*((uint8_t*)(msg->payload)) = temp;


	//security control field
	packetfunctions_reserveHeaderSize(msg, sizeof(uint8_t));

	temp8b = 0;
	temp8b |= securityLevel << ASH_SCF_SECURITY_LEVEL;//3b
	temp8b |= keyIdMode << ASH_SCF_KEY_IDENTIFIER_MODE;//2b
	temp8b |= 0 << 3;//3b reserved
	*((uint8_t*)(msg->payload)) = temp8b;

	//cryptographic block
	for(i=0; i<8; i++){
		 nonce[i] = keySource->addr_64b[i];
	}

	temp = m_macFrameCounter;

	nonce[8] = temp;
	nonce[9] = temp << 8;
	nonce[10] = temp <<16;
	nonce[11] = temp <<24;
	nonce[12] = securityLevel;

//		CRYPTO TEST
//		asn_t init;
//
//		if(msg->l2_frameType == IEEE154_TYPE_DATA){
//
//		uint8_t start[5];
//
//		ieee154e_getAsn(start);
//
//		init.bytes0and1 = start[0]+256*start[1];
//		init.bytes2and3 = start[2]+256*start[3];
//		init.byte4 = start[4];
//		}


	//CCMstar(msg,keypoint->key);

//		if(msg->l2_frameType == IEEE154_TYPE_DATA){
//		uint16_t diff;
//		diff = ieee154e_asnDiff(&init);
//
//		openserial_printError(COMPONENT_RES,ERR_OK,
//							(errorparameter_t)diff,
//							(errorparameter_t)501);
//		}

	//h increment the Frame Counter and save.
	m_macFrameCounter++;

}
Beispiel #27
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;
}
Beispiel #28
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;   
   }
   
}
Beispiel #29
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);
   }
}
Beispiel #30
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;
}