API for communicating with XBee devices.

Dependencies:   CircularBuffer FixedLengthList

Dependents:   XBeeApiTest XBeeApiSimpleATCmdsExample XBeeApiBroadcastExample XBeeApiBroadcastExampleRTOS ... more

Overview

XBeeApi is intended to be a library for providing a high-level API interface to the XBee - for example getChannel() and setChannel(2) methods rather than needing to send( "ATCH" ) and send( "ATCH 2" ) - and then de-code the responses.

See the notebook page here for a description of how the API works & some details on the various classes.

Features:

  • Support for transmission & reception of data packets
  • Support for reading & changing settings
  • Support for "Remote AT" interface to access settings & I/O channels on remote XBees
  • XBeeApi should work if you're using mbed-rtos, though it is not currently threadsafe. Take a look at the XBeeApiBroadcastExampleRTOS example if you're including mbed-rtos.

Example Programs

There are also example programs available:

Transmit

Import programXBeeApiSimpleBroadcastExample

Simple example of how to use XBeeApi - set up the XBee, configure P2P networking then transmit a frame.

Import programXBeeApiBroadcastExample

Example for XBeeAPI; a little more involved than XBeeApiSimpleBroadcastExample with report on failure to set up the XBee and on the transmit status of the message.

Import programXBeeApiBroadcastExampleRTOS

Example of using the XBeeApi library to broadcast a message, based on XBeeApiBroadcastExample. This example shows how to use the library when using mbed-rtos. Before compiling you must open "XbeeApi\Config\XBeeApiCfg.hpp" and change the '#if 0' to '#if 1' on the line above the comment reading "Use RTOS features to make XBeeApi threadsafe"

Settings/Status

Import programXBeeApiSimpleATCmdsExample

Simple example of using XBeeApi to send AT-style commands to the XBee

Import programXBeeApiRemoteATCmdsExample

Example of using the XBeeApi library to send AT commands to remote XBee devices in order to read/write settings

Receive

Import programXBeeApiSimpleReceiveExample

Simple example of using XBeeApi to receive data packets via wireless

Import programXBeeApiReceiveCallbackExample

Example of using the XBeeApi library to receive a message via a callback method

Import programXBeeApiReceiveCallbackExampleRTOS

Example of using the XBeeApi library to receive a message via a callback method. This example shows how to use the library when using mbed-rtos. See the comment at the top of main.cpp

Remote I/O

Import programXBeeApiRemoteIOExample

Example of using the XBeeApi library to read inputs on a remote XBee

If you have 2 mbed connected XBees available then you can use XBeeApiSimpleReceiveExample and XBeeApiSimpleBroadcastExample as a pair.

Note that this is still a work in progress! XBeeApiTodoList tracks some of the functionality still to be added.

Committer:
johnb
Date:
Thu Feb 06 21:26:48 2014 +0000
Revision:
30:9532b01a1ae1
Parent:
29:c6d037cceb02
Child:
31:c144106e55b5
Tidy up

Who changed what in which revision?

