diff --git a/examples/platforms/cc2538/radio.c b/examples/platforms/cc2538/radio.c index 62f5702be..8b934bc27 100644 --- a/examples/platforms/cc2538/radio.c +++ b/examples/platforms/cc2538/radio.c @@ -74,17 +74,7 @@ static ThreadError sReceiveError; static uint8_t sTransmitPsdu[IEEE802154_MAX_LENGTH]; static uint8_t sReceivePsdu[IEEE802154_MAX_LENGTH]; -typedef enum PhyState -{ - kStateDisabled = 0, - kStateSleep, - kStateIdle, - kStateListen, - kStateReceive, - kStateTransmit, -} PhyState; - -static PhyState sState; +static PhyState sState = kStateDisabled; static bool sIsReceiverEnabled = false; void enableReceiver(void) @@ -128,28 +118,49 @@ void setChannel(uint8_t channel) ThreadError otPlatRadioSetPanId(uint16_t panid) { - HWREG(RFCORE_FFSM_PAN_ID0) = panid & 0xFF; - HWREG(RFCORE_FFSM_PAN_ID1) = panid >> 8; - return kThreadError_None; + ThreadError error = kThreadError_Busy; + + if (sState != kStateTransmit) + { + HWREG(RFCORE_FFSM_PAN_ID0) = panid & 0xFF; + HWREG(RFCORE_FFSM_PAN_ID1) = panid >> 8; + error = kThreadError_None; + } + + return error; } ThreadError otPlatRadioSetExtendedAddress(uint8_t *address) { - int i; + ThreadError error = kThreadError_Busy; - for (i = 0; i < 8; i++) + if (sState != kStateTransmit) { - ((volatile uint32_t *)RFCORE_FFSM_EXT_ADDR0)[i] = address[i]; + int i; + + for (i = 0; i < 8; i++) + { + ((volatile uint32_t *)RFCORE_FFSM_EXT_ADDR0)[i] = address[i]; + } + + error = kThreadError_None; } - return kThreadError_None; + return error; } ThreadError otPlatRadioSetShortAddress(uint16_t address) { - HWREG(RFCORE_FFSM_SHORT_ADDR0) = address & 0xFF; - HWREG(RFCORE_FFSM_SHORT_ADDR1) = address >> 8; - return kThreadError_None; + ThreadError error = kThreadError_Busy; + + if (sState != kStateTransmit) + { + HWREG(RFCORE_FFSM_SHORT_ADDR0) = address & 0xFF; + HWREG(RFCORE_FFSM_SHORT_ADDR1) = address >> 8; + error = kThreadError_None; + } + + return error; } void cc2538RadioInit(void) @@ -181,76 +192,102 @@ void cc2538RadioInit(void) ThreadError otPlatRadioEnable(void) { - ThreadError error = kThreadError_None; + ThreadError error = kThreadError_Busy; - VerifyOrExit(sState == kStateDisabled, error = kThreadError_Busy); - sState = kStateSleep; + if (sState == kStateSleep || sState == kStateDisabled) + { + error = kThreadError_None; + sState = kStateSleep; + } -exit: return error; } ThreadError otPlatRadioDisable(void) { - ThreadError error = kThreadError_None; + ThreadError error = kThreadError_Busy; - VerifyOrExit(sState == kStateIdle, error = kThreadError_Busy); - sState = kStateDisabled; + if (sState == kStateDisabled || sState == kStateSleep) + { + error = kThreadError_None; + sState = kStateDisabled; + } -exit: return error; } ThreadError otPlatRadioSleep(void) { - ThreadError error = kThreadError_None; + ThreadError error = kThreadError_Busy; - VerifyOrExit(error == kStateIdle, error = kThreadError_Busy); - sState = kStateSleep; - -exit: - return error; -} - -ThreadError otPlatRadioIdle(void) -{ - ThreadError error = kThreadError_None; - - switch (sState) + if (sState == kStateSleep || sState == kStateReceive) { - case kStateSleep: - sState = kStateIdle; - break; - - case kStateIdle: - break; - - case kStateListen: - case kStateTransmit: + error = kThreadError_None; + sState = kStateSleep; disableReceiver(); - sState = kStateIdle; - break; - - case kStateReceive: - case kStateDisabled: - ExitNow(error = kThreadError_Busy); - break; } -exit: return error; } ThreadError otPlatRadioReceive(uint8_t aChannel) { - ThreadError error = kThreadError_None; + ThreadError error = kThreadError_Busy; - VerifyOrExit(sState == kStateIdle, error = kThreadError_Busy); - sState = kStateListen; + if (sState != kStateDisabled) + { + error = kThreadError_None; + sState = kStateReceive; + setChannel(aChannel); + sReceiveFrame.mChannel = aChannel; + enableReceiver(); + } - setChannel(aChannel); - sReceiveFrame.mChannel = aChannel; - enableReceiver(); + return error; +} + +ThreadError otPlatRadioTransmit(void) +{ + ThreadError error = kThreadError_Busy; + + if (sState == kStateReceive) + { + int i; + + error = kThreadError_None; + sState = kStateTransmit; + sTransmitError = kThreadError_None; + + while (HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); + + // flush txfifo + HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX; + HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX; + + // frame length + HWREG(RFCORE_SFR_RFDATA) = sTransmitFrame.mLength; + + // frame data + for (i = 0; i < sTransmitFrame.mLength; i++) + { + HWREG(RFCORE_SFR_RFDATA) = sTransmitFrame.mPsdu[i]; + } + + setChannel(sTransmitFrame.mChannel); + + while ((HWREG(RFCORE_XREG_FSMSTAT1) & 1) == 0); + + // wait for valid rssi + while ((HWREG(RFCORE_XREG_RSSISTAT) & RFCORE_XREG_RSSISTAT_RSSI_VALID) == 0); + + VerifyOrExit(HWREG(RFCORE_XREG_FSMSTAT1) & (RFCORE_XREG_FSMSTAT1_CCA | RFCORE_XREG_FSMSTAT1_SFD), + sTransmitError = kThreadError_ChannelAccessFailure); + + // begin transmit + HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISTXON; + + while (HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); + } exit: return error; @@ -261,56 +298,6 @@ RadioPacket *otPlatRadioGetTransmitBuffer(void) return &sTransmitFrame; } -ThreadError otPlatRadioTransmit(void) -{ - ThreadError error = kThreadError_None; - int i; - - VerifyOrExit(sState == kStateIdle, error = kThreadError_Busy); - sState = kStateTransmit; - sTransmitError = kThreadError_None; - - while (HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); - - // flush txfifo - HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX; - HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISFLUSHTX; - - // frame length - HWREG(RFCORE_SFR_RFDATA) = sTransmitFrame.mLength; - - // frame data - for (i = 0; i < sTransmitFrame.mLength; i++) - { - HWREG(RFCORE_SFR_RFDATA) = sTransmitFrame.mPsdu[i]; - } - - setChannel(sTransmitFrame.mChannel); - enableReceiver(); - - while ((HWREG(RFCORE_XREG_FSMSTAT1) & 1) == 0); - - // wait for valid rssi - while ((HWREG(RFCORE_XREG_RSSISTAT) & RFCORE_XREG_RSSISTAT_RSSI_VALID) == 0); - - VerifyOrExit(HWREG(RFCORE_XREG_FSMSTAT1) & (RFCORE_XREG_FSMSTAT1_CCA | RFCORE_XREG_FSMSTAT1_SFD), - sTransmitError = kThreadError_ChannelAccessFailure); - - // begin transmit - HWREG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_ISTXON; - - while (HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE); - -exit: - - if (sTransmitError != kThreadError_None || (sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0) - { - disableReceiver(); - } - - return error; -} - int8_t otPlatRadioGetNoiseFloor(void) { return 0; @@ -344,7 +331,7 @@ void readFrame(void) uint8_t crcCorr; int i; - VerifyOrExit(sState == kStateListen || sState == kStateTransmit, ;); + VerifyOrExit(sState == kStateReceive || sState == kStateTransmit, ;); VerifyOrExit((HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP) != 0, ;); // read length @@ -382,50 +369,28 @@ void cc2538RadioProcess(void) { readFrame(); - switch (sState) + if ((sState == kStateReceive) && (sReceiveFrame.mLength > 0)) { - case kStateDisabled: - break; + otPlatRadioReceiveDone(&sReceiveFrame, sReceiveError); + } - case kStateSleep: - break; - - case kStateIdle: - break; - - case kStateListen: - case kStateReceive: - if (sReceiveFrame.mLength > 0) - { - sState = kStateIdle; - otPlatRadioReceiveDone(&sReceiveFrame, sReceiveError); - } - - break; - - case kStateTransmit: + if (sState == kStateTransmit) + { if (sTransmitError != kThreadError_None || (sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0) { - sState = kStateIdle; + sState = kStateReceive; otPlatRadioTransmitDone(false, sTransmitError); } else if (sReceiveFrame.mLength == IEEE802154_ACK_LENGTH && (sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_ACK && (sReceiveFrame.mPsdu[IEEE802154_DSN_OFFSET] == sTransmitFrame.mPsdu[IEEE802154_DSN_OFFSET])) { - sState = kStateIdle; + sState = kStateReceive; otPlatRadioTransmitDone((sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_PENDING) != 0, sTransmitError); } - - break; } sReceiveFrame.mLength = 0; - - if (sState == kStateIdle) - { - disableReceiver(); - } } void RFCoreRxTxIntHandler(void) diff --git a/examples/platforms/posix/radio.c b/examples/platforms/posix/radio.c index 6a7f7cc91..520f68d5b 100644 --- a/examples/platforms/posix/radio.c +++ b/examples/platforms/posix/radio.c @@ -86,41 +86,31 @@ enum IEEE802154_MACCMD_DATA_REQ = 4, }; -typedef enum PhyState -{ - kStateDisabled = 0, - kStateSleep = 1, - kStateIdle = 2, - kStateListen = 3, - kStateReceive = 4, - kStateTransmit = 5, - kStateAckWait = 6, -} PhyState; - struct OT_TOOL_PACKED_BEGIN RadioMessage { uint8_t mChannel; uint8_t mPsdu[kMaxPHYPacketSize]; } OT_TOOL_PACKED_END; +static void radioTransmit(const struct RadioMessage *msg, const struct RadioPacket *pkt); +static void radioSendMessage(void); static void radioSendAck(void); static void radioProcessFrame(void); -static PhyState s_state = kStateDisabled; -static struct RadioMessage s_receive_message; -static struct RadioMessage s_transmit_message; -static struct RadioMessage s_ack_message; -static RadioPacket s_receive_frame; -static RadioPacket s_transmit_frame; -static RadioPacket s_ack_frame; +static PhyState sState = kStateDisabled; +static struct RadioMessage sReceiveMessage; +static struct RadioMessage sTransmitMessage; +static struct RadioMessage sAckMessage; +static RadioPacket sReceiveFrame; +static RadioPacket sTransmitFrame; +static RadioPacket sAckFrame; -static uint8_t s_extended_address[OT_EXT_ADDRESS_SIZE]; -static uint16_t s_short_address; -static uint16_t s_panid; - -static int s_sockfd; - -static bool s_promiscuous = false; +static uint8_t sExtendedAddress[OT_EXT_ADDRESS_SIZE]; +static uint16_t sShortAddress; +static uint16_t sPanid; +static int sSockFd; +static bool sPromiscuous = false; +static bool sAckWait = false; static inline bool isFrameTypeAck(const uint8_t *frame) { @@ -267,26 +257,52 @@ static inline void getExtAddress(const uint8_t *frame, otExtAddress *address) ThreadError otPlatRadioSetPanId(uint16_t panid) { - s_panid = panid; - return kThreadError_None; + ThreadError error = kThreadError_Busy; + + if (sState != kStateTransmit) + { + sPanid = panid; + error = kThreadError_None; + } + + return error; } ThreadError otPlatRadioSetExtendedAddress(uint8_t *address) { - size_t i; + ThreadError error = kThreadError_Busy; - for (i = 0; i < sizeof(s_extended_address); i++) + if (sState != kStateTransmit) { - s_extended_address[i] = address[sizeof(s_extended_address) - 1 - i]; + size_t i; + + for (i = 0; i < sizeof(sExtendedAddress); i++) + { + sExtendedAddress[i] = address[sizeof(sExtendedAddress) - 1 - i]; + } + + error = kThreadError_None; } - return kThreadError_None; + return error; } ThreadError otPlatRadioSetShortAddress(uint16_t address) { - s_short_address = address; - return kThreadError_None; + ThreadError error = kThreadError_Busy; + + if (sState != kStateTransmit) + { + sShortAddress = address; + error = kThreadError_None; + } + + return error; +} + +void otPlatRadioSetPromiscuous(bool aEnable) +{ + sPromiscuous = aEnable; } void posixRadioInit(void) @@ -295,7 +311,7 @@ void posixRadioInit(void) memset(&sockaddr, 0, sizeof(sockaddr)); sockaddr.sin_family = AF_INET; - if (s_promiscuous) + if (sPromiscuous) { sockaddr.sin_port = htons(9000 + WELLKNOWN_NODE_ID); } @@ -306,96 +322,84 @@ void posixRadioInit(void) sockaddr.sin_addr.s_addr = INADDR_ANY; - s_sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - bind(s_sockfd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); + sSockFd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + bind(sSockFd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); - s_receive_frame.mPsdu = s_receive_message.mPsdu; - s_transmit_frame.mPsdu = s_transmit_message.mPsdu; - s_ack_frame.mPsdu = s_ack_message.mPsdu; + sReceiveFrame.mPsdu = sReceiveMessage.mPsdu; + sTransmitFrame.mPsdu = sTransmitMessage.mPsdu; + sAckFrame.mPsdu = sAckMessage.mPsdu; } ThreadError otPlatRadioEnable(void) { - ThreadError error = kThreadError_None; + ThreadError error = kThreadError_Busy; - VerifyOrExit(s_state == kStateDisabled, error = kThreadError_Busy); - s_state = kStateSleep; + if (sState == kStateSleep || sState == kStateDisabled) + { + error = kThreadError_None; + sState = kStateSleep; + } -exit: return error; } ThreadError otPlatRadioDisable(void) { - s_state = kStateDisabled; - return kThreadError_None; + ThreadError error = kThreadError_Busy; + + if (sState == kStateDisabled || sState == kStateSleep) + { + error = kThreadError_None; + sState = kStateDisabled; + } + + return error; } ThreadError otPlatRadioSleep(void) { - ThreadError error = kThreadError_None; + ThreadError error = kThreadError_Busy; - VerifyOrExit(s_state == kStateIdle, error = kThreadError_Busy); - s_state = kStateSleep; - -exit: - return error; -} - -ThreadError otPlatRadioIdle(void) -{ - ThreadError error = kThreadError_None; - - switch (s_state) + if (sState == kStateSleep || sState == kStateReceive) { - case kStateSleep: - s_state = kStateIdle; - break; - - case kStateIdle: - break; - - case kStateListen: - case kStateTransmit: - case kStateAckWait: - s_state = kStateIdle; - break; - - case kStateDisabled: - case kStateReceive: - ExitNow(error = kThreadError_Busy); + error = kThreadError_None; + sState = kStateSleep; } -exit: return error; } ThreadError otPlatRadioReceive(uint8_t aChannel) { - ThreadError error = kThreadError_None; + ThreadError error = kThreadError_Busy; - VerifyOrExit(s_state == kStateIdle, error = kThreadError_Busy); - s_state = kStateListen; - s_receive_frame.mChannel = aChannel; + if (sState != kStateDisabled) + { + error = kThreadError_None; + sState = kStateReceive; + sAckWait = false; + sReceiveFrame.mChannel = aChannel; + } + + return error; +} + +ThreadError otPlatRadioTransmit(void) +{ + ThreadError error = kThreadError_Busy; + + if ((sState == kStateTransmit && !sAckWait) || sState == kStateReceive) + { + error = kThreadError_None; + sState = kStateTransmit; + } -exit: return error; } RadioPacket *otPlatRadioGetTransmitBuffer(void) { - return &s_transmit_frame; -} - -ThreadError otPlatRadioTransmit(void) -{ - ThreadError error = kThreadError_None; - - VerifyOrExit(s_state == kStateIdle, error = kThreadError_Busy); - s_state = kStateTransmit; - -exit: - return error; + return &sTransmitFrame; } int8_t otPlatRadioGetNoiseFloor(void) @@ -408,139 +412,76 @@ otRadioCaps otPlatRadioGetCaps(void) return kRadioCapsNone; } -void otPlatRadioSetPromiscuous(bool aEnable) -{ - s_promiscuous = aEnable; -} - bool otPlatRadioGetPromiscuous(void) { - return s_promiscuous; + return sPromiscuous; } void radioReceive(void) { - uint8_t tx_sequence, rx_sequence; - int rval; - - VerifyOrExit(s_state == kStateDisabled || s_state == kStateSleep || s_state == kStateListen || - s_state == kStateAckWait, ;); - - rval = recvfrom(s_sockfd, &s_receive_message, sizeof(s_receive_message), 0, NULL, NULL); + int rval = recvfrom(sSockFd, &sReceiveMessage, sizeof(sReceiveMessage), 0, NULL, NULL); assert(rval >= 0); - switch (s_state) + sReceiveFrame.mLength = rval - 1; + + if (sAckWait) { - case kStateDisabled: - case kStateSleep: - case kStateIdle: - case kStateTransmit: - break; - - case kStateAckWait: - s_receive_frame.mLength = rval - 1; - - if (!isFrameTypeAck(s_receive_frame.mPsdu)) + if (isFrameTypeAck(sReceiveFrame.mPsdu)) { - break; + uint8_t tx_sequence = getDsn(sTransmitFrame.mPsdu); + uint8_t rx_sequence = getDsn(sReceiveFrame.mPsdu); + + if (tx_sequence == rx_sequence) + { + sState = kStateReceive; + sAckWait = false; + otPlatRadioTransmitDone(isFramePending(sReceiveFrame.mPsdu), kThreadError_None); + } } - - tx_sequence = getDsn(s_transmit_frame.mPsdu); - rx_sequence = getDsn(s_receive_frame.mPsdu); - - if (tx_sequence != rx_sequence) - { - break; - } - - s_state = kStateIdle; - otPlatRadioTransmitDone(isFramePending(s_receive_frame.mPsdu), kThreadError_None); - break; - - case kStateListen: - if (s_receive_frame.mChannel != s_receive_message.mChannel) - { - break; - } - - s_state = kStateReceive; - s_receive_frame.mLength = rval - 1; - - radioProcessFrame(); - break; - - case kStateReceive: - assert(false); - break; - } - -exit: - return; -} - -int radioTransmit(void) -{ - struct sockaddr_in sockaddr; - int rval = 0; - uint32_t i; - - memset(&sockaddr, 0, sizeof(sockaddr)); - sockaddr.sin_family = AF_INET; - inet_pton(AF_INET, "127.0.0.1", &sockaddr.sin_addr); - - s_transmit_message.mChannel = s_transmit_frame.mChannel; - - for (i = 1; i < WELLKNOWN_NODE_ID; i++) - { - if (NODE_ID == i) - { - continue; - } - - sockaddr.sin_port = htons(9000 + i); - rval = sendto(s_sockfd, &s_transmit_message, 1 + s_transmit_frame.mLength, 0, (struct sockaddr *)&sockaddr, - sizeof(sockaddr)); - assert(rval >= 0); - } - - sockaddr.sin_port = htons(9000 + WELLKNOWN_NODE_ID); - rval = sendto(s_sockfd, &s_transmit_message, 1 + s_transmit_frame.mLength, 0, (struct sockaddr *)&sockaddr, - sizeof(sockaddr)); - assert(rval >= 0); - - if (isAckRequested(s_transmit_frame.mPsdu)) - { - s_state = kStateAckWait; } else { - s_state = kStateIdle; + if (sReceiveFrame.mChannel == sReceiveMessage.mChannel) + { + radioProcessFrame(); + } + } +} + +void radioSendMessage(void) +{ + sTransmitMessage.mChannel = sTransmitFrame.mChannel; + + radioTransmit(&sTransmitMessage, &sTransmitFrame); + + sAckWait = isAckRequested(sTransmitFrame.mPsdu); + + if (!sAckWait) + { + sState = kStateReceive; otPlatRadioTransmitDone(false, kThreadError_None); } - - return rval; } void posixRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMaxFd) { - if (aReadFdSet != NULL && - (s_state == kStateDisabled || s_state == kStateSleep || s_state == kStateListen || s_state == kStateAckWait)) + if (aReadFdSet != NULL && (sState != kStateTransmit || sAckWait)) { - FD_SET(s_sockfd, aReadFdSet); + FD_SET(sSockFd, aReadFdSet); - if (aMaxFd != NULL && *aMaxFd < s_sockfd) + if (aMaxFd != NULL && *aMaxFd < sSockFd) { - *aMaxFd = s_sockfd; + *aMaxFd = sSockFd; } } - if (aWriteFdSet != NULL && s_state == kStateTransmit) + if (aWriteFdSet != NULL && sState == kStateTransmit && !sAckWait) { - FD_SET(s_sockfd, aWriteFdSet); + FD_SET(sSockFd, aWriteFdSet); - if (aMaxFd != NULL && *aMaxFd < s_sockfd) + if (aMaxFd != NULL && *aMaxFd < sSockFd) { - *aMaxFd = s_sockfd; + *aMaxFd = sSockFd; } } } @@ -548,54 +489,63 @@ void posixRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMaxFd) void posixRadioProcess(void) { const int flags = POLLRDNORM | POLLERR | POLLNVAL | POLLHUP; - struct pollfd pollfd = { s_sockfd, flags, 0 }; + struct pollfd pollfd = { sSockFd, flags, 0 }; if (poll(&pollfd, 1, 0) > 0 && (pollfd.revents & flags) != 0) { - radioReceive(); + if (sAckWait || sState == kStateReceive) + { + radioReceive(); + } } - if (s_state == kStateTransmit) + if (sState == kStateTransmit && !sAckWait) { - radioTransmit(); + radioSendMessage(); } } -void radioSendAck(void) +void radioTransmit(const struct RadioMessage *msg, const struct RadioPacket *pkt) { - struct sockaddr_in sockaddr; uint32_t i; - - s_ack_frame.mLength = IEEE802154_ACK_LENGTH; - s_ack_message.mPsdu[0] = IEEE802154_FRAME_TYPE_ACK; - - if (isDataRequest(s_receive_frame.mPsdu)) - { - s_ack_message.mPsdu[0] |= IEEE802154_FRAME_PENDING; - } - - s_ack_message.mPsdu[1] = 0; - s_ack_message.mPsdu[2] = getDsn(s_receive_frame.mPsdu); + struct sockaddr_in sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); sockaddr.sin_family = AF_INET; inet_pton(AF_INET, "127.0.0.1", &sockaddr.sin_addr); - s_ack_message.mChannel = s_receive_frame.mChannel; - - for (i = 1; i < WELLKNOWN_NODE_ID; i++) + for (i = 1; i <= WELLKNOWN_NODE_ID; i++) { + int rval; + if (NODE_ID == i) { continue; } sockaddr.sin_port = htons(9000 + i); - sendto(s_sockfd, &s_ack_message, 1 + s_ack_frame.mLength, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); + rval = sendto(sSockFd, msg, 1 + pkt->mLength, + 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); + assert(rval >= 0); + } +} + +void radioSendAck(void) +{ + sAckFrame.mLength = IEEE802154_ACK_LENGTH; + sAckMessage.mPsdu[0] = IEEE802154_FRAME_TYPE_ACK; + + if (isDataRequest(sReceiveFrame.mPsdu)) + { + sAckMessage.mPsdu[0] |= IEEE802154_FRAME_PENDING; } - sockaddr.sin_port = htons(9000 + WELLKNOWN_NODE_ID); - sendto(s_sockfd, &s_ack_message, 1 + s_ack_frame.mLength, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); + sAckMessage.mPsdu[1] = 0; + sAckMessage.mPsdu[2] = getDsn(sReceiveFrame.mPsdu); + + sAckMessage.mChannel = sReceiveFrame.mChannel; + + radioTransmit(&sAckMessage, &sAckFrame); } void radioProcessFrame(void) @@ -605,26 +555,26 @@ void radioProcessFrame(void) otShortAddress short_address; otExtAddress ext_address; - VerifyOrExit(s_promiscuous == false, error = kThreadError_None); + VerifyOrExit(sPromiscuous == false, error = kThreadError_None); - switch (s_receive_frame.mPsdu[1] & IEEE802154_DST_ADDR_MASK) + switch (sReceiveFrame.mPsdu[1] & IEEE802154_DST_ADDR_MASK) { case IEEE802154_DST_ADDR_NONE: break; case IEEE802154_DST_ADDR_SHORT: - dstpan = getDstPan(s_receive_frame.mPsdu); - short_address = getShortAddress(s_receive_frame.mPsdu); - VerifyOrExit((dstpan == IEEE802154_BROADCAST || dstpan == s_panid) && - (short_address == IEEE802154_BROADCAST || short_address == s_short_address), + dstpan = getDstPan(sReceiveFrame.mPsdu); + short_address = getShortAddress(sReceiveFrame.mPsdu); + VerifyOrExit((dstpan == IEEE802154_BROADCAST || dstpan == sPanid) && + (short_address == IEEE802154_BROADCAST || short_address == sShortAddress), error = kThreadError_Abort); break; case IEEE802154_DST_ADDR_EXT: - dstpan = getDstPan(s_receive_frame.mPsdu); - getExtAddress(s_receive_frame.mPsdu, &ext_address); - VerifyOrExit((dstpan == IEEE802154_BROADCAST || dstpan == s_panid) && - memcmp(&ext_address, s_extended_address, sizeof(ext_address)) == 0, + dstpan = getDstPan(sReceiveFrame.mPsdu); + getExtAddress(sReceiveFrame.mPsdu, &ext_address); + VerifyOrExit((dstpan == IEEE802154_BROADCAST || dstpan == sPanid) && + memcmp(&ext_address, sExtendedAddress, sizeof(ext_address)) == 0, error = kThreadError_Abort); break; @@ -632,21 +582,16 @@ void radioProcessFrame(void) ExitNow(error = kThreadError_Abort); } - s_receive_frame.mPower = -20; - s_receive_frame.mLqi = kPhyNoLqi; + sReceiveFrame.mPower = -20; + sReceiveFrame.mLqi = kPhyNoLqi; // generate acknowledgment - if (isAckRequested(s_receive_frame.mPsdu)) + if (isAckRequested(sReceiveFrame.mPsdu)) { radioSendAck(); } exit: - if (s_state != kStateDisabled) - { - s_state = kStateIdle; - } - - otPlatRadioReceiveDone(error == kThreadError_None ? &s_receive_frame : NULL, error); + otPlatRadioReceiveDone(error == kThreadError_None ? &sReceiveFrame : NULL, error); } diff --git a/include/platform/radio.h b/include/platform/radio.h index 0e131ddc7..c195c95ae 100644 --- a/include/platform/radio.h +++ b/include/platform/radio.h @@ -104,6 +104,31 @@ typedef struct RadioPacket bool mSecurityValid; ///< Security Enabled flag is set and frame passes security checks. } RadioPacket; +/** + * This structure represents the state of a radio. + * Initially, a radio is in the Disabled state. + */ +typedef enum PhyState +{ + kStateDisabled = 0, + kStateSleep = 1, + kStateReceive = 2, + kStateTransmit = 3 +} PhyState; + +/** + * The following are valid radio state transitions: + * + * (Radio ON) + * +----------+ Enable() +-------+ Receive() +---------+ Trasnmit() +----------+ + * | |----------->| |----------->| |-------------->| | + * | Disabled | | Sleep | | Receive | | Transmit | + * | |<-----------| |<-----------| |<--------------| | + * +----------+ Disable() +-------+ Sleep() +---------+ Receive() +----------+ + * (Radio OFF) or + * signal TransmitDone + */ + /** * @} * @@ -164,7 +189,7 @@ ThreadError otPlatRadioSetShortAddress(uint16_t aShortAddress); /** * Enable the radio. * - * @retval ::kThreadError_None Successfully transitioned to Idle. + * @retval ::kThreadError_None Successfully transitioned to Sleep. * @retval ::kThreadError_Busy The radio was already enabled. */ ThreadError otPlatRadioEnable(void); @@ -177,33 +202,22 @@ ThreadError otPlatRadioEnable(void); ThreadError otPlatRadioDisable(void); /** - * Transition the radio to Sleep. + * Transition the radio from Receive to Sleep. + * Turn off the radio. * * @retval ::kThreadError_None Successfully transitioned to Sleep. - * @retval ::kThreadError_Busy The radio was not in the Idle state. + * @retval ::kThreadError_Busy The radio was not in the Receive state. */ ThreadError otPlatRadioSleep(void); /** - * Transition the radio to Idle. - * - * @retval ::kThreadError_None Successfully transitioned to Idle. - * @retval ::kThreadError_Busy The radio was busy transmitting or receiving. - */ -ThreadError otPlatRadioIdle(void); - -/** - * Begins the receive sequence on the radio. - * - * The receive sequence consists of: - * 1. Transitioning the radio to Receive from Idle. - * 2. Remain in Receive until a packet is received or reception is aborted. - * 3. Return to Idle. + * Transitioning the radio from Sleep to Receive. + * Turn on the radio. * * @param[in] aChannel The channel to use for receiving. * * @retval ::kThreadError_None Successfully transitioned to Receive. - * @retval ::kThreadError_Busy The radio was not in the Idle state. + * @retval ::kThreadError_Busy The radio was not in the Sleep state. */ ThreadError otPlatRadioReceive(uint8_t aChannel); @@ -218,6 +232,7 @@ ThreadError otPlatRadioReceive(uint8_t aChannel); extern void otPlatRadioReceiveDone(RadioPacket *aPacket, ThreadError aError); /** + * The radio tranitions from Transmit to Receive. * This method returns a pointer to the transmit buffer. * * The caller forms the IEEE 802.15.4 frame in this buffer then calls otPlatRadioTransmit() to request transmission. @@ -234,12 +249,11 @@ RadioPacket *otPlatRadioGetTransmitBuffer(void); * requesting transmission. The channel and transmit power are also included in the RadioPacket structure. * * The transmit sequence consists of: - * 1. Transitioning the radio to Transmit from Idle. + * 1. Transitioning the radio to Transmit from Receive. * 2. Transmits the psdu on the given channel and at the given transmit power. - * 3. Return to Idle. * * @retval ::kThreadError_None Successfully transitioned to Transmit. - * @retval ::kThreadError_Busy The radio was not in the Idle state. + * @retval ::kThreadError_Busy The radio was not in the Receive state. */ ThreadError otPlatRadioTransmit(void); diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index 9a03156d0..e27f5533f 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -433,7 +433,7 @@ void Mac::HandleBeginTransmit(void) Frame &sendFrame(*static_cast(otPlatRadioGetTransmitBuffer())); ThreadError error = kThreadError_None; - if (otPlatRadioIdle() != kThreadError_None) + if (otPlatRadioReceive(mChannel) != kThreadError_None) { mBeginTransmit.Post(); ExitNow(); @@ -543,7 +543,7 @@ void Mac::HandleAckTimer(void *aContext) void Mac::HandleAckTimer(void) { - otPlatRadioIdle(); + otPlatRadioReceive(mChannel); switch (mState) { @@ -1020,7 +1020,7 @@ void Mac::SetPromiscuous(bool aPromiscuous) { otPlatRadioSetPromiscuous(aPromiscuous); - SuccessOrExit(otPlatRadioIdle()); + SuccessOrExit(otPlatRadioReceive(mChannel)); NextOperation(); exit: