owerror_t opentcp_connect(open_addr_t* dest, uint16_t param_tcp_hisPort, uint16_t param_tcp_myPort) { //[command] establishment OpenQueueEntry_t* tempPkt; if (tcp_vars.state!=TCP_STATE_CLOSED) { openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, (errorparameter_t)tcp_vars.state, (errorparameter_t)0); return E_FAIL; } tcp_vars.myPort = param_tcp_myPort; tcp_vars.hisPort = param_tcp_hisPort; memcpy(&tcp_vars.hisIPv6Address,dest,sizeof(open_addr_t)); //I receive command 'connect', I send SYNC tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); if (tempPkt==NULL) { openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); return E_FAIL; } tempPkt->creator = COMPONENT_OPENTCP; tempPkt->owner = COMPONENT_OPENTCP; memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); tcp_vars.mySeqNum = TCP_INITIAL_SEQNUM; prependTCPHeader(tempPkt, TCP_ACK_NO, TCP_PSH_NO, TCP_RST_NO, TCP_SYN_YES, TCP_FIN_NO); tcp_change_state(TCP_STATE_ALMOST_SYN_SENT); return forwarding_send(tempPkt); }
owerror_t opentcp_send(OpenQueueEntry_t* msg) { //[command] data msg->owner = COMPONENT_OPENTCP; if (tcp_vars.state!=TCP_STATE_ESTABLISHED) { openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, (errorparameter_t)tcp_vars.state, (errorparameter_t)2); return E_FAIL; } if (tcp_vars.dataToSend!=NULL) { openserial_printError(COMPONENT_OPENTCP,ERR_BUSY_SENDING, (errorparameter_t)0, (errorparameter_t)0); return E_FAIL; } //I receive command 'send', I send data msg->l4_protocol = IANA_TCP; msg->l4_sourcePortORicmpv6Type = tcp_vars.myPort; msg->l4_destination_port = tcp_vars.hisPort; msg->l4_payload = msg->payload; msg->l4_length = msg->length; memcpy(&(msg->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); tcp_vars.dataToSend = msg; prependTCPHeader(tcp_vars.dataToSend, TCP_ACK_YES, TCP_PSH_YES, TCP_RST_NO, TCP_SYN_NO, TCP_FIN_NO); tcp_vars.mySeqNum += tcp_vars.dataToSend->l4_length; tcp_change_state(TCP_STATE_ALMOST_DATA_SENT); return forwarding_send(tcp_vars.dataToSend); }
void icmpv6echo_trigger() { uint8_t number_bytes_from_input_buffer; uint8_t input_buffer[16]; OpenQueueEntry_t* msg; //get command from OpenSerial (16B IPv6 destination address) 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_ICMPv6ECHO,ERR_INPUTBUFFER_LENGTH, (errorparameter_t)number_bytes_from_input_buffer, (errorparameter_t)0); return; }; icmpv6echo_vars.hisAddress.type = ADDR_128B; memcpy(&(icmpv6echo_vars.hisAddress.addr_128b[0]),&(input_buffer[0]),16); //send if (icmpv6echo_vars.busySending==TRUE) { openserial_printError(COMPONENT_ICMPv6ECHO,ERR_BUSY_SENDING, (errorparameter_t)0, (errorparameter_t)0); } else { icmpv6echo_vars.busySending = TRUE; msg = openqueue_getFreePacketBuffer(COMPONENT_ICMPv6ECHO); if (msg==NULL) { openserial_printError(COMPONENT_ICMPv6ECHO,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); icmpv6echo_vars.busySending = FALSE; return; } //admin msg->creator = COMPONENT_ICMPv6ECHO; msg->owner = COMPONENT_ICMPv6ECHO; //l4 msg->l4_protocol = IANA_ICMPv6; msg->l4_sourcePortORicmpv6Type = IANA_ICMPv6_ECHO_REQUEST; //l3 memcpy(&(msg->l3_destinationAdd),&icmpv6echo_vars.hisAddress,sizeof(open_addr_t)); //payload packetfunctions_reserveHeaderSize(msg,4); packetfunctions_htonl(0x789abcde,(uint8_t*)(msg->payload)); //ICMPv6 header packetfunctions_reserveHeaderSize(msg,sizeof(ICMPv6_ht)); ((ICMPv6_ht*)(msg->payload))->type = msg->l4_sourcePortORicmpv6Type; ((ICMPv6_ht*)(msg->payload))->code = 0; // Below Identifier might need to be replaced by the identifier used by icmpv6rpl // packetfunctions_htons(0x1234 ,(uint8_t*)&((ICMPv6_ht*)(msg->payload))->identifier); // Below sequence_number might need to be removed // packetfunctions_htons(icmpv6echo_vars.seq++ ,(uint8_t*)&((ICMPv6_ht*)(msg->payload))->sequence_number); packetfunctions_calculateChecksum(msg,(uint8_t*)&(((ICMPv6_ht*)(msg->payload))->checksum));//do last //send if (icmpv6_send(msg)!=E_SUCCESS) { icmpv6echo_vars.busySending = FALSE; openqueue_freePacketBuffer(msg); } } }
void registerNewNeighbor(open_addr_t* address, int8_t rssi, asn_t* asnTimestamp) { uint8_t i,j; bool iHaveAPreferedParent; // filter errors if (address->type!=ADDR_64B) { openserial_printError(COMPONENT_NEIGHBORS,ERR_WRONG_ADDR_TYPE, (errorparameter_t)address->type, (errorparameter_t)2); return; } // add this neighbor if (isNeighbor(address)==FALSE) { i=0; while(i<MAXNUMNEIGHBORS) { if (neighbors_vars.neighbors[i].used==FALSE) { // add this neighbor neighbors_vars.neighbors[i].used = TRUE; neighbors_vars.neighbors[i].parentPreference = 0; //neighbors_vars.neighbors[i].stableNeighbor = FALSE; // poipoi: all new neighbors are consider stable neighbors_vars.neighbors[i].stableNeighbor = TRUE; neighbors_vars.neighbors[i].switchStabilityCounter = 0; memcpy(&neighbors_vars.neighbors[i].addr_64b, address, sizeof(open_addr_t)); neighbors_vars.neighbors[i].DAGrank = 0xffff; neighbors_vars.neighbors[i].rssi = rssi; neighbors_vars.neighbors[i].numRx = 1; neighbors_vars.neighbors[i].numTx = 0; neighbors_vars.neighbors[i].numTxACK = 0; memcpy(&neighbors_vars.neighbors[i].asn,asnTimestamp,sizeof(asn_t)); // do I already have a preferred parent ? iHaveAPreferedParent = FALSE; for (j=0;j<MAXNUMNEIGHBORS;j++) { if (neighbors_vars.neighbors[j].parentPreference==MAXPREFERENCE) { iHaveAPreferedParent = TRUE; } } // if I have none, and I'm not DAGroot, the new neighbor is my preferred if (iHaveAPreferedParent==FALSE && idmanager_getIsDAGroot()==FALSE) { neighbors_vars.neighbors[i].parentPreference = MAXPREFERENCE; } break; } i++; } if (i==MAXNUMNEIGHBORS) { openserial_printError(COMPONENT_NEIGHBORS,ERR_NEIGHBORS_FULL, (errorparameter_t)MAXNUMNEIGHBORS, (errorparameter_t)0); return; } } }
void icmpv6echo_receive(OpenQueueEntry_t* msg) { OpenQueueEntry_t* reply; msg->owner = COMPONENT_ICMPv6ECHO; switch(msg->l4_sourcePortORicmpv6Type) { case IANA_ICMPv6_ECHO_REQUEST: openserial_printInfo(COMPONENT_ICMPv6ECHO,ERR_RCVD_ECHO_REQUEST, (errorparameter_t)0, (errorparameter_t)0); // get a new openqueuEntry_t for the echo reply reply = openqueue_getFreePacketBuffer(COMPONENT_ICMPv6ECHO); if (reply==NULL) { openserial_printError(COMPONENT_ICMPv6ECHO,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)1, (errorparameter_t)0); openqueue_freePacketBuffer(msg); return; } // take ownership over reply reply->creator = COMPONENT_ICMPv6ECHO; reply->owner = COMPONENT_ICMPv6ECHO; // copy payload from msg to (end of) reply packetfunctions_reserveHeaderSize(reply,msg->length); memcpy(reply->payload,msg->payload,msg->length); // copy source of msg in destination of reply memcpy(&(reply->l3_destinationAdd),&(msg->l3_sourceAdd),sizeof(open_addr_t)); // free up msg openqueue_freePacketBuffer(msg); msg = NULL; // administrative information for reply reply->l4_protocol = IANA_ICMPv6; reply->l4_sourcePortORicmpv6Type = IANA_ICMPv6_ECHO_REPLY; ((ICMPv6_ht*)(reply->payload))->type = reply->l4_sourcePortORicmpv6Type; packetfunctions_calculateChecksum(reply,(uint8_t*)&(((ICMPv6_ht*)(reply->payload))->checksum));//do last icmpv6echo_vars.busySending = TRUE; if (icmpv6_send(reply)!=E_SUCCESS) { icmpv6echo_vars.busySending = FALSE; openqueue_freePacketBuffer(reply); } break; case IANA_ICMPv6_ECHO_REPLY: openserial_printInfo(COMPONENT_ICMPv6ECHO,ERR_RCVD_ECHO_REPLY, (errorparameter_t)0, (errorparameter_t)0); openqueue_freePacketBuffer(msg); break; default: openserial_printError(COMPONENT_ICMPv6ECHO,ERR_UNSUPPORTED_ICMPV6_TYPE, (errorparameter_t)msg->l4_sourcePortORicmpv6Type, (errorparameter_t)2); openqueue_freePacketBuffer(msg); break; } }
void openbridge_triggerData(void) { uint8_t input_buffer[136];//worst case: 8B of next hop + 128B of data OpenQueueEntry_t* pkt; uint8_t numDataBytes; numDataBytes = openserial_getNumDataBytes(); //poipoi xv //this is a temporal workaround as we are never supposed to get chunks of data //longer than input buffer size.. I assume that HDLC will solve that. // MAC header is 13B + 8 next hop so we cannot accept packets that are longer than 118B if (numDataBytes>(136 - 21) || numDataBytes<8){ //to prevent too short or too long serial frames to kill the stack openserial_printError(COMPONENT_OPENBRIDGE,ERR_INPUTBUFFER_LENGTH, (errorparameter_t)numDataBytes, (errorparameter_t)0); return; } //copying the buffer once we know it is not too big openserial_getInputBuffer(&(input_buffer[0]),numDataBytes); if (idmanager_getIsDAGroot()==TRUE && numDataBytes>0) { pkt = openqueue_getFreePacketBuffer(COMPONENT_OPENBRIDGE); if (pkt==NULL) { openserial_printError(COMPONENT_OPENBRIDGE,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); return; } //admin pkt->creator = COMPONENT_OPENBRIDGE; pkt->owner = COMPONENT_OPENBRIDGE; //l2 pkt->l2_nextORpreviousHop.type = ADDR_64B; memcpy(&(pkt->l2_nextORpreviousHop.addr_64b[0]),&(input_buffer[0]),8); //payload packetfunctions_reserveHeaderSize(pkt,numDataBytes-8); memcpy(pkt->payload,&(input_buffer[8]),numDataBytes-8); //this is to catch the too short packet. remove it after fw-103 is solved. if (numDataBytes<16){ openserial_printError(COMPONENT_OPENBRIDGE,ERR_INVALIDSERIALFRAME, (errorparameter_t)0, (errorparameter_t)0); } //send if ((iphc_sendFromBridge(pkt))==E_FAIL) { openqueue_freePacketBuffer(pkt); } } }
void remote_init(ieee802154_header_iht ieee802514_header){ open_addr_t* src; //open_addr_t* panid; src= &ieee802514_header.src; MacKeyTable.KeyDescriptorElement[0].KeyIdLookupList.KeyIdMode = 3; MacKeyTable.KeyDescriptorElement[0].KeyIdLookupList.KeySource = *(src); //MacKeyTable.KeyDescriptorElement[0].KeyIdLookupList.PANId = ieee802514_header.panid; MacKeyTable.KeyDescriptorElement[0].KeyIdLookupList.KeyIndex = 1; MacKeyTable.KeyDescriptorElement[0].KeyIdLookupList.Address = (ieee802514_header.src); MacKeyTable.KeyDescriptorElement[0].KeyUsageList[1].FrameType = IEEE154_TYPE_DATA; MacKeyTable.KeyDescriptorElement[0].key = M_k; m_macDefaultKeySource = *(idmanager_getMyID(ADDR_16B)); MacKeyTable.KeyDescriptorElement[0].KeyIdLookupList.KeyIndex = 1; MacKeyTable.KeyDescriptorElement[0].KeyIdLookupList.Address = *(src); //DEVICE TABLE MacDeviceTable.DeviceDescriptorEntry[0].deviceAddress = *(src); MacDeviceTable.DeviceDescriptorEntry[0].FrameCounter = 0; MacKeyTable.KeyDescriptorElement[0].DeviceTable = &MacDeviceTable; openserial_printError(COMPONENT_RES,ERR_OK, (errorparameter_t)M_k, (errorparameter_t)201); }
void openserial_startInput() { INTERRUPT_DECLARATION(); if (openserial_vars.inputBufFill>0) { openserial_printError(COMPONENT_OPENSERIAL,ERR_INPUTBUFFER_LENGTH, (errorparameter_t)openserial_vars.inputBufFill, (errorparameter_t)0); DISABLE_INTERRUPTS(); openserial_vars.inputBufFill=0; ENABLE_INTERRUPTS(); } uart_clearTxInterrupts(); uart_clearRxInterrupts(); // clear possible pending interrupts uart_enableInterrupts(); // Enable USCI_A1 TX & RX interrupt DISABLE_INTERRUPTS(); openserial_vars.busyReceiving = FALSE; openserial_vars.mode = MODE_INPUT; openserial_vars.reqFrameIdx = 0; #ifdef FASTSIM uart_writeBufferByLen_FASTSIM( openserial_vars.reqFrame, sizeof(openserial_vars.reqFrame) ); openserial_vars.reqFrameIdx = sizeof(openserial_vars.reqFrame); #else uart_writeByte(openserial_vars.reqFrame[openserial_vars.reqFrameIdx]); #endif ENABLE_INTERRUPTS(); }
void coordinator_init(){ open_addr_t* my; my = idmanager_getMyID(ADDR_64B); //Creation of the KeyDescriptor MacKeyTable.KeyDescriptorElement[0].KeyIdLookupList.KeyIdMode = 3; MacKeyTable.KeyDescriptorElement[0].KeyIdLookupList.KeyIndex = 1; MacKeyTable.KeyDescriptorElement[0].KeyIdLookupList.KeySource = *(my); MacKeyTable.KeyDescriptorElement[0].KeyIdLookupList.Address = *(my); //macKeyTab.KeyDescriptorElement[0].KeyIdLookupList.PANId = *(idmanager_getMyID(ADDR_PANID)); MacKeyTable.KeyDescriptorElement[0].KeyUsageList[1].FrameType = IEEE154_TYPE_DATA; MacKeyTable.KeyDescriptorElement[0].key = M_k; MacDeviceTable.DeviceDescriptorEntry[0].deviceAddress = *(my); MacDeviceTable.DeviceDescriptorEntry[0].FrameCounter = 0; MacKeyTable.KeyDescriptorElement[0].DeviceTable = &MacDeviceTable; openserial_printError(COMPONENT_RES,ERR_OK, (errorparameter_t)M_k, (errorparameter_t)102); }
void idmanager_triggerAboutBridge() { uint8_t number_bytes_from_input_buffer; uint8_t input_buffer; //get command from OpenSerial number_bytes_from_input_buffer = openserial_getInputBuffer(&input_buffer,sizeof(input_buffer)); if (number_bytes_from_input_buffer!=sizeof(input_buffer)) { openserial_printError(COMPONENT_IDMANAGER,ERR_INPUTBUFFER_LENGTH, (errorparameter_t)number_bytes_from_input_buffer, (errorparameter_t)1); return; }; //handle command switch (input_buffer) { case ACTION_YES: idmanager_setIsBridge(TRUE); break; case ACTION_NO: idmanager_setIsBridge(FALSE); break; case ACTION_TOGGLE: if (idmanager_getIsBridge()) { idmanager_setIsBridge(FALSE); } else { idmanager_setIsBridge(TRUE); } break; } return; }
void udpecho_receive(OpenQueueEntry_t* msg) { uint16_t temp_l4_destination_port; OpenQueueEntry_t * pkt = openqueue_getFreePacketBuffer(COMPONENT_UDPECHO); if (pkt==NULL) { openserial_printError(COMPONENT_UDPLATENCY,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); return; } pkt->owner = COMPONENT_UDPECHO; //reply with the same OpenQueueEntry_t pkt->creator = COMPONENT_UDPECHO; pkt->l4_protocol = IANA_UDP; temp_l4_destination_port = msg->l4_destination_port; pkt->l4_destination_port = msg->l4_sourcePortORicmpv6Type; pkt->l4_sourcePortORicmpv6Type = temp_l4_destination_port; pkt->l3_destinationAdd.type = ADDR_128B; //copy source to destination to echo. memcpy(&pkt->l3_destinationAdd.addr_128b[0],&msg->l3_sourceAdd.addr_128b[0],16); packetfunctions_reserveHeaderSize(pkt,msg->length); memcpy(&pkt->payload[0],&msg->payload[0],msg->length); openqueue_freePacketBuffer(msg); if ((openudp_send(pkt))==E_FAIL) { openqueue_freePacketBuffer(pkt); } }
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; } }
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(); } }
//executed in ISR, called from scheduler.c void isr_openserial_rx() { if (openserial_vars.mode==MODE_INPUT) { if (openserial_vars.ready_receive_command==TRUE) { openserial_vars.ready_receive_command=FALSE; openserial_vars.received_command=uart_readByte(); openserial_vars.ready_receive_length=TRUE; } else if (openserial_vars.ready_receive_length==TRUE) { openserial_vars.ready_receive_length=FALSE; openserial_vars.input_buffer_bytes_still_to_come=uart_readByte(); } else { openserial_vars.input_buffer[openserial_vars.input_buffer_fill_level++]=uart_readByte(); if (openserial_vars.input_buffer_fill_level+1>SERIAL_INPUT_BUFFER_SIZE) { openserial_printError(COMPONENT_OPENSERIAL,ERR_INPUT_BUFFER_OVERFLOW, (errorparameter_t)0, (errorparameter_t)0); openserial_vars.input_buffer_fill_level=0; openserial_stop(); } openserial_vars.input_buffer_bytes_still_to_come--; if (openserial_vars.input_buffer_bytes_still_to_come==0) { openserial_stop(); } } } }
bool packetfunctions_sameAddress(open_addr_t* address_1, open_addr_t* address_2) { uint8_t address_length; if (address_1->type!=address_2->type) { return FALSE; } switch (address_1->type) { case ADDR_16B: case ADDR_PANID: address_length = 2; break; case ADDR_64B: case ADDR_PREFIX: address_length = 8; break; case ADDR_128B: address_length = 16; break; default: openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, (errorparameter_t)address_1->type, (errorparameter_t)5); return FALSE; } if (memcmp((void*)address_1->addr_128b,(void*)address_2->addr_128b,address_length)==0) { return TRUE; } return FALSE; }
bool packetfunctions_isBroadcastMulticast(open_addr_t* address) { uint8_t i; uint8_t address_length; //IPv6 multicast if (address->type==ADDR_128B) { if (address->addr_128b[0]==0xff) { return TRUE; } else { return FALSE; } } //15.4 broadcast switch (address->type) { case ADDR_16B: address_length = 2; break; case ADDR_64B: address_length = 8; break; default: openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, (errorparameter_t)address->type, (errorparameter_t)4); return FALSE; } for (i=0;i<address_length;i++) { if (address->addr_128b[i]!=0xFF) { return FALSE; } } return TRUE; }
uint8_t openserial_getInputBuffer(uint8_t* bufferToWrite, uint8_t maxNumBytes) { uint8_t numBytesWritten; uint8_t inputBufFillLevel; INTERRUPT_DECLARATION(); //<<<<<<<<<<<<<<<<<<<<<<< DISABLE_INTERRUPTS(); inputBufFillLevel = openserial_vars.inputBufFillLevel; ENABLE_INTERRUPTS(); //>>>>>>>>>>>>>>>>>>>>>>> if (maxNumBytes<inputBufFillLevel-1) { openserial_printError( COMPONENT_OPENSERIAL, ERR_GETDATA_ASKS_TOO_FEW_BYTES, (errorparameter_t)maxNumBytes, (errorparameter_t)inputBufFillLevel-1 ); numBytesWritten = 0; } else { numBytesWritten = inputBufFillLevel-1; //<<<<<<<<<<<<<<<<<<<<<<< DISABLE_INTERRUPTS(); memcpy(bufferToWrite,&(openserial_vars.inputBuf[1]),numBytesWritten); ENABLE_INTERRUPTS(); //>>>>>>>>>>>>>>>>>>>>>>> } return numBytesWritten; }
void packetfunctions_writeAddress(OpenQueueEntry_t* msg, open_addr_t* address, bool littleEndian) { uint8_t i; uint8_t address_length; switch (address->type) { case ADDR_16B: case ADDR_PANID: address_length = 2; break; case ADDR_64B: case ADDR_PREFIX: address_length = 8; break; case ADDR_128B: address_length = 16; break; default: openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, (errorparameter_t)address->type, (errorparameter_t)7); return; } for (i=0;i<address_length;i++) { msg->payload -= sizeof(uint8_t); msg->length += sizeof(uint8_t); if (littleEndian) { *((uint8_t*)(msg->payload)) = address->addr_128b[i]; } else { *((uint8_t*)(msg->payload)) = address->addr_128b[address_length-1-i]; } } }
void packetfunctions_readAddress(uint8_t* payload, uint8_t type, open_addr_t* writeToAddress, bool littleEndian) { uint8_t i; uint8_t address_length; writeToAddress->type = type; switch (type) { case ADDR_16B: case ADDR_PANID: address_length = 2; break; case ADDR_64B: case ADDR_PREFIX: address_length = 8; break; case ADDR_128B: address_length = 16; break; default: openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, (errorparameter_t)type, (errorparameter_t)6); return; } for (i=0;i<address_length;i++) { if (littleEndian) { writeToAddress->addr_128b[address_length-1-i] = *(payload+i); } else { writeToAddress->addr_128b[i] = *(payload+i); } } }
bool packetfunctions_sameAddress(open_addr_t* address_1, open_addr_t* address_2) { uint8_t address_length; if (address_1->type!=address_2->type) { return FALSE; } switch (address_1->type) { case ADDR_16B: case ADDR_PANID: address_length = 2; break; case ADDR_64B: // poipoi: spoofing 64-bit addresses // return (address_1->addr_64b[6]==address_2->addr_64b[6] && // address_1->addr_64b[7]==address_2->addr_64b[7]); //no break.. as it is the same as PREFIX case ADDR_PREFIX: address_length = 8; break; case ADDR_128B: address_length = 16; break; default: openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, (errorparameter_t)address_1->type, (errorparameter_t)5); return FALSE; } if (memcmp((void*)address_1->addr_128b,(void*)address_2->addr_128b,address_length)==0) { return TRUE; } return FALSE; }
//executed in ISR, called from scheduler.c void openserial_rxInterrupt() { UC1IFG &= ~UCA1RXIFG; // TODO: do not clear, but disable when done if (openserial_mode==MODE_INPUT) { if (openserial_ready_receive_command==TRUE) { openserial_ready_receive_command=FALSE; openserial_received_command=UCA1RXBUF; openserial_ready_receive_length=TRUE; } else if (openserial_ready_receive_length==TRUE) { openserial_ready_receive_length=FALSE; openserial_input_buffer_bytes_still_to_come=UCA1RXBUF; } else { openserial_input_buffer[openserial_input_buffer_fill_level++]=UCA1RXBUF; if (openserial_input_buffer_fill_level+1>SERIAL_INPUT_BUFFER_SIZE){ openserial_printError(COMPONENT_OPENSERIAL,ERR_INPUT_BUFFER_OVERFLOW, (errorparameter_t)0, (errorparameter_t)0); openserial_input_buffer_fill_level=0; openserial_stop(); } openserial_input_buffer_bytes_still_to_come--; if (openserial_input_buffer_bytes_still_to_come==0) { openserial_stop(); } } } }
//I just sent a IMU packet, check I need to resend one void heli_sendDone(OpenQueueEntry_t* msg, error_t error) { msg->owner = COMPONENT_HELI; if (msg->creator!=COMPONENT_HELI) { openserial_printError(COMPONENT_HELI,ERR_SENDDONE_FOR_MSG_I_DID_NOT_SEND,0,0); } openqueue_freePacketBuffer(msg); }
/** \brief Indicates that the CoAP response has been sent. \param[in] msg A pointer to the message which was sent. \param[in] error The outcome of the send function. */ void opencoap_sendDone(OpenQueueEntry_t* msg, owerror_t error) { coap_resource_desc_t* temp_resource; // take ownership over that packet msg->owner = COMPONENT_OPENCOAP; // indicate sendDone to creator of that packet //=== mine if (msg->creator==COMPONENT_OPENCOAP) { openqueue_freePacketBuffer(msg); return; } //=== someone else's temp_resource = opencoap_vars.resources; while (temp_resource!=NULL) { if ( temp_resource->componentID==msg->creator && temp_resource->callbackSendDone!=NULL ) { temp_resource->callbackSendDone(msg,error); return; } temp_resource = temp_resource->next; } // if you get here, no valid creator was found openserial_printError( COMPONENT_OPENCOAP,ERR_UNEXPECTED_SENDDONE, (errorparameter_t)0, (errorparameter_t)0 ); openqueue_freePacketBuffer(msg); }
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); } }
void macpong_send(uint8_t payloadCtr) { OpenQueueEntry_t* pkt; uint8_t i; pkt = openqueue_getFreePacketBuffer(COMPONENT_UECHO); if (pkt==NULL) { openserial_printError( COMPONENT_IPHC, ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0 ); return; } pkt->creator = COMPONENT_IPHC; pkt->owner = COMPONENT_IPHC; neighbors_getNeighbor(&pkt->l2_nextORpreviousHop,ADDR_64B,0); packetfunctions_reserveHeaderSize(pkt,LEN_PAYLOAD); ((uint8_t*)pkt->payload)[0] = payloadCtr; for (i=1;i<LEN_PAYLOAD;i++){ ((uint8_t*)pkt->payload)[i] = i; } sixtop_send(pkt); }
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); } } }
/** \brief Indicate I just received a RPL DIO from a neighbor. This function should be called for each received a DIO is received so neighbor routing information in the neighbor table can be updated. The fields which are updated are: - DAGrank \param[in] msg The received message with msg->payload pointing to the DIO header. */ void neighbors_indicateRxDIO(OpenQueueEntry_t* msg) { uint8_t i; uint8_t temp_8b; // take ownership over the packet msg->owner = COMPONENT_NEIGHBORS; // update rank of that neighbor in table neighbors_vars.dio = (icmpv6rpl_dio_ht*)(msg->payload); // retrieve rank temp_8b = *(msg->payload+2); neighbors_vars.dio->rank = (temp_8b << 8) + *(msg->payload+3); if (isNeighbor(&(msg->l2_nextORpreviousHop))==TRUE) { for (i=0;i<MAXNUMNEIGHBORS;i++) { if (isThisRowMatching(&(msg->l2_nextORpreviousHop),i)) { if ( neighbors_vars.dio->rank > neighbors_vars.neighbors[i].DAGrank && neighbors_vars.dio->rank - neighbors_vars.neighbors[i].DAGrank >(DEFAULTLINKCOST*2*MINHOPRANKINCREASE) ) { // the new DAGrank looks suspiciously high, only increment a bit neighbors_vars.neighbors[i].DAGrank += (DEFAULTLINKCOST*2*MINHOPRANKINCREASE); openserial_printError(COMPONENT_NEIGHBORS,ERR_LARGE_DAGRANK, (errorparameter_t)neighbors_vars.dio->rank, (errorparameter_t)neighbors_vars.neighbors[i].DAGrank); } else { neighbors_vars.neighbors[i].DAGrank = neighbors_vars.dio->rank; } break; } } } // update my routing information neighbors_updateMyDAGrankAndNeighborPreference(); }
owerror_t opentcp_close() { //[command] teardown OpenQueueEntry_t* tempPkt; if ( tcp_vars.state==TCP_STATE_ALMOST_CLOSE_WAIT || tcp_vars.state==TCP_STATE_CLOSE_WAIT || tcp_vars.state==TCP_STATE_ALMOST_LAST_ACK || tcp_vars.state==TCP_STATE_LAST_ACK || tcp_vars.state==TCP_STATE_CLOSED) { //not an error, can happen when distant node has already started tearing down return E_SUCCESS; } //I receive command 'close', 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); return E_FAIL; } 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); tcp_vars.mySeqNum++; tcp_change_state(TCP_STATE_ALMOST_FIN_WAIT_1); return forwarding_send(tempPkt); }
void udprand_task(){ OpenQueueEntry_t* pkt; // don't run if not synch if (ieee154e_isSynch() == FALSE) return; // don't run on dagroot if (idmanager_getIsDAGroot()) { opentimers_stop(udprand_vars.timerId); return; } //prepare packet pkt = openqueue_getFreePacketBuffer(COMPONENT_UDPRAND); if (pkt==NULL) { openserial_printError(COMPONENT_UDPRAND,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); return; } pkt->creator = COMPONENT_UDPRAND; pkt->owner = COMPONENT_UDPRAND; pkt->l4_protocol = IANA_UDP; pkt->l4_sourcePortORicmpv6Type = WKP_UDP_RAND; pkt->l4_destination_port = WKP_UDP_RAND; pkt->l3_destinationAdd.type = ADDR_128B; memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_motedata,16); packetfunctions_reserveHeaderSize(pkt,2); ((uint8_t*)pkt->payload)[0] = openrandom_get16b()%0xff; ((uint8_t*)pkt->payload)[1] = openrandom_get16b()%0xff; //send packet if ((openudp_send(pkt))==E_FAIL) { openqueue_freePacketBuffer(pkt); } }
/** \brief Send an keep-alive message, if nessary. 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 sendKa() { OpenQueueEntry_t* kaPkt; open_addr_t* kaNeighAddr; // 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) { kaNeighAddr = neighbors_KaNeighbor(); if (kaNeighAddr!=NULL) { // get a free packet buffer kaPkt = openqueue_getFreePacketBuffer(COMPONENT_RES); if (kaPkt==NULL) { openserial_printError(COMPONENT_RES,ERR_NO_FREE_PACKET_BUFFER, (errorparameter_t)0, (errorparameter_t)0); return; } // declare ownership over that packet kaPkt->creator = COMPONENT_RES; kaPkt->owner = COMPONENT_RES; // some l2 information about this packet kaPkt->l2_frameType = IEEE154_TYPE_DATA; memcpy(&(kaPkt->l2_nextORpreviousHop),kaNeighAddr,sizeof(open_addr_t)); // put in queue for MAC to handle res_send_internal(kaPkt); res_vars.busySending = TRUE; } } }