wayne roberts
/
lora_mesh
star-mesh LoRa network
Embed:
(wiki syntax)
Show/hide line numbers
downstream_interface.cpp
00001 00002 ///* downstream: interface away from gateway 35m = magenta */; 00003 #include "main.h" 00004 00005 lid_list_t* attachedDevices; 00006 struct remove downRemove; 00007 00008 void request_remove_device() 00009 { 00010 txBuf[txBuf_idx++] = CMD_REMOVE_DEVICE_REQ; 00011 putu32ToBuf(&txBuf[txBuf_idx], downRemove.removeID); 00012 txBuf_idx += 4; 00013 tx_dest_id = downRemove.destID; 00014 queue.call_in(500, txBuf_send, true); 00015 reqFlags.bits.currentOp = CMD_REMOVE_DEVICE_REQ; 00016 } 00017 00018 /* return true: device is new */ 00019 static bool list_add_local_device(uint32_t newID) 00020 { 00021 Rx_log_printf("newID:%lx ", newID); 00022 if (attachedDevices == NULL) { 00023 attachedDevices = (lid_list_t*)malloc(sizeof(lid_list_t)); 00024 attachedDevices->id = newID; 00025 attachedDevices->attachedList = NULL; 00026 attachedDevices->next = NULL; 00027 return true; 00028 } else { 00029 lid_list_t *L, **mallocTarget; 00030 /* first check if this device was previously attached to a device attached to us */ 00031 for (L = attachedDevices; L != NULL; L = L->next) { 00032 cid_list_t* children; 00033 for (children = L->attachedList; children != NULL; children = children->next) { 00034 Rx_log_printf("checkChild:%lx_onLocal:%lx ", children->id, L->id); 00035 if (children->id == newID) { 00036 Rx_log_printf("CLEARing_%lx_from_%lx ", children->id, L->id); 00037 children->id = ID_NONE; 00038 } 00039 } 00040 } 00041 00042 L = attachedDevices; 00043 mallocTarget = &attachedDevices->next; 00044 do { 00045 if (L->id == newID) { 00046 Rx_log_printf("alreadyHave:%lx ", L->id); 00047 //return false; 00048 return true; /* return true: notify upstream of moved device */ 00049 } else if (L->id == ID_NONE) { 00050 Rx_log_printf("replaceCleared "); 00051 L->id = newID; 00052 return true; /* return true: notify upstream of moved device */ 00053 } 00054 mallocTarget = &L->next; 00055 L = L->next; 00056 } while (L != NULL); 00057 *mallocTarget = (lid_list_t*)malloc(sizeof(lid_list_t)); 00058 L = *mallocTarget; 00059 L->id = newID; 00060 L->attachedList = NULL; 00061 L->next = NULL; 00062 Rx_log_printf("addedToList:%lx ", L->id); 00063 return true; 00064 } 00065 } 00066 00067 static void add_new_downstream_attached(uint32_t attachedTo, uint32_t newID) 00068 { 00069 lid_list_t* L; 00070 /* first find if this device already exists anywhere, and remove/clear it */ 00071 for (L = attachedDevices; L != NULL; L = L->next) { 00072 cid_list_t* children; 00073 if (L->id == newID) { 00074 L->id = ID_NONE; 00075 } 00076 if (L->attachedList == NULL) 00077 continue; 00078 for (children = L->attachedList; children != NULL; children = children->next) { 00079 if (children->id == newID) { 00080 #ifdef GATEWAY 00081 if (L->id != attachedTo) { 00082 /* notify downstream */ 00083 downRemove.destID = L->id; 00084 downRemove.removeID = newID; 00085 } 00086 #endif /* GATEWAY */ 00087 children->id = ID_NONE; 00088 } 00089 } 00090 } 00091 00092 /* add */ 00093 for (L = attachedDevices; L != NULL; L = L->next) { 00094 if (L->id == attachedTo) { 00095 cid_list_t* child; 00096 if (L->attachedList == NULL) { // first added child 00097 L->attachedList = (cid_list_t*)malloc(sizeof(cid_list_t)); 00098 L->attachedList->id = newID; 00099 L->attachedList->next = NULL; 00100 return; 00101 } 00102 /* first check for vacated slot */ 00103 for (child = L->attachedList; child != NULL; child = child->next) { 00104 if (child->id == ID_NONE) { 00105 child->id = newID; 00106 return; 00107 } else if (child->next == NULL) 00108 break; // next pointer available to malloc 00109 } 00110 child->next = (cid_list_t*)malloc(sizeof(cid_list_t)); 00111 child = child->next; 00112 child->id = newID; 00113 child->next = NULL; 00114 return; 00115 } 00116 } 00117 } // ..add_new_downstream_attached() 00118 00119 00120 void downstream_ans_rxDoneCB(float rssi, float snr, uint8_t* Idx, uint32_t sendingID, uint8_t cmd) 00121 { 00122 if (reqFlags.bits.currentOp == CMD_USER_PAYLOAD_DN_REQ) { 00123 reqFlags.bits.currentOp = CMD_UNUSED; 00124 } else if (reqFlags.bits.currentOp == CMD_REMOVE_DEVICE_REQ) { 00125 downRemove.destID = ID_NONE; // removal request complete 00126 reqFlags.bits.currentOp = CMD_UNUSED; 00127 } else if (reqFlags.bits.currentOp == CMD_DOWNSTREAM_NOT_RESPONDING) { 00128 reqFlags.bits.currentOp = CMD_UNUSED; 00129 } 00130 } 00131 00132 void discovery_tx_end() 00133 { 00134 flags.discoverAnswering = 0; 00135 start_periodic_rxing(0x90); 00136 } 00137 00138 #ifdef GATEWAY 00139 void downstream_req_rxDoneCB(float rssi, float snr, uint8_t* Idx, uint32_t sendingID, uint8_t cmd, upInfo_t* up) 00140 #else 00141 void downstream_req_rxDoneCB(float rssi, float snr, uint8_t* Idx, uint32_t sendingID, uint8_t cmd) 00142 #endif 00143 { 00144 00145 if (cmd == CMD_DISCOVERY_REQ) { 00146 unsigned toms, rnd; 00147 int8_t sq; 00148 00149 Radio::Standby(); 00150 reqFlags.bits.currentOp = CMD_DISCOVERY_ANS; 00151 00152 txBuf[txBuf_idx++] = CMD_DISCOVERY_ANS; 00153 sq = rssi + snr; 00154 txBuf[txBuf_idx++] = sq; 00155 txBuf[txBuf_idx++] = hops_from_gateway; 00156 00157 /* schedule transmit to occur randomly, twice */ 00158 flags.firstDiscoverAns = 1; 00159 flags.discoverAnswering = 1; 00160 tx_dest_id = sendingID; // discovery req -> ans 00161 setPreambleSize(false, 1); // sending discovery answer 00162 rnd = Radio::Random() % N_HALF_DISCOVERY_ANS; 00163 queue.call_in((discovery_ans_time_step_us * rnd) / 1000, txBuf_send, false); 00164 toms = discovery_ans_time_total_us / 1000; 00165 queue.call_in(toms, discovery_tx_end); 00166 } else if (cmd == CMD_ATTACH_REQ) { 00167 Radio::Standby(); 00168 reqFlags.bits.txAns = ANSWER_OK; 00169 00170 #ifndef GATEWAY 00171 if (sendingID == attUp.id) { 00172 /* upstream device restarted or re-connected */ 00173 init_attached_upstream(); 00174 hops_from_gateway = HFG_UNATTACHED; 00175 } 00176 #endif /* GATEWAY */ 00177 00178 /* add sending_ID to list of attached devices */ 00179 if (list_add_local_device(sendingID)) { 00180 /* device is new: if hfg > 0: notify upstream of new device upon txdone of CMD_ATTACH_ANS sent downstream */ 00181 #ifndef GATEWAY 00182 id_newDeviceNotification = sendingID; 00183 #endif /* GATEWAY */ 00184 } 00185 00186 } else if (cmd == CMD_NEW_DEVICE_ATTACHED_REQ) { // rxDone callback 00187 uint32_t new_id = getu32FromBuf(&Radio::radio.rx_buf[*Idx]); 00188 *Idx += 4; 00189 /* new device not attached directly to me, but to a downstream device attached to me */ 00190 add_new_downstream_attached(sendingID, new_id); 00191 00192 /* ack sent first downstream, then (if we;re not a gateway) newDeviceNotification sent upstream */ 00193 00194 #ifdef GATEWAY 00195 reqFlags.bits.txAns = ANSWER_OK; 00196 #else 00197 if (id_newDeviceNotification == ID_NONE) { 00198 reqFlags.bits.txAns = ANSWER_OK; 00199 id_newDeviceNotification = new_id; 00200 } else 00201 reqFlags.bits.txAns = ANSWER_BUSY; 00202 #endif /* !GATEWAY */ 00203 } else if (cmd == CMD_USER_PAYLOAD_UP_REQ) { // rxDone callback, pkt from downstream 00204 uint8_t len; 00205 uint32_t originating_src_id = getu32FromBuf(&Radio::radio.rx_buf[*Idx]); 00206 *Idx += 4; 00207 len = Radio::radio.rx_buf[*Idx]; 00208 (*Idx)++; 00209 #ifdef GATEWAY 00210 //gateway_uplink(len, originating_src_id, &Radio::radio.rx_buf[*Idx]); 00211 up->rxBufIdx = *Idx; 00212 up->originating_src_id = originating_src_id; 00213 up->len = len; 00214 reqFlags.bits.txAns = ANSWER_OK; 00215 #else 00216 if (fwd.len == -1) { 00217 fwd.len = len; 00218 fwd.B_id = originating_src_id; 00219 fwd.tx_dest_id = attUp.id; 00220 memcpy(fwd.buf, &Radio::radio.rx_buf[*Idx], len); 00221 reqFlags.bits.currentOp = CMD_USER_PAYLOAD_UP_REQ; // this is uplink 00222 reqFlags.bits.txAns = ANSWER_OK; 00223 // txBuf_send() (for forwarding) will be called after ANS sent 00224 } else 00225 reqFlags.bits.txAns = ANSWER_BUSY; 00226 00227 #endif 00228 (*Idx) += len; 00229 } else if (cmd == CMD_DOWNSTREAM_NOT_RESPONDING) { // rxDone callback, pkt from downstream 00230 #ifndef GATEWAY 00231 uint32_t reporting_id = getu32FromBuf(&Radio::radio.rx_buf[*Idx]); 00232 #endif /* !reporting_id */ 00233 *Idx += 4; 00234 #ifndef GATEWAY 00235 uint32_t device_not_respoding_id = getu32FromBuf(&Radio::radio.rx_buf[*Idx]); 00236 #endif /* !reporting_id */ 00237 *Idx += 4; 00238 #ifdef GATEWAY 00239 reqFlags.bits.txAns = ANSWER_OK; 00240 #else 00241 if (notResponding.reporting_id == ID_NONE) { 00242 reqFlags.bits.currentOp = CMD_DOWNSTREAM_NOT_RESPONDING; 00243 notResponding.reporting_id = reporting_id; 00244 notResponding.device_not_respoding_id = device_not_respoding_id; 00245 reqFlags.bits.txAns = ANSWER_OK; 00246 } else 00247 reqFlags.bits.txAns = ANSWER_BUSY; 00248 #endif /* !GATEWAY */ 00249 } 00250 00251 } // ..downstream_req_rxDoneCB() 00252
Generated on Fri Jul 15 2022 20:28:20 by 1.7.2