/****************************************************************************** * @fn nwk_buildFrame * * @brief Builds an output frame for the port and message enclosed. * This routine prepends the frame header and populates the * frame in the output queue. * * input parameters * @param port - port from application * @param msg - pointer to message from app to be sent * @param len - length of enclosed message * @param hops - number of hops allowed. this is less than MAX_HOPS * whenever the frame is being sent to the AP. this is to * help mitigate the (short) broadcast storms * * output parameters * * @return pointer to frameInfo_t structure created. NULL if there is * no room in output queue. */ frameInfo_t *nwk_buildFrame(uint8_t port, uint8_t *msg, uint8_t len, uint8_t hops) { frameInfo_t *fInfoPtr; if (!(fInfoPtr=nwk_QfindSlot(OUTQ))) { return (frameInfo_t *)NULL; } MRFI_SET_PAYLOAD_LEN(&fInfoPtr->mrfiPkt, len+F_APP_PAYLOAD_OS); PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ENCRYPT_OS, 0); PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_PORT_OS, port); PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_TRACTID_OS, sTRACTID); while (!(++sTRACTID)) ; /* transaction ID can't be 0 */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_RX_TYPE, sMyRxType); PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_HOP_COUNT, hops); /* reset ack-relevant bits */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ACK_REQ, 0); PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_ACK_RPLY, 0); /* reset forwarding bit */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt), F_FWD_FRAME, 0); memcpy(MRFI_P_PAYLOAD(&fInfoPtr->mrfiPkt)+F_APP_PAYLOAD_OS, msg, len); memcpy(MRFI_P_SRC_ADDR(&fInfoPtr->mrfiPkt), sMyAddr, NET_ADDR_SIZE); return fInfoPtr; }
/****************************************************************************** * @fn mrfiLinkSend * * @brief Send data on the RX link. * * @param pBuf - buffer to be transmitted * * @param len - number of bytes to be transmitted * * @return Return code indicates success or failure of transmit: * MRFI_TX_RESULT_SUCCESS - transmit succeeded * MRFI_TX_RESULT_FAILED - transmit failed because CCA or ACK failed */ uint8 mrfiLinkSend(uint8 *pBuf, uint8 len, uint8 nRetrans) { uint8 v,i,status; v= halIntLock(); MRFI_SET_PAYLOAD_LEN(&pkt, len+2); memcpy(MRFI_P_DST_ADDR(&pkt), dest_addr, 4); memcpy(MRFI_P_SRC_ADDR(&pkt), src_addr, 4); MRFI_P_PAYLOAD(&pkt)[0]= seqSend; MRFI_P_PAYLOAD(&pkt)[1]= MRFI_LINK_DATA; memcpy(MRFI_P_PAYLOAD(&pkt)+2, pBuf, len); halIntUnlock(v); for (i=0;i<nRetrans;i++) { status= MRFI_Transmit(&pkt, MRFI_TX_TYPE_CCA); if (status==MRFI_TX_RESULT_SUCCESS) { if (waitForAck(20)) { seqSend++; break; } else { status= MRFI_TX_RESULT_FAILED; // wait random time if sending is not successful // (20-40 milliseconds) halMcuWaitUs( (20000/255*MRFI_RandomByte()) + 20000 ); } } } return status; }
/****************************************************************************** * @fn sendAck * * @brief Send an acknowledge packet (no payload) * * @param none * * @return none */ static void sendAck(void) { uint8 v; v= halIntLock(); MRFI_SET_PAYLOAD_LEN(&pkt, 2); memcpy(MRFI_P_DST_ADDR(&pkt), dest_addr, 4); memcpy(MRFI_P_SRC_ADDR(&pkt), src_addr, 4); MRFI_P_PAYLOAD(&pkt)[0]= seqRecv; MRFI_P_PAYLOAD(&pkt)[1]= MRFI_LINK_ACK; halIntUnlock(v); MRFI_Transmit(&pkt, MRFI_TX_TYPE_FORCED); }
/****************************************************************************** * @fn nwk_sendAckReply * * @brief Send an acknowledgement reply frame. * * input parameters * @param frame - pointer to frame with ack request. * @param port - port on whcih reply expected. * * output parameters * * @return void */ void nwk_sendAckReply(mrfiPacket_t *frame, uint8_t port) { mrfiPacket_t dFrame; uint8_t tid = GET_FROM_FRAME(MRFI_P_PAYLOAD(frame), F_TRACTID_OS); /* set the type of device sending the frame in the header */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TX_DEVICE, sMyTxType); /* set the listen type of device sending the frame in the header. */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_RX_TYPE, sMyRxType); /* destination address from received frame */ memcpy(MRFI_P_DST_ADDR(&dFrame), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); /* source address */ memcpy(MRFI_P_SRC_ADDR(&dFrame), sMyAddr, NET_ADDR_SIZE); /* port is the source the Tx port from the connection object */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_PORT_OS, port); /* frame length... */ MRFI_SET_PAYLOAD_LEN(&dFrame,F_APP_PAYLOAD_OS); /* transaction ID taken from source frame */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TRACTID_OS, tid); /* hop count... */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_HOP_COUNT, MAX_HOPS); /* set ACK field */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_RPLY, F_ACK_RPLY_TYPE); PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_REQ, 0); /* This is not a forwarded frame */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_FWD_FRAME, 0); /* Encryption state */ #if !defined(SMPL_SECURE) PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, 0); #else PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); nwk_setSecureFrame(&dFrame, 0, 0); #endif MRFI_Transmit(&dFrame, MRFI_TX_TYPE_FORCED); return; }
void nwk_SendEmptyPollRspFrame(mrfiPacket_t *frame) { mrfiPacket_t dFrame; uint8_t port = *(MRFI_P_PAYLOAD(frame) + F_APP_PAYLOAD_OS + M_POLL_PORT_OS); /* set the type of device sending the frame in the header. we know it's an AP */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TX_DEVICE, F_TX_DEVICE_AP); /* set the listen type of device sending the frame in the header. we know it's * an AP is is probably always on...but use the static variable anyway. */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_RX_TYPE, sMyRxType); /* destination address from received frame (polling device) */ memcpy(MRFI_P_DST_ADDR(&dFrame), MRFI_P_SRC_ADDR(frame), NET_ADDR_SIZE); /* source address */ memcpy(MRFI_P_SRC_ADDR(&dFrame), MRFI_P_PAYLOAD( frame) + F_APP_PAYLOAD_OS + M_POLL_ADDR_OS, NET_ADDR_SIZE); /* port is the port requested */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_PORT_OS, port); /* frame length... */ MRFI_SET_PAYLOAD_LEN(&dFrame, F_APP_PAYLOAD_OS); /* transaction ID... */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_TRACTID_OS, sTRACTID); sTRACTID++; /* hop count... */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_HOP_COUNT, MAX_HOPS_FROM_AP); /* Ack fields */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_RPLY, 0); PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ACK_REQ, 0); /* This is logically a forwarded frame */ PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_FWD_FRAME, F_FRAME_FWD_TYPE); /* Encryption state */ # if !defined(SMPL_SECURE) PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, 0); # else PUT_INTO_FRAME(MRFI_P_PAYLOAD(&dFrame), F_ENCRYPT_OS, F_ENCRYPT_OS_MSK); nwk_setSecureFrame(&dFrame, 0, 0); # endif MRFI_Transmit(&dFrame, MRFI_TX_TYPE_FORCED); return; }