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:
Wed Feb 05 21:05:10 2014 +0000
Revision:
25:db6874b7ac4b
Parent:
24:2cd1094c4fd7
Child:
29:c6d037cceb02
Add XBeeApiCmdAtSet to replace various classes in XBeeApiCmdAt

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