diff --git a/examples/platform/posix/platform.c b/examples/platform/posix/platform.c index 7dc8a8362..e913e0162 100644 --- a/examples/platform/posix/platform.c +++ b/examples/platform/posix/platform.c @@ -44,6 +44,7 @@ #include "platform.h" uint32_t NODE_ID = 1; +uint32_t WELLKNOWN_NODE_ID = 34; void PlatformInit(void) { diff --git a/examples/platform/posix/platform.h b/examples/platform/posix/platform.h index 32d125fd6..b5bc4368d 100644 --- a/examples/platform/posix/platform.h +++ b/examples/platform/posix/platform.h @@ -49,6 +49,12 @@ extern "C" { */ extern uint32_t NODE_ID; +/** + * Well-known Unique ID used by a simulated radio that supports promiscuous mode. + * + */ +extern uint32_t WELLKNOWN_NODE_ID; + /** * This method performs all platform-specific initialization. * diff --git a/examples/platform/posix/radio.cpp b/examples/platform/posix/radio.cpp index deb6ff0df..8c5da7c54 100644 --- a/examples/platform/posix/radio.cpp +++ b/examples/platform/posix/radio.cpp @@ -86,6 +86,8 @@ static uint16_t s_panid; static int s_sockfd; +static bool s_promiscuous = false; + ThreadError otPlatRadioSetPanId(uint16_t panid) { s_panid = panid; @@ -113,7 +115,16 @@ void PlatformRadioInit(void) struct sockaddr_in sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); sockaddr.sin_family = AF_INET; - sockaddr.sin_port = htons(9000 + NODE_ID); + + if (s_promiscuous) + { + sockaddr.sin_port = htons(9000 + WELLKNOWN_NODE_ID); + } + else + { + sockaddr.sin_port = htons(9000 + NODE_ID); + } + sockaddr.sin_addr.s_addr = INADDR_ANY; s_sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); @@ -219,6 +230,16 @@ otRadioCaps otPlatRadioGetCaps(void) return kRadioCapsNone; } +void otPlatRadioSetPromiscuous(bool aEnable) +{ + s_promiscuous = aEnable; +} + +bool otPlatRadioGetPromiscuous(void) +{ + return s_promiscuous; +} + ThreadError otPlatRadioHandleTransmitDone(bool *rxPending) { ThreadError error = kThreadError_None; @@ -318,7 +339,7 @@ int radioTransmit(void) s_transmit_message.mChannel = s_transmit_frame.mChannel; - for (unsigned i = 1; i < 34; i++) + for (unsigned i = 1; i < WELLKNOWN_NODE_ID; i++) { if (NODE_ID == i) { @@ -331,6 +352,11 @@ int radioTransmit(void) 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 (reinterpret_cast(&s_transmit_frame)->GetAckRequest()) { s_state = kStateAckWait; @@ -402,7 +428,7 @@ void radioSendAck(void) s_ack_message.mChannel = s_receive_frame.mChannel; - for (unsigned i = 1; i < 34; i++) + for (unsigned i = 1; i < WELLKNOWN_NODE_ID; i++) { if (NODE_ID == i) { @@ -412,6 +438,9 @@ void radioSendAck(void) sockaddr.sin_port = htons(9000 + i); sendto(s_sockfd, &s_ack_message, 1 + s_ack_frame.mLength, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); } + + 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)); } void radioProcessFrame(void) @@ -421,6 +450,7 @@ void radioProcessFrame(void) uint16_t dstpan; Mac::Address dstaddr; + VerifyOrExit(s_promiscuous == false, error = kThreadError_None); receive_frame = reinterpret_cast(&s_receive_frame); receive_frame->GetDstAddr(dstaddr); diff --git a/include/platform/radio.h b/include/platform/radio.h index 7d028ea89..76e3e0846 100644 --- a/include/platform/radio.h +++ b/include/platform/radio.h @@ -277,6 +277,21 @@ int8_t otPlatRadioGetNoiseFloor(void); */ otRadioCaps otPlatRadioGetCaps(void); +/** + * Enable or disable promiscuous mode. + * + * @param[in] aEnable A value to enable or disable promiscuous mode. + */ +void otPlatRadioSetPromiscuous(bool aEnable); + +/** + * Get the status of promiscuous mode. + * + * @retval ::true The promiscuous mode is enabled. + * @retval ::false The promiscuous mode is disabled. + */ +bool otPlatRadioGetPromiscuous(void); + /** * @} *