diff --git a/examples/cli/Makefile.am b/examples/cli/Makefile.am index 1eb049241..7a247e714 100644 --- a/examples/cli/Makefile.am +++ b/examples/cli/Makefile.am @@ -44,7 +44,6 @@ soc_LDADD = \ $(top_builddir)/src/cli/libopenthread-cli.a \ $(top_builddir)/examples/platform/posix/libopenthread-posix.a \ $(top_builddir)/third_party/mbedtls/libmbedcrypto.a \ - -lpthread \ $(NULL) soc_SOURCES = \ diff --git a/examples/cli/main.cpp b/examples/cli/main.cpp index a28768acc..e0a815e2f 100644 --- a/examples/cli/main.cpp +++ b/examples/cli/main.cpp @@ -32,7 +32,6 @@ #include #include -#include #include struct gengetopt_args_info args_info; @@ -45,32 +44,19 @@ void otSignalTaskletPending(void) int main(int argc, char *argv[]) { - uint32_t atomic_state; - if (cmdline_parser(argc, argv, &args_info) != 0) { exit(1); } - hwAlarmInit(); - hwRadioInit(); - hwRandomInit(); - + PlatformInit(); otInit(); sCliServer.Start(); while (1) { otProcessNextTasklet(); - - atomic_state = otPlatAtomicBegin(); - - if (!otAreTaskletsPending()) - { - hwSleep(); - } - - otPlatAtomicEnd(atomic_state); + PlatformProcessDrivers(); } return 0; diff --git a/examples/ncp/Makefile.am b/examples/ncp/Makefile.am index e495eacae..56a689307 100644 --- a/examples/ncp/Makefile.am +++ b/examples/ncp/Makefile.am @@ -45,7 +45,6 @@ ncp_LDADD = \ $(top_builddir)/src/core/libopenthread.a \ $(top_builddir)/examples/platform/posix/libopenthread-posix.a \ $(top_builddir)/third_party/mbedtls/libmbedcrypto.a \ - -lpthread \ $(NULL) ncp_SOURCES = main.cpp diff --git a/examples/ncp/main.cpp b/examples/ncp/main.cpp index 65a0dd67a..583c9f5e9 100644 --- a/examples/ncp/main.cpp +++ b/examples/ncp/main.cpp @@ -30,7 +30,6 @@ #include #include -#include #include struct gengetopt_args_info args_info; @@ -43,19 +42,12 @@ void otSignalTaskletPending(void) int main(int argc, char *argv[]) { - uint32_t atomic_state; - - memset(&args_info, 0, sizeof(args_info)); - if (cmdline_parser(argc, argv, &args_info) != 0) { exit(1); } - hwAlarmInit(); - hwRadioInit(); - hwRandomInit(); - + PlatformInit(); otInit(); sNcp.Start(); @@ -63,15 +55,7 @@ int main(int argc, char *argv[]) while (1) { otProcessNextTasklet(); - - atomic_state = otPlatAtomicBegin(); - - if (!otAreTaskletsPending()) - { - hwSleep(); - } - - otPlatAtomicEnd(atomic_state); + PlatformProcessDrivers(); } return 0; diff --git a/examples/platform/posix/Makefile.am b/examples/platform/posix/Makefile.am index 82583d965..d2dfef911 100644 --- a/examples/platform/posix/Makefile.am +++ b/examples/platform/posix/Makefile.am @@ -52,9 +52,9 @@ libopenthread_posix_a_CXXFLAGS = \ libopenthread_posix_a_SOURCES = \ alarm.c \ - atomic.c \ cmdline.c \ logging.c \ + platform.c \ radio.cpp \ random.c \ serial.c \ diff --git a/examples/platform/posix/alarm.c b/examples/platform/posix/alarm.c index cf9c07b45..46248bc31 100644 --- a/examples/platform/posix/alarm.c +++ b/examples/platform/posix/alarm.c @@ -26,7 +26,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include #include #include #include @@ -34,20 +33,13 @@ #include -static void *alarm_thread(void *arg); - static bool s_is_running = false; static uint32_t s_alarm = 0; static struct timeval s_start; -static pthread_t s_thread; -static pthread_mutex_t s_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t s_cond = PTHREAD_COND_INITIALIZER; - -void hwAlarmInit(void) +void PlatformAlarmInit(void) { gettimeofday(&s_start, NULL); - pthread_create(&s_thread, NULL, alarm_thread, NULL); } uint32_t otPlatAlarmGetNow(void) @@ -62,65 +54,58 @@ uint32_t otPlatAlarmGetNow(void) void otPlatAlarmStartAt(uint32_t t0, uint32_t dt) { - pthread_mutex_lock(&s_mutex); s_alarm = t0 + dt; s_is_running = true; - pthread_mutex_unlock(&s_mutex); - pthread_cond_signal(&s_cond); } void otPlatAlarmStop(void) { - pthread_mutex_lock(&s_mutex); s_is_running = false; - pthread_mutex_unlock(&s_mutex); } -void *alarm_thread(void *arg) +void PlatformAlarmUpdateTimeout(struct timeval *aTimeout) { int32_t remaining; - struct timeval tva; - struct timeval tvb; - struct timespec ts; - while (1) + if (aTimeout == NULL) { - pthread_mutex_lock(&s_mutex); + return; + } - if (!s_is_running) + if (s_is_running) + { + remaining = s_alarm - otPlatAlarmGetNow(); + + if (remaining > 0) { - // alarm is not running, wait indefinitely - pthread_cond_wait(&s_cond, &s_mutex); - pthread_mutex_unlock(&s_mutex); + aTimeout->tv_sec = remaining / 1000; + aTimeout->tv_usec = (remaining % 1000) * 1000; } else { - // alarm is running - remaining = s_alarm - otPlatAlarmGetNow(); + aTimeout->tv_sec = 0; + aTimeout->tv_usec = 0; + } + } + else + { + aTimeout->tv_sec = 10; + aTimeout->tv_usec = 0; + } +} - if (remaining > 0) - { - // alarm has not passed, wait - gettimeofday(&tva, NULL); - tvb.tv_sec = remaining / 1000; - tvb.tv_usec = (remaining % 1000) * 1000; - timeradd(&tva, &tvb, &tva); +void PlatformAlarmProcess(void) +{ + int32_t remaining; - ts.tv_sec = tva.tv_sec; - ts.tv_nsec = tva.tv_usec * 1000; + if (s_is_running) + { + remaining = s_alarm - otPlatAlarmGetNow(); - pthread_cond_timedwait(&s_cond, &s_mutex, &ts); - pthread_mutex_unlock(&s_mutex); - } - else - { - // alarm has passed, signal - s_is_running = false; - pthread_mutex_unlock(&s_mutex); - otPlatAlarmSignalFired(); - } + if (remaining <= 0) + { + s_is_running = false; + otPlatAlarmFired(); } } - - return NULL; } diff --git a/examples/platform/posix/atomic.c b/examples/platform/posix/atomic.c deleted file mode 100644 index c0e3dcbfd..000000000 --- a/examples/platform/posix/atomic.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2016, Nest Labs, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include - -static pthread_mutex_t s_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t s_cond = PTHREAD_COND_INITIALIZER; - -uint32_t otPlatAtomicBegin(void) -{ - pthread_mutex_lock(&s_mutex); - return 0; -} - -void otPlatAtomicEnd(uint32_t state) -{ - pthread_mutex_unlock(&s_mutex); - pthread_cond_signal(&s_cond); -} - -void hwSleep(void) -{ - pthread_cond_wait(&s_cond, &s_mutex); -} diff --git a/include/platform/atomic.h b/examples/platform/posix/platform.c similarity index 64% rename from include/platform/atomic.h rename to examples/platform/posix/platform.c index c8821ac18..dcb235733 100644 --- a/include/platform/atomic.h +++ b/examples/platform/posix/platform.c @@ -29,46 +29,48 @@ /** * @file * @brief - * This file includes the platform abstraction to support critical sections. + * This file includes the platform-specific initializers. */ -#ifndef ATOMIC_H_ -#define ATOMIC_H_ - +#include +#include +#include #include +#include -#ifdef __cplusplus -extern "C" { -#endif +#include +#include +#include "platform.h" -/** - * @defgroup atomic Atomic - * @ingroup platform - * - * @brief - * This module includes the platform abstraction to support critical sections. - * - * @{ - * - */ +void PlatformInit(void) +{ + PlatformAlarmInit(); + PlatformRadioInit(); + PlatformRandomInit(); +} -/** - * Begin critical section. - */ -uint32_t otPlatAtomicBegin(void); +void PlatformProcessDrivers(void) +{ + fd_set read_fds; + fd_set write_fds; + int max_fd = -1; + struct timeval timeout; + int rval; -/** - * End critical section. - */ -void otPlatAtomicEnd(uint32_t state); + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); -/** - * @} - * - */ + PlatformSerialUpdateFdSet(&read_fds, &write_fds, &max_fd); + PlatformRadioUpdateFdSet(&read_fds, &write_fds, &max_fd); + PlatformAlarmUpdateTimeout(&timeout); -#ifdef __cplusplus -} // end of extern "C" -#endif + if (!otAreTaskletsPending()) + { + rval = select(max_fd + 1, &read_fds, &write_fds, NULL, &timeout); + assert(rval >= 0 && errno != ETIME); + } -#endif // ATOMIC_H_ + PlatformSerialProcess(); + PlatformRadioProcess(); + PlatformAlarmProcess(); +} diff --git a/examples/platform/posix/platform.h b/examples/platform/posix/platform.h index fa8a794b4..72ccf9f40 100644 --- a/examples/platform/posix/platform.h +++ b/examples/platform/posix/platform.h @@ -36,34 +36,94 @@ #define PLATFORM_H_ #include +#include +#include #ifdef __cplusplus extern "C" { #endif +/** + * This method performs all platform-specific initialization. + * + */ +void PlatformInit(void); + +/** + * This method performs all platform-specific processing. + * + */ +void PlatformProcessDrivers(void); + /** * This method initializes the alarm service used by OpenThread. * */ -void hwAlarmInit(void); +void PlatformAlarmInit(void); + +/** + * This method retrieves the time remaining until the alarm fires. + * + * @param[out] aTimeval A pointer to the timeval struct. + * + */ +void PlatformAlarmUpdateTimeout(struct timeval *tv); + +/** + * This method performs alarm driver processing. + * + */ +void PlatformAlarmProcess(void); /** * This method initializes the radio service used by OpenThread. * */ -void hwRadioInit(void); +void PlatformRadioInit(void); + +/** + * This method updates the file descriptor sets with file descriptors used by the radio driver. + * + * @param[inout] aReadFdSet A pointer to the read file descriptors. + * @param[inout] aWriteFdSet A pointer to the write file descriptors. + * @param[inout] aMaxFd A pointer to the max file descriptor. + * + */ +void PlatformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMaxFd); + +/** + * This method performs radio driver processing. + * + */ +void PlatformRadioProcess(void); /** * This method initializes the random number service used by OpenThread. * */ -void hwRandomInit(void); +void PlatformRandomInit(void); + +/** + * This method updates the file descriptor sets with file descriptors used by the serial driver. + * + * @param[inout] aReadFdSet A pointer to the read file descriptors. + * @param[inout] aWriteFdSet A pointer to the write file descriptors. + * @param[inout] aMaxFd A pointer to the max file descriptor. + * + */ +void PlatformSerialUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMaxFd); + +/** + * This method performs radio driver processing. + * + */ +void PlatformSerialProcess(void); /** * This method puts the thread executing OpenThread to sleep. * */ -void hwSleep(void); +void PlatformSleep(void); #ifdef __cplusplus } // extern "C" diff --git a/examples/platform/posix/radio.cpp b/examples/platform/posix/radio.cpp index 785d539c6..23bcac9b0 100644 --- a/examples/platform/posix/radio.cpp +++ b/examples/platform/posix/radio.cpp @@ -28,8 +28,8 @@ #include #include -#include #include +#include #include #include #include @@ -70,7 +70,8 @@ struct RadioMessage uint8_t mPsdu[Mac::Frame::kMTU]; } __attribute__((packed)); -static void *phy_receive_thread(void *arg); +static void radioSendAck(void); +static void radioProcessFrame(void); static PhyState s_state = kStateDisabled; static RadioPacket *s_receive_frame = NULL; @@ -82,9 +83,6 @@ static uint8_t s_extended_address[8]; static uint16_t s_short_address; static uint16_t s_panid; -static pthread_t s_pthread; -static pthread_mutex_t s_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t s_condition_variable = PTHREAD_COND_INITIALIZER; static int s_sockfd; ThreadError otPlatRadioSetPanId(uint16_t panid) @@ -109,7 +107,7 @@ ThreadError otPlatRadioSetShortAddress(uint16_t address) return kThreadError_None; } -void hwRadioInit() +void PlatformRadioInit(void) { struct sockaddr_in sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); @@ -119,58 +117,44 @@ void hwRadioInit() s_sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); bind(s_sockfd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); - - pthread_create(&s_pthread, NULL, &phy_receive_thread, NULL); } -ThreadError otPlatRadioEnable() +ThreadError otPlatRadioEnable(void) { ThreadError error = kThreadError_None; - pthread_mutex_lock(&s_mutex); VerifyOrExit(s_state == kStateDisabled, error = kThreadError_Busy); s_state = kStateSleep; - pthread_cond_signal(&s_condition_variable); exit: - pthread_mutex_unlock(&s_mutex); return error; } -ThreadError otPlatRadioDisable() +ThreadError otPlatRadioDisable(void) { - pthread_mutex_lock(&s_mutex); s_state = kStateDisabled; - pthread_cond_signal(&s_condition_variable); - pthread_mutex_unlock(&s_mutex); return kThreadError_None; } -ThreadError otPlatRadioSleep() +ThreadError otPlatRadioSleep(void) { ThreadError error = kThreadError_None; - pthread_mutex_lock(&s_mutex); VerifyOrExit(s_state == kStateIdle, error = kThreadError_Busy); s_state = kStateSleep; - pthread_cond_signal(&s_condition_variable); exit: - pthread_mutex_unlock(&s_mutex); return error; } -ThreadError otPlatRadioIdle() +ThreadError otPlatRadioIdle(void) { ThreadError error = kThreadError_None; - pthread_mutex_lock(&s_mutex); - switch (s_state) { case kStateSleep: s_state = kStateIdle; - pthread_cond_signal(&s_condition_variable); break; case kStateIdle: @@ -180,7 +164,6 @@ ThreadError otPlatRadioIdle() case kStateTransmit: case kStateAckWait: s_state = kStateIdle; - pthread_cond_signal(&s_condition_variable); break; case kStateDisabled: @@ -189,7 +172,6 @@ ThreadError otPlatRadioIdle() } exit: - pthread_mutex_unlock(&s_mutex); return error; } @@ -197,32 +179,135 @@ ThreadError otPlatRadioReceive(RadioPacket *packet) { ThreadError error = kThreadError_None; - pthread_mutex_lock(&s_mutex); VerifyOrExit(s_state == kStateIdle, error = kThreadError_Busy); s_state = kStateListen; - pthread_cond_signal(&s_condition_variable); - s_receive_frame = packet; exit: - pthread_mutex_unlock(&s_mutex); return error; } ThreadError otPlatRadioTransmit(RadioPacket *packet) { ThreadError error = kThreadError_None; - struct sockaddr_in sockaddr; - RadioMessage message; - pthread_mutex_lock(&s_mutex); VerifyOrExit(s_state == kStateIdle, error = kThreadError_Busy); s_state = kStateTransmit; - pthread_cond_signal(&s_condition_variable); - s_transmit_frame = packet; s_data_pending = false; +exit: + return error; +} + +int8_t otPlatRadioGetNoiseFloor(void) +{ + return 0; +} + +otRadioCaps otPlatRadioGetCaps(void) +{ + return kRadioCapsNone; +} + +ThreadError otPlatRadioHandleTransmitDone(bool *rxPending) +{ + ThreadError error = kThreadError_None; + + VerifyOrExit(s_state == kStateTransmit || s_state == kStateAckWait, error = kThreadError_InvalidState); + + s_state = kStateIdle; + + if (rxPending != NULL) + { + *rxPending = s_data_pending; + } + +exit: + return error; +} + +void radioReceive(void) +{ + RadioPacket receive_frame; + RadioMessage message; + uint8_t tx_sequence, rx_sequence; + uint8_t command_id; + int rval; + + VerifyOrExit(s_state == kStateDisabled || s_state == kStateSleep || s_state == kStateListen || + s_state == kStateAckWait, ;); + + rval = recvfrom(s_sockfd, &message, sizeof(message), 0, NULL, NULL); + assert(rval >= 0); + + switch (s_state) + { + case kStateDisabled: + case kStateSleep: + case kStateIdle: + case kStateTransmit: + break; + + case kStateAckWait: + receive_frame.mLength = rval - 1; + memcpy(receive_frame.mPsdu, message.mPsdu, receive_frame.mLength); + + if (reinterpret_cast(&receive_frame)->GetType() != Mac::Frame::kFcfFrameAck) + { + break; + } + + tx_sequence = reinterpret_cast(s_transmit_frame)->GetSequence(); + rx_sequence = reinterpret_cast(&receive_frame)->GetSequence(); + + if (tx_sequence != rx_sequence) + { + break; + } + + if (reinterpret_cast(s_transmit_frame)->GetType() == Mac::Frame::kFcfFrameMacCmd) + { + reinterpret_cast(s_transmit_frame)->GetCommandId(command_id); + + if (command_id == Mac::Frame::kMacCmdDataRequest) + { + s_data_pending = true; + } + } + + s_state = kStateIdle; + otPlatRadioTransmitDone(s_data_pending, kThreadError_None); + break; + + case kStateListen: + if (s_receive_frame->mChannel != message.mChannel) + { + break; + } + + s_state = kStateReceive; + s_receive_frame->mLength = rval - 1; + memcpy(s_receive_frame->mPsdu, message.mPsdu, s_receive_frame->mLength); + + radioProcessFrame(); + break; + + case kStateReceive: + assert(false); + break; + } + +exit: + return; +} + +int radioTransmit(void) +{ + struct sockaddr_in sockaddr; + RadioMessage message; + int rval; + memset(&sockaddr, 0, sizeof(sockaddr)); sockaddr.sin_family = AF_INET; inet_pton(AF_INET, "127.0.0.1", &sockaddr.sin_addr); @@ -238,7 +323,9 @@ ThreadError otPlatRadioTransmit(RadioPacket *packet) } sockaddr.sin_port = htons(9000 + i); - sendto(s_sockfd, &message, 1 + s_transmit_frame->mLength, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); + rval = sendto(s_sockfd, &message, 1 + s_transmit_frame->mLength, 0, (struct sockaddr *)&sockaddr, + sizeof(sockaddr)); + assert(rval >= 0); } if (reinterpret_cast(s_transmit_frame)->GetAckRequest()) @@ -247,154 +334,56 @@ ThreadError otPlatRadioTransmit(RadioPacket *packet) } else { - otPlatRadioSignalTransmitDone(); + s_state = kStateIdle; + otPlatRadioTransmitDone(false, kThreadError_None); } -exit: - pthread_mutex_unlock(&s_mutex); - return error; + return rval; } -int8_t otPlatRadioGetNoiseFloor() +void PlatformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMaxFd) { + if (aReadFdSet != NULL && + (s_state == kStateDisabled || s_state == kStateSleep || s_state == kStateListen || s_state == kStateAckWait)) + { + FD_SET(s_sockfd, aReadFdSet); + + if (aMaxFd != NULL && *aMaxFd < s_sockfd) + { + *aMaxFd = s_sockfd; + } + } + + if (aWriteFdSet != NULL && s_state == kStateTransmit) + { + FD_SET(s_sockfd, aWriteFdSet); + + if (aMaxFd != NULL && *aMaxFd < s_sockfd) + { + *aMaxFd = s_sockfd; + } + } +} + +int PlatformRadioProcess(void) +{ + const int flags = POLLRDNORM | POLLERR | POLLNVAL | POLLHUP; + struct pollfd pollfd = { s_sockfd, flags, 0 }; + + if (poll(&pollfd, 1, 0) > 0 && (pollfd.revents & flags) != 0) + { + radioReceive(); + } + + if (s_state == kStateTransmit) + { + radioTransmit(); + } + return 0; } -otRadioCaps otPlatRadioGetCaps() -{ - return kRadioCapsNone; -} - -ThreadError otPlatRadioHandleTransmitDone(bool *rxPending) -{ - ThreadError error = kThreadError_None; - - VerifyOrExit(s_state == kStateTransmit || s_state == kStateAckWait, error = kThreadError_InvalidState); - - pthread_mutex_lock(&s_mutex); - s_state = kStateIdle; - pthread_cond_signal(&s_condition_variable); - pthread_mutex_unlock(&s_mutex); - - if (rxPending != NULL) - { - *rxPending = s_data_pending; - } - -exit: - return error; -} - -void *phy_receive_thread(void *arg) -{ - fd_set fds; - int rval; - RadioPacket receive_frame; - int length; - uint8_t tx_sequence, rx_sequence; - uint8_t command_id; - RadioMessage message; - - while (1) - { - FD_ZERO(&fds); - FD_SET(s_sockfd, &fds); - - rval = select(s_sockfd + 1, &fds, NULL, NULL, NULL); - - if (rval < 0 || !FD_ISSET(s_sockfd, &fds)) - { - continue; - } - - pthread_mutex_lock(&s_mutex); - - while (s_state == kStateIdle || s_state == kStateTransmit) - { - pthread_cond_wait(&s_condition_variable, &s_mutex); - } - - switch (s_state) - { - case kStateDisabled: - case kStateIdle: - case kStateSleep: - recvfrom(s_sockfd, NULL, 0, 0, NULL, NULL); - break; - - case kStateTransmit: - break; - - case kStateAckWait: - length = recvfrom(s_sockfd, &message, sizeof(message), 0, NULL, NULL); - receive_frame.mLength = length - 1; - memcpy(receive_frame.mPsdu, message.mPsdu, receive_frame.mLength); - - if (length < 0) - { - assert(false); - } - - if (reinterpret_cast(&receive_frame)->GetType() != Mac::Frame::kFcfFrameAck) - { - break; - } - - tx_sequence = reinterpret_cast(s_transmit_frame)->GetSequence(); - - rx_sequence = reinterpret_cast(&receive_frame)->GetSequence(); - - if (tx_sequence != rx_sequence) - { - break; - } - - if (reinterpret_cast(s_transmit_frame)->GetType() == Mac::Frame::kFcfFrameMacCmd) - { - reinterpret_cast(s_transmit_frame)->GetCommandId(command_id); - - if (command_id == Mac::Frame::kMacCmdDataRequest) - { - s_data_pending = true; - } - } - - otPlatRadioSignalTransmitDone(); - break; - - case kStateListen: - length = recvfrom(s_sockfd, &message, sizeof(message), 0, NULL, NULL); - - if (s_receive_frame->mChannel != message.mChannel) - { - break; - } - - s_state = kStateReceive; - s_receive_frame->mLength = length - 1; - memcpy(s_receive_frame->mPsdu, message.mPsdu, s_receive_frame->mLength); - - otPlatRadioSignalReceiveDone(); - - while (s_state == kStateReceive) - { - pthread_cond_wait(&s_condition_variable, &s_mutex); - } - - break; - - case kStateReceive: - assert(false); - break; - } - - pthread_mutex_unlock(&s_mutex); - } - - return NULL; -} - -void send_ack() +void radioSendAck(void) { Mac::Frame *ack_frame; RadioMessage message; @@ -426,17 +415,14 @@ void send_ack() } } -ThreadError otPlatRadioHandleReceiveDone() +void radioProcessFrame(void) { ThreadError error = kThreadError_None; Mac::Frame *receive_frame; uint16_t dstpan; Mac::Address dstaddr; - VerifyOrExit(s_state == kStateReceive, error = kThreadError_InvalidState); - receive_frame = reinterpret_cast(s_receive_frame); - receive_frame->GetDstAddr(dstaddr); switch (dstaddr.mLength) @@ -468,21 +454,17 @@ ThreadError otPlatRadioHandleReceiveDone() // generate acknowledgment if (reinterpret_cast(s_receive_frame)->GetAckRequest()) { - send_ack(); + radioSendAck(); } exit: - pthread_mutex_lock(&s_mutex); if (s_state != kStateDisabled) { s_state = kStateIdle; } - pthread_cond_signal(&s_condition_variable); - pthread_mutex_unlock(&s_mutex); - - return error; + otPlatRadioReceiveDone(error); } #ifdef __cplusplus diff --git a/examples/platform/posix/random.c b/examples/platform/posix/random.c index 39fe362e1..efae3b3b8 100644 --- a/examples/platform/posix/random.c +++ b/examples/platform/posix/random.c @@ -41,7 +41,7 @@ extern struct gengetopt_args_info args_info; static uint32_t s_state = 1; -void hwRandomInit(void) +void PlatformRandomInit(void) { s_state = args_info.nodeid_arg; } diff --git a/examples/platform/posix/serial.c b/examples/platform/posix/serial.c index af5f48b63..bea8312da 100644 --- a/examples/platform/posix/serial.c +++ b/examples/platform/posix/serial.c @@ -26,9 +26,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include #include -#include -#include +#include #include #include #include @@ -37,8 +37,6 @@ #include #include -static void *serial_receive_thread(void *arg); - #ifdef OPENTHREAD_TARGET_LINUX int posix_openpt(int oflag); int grantpt(int fildes); @@ -49,20 +47,20 @@ char *ptsname(int fd); extern struct gengetopt_args_info args_info; static uint8_t s_receive_buffer[128]; +static const uint8_t *s_write_buffer; +static uint16_t s_write_length; static int s_in_fd; static int s_out_fd; -static pthread_t s_pthread; -static sem_t *s_semaphore; static struct termios original_stdin_termios; static struct termios original_stdout_termios; -static void restore_stdin_termios() +static void restore_stdin_termios(void) { tcsetattr(s_in_fd, TCSAFLUSH, &original_stdin_termios); } -static void restore_stdout_termios() +static void restore_stdout_termios(void) { tcsetattr(s_out_fd, TCSAFLUSH, &original_stdout_termios); } @@ -72,7 +70,6 @@ ThreadError otPlatSerialEnable(void) ThreadError error = kThreadError_None; struct termios termios; char *path; - char cmd[256]; if (args_info.stdserial_given == 1) { @@ -171,10 +168,6 @@ ThreadError otPlatSerialEnable(void) VerifyOrExit(tcsetattr(s_out_fd, TCSANOW, &termios) == 0, perror("tcsetattr"); error = kThreadError_Error); } - snprintf(cmd, sizeof(cmd), "thread_serial_semaphore_%d", args_info.nodeid_arg); - s_semaphore = sem_open(cmd, O_CREAT, 0644, 0); - pthread_create(&s_pthread, NULL, &serial_receive_thread, NULL); - return error; exit: @@ -197,54 +190,56 @@ ThreadError otPlatSerialSend(const uint8_t *aBuf, uint16_t aBufLength) { ThreadError error = kThreadError_None; - VerifyOrExit(write(s_out_fd, aBuf, aBufLength) >= 0, error = kThreadError_Error); - otPlatSerialSignalSendDone(); + VerifyOrExit(s_write_length == 0, error = kThreadError_Busy); + + s_write_buffer = aBuf; + s_write_length = aBufLength; exit: return error; } -void otPlatSerialHandleSendDone(void) +void PlatformSerialUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMaxFd) { -} - -void *serial_receive_thread(void *aContext) -{ - fd_set fds; - int rval; - - while (1) + if (aReadFdSet != NULL) { - FD_ZERO(&fds); - FD_SET(s_in_fd, &fds); + FD_SET(s_in_fd, aReadFdSet); - rval = select(s_in_fd + 1, &fds, NULL, NULL, NULL); - - if (rval >= 0 && FD_ISSET(s_in_fd, &fds)) + if (aMaxFd != NULL && *aMaxFd < s_in_fd) { - otPlatSerialSignalReceive(); - sem_wait(s_semaphore); + *aMaxFd = s_in_fd; } } - return NULL; + if (aWriteFdSet != NULL && s_write_length > 0) + { + FD_SET(s_out_fd, aWriteFdSet); + + if (aMaxFd != NULL && *aMaxFd < s_out_fd) + { + *aMaxFd = s_out_fd; + } + } } -const uint8_t *otPlatSerialGetReceivedBytes(uint16_t *aBufLength) +void PlatformSerialProcess(void) { - size_t length; + const int flags = POLLRDNORM | POLLERR | POLLNVAL | POLLHUP; + struct pollfd pollfd = { s_in_fd, flags, 0 }; + int rval; - length = read(s_in_fd, s_receive_buffer, sizeof(s_receive_buffer)); - - if (aBufLength != NULL) + if (poll(&pollfd, 1, 0) > 0 && (pollfd.revents & flags) != 0) { - *aBufLength = length; + rval = read(s_in_fd, s_receive_buffer, sizeof(s_receive_buffer)); + assert(rval >= 0); + otPlatSerialReceived(s_receive_buffer, rval); } - return s_receive_buffer; -} - -void otPlatSerialHandleReceiveDone(void) -{ - sem_post(s_semaphore); + if (s_write_length > 0) + { + rval = write(s_out_fd, s_write_buffer, s_write_length); + assert(rval >= 0); + s_write_length = 0; + otPlatSerialSendDone(); + } } diff --git a/include/platform/Makefile.am b/include/platform/Makefile.am index bccd6efb9..f848009b2 100644 --- a/include/platform/Makefile.am +++ b/include/platform/Makefile.am @@ -29,7 +29,6 @@ include $(abs_top_nlbuild_autotools_dir)/automake/pre.am include_HEADERS = \ - atomic.h \ alarm.h \ logging.h \ radio.h \ diff --git a/include/platform/alarm.h b/include/platform/alarm.h index bb57adff7..8693f7b0f 100644 --- a/include/platform/alarm.h +++ b/include/platform/alarm.h @@ -71,7 +71,7 @@ void otPlatAlarmStartAt(uint32_t aT0, uint32_t aDt); void otPlatAlarmStop(void); /** - * Get the current current time. + * Get the current time. * * @returns The current time in milliseconds. */ @@ -80,7 +80,7 @@ uint32_t otPlatAlarmGetNow(void); /** * Signal that the alarm has fired. */ -extern void otPlatAlarmSignalFired(void); +extern void otPlatAlarmFired(void); /** * @} diff --git a/include/platform/radio.h b/include/platform/radio.h index fe6dbaee7..a4e9fc7c6 100644 --- a/include/platform/radio.h +++ b/include/platform/radio.h @@ -208,9 +208,6 @@ ThreadError otPlatRadioIdle(void); * 2. Remain in Receive until a packet is received or reception is aborted. * 3. Return to Idle. * - * Upon completion of the receive sequence, otPlatRadioSignalReceiveDone() is called to signal completion to the MAC - * layer. - * * @param[in] aPacket A pointer to a packet buffer. * * @note The channel is specified in @p aPacket. @@ -221,21 +218,13 @@ ThreadError otPlatRadioIdle(void); ThreadError otPlatRadioReceive(RadioPacket *aPacket); /** - * Signal that a packet has been received. + * The radio driver calls this method to notify OpenThread of a received packet. * - * This may be called from interrupt context. The MAC layer will then schedule a call to otPlatRadioHandleReceive(). - */ - -extern void otPlatRadioSignalReceiveDone(void); - -/** - * Complete the receive sequence. + * @param[in] aError ::kThreadError_None when successfully received a frame, ::kThreadError_Abort when reception + * was aborted and a frame was not received. * - * @retval ::kThreadError_None Successfully received a frame. - * @retval ::kThreadError_Abort Reception was aborted and a frame was not received. - * @retval ::kThreadError_InvalidState The radio was not in Receive. */ -ThreadError otPlatRadioHandleReceiveDone(void); +extern void otPlatRadioReceiveDone(ThreadError error); /** * Begins the transmit sequence on the radio. @@ -245,9 +234,6 @@ ThreadError otPlatRadioHandleReceiveDone(void); * 2. Transmits the psdu on the given channel and at the given transmit power. * 3. Return to Idle. * - * Upon completion of the transmit sequence, otPlatRadioSignalTransmitDone() is called to signal completion to the MAC - * layer. - * * @param[in] aPacket A pointer to a packet buffer. * * @note The channel is specified in @p aPacket. @@ -260,25 +246,16 @@ ThreadError otPlatRadioHandleReceiveDone(void); ThreadError otPlatRadioTransmit(RadioPacket *aPacket); /** - * Signal that the requested transmission is complete. + * The radio driver calls this method to notify OpenThread that the transmission has completed. + * + * @param[in] aFramePending TRUE if an ACK frame was received and the Frame Pending bit was set. + * @param[in] aError ::kThreadError_None when the frame was transmitted, ::kThreadError_NoAck when the frame was + * transmitted but no ACK was received, ::kThreadError_ChannelAccessFailure when the transmission + * could not take place due to activity on the channel, ::kThreadError_Abort when transmission was + * aborted for other reasons. * - * This may be called from interrupt context. OpenThread will then schedule a call to - * otPlatRadio_handle_transmit_done(). */ -extern void otPlatRadioSignalTransmitDone(void); - -/** - * Complete the transmit sequence on the radio. - * - * @param[out] aFramePending TRUE if an ACK frame was received and the Frame Pending bit was set. - * - * @retval ::kThreadError_None The frame was transmitted. - * @retval ::kThreadError_NoAck The frame was transmitted, but no ACK was received. - * @retval ::kThreadError_CcaFailed The transmission was aborted due to CCA failure. - * @retval ::kThreadError_Abort The transmission was aborted for other reasons. - * @retval ::kThreadError_InvalidState The radio did not transmit a packet. - */ -ThreadError otPlatRadioHandleTransmitDone(bool *aFramePending); +extern void otPlatRadioTransmitDone(bool aFramePending, ThreadError error); /** * Get the most recent RSSI measurement. diff --git a/include/platform/serial.h b/include/platform/serial.h index e7e03085d..510a46ef0 100644 --- a/include/platform/serial.h +++ b/include/platform/serial.h @@ -82,38 +82,19 @@ ThreadError otPlatSerialDisable(void); ThreadError otPlatSerialSend(const uint8_t *aBuf, uint16_t aBufLength); /** - * Signal that the bytes send operation has completed. + * The serial driver calls this method to notify OpenThread that the requested bytes have been sent. * - * This may be called from interrupt context. This will schedule calls to otPlatSerialHandleSendDone(). */ -extern void otPlatSerialSignalSendDone(void); +extern void otPlatSerialSendDone(void); /** - * Complete the send sequence. - */ -void otPlatSerialHandleSendDone(void); - -/** - * Signal that bytes have been received. + * The serial driver calls this method to notify OpenThread that bytes have been received. * - * This may be called from interrupt context. This will schedule calls to otPlatSerialGetReceivedBytes() and - * otPlatSerialHandleReceiveDone(). - */ -extern void otPlatSerialSignalReceive(void); - -/** - * Get a pointer to the received bytes. + * @param[in] aBuf A pointer to the received bytes. + * @param[in] aBufLength The number of bytes received. * - * @param[out] aBufLength A pointer to a variable that this function will put the number of bytes received. - * - * @returns A pointer to the received bytes. NULL, if there are no received bytes to process. */ -const uint8_t *otPlatSerialGetReceivedBytes(uint16_t *aBufLength); - -/** - * Release received bytes. - */ -void otPlatSerialHandleReceiveDone(void); +extern void otPlatSerialReceived(const uint8_t *aBuf, uint16_t aBufLength); /** * @} diff --git a/src/cli/cli_serial.cpp b/src/cli/cli_serial.cpp index 9ecb65bc8..3812d4f78 100644 --- a/src/cli/cli_serial.cpp +++ b/src/cli/cli_serial.cpp @@ -50,9 +50,6 @@ static const char sEraseString[] = {'\b', ' ', '\b'}; static const char CRNL[] = {'\r', '\n'}; static Serial *sServer; -Tasklet Serial::sReceiveTask(&ReceiveTask, NULL); -Tasklet Serial::sSendDoneTask(&SendDoneTask, NULL); - Serial::Serial(void) { sServer = this; @@ -68,28 +65,20 @@ ThreadError Serial::Start(void) return kThreadError_None; } -extern "C" void otPlatSerialSignalReceive(void) +extern "C" void otPlatSerialReceived(const uint8_t *aBuf, uint16_t aBufLength) { - Serial::sReceiveTask.Post(); + sServer->ReceiveTask(aBuf, aBufLength); } -void Serial::ReceiveTask(void *aContext) +void Serial::ReceiveTask(const uint8_t *aBuf, uint16_t aBufLength) { - sServer->ReceiveTask(); -} - -void Serial::ReceiveTask(void) -{ - uint16_t bufLength; - const uint8_t *buf; const uint8_t *end; - buf = otPlatSerialGetReceivedBytes(&bufLength); - end = buf + bufLength; + end = aBuf + aBufLength; - for (; buf < end; buf++) + for (; aBuf < end; aBuf++) { - switch (*buf) + switch (*aBuf) { case '\r': case '\n': @@ -115,13 +104,11 @@ void Serial::ReceiveTask(void) break; default: - Output(reinterpret_cast(buf), 1); - mRxBuffer[mRxLength++] = *buf; + Output(reinterpret_cast(aBuf), 1); + mRxBuffer[mRxLength++] = *aBuf; break; } } - - otPlatSerialHandleReceiveDone(); } ThreadError Serial::ProcessCommand(void) @@ -201,12 +188,7 @@ exit: return; } -extern "C" void otPlatSerialSignalSendDone(void) -{ - Serial::sSendDoneTask.Post(); -} - -void Serial::SendDoneTask(void *aContext) +extern "C" void otPlatSerialSendDone(void) { sServer->SendDoneTask(); } diff --git a/src/cli/cli_serial.hpp b/src/cli/cli_serial.hpp index 68f6a5d92..fc6aeecd5 100644 --- a/src/cli/cli_serial.hpp +++ b/src/cli/cli_serial.hpp @@ -80,8 +80,8 @@ public: */ int OutputFormat(const char *fmt, ...); - static Tasklet sReceiveTask; - static Tasklet sSendDoneTask; + void ReceiveTask(const uint8_t *aBuf, uint16_t aBufLength); + void SendDoneTask(void); private: enum @@ -91,12 +91,7 @@ private: kMaxLineLength = 128, }; - static void ReceiveTask(void *aContext); - static void SendDoneTask(void *aContext); - ThreadError ProcessCommand(void); - void ReceiveTask(void); - void SendDoneTask(void); void Send(void); char mRxBuffer[kRxBufferSize]; diff --git a/src/cli/cli_udp.hpp b/src/cli/cli_udp.hpp index 4dd994203..beb4cb67a 100644 --- a/src/cli/cli_udp.hpp +++ b/src/cli/cli_udp.hpp @@ -80,7 +80,7 @@ public: private: enum { - kMaxLineLength = 80, + kMaxLineLength = 128, }; static void HandleUdpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo); diff --git a/src/core/common/tasklet.cpp b/src/core/common/tasklet.cpp index 0f47458c5..b46ef2841 100644 --- a/src/core/common/tasklet.cpp +++ b/src/core/common/tasklet.cpp @@ -35,7 +35,6 @@ #include #include #include -#include namespace Thread { @@ -57,7 +56,6 @@ ThreadError Tasklet::Post(void) ThreadError TaskletScheduler::Post(Tasklet &aTasklet) { ThreadError error = kThreadError_None; - uint32_t state = otPlatAtomicBegin(); VerifyOrExit(sTail != &aTasklet && aTasklet.mNext == NULL, error = kThreadError_Busy); @@ -74,8 +72,6 @@ ThreadError TaskletScheduler::Post(Tasklet &aTasklet) } exit: - otPlatAtomicEnd(state); - return error; } @@ -105,12 +101,9 @@ bool TaskletScheduler::AreTaskletsPending(void) void TaskletScheduler::RunNextTasklet(void) { - uint32_t state; Tasklet *task; - state = otPlatAtomicBegin(); task = PopTasklet(); - otPlatAtomicEnd(state); if (task != NULL) { diff --git a/src/core/common/timer.cpp b/src/core/common/timer.cpp index 2fbce718e..bd7e46d14 100644 --- a/src/core/common/timer.cpp +++ b/src/core/common/timer.cpp @@ -37,7 +37,6 @@ namespace Thread { -static Tasklet sTask(&TimerScheduler::FireTimers, NULL); static Timer *sHead = NULL; static Timer *sTail = NULL; @@ -144,25 +143,18 @@ void TimerScheduler::SetAlarm(void) } } - if (minRemaining <= 0) - { - sTask.Post(); - } - else - { - otPlatAlarmStartAt(now, minRemaining); - } + otPlatAlarmStartAt(now, minRemaining); exit: {} } -extern "C" void otPlatAlarmSignalFired(void) +extern "C" void otPlatAlarmFired(void) { - Thread::sTask.Post(); + TimerScheduler::FireTimers(); } -void TimerScheduler::FireTimers(void *aContext) +void TimerScheduler::FireTimers(void) { uint32_t now = otPlatAlarmGetNow(); uint32_t elapsed; diff --git a/src/core/common/timer.hpp b/src/core/common/timer.hpp index 8c0226a1f..737d2a235 100644 --- a/src/core/common/timer.hpp +++ b/src/core/common/timer.hpp @@ -95,7 +95,7 @@ public: * @param[in] aContext A pointer to arbitrary context information. * */ - static void FireTimers(void *aContext); + static void FireTimers(void); private: static void SetAlarm(void); diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index cb278e663..d89163522 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -50,9 +50,6 @@ static const uint8_t sExtendedPanidInit[] = {0xde, 0xad, 0x00, 0xbe, 0xef, 0x00, static const char sNetworkNameInit[] = "OpenThread"; static Mac *sMac; -static Tasklet sReceiveDoneTask(&Mac::ReceiveDoneTask, NULL); -static Tasklet sTransmitDoneTask(&Mac::TransmitDoneTask, NULL); - void Mac::StartCsmaBackoff(void) { uint32_t backoffExponent = kMinBE + mTransmitAttempts + mCsmaAttempts; @@ -63,8 +60,8 @@ void Mac::StartCsmaBackoff(void) backoffExponent = kMaxBE; } - backoff = (kUnitBackoffPeriod * kPhyUsPerSymbol * (1 << backoffExponent)) / 1000; - backoff = (otPlatRandomGet() % backoff) + kMinBackoff; + backoff = kMinBackoff + (kUnitBackoffPeriod * kPhyUsPerSymbol * (1 << backoffExponent)) / 1000; + backoff = (otPlatRandomGet() % backoff); mBackoffTimer.Start(backoff); } @@ -481,26 +478,16 @@ exit: } } -extern "C" void otPlatRadioSignalTransmitDone(void) +extern "C" void otPlatRadioTransmitDone(bool aRxPending, ThreadError aError) { - sTransmitDoneTask.Post(); + sMac->TransmitDoneTask(aRxPending, aError); } -void Mac::TransmitDoneTask(void *aContext) +void Mac::TransmitDoneTask(bool aRxPending, ThreadError aError) { - sMac->TransmitDoneTask(); -} - -void Mac::TransmitDoneTask(void) -{ - ThreadError error; - bool rxPending; - - error = otPlatRadioHandleTransmitDone(&rxPending); - mAckTimer.Stop(); - if (error == kThreadError_ChannelAccessFailure && + if (aError == kThreadError_ChannelAccessFailure && mCsmaAttempts < kMaxCSMABackoffs) { mCsmaAttempts++; @@ -521,7 +508,7 @@ void Mac::TransmitDoneTask(void) break; case kStateTransmitData: - if (rxPending) + if (aRxPending) { mReceiveTimer.Start(kDataPollTimeout); } @@ -530,7 +517,7 @@ void Mac::TransmitDoneTask(void) mReceiveTimer.Stop(); } - SentFrame(error == kThreadError_None); + SentFrame(aError == kThreadError_None); break; default: @@ -752,19 +739,13 @@ exit: return error; } -extern "C" void otPlatRadioSignalReceiveDone(void) +extern "C" void otPlatRadioReceiveDone(ThreadError aError) { - sReceiveDoneTask.Post(); + sMac->ReceiveDoneTask(aError); } -void Mac::ReceiveDoneTask(void *aContext) +void Mac::ReceiveDoneTask(ThreadError aError) { - sMac->ReceiveDoneTask(); -} - -void Mac::ReceiveDoneTask(void) -{ - ThreadError error; Address srcaddr; Address dstaddr; PanId panid; @@ -772,8 +753,7 @@ void Mac::ReceiveDoneTask(void) Whitelist::Entry *entry; int8_t rssi; - error = otPlatRadioHandleReceiveDone(); - VerifyOrExit(error == kThreadError_None, ;); + VerifyOrExit(aError == kThreadError_None, ;); mReceiveFrame.GetSrcAddr(srcaddr); neighbor = mMle.GetNeighbor(srcaddr); diff --git a/src/core/mac/mac.hpp b/src/core/mac/mac.hpp index d3f6dbd35..105da48c2 100644 --- a/src/core/mac/mac.hpp +++ b/src/core/mac/mac.hpp @@ -366,18 +366,23 @@ public: /** * This method is called to handle receive events. * - * @param[in] aContext A pointer to arbitrary context information. + * @param[in] aError ::kThreadError_None when successfully received a frame, ::kThreadError_Abort when reception + * was aborted and a frame was not received. * */ - static void ReceiveDoneTask(void *aContext); + void ReceiveDoneTask(ThreadError aError); /** * This method is called to handle transmit events. * - * @param[in] aContext A pointer to arbitrary context information. + * @param[in] aFramePending TRUE if an ACK frame was received and the Frame Pending bit was set. + * @param[in] aError ::kThreadError_None when the frame was transmitted, ::kThreadError_NoAck when the frame was + * transmitted but no ACK was received, ::kThreadError_ChannelAccessFailure when the transmission + * could not take place due to activity on the channel, ::kThreadError_Abort when transmission + * was aborted for other reasons. * */ - static void TransmitDoneTask(void *aContext); + void TransmitDoneTask(bool aRxPending, ThreadError aError); /** * This method returns if an active scan is in progress. @@ -406,9 +411,6 @@ private: void StartCsmaBackoff(void); - void ReceiveDoneTask(void); - void TransmitDoneTask(void); - Tasklet mBeginTransmit; Timer mAckTimer; Timer mBackoffTimer; diff --git a/src/ncp/ncp.cpp b/src/ncp/ncp.cpp index f89d01767..8bebb72b0 100644 --- a/src/ncp/ncp.cpp +++ b/src/ncp/ncp.cpp @@ -36,8 +36,6 @@ namespace Thread { -static Tasklet sSendDoneTask(&Ncp::SendDoneTask, NULL); -static Tasklet sReceiveTask(&Ncp::ReceiveTask, NULL); static Ncp *sNcp; Ncp::Ncp(): @@ -146,17 +144,12 @@ Ncp::OutboundFrameSend(void) return errorCode; } -extern "C" void otPlatSerialSignalSendDone() -{ - sSendDoneTask.Post(); -} - -void Ncp::SendDoneTask(void *context) +extern "C" void otPlatSerialSendDone(void) { sNcp->SendDoneTask(); } -void Ncp::SendDoneTask() +void Ncp::SendDoneTask(void) { mSending = false; @@ -169,26 +162,14 @@ void Ncp::SendDoneTask() super_t::HandleSendDone(); } -extern "C" void otPlatSerialSignalReceive() +extern "C" void otPlatSerialReceived(const uint8_t *aBuf, uint16_t aBufLength) { - sReceiveTask.Post(); + sNcp->ReceiveTask(aBuf, aBufLength); } -void Ncp::ReceiveTask(void *context) +void Ncp::ReceiveTask(const uint8_t *aBuf, uint16_t aBufLength) { - sNcp->ReceiveTask(); -} - -void Ncp::ReceiveTask() -{ - const uint8_t *buf; - uint16_t bufLength; - - buf = otPlatSerialGetReceivedBytes(&bufLength); - - mFrameDecoder.Decode(buf, bufLength); - - otPlatSerialHandleReceiveDone(); + mFrameDecoder.Decode(aBuf, aBufLength); } void Ncp::HandleFrame(void *context, uint8_t *aBuf, uint16_t aBufLength) diff --git a/src/ncp/ncp.hpp b/src/ncp/ncp.hpp index d995ede13..8053a8001 100644 --- a/src/ncp/ncp.hpp +++ b/src/ncp/ncp.hpp @@ -57,13 +57,11 @@ public: virtual ThreadError OutboundFrameSend(void); static void HandleFrame(void *context, uint8_t *aBuf, uint16_t aBufLength); - static void SendDoneTask(void *context); - static void ReceiveTask(void *context); + void SendDoneTask(void); + void ReceiveTask(const uint8_t *aBuf, uint16_t aBufLength); private: void HandleFrame(uint8_t *aBuf, uint16_t aBufLength); - void SendDoneTask(); - void ReceiveTask(); Hdlc::Encoder mFrameEncoder; Hdlc::Decoder mFrameDecoder;