Scan nearby anchors and send result for location engine.

Dependencies:   modem_ref_helper DebouncedInterrupt

Committer:
Jeej
Date:
Wed Nov 13 13:40:28 2019 +0000
Revision:
0:83836029943b
Child:
1:4534345afb6b
First version.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jeej 0:83836029943b 1 // @autor: jeremie@wizzilab.com
Jeej 0:83836029943b 2 // @date: 2017-05-02
Jeej 0:83836029943b 3
Jeej 0:83836029943b 4 #include "DebouncedInterrupt.h"
Jeej 0:83836029943b 5 #include "modem_ref_helper.h"
Jeej 0:83836029943b 6 #include "modem_callbacks.h"
Jeej 0:83836029943b 7 #include "files.h"
Jeej 0:83836029943b 8
Jeej 0:83836029943b 9 Semaphore button_user(0);
Jeej 0:83836029943b 10 Semaphore modem_ready(0);
Jeej 0:83836029943b 11 Semaphore user_ready(0);
Jeej 0:83836029943b 12 Queue<void, 8> modem_resp;
Jeej 0:83836029943b 13
Jeej 0:83836029943b 14 enum {
Jeej 0:83836029943b 15 MODEM_RESP_NO,
Jeej 0:83836029943b 16 MODEM_RESP_TERMINAL,
Jeej 0:83836029943b 17 MODEM_RESP_ERROR,
Jeej 0:83836029943b 18 MODEM_RESP_ACK,
Jeej 0:83836029943b 19 MODEM_RESP_TIMEOUT,
Jeej 0:83836029943b 20 };
Jeej 0:83836029943b 21
Jeej 0:83836029943b 22 alp_d7a_itf_t report_itf = {
Jeej 0:83836029943b 23 .type = ALP_ITF_TYPE_D7A,
Jeej 0:83836029943b 24 .cfg.to = 0,
Jeej 0:83836029943b 25 .cfg.te = 0,
Jeej 0:83836029943b 26 .cfg.qos.bf.resp = D7A_RESP_PREFERRED,
Jeej 0:83836029943b 27 .cfg.qos.bf.retry = ALP_RPOL_ONESHOT,
Jeej 0:83836029943b 28 .cfg.addressee.ctrl.bf.nls = D7A_NLS_AES_CCM_64,
Jeej 0:83836029943b 29 .cfg.addressee.ctrl.bf.idf = D7A_ID_NOID,
Jeej 0:83836029943b 30 .cfg.addressee.xcl.bf = {.s = 2, .m = 0x1},
Jeej 0:83836029943b 31 };
Jeej 0:83836029943b 32
Jeej 0:83836029943b 33 alp_d7a_itf_t scan_itf = {
Jeej 0:83836029943b 34 .type = ALP_ITF_TYPE_D7A,
Jeej 0:83836029943b 35 .cfg.to = 0,
Jeej 0:83836029943b 36 .cfg.te = 0,
Jeej 0:83836029943b 37 .cfg.qos.bf.resp = D7A_RESP_ALL,
Jeej 0:83836029943b 38 .cfg.qos.bf.retry = ALP_RPOL_ONESHOT,
Jeej 0:83836029943b 39 .cfg.addressee.ctrl.bf.nls = D7A_NLS_AES_CCM_64,
Jeej 0:83836029943b 40 .cfg.addressee.ctrl.bf.idf = D7A_ID_NBID,
Jeej 0:83836029943b 41 .cfg.addressee.xcl.bf = {.s = 2, .m = 0x1},// XXX D7A_XCL_GW,
Jeej 0:83836029943b 42 .cfg.addressee.id[0] = D7A_CTF_ENCODE(8),
Jeej 0:83836029943b 43 };
Jeej 0:83836029943b 44
Jeej 0:83836029943b 45 // Main Callback
Jeej 0:83836029943b 46 void my_main_callback(uint8_t terminal, int8_t err, uint8_t id)
Jeej 0:83836029943b 47 {
Jeej 0:83836029943b 48 (void)id;
Jeej 0:83836029943b 49
Jeej 0:83836029943b 50 if (ALP_ERR_NONE != err)
Jeej 0:83836029943b 51 {
Jeej 0:83836029943b 52 modem_print_error(ALP_ITF_TYPE_D7A, err);
Jeej 0:83836029943b 53 }
Jeej 0:83836029943b 54
Jeej 0:83836029943b 55 if (terminal)
Jeej 0:83836029943b 56 {
Jeej 0:83836029943b 57 modem_ready.release();
Jeej 0:83836029943b 58 }
Jeej 0:83836029943b 59 }
Jeej 0:83836029943b 60
Jeej 0:83836029943b 61 // Response Callback
Jeej 0:83836029943b 62 void my_response_callback(uint8_t terminal, int8_t err, uint8_t id)
Jeej 0:83836029943b 63 {
Jeej 0:83836029943b 64 (void)id;
Jeej 0:83836029943b 65
Jeej 0:83836029943b 66 if (ALP_ERR_NONE != err)
Jeej 0:83836029943b 67 {
Jeej 0:83836029943b 68 modem_print_error(ALP_ITF_TYPE_D7A, err);
Jeej 0:83836029943b 69 }
Jeej 0:83836029943b 70
Jeej 0:83836029943b 71 if (terminal)
Jeej 0:83836029943b 72 {
Jeej 0:83836029943b 73 modem_resp.put((void*)MODEM_RESP_TERMINAL);
Jeej 0:83836029943b 74 }
Jeej 0:83836029943b 75 else
Jeej 0:83836029943b 76 {
Jeej 0:83836029943b 77 if (ALP_ERR_NONE == err)
Jeej 0:83836029943b 78 {
Jeej 0:83836029943b 79 modem_resp.put((void*)MODEM_RESP_ACK);
Jeej 0:83836029943b 80 }
Jeej 0:83836029943b 81 else
Jeej 0:83836029943b 82 {
Jeej 0:83836029943b 83 modem_resp.put((void*)MODEM_RESP_ERROR);
Jeej 0:83836029943b 84 }
Jeej 0:83836029943b 85 }
Jeej 0:83836029943b 86
Jeej 0:83836029943b 87 // Wait end of user processing before resuming
Jeej 0:83836029943b 88 user_ready.acquire();
Jeej 0:83836029943b 89 }
Jeej 0:83836029943b 90
Jeej 0:83836029943b 91 // Interrupt Service Routine on button press.
Jeej 0:83836029943b 92 void button_push_isr( void )
Jeej 0:83836029943b 93 {
Jeej 0:83836029943b 94 button_user.release();
Jeej 0:83836029943b 95 }
Jeej 0:83836029943b 96
Jeej 0:83836029943b 97 void button_user_thread()
Jeej 0:83836029943b 98 {
Jeej 0:83836029943b 99 osEvent evt;
Jeej 0:83836029943b 100 uint32_t resp;
Jeej 0:83836029943b 101 d7a_sp_res_t istat;
Jeej 0:83836029943b 102 fw_version_t fw_ver;
Jeej 0:83836029943b 103 uint8_t nb = 0;
Jeej 0:83836029943b 104
Jeej 0:83836029943b 105 uint8_t id = modem_get_id(my_response_callback);
Jeej 0:83836029943b 106 uint8_t main_id = modem_get_id(my_main_callback);
Jeej 0:83836029943b 107
Jeej 0:83836029943b 108 memset(&istat, 0, sizeof(d7a_sp_res_t));
Jeej 0:83836029943b 109 memset(&fw_ver, 0, sizeof(fw_version_t));
Jeej 0:83836029943b 110
Jeej 0:83836029943b 111 while (true)
Jeej 0:83836029943b 112 {
Jeej 0:83836029943b 113 // Wait for button press
Jeej 0:83836029943b 114 PRINT("Press button to scan...\r\n");
Jeej 0:83836029943b 115 button_user.acquire();
Jeej 0:83836029943b 116
Jeej 0:83836029943b 117 nb = 0;
Jeej 0:83836029943b 118
Jeej 0:83836029943b 119 PRINT("Scanning...\n");
Jeej 0:83836029943b 120
Jeej 0:83836029943b 121 // Any broadcast with response is fine
Jeej 0:83836029943b 122 modem_remote_read_file((uint8_t*)&scan_itf, D7_ITF_SIZE(&scan_itf), (void*)&istat, D7A_FID_FIRMWARE_VERSION, (void*)&fw_ver, 12, sizeof(fw_version_t), id);
Jeej 0:83836029943b 123
Jeej 0:83836029943b 124 do
Jeej 0:83836029943b 125 {
Jeej 0:83836029943b 126 // Wait for callback
Jeej 0:83836029943b 127 evt = modem_resp.get(3000);
Jeej 0:83836029943b 128 resp = (evt.status == osEventMessage)? (uint32_t)evt.value.p : MODEM_RESP_TIMEOUT;
Jeej 0:83836029943b 129
Jeej 0:83836029943b 130 if (MODEM_RESP_ACK == resp)
Jeej 0:83836029943b 131 {
Jeej 0:83836029943b 132 // Print metadata
Jeej 0:83836029943b 133 nb++;
Jeej 0:83836029943b 134 PRINT("%d: XCL:%02X ", nb, istat.addressee.xcl.byte);
Jeej 0:83836029943b 135 PRINT_DATA("UID:", "%02X", istat.addressee.id, D7A_UID_LEN, " ");
Jeej 0:83836029943b 136 PRINT("snr:%d rxlev:%d lb:%d ", istat.snr, istat.rxlev, istat.lb);
Jeej 0:83836029943b 137 PRINT("v%d.%d.%d\n", fw_ver.major, fw_ver.minor, fw_ver.patch);
Jeej 0:83836029943b 138
Jeej 0:83836029943b 139 // Fill file
Jeej 0:83836029943b 140 if (nb <= STATUS_MAX_DEVICES)
Jeej 0:83836029943b 141 {
Jeej 0:83836029943b 142 // Update number of devices
Jeej 0:83836029943b 143 ram_fs_write(FID_STATUS, 0, sizeof(uint8_t), &nb);
Jeej 0:83836029943b 144 // Add new Link budget
Jeej 0:83836029943b 145 ram_fs_write(FID_STATUS, sizeof(uint8_t) + ((nb-1) * sizeof(device_t)), sizeof(uint8_t), &istat.lb);
Jeej 0:83836029943b 146 // Add new UID
Jeej 0:83836029943b 147 ram_fs_write(FID_STATUS, sizeof(uint8_t) + ((nb-1) * sizeof(device_t)) + sizeof(uint8_t), D7A_UID_LEN, istat.addressee.id);
Jeej 0:83836029943b 148 }
Jeej 0:83836029943b 149
Jeej 0:83836029943b 150 // Clear istatus buffer
Jeej 0:83836029943b 151 memset(&istat, 0, sizeof(d7a_sp_res_t));
Jeej 0:83836029943b 152
Jeej 0:83836029943b 153 // Resume processing
Jeej 0:83836029943b 154 user_ready.release();
Jeej 0:83836029943b 155 }
Jeej 0:83836029943b 156 else if (MODEM_RESP_TIMEOUT == resp)
Jeej 0:83836029943b 157 {
Jeej 0:83836029943b 158 // Could be because of the RF duty cycle,
Jeej 0:83836029943b 159 // especialy after boot where the duty credit is near 0.
Jeej 0:83836029943b 160 // The only thing to do is wait.
Jeej 0:83836029943b 161 // The transmission will resume once some duty credit is available.
Jeej 0:83836029943b 162 PRINT("WAITING...\n");
Jeej 0:83836029943b 163 }
Jeej 0:83836029943b 164 else if (MODEM_RESP_ERROR == resp)
Jeej 0:83836029943b 165 {
Jeej 0:83836029943b 166 PRINT("ERROR.\n");
Jeej 0:83836029943b 167
Jeej 0:83836029943b 168 // Resume processing
Jeej 0:83836029943b 169 user_ready.release();
Jeej 0:83836029943b 170 }
Jeej 0:83836029943b 171 else if (MODEM_RESP_TERMINAL == resp)
Jeej 0:83836029943b 172 {
Jeej 0:83836029943b 173 PRINT("DONE.\n");
Jeej 0:83836029943b 174
Jeej 0:83836029943b 175 // Resume processing
Jeej 0:83836029943b 176 user_ready.release();
Jeej 0:83836029943b 177 }
Jeej 0:83836029943b 178
Jeej 0:83836029943b 179 } while (MODEM_RESP_TERMINAL != resp);
Jeej 0:83836029943b 180
Jeej 0:83836029943b 181 // Send list
Jeej 0:83836029943b 182 status_t status;
Jeej 0:83836029943b 183 ram_fs_read(FID_STATUS, 0, sizeof(uint8_t), (uint8_t*)&status.nb);
Jeej 0:83836029943b 184 ram_fs_read(FID_STATUS, 0, sizeof(uint8_t) + (status.nb * sizeof(device_t)), (uint8_t*)&status);
Jeej 0:83836029943b 185 modem_send_file_content((uint8_t*)&report_itf, D7_ITF_SIZE(&report_itf), NULL, FID_STATUS, &status, 0, sizeof(uint8_t) + (status.nb * sizeof(device_t)), main_id);
Jeej 0:83836029943b 186 modem_ready.acquire();
Jeej 0:83836029943b 187 }
Jeej 0:83836029943b 188 }
Jeej 0:83836029943b 189
Jeej 0:83836029943b 190 modem_callbacks_t callbacks = {
Jeej 0:83836029943b 191 .read = my_read,
Jeej 0:83836029943b 192 .write = my_write,
Jeej 0:83836029943b 193 .read_fprop = my_read_fprop,
Jeej 0:83836029943b 194 .flush = my_flush,
Jeej 0:83836029943b 195 .remove = my_delete,
Jeej 0:83836029943b 196 .udata = my_udata,
Jeej 0:83836029943b 197 .lqual = my_lqual,
Jeej 0:83836029943b 198 .ldown = my_ldown,
Jeej 0:83836029943b 199 .reset = my_reset,
Jeej 0:83836029943b 200 .boot = my_boot,
Jeej 0:83836029943b 201 .busy = my_busy,
Jeej 0:83836029943b 202 .itf_busy = NULL,
Jeej 0:83836029943b 203 };
Jeej 0:83836029943b 204
Jeej 0:83836029943b 205
Jeej 0:83836029943b 206 /*** Main function ------------------------------------------------------------- ***/
Jeej 0:83836029943b 207 int main()
Jeej 0:83836029943b 208 {
Jeej 0:83836029943b 209 // Start & initialize
Jeej 0:83836029943b 210 DBG_OPEN(DEBUG_LED);
Jeej 0:83836029943b 211
Jeej 0:83836029943b 212 PRINT("\n"
Jeej 0:83836029943b 213 "-----------------------------------------\n"
Jeej 0:83836029943b 214 "------------- Demo Localisation ---------\n"
Jeej 0:83836029943b 215 "-----------------------------------------\n");
Jeej 0:83836029943b 216
Jeej 0:83836029943b 217 modem_helper_open(&callbacks);
Jeej 0:83836029943b 218
Jeej 0:83836029943b 219 uint8_t id = modem_get_id(my_main_callback);
Jeej 0:83836029943b 220
Jeej 0:83836029943b 221 PRINT("Register Files\n");
Jeej 0:83836029943b 222 // This is a local file. As we want to check the outcome of sending
Jeej 0:83836029943b 223 // this, don't use D7AActP Notification but rather plain ALP ITF Forwarding.
Jeej 0:83836029943b 224 // Declaration just allows remote access.
Jeej 0:83836029943b 225 modem_update_file(FID_STATUS, (alp_file_header_t*)&h_status, (uint8_t*)&f_status);
Jeej 0:83836029943b 226
Jeej 0:83836029943b 227 PRINT("Start D7A Stack\n");
Jeej 0:83836029943b 228 modem_activate_itf(ALP_ITF_TYPE_D7A, 24, 0, ALP_D7A_ISTAT_RESP | ALP_D7A_ISTAT_UNS | ALP_D7A_ISTAT_EOP, true, id);
Jeej 0:83836029943b 229 modem_ready.acquire();
Jeej 0:83836029943b 230
Jeej 0:83836029943b 231 PRINT("Notify Modem Version\n");
Jeej 0:83836029943b 232 modem_notify_file(D7A_FID_FIRMWARE_VERSION, 0, SIZE_HOST_REV, id);
Jeej 0:83836029943b 233 modem_ready.acquire();
Jeej 0:83836029943b 234
Jeej 0:83836029943b 235 PRINT("Notify FW Version\n");
Jeej 0:83836029943b 236 uint8_t default_root_key[16] = DEFAULT_ROOT_KEY;
Jeej 0:83836029943b 237 modem_notify_host_rev(&f_rev, &h_rev, default_root_key);
Jeej 0:83836029943b 238
Jeej 0:83836029943b 239 modem_free_id(id);
Jeej 0:83836029943b 240
Jeej 0:83836029943b 241 DebouncedInterrupt user_interrupt(DEBUG_BUTTON);
Jeej 0:83836029943b 242 user_interrupt.attach(button_push_isr, IRQ_FALL, 500, true);
Jeej 0:83836029943b 243
Jeej 0:83836029943b 244 Thread but_th(osPriorityNormal, 2048, NULL);
Jeej 0:83836029943b 245 osStatus status = but_th.start(button_user_thread);
Jeej 0:83836029943b 246 ASSERT(status == osOK, "Failed to start but thread (err: %d)\r\n", status);
Jeej 0:83836029943b 247
Jeej 0:83836029943b 248 DigitalOut my_led(DEBUG_LED);
Jeej 0:83836029943b 249
Jeej 0:83836029943b 250 // Set main task to lowest priority
Jeej 0:83836029943b 251 osThreadSetPriority(osThreadGetId(), osPriorityLow);
Jeej 0:83836029943b 252 while(true)
Jeej 0:83836029943b 253 {
Jeej 0:83836029943b 254 ThisThread::sleep_for(500);
Jeej 0:83836029943b 255 my_led = !my_led;
Jeej 0:83836029943b 256 }
Jeej 0:83836029943b 257 }