star-mesh LoRa network

Dependencies:   sx12xx_hal

start-mesh

radio chip selection

Radio chip driver is not included, because options are available.
If you're using SX1272 or SX1276, then import sx127x driver into your program.
if you're using SX1261 or SX1262, then import sx126x driver into your program.
If you're using NAmote72 or Murata discovery, then you must import only sx127x driver.

In this network, devices repeat messages to/from devices out of range of central gateway device. Appropriate for use when slightly larger batteries cost less than extra LoRaWAN gateways. This network uses LoRa transceiver directly and is not LoRaWAN. This network is appropriate for use where extra latency added from store-and-forward is of minimal consequence.

network implementation

Network achieves low-power operation by device waking up at regular intervals to check if LoRa preamble exists. If so, packet is received, otherwise devices sleeps. In this type of operation, trade-off is made between transmitter sending long preamble, and receiver waking up to receive this preamble along with associate message at the end of preamble. This long preamble is only used for request packets: the reply packet will have normal 8-symbol preamble length. This is known as asynchronous low-power operation, permitting an arbitrary number of devices to operate.

Devices start operation on the network by sending a discovery request to any devices that can hear it. Any devices which hears this discovery request will then send a discovery reply at randomized time offset relative to the request. After a pre-established time limit, the discovering device will decide which device to attach to depending on signal quality and how many hops away from the central gateway the device resides.

After device has attached to network, downlinks and uplinks can be sent to/from device. To facilitate downlinks, the devices closer to central gateway will be sent a new-device-notification to inform all devices between the central gateway and the newly attached device, which devices the new device can be reached via.

All devices have two logical interfaces to the network: An upstream interface, and a downstream interface. However, the central gateway device only has a downstream interface, because the "upstream" is only a UART interface to the user handling the user payloads on central gateway.

All devices on network are programmed with same firmware, except for gateway. In main.h #define GATEWAY is commented-out for devices on network, or is defined for central gateway device. Only one central gateway must exist on this network. The unique identifying address of device is derived from CPU unique ID registers, of which 4 byte ID number is used on this network. Using this CPU serial number permits the same binary file to be programmed into any number of devices.

network configuration

Network is configured in main.h

define in main.h
spreading factorSPREADING_FACTOR
bandwidthBW_KHZ
operating radio frequencyCF_MHZ
gateway or deviceGATEWAY
transmit powerTX_DBM

MAC layer timing scales according to LoRa symbol period. When spreading factor and/or bandwidth is changed, all network timing is scaled accordingly by MAC layer.
The transceivers used with the project operate at one datarate. This datarate is fixed, and must be defined at compile time for all devices and gateway.

low power operation

This MAC layer uses mbed eventqueue for scheduling. To enable low power operation, events.use-lowpower-timer-ticker is defined in mbed_app.json. This requires bare-metal operation to have eventqueue use low power timer, permitting deep sleep. LoRa applications such as this do not require RTOS: bare-metal mode is preferred for typical LoRa use.

application layer

User payloads are handled in app_endDevice.cpp. Uplinks are send from application layer by calling uplink(uint8_t *buffer_ptr, uint8_t length) Downlinks are handled in callback function app_downlink()

For gateway, app_gateway.cpp handles user payloads. For downlinks, an example is provided in cmd_downlink() where destination and payload is entered on serial port. All uplinks are handled in callback function gateway_uplink().

Header file app.h contains definitions common to application layer on both network central control and end device.

Note

This page describes how to use the network, for more detailed description of implementation, see details page.

serial terminal user interface

The STDIO UART is used to send and receive user-payload on the gateway, but is also available on end-devices. This serial port is configured at 115200 : 8,N,1.

commandargumentsdescription
?list commands
dldestID byte0 byte1 etcsend downlink to device (from gateway)
lslist downstream devices attached
opdBmmanually change transmit power

For the list of downstream devices, on start each row is printed directly attached device. If devices are attached further downstream, they will be subsequently printed on the same row.

testing / evaluation

Use 3 devices for testing: one gateway and two devices.
Three devices required for checking message repeating (relaying) function. The gateway device must be installed at some distance to prevent both devices from connecting directly to gateway.
Gateway needs to be located far enough away, so signal strength preference overrides hop count from gateway.

