wayne roberts / Mbed OS lr1110_wifi_geolocation_gateway

Dependencies:   mbed-http lr1110 sx12xx_hal

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "main.h"
00002 #include "network-helper.h"
00003 #include "radio.h"
00004 
00005 #define TX_DBM              20
00006 #define BW_KHZ              500
00007 #define SPREADING_FACTOR    11
00008 #define CF_HZ               919000000
00009 
00010 /* geolocation provider wont operate with less than 3 wifi access points */
00011 #define MINIMUM_REQUIRED_ACCESS_POINTS      2
00012 
00013 bool wifiResultFormatBasic;
00014 
00015 struct location {
00016     float lat, lng;
00017     int accuracy;
00018 };
00019 
00020 typedef struct {
00021     const char* const cmd;
00022     void (*handler)(uint8_t args_at);
00023     const char* const arg_descr;
00024     const char* const description;
00025 } menu_item_t;
00026 
00027 EventQueue queue(4 * EVENTS_EVENT_SIZE);
00028 
00029 RawSerial pc(USBTX, USBRX, MBED_CONF_PLATFORM_STDIO_BAUD_RATE); // speed from mbed_app.json
00030 char pcbuf[64];
00031 int pcbuf_len;
00032 
00033 NetworkInterface* network;
00034 
00035 event_callback_t    serialEventCb;
00036 
00037 uint8_t wifiScan_buf[9];
00038 uint64_t wifi_start_at, wifi_scan_dur;
00039 bool post_enable;
00040 bool send_reply;
00041 
00042 void cmd_help(uint8_t);
00043 
00044 struct location geoloc_result;
00045 
00046 uint8_t remote_chip_eui[8];
00047 
00048 struct wifidr {
00049     const char *txt;
00050     float Mbps;
00051 };
00052 
00053 const struct wifidr wifiDatarates[] = {
00054     /*   0 */ { NULL, 0},
00055     /*   1 */ { "DBPSK", 1},
00056     /*   2 */ { "DQPSK", 2},
00057     /*   3 */ { "BPSK", 6},
00058     /*   4 */ { "BPSK", 9},
00059     /*   5 */ { "QPSK", 12},
00060     /*   6 */ { "QPSK", 18},
00061     /*   7 */ { "16-QAM", 24},
00062     /*   8 */ { "16-QAM", 36},
00063     /*   9 */ { "(9)", 0},
00064     /*  10 */ { "(10)", 0},
00065     /*  11 */ { "BPSK", 6.5},
00066     /*  12 */ { "QPSK", 13},
00067     /*  13 */ { "QPSK", 19.5},
00068     /*  14 */ { "16-QAM", 26},
00069     /*  15 */ { "16-QAM", 39},
00070     /*  16 */ { "(16)", 0},
00071     /*  17 */ { "(17)", 0},
00072     /*  18 */ { "(18)", 0},
00073     /*  19 */ { "BPSK", 7.2},
00074     /*  20 */ { "QPSK", 14.4},
00075     /*  21 */ { "QPSK", 21.7},
00076     /*  22 */ { "16-QAM", 28.9},
00077     /*  23 */ { "16-QAM", 43.3},
00078 };
00079 
00080 char json[1536];
00081 
00082 void dump_response(HttpResponse* res)
00083 {
00084     printf("Status: %d - %s\n", res->get_status_code(), res->get_status_message().c_str());
00085 
00086     printf("Headers:\n");
00087     for (size_t ix = 0; ix < res->get_headers_length(); ix++) {
00088         printf("\t%s: %s\n", res->get_headers_fields()[ix]->c_str(), res->get_headers_values()[ix]->c_str());
00089     }
00090     printf("\nBody (%lu bytes):\n\n%s\n", res->get_body_length(), res->get_body_as_string().c_str());
00091 }
00092 
00093 void cfg_lora()
00094 {
00095     Radio::LoRaModemConfig(BW_KHZ, SPREADING_FACTOR, 1);
00096     Radio::SetChannel(CF_HZ);
00097     Radio::set_tx_dbm(TX_DBM);
00098                // preambleLen, fixLen, crcOn, invIQ
00099     Radio::LoRaPacketConfig(8, false, true, false);
00100 }
00101 
00102 void cmd_wifi_scan(uint8_t idx)
00103 {
00104     Radio::radio.xfer(OPCODE_WIFI_SCAN, 9, 0, wifiScan_buf);
00105     wifi_start_at = Kernel::get_ms_count();
00106     printf("wifiScan...\r\n");
00107 
00108     post_enable = pcbuf[idx] == 'p';
00109     send_reply = false;
00110 }
00111 
00112 /* List of trusted root CA certificates
00113  * currently two: Amazon, the CA for os.mbed.com and Let's Encrypt, the CA for httpbin.org
00114  *
00115  * To add more root certificates, just concatenate them.
00116  */
00117 const char HTTBIN_ORG_SSL_CA_PEM[] =  "-----BEGIN CERTIFICATE-----\n"
00118     "MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\n"
00119     "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n"
00120     "b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\n"
00121     "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\n"
00122     "b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\n"
00123     "ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\n"
00124     "9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\n"
00125     "IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\n"
00126     "VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\n"
00127     "93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\n"
00128     "jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
00129     "AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\n"
00130     "A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\n"
00131     "U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\n"
00132     "N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\n"
00133     "o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\n"
00134     "5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\n"
00135     "rqXRfboQnoZsG4q5WTP468SQvvG5\n"
00136     "-----END CERTIFICATE-----\n"
00137     "-----BEGIN CERTIFICATE-----\n"
00138     "MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\n"
00139     "MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n"
00140     "DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\n"
00141     "SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\n"
00142     "GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\n"
00143     "AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\n"
00144     "q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\n"
00145     "SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\n"
00146     "Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\n"
00147     "a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\n"
00148     "/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\n"
00149     "AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\n"
00150     "CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\n"
00151     "bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\n"
00152     "c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\n"
00153     "VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\n"
00154     "ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\n"
00155     "MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\n"
00156     "Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\n"
00157     "AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\n"
00158     "uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\n"
00159     "wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\n"
00160     "X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\n"
00161     "PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\n"
00162     "KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\n"
00163     "-----END CERTIFICATE-----\n";
00164 
00165 
00166 void cmd_httpbin_post(uint8_t idx)
00167 {
00168     const char body[] = "{\"hello\":\"world\"}";
00169 
00170 #if DEMO == DEMO_HTTPS
00171     printf("\n----- HTTPS POST request -----\n");
00172     HttpsRequest* post_req = new HttpsRequest(network, HTTBIN_ORG_SSL_CA_PEM, HTTP_POST, "https://httpbin.org/post");
00173 #elif DEMO == DEMO_HTTP
00174     printf("\n----- HTTP POST request -----\n");
00175     HttpRequest* post_req = new HttpRequest(network, HTTP_POST, "http://httpbin.org/post");
00176 #endif
00177 
00178     post_req->set_header("Content-Type", "application/json");
00179 
00180     HttpResponse* post_res = post_req->send(body, strlen(body));
00181     if (!post_res) {
00182         printf("HttpRequest failed (error code %d)\n", post_req->get_error());
00183         return;
00184     }
00185 
00186     dump_response(post_res);
00187     delete post_req;
00188 }
00189 
00190 
00191 void cmd_print_status(uint8_t idx)
00192 {
00193     stat_t stat;
00194     uint8_t buf[4];
00195     printf("[NWKH] IP address: %s\n", network->get_ip_address());
00196 
00197     stat.word = Radio::radio.xfer(OPCODE_GET_VERSION, 0, 0, NULL);
00198     stat.word = Radio::radio.xfer(0x0000, 0, 4, buf);
00199     if (stat.bits.cmdStatus == CMD_DAT) {
00200         printf("LR1110 chip:%02x use:%02x fw-v%u.%u\r\n",
00201             buf[0], /* silicon rev */
00202             buf[1], /* use case */
00203             buf[2], /* firmware major */
00204             buf[3]  /* firmware minor */
00205         );
00206     }
00207 
00208     stat.word = Radio::radio.xfer(OPCODE_GET_STATUS, 4, 0, buf);
00209     printf("chipMode:%d, cmdStatus:%d\r\n", stat.bits.chipMode, stat.bits.cmdStatus);
00210 }
00211 
00212 const menu_item_t menu_items[] = 
00213 {
00214     { "phb", cmd_httpbin_post, "","test post to httpbin.org"},
00215     { "ws", cmd_wifi_scan, "","local wifi scan"},
00216     { ".", cmd_print_status, "","print status"},
00217     { "?", cmd_help, "","this list of commands"},
00218     { NULL, NULL, NULL, NULL }
00219 };
00220 
00221 void
00222 console()
00223 {
00224     int i;
00225     uint8_t user_cmd_len;
00226 
00227     if (pcbuf_len < 0) {
00228         printf("abort\r\n");
00229         pcbuf_len = 0;
00230         return;
00231     }
00232 
00233     printf("\r\n");
00234 
00235     if (pcbuf_len > 0) {
00236         /* get end of user-entered command */
00237         user_cmd_len = 1;   // first character can be any character
00238         for (i = 1; i <= pcbuf_len; i++) {
00239             if (pcbuf[i] < 'A' || (pcbuf[i] > 'Z' && pcbuf[i] < 'a') || pcbuf[i] > 'z') {
00240                 user_cmd_len = i;
00241                 break;
00242             }
00243         }
00244 
00245      
00246         for (i = 0; menu_items[i].cmd != NULL ; i++) {
00247             int mi_len = strlen(menu_items[i].cmd);
00248             if (menu_items[i].handler && user_cmd_len == mi_len && (strncmp(pcbuf, menu_items[i].cmd, mi_len) == 0)) {
00249                 while (pcbuf[mi_len] == ' ')   // skip past spaces
00250                     mi_len++;
00251                 menu_items[i].handler(mi_len);
00252                 break;
00253             }
00254         }
00255     }
00256    
00257     pcbuf_len = 0;
00258     printf("> ");
00259     fflush(stdout); 
00260 }
00261 
00262 void echo(char c)
00263 {
00264     if (c == 8) {
00265         pc.putc(8);
00266         pc.putc(' ');
00267         pc.putc(8);
00268     } else
00269         pc.putc(c);
00270 }
00271 
00272 uint8_t serial_rx_buf;
00273 
00274 void serialCb(int events)
00275 {
00276     if (events & SERIAL_EVENT_RX_COMPLETE) {
00277         char c = serial_rx_buf;
00278         static uint8_t pcbuf_idx = 0;
00279         static uint8_t prev_len = 0;;
00280         if (c == 8) {
00281             if (pcbuf_idx > 0) {
00282                 queue.call(echo, 8);
00283                 pcbuf_idx--;
00284             }
00285         } else if (c == 3) {    // ctrl-C
00286             pcbuf_len = -1;
00287             queue.call(console);
00288         } else if (c == '\r') {
00289             if (pcbuf_idx == 0) {
00290                 pcbuf_len = prev_len;
00291             } else {
00292                 pcbuf[pcbuf_idx] = 0;   // null terminate
00293                 prev_len = pcbuf_idx;
00294                 pcbuf_idx = 0;
00295                 pcbuf_len = prev_len;
00296             }
00297             queue.call(console);
00298         } else if (pcbuf_idx < sizeof(pcbuf)) {
00299             pcbuf[pcbuf_idx++] = c;
00300             queue.call(echo, c);
00301         }
00302     }
00303 
00304     if (pc.read(&serial_rx_buf, 1, serialCb) != 0)
00305         printf("Serial-Read-Fail\r\n");
00306 }
00307 
00308 void cmd_help(uint8_t args_at)
00309 {
00310     int i;
00311     
00312     for (i = 0; menu_items[i].cmd != NULL ; i++) {
00313         printf("%s%s\t%s\r\n", menu_items[i].cmd, menu_items[i].arg_descr, menu_items[i].description);
00314     }
00315 }
00316 
00317 
00318 void print_wifi_result(const uint8_t *result)
00319 {
00320     char out[96];
00321     char str[24];
00322     unsigned n, macStart;
00323     wifiType_t wt;
00324     wifiChanInfo_t ci;
00325     wt.octet = result[0];
00326     ci.octet = result[1];
00327     out[0] = 0;
00328     strcat(out, "802.11");
00329     switch (wt.bits.signal) {
00330         case 1: strcat(out, "b"); break;
00331         case 2: strcat(out, "g"); break;
00332         case 3: strcat(out, "n"); break;
00333     }
00334     sprintf(str, " %s %.1fMbps", wifiDatarates[wt.bits.datarate].txt, wifiDatarates[wt.bits.datarate].Mbps);
00335     strcat(out, str);
00336     strcat(out, " ");
00337 
00338     sprintf(str, "ch%u ", ci.bits.channelID);
00339     strcat(out, str);
00340     switch (ci.bits.channelID) {
00341         // table 10-5
00342     }
00343     strcat(out, " ");
00344     sprintf(str, "mv:%u ", ci.bits.macValidationID);
00345     strcat(out, str);
00346     switch (ci.bits.macValidationID) {
00347         case 1: strcat(out, "gateway"); break;
00348         case 2: strcat(out, "phone"); break;
00349         case 3: strcat(out, "?"); break;
00350         // table 10.8
00351     }
00352 
00353     strcat(out, " ");
00354 
00355     if (wifiResultFormatBasic) {
00356         macStart = 3;
00357     } else {
00358         macStart = 4;
00359     }
00360     for (n = 0; n < 6; n++) {
00361         sprintf(str, "%02x", result[n+macStart]);
00362         strcat(out, str);
00363         if (n < 5)
00364             strcat(out, ":");
00365     }
00366 
00367     sprintf(str, " rssi:%d ", (int8_t)result[2]);
00368     strcat(out, str);
00369 
00370     if (!wifiResultFormatBasic) {
00371         sprintf(str, "frameCtrl:%02x ", result[3]);
00372         strcat(out, str);
00373     }
00374     printf("%s\r\n", out);
00375 }
00376 
00377 void take_result()
00378 {
00379     printf("result %f, %f, %d\r\n", 
00380         geoloc_result.lat,
00381         geoloc_result.lng,
00382         geoloc_result.accuracy
00383     );
00384 
00385     /* TODO: store result to database and show on map */
00386 
00387     if (send_reply) {
00388         unsigned len;
00389         memcpy(Radio::radio.tx_buf, remote_chip_eui, 8);
00390         Radio::radio.tx_buf[8] = 0; // rfu
00391         Radio::radio.tx_buf[9] = 0; // rfu
00392         len = sprintf((char*)(Radio::radio.tx_buf + HEADER_LENGTH), "%f, %f, %u",
00393             geoloc_result.lat,
00394             geoloc_result.lng,
00395             geoloc_result.accuracy
00396         );
00397         Radio::Send(len + HEADER_LENGTH, 0, 0, 0);   /* begin transmission */
00398         send_reply = false; // sent
00399     }
00400 }
00401 
00402 void service()
00403 {
00404     irq_t irq;
00405     irq.dword = Radio::radio.service();
00406     if (irq.bits.WifiDone) {
00407         stat_t stat;
00408         uint8_t nbResults;
00409         json_start();
00410         stat.word = Radio::radio.xfer(OPCODE_GET_WIFI_NB_RESULTS, 0, 0, NULL);
00411         stat.word = Radio::radio.xfer(0x0000, 0, 1, &nbResults);
00412         if (stat.bits.cmdStatus == CMD_DAT) {
00413             unsigned n;
00414             printf("%ums nbResults:%u\r\n", (unsigned)wifi_scan_dur, nbResults);
00415             for (n = 0; n < nbResults; n++) {
00416                 uint8_t buf[3];
00417                 uint8_t resultBuf[22];
00418                 buf[0] = n;
00419                 buf[1] = 1; // number of results in this read
00420                 buf[2] = wifiResultFormatBasic ? 4 : 1;
00421                 stat.word = Radio::radio.xfer(OPCODE_WIFI_READ_RESULTS, 3, 0, buf);
00422                 // basic =  9byte length
00423                 // full  = 22byte length
00424                 stat.word = Radio::radio.xfer(0x0000, 0, wifiResultFormatBasic ? 9 : 22, resultBuf);
00425                 if (stat.bits.cmdStatus == CMD_DAT) {
00426                     wifiChanInfo_t ci;
00427                     print_wifi_result(resultBuf);
00428                     ci.octet = resultBuf[1];
00429                     if (ci.bits.macValidationID == 1)   // 1 is AP
00430                         wifi_result_to_json(n == 0, resultBuf, wifiResultFormatBasic ? 3 : 4, 2);
00431                 } else
00432                     printf("readResult:%s\r\n", Radio::radio.cmdStatus_toString(stat.bits.cmdStatus));
00433             }
00434         }
00435         json_end();
00436         //printf("JSON %s\r\n", json);
00437         if (post_enable) {
00438             printf("post_enabled\r\n");
00439             if (nbResults > MINIMUM_REQUIRED_ACCESS_POINTS) {
00440                 post_scan_result(json, &geoloc_result.lat, &geoloc_result.lng, &geoloc_result.accuracy);
00441                 queue.call(take_result);
00442             } else
00443                 printf("only %u access points\r\n", nbResults);
00444         }
00445 
00446         cfg_lora();
00447         Radio::Rx(0);
00448     } // ..if (irq.bits.WifiDone)
00449 }
00450 
00451 void radio_irq_handler()
00452 {
00453     wifi_scan_dur = Kernel::get_ms_count() - wifi_start_at;
00454     queue.call(service);
00455 }
00456 
00457 void txDoneCB()
00458 {
00459     Radio::Rx(0);
00460 }
00461 
00462 void parse_remote_wifi_scan(uint8_t pktLen)
00463 {
00464     uint8_t ap_cnt = 0;
00465     uint8_t pkt_idx = HEADER_LENGTH;
00466     json_start();
00467     while (pkt_idx < pktLen) {
00468         wifi_result_to_json(pkt_idx == HEADER_LENGTH, Radio::radio.rx_buf + pkt_idx, 0, 6);
00469         if (strlen(json) >= sizeof(json)) {
00470             printf("json-overrun\r\n");
00471             return;
00472         }
00473         pkt_idx += 7;
00474         ap_cnt++;
00475     }
00476     json_end();
00477 
00478     if (ap_cnt > MINIMUM_REQUIRED_ACCESS_POINTS) {
00479         post_scan_result(json, &geoloc_result.lat, &geoloc_result.lng, &geoloc_result.accuracy);
00480         queue.call(take_result);
00481     } else
00482         printf("only %u access points\r\n", ap_cnt);
00483 
00484     send_reply = true;
00485 }
00486 
00487 void rxDoneCB(uint8_t size, float rssi, float snr)
00488 {
00489     unsigned i;
00490     printf("%.1fdBm  snr:%.1fdB\t", rssi, snr);
00491 
00492     for (i = 0; i < size; i++) {
00493         printf("%02x ", Radio::radio.rx_buf[i]);
00494     }
00495     printf("\r\n");
00496 
00497     for (i = 0; i < 8; i++)
00498         remote_chip_eui[i] = Radio::radio.rx_buf[i];
00499 
00500     parse_remote_wifi_scan(size);
00501 }
00502 
00503 const RadioEvents_t rev = {
00504     /* Dio0_top_half */     radio_irq_handler,
00505     /* TxDone_topHalf */    NULL,
00506     /* TxDone_botHalf */    txDoneCB,
00507     /* TxTimeout  */        NULL,
00508     /* RxDone  */           rxDoneCB,
00509     /* RxTimeout  */        NULL,
00510     /* RxError  */          NULL,
00511     /* FhssChangeChannel  */NULL,
00512     /* CadDone  */          NULL
00513 };
00514 
00515 int main()
00516 {
00517     {   /* wifi scan defaults, see LR1110 user manual section 10.2 */
00518         unsigned chanmask = 0x0421; // ch1, ch6, ch11
00519         unsigned timeout = 105; // in milliseconds, 100 wifi TUs (beacon interval)
00520 
00521         wifiScan_buf[0] = 0x01; // wifi type
00522         wifiScan_buf[2] = chanmask; // chanmask-lo
00523         chanmask >>= 8;
00524         wifiScan_buf[1] = chanmask; // chanmask-hi
00525         wifiScan_buf[3] = 0x02; // acqMode
00526         wifiScan_buf[4] = 0x0a; // NbMaxRes
00527         wifiScan_buf[5] = 0x10; // NbScanPerChan
00528         wifiScan_buf[7] = timeout; // Timeout-lo
00529         timeout >>= 8;
00530         wifiScan_buf[6] = timeout; // Timeout-hi
00531         wifiScan_buf[8] = 0x00; // AbortOnTimeout
00532     }
00533 
00534     serialEventCb = serialCb;
00535 
00536     if (pc.read(&serial_rx_buf, 1, serialCb) != 0)
00537         printf("serial-read-fail\r\n");
00538 
00539     // Connect to the network with the default networking interface
00540     // if you use WiFi: see mbed_app.json for the credentials
00541     network = connect_to_default_network_interface();
00542     if (!network) {
00543         printf("Cannot connect to the network, see serial output\n");
00544         return 1;
00545     }
00546 
00547     Radio::Init(&rev);
00548 
00549     Radio::Standby();
00550     cfg_lora();
00551     Radio::Rx(0);
00552 
00553     queue.dispatch();
00554 }
00555