UserRevisionLine numberNew contents of line
johnb 8:1b48b619d7f6 1 /**
johnb 8:1b48b619d7f6 2
johnb 8:1b48b619d7f6 3 Copyright 2014 John Bailey
johnb 13:302e7c1ea0b3 4
johnb 8:1b48b619d7f6 5 Licensed under the Apache License, Version 2.0 (the "License");
johnb 8:1b48b619d7f6 6 you may not use this file except in compliance with the License.
johnb 8:1b48b619d7f6 7 You may obtain a copy of the License at
johnb 8:1b48b619d7f6 8
johnb 8:1b48b619d7f6 9 http://www.apache.org/licenses/LICENSE-2.0
johnb 8:1b48b619d7f6 10
johnb 8:1b48b619d7f6 11 Unless required by applicable law or agreed to in writing, software
johnb 8:1b48b619d7f6 12 distributed under the License is distributed on an "AS IS" BASIS,
johnb 8:1b48b619d7f6 13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
johnb 8:1b48b619d7f6 14 See the License for the specific language governing permissions and
johnb 8:1b48b619d7f6 15 limitations under the License.
johnb 8:1b48b619d7f6 16
johnb 8:1b48b619d7f6 17 */
johnb 8:1b48b619d7f6 18
johnb 8:1b48b619d7f6 19 #include "XBeeApiCmdAt.hpp"
johnb 8:1b48b619d7f6 20
johnb 8:1b48b619d7f6 21 /* Set of Frame ID codes for the various commands (see XBEE_CMD_POSN_FRAME_ID) */
johnb 8:1b48b619d7f6 22
johnb 13:302e7c1ea0b3 23 #define CMD_RESPONSE_GET_VR '1'
johnb 13:302e7c1ea0b3 24 #define CMD_RESPONSE_GET_HV '2'
johnb 13:302e7c1ea0b3 25 #define CMD_RESPONSE_GET_CH '3'
johnb 13:302e7c1ea0b3 26 #define CMD_RESPONSE_SET_CH '4'
johnb 13:302e7c1ea0b3 27 #define CMD_RESPONSE_SET_CE '5'
johnb 13:302e7c1ea0b3 28 #define CMD_RESPONSE_GET_CE '6'
johnb 13:302e7c1ea0b3 29 #define CMD_RESPONSE_SET_EDA '7'
johnb 13:302e7c1ea0b3 30 #define CMD_RESPONSE_GET_EDA '8'
johnb 13:302e7c1ea0b3 31 #define CMD_RESPONSE_SET_PID '9'
johnb 13:302e7c1ea0b3 32 #define CMD_RESPONSE_GET_PID '0'
johnb 13:302e7c1ea0b3 33
johnb 30:9532b01a1ae1 34 /** Lowest channel supported by the XBee S1 */
johnb 30:9532b01a1ae1 35 #define XBEE_CHAN_MIN 0x0b
johnb 30:9532b01a1ae1 36 /** Highest channel supported by the XBee S1 */
johnb 30:9532b01a1ae1 37 #define XBEE_CHAN_MAX 0x1a
johnb 13:302e7c1ea0b3 38
johnb 30:9532b01a1ae1 39 /** Lowest channel supported by the XBee S1 Pro */
johnb 30:9532b01a1ae1 40 #define XBEE_PRO_CHAN_MIN 0x0c
johnb 30:9532b01a1ae1 41 /** Highest channel supported by the XBee S1 Pro */
johnb 30:9532b01a1ae1 42 #define XBEE_PRO_CHAN_MAX 0x17
johnb 8:1b48b619d7f6 43
johnb 8:1b48b619d7f6 44 /* Content for the various commands - value of 0 indicates a value to be populated (i.e. variable) */
johnb 8:1b48b619d7f6 45
johnb 13:302e7c1ea0b3 46 const uint8_t cmd_vr[] = { CMD_RESPONSE_GET_VR, 'V', 'R' };
johnb 13:302e7c1ea0b3 47 const uint8_t cmd_hv[] = { CMD_RESPONSE_GET_HV, 'H', 'V' };
johnb 13:302e7c1ea0b3 48
johnb 13:302e7c1ea0b3 49 const uint8_t cmd_ch[] = { CMD_RESPONSE_GET_CH, 'C', 'H' };
johnb 13:302e7c1ea0b3 50 const uint8_t cmd_set_ch[] = { CMD_RESPONSE_SET_CH, 'C', 'H', 0 };
johnb 13:302e7c1ea0b3 51
johnb 13:302e7c1ea0b3 52 const uint8_t cmd_ce[] = { CMD_RESPONSE_GET_CE, 'C', 'E' };
johnb 13:302e7c1ea0b3 53 const uint8_t cmd_set_ce[] = { CMD_RESPONSE_SET_CE, 'C', 'E', 0 };
johnb 13:302e7c1ea0b3 54
johnb 13:302e7c1ea0b3 55 const uint8_t cmd_eda[] = { CMD_RESPONSE_GET_EDA, 'A', '1' };
johnb 13:302e7c1ea0b3 56 const uint8_t cmd_set_eda[] = { CMD_RESPONSE_SET_EDA, 'A', '1', 0 };
johnb 13:302e7c1ea0b3 57
johnb 13:302e7c1ea0b3 58 const uint8_t cmd_pid[] = { CMD_RESPONSE_GET_PID, 'I', 'D' };
johnb 13:302e7c1ea0b3 59 const uint8_t cmd_set_pid[] = { CMD_RESPONSE_SET_PID, 'I', 'D', 0, 0 };
johnb 8:1b48b619d7f6 60
johnb 8:1b48b619d7f6 61 #define XBEE_CMD_POSN_FRAME_ID (4U)
johnb 13:302e7c1ea0b3 62 #define XBEE_CMD_POSN_STATUS (7U)
johnb 8:1b48b619d7f6 63 #define XBEE_CMD_POSN_PARAM_START (8U)
johnb 8:1b48b619d7f6 64
johnb 13:302e7c1ea0b3 65 #define XBEE_CMD_RESPONS_HAS_DATA( _p_len ) ((_p_len > ( XBEE_CMD_POSN_PARAM_START + 1 ))
johnb 13:302e7c1ea0b3 66
johnb 29:c6d037cceb02 67 XBeeApiCmdAt::XBeeApiCmdAt( XBeeDevice* const p_device ) : XBeeApiFrameDecoder( p_device ) ,
johnb 29:c6d037cceb02 68 m_haveHwVer( false ),
johnb 13:302e7c1ea0b3 69 m_haveFwVer( false ),
johnb 13:302e7c1ea0b3 70 m_haveChan( false ),
johnb 13:302e7c1ea0b3 71 m_havePANId( false ),
johnb 13:302e7c1ea0b3 72 m_haveEDA( false ),
johnb 13:302e7c1ea0b3 73 m_haveCE( false )
johnb 8:1b48b619d7f6 74 {
johnb 8:1b48b619d7f6 75 }
johnb 8:1b48b619d7f6 76
johnb 8:1b48b619d7f6 77 bool XBeeApiCmdAt::decodeCallback( const uint8_t* const p_data, size_t p_len )
johnb 8:1b48b619d7f6 78 {
johnb 8:1b48b619d7f6 79 bool ret_val = false;
johnb 13:302e7c1ea0b3 80
johnb 13:302e7c1ea0b3 81 if( XBEE_CMD_AT_RESPONSE == p_data[ XBEE_CMD_POSN_API_ID ] ) {
johnb 13:302e7c1ea0b3 82
johnb 13:302e7c1ea0b3 83 switch( p_data[ XBEE_CMD_POSN_FRAME_ID ] ) {
johnb 8:1b48b619d7f6 84 case CMD_RESPONSE_GET_HV:
johnb 13:302e7c1ea0b3 85 if( p_data[ XBEE_CMD_POSN_STATUS ] == 0 )
johnb 13:302e7c1ea0b3 86 {
johnb 13:302e7c1ea0b3 87 m_hwVer = ((uint16_t)p_data[ XBEE_CMD_POSN_PARAM_START ] << 8) + p_data[ XBEE_CMD_POSN_PARAM_START + 1 ];
johnb 13:302e7c1ea0b3 88 m_haveHwVer = true;
johnb 13:302e7c1ea0b3 89 }
johnb 13:302e7c1ea0b3 90 else
johnb 13:302e7c1ea0b3 91 {
johnb 13:302e7c1ea0b3 92 pc.printf("\r\nERROR1\r\n");
johnb 13:302e7c1ea0b3 93 }
johnb 13:302e7c1ea0b3 94 ret_val = true;
johnb 13:302e7c1ea0b3 95 break;
johnb 13:302e7c1ea0b3 96
johnb 13:302e7c1ea0b3 97 case CMD_RESPONSE_GET_VR:
johnb 13:302e7c1ea0b3 98 if( p_data[ XBEE_CMD_POSN_STATUS ] == 0 )
johnb 13:302e7c1ea0b3 99 {
johnb 13:302e7c1ea0b3 100 m_fwVer = ((uint16_t)p_data[ XBEE_CMD_POSN_PARAM_START ] << 8) + p_data[ XBEE_CMD_POSN_PARAM_START + 1 ];
johnb 13:302e7c1ea0b3 101 m_haveFwVer = true;
johnb 13:302e7c1ea0b3 102 }
johnb 13:302e7c1ea0b3 103 else
johnb 13:302e7c1ea0b3 104 {
johnb 13:302e7c1ea0b3 105 pc.printf("\r\nERROR2\r\n");
johnb 13:302e7c1ea0b3 106 }
johnb 13:302e7c1ea0b3 107 ret_val = true;
johnb 13:302e7c1ea0b3 108 break;
johnb 13:302e7c1ea0b3 109
johnb 13:302e7c1ea0b3 110 case CMD_RESPONSE_GET_CH:
johnb 13:302e7c1ea0b3 111 case CMD_RESPONSE_SET_CH:
johnb 13:302e7c1ea0b3 112 if( p_data[ XBEE_CMD_POSN_STATUS ] == 0 )
johnb 13:302e7c1ea0b3 113 {
johnb 13:302e7c1ea0b3 114 if( CMD_RESPONSE_GET_CH == p_data[ XBEE_CMD_POSN_API_ID ] )
johnb 13:302e7c1ea0b3 115 {
johnb 13:302e7c1ea0b3 116 m_chan = p_data[ XBEE_CMD_POSN_PARAM_START ];
johnb 13:302e7c1ea0b3 117 }
johnb 13:302e7c1ea0b3 118 else
johnb 13:302e7c1ea0b3 119 {
johnb 13:302e7c1ea0b3 120 m_chan = m_chanPend;
johnb 13:302e7c1ea0b3 121 }
johnb 13:302e7c1ea0b3 122 #if 0
johnb 13:302e7c1ea0b3 123 printf("\r\n%02x (%2d) - %02x %02x %02x %02x %02x %02x %02x %02x %02x\r\n",p_data[ XBEE_CMD_POSN_API_ID ],p_len,
johnb 13:302e7c1ea0b3 124 p_data[0],p_data[1],p_data[2],p_data[3],p_data[4],p_data[5],p_data[6],p_data[7],p_data[8]);
johnb 13:302e7c1ea0b3 125 #endif
johnb 13:302e7c1ea0b3 126 m_haveChan = true;
johnb 13:302e7c1ea0b3 127 }
johnb 13:302e7c1ea0b3 128 else
johnb 13:302e7c1ea0b3 129 {
johnb 13:302e7c1ea0b3 130 /* TODO */
johnb 13:302e7c1ea0b3 131 pc.printf("\r\nERROR3\r\n");
johnb 13:302e7c1ea0b3 132 }
johnb 8:1b48b619d7f6 133 ret_val = true;
johnb 8:1b48b619d7f6 134 break;
johnb 13:302e7c1ea0b3 135
johnb 13:302e7c1ea0b3 136 case CMD_RESPONSE_SET_CE:
johnb 13:302e7c1ea0b3 137 case CMD_RESPONSE_GET_CE:
johnb 13:302e7c1ea0b3 138 if( p_data[ XBEE_CMD_POSN_STATUS ] == 0 )
johnb 13:302e7c1ea0b3 139 {
johnb 13:302e7c1ea0b3 140 if( CMD_RESPONSE_GET_CE == p_data[ XBEE_CMD_POSN_API_ID ] )
johnb 13:302e7c1ea0b3 141 {
johnb 13:302e7c1ea0b3 142 m_CE = p_data[ XBEE_CMD_POSN_PARAM_START ];
johnb 13:302e7c1ea0b3 143 }
johnb 13:302e7c1ea0b3 144 else
johnb 13:302e7c1ea0b3 145 {
johnb 13:302e7c1ea0b3 146 m_CE = m_CEPend;
johnb 13:302e7c1ea0b3 147 }
johnb 13:302e7c1ea0b3 148 m_haveCE = true;
johnb 13:302e7c1ea0b3 149 }
johnb 13:302e7c1ea0b3 150 else
johnb 13:302e7c1ea0b3 151 {
johnb 13:302e7c1ea0b3 152 pc.printf("\r\nERROR3\r\n");
johnb 13:302e7c1ea0b3 153 }
johnb 8:1b48b619d7f6 154 ret_val = true;
johnb 8:1b48b619d7f6 155 break;
johnb 13:302e7c1ea0b3 156
johnb 13:302e7c1ea0b3 157 case CMD_RESPONSE_SET_PID:
johnb 13:302e7c1ea0b3 158 case CMD_RESPONSE_GET_PID:
johnb 13:302e7c1ea0b3 159 if( p_data[ XBEE_CMD_POSN_STATUS ] == 0 )
johnb 13:302e7c1ea0b3 160 {
johnb 13:302e7c1ea0b3 161 if( CMD_RESPONSE_GET_PID == p_data[ XBEE_CMD_POSN_API_ID ] )
johnb 13:302e7c1ea0b3 162 {
johnb 13:302e7c1ea0b3 163 m_PANId = p_data[ XBEE_CMD_POSN_PARAM_START ];
johnb 13:302e7c1ea0b3 164 }
johnb 13:302e7c1ea0b3 165 else
johnb 13:302e7c1ea0b3 166 {
johnb 13:302e7c1ea0b3 167 m_PANId = m_PANIdPend;
johnb 13:302e7c1ea0b3 168 }
johnb 13:302e7c1ea0b3 169 m_havePANId = true;
johnb 13:302e7c1ea0b3 170 }
johnb 13:302e7c1ea0b3 171 else
johnb 13:302e7c1ea0b3 172 {
johnb 13:302e7c1ea0b3 173 pc.printf("\r\nERROR3\r\n");
johnb 13:302e7c1ea0b3 174 }
johnb 8:1b48b619d7f6 175 ret_val = true;
johnb 8:1b48b619d7f6 176 break;
johnb 13:302e7c1ea0b3 177
johnb 13:302e7c1ea0b3 178 case CMD_RESPONSE_SET_EDA:
johnb 13:302e7c1ea0b3 179 case CMD_RESPONSE_GET_EDA:
johnb 13:302e7c1ea0b3 180 if( p_data[ XBEE_CMD_POSN_STATUS ] == 0 )
johnb 13:302e7c1ea0b3 181 {
johnb 13:302e7c1ea0b3 182 if( CMD_RESPONSE_GET_EDA == p_data[ XBEE_CMD_POSN_API_ID ] )
johnb 13:302e7c1ea0b3 183 {
johnb 13:302e7c1ea0b3 184 m_EDA = p_data[ XBEE_CMD_POSN_PARAM_START ];
johnb 13:302e7c1ea0b3 185 }
johnb 13:302e7c1ea0b3 186 else
johnb 13:302e7c1ea0b3 187 {
johnb 13:302e7c1ea0b3 188 m_EDA = m_EDAPend;
johnb 13:302e7c1ea0b3 189 }
johnb 13:302e7c1ea0b3 190 m_haveEDA = true;
johnb 13:302e7c1ea0b3 191 }
johnb 13:302e7c1ea0b3 192 else
johnb 13:302e7c1ea0b3 193 {
johnb 13:302e7c1ea0b3 194 pc.printf("\r\nERROR3\r\n");
johnb 13:302e7c1ea0b3 195 }
johnb 13:302e7c1ea0b3 196 ret_val = true;
johnb 8:1b48b619d7f6 197 break;
johnb 13:302e7c1ea0b3 198
johnb 8:1b48b619d7f6 199 }
johnb 8:1b48b619d7f6 200 }
johnb 8:1b48b619d7f6 201 return ret_val;
johnb 8:1b48b619d7f6 202 }
johnb 8:1b48b619d7f6 203
johnb 8:1b48b619d7f6 204 bool XBeeApiCmdAt::setChannel( uint8_t const p_chan )
johnb 8:1b48b619d7f6 205 {
johnb 29:c6d037cceb02 206 bool ret_val = false;
johnb 29:c6d037cceb02 207
johnb 29:c6d037cceb02 208 if((( m_device->getXBeeModel() == XBeeDevice::XBEEDEVICE_S1 ) &&
johnb 29:c6d037cceb02 209 ( p_chan >= XBEE_CHAN_MIN ) &&
johnb 29:c6d037cceb02 210 ( p_chan <= XBEE_CHAN_MAX )) ||
johnb 29:c6d037cceb02 211 (( m_device->getXBeeModel() == XBeeDevice::XBEEDEVICE_S1_PRO ) &&
johnb 29:c6d037cceb02 212 ( p_chan >= XBEE_PRO_CHAN_MIN ) &&
johnb 29:c6d037cceb02 213 ( p_chan <= XBEE_PRO_CHAN_MAX )))
johnb 29:c6d037cceb02 214 {
johnb 29:c6d037cceb02 215 XBeeApiCmdAtSet<uint8_t> req( cmd_set_ch, p_chan );
johnb 29:c6d037cceb02 216
johnb 29:c6d037cceb02 217 m_chanPend = p_chan;
johnb 29:c6d037cceb02 218 m_device->SendFrame( &req );
johnb 29:c6d037cceb02 219 ret_val = true;
johnb 29:c6d037cceb02 220 }
johnb 29:c6d037cceb02 221 return ret_val;
johnb 8:1b48b619d7f6 222 }
johnb 8:1b48b619d7f6 223
johnb 8:1b48b619d7f6 224 bool XBeeApiCmdAt::requestHardwareVersion( void )
johnb 8:1b48b619d7f6 225 {
johnb 24:2cd1094c4fd7 226 XBeeApiFrame req( XBEE_CMD_AT_CMD, cmd_hv, sizeof( cmd_hv ));
johnb 13:302e7c1ea0b3 227 m_haveHwVer = false;
johnb 8:1b48b619d7f6 228 m_device->SendFrame( &req );
johnb 8:1b48b619d7f6 229 return true;
johnb 8:1b48b619d7f6 230 }
johnb 13:302e7c1ea0b3 231
johnb 8:1b48b619d7f6 232 bool XBeeApiCmdAt::requestFirmwareVersion( void )
johnb 8:1b48b619d7f6 233 {
johnb 24:2cd1094c4fd7 234 XBeeApiFrame req( XBEE_CMD_AT_CMD, cmd_vr, sizeof( cmd_vr ));
johnb 8:1b48b619d7f6 235 m_haveFwVer = false;
johnb 13:302e7c1ea0b3 236 m_device->SendFrame( &req );
johnb 8:1b48b619d7f6 237 return true;
johnb 8:1b48b619d7f6 238 }
johnb 8:1b48b619d7f6 239
johnb 8:1b48b619d7f6 240 bool XBeeApiCmdAt::requestChannel( void )
johnb 8:1b48b619d7f6 241 {
johnb 24:2cd1094c4fd7 242 XBeeApiFrame req( XBEE_CMD_AT_CMD, cmd_ch, sizeof( cmd_ch ));
johnb 8:1b48b619d7f6 243 m_haveChan = false;
johnb 8:1b48b619d7f6 244 m_device->SendFrame( &req );
johnb 8:1b48b619d7f6 245 return true;
johnb 8:1b48b619d7f6 246 }
johnb 8:1b48b619d7f6 247
johnb 13:302e7c1ea0b3 248 bool XBeeApiCmdAt::requestPanId( void )
johnb 13:302e7c1ea0b3 249 {
johnb 24:2cd1094c4fd7 250 XBeeApiFrame req( XBEE_CMD_AT_CMD, cmd_pid, sizeof( cmd_pid ));
johnb 13:302e7c1ea0b3 251 m_havePANId = false;
johnb 13:302e7c1ea0b3 252 m_device->SendFrame( &req );
johnb 13:302e7c1ea0b3 253 return true;
johnb 13:302e7c1ea0b3 254 }
johnb 13:302e7c1ea0b3 255
johnb 13:302e7c1ea0b3 256 bool XBeeApiCmdAt::requestCoordinatorEnabled( void )
johnb 13:302e7c1ea0b3 257 {
johnb 24:2cd1094c4fd7 258 XBeeApiFrame req( XBEE_CMD_AT_CMD, cmd_ce, sizeof( cmd_ce ));
johnb 13:302e7c1ea0b3 259 m_haveCE = false;
johnb 13:302e7c1ea0b3 260 m_device->SendFrame( &req );
johnb 13:302e7c1ea0b3 261 return true;
johnb 13:302e7c1ea0b3 262 }
johnb 13:302e7c1ea0b3 263
johnb 13:302e7c1ea0b3 264 bool XBeeApiCmdAt::requestEndDeviceAssociationEnabled( void )
johnb 13:302e7c1ea0b3 265 {
johnb 24:2cd1094c4fd7 266 XBeeApiFrame req( XBEE_CMD_AT_CMD, cmd_eda, sizeof( cmd_eda ));
johnb 13:302e7c1ea0b3 267 m_haveEDA = false;
johnb 13:302e7c1ea0b3 268 m_device->SendFrame( &req );
johnb 13:302e7c1ea0b3 269 return true;
johnb 13:302e7c1ea0b3 270 }
johnb 13:302e7c1ea0b3 271
johnb 8:1b48b619d7f6 272 bool XBeeApiCmdAt::getFirmwareVersion( uint16_t* const p_ver )
johnb 8:1b48b619d7f6 273 {
johnb 13:302e7c1ea0b3 274 if( m_haveFwVer ) {
johnb 8:1b48b619d7f6 275 *p_ver = m_fwVer;
johnb 8:1b48b619d7f6 276 }
johnb 8:1b48b619d7f6 277 return m_haveFwVer;
johnb 13:302e7c1ea0b3 278
johnb 8:1b48b619d7f6 279 }
johnb 8:1b48b619d7f6 280
johnb 8:1b48b619d7f6 281 bool XBeeApiCmdAt::getHardwareVersion( uint16_t* const p_ver )
johnb 8:1b48b619d7f6 282 {
johnb 13:302e7c1ea0b3 283 if( m_haveHwVer ) {
johnb 8:1b48b619d7f6 284 *p_ver = m_hwVer;
johnb 8:1b48b619d7f6 285 }
johnb 8:1b48b619d7f6 286 return m_haveHwVer;
johnb 8:1b48b619d7f6 287 }
johnb 8:1b48b619d7f6 288
johnb 8:1b48b619d7f6 289 bool XBeeApiCmdAt::getChannel( uint8_t* const p_chan )
johnb 8:1b48b619d7f6 290 {
johnb 13:302e7c1ea0b3 291 if( m_haveChan ) {
johnb 8:1b48b619d7f6 292 *p_chan = m_chan;
johnb 8:1b48b619d7f6 293 }
johnb 8:1b48b619d7f6 294 return m_haveChan;
johnb 8:1b48b619d7f6 295 }
johnb 8:1b48b619d7f6 296
johnb 13:302e7c1ea0b3 297 bool XBeeApiCmdAt::getCoordinatorEnabled( bool* const p_en )
johnb 13:302e7c1ea0b3 298 {
johnb 13:302e7c1ea0b3 299 if( m_haveCE ) {
johnb 13:302e7c1ea0b3 300 *p_en = m_CE;
johnb 13:302e7c1ea0b3 301 }
johnb 13:302e7c1ea0b3 302 return m_haveCE;
johnb 13:302e7c1ea0b3 303 }
johnb 13:302e7c1ea0b3 304
johnb 13:302e7c1ea0b3 305 bool XBeeApiCmdAt::setCoordinatorEnabled( const bool p_en )
johnb 13:302e7c1ea0b3 306 {
johnb 25:db6874b7ac4b 307 XBeeApiCmdAtSet<bool> req( cmd_set_ce, p_en );
johnb 25:db6874b7ac4b 308
johnb 13:302e7c1ea0b3 309 m_haveCE = false;
johnb 13:302e7c1ea0b3 310 m_CEPend = p_en;
johnb 25:db6874b7ac4b 311 m_device->SendFrame( &req );
johnb 13:302e7c1ea0b3 312 return true;
johnb 13:302e7c1ea0b3 313 }
johnb 13:302e7c1ea0b3 314
johnb 13:302e7c1ea0b3 315 bool XBeeApiCmdAt::getEndDeviceAssociationEnabled( bool* const p_en )
johnb 13:302e7c1ea0b3 316 {
johnb 13:302e7c1ea0b3 317 if( m_haveEDA ) {
johnb 13:302e7c1ea0b3 318 *p_en = m_EDA;
johnb 13:302e7c1ea0b3 319 }
johnb 13:302e7c1ea0b3 320 return m_haveEDA;
johnb 13:302e7c1ea0b3 321 }
johnb 13:302e7c1ea0b3 322 bool XBeeApiCmdAt::setEndDeviceAssociationEnabled( const bool p_en )
johnb 13:302e7c1ea0b3 323 {
johnb 25:db6874b7ac4b 324 XBeeApiCmdAtSet<bool> req( cmd_set_eda, p_en );
johnb 25:db6874b7ac4b 325
johnb 13:302e7c1ea0b3 326 m_haveEDA = false;
johnb 13:302e7c1ea0b3 327 m_EDAPend = p_en;
johnb 13:302e7c1ea0b3 328 m_device->SendFrame( &req );
johnb 13:302e7c1ea0b3 329 return true;
johnb 13:302e7c1ea0b3 330 }
johnb 13:302e7c1ea0b3 331
johnb 13:302e7c1ea0b3 332 bool XBeeApiCmdAt::getPanId( panId_t* const p_chan )
johnb 13:302e7c1ea0b3 333 {
johnb 13:302e7c1ea0b3 334 if( m_havePANId ) {
johnb 13:302e7c1ea0b3 335 *p_chan = m_PANId;
johnb 13:302e7c1ea0b3 336 }
johnb 13:302e7c1ea0b3 337 return m_havePANId;
johnb 13:302e7c1ea0b3 338
johnb 13:302e7c1ea0b3 339 }
johnb 13:302e7c1ea0b3 340 bool XBeeApiCmdAt::setPanId( const panId_t p_chan )
johnb 13:302e7c1ea0b3 341 {
johnb 25:db6874b7ac4b 342 XBeeApiCmdAtSet<panId_t> panid( cmd_set_pid, p_chan );
johnb 25:db6874b7ac4b 343
johnb 13:302e7c1ea0b3 344 m_havePANId = false;
johnb 13:302e7c1ea0b3 345 m_PANIdPend = p_chan;
johnb 13:302e7c1ea0b3 346 m_device->SendFrame( &panid );
johnb 13:302e7c1ea0b3 347 return true;
johnb 13:302e7c1ea0b3 348 }
johnb 13:302e7c1ea0b3 349
johnb 13:302e7c1ea0b3 350
johnb 29:c6d037cceb02 351 XBeeApiCmdAtBlocking::XBeeApiCmdAtBlocking( XBeeDevice* const p_device, const uint16_t p_timeout, const uint16_t p_slice ) :
johnb 29:c6d037cceb02 352 XBeeApiCmdAt( p_device ),
johnb 13:302e7c1ea0b3 353 m_timeout( p_timeout ),
johnb 13:302e7c1ea0b3 354 m_slice( p_slice )
johnb 8:1b48b619d7f6 355 {
johnb 8:1b48b619d7f6 356 }
johnb 8:1b48b619d7f6 357
johnb 13:302e7c1ea0b3 358 /**
johnb 11:bfcf1356027b 359 Macro to wrap around the "requestXXX" & "getXXX" methods and implement a blocking call.
johnb 11:bfcf1356027b 360 This macro is used as the basis for getXXX functions in XBeeApiCmdAtBlocking.
johnb 8:1b48b619d7f6 361
johnb 13:302e7c1ea0b3 362 Originally looked to achieve this using a template function passing method pointers, however
johnb 13:302e7c1ea0b3 363 there's no way to get a method pointer to the parent class implementation as opposed to the
johnb 13:302e7c1ea0b3 364 implementation in this class, meaning that the result was a recursive method call. The joys of
johnb 11:bfcf1356027b 365 polymorphism.
johnb 13:302e7c1ea0b3 366
johnb 11:bfcf1356027b 367 e.g. We pass a pointer to method getHardwareVersion(). The function receiving the pointer
johnb 11:bfcf1356027b 368 uses it to make a function call. The actual function that's called is (correctly)
johnb 11:bfcf1356027b 369 the one implemented in this class, however what we actually wanted in this case
johnb 11:bfcf1356027b 370 was to call the implementation in the base class. Using static_cast<> doesn't have
johnb 11:bfcf1356027b 371 any effect and taking the address of XBeeApiCmdAt::getHardwareVersion ends up with
johnb 11:bfcf1356027b 372 XBeeApiCmdAtBlocking::getHardwareVersion being called due to polymorphism. */
johnb 11:bfcf1356027b 373 #define BLOCKING_GET( _REQ_FN, _GET_FN, _VAR ) \
johnb 11:bfcf1356027b 374 bool ret_val = false; \
johnb 11:bfcf1356027b 375 uint16_t counter = m_timeout; \
johnb 11:bfcf1356027b 376 \
johnb 11:bfcf1356027b 377 if( _GET_FN( _VAR ) )\
johnb 11:bfcf1356027b 378 {\
johnb 11:bfcf1356027b 379 ret_val = true;\
johnb 11:bfcf1356027b 380 } \
johnb 11:bfcf1356027b 381 else if( _REQ_FN() )\
johnb 11:bfcf1356027b 382 {\
johnb 11:bfcf1356027b 383 bool cont = false;\
johnb 11:bfcf1356027b 384 \
johnb 11:bfcf1356027b 385 do{\
johnb 11:bfcf1356027b 386 wait_ms( m_slice );\
johnb 11:bfcf1356027b 387 if( _GET_FN( _VAR ) )\
johnb 11:bfcf1356027b 388 {\
johnb 11:bfcf1356027b 389 ret_val = true;\
johnb 11:bfcf1356027b 390 }\
johnb 11:bfcf1356027b 391 else if( counter > m_slice ) {\
johnb 11:bfcf1356027b 392 counter -= m_slice; \
johnb 11:bfcf1356027b 393 cont = true;\
johnb 11:bfcf1356027b 394 } \
johnb 11:bfcf1356027b 395 } while( cont );\
johnb 11:bfcf1356027b 396 }\
johnb 11:bfcf1356027b 397 \
johnb 8:1b48b619d7f6 398 return( ret_val );
johnb 8:1b48b619d7f6 399
johnb 13:302e7c1ea0b3 400 /**
johnb 11:bfcf1356027b 401 Macro to wrap around the "setXXX" & "getXXX" methods and implement a blocking call.
johnb 11:bfcf1356027b 402 This macro is used as the basis for setXXX functions in XBeeApiCmdAtBlocking.
johnb 11:bfcf1356027b 403 */
johnb 11:bfcf1356027b 404 #define BLOCKING_SET( _SET_FN, _GET_FN, _VAR, _TYPE ) \
johnb 11:bfcf1356027b 405 bool ret_val = false; \
johnb 11:bfcf1356027b 406 uint16_t counter = m_timeout; \
johnb 11:bfcf1356027b 407 _TYPE readback; \
johnb 11:bfcf1356027b 408 \
johnb 11:bfcf1356027b 409 if( _SET_FN( _VAR ) )\
johnb 11:bfcf1356027b 410 {\
johnb 11:bfcf1356027b 411 bool cont = false;\
johnb 11:bfcf1356027b 412 \
johnb 11:bfcf1356027b 413 do{\
johnb 11:bfcf1356027b 414 wait_ms( m_slice );\
johnb 11:bfcf1356027b 415 if( _GET_FN( &readback ) &&\
johnb 13:302e7c1ea0b3 416 ( readback == _VAR ))\
johnb 11:bfcf1356027b 417 {\
johnb 11:bfcf1356027b 418 ret_val = true;\
johnb 11:bfcf1356027b 419 }\
johnb 11:bfcf1356027b 420 else if( counter > m_slice ) {\
johnb 11:bfcf1356027b 421 counter -= m_slice; \
johnb 11:bfcf1356027b 422 cont = true;\
johnb 11:bfcf1356027b 423 } \
johnb 11:bfcf1356027b 424 } while( cont );\
johnb 11:bfcf1356027b 425 }\
johnb 11:bfcf1356027b 426 \
johnb 11:bfcf1356027b 427 return( ret_val );
johnb 8:1b48b619d7f6 428
johnb 13:302e7c1ea0b3 429
johnb 8:1b48b619d7f6 430 bool XBeeApiCmdAtBlocking::getHardwareVersion( uint16_t* const p_ver )
johnb 8:1b48b619d7f6 431 {
johnb 13:302e7c1ea0b3 432 BLOCKING_GET( XBeeApiCmdAt::requestHardwareVersion,
johnb 13:302e7c1ea0b3 433 XBeeApiCmdAt::getHardwareVersion,
johnb 11:bfcf1356027b 434 p_ver );
johnb 8:1b48b619d7f6 435 }
johnb 8:1b48b619d7f6 436
johnb 8:1b48b619d7f6 437 bool XBeeApiCmdAtBlocking::getFirmwareVersion( uint16_t* const p_ver )
johnb 8:1b48b619d7f6 438 {
johnb 14:edec6cd78ffb 439 BLOCKING_GET( XBeeApiCmdAt::requestFirmwareVersion,
johnb 14:edec6cd78ffb 440 XBeeApiCmdAt::getFirmwareVersion,
johnb 11:bfcf1356027b 441 p_ver );
johnb 8:1b48b619d7f6 442 }
johnb 8:1b48b619d7f6 443
johnb 8:1b48b619d7f6 444 bool XBeeApiCmdAtBlocking::getChannel( uint8_t* const p_chan )
johnb 8:1b48b619d7f6 445 {
johnb 14:edec6cd78ffb 446 BLOCKING_GET( XBeeApiCmdAt::requestChannel,
johnb 14:edec6cd78ffb 447 XBeeApiCmdAt::getChannel,
johnb 11:bfcf1356027b 448 p_chan );
johnb 8:1b48b619d7f6 449 }
johnb 13:302e7c1ea0b3 450
johnb 8:1b48b619d7f6 451 bool XBeeApiCmdAtBlocking::setChannel( uint8_t const p_chan )
johnb 8:1b48b619d7f6 452 {
johnb 14:edec6cd78ffb 453 BLOCKING_SET( XBeeApiCmdAt::setChannel,
johnb 14:edec6cd78ffb 454 XBeeApiCmdAt::getChannel,
johnb 11:bfcf1356027b 455 p_chan,
johnb 13:302e7c1ea0b3 456 uint8_t );
johnb 13:302e7c1ea0b3 457 }
johnb 13:302e7c1ea0b3 458
johnb 13:302e7c1ea0b3 459 bool XBeeApiCmdAtBlocking::getCoordinatorEnabled( bool* const p_en )
johnb 13:302e7c1ea0b3 460 {
johnb 13:302e7c1ea0b3 461 BLOCKING_GET( XBeeApiCmdAt::requestCoordinatorEnabled,
johnb 13:302e7c1ea0b3 462 XBeeApiCmdAt::getCoordinatorEnabled,
johnb 13:302e7c1ea0b3 463 p_en );
johnb 13:302e7c1ea0b3 464 }
johnb 13:302e7c1ea0b3 465
johnb 13:302e7c1ea0b3 466 bool XBeeApiCmdAtBlocking::setCoordinatorEnabled( const bool p_en )
johnb 13:302e7c1ea0b3 467 {
johnb 14:edec6cd78ffb 468 BLOCKING_SET( XBeeApiCmdAt::setCoordinatorEnabled,
johnb 14:edec6cd78ffb 469 XBeeApiCmdAt::getCoordinatorEnabled,
johnb 13:302e7c1ea0b3 470 p_en,
johnb 13:302e7c1ea0b3 471 bool );
johnb 13:302e7c1ea0b3 472 }
johnb 13:302e7c1ea0b3 473
johnb 13:302e7c1ea0b3 474 bool XBeeApiCmdAtBlocking::getEndDeviceAssociationEnabled( bool* const p_en )
johnb 13:302e7c1ea0b3 475 {
johnb 13:302e7c1ea0b3 476 BLOCKING_GET( XBeeApiCmdAt::requestEndDeviceAssociationEnabled,
johnb 13:302e7c1ea0b3 477 XBeeApiCmdAt::getEndDeviceAssociationEnabled,
johnb 13:302e7c1ea0b3 478 p_en );
johnb 8:1b48b619d7f6 479 }
johnb 8:1b48b619d7f6 480
johnb 13:302e7c1ea0b3 481 bool XBeeApiCmdAtBlocking::setEndDeviceAssociationEnabled( const bool p_en )
johnb 13:302e7c1ea0b3 482 {
johnb 14:edec6cd78ffb 483 BLOCKING_SET( XBeeApiCmdAt::setEndDeviceAssociationEnabled,
johnb 14:edec6cd78ffb 484 XBeeApiCmdAt::getEndDeviceAssociationEnabled,
johnb 13:302e7c1ea0b3 485 p_en,
johnb 13:302e7c1ea0b3 486 bool );
johnb 13:302e7c1ea0b3 487 }
johnb 13:302e7c1ea0b3 488
johnb 13:302e7c1ea0b3 489 bool XBeeApiCmdAtBlocking::getPanId( panId_t* const p_chan )
johnb 13:302e7c1ea0b3 490 {
johnb 13:302e7c1ea0b3 491 BLOCKING_GET( XBeeApiCmdAt::requestPanId,
johnb 13:302e7c1ea0b3 492 XBeeApiCmdAt::getPanId,
johnb 13:302e7c1ea0b3 493 p_chan );
johnb 13:302e7c1ea0b3 494 }
johnb 13:302e7c1ea0b3 495
johnb 13:302e7c1ea0b3 496 bool XBeeApiCmdAtBlocking::setPanId( const panId_t p_chan )
johnb 13:302e7c1ea0b3 497 {
johnb 14:edec6cd78ffb 498 BLOCKING_SET( XBeeApiCmdAt::setPanId,
johnb 14:edec6cd78ffb 499 XBeeApiCmdAt::getPanId,
johnb 13:302e7c1ea0b3 500 p_chan,
johnb 13:302e7c1ea0b3 501 panId_t );
johnb 13:302e7c1ea0b3 502 }
johnb 13:302e7c1ea0b3 503
johnb 25:db6874b7ac4b 504 template < typename T >
johnb 25:db6874b7ac4b 505 XBeeApiCmdAt::XBeeApiCmdAtSet<T>::XBeeApiCmdAtSet( const uint8_t* const p_data,
johnb 25:db6874b7ac4b 506 const T p_val ) : XBeeApiFrame( )
johnb 8:1b48b619d7f6 507 {
johnb 25:db6874b7ac4b 508 size_t s;
johnb 25:db6874b7ac4b 509 uint8_t* dest;
johnb 25:db6874b7ac4b 510 const uint8_t* src = (uint8_t*)(&p_val);
johnb 25:db6874b7ac4b 511
johnb 13:302e7c1ea0b3 512 m_apiId = XBEE_CMD_AT_CMD;
johnb 25:db6874b7ac4b 513
johnb 25:db6874b7ac4b 514 m_buffer[0] = p_data[0];
johnb 25:db6874b7ac4b 515 m_buffer[1] = p_data[1];
johnb 25:db6874b7ac4b 516 m_buffer[2] = p_data[2];
johnb 25:db6874b7ac4b 517
johnb 25:db6874b7ac4b 518 dest = &( m_buffer[3] );
johnb 25:db6874b7ac4b 519
johnb 25:db6874b7ac4b 520 for( s = 0;
johnb 25:db6874b7ac4b 521 s < sizeof( T );
johnb 25:db6874b7ac4b 522 s++, dest++, src++ ) {
johnb 25:db6874b7ac4b 523 *dest = *src;
johnb 25:db6874b7ac4b 524 }
johnb 25:db6874b7ac4b 525
johnb 13:302e7c1ea0b3 526 m_data = m_buffer;
johnb 25:db6874b7ac4b 527 m_dataLen = sizeof( m_buffer );
johnb 8:1b48b619d7f6 528 }
johnb 13:302e7c1ea0b3 529
johnb 25:db6874b7ac4b 530 template < typename T >
johnb 25:db6874b7ac4b 531 XBeeApiCmdAt::XBeeApiCmdAtSet<T>::~XBeeApiCmdAtSet()
johnb 13:302e7c1ea0b3 532 {
johnb 25:db6874b7ac4b 533 }