Committer:
Wayne Roberts
Date:
Tue Dec 03 09:48:53 2019 -0800
Revision:
0:6015834e4279
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wayne Roberts 0:6015834e4279 1
Wayne Roberts 0:6015834e4279 2 ///* downstream: interface away from gateway 35m = magenta */;
Wayne Roberts 0:6015834e4279 3 #include "main.h"
Wayne Roberts 0:6015834e4279 4
Wayne Roberts 0:6015834e4279 5 lid_list_t* attachedDevices;
Wayne Roberts 0:6015834e4279 6 struct remove downRemove;
Wayne Roberts 0:6015834e4279 7
Wayne Roberts 0:6015834e4279 8 void request_remove_device()
Wayne Roberts 0:6015834e4279 9 {
Wayne Roberts 0:6015834e4279 10 txBuf[txBuf_idx++] = CMD_REMOVE_DEVICE_REQ;
Wayne Roberts 0:6015834e4279 11 putu32ToBuf(&txBuf[txBuf_idx], downRemove.removeID);
Wayne Roberts 0:6015834e4279 12 txBuf_idx += 4;
Wayne Roberts 0:6015834e4279 13 tx_dest_id = downRemove.destID;
Wayne Roberts 0:6015834e4279 14 queue.call_in(500, txBuf_send, true);
Wayne Roberts 0:6015834e4279 15 reqFlags.bits.currentOp = CMD_REMOVE_DEVICE_REQ;
Wayne Roberts 0:6015834e4279 16 }
Wayne Roberts 0:6015834e4279 17
Wayne Roberts 0:6015834e4279 18 /* return true: device is new */
Wayne Roberts 0:6015834e4279 19 static bool list_add_local_device(uint32_t newID)
Wayne Roberts 0:6015834e4279 20 {
Wayne Roberts 0:6015834e4279 21 Rx_log_printf("newID:%lx ", newID);
Wayne Roberts 0:6015834e4279 22 if (attachedDevices == NULL) {
Wayne Roberts 0:6015834e4279 23 attachedDevices = (lid_list_t*)malloc(sizeof(lid_list_t));
Wayne Roberts 0:6015834e4279 24 attachedDevices->id = newID;
Wayne Roberts 0:6015834e4279 25 attachedDevices->attachedList = NULL;
Wayne Roberts 0:6015834e4279 26 attachedDevices->next = NULL;
Wayne Roberts 0:6015834e4279 27 return true;
Wayne Roberts 0:6015834e4279 28 } else {
Wayne Roberts 0:6015834e4279 29 lid_list_t *L, **mallocTarget;
Wayne Roberts 0:6015834e4279 30 /* first check if this device was previously attached to a device attached to us */
Wayne Roberts 0:6015834e4279 31 for (L = attachedDevices; L != NULL; L = L->next) {
Wayne Roberts 0:6015834e4279 32 cid_list_t* children;
Wayne Roberts 0:6015834e4279 33 for (children = L->attachedList; children != NULL; children = children->next) {
Wayne Roberts 0:6015834e4279 34 Rx_log_printf("checkChild:%lx_onLocal:%lx ", children->id, L->id);
Wayne Roberts 0:6015834e4279 35 if (children->id == newID) {
Wayne Roberts 0:6015834e4279 36 Rx_log_printf("CLEARing_%lx_from_%lx ", children->id, L->id);
Wayne Roberts 0:6015834e4279 37 children->id = ID_NONE;
Wayne Roberts 0:6015834e4279 38 }
Wayne Roberts 0:6015834e4279 39 }
Wayne Roberts 0:6015834e4279 40 }
Wayne Roberts 0:6015834e4279 41
Wayne Roberts 0:6015834e4279 42 L = attachedDevices;
Wayne Roberts 0:6015834e4279 43 mallocTarget = &attachedDevices->next;
Wayne Roberts 0:6015834e4279 44 do {
Wayne Roberts 0:6015834e4279 45 if (L->id == newID) {
Wayne Roberts 0:6015834e4279 46 Rx_log_printf("alreadyHave:%lx ", L->id);
Wayne Roberts 0:6015834e4279 47 //return false;
Wayne Roberts 0:6015834e4279 48 return true; /* return true: notify upstream of moved device */
Wayne Roberts 0:6015834e4279 49 } else if (L->id == ID_NONE) {
Wayne Roberts 0:6015834e4279 50 Rx_log_printf("replaceCleared ");
Wayne Roberts 0:6015834e4279 51 L->id = newID;
Wayne Roberts 0:6015834e4279 52 return true; /* return true: notify upstream of moved device */
Wayne Roberts 0:6015834e4279 53 }
Wayne Roberts 0:6015834e4279 54 mallocTarget = &L->next;
Wayne Roberts 0:6015834e4279 55 L = L->next;
Wayne Roberts 0:6015834e4279 56 } while (L != NULL);
Wayne Roberts 0:6015834e4279 57 *mallocTarget = (lid_list_t*)malloc(sizeof(lid_list_t));
Wayne Roberts 0:6015834e4279 58 L = *mallocTarget;
Wayne Roberts 0:6015834e4279 59 L->id = newID;
Wayne Roberts 0:6015834e4279 60 L->attachedList = NULL;
Wayne Roberts 0:6015834e4279 61 L->next = NULL;
Wayne Roberts 0:6015834e4279 62 Rx_log_printf("addedToList:%lx ", L->id);
Wayne Roberts 0:6015834e4279 63 return true;
Wayne Roberts 0:6015834e4279 64 }
Wayne Roberts 0:6015834e4279 65 }
Wayne Roberts 0:6015834e4279 66
Wayne Roberts 0:6015834e4279 67 static void add_new_downstream_attached(uint32_t attachedTo, uint32_t newID)
Wayne Roberts 0:6015834e4279 68 {
Wayne Roberts 0:6015834e4279 69 lid_list_t* L;
Wayne Roberts 0:6015834e4279 70 /* first find if this device already exists anywhere, and remove/clear it */
Wayne Roberts 0:6015834e4279 71 for (L = attachedDevices; L != NULL; L = L->next) {
Wayne Roberts 0:6015834e4279 72 cid_list_t* children;
Wayne Roberts 0:6015834e4279 73 if (L->id == newID) {
Wayne Roberts 0:6015834e4279 74 L->id = ID_NONE;
Wayne Roberts 0:6015834e4279 75 }
Wayne Roberts 0:6015834e4279 76 if (L->attachedList == NULL)
Wayne Roberts 0:6015834e4279 77 continue;
Wayne Roberts 0:6015834e4279 78 for (children = L->attachedList; children != NULL; children = children->next) {
Wayne Roberts 0:6015834e4279 79 if (children->id == newID) {
Wayne Roberts 0:6015834e4279 80 #ifdef GATEWAY
Wayne Roberts 0:6015834e4279 81 if (L->id != attachedTo) {
Wayne Roberts 0:6015834e4279 82 /* notify downstream */
Wayne Roberts 0:6015834e4279 83 downRemove.destID = L->id;
Wayne Roberts 0:6015834e4279 84 downRemove.removeID = newID;
Wayne Roberts 0:6015834e4279 85 }
Wayne Roberts 0:6015834e4279 86 #endif /* GATEWAY */
Wayne Roberts 0:6015834e4279 87 children->id = ID_NONE;
Wayne Roberts 0:6015834e4279 88 }
Wayne Roberts 0:6015834e4279 89 }
Wayne Roberts 0:6015834e4279 90 }
Wayne Roberts 0:6015834e4279 91
Wayne Roberts 0:6015834e4279 92 /* add */
Wayne Roberts 0:6015834e4279 93 for (L = attachedDevices; L != NULL; L = L->next) {
Wayne Roberts 0:6015834e4279 94 if (L->id == attachedTo) {
Wayne Roberts 0:6015834e4279 95 cid_list_t* child;
Wayne Roberts 0:6015834e4279 96 if (L->attachedList == NULL) { // first added child
Wayne Roberts 0:6015834e4279 97 L->attachedList = (cid_list_t*)malloc(sizeof(cid_list_t));
Wayne Roberts 0:6015834e4279 98 L->attachedList->id = newID;
Wayne Roberts 0:6015834e4279 99 L->attachedList->next = NULL;
Wayne Roberts 0:6015834e4279 100 return;
Wayne Roberts 0:6015834e4279 101 }
Wayne Roberts 0:6015834e4279 102 /* first check for vacated slot */
Wayne Roberts 0:6015834e4279 103 for (child = L->attachedList; child != NULL; child = child->next) {
Wayne Roberts 0:6015834e4279 104 if (child->id == ID_NONE) {
Wayne Roberts 0:6015834e4279 105 child->id = newID;
Wayne Roberts 0:6015834e4279 106 return;
Wayne Roberts 0:6015834e4279 107 } else if (child->next == NULL)
Wayne Roberts 0:6015834e4279 108 break; // next pointer available to malloc
Wayne Roberts 0:6015834e4279 109 }
Wayne Roberts 0:6015834e4279 110 child->next = (cid_list_t*)malloc(sizeof(cid_list_t));
Wayne Roberts 0:6015834e4279 111 child = child->next;
Wayne Roberts 0:6015834e4279 112 child->id = newID;
Wayne Roberts 0:6015834e4279 113 child->next = NULL;
Wayne Roberts 0:6015834e4279 114 return;
Wayne Roberts 0:6015834e4279 115 }
Wayne Roberts 0:6015834e4279 116 }
Wayne Roberts 0:6015834e4279 117 } // ..add_new_downstream_attached()
Wayne Roberts 0:6015834e4279 118
Wayne Roberts 0:6015834e4279 119
Wayne Roberts 0:6015834e4279 120 void downstream_ans_rxDoneCB(float rssi, float snr, uint8_t* Idx, uint32_t sendingID, uint8_t cmd)
Wayne Roberts 0:6015834e4279 121 {
Wayne Roberts 0:6015834e4279 122 if (reqFlags.bits.currentOp == CMD_USER_PAYLOAD_DN_REQ) {
Wayne Roberts 0:6015834e4279 123 reqFlags.bits.currentOp = CMD_UNUSED;
Wayne Roberts 0:6015834e4279 124 } else if (reqFlags.bits.currentOp == CMD_REMOVE_DEVICE_REQ) {
Wayne Roberts 0:6015834e4279 125 downRemove.destID = ID_NONE; // removal request complete
Wayne Roberts 0:6015834e4279 126 reqFlags.bits.currentOp = CMD_UNUSED;
Wayne Roberts 0:6015834e4279 127 } else if (reqFlags.bits.currentOp == CMD_DOWNSTREAM_NOT_RESPONDING) {
Wayne Roberts 0:6015834e4279 128 reqFlags.bits.currentOp = CMD_UNUSED;
Wayne Roberts 0:6015834e4279 129 }
Wayne Roberts 0:6015834e4279 130 }
Wayne Roberts 0:6015834e4279 131
Wayne Roberts 0:6015834e4279 132 void discovery_tx_end()
Wayne Roberts 0:6015834e4279 133 {
Wayne Roberts 0:6015834e4279 134 flags.discoverAnswering = 0;
Wayne Roberts 0:6015834e4279 135 start_periodic_rxing(0x90);
Wayne Roberts 0:6015834e4279 136 }
Wayne Roberts 0:6015834e4279 137
Wayne Roberts 0:6015834e4279 138 #ifdef GATEWAY
Wayne Roberts 0:6015834e4279 139 void downstream_req_rxDoneCB(float rssi, float snr, uint8_t* Idx, uint32_t sendingID, uint8_t cmd, upInfo_t* up)
Wayne Roberts 0:6015834e4279 140 #else
Wayne Roberts 0:6015834e4279 141 void downstream_req_rxDoneCB(float rssi, float snr, uint8_t* Idx, uint32_t sendingID, uint8_t cmd)
Wayne Roberts 0:6015834e4279 142 #endif
Wayne Roberts 0:6015834e4279 143 {
Wayne Roberts 0:6015834e4279 144
Wayne Roberts 0:6015834e4279 145 if (cmd == CMD_DISCOVERY_REQ) {
Wayne Roberts 0:6015834e4279 146 unsigned toms, rnd;
Wayne Roberts 0:6015834e4279 147 int8_t sq;
Wayne Roberts 0:6015834e4279 148
Wayne Roberts 0:6015834e4279 149 Radio::Standby();
Wayne Roberts 0:6015834e4279 150 reqFlags.bits.currentOp = CMD_DISCOVERY_ANS;
Wayne Roberts 0:6015834e4279 151
Wayne Roberts 0:6015834e4279 152 txBuf[txBuf_idx++] = CMD_DISCOVERY_ANS;
Wayne Roberts 0:6015834e4279 153 sq = rssi + snr;
Wayne Roberts 0:6015834e4279 154 txBuf[txBuf_idx++] = sq;
Wayne Roberts 0:6015834e4279 155 txBuf[txBuf_idx++] = hops_from_gateway;
Wayne Roberts 0:6015834e4279 156
Wayne Roberts 0:6015834e4279 157 /* schedule transmit to occur randomly, twice */
Wayne Roberts 0:6015834e4279 158 flags.firstDiscoverAns = 1;
Wayne Roberts 0:6015834e4279 159 flags.discoverAnswering = 1;
Wayne Roberts 0:6015834e4279 160 tx_dest_id = sendingID; // discovery req -> ans
Wayne Roberts 0:6015834e4279 161 setPreambleSize(false, 1); // sending discovery answer
Wayne Roberts 0:6015834e4279 162 rnd = Radio::Random() % N_HALF_DISCOVERY_ANS;
Wayne Roberts 0:6015834e4279 163 queue.call_in((discovery_ans_time_step_us * rnd) / 1000, txBuf_send, false);
Wayne Roberts 0:6015834e4279 164 toms = discovery_ans_time_total_us / 1000;
Wayne Roberts 0:6015834e4279 165 queue.call_in(toms, discovery_tx_end);
Wayne Roberts 0:6015834e4279 166 } else if (cmd == CMD_ATTACH_REQ) {
Wayne Roberts 0:6015834e4279 167 Radio::Standby();
Wayne Roberts 0:6015834e4279 168 reqFlags.bits.txAns = ANSWER_OK;
Wayne Roberts 0:6015834e4279 169
Wayne Roberts 0:6015834e4279 170 #ifndef GATEWAY
Wayne Roberts 0:6015834e4279 171 if (sendingID == attUp.id) {
Wayne Roberts 0:6015834e4279 172 /* upstream device restarted or re-connected */
Wayne Roberts 0:6015834e4279 173 init_attached_upstream();
Wayne Roberts 0:6015834e4279 174 hops_from_gateway = HFG_UNATTACHED;
Wayne Roberts 0:6015834e4279 175 }
Wayne Roberts 0:6015834e4279 176 #endif /* GATEWAY */
Wayne Roberts 0:6015834e4279 177
Wayne Roberts 0:6015834e4279 178 /* add sending_ID to list of attached devices */
Wayne Roberts 0:6015834e4279 179 if (list_add_local_device(sendingID)) {
Wayne Roberts 0:6015834e4279 180 /* device is new: if hfg > 0: notify upstream of new device upon txdone of CMD_ATTACH_ANS sent downstream */
Wayne Roberts 0:6015834e4279 181 #ifndef GATEWAY
Wayne Roberts 0:6015834e4279 182 id_newDeviceNotification = sendingID;
Wayne Roberts 0:6015834e4279 183 #endif /* GATEWAY */
Wayne Roberts 0:6015834e4279 184 }
Wayne Roberts 0:6015834e4279 185
Wayne Roberts 0:6015834e4279 186 } else if (cmd == CMD_NEW_DEVICE_ATTACHED_REQ) { // rxDone callback
Wayne Roberts 0:6015834e4279 187 uint32_t new_id = getu32FromBuf(&Radio::radio.rx_buf[*Idx]);
Wayne Roberts 0:6015834e4279 188 *Idx += 4;
Wayne Roberts 0:6015834e4279 189 /* new device not attached directly to me, but to a downstream device attached to me */
Wayne Roberts 0:6015834e4279 190 add_new_downstream_attached(sendingID, new_id);
Wayne Roberts 0:6015834e4279 191
Wayne Roberts 0:6015834e4279 192 /* ack sent first downstream, then (if we;re not a gateway) newDeviceNotification sent upstream */
Wayne Roberts 0:6015834e4279 193
Wayne Roberts 0:6015834e4279 194 #ifdef GATEWAY
Wayne Roberts 0:6015834e4279 195 reqFlags.bits.txAns = ANSWER_OK;
Wayne Roberts 0:6015834e4279 196 #else
Wayne Roberts 0:6015834e4279 197 if (id_newDeviceNotification == ID_NONE) {
Wayne Roberts 0:6015834e4279 198 reqFlags.bits.txAns = ANSWER_OK;
Wayne Roberts 0:6015834e4279 199 id_newDeviceNotification = new_id;
Wayne Roberts 0:6015834e4279 200 } else
Wayne Roberts 0:6015834e4279 201 reqFlags.bits.txAns = ANSWER_BUSY;
Wayne Roberts 0:6015834e4279 202 #endif /* !GATEWAY */
Wayne Roberts 0:6015834e4279 203 } else if (cmd == CMD_USER_PAYLOAD_UP_REQ) { // rxDone callback, pkt from downstream
Wayne Roberts 0:6015834e4279 204 uint8_t len;
Wayne Roberts 0:6015834e4279 205 uint32_t originating_src_id = getu32FromBuf(&Radio::radio.rx_buf[*Idx]);
Wayne Roberts 0:6015834e4279 206 *Idx += 4;
Wayne Roberts 0:6015834e4279 207 len = Radio::radio.rx_buf[*Idx];
Wayne Roberts 0:6015834e4279 208 (*Idx)++;
Wayne Roberts 0:6015834e4279 209 #ifdef GATEWAY
Wayne Roberts 0:6015834e4279 210 //gateway_uplink(len, originating_src_id, &Radio::radio.rx_buf[*Idx]);
Wayne Roberts 0:6015834e4279 211 up->rxBufIdx = *Idx;
Wayne Roberts 0:6015834e4279 212 up->originating_src_id = originating_src_id;
Wayne Roberts 0:6015834e4279 213 up->len = len;
Wayne Roberts 0:6015834e4279 214 reqFlags.bits.txAns = ANSWER_OK;
Wayne Roberts 0:6015834e4279 215 #else
Wayne Roberts 0:6015834e4279 216 if (fwd.len == -1) {
Wayne Roberts 0:6015834e4279 217 fwd.len = len;
Wayne Roberts 0:6015834e4279 218 fwd.B_id = originating_src_id;
Wayne Roberts 0:6015834e4279 219 fwd.tx_dest_id = attUp.id;
Wayne Roberts 0:6015834e4279 220 memcpy(fwd.buf, &Radio::radio.rx_buf[*Idx], len);
Wayne Roberts 0:6015834e4279 221 reqFlags.bits.currentOp = CMD_USER_PAYLOAD_UP_REQ; // this is uplink
Wayne Roberts 0:6015834e4279 222 reqFlags.bits.txAns = ANSWER_OK;
Wayne Roberts 0:6015834e4279 223 // txBuf_send() (for forwarding) will be called after ANS sent
Wayne Roberts 0:6015834e4279 224 } else
Wayne Roberts 0:6015834e4279 225 reqFlags.bits.txAns = ANSWER_BUSY;
Wayne Roberts 0:6015834e4279 226
Wayne Roberts 0:6015834e4279 227 #endif
Wayne Roberts 0:6015834e4279 228 (*Idx) += len;
Wayne Roberts 0:6015834e4279 229 } else if (cmd == CMD_DOWNSTREAM_NOT_RESPONDING) { // rxDone callback, pkt from downstream
Wayne Roberts 0:6015834e4279 230 #ifndef GATEWAY
Wayne Roberts 0:6015834e4279 231 uint32_t reporting_id = getu32FromBuf(&Radio::radio.rx_buf[*Idx]);
Wayne Roberts 0:6015834e4279 232 #endif /* !reporting_id */
Wayne Roberts 0:6015834e4279 233 *Idx += 4;
Wayne Roberts 0:6015834e4279 234 #ifndef GATEWAY
Wayne Roberts 0:6015834e4279 235 uint32_t device_not_respoding_id = getu32FromBuf(&Radio::radio.rx_buf[*Idx]);
Wayne Roberts 0:6015834e4279 236 #endif /* !reporting_id */
Wayne Roberts 0:6015834e4279 237 *Idx += 4;
Wayne Roberts 0:6015834e4279 238 #ifdef GATEWAY
Wayne Roberts 0:6015834e4279 239 reqFlags.bits.txAns = ANSWER_OK;
Wayne Roberts 0:6015834e4279 240 #else
Wayne Roberts 0:6015834e4279 241 if (notResponding.reporting_id == ID_NONE) {
Wayne Roberts 0:6015834e4279 242 reqFlags.bits.currentOp = CMD_DOWNSTREAM_NOT_RESPONDING;
Wayne Roberts 0:6015834e4279 243 notResponding.reporting_id = reporting_id;
Wayne Roberts 0:6015834e4279 244 notResponding.device_not_respoding_id = device_not_respoding_id;
Wayne Roberts 0:6015834e4279 245 reqFlags.bits.txAns = ANSWER_OK;
Wayne Roberts 0:6015834e4279 246 } else
Wayne Roberts 0:6015834e4279 247 reqFlags.bits.txAns = ANSWER_BUSY;
Wayne Roberts 0:6015834e4279 248 #endif /* !GATEWAY */
Wayne Roberts 0:6015834e4279 249 }
Wayne Roberts 0:6015834e4279 250
Wayne Roberts 0:6015834e4279 251 } // ..downstream_req_rxDoneCB()
Wayne Roberts 0:6015834e4279 252