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:
- google geolocation
- combain geolocation
TODO
others?
(choose one) Put your API key for geolocation provider into the URL in geolocation source file (such asgoogle_geolocation.cpp
orcombain.cpp
)
notice
This project is not using LoRaWAN, instead just LoRa transceiver directly to geolocation provider
combain.cpp@1:4a05f91c9c38, 2021-02-09 (annotated)
- Committer:
- Wayne Roberts
- Date:
- Tue Feb 09 10:49:02 2021 -0800
- Revision:
- 1:4a05f91c9c38
add source files
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Wayne Roberts |
1:4a05f91c9c38 | 1 | #include "main.h" |
Wayne Roberts |
1:4a05f91c9c38 | 2 | #if (GEOLOCATION_PROVIDER == COMBAIN) |
Wayne Roberts |
1:4a05f91c9c38 | 3 | #include "radio.h" |
Wayne Roberts |
1:4a05f91c9c38 | 4 | |
Wayne Roberts |
1:4a05f91c9c38 | 5 | char my_copy[128]; |
Wayne Roberts |
1:4a05f91c9c38 | 6 | |
Wayne Roberts |
1:4a05f91c9c38 | 7 | const char COMBAIN_SSL_CA_PEM[] = "-----BEGIN CERTIFICATE-----\n" |
Wayne Roberts |
1:4a05f91c9c38 | 8 | "MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/\n" |
Wayne Roberts |
1:4a05f91c9c38 | 9 | "MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n" |
Wayne Roberts |
1:4a05f91c9c38 | 10 | "DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow\n" |
Wayne Roberts |
1:4a05f91c9c38 | 11 | "PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD\n" |
Wayne Roberts |
1:4a05f91c9c38 | 12 | "Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n" |
Wayne Roberts |
1:4a05f91c9c38 | 13 | "AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O\n" |
Wayne Roberts |
1:4a05f91c9c38 | 14 | "rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq\n" |
Wayne Roberts |
1:4a05f91c9c38 | 15 | "OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b\n" |
Wayne Roberts |
1:4a05f91c9c38 | 16 | "xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw\n" |
Wayne Roberts |
1:4a05f91c9c38 | 17 | "7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD\n" |
Wayne Roberts |
1:4a05f91c9c38 | 18 | "aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV\n" |
Wayne Roberts |
1:4a05f91c9c38 | 19 | "HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG\n" |
Wayne Roberts |
1:4a05f91c9c38 | 20 | "SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69\n" |
Wayne Roberts |
1:4a05f91c9c38 | 21 | "ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr\n" |
Wayne Roberts |
1:4a05f91c9c38 | 22 | "AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz\n" |
Wayne Roberts |
1:4a05f91c9c38 | 23 | "R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5\n" |
Wayne Roberts |
1:4a05f91c9c38 | 24 | "JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo\n" |
Wayne Roberts |
1:4a05f91c9c38 | 25 | "Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ\n" |
Wayne Roberts |
1:4a05f91c9c38 | 26 | "-----END CERTIFICATE-----\n"; |
Wayne Roberts |
1:4a05f91c9c38 | 27 | |
Wayne Roberts |
1:4a05f91c9c38 | 28 | /* parse_json: get result sent from server */ |
Wayne Roberts |
1:4a05f91c9c38 | 29 | void parse_json(const char *body, float *lat, float *lng, int *accuracy) |
Wayne Roberts |
1:4a05f91c9c38 | 30 | { |
Wayne Roberts |
1:4a05f91c9c38 | 31 | bool in_location = false; |
Wayne Roberts |
1:4a05f91c9c38 | 32 | bool get_lat = false; |
Wayne Roberts |
1:4a05f91c9c38 | 33 | bool get_lng = false; |
Wayne Roberts |
1:4a05f91c9c38 | 34 | bool get_accuracy = false; |
Wayne Roberts |
1:4a05f91c9c38 | 35 | unsigned n; |
Wayne Roberts |
1:4a05f91c9c38 | 36 | strncpy(my_copy, body, sizeof(my_copy)); |
Wayne Roberts |
1:4a05f91c9c38 | 37 | strtok(my_copy, "\""); |
Wayne Roberts |
1:4a05f91c9c38 | 38 | for (n = 0; n < 10; n++) { |
Wayne Roberts |
1:4a05f91c9c38 | 39 | char *t = strtok(NULL, "\":"); |
Wayne Roberts |
1:4a05f91c9c38 | 40 | if (!t) |
Wayne Roberts |
1:4a05f91c9c38 | 41 | break; |
Wayne Roberts |
1:4a05f91c9c38 | 42 | if (in_location) { |
Wayne Roberts |
1:4a05f91c9c38 | 43 | if (get_lat) { |
Wayne Roberts |
1:4a05f91c9c38 | 44 | sscanf(t, "%f", lat); |
Wayne Roberts |
1:4a05f91c9c38 | 45 | get_lat = false; |
Wayne Roberts |
1:4a05f91c9c38 | 46 | } else if (get_lng) { |
Wayne Roberts |
1:4a05f91c9c38 | 47 | sscanf(t, "%f", lng); |
Wayne Roberts |
1:4a05f91c9c38 | 48 | get_lng = false; |
Wayne Roberts |
1:4a05f91c9c38 | 49 | } |
Wayne Roberts |
1:4a05f91c9c38 | 50 | if (strchr(t, '}')) |
Wayne Roberts |
1:4a05f91c9c38 | 51 | in_location = false; |
Wayne Roberts |
1:4a05f91c9c38 | 52 | else if (strcmp(t, "lat") == 0) |
Wayne Roberts |
1:4a05f91c9c38 | 53 | get_lat = true; |
Wayne Roberts |
1:4a05f91c9c38 | 54 | else if (strcmp(t, "lng") == 0) |
Wayne Roberts |
1:4a05f91c9c38 | 55 | get_lng = true; |
Wayne Roberts |
1:4a05f91c9c38 | 56 | } else { |
Wayne Roberts |
1:4a05f91c9c38 | 57 | if (get_accuracy) { |
Wayne Roberts |
1:4a05f91c9c38 | 58 | sscanf(t, "%d", accuracy); |
Wayne Roberts |
1:4a05f91c9c38 | 59 | get_accuracy = false; |
Wayne Roberts |
1:4a05f91c9c38 | 60 | } |
Wayne Roberts |
1:4a05f91c9c38 | 61 | if (strcmp(t, "location") == 0) |
Wayne Roberts |
1:4a05f91c9c38 | 62 | in_location = true; |
Wayne Roberts |
1:4a05f91c9c38 | 63 | else if (strcmp(t, "accuracy") == 0) |
Wayne Roberts |
1:4a05f91c9c38 | 64 | get_accuracy = true; |
Wayne Roberts |
1:4a05f91c9c38 | 65 | } |
Wayne Roberts |
1:4a05f91c9c38 | 66 | } |
Wayne Roberts |
1:4a05f91c9c38 | 67 | } |
Wayne Roberts |
1:4a05f91c9c38 | 68 | |
Wayne Roberts |
1:4a05f91c9c38 | 69 | int post_scan_result(const char *body, float *lat, float *lng, int *accuracy) |
Wayne Roberts |
1:4a05f91c9c38 | 70 | { |
Wayne Roberts |
1:4a05f91c9c38 | 71 | HttpsRequest* post_req = new HttpsRequest(network, COMBAIN_SSL_CA_PEM, HTTP_POST, "https://apiv2.combain.com?key=YOUR_API_KEY"); |
Wayne Roberts |
1:4a05f91c9c38 | 72 | |
Wayne Roberts |
1:4a05f91c9c38 | 73 | post_req->set_header("Content-Type", "application/json"); |
Wayne Roberts |
1:4a05f91c9c38 | 74 | |
Wayne Roberts |
1:4a05f91c9c38 | 75 | HttpResponse* post_res = post_req->send(body, strlen(body)); |
Wayne Roberts |
1:4a05f91c9c38 | 76 | if (!post_res) { |
Wayne Roberts |
1:4a05f91c9c38 | 77 | printf("HttpRequest failed (error code %d)\n", post_req->get_error()); |
Wayne Roberts |
1:4a05f91c9c38 | 78 | return -1; |
Wayne Roberts |
1:4a05f91c9c38 | 79 | } |
Wayne Roberts |
1:4a05f91c9c38 | 80 | |
Wayne Roberts |
1:4a05f91c9c38 | 81 | dump_response(post_res); |
Wayne Roberts |
1:4a05f91c9c38 | 82 | parse_json(post_res->get_body_as_string().c_str(), lat, lng, accuracy); |
Wayne Roberts |
1:4a05f91c9c38 | 83 | delete post_req; |
Wayne Roberts |
1:4a05f91c9c38 | 84 | |
Wayne Roberts |
1:4a05f91c9c38 | 85 | return 0; |
Wayne Roberts |
1:4a05f91c9c38 | 86 | } |
Wayne Roberts |
1:4a05f91c9c38 | 87 | |
Wayne Roberts |
1:4a05f91c9c38 | 88 | /* |
Wayne Roberts |
1:4a05f91c9c38 | 89 | * https://combain.com/api/#request-body |
Wayne Roberts |
1:4a05f91c9c38 | 90 | */ |
Wayne Roberts |
1:4a05f91c9c38 | 91 | |
Wayne Roberts |
1:4a05f91c9c38 | 92 | void wifi_result_to_json(bool first, const uint8_t *result, unsigned macStart, unsigned rssi_idx) |
Wayne Roberts |
1:4a05f91c9c38 | 93 | { |
Wayne Roberts |
1:4a05f91c9c38 | 94 | char str[8]; |
Wayne Roberts |
1:4a05f91c9c38 | 95 | unsigned i; |
Wayne Roberts |
1:4a05f91c9c38 | 96 | |
Wayne Roberts |
1:4a05f91c9c38 | 97 | if (!first) |
Wayne Roberts |
1:4a05f91c9c38 | 98 | strcat(json, ","); // end previous wifiAccessPoint |
Wayne Roberts |
1:4a05f91c9c38 | 99 | |
Wayne Roberts |
1:4a05f91c9c38 | 100 | strcat(json, "{\"macAddress\": \""); |
Wayne Roberts |
1:4a05f91c9c38 | 101 | for (i = 0; i < 6; i++) { |
Wayne Roberts |
1:4a05f91c9c38 | 102 | sprintf(str, "%02x", result[i + macStart]); |
Wayne Roberts |
1:4a05f91c9c38 | 103 | strcat(json, str); |
Wayne Roberts |
1:4a05f91c9c38 | 104 | if (i < 5) |
Wayne Roberts |
1:4a05f91c9c38 | 105 | strcat(json, ":"); |
Wayne Roberts |
1:4a05f91c9c38 | 106 | } |
Wayne Roberts |
1:4a05f91c9c38 | 107 | strcat(json, "\",\"signalStrength\": "); |
Wayne Roberts |
1:4a05f91c9c38 | 108 | sprintf(str, "%d", (int8_t)result[rssi_idx]); |
Wayne Roberts |
1:4a05f91c9c38 | 109 | strcat(json, str); |
Wayne Roberts |
1:4a05f91c9c38 | 110 | /* TODO: combain takes channel and/or frequency of access point */ |
Wayne Roberts |
1:4a05f91c9c38 | 111 | |
Wayne Roberts |
1:4a05f91c9c38 | 112 | strcat(json, "}"); |
Wayne Roberts |
1:4a05f91c9c38 | 113 | } |
Wayne Roberts |
1:4a05f91c9c38 | 114 | |
Wayne Roberts |
1:4a05f91c9c38 | 115 | void json_start() |
Wayne Roberts |
1:4a05f91c9c38 | 116 | { |
Wayne Roberts |
1:4a05f91c9c38 | 117 | strcpy(json, "{\"considerIp\": \"false\","); |
Wayne Roberts |
1:4a05f91c9c38 | 118 | strcat(json, "\"wifiAccessPoints\": ["); |
Wayne Roberts |
1:4a05f91c9c38 | 119 | } |
Wayne Roberts |
1:4a05f91c9c38 | 120 | |
Wayne Roberts |
1:4a05f91c9c38 | 121 | void json_end() |
Wayne Roberts |
1:4a05f91c9c38 | 122 | { |
Wayne Roberts |
1:4a05f91c9c38 | 123 | strcat(json, "]"); |
Wayne Roberts |
1:4a05f91c9c38 | 124 | strcat(json, "}"); |
Wayne Roberts |
1:4a05f91c9c38 | 125 | } |
Wayne Roberts |
1:4a05f91c9c38 | 126 | |
Wayne Roberts |
1:4a05f91c9c38 | 127 | #endif /* GEOLOCATION_PROVIDER == COMBAIN */ |