simple example of scanning wifi AP and sending to geolocation resolver on cloud

Dependencies:   mbed-http lr1110 sx12xx_hal

test Wifi geolocation with resolving using HTTP POST.

Use with mbed board with internet access and arduino form factor.
With HTTPS, the RAM requirement is minimum 128Kbytes.

and, use with radio shield for europe
or radio shield for USA
which is programmed with trx firmware from updater tool.

This project presents to user mbed STDIO serial port at 115200bps, which lets you perform wifi access point scan on LR1110 and send the resulting access point list to a geolocation provider on the cloud.

Use the project by itself to run wifi scan on the serial terminal (at 115200bps), or use with lr1110_wifi_geolocation_device to receive wifi list from remote device (over LoRa) to resolve location of that device using gelocation provider on cloud.

On serial terminal, use ? question mark to see list of commands. ws to run wifi scan, or ws p to wifi scan and resolve location with cloud provider via HTTP POST.

project setup

Edit main.h to uncomment which geolocation provider you wish to use, and get API key from them:

notice

This project is not using LoRaWAN, instead just LoRa transceiver directly to geolocation provider

Committer:
Wayne Roberts
Date:
Tue Feb 09 10:49:02 2021 -0800
Revision:
1:4a05f91c9c38
add source files

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wayne Roberts 1:4a05f91c9c38 1 #include "main.h"
Wayne Roberts 1:4a05f91c9c38 2 #if (GEOLOCATION_PROVIDER == GOOGLE)
Wayne Roberts 1:4a05f91c9c38 3 #include "radio.h"
Wayne Roberts 1:4a05f91c9c38 4
Wayne Roberts 1:4a05f91c9c38 5 const char GOOGLE_SSL_CA_PEM[] = "-----BEGIN CERTIFICATE-----\n"
Wayne Roberts 1:4a05f91c9c38 6 "MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G\n"
Wayne Roberts 1:4a05f91c9c38 7 "A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp\n"
Wayne Roberts 1:4a05f91c9c38 8 "Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1\n"
Wayne Roberts 1:4a05f91c9c38 9 "MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG\n"
Wayne Roberts 1:4a05f91c9c38 10 "A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI\n"
Wayne Roberts 1:4a05f91c9c38 11 "hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL\n"
Wayne Roberts 1:4a05f91c9c38 12 "v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8\n"
Wayne Roberts 1:4a05f91c9c38 13 "eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq\n"
Wayne Roberts 1:4a05f91c9c38 14 "tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd\n"
Wayne Roberts 1:4a05f91c9c38 15 "C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa\n"
Wayne Roberts 1:4a05f91c9c38 16 "zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB\n"
Wayne Roberts 1:4a05f91c9c38 17 "mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH\n"
Wayne Roberts 1:4a05f91c9c38 18 "V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n\n"
Wayne Roberts 1:4a05f91c9c38 19 "bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG\n"
Wayne Roberts 1:4a05f91c9c38 20 "3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs\n"
Wayne Roberts 1:4a05f91c9c38 21 "J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO\n"
Wayne Roberts 1:4a05f91c9c38 22 "291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS\n"
Wayne Roberts 1:4a05f91c9c38 23 "ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd\n"
Wayne Roberts 1:4a05f91c9c38 24 "AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7\n"
Wayne Roberts 1:4a05f91c9c38 25 "TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==\n"
Wayne Roberts 1:4a05f91c9c38 26 "-----END CERTIFICATE-----\n";
Wayne Roberts 1:4a05f91c9c38 27
Wayne Roberts 1:4a05f91c9c38 28 char my_copy[128];
Wayne Roberts 1:4a05f91c9c38 29
Wayne Roberts 1:4a05f91c9c38 30 /* parse_json: get result sent from server */
Wayne Roberts 1:4a05f91c9c38 31 void parse_json(const char *body, float *lat, float *lng, int *accuracy)
Wayne Roberts 1:4a05f91c9c38 32 {
Wayne Roberts 1:4a05f91c9c38 33 bool in_location = false;
Wayne Roberts 1:4a05f91c9c38 34 bool get_lat = false;
Wayne Roberts 1:4a05f91c9c38 35 bool get_lng = false;
Wayne Roberts 1:4a05f91c9c38 36 bool get_accuracy = false;
Wayne Roberts 1:4a05f91c9c38 37 unsigned n;
Wayne Roberts 1:4a05f91c9c38 38 strncpy(my_copy, body, sizeof(my_copy));
Wayne Roberts 1:4a05f91c9c38 39 strtok(my_copy, "\"");
Wayne Roberts 1:4a05f91c9c38 40 for (n = 0; n < 10; n++) {
Wayne Roberts 1:4a05f91c9c38 41 char *t = strtok(NULL, "\":");
Wayne Roberts 1:4a05f91c9c38 42 if (!t)
Wayne Roberts 1:4a05f91c9c38 43 break;
Wayne Roberts 1:4a05f91c9c38 44 if (in_location) {
Wayne Roberts 1:4a05f91c9c38 45 if (get_lat) {
Wayne Roberts 1:4a05f91c9c38 46 sscanf(t, "%f", lat);
Wayne Roberts 1:4a05f91c9c38 47 get_lat = false;
Wayne Roberts 1:4a05f91c9c38 48 } else if (get_lng) {
Wayne Roberts 1:4a05f91c9c38 49 sscanf(t, "%f", lng);
Wayne Roberts 1:4a05f91c9c38 50 get_lng = false;
Wayne Roberts 1:4a05f91c9c38 51 }
Wayne Roberts 1:4a05f91c9c38 52 if (strchr(t, '}'))
Wayne Roberts 1:4a05f91c9c38 53 in_location = false;
Wayne Roberts 1:4a05f91c9c38 54 else if (strcmp(t, "lat") == 0)
Wayne Roberts 1:4a05f91c9c38 55 get_lat = true;
Wayne Roberts 1:4a05f91c9c38 56 else if (strcmp(t, "lng") == 0)
Wayne Roberts 1:4a05f91c9c38 57 get_lng = true;
Wayne Roberts 1:4a05f91c9c38 58 } else {
Wayne Roberts 1:4a05f91c9c38 59 if (get_accuracy) {
Wayne Roberts 1:4a05f91c9c38 60 sscanf(t, "%d", accuracy);
Wayne Roberts 1:4a05f91c9c38 61 get_accuracy = false;
Wayne Roberts 1:4a05f91c9c38 62 }
Wayne Roberts 1:4a05f91c9c38 63 if (strcmp(t, "location") == 0)
Wayne Roberts 1:4a05f91c9c38 64 in_location = true;
Wayne Roberts 1:4a05f91c9c38 65 else if (strcmp(t, "accuracy") == 0)
Wayne Roberts 1:4a05f91c9c38 66 get_accuracy = true;
Wayne Roberts 1:4a05f91c9c38 67 }
Wayne Roberts 1:4a05f91c9c38 68 }
Wayne Roberts 1:4a05f91c9c38 69 }
Wayne Roberts 1:4a05f91c9c38 70
Wayne Roberts 1:4a05f91c9c38 71 /*
Wayne Roberts 1:4a05f91c9c38 72 * https://developers.google.com/maps/documentation/geolocation/overview
Wayne Roberts 1:4a05f91c9c38 73 */
Wayne Roberts 1:4a05f91c9c38 74 int post_scan_result(const char *body, float *lat, float *lng, int *accuracy)
Wayne Roberts 1:4a05f91c9c38 75 {
Wayne Roberts 1:4a05f91c9c38 76 HttpsRequest* post_req = new HttpsRequest(network, GOOGLE_SSL_CA_PEM, HTTP_POST, "https://www.googleapis.com/geolocation/v1/geolocate?key=YOUR-API-KEY");
Wayne Roberts 1:4a05f91c9c38 77
Wayne Roberts 1:4a05f91c9c38 78 post_req->set_header("Content-Type", "application/json");
Wayne Roberts 1:4a05f91c9c38 79
Wayne Roberts 1:4a05f91c9c38 80 HttpResponse* post_res = post_req->send(body, strlen(body));
Wayne Roberts 1:4a05f91c9c38 81 if (!post_res) {
Wayne Roberts 1:4a05f91c9c38 82 printf("HttpRequest failed (error code %d)\n", post_req->get_error());
Wayne Roberts 1:4a05f91c9c38 83 return -1;
Wayne Roberts 1:4a05f91c9c38 84 }
Wayne Roberts 1:4a05f91c9c38 85
Wayne Roberts 1:4a05f91c9c38 86 dump_response(post_res);
Wayne Roberts 1:4a05f91c9c38 87 parse_json(post_res->get_body_as_string().c_str(), lat, lng, accuracy);
Wayne Roberts 1:4a05f91c9c38 88 delete post_req;
Wayne Roberts 1:4a05f91c9c38 89
Wayne Roberts 1:4a05f91c9c38 90 return 0;
Wayne Roberts 1:4a05f91c9c38 91 }
Wayne Roberts 1:4a05f91c9c38 92
Wayne Roberts 1:4a05f91c9c38 93 void json_start()
Wayne Roberts 1:4a05f91c9c38 94 {
Wayne Roberts 1:4a05f91c9c38 95 strcpy(json, "{\"considerIp\": \"false\",");
Wayne Roberts 1:4a05f91c9c38 96 strcat(json, "\"wifiAccessPoints\": [");
Wayne Roberts 1:4a05f91c9c38 97 }
Wayne Roberts 1:4a05f91c9c38 98
Wayne Roberts 1:4a05f91c9c38 99 void json_end()
Wayne Roberts 1:4a05f91c9c38 100 {
Wayne Roberts 1:4a05f91c9c38 101 strcat(json, "]");
Wayne Roberts 1:4a05f91c9c38 102 strcat(json, "}");
Wayne Roberts 1:4a05f91c9c38 103 }
Wayne Roberts 1:4a05f91c9c38 104
Wayne Roberts 1:4a05f91c9c38 105 void wifi_result_to_json(bool first, const uint8_t *result, unsigned macStart, unsigned rssi_idx)
Wayne Roberts 1:4a05f91c9c38 106 {
Wayne Roberts 1:4a05f91c9c38 107 char str[8];
Wayne Roberts 1:4a05f91c9c38 108 unsigned i;
Wayne Roberts 1:4a05f91c9c38 109
Wayne Roberts 1:4a05f91c9c38 110 if (!first)
Wayne Roberts 1:4a05f91c9c38 111 strcat(json, ","); // end previous wifiAccessPoint
Wayne Roberts 1:4a05f91c9c38 112
Wayne Roberts 1:4a05f91c9c38 113 strcat(json, "{\"macAddress\": \"");
Wayne Roberts 1:4a05f91c9c38 114 for (i = 0; i < 6; i++) {
Wayne Roberts 1:4a05f91c9c38 115 sprintf(str, "%02x", result[i + macStart]);
Wayne Roberts 1:4a05f91c9c38 116 strcat(json, str);
Wayne Roberts 1:4a05f91c9c38 117 if (i < 5)
Wayne Roberts 1:4a05f91c9c38 118 strcat(json, ":");
Wayne Roberts 1:4a05f91c9c38 119 }
Wayne Roberts 1:4a05f91c9c38 120 strcat(json, "\",\"signalStrength\": ");
Wayne Roberts 1:4a05f91c9c38 121 sprintf(str, "%d", (int8_t)result[rssi_idx]);
Wayne Roberts 1:4a05f91c9c38 122 strcat(json, str);
Wayne Roberts 1:4a05f91c9c38 123 strcat(json, ",\"signalToNoiseRatio\": 0");
Wayne Roberts 1:4a05f91c9c38 124
Wayne Roberts 1:4a05f91c9c38 125 strcat(json, "}");
Wayne Roberts 1:4a05f91c9c38 126 }
Wayne Roberts 1:4a05f91c9c38 127
Wayne Roberts 1:4a05f91c9c38 128 #endif /* GEOLOCATION_PROVIDER == GOOGLE */