From 266d47649d682d4434a8a1b000052ed7ff56c2d6 Mon Sep 17 00:00:00 2001 From: ayer1 Date: Fri, 4 Sep 2009 18:02:02 +0000 Subject: [PATCH] bringing port of up-to-date bluetooth interface and implementation to tos-2.x --- .../shimmer/chips/bluetooth/Bluetooth.nc | 96 ++++ .../shimmer/chips/bluetooth/RovingNetworks.h | 32 ++ .../chips/bluetooth/RovingNetworksC.nc | 70 +++ .../chips/bluetooth/RovingNetworksP.nc | 521 ++++++++++++++++++ 4 files changed, 719 insertions(+) create mode 100644 tos/platforms/shimmer/chips/bluetooth/Bluetooth.nc create mode 100644 tos/platforms/shimmer/chips/bluetooth/RovingNetworks.h create mode 100644 tos/platforms/shimmer/chips/bluetooth/RovingNetworksC.nc create mode 100644 tos/platforms/shimmer/chips/bluetooth/RovingNetworksP.nc diff --git a/tos/platforms/shimmer/chips/bluetooth/Bluetooth.nc b/tos/platforms/shimmer/chips/bluetooth/Bluetooth.nc new file mode 100644 index 00000000..f03f0a5d --- /dev/null +++ b/tos/platforms/shimmer/chips/bluetooth/Bluetooth.nc @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the Intel Corporation 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 OWNER 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. + * + * Authors: Steve Ayer, Adrian Burns + * February, 2007 + */ +/** + * @author Steve Ayer + * @author Adrian Burns + * @date February, 2007 + * + * @author Mike Healy + * @date April 20, 2009 - ported to TinyOS 2.x + */ + + + +#include "RovingNetworks.h" + +interface Bluetooth { + + /* write SPP (Serial Port Profile) data to the connected BT device */ + command error_t write(const uint8_t *buf, uint16_t len); + + /* after this command is called there will be no link to the connected device */ + command error_t disconnect(); + + /* commands useful for Master(client) applications only */ + /* do an BT Inquiry to discover all listening devices within range */ + command void discoverDevices(); + + /* connect to a specific device that was previously discovered */ + command error_t connect(uint8_t * addr); + + // enum SLAVE_MODE, MASTER_MODE, TRIGGER_MASTER_MODE, AUTO_MASTER_MODE + command void setRadioMode(uint8_t mode); + + command void setDiscoverable(bool disc); + command void setEncryption(bool enc); + command void setAuthentication(bool auth); + command void setName(char * name); // max 16 chars + command void setPIN(char * name); // max 16 chars + command void setServiceClass(char * class); // max 4 chars (hex word) + command void setServiceName(char * name); // max 16 chars + command void setDeviceClass(char * class); // max 4 chars (hex word) + command void disableRemoteConfig(bool disableConfig); + command void setBaudrate(char * rate_factor); // max 4 chars, must be integer + /* save power by minimising time Inquiry/Page scanning, call these commands from */ + /* your StdControl.init() - module reset necessary for changes to take effect */ + command void setPagingTime(char * hexval_time); // max 4 chars (hex word) + command void setInquiryTime(char * hexval_time); // max 4 chars (hex word) + command void resetDefaults(); + + /* whether or not it succeeded */ + async event void connectionMade(uint8_t status); + async event void connectionClosed(uint8_t reason); + async event void commandModeEnded(); + /* + * buffered data depends upon line demarcation or eot for this... + * event void dataAvailable(uint8_t * data, uint16_t len); + * and this... + * event void discoveryStatus(uint8_t * devices); + * + */ + async event void dataAvailable(uint8_t data); + event void writeDone(); +} + + diff --git a/tos/platforms/shimmer/chips/bluetooth/RovingNetworks.h b/tos/platforms/shimmer/chips/bluetooth/RovingNetworks.h new file mode 100644 index 00000000..5a7d82dd --- /dev/null +++ b/tos/platforms/shimmer/chips/bluetooth/RovingNetworks.h @@ -0,0 +1,32 @@ +/* radioMode in enableBluetooth() can be set to one of the following modes, + see the RovingNetworks AT command set for further details on module configuration */ + +#ifndef ROVINGNETWORKS_H +#define ROVINGNETWORKS_H +enum { + SLAVE_MODE, + MASTER_MODE, + TRIGGER_MASTER_MODE, + AUTO_MASTER_MODE +}; + +enum { + NADA, + INITIAL, + FINAL +}; +/* +const char * SETMODE = "SM,"; +const char * SETMASTERMODE = "SM,1"; +const char * SETSLAVEMODE = "SM,0"; +const char * DISCOVERRADIOS = "I,"; +const char * DISCOVERRADIOS2 = ",0"; + +const char * SETFASTBAUD = "SU,115"; +const char * ENTERCOMMANDMODE = "$$$"; +const char * SETSLEEPMODE = "SW,0300"; +const char * DIALRADIO = "C,"; +const char * HANGUPRADIO = "R,1"; +const char * WAKERADIO = ""; +*/ +#endif diff --git a/tos/platforms/shimmer/chips/bluetooth/RovingNetworksC.nc b/tos/platforms/shimmer/chips/bluetooth/RovingNetworksC.nc new file mode 100644 index 00000000..046b12ae --- /dev/null +++ b/tos/platforms/shimmer/chips/bluetooth/RovingNetworksC.nc @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the Intel Corporation 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 OWNER 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. + * + * Author: Steve Ayer + * February, 2007 + */ +/** + * @author Steve Ayer + * @author Adrian Burns + * @date February, 2007 + * + * @author Mike Healy + * @date April 20, 2009 - ported to TinyOS 2.x + */ + + + +configuration RovingNetworksC { + provides { + interface StdControl; + interface Bluetooth; + interface Init; + } +} +implementation { + components + RovingNetworksP, + MainC, + HplMsp430InterruptC, + HplMsp430Usart1C, + LedsC; + + StdControl = RovingNetworksP; + Bluetooth = RovingNetworksP; + Init = RovingNetworksP; + + RovingNetworksP.UARTControl -> HplMsp430Usart1C.HplMsp430Usart; + RovingNetworksP.UARTData -> HplMsp430Usart1C.HplMsp430UsartInterrupts; + RovingNetworksP.RTSInterrupt -> HplMsp430InterruptC.Port16; + RovingNetworksP.ConnectionInterrupt -> HplMsp430InterruptC.Port15; + RovingNetworksP.Leds -> LedsC; + +} diff --git a/tos/platforms/shimmer/chips/bluetooth/RovingNetworksP.nc b/tos/platforms/shimmer/chips/bluetooth/RovingNetworksP.nc new file mode 100644 index 00000000..7f0b6b49 --- /dev/null +++ b/tos/platforms/shimmer/chips/bluetooth/RovingNetworksP.nc @@ -0,0 +1,521 @@ +/* + * Copyright (c) 2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the Intel Corporation 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 OWNER 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. + * + * Author: Steve Ayer + * February, 2007 + */ +/** + * @author Steve Ayer + * @author Adrian Burns + * @date February, 2007 + * + * @author Mike Healy + * @date April 20, 2009 - ported to TinyOS 2.x + */ + + +#include "RovingNetworks.h" +#include "Message.h" + +module RovingNetworksP { + provides { + interface Init; + interface StdControl; + interface Bluetooth; + } + uses { + interface HplMsp430Usart as UARTControl; + interface HplMsp430UsartInterrupts as UARTData; + interface HplMsp430Interrupt as RTSInterrupt; + interface HplMsp430Interrupt as ConnectionInterrupt; + interface Leds; + } +} + +implementation { + extern int sprintf(char *str, const char *format, ...) __attribute__ ((C)); + extern int snprintf(char *str, size_t len, const char *format, ...) __attribute__ ((C)); + + uint8_t radioMode, charsSent, setupStep; + bool discoverable, authenticate, encrypt, setNameRequest, setPINRequest, runDiscoveryRequest, resetDefaultsRequest, + setSvcClassRequest, setDevClassRequest, setSvcNameRequest, setCustomBaudrate, disableRemoteConfig, newMode, + setCustomInquiryTime, setCustomPagingTime; + norace bool transmissionOverflow, messageInProgress; + char expectedCommandResponse[8], newName[17], newPIN[17], newSvcClass[5], newDevClass[5], newSvcName[17], newBaudrate[5], + newInquiryTime[5], newPagingTime[5]; + + norace struct Message outgoingMsg; + norace struct Message incomingMsg; + + + task void sendNextChar() { + if(charsSent < outgoingMsg.length) { + call UARTControl.tx(msg_get_uint8(&outgoingMsg, charsSent)); + atomic charsSent++; + } + else{ + messageInProgress = FALSE; + atomic if(!*expectedCommandResponse) + signal Bluetooth.writeDone(); + } + } + + command error_t Bluetooth.write(const uint8_t * buf, uint16_t len) { + if(messageInProgress) + return FAIL; + + messageInProgress = TRUE; + atomic charsSent = 0; + msg_clear(&outgoingMsg); + msg_append_buf(&outgoingMsg, buf, len); + + if(!transmissionOverflow){ + post sendNextChar(); + } + + return SUCCESS; + } + + void initRN() { + register uint16_t i; + /* + * powerup state is reset == low (true); mike conrad of roving networks sez: + * wait about 1/2 s after reset toggle + */ + TOSH_SET_BT_RESET_PIN(); + for(i = 0; i< 400; i++) + TOSH_uwait(5000); + + TOSH_MAKE_BT_PIO_INPUT(); // this is the connection interrupt pin, was default output + + call RTSInterrupt.edge(TRUE); // initially, we look for a connection + call RTSInterrupt.enable(); // request to send raises when bt has trans overflow + call RTSInterrupt.clear(); + + call ConnectionInterrupt.edge(TRUE); // initially, we look for a connection + call ConnectionInterrupt.clear(); + call ConnectionInterrupt.enable(); // interrupt upon connection state change (raises when connected, falls when dropped) + + TOSH_CLR_BT_CTS_PIN(); // toggling cts wakes it up + TOSH_SET_BT_CTS_PIN(); + TOSH_uwait(5000); + TOSH_CLR_BT_CTS_PIN(); // tell bt module msp430 is ready + } + + void setupUART() { + msp430_uart_union_config_t RN_uart_config = { {ubr: UBR_1MHZ_115200, umctl: UMCTL_1MHZ_115200, + ssel: 0x02, pena: 0, pev: 0, spb: 0, clen: 1,listen: 0, mm: 0, ckpl: 0, urxse: 0, urxeie: 0, + urxwie: 0, utxe : 1, urxe :1} }; + +#ifdef USE_8MHZ_CRYSTAL // we need exact divisors, else the thing acts unpredictably + call UARTControl.setUbr(0x08); + call UARTControl.setUmctl(0xee); +#endif + call UARTControl.setModeUart(&RN_uart_config); // set to UART mode + + call UARTControl.enableTxIntr(); + call UARTControl.enableRxIntr(); + } + + void disableRN() { + TOSH_CLR_BT_RESET_PIN(); + call UARTControl.disableUart(); + call RTSInterrupt.disable(); + call ConnectionInterrupt.disable(); + } + + error_t writeCommand(char * cmd, char * response) { + atomic strcpy(expectedCommandResponse, response); + if(call Bluetooth.write(cmd, strlen(cmd)) == FAIL) + return FAIL; + + return SUCCESS; + } + + command void Bluetooth.setRadioMode(uint8_t mode){ + newMode = TRUE; + radioMode = mode; + } + + command void Bluetooth.setDiscoverable(bool disc){ + discoverable = disc; + } + + command void Bluetooth.setEncryption(bool enc){ + encrypt = enc; + } + + command void Bluetooth.setAuthentication(bool auth){ + authenticate = auth; + } + + command void Bluetooth.disableRemoteConfig(bool disableConfig){ + disableRemoteConfig = disableConfig; + } + + command void Bluetooth.resetDefaults(){ + resetDefaultsRequest = TRUE; + } + + command void Bluetooth.setName(char * name){ + setNameRequest = TRUE; + snprintf(newName, 17, "%s", name); + } + + command void Bluetooth.setDeviceClass(char * class){ + setDevClassRequest = TRUE; + snprintf(newDevClass, 5, "%s", class); + } + + command void Bluetooth.setServiceClass(char * class){ + setSvcClassRequest = TRUE; + snprintf(newSvcClass, 5, "%s", class); + } + + command void Bluetooth.setServiceName(char * name){ + setSvcNameRequest = TRUE; + snprintf(newSvcName, 5, "%s", name); + } + + /* + * this one makes sense only to roving networks + * the supplied "rate_factor" is the baudrate * 0.004096 + * this factor must be an integer value... + */ + command void Bluetooth.setBaudrate(char * rate_factor){ + setCustomBaudrate = TRUE; + snprintf(newBaudrate, 5, "%s", rate_factor); + } + + command void Bluetooth.setPIN(char * PIN){ + setPINRequest = TRUE; + snprintf(newPIN, 17, "%s", PIN); + } + + /* + * Sets the Inquiry Scan Window - amount of time device + * spends enabling inquiry scan (discoverability). + * Minimum = (hex word) "0012", corresponding to about 1% duty cycle. + * Maximum = (hex word) "1000" + */ + command void Bluetooth.setInquiryTime(char * hexval_time){ + setCustomInquiryTime = TRUE; + snprintf(newInquiryTime, 5, "%s", hexval_time); + } + + /* + * Sets the Paging Scan Window - amount of time device + * spends enabling page scan (connectability). + * Minimum = (hex word) "0012", corresponding to about 1% duty cycle. + * Maximum = (hex word) "1000" + */ + command void Bluetooth.setPagingTime(char * hexval_time){ + setCustomPagingTime = TRUE; + snprintf(newPagingTime, 5, "%s", hexval_time); + } + + /* + * this one is weird. we need to do one at a time; the only way + * to get back is if the previous command responds properly and calls + * back to runSetCommands(). so if we get into command mode, each time here + * we have to send another command. we keep falling down the switch + * until we find it, eventually hitting end. + */ + task void runSetCommands() { + char commandbuf[32]; + + switch(setupStep) { + case 0: + setupStep++; + writeCommand("$$$", "CMD"); + break; + case 1: + setupStep++; + // reset factory defaults + if(resetDefaultsRequest){ + writeCommand("SF,1\r", "AOK"); + break; + } + case 2: + setupStep++; + // default is slave (== 0), otherwise set mode + if(newMode){ + sprintf(commandbuf, "SM,%d\r", radioMode); + writeCommand(commandbuf, "AOK"); + break; + } + case 3: + setupStep++; + /* + * device is discoverable with a non-zero inquiry scan window + * default "time" is 0x0200 (units unspecified) + */ + if(!discoverable){ + writeCommand("SI,0000\r", "AOK"); + break; + } + case 4: + setupStep++; + // device default is off + if(authenticate){ + writeCommand("SA,1\r", "AOK"); + break; + } + case 5: + setupStep++; + // device default is off + if(encrypt){ + writeCommand("SE,1\r", "AOK"); + break; + } + case 6: + setupStep++; + // default is none + if(setNameRequest){ + sprintf(commandbuf, "SN,%s\r", newName); + writeCommand(commandbuf, "AOK"); + break; + } + case 7: + setupStep++; + // default is none + if(setPINRequest){ + sprintf(commandbuf, "SP,%s\r", newPIN); + writeCommand(commandbuf, "AOK"); + break; + } + case 8: + setupStep++; + if(setSvcClassRequest){ + sprintf(commandbuf, "SC,%s\r", newSvcClass); + writeCommand(commandbuf, "AOK"); + break; + } + case 9: + setupStep++; + if(setDevClassRequest){ + sprintf(commandbuf, "SD,%s\r", newDevClass); + writeCommand(commandbuf, "AOK"); + break; + } + case 10: + setupStep++; + if(setSvcNameRequest){ + sprintf(commandbuf, "SS,%s\r", newSvcName); + writeCommand(commandbuf, "AOK"); + break; + } + case 11: + setupStep++; + if(setCustomBaudrate){ + // set the baudrate to suit the MSP430 running at 8Mhz + sprintf(commandbuf, "SZ,%s\r", newBaudrate); + writeCommand(commandbuf, "AOK"); + break; + } + case 12: + setupStep++; + if(disableRemoteConfig){ + // disable remote configuration to enhance throughput + writeCommand("ST,0\r", "AOK"); + } + else{ + // disable remote configuration to enhance throughput + writeCommand("ST,60\r", "AOK"); + } + break; + case 13: + setupStep++; + if(setCustomInquiryTime){ + sprintf(commandbuf, "SI,%s\r", newInquiryTime); + writeCommand(commandbuf, "AOK"); + } + else{ + // to save power only leave inquiry on for approx 40msec (every 1.28 secs) + writeCommand("SI,0040\r", "AOK"); + } + break; + case 14: + setupStep++; + if(setCustomPagingTime){ + sprintf(commandbuf, "SJ,%s\r", newPagingTime); + writeCommand(commandbuf, "AOK"); + } + else{ + // to save power only leave paging on for approx 80msec (every 1.28 secs) + writeCommand("SJ,0080\r", "AOK"); + } + break; + case 15: + setupStep++; + // exit command mode + writeCommand("---\r", "END"); + break; + default: + break; + } + } + + command error_t Init.init(){ + TOSH_MAKE_BT_RTS_INPUT(); + + TOSH_MAKE_BT_RXD_INPUT(); + TOSH_SEL_BT_RXD_MODFUNC(); + + // this powers it up on models so equipped, otherwise harmless +#ifdef BT_PWR_LOGIC_TRUE + TOSH_SET_SW_BT_PWR_N_PIN(); +#else + TOSH_CLR_SW_BT_PWR_N_PIN(); +#endif + + newMode = FALSE; + radioMode = SLAVE_MODE; + discoverable = TRUE; + authenticate = FALSE; + encrypt = FALSE; + resetDefaultsRequest = FALSE; + setNameRequest = FALSE; + setPINRequest = FALSE; + setSvcClassRequest = FALSE; + setSvcNameRequest = FALSE; + setDevClassRequest = FALSE; + setCustomBaudrate = FALSE; + disableRemoteConfig = FALSE; + setCustomInquiryTime = FALSE; + setCustomPagingTime = FALSE; + + setupStep = 0; + atomic *expectedCommandResponse = 0; // NULL pointer + transmissionOverflow = FALSE, messageInProgress = FALSE; + + initRN(); + setupUART(); + + return SUCCESS; + } + + command error_t StdControl.start(){ + TOSH_uwait(15000); + post runSetCommands(); + + return SUCCESS; + } + + command error_t StdControl.stop(){ + disableRN(); + +#ifdef BT_PWR_LOGIC_TRUE + TOSH_CLR_SW_BT_PWR_N_PIN(); +#else + TOSH_SET_SW_BT_PWR_N_PIN(); +#endif + + return SUCCESS; + } + + /* after this command is called there will be no link to the connected device */ + command error_t Bluetooth.disconnect(){ + call Bluetooth.write("K,\r", 3); + } + + /* commands useful for Master(client) applications only */ + /* do an BT Inquiry to discover all listening devices within range */ + command void Bluetooth.discoverDevices() { + if(!radioMode) // we're a slave, shouldn't do this + return; + + runDiscoveryRequest = TRUE; + } + + /* connect to a specific device that was previously discovered */ + command error_t Bluetooth.connect(uint8_t * addr) { + char buffer[64]; + + sprintf(buffer, "C,%s\r", addr); + return writeCommand(buffer, "AOK"); + } + + async event void UARTData.rxDone(uint8_t data) { + if(!*expectedCommandResponse){ + signal Bluetooth.dataAvailable(data); + } + else{ + if(isalpha(data)){ + msg_append_uint8(&incomingMsg, data); + if(msg_cmp_buf(&incomingMsg, // which is affirmative + 0, + expectedCommandResponse, + strlen(expectedCommandResponse))){ + msg_clear(&incomingMsg); + if(!strcmp(expectedCommandResponse, "END")) + signal Bluetooth.commandModeEnded(); //call Leds.greenOn(); + else + post runSetCommands(); + atomic *expectedCommandResponse = '\0'; + } + } + else + msg_clear(&incomingMsg); + } + } + + async event void UARTData.txDone() { + if (!transmissionOverflow) { + post sendNextChar(); + } + } + + // Interrupt associated with radio flow control. Ensures that there are no buffer overflows. + async event void RTSInterrupt.fired() { + if (call RTSInterrupt.getValue() == TRUE) { + transmissionOverflow = 1; + call RTSInterrupt.edge(FALSE); + } + else{ + atomic transmissionOverflow = 0; + post sendNextChar(); + call RTSInterrupt.edge(TRUE); + } + atomic call RTSInterrupt.clear(); + } + + async event void ConnectionInterrupt.fired() { + if(call ConnectionInterrupt.getValue() == TRUE){ + call ConnectionInterrupt.edge(FALSE); + signal Bluetooth.connectionMade(SUCCESS); + } + else{ + call ConnectionInterrupt.edge(TRUE); + signal Bluetooth.connectionClosed(0); + } + atomic call ConnectionInterrupt.clear(); + } +} -- 2.39.2