Fork of my original MQTTGateway
XbeeMonitor/XBeeLib/FrameHandlers/FH_AtCmdResp.cpp@0:a1734fe1ec4b, 2017-04-08 (annotated)
- Committer:
- vpcola
- Date:
- Sat Apr 08 14:43:14 2017 +0000
- Revision:
- 0:a1734fe1ec4b
Initial commit
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| vpcola | 0:a1734fe1ec4b | 1 | /** |
| vpcola | 0:a1734fe1ec4b | 2 | * Copyright (c) 2015 Digi International Inc., |
| vpcola | 0:a1734fe1ec4b | 3 | * All rights not expressly granted are reserved. |
| vpcola | 0:a1734fe1ec4b | 4 | * |
| vpcola | 0:a1734fe1ec4b | 5 | * This Source Code Form is subject to the terms of the Mozilla Public |
| vpcola | 0:a1734fe1ec4b | 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
| vpcola | 0:a1734fe1ec4b | 7 | * You can obtain one at http://mozilla.org/MPL/2.0/. |
| vpcola | 0:a1734fe1ec4b | 8 | * |
| vpcola | 0:a1734fe1ec4b | 9 | * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343 |
| vpcola | 0:a1734fe1ec4b | 10 | * ======================================================================= |
| vpcola | 0:a1734fe1ec4b | 11 | */ |
| vpcola | 0:a1734fe1ec4b | 12 | |
| vpcola | 0:a1734fe1ec4b | 13 | #include "FrameHandlers/FH_AtCmdResp.h" |
| vpcola | 0:a1734fe1ec4b | 14 | #include "Frames/ApiFrame.h" |
| vpcola | 0:a1734fe1ec4b | 15 | |
| vpcola | 0:a1734fe1ec4b | 16 | using namespace XBeeLib; |
| vpcola | 0:a1734fe1ec4b | 17 | |
| vpcola | 0:a1734fe1ec4b | 18 | /** Class constructor */ |
| vpcola | 0:a1734fe1ec4b | 19 | FH_AtCmdResp::FH_AtCmdResp() : |
| vpcola | 0:a1734fe1ec4b | 20 | FrameHandler(ApiFrame::AtCmdResp), at_cmd_resp_cb(NULL) |
| vpcola | 0:a1734fe1ec4b | 21 | { |
| vpcola | 0:a1734fe1ec4b | 22 | } |
| vpcola | 0:a1734fe1ec4b | 23 | |
| vpcola | 0:a1734fe1ec4b | 24 | FH_AtCmdResp::FH_AtCmdResp(ApiFrame::ApiFrameType type) : |
| vpcola | 0:a1734fe1ec4b | 25 | FrameHandler(type), at_cmd_resp_cb(NULL) |
| vpcola | 0:a1734fe1ec4b | 26 | { |
| vpcola | 0:a1734fe1ec4b | 27 | } |
| vpcola | 0:a1734fe1ec4b | 28 | |
| vpcola | 0:a1734fe1ec4b | 29 | /** Class destructor */ |
| vpcola | 0:a1734fe1ec4b | 30 | FH_AtCmdResp::~FH_AtCmdResp() |
| vpcola | 0:a1734fe1ec4b | 31 | { |
| vpcola | 0:a1734fe1ec4b | 32 | } |
| vpcola | 0:a1734fe1ec4b | 33 | |
| vpcola | 0:a1734fe1ec4b | 34 | void FH_AtCmdResp::register_at_cmd_resp_cb(at_cmd_resp_cb_t function) |
| vpcola | 0:a1734fe1ec4b | 35 | { |
| vpcola | 0:a1734fe1ec4b | 36 | at_cmd_resp_cb = function; |
| vpcola | 0:a1734fe1ec4b | 37 | } |
| vpcola | 0:a1734fe1ec4b | 38 | |
| vpcola | 0:a1734fe1ec4b | 39 | void FH_AtCmdResp::unregister_at_cmd_resp_cb() |
| vpcola | 0:a1734fe1ec4b | 40 | { |
| vpcola | 0:a1734fe1ec4b | 41 | at_cmd_resp_cb = NULL; |
| vpcola | 0:a1734fe1ec4b | 42 | } |
| vpcola | 0:a1734fe1ec4b | 43 | |
| vpcola | 0:a1734fe1ec4b | 44 | void FH_AtCmdResp::process_frame_data(const ApiFrame * const frame) |
| vpcola | 0:a1734fe1ec4b | 45 | { |
| vpcola | 0:a1734fe1ec4b | 46 | /* The caller checks that the type matches, so no need to check it here again */ |
| vpcola | 0:a1734fe1ec4b | 47 | |
| vpcola | 0:a1734fe1ec4b | 48 | if (at_cmd_resp_cb == NULL) { |
| vpcola | 0:a1734fe1ec4b | 49 | return; |
| vpcola | 0:a1734fe1ec4b | 50 | } |
| vpcola | 0:a1734fe1ec4b | 51 | |
| vpcola | 0:a1734fe1ec4b | 52 | at_cmd_resp_cb(frame->get_data(), frame->get_data_len()); |
| vpcola | 0:a1734fe1ec4b | 53 | } |
| vpcola | 0:a1734fe1ec4b | 54 | |
| vpcola | 0:a1734fe1ec4b | 55 | |
| vpcola | 0:a1734fe1ec4b | 56 | /** Class constructor */ |
| vpcola | 0:a1734fe1ec4b | 57 | FH_NodeDiscoveryZB::FH_NodeDiscoveryZB() : |
| vpcola | 0:a1734fe1ec4b | 58 | FH_AtCmdResp(ApiFrame::AtCmdResp), node_discovery_cb(NULL) |
| vpcola | 0:a1734fe1ec4b | 59 | { |
| vpcola | 0:a1734fe1ec4b | 60 | } |
| vpcola | 0:a1734fe1ec4b | 61 | |
| vpcola | 0:a1734fe1ec4b | 62 | /** Class destructor */ |
| vpcola | 0:a1734fe1ec4b | 63 | FH_NodeDiscoveryZB::~FH_NodeDiscoveryZB() |
| vpcola | 0:a1734fe1ec4b | 64 | { |
| vpcola | 0:a1734fe1ec4b | 65 | } |
| vpcola | 0:a1734fe1ec4b | 66 | |
| vpcola | 0:a1734fe1ec4b | 67 | void FH_NodeDiscoveryZB::register_node_discovery_cb(node_discovery_zb_cb_t function) |
| vpcola | 0:a1734fe1ec4b | 68 | { |
| vpcola | 0:a1734fe1ec4b | 69 | node_discovery_cb = function; |
| vpcola | 0:a1734fe1ec4b | 70 | } |
| vpcola | 0:a1734fe1ec4b | 71 | |
| vpcola | 0:a1734fe1ec4b | 72 | void FH_NodeDiscoveryZB::unregister_node_discovery_cb() |
| vpcola | 0:a1734fe1ec4b | 73 | { |
| vpcola | 0:a1734fe1ec4b | 74 | node_discovery_cb = NULL; |
| vpcola | 0:a1734fe1ec4b | 75 | } |
| vpcola | 0:a1734fe1ec4b | 76 | |
| vpcola | 0:a1734fe1ec4b | 77 | |
| vpcola | 0:a1734fe1ec4b | 78 | void FH_NodeDiscoveryZB::process_frame_data(const ApiFrame *const frame) |
| vpcola | 0:a1734fe1ec4b | 79 | { |
| vpcola | 0:a1734fe1ec4b | 80 | /* The caller checks that the type matches, so no need to check it here again */ |
| vpcola | 0:a1734fe1ec4b | 81 | |
| vpcola | 0:a1734fe1ec4b | 82 | if (node_discovery_cb == NULL) { |
| vpcola | 0:a1734fe1ec4b | 83 | return; |
| vpcola | 0:a1734fe1ec4b | 84 | } |
| vpcola | 0:a1734fe1ec4b | 85 | |
| vpcola | 0:a1734fe1ec4b | 86 | if (frame->get_data_at(ATCMD_RESP_CMD_LOW_OFFSET) != 'N' || |
| vpcola | 0:a1734fe1ec4b | 87 | frame->get_data_at(ATCMD_RESP_CMD_HIGH_OFFSET) != 'D') { |
| vpcola | 0:a1734fe1ec4b | 88 | return; |
| vpcola | 0:a1734fe1ec4b | 89 | } |
| vpcola | 0:a1734fe1ec4b | 90 | |
| vpcola | 0:a1734fe1ec4b | 91 | if (frame->get_data_at(ATCMD_RESP_STATUS_OFFSET) != AtCmdFrame::AtCmdRespOk) { |
| vpcola | 0:a1734fe1ec4b | 92 | return; |
| vpcola | 0:a1734fe1ec4b | 93 | } |
| vpcola | 0:a1734fe1ec4b | 94 | |
| vpcola | 0:a1734fe1ec4b | 95 | const uint8_t * const data = frame->get_data(); /* The data payload we get here is the full AT command response payload, excluding the frameid. Keep that in mind for the offsets */ |
| vpcola | 0:a1734fe1ec4b | 96 | const uint16_t addr16 = UINT16(data[ATCMD_RESP_NW_ADDR_H_OFFSET], data[ATCMD_RESP_NW_ADDR_L_OFFSET]); |
| vpcola | 0:a1734fe1ec4b | 97 | const uint64_t addr64 = addr64_from_uint8_t(&data[ATCMD_RESP_SH_ADDR_L_OFFSET]); |
| vpcola | 0:a1734fe1ec4b | 98 | const char * const node_id = (const char *)&data[ATCMD_RESP_NI_OFFSET]; |
| vpcola | 0:a1734fe1ec4b | 99 | RemoteXBeeZB remote = RemoteXBeeZB(addr64, addr16); |
| vpcola | 0:a1734fe1ec4b | 100 | |
| vpcola | 0:a1734fe1ec4b | 101 | node_discovery_cb(remote, node_id); |
| vpcola | 0:a1734fe1ec4b | 102 | } |
| vpcola | 0:a1734fe1ec4b | 103 | |
| vpcola | 0:a1734fe1ec4b | 104 | |
| vpcola | 0:a1734fe1ec4b | 105 | |
| vpcola | 0:a1734fe1ec4b | 106 | /** Class constructor */ |
| vpcola | 0:a1734fe1ec4b | 107 | FH_NodeDiscovery802::FH_NodeDiscovery802() : |
| vpcola | 0:a1734fe1ec4b | 108 | FH_AtCmdResp(ApiFrame::AtCmdResp), node_discovery_cb(NULL) |
| vpcola | 0:a1734fe1ec4b | 109 | { |
| vpcola | 0:a1734fe1ec4b | 110 | } |
| vpcola | 0:a1734fe1ec4b | 111 | |
| vpcola | 0:a1734fe1ec4b | 112 | /** Class destructor */ |
| vpcola | 0:a1734fe1ec4b | 113 | FH_NodeDiscovery802::~FH_NodeDiscovery802() |
| vpcola | 0:a1734fe1ec4b | 114 | { |
| vpcola | 0:a1734fe1ec4b | 115 | } |
| vpcola | 0:a1734fe1ec4b | 116 | |
| vpcola | 0:a1734fe1ec4b | 117 | void FH_NodeDiscovery802::register_node_discovery_cb(node_discovery_802_cb_t function) |
| vpcola | 0:a1734fe1ec4b | 118 | { |
| vpcola | 0:a1734fe1ec4b | 119 | node_discovery_cb = function; |
| vpcola | 0:a1734fe1ec4b | 120 | } |
| vpcola | 0:a1734fe1ec4b | 121 | |
| vpcola | 0:a1734fe1ec4b | 122 | void FH_NodeDiscovery802::unregister_node_discovery_cb() |
| vpcola | 0:a1734fe1ec4b | 123 | { |
| vpcola | 0:a1734fe1ec4b | 124 | node_discovery_cb = NULL; |
| vpcola | 0:a1734fe1ec4b | 125 | } |
| vpcola | 0:a1734fe1ec4b | 126 | |
| vpcola | 0:a1734fe1ec4b | 127 | |
| vpcola | 0:a1734fe1ec4b | 128 | void FH_NodeDiscovery802::process_frame_data(const ApiFrame *const frame) |
| vpcola | 0:a1734fe1ec4b | 129 | { |
| vpcola | 0:a1734fe1ec4b | 130 | /* The caller checks that the type matches, so no need to check it here again */ |
| vpcola | 0:a1734fe1ec4b | 131 | |
| vpcola | 0:a1734fe1ec4b | 132 | if (node_discovery_cb == NULL) { |
| vpcola | 0:a1734fe1ec4b | 133 | return; |
| vpcola | 0:a1734fe1ec4b | 134 | } |
| vpcola | 0:a1734fe1ec4b | 135 | |
| vpcola | 0:a1734fe1ec4b | 136 | if (frame->get_data_at(ATCMD_RESP_CMD_LOW_OFFSET) != 'N' || |
| vpcola | 0:a1734fe1ec4b | 137 | frame->get_data_at(ATCMD_RESP_CMD_HIGH_OFFSET) != 'D') { |
| vpcola | 0:a1734fe1ec4b | 138 | return; |
| vpcola | 0:a1734fe1ec4b | 139 | } |
| vpcola | 0:a1734fe1ec4b | 140 | |
| vpcola | 0:a1734fe1ec4b | 141 | if (frame->get_data_at(ATCMD_RESP_STATUS_OFFSET) != AtCmdFrame::AtCmdRespOk) { |
| vpcola | 0:a1734fe1ec4b | 142 | return; |
| vpcola | 0:a1734fe1ec4b | 143 | } |
| vpcola | 0:a1734fe1ec4b | 144 | |
| vpcola | 0:a1734fe1ec4b | 145 | const uint16_t min_atnd_response_with_data = sizeof (uint16_t) + sizeof(uint64_t); |
| vpcola | 0:a1734fe1ec4b | 146 | if (frame->get_data_len() < min_atnd_response_with_data) { |
| vpcola | 0:a1734fe1ec4b | 147 | /* Do not process the ATND "OK" response */ |
| vpcola | 0:a1734fe1ec4b | 148 | return; |
| vpcola | 0:a1734fe1ec4b | 149 | } |
| vpcola | 0:a1734fe1ec4b | 150 | |
| vpcola | 0:a1734fe1ec4b | 151 | const uint8_t * const data = frame->get_data(); |
| vpcola | 0:a1734fe1ec4b | 152 | const uint16_t addr16 = UINT16(data[ATCMD_RESP_NW_ADDR_H_OFFSET], data[ATCMD_RESP_NW_ADDR_L_OFFSET]); |
| vpcola | 0:a1734fe1ec4b | 153 | const uint64_t addr64 = addr64_from_uint8_t(&data[ATCMD_RESP_SH_ADDR_L_OFFSET]); |
| vpcola | 0:a1734fe1ec4b | 154 | #if 0 |
| vpcola | 0:a1734fe1ec4b | 155 | const uint8_t signal_strength = data[ATCMD_802_RESP_SIGN_STR_OFFSET]; |
| vpcola | 0:a1734fe1ec4b | 156 | #endif |
| vpcola | 0:a1734fe1ec4b | 157 | const RemoteXBee802 remote = RemoteXBee802(addr64, addr16); |
| vpcola | 0:a1734fe1ec4b | 158 | const char * const nodeid = (const char *)(&data[ATCMD_802_RESP_NI_OFFSET]); |
| vpcola | 0:a1734fe1ec4b | 159 | |
| vpcola | 0:a1734fe1ec4b | 160 | node_discovery_cb(remote, nodeid); |
| vpcola | 0:a1734fe1ec4b | 161 | } |
| vpcola | 0:a1734fe1ec4b | 162 | |
| vpcola | 0:a1734fe1ec4b | 163 | /** Class constructor */ |
| vpcola | 0:a1734fe1ec4b | 164 | FH_NodeDiscoveryDM::FH_NodeDiscoveryDM() : |
| vpcola | 0:a1734fe1ec4b | 165 | FH_AtCmdResp(ApiFrame::AtCmdResp), node_discovery_cb(NULL) |
| vpcola | 0:a1734fe1ec4b | 166 | { |
| vpcola | 0:a1734fe1ec4b | 167 | } |
| vpcola | 0:a1734fe1ec4b | 168 | |
| vpcola | 0:a1734fe1ec4b | 169 | /** Class destructor */ |
| vpcola | 0:a1734fe1ec4b | 170 | FH_NodeDiscoveryDM::~FH_NodeDiscoveryDM() |
| vpcola | 0:a1734fe1ec4b | 171 | { |
| vpcola | 0:a1734fe1ec4b | 172 | } |
| vpcola | 0:a1734fe1ec4b | 173 | |
| vpcola | 0:a1734fe1ec4b | 174 | void FH_NodeDiscoveryDM::register_node_discovery_cb(node_discovery_dm_cb_t function) |
| vpcola | 0:a1734fe1ec4b | 175 | { |
| vpcola | 0:a1734fe1ec4b | 176 | node_discovery_cb = function; |
| vpcola | 0:a1734fe1ec4b | 177 | } |
| vpcola | 0:a1734fe1ec4b | 178 | |
| vpcola | 0:a1734fe1ec4b | 179 | void FH_NodeDiscoveryDM::unregister_node_discovery_cb() |
| vpcola | 0:a1734fe1ec4b | 180 | { |
| vpcola | 0:a1734fe1ec4b | 181 | node_discovery_cb = NULL; |
| vpcola | 0:a1734fe1ec4b | 182 | } |
| vpcola | 0:a1734fe1ec4b | 183 | |
| vpcola | 0:a1734fe1ec4b | 184 | |
| vpcola | 0:a1734fe1ec4b | 185 | void FH_NodeDiscoveryDM::process_frame_data(const ApiFrame *const frame) |
| vpcola | 0:a1734fe1ec4b | 186 | { |
| vpcola | 0:a1734fe1ec4b | 187 | /* The caller checks that the type matches, so no need to check it here again */ |
| vpcola | 0:a1734fe1ec4b | 188 | |
| vpcola | 0:a1734fe1ec4b | 189 | if (node_discovery_cb == NULL) { |
| vpcola | 0:a1734fe1ec4b | 190 | return; |
| vpcola | 0:a1734fe1ec4b | 191 | } |
| vpcola | 0:a1734fe1ec4b | 192 | |
| vpcola | 0:a1734fe1ec4b | 193 | if (frame->get_data_at(ATCMD_RESP_CMD_LOW_OFFSET) != 'N' || |
| vpcola | 0:a1734fe1ec4b | 194 | frame->get_data_at(ATCMD_RESP_CMD_HIGH_OFFSET) != 'D') { |
| vpcola | 0:a1734fe1ec4b | 195 | return; |
| vpcola | 0:a1734fe1ec4b | 196 | } |
| vpcola | 0:a1734fe1ec4b | 197 | |
| vpcola | 0:a1734fe1ec4b | 198 | if (frame->get_data_at(ATCMD_RESP_STATUS_OFFSET) != AtCmdFrame::AtCmdRespOk) { |
| vpcola | 0:a1734fe1ec4b | 199 | return; |
| vpcola | 0:a1734fe1ec4b | 200 | } |
| vpcola | 0:a1734fe1ec4b | 201 | |
| vpcola | 0:a1734fe1ec4b | 202 | const uint8_t * const data = frame->get_data(); /* The data payload we get here is the full AT command response payload, excluding the frameid. Keep that in mind for the offsets */ |
| vpcola | 0:a1734fe1ec4b | 203 | const uint64_t addr64 = addr64_from_uint8_t(&data[ATCMD_RESP_SH_ADDR_L_OFFSET]); |
| vpcola | 0:a1734fe1ec4b | 204 | const char * const node_id = (const char *)&data[ATCMD_RESP_NI_OFFSET]; |
| vpcola | 0:a1734fe1ec4b | 205 | RemoteXBeeDM remote = RemoteXBeeDM(addr64); |
| vpcola | 0:a1734fe1ec4b | 206 | |
| vpcola | 0:a1734fe1ec4b | 207 | node_discovery_cb(remote, node_id); |
| vpcola | 0:a1734fe1ec4b | 208 | } |