mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-29 07:32:18 +03:00
changes
This commit is contained in:
239
lib/WifiLocation/src/WifiLocation.cpp
Normal file
239
lib/WifiLocation/src/WifiLocation.cpp
Normal file
@@ -0,0 +1,239 @@
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include "WifiLocation.h"
|
||||
#include "time.h"
|
||||
|
||||
const char* googleApisHost = "www.googleapis.com";
|
||||
const char* googleApiUrl = "/geolocation/v1/geolocate";
|
||||
|
||||
// GlobalSign CA certificate valid until 15th december 2021
|
||||
#if defined ARDUINO_ARCH_ESP32 || defined ARDUINO_ARCH_ESP8266
|
||||
static const char GlobalSignCA[] PROGMEM = R"EOF(
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIESjCCAzKgAwIBAgINAeO0mqGNiqmBJWlQuDANBgkqhkiG9w0BAQsFADBMMSAw
|
||||
HgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFs
|
||||
U2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0xNzA2MTUwMDAwNDJaFw0yMTEy
|
||||
MTUwMDAwNDJaMEIxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVHb29nbGUgVHJ1c3Qg
|
||||
U2VydmljZXMxEzARBgNVBAMTCkdUUyBDQSAxTzEwggEiMA0GCSqGSIb3DQEBAQUA
|
||||
A4IBDwAwggEKAoIBAQDQGM9F1IvN05zkQO9+tN1pIRvJzzyOTHW5DzEZhD2ePCnv
|
||||
UA0Qk28FgICfKqC9EksC4T2fWBYk/jCfC3R3VZMdS/dN4ZKCEPZRrAzDsiKUDzRr
|
||||
mBBJ5wudgzndIMYcLe/RGGFl5yODIKgjEv/SJH/UL+dEaltN11BmsK+eQmMF++Ac
|
||||
xGNhr59qM/9il71I2dN8FGfcddwuaej4bXhp0LcQBbjxMcI7JP0aM3T4I+DsaxmK
|
||||
FsbjzaTNC9uzpFlgOIg7rR25xoynUxv8vNmkq7zdPGHXkxWY7oG9j+JkRyBABk7X
|
||||
rJfoucBZEqFJJSPk7XA0LKW0Y3z5oz2D0c1tJKwHAgMBAAGjggEzMIIBLzAOBgNV
|
||||
HQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1Ud
|
||||
EwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFJjR+G4Q68+b7GCfGJAboOt9Cf0rMB8G
|
||||
A1UdIwQYMBaAFJviB1dnHB7AagbeWbSaLd/cGYYuMDUGCCsGAQUFBwEBBCkwJzAl
|
||||
BggrBgEFBQcwAYYZaHR0cDovL29jc3AucGtpLmdvb2cvZ3NyMjAyBgNVHR8EKzAp
|
||||
MCegJaAjhiFodHRwOi8vY3JsLnBraS5nb29nL2dzcjIvZ3NyMi5jcmwwPwYDVR0g
|
||||
BDgwNjA0BgZngQwBAgIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly9wa2kuZ29vZy9y
|
||||
ZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAGoA+Nnn78y6pRjd9XlQWNa7H
|
||||
TgiZ/r3RNGkmUmYHPQq6Scti9PEajvwRT2iWTHQr02fesqOqBY2ETUwgZQ+lltoN
|
||||
FvhsO9tvBCOIazpswWC9aJ9xju4tWDQH8NVU6YZZ/XteDSGU9YzJqPjY8q3MDxrz
|
||||
mqepBCf5o8mw/wJ4a2G6xzUr6Fb6T8McDO22PLRL6u3M4Tzs3A2M1j6bykJYi8wW
|
||||
IRdAvKLWZu/axBVbzYmqmwkm5zLSDW5nIAJbELCQCZwMH56t2Dvqofxs6BBcCFIZ
|
||||
USpxu6x6td0V7SvJCCosirSmIatj/9dSSVDQibet8q/7UK4v4ZUN80atnZz1yg==
|
||||
-----END CERTIFICATE-----
|
||||
)EOF";
|
||||
#endif
|
||||
|
||||
String WifiLocation::MACtoString(uint8_t* macAddress) {
|
||||
uint8_t mac[6];
|
||||
char macStr[18] = { 0 };
|
||||
#ifdef ARDUINO_ARCH_SAMD
|
||||
sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", macAddress[5], macAddress[4], macAddress[3], macAddress[2], macAddress[1], macAddress[0]);
|
||||
#elif defined ARDUINO_ARCH_ESP8266 || defined ARDUINO_ARCH_ESP32
|
||||
sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", macAddress[0], macAddress[1], macAddress[2], macAddress[3], macAddress[4], macAddress[5]);
|
||||
#endif
|
||||
return String(macStr);
|
||||
}
|
||||
|
||||
WifiLocation::WifiLocation(String googleKey) {
|
||||
_googleApiKey = googleKey;
|
||||
}
|
||||
|
||||
// Function to get a list of surrounding WiFi signals in JSON format to get location via Google Location API
|
||||
String WifiLocation::getSurroundingWiFiJson() {
|
||||
String wifiArray = "[\n";
|
||||
|
||||
int8_t numWifi = WiFi.scanNetworks();
|
||||
if(numWifi > MAX_WIFI_SCAN) {
|
||||
numWifi = MAX_WIFI_SCAN;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_WIFI_LOCATION
|
||||
Serial.println(String(numWifi) + " WiFi networks found");
|
||||
#endif // DEBUG_WIFI_LOCATION
|
||||
for (uint8_t i = 0; i < numWifi; i++) {//numWifi; i++) {
|
||||
//Serial.print("WiFi.BSSID(i) = ");
|
||||
//Serial.println((char *)WiFi.BSSID(i));
|
||||
#ifdef ARDUINO_ARCH_SAMD
|
||||
byte bssid[6];
|
||||
|
||||
wifiArray += "{\"macAddress\":\"" + MACtoString(WiFi.BSSID(i,bssid)) + "\",";
|
||||
#elif defined ARDUINO_ARCH_ESP8266 || defined ARDUINO_ARCH_ESP32
|
||||
wifiArray += "{\"macAddress\":\"" + MACtoString(WiFi.BSSID(i)) + "\",";
|
||||
#else
|
||||
#error Only ESP8266 and SAMD platforms are supported
|
||||
#endif
|
||||
wifiArray += "\"signalStrength\":" + String(WiFi.RSSI(i)) + ",";
|
||||
wifiArray += "\"channel\":" + String(WiFi.channel(i)) + "}";
|
||||
if (i < (numWifi - 1)) {
|
||||
wifiArray += ",\n";
|
||||
}
|
||||
}
|
||||
#if defined ARDUINO_ARCH_ESP8266 || defined ARDUINO_ARCH_ESP32
|
||||
WiFi.scanDelete();
|
||||
#endif
|
||||
wifiArray += "]";
|
||||
#ifdef DEBUG_WIFI_LOCATION
|
||||
Serial.println("WiFi list :\n" + wifiArray);
|
||||
#endif // DEBUG_WIFI_LOCATION
|
||||
return wifiArray;
|
||||
}
|
||||
|
||||
#if defined ARDUINO_ARCH_ESP32 || defined ARDUINO_ARCH_ESP8266
|
||||
// Set time via NTP, as required for x.509 validation
|
||||
void setClock () {
|
||||
configTime (3600, 0, "pool.ntp.org", "time.nist.gov");
|
||||
|
||||
#ifdef DEBUG_WIFI_LOCATION
|
||||
Serial.print ("Waiting for NTP time sync: ");
|
||||
#endif
|
||||
time_t now = time (nullptr);
|
||||
while (now < 8 * 3600 * 2) {
|
||||
delay (500);
|
||||
#ifdef DEBUG_WIFI_LOCATION
|
||||
Serial.print (".");
|
||||
#endif
|
||||
now = time (nullptr);
|
||||
}
|
||||
struct tm timeinfo;
|
||||
gmtime_r (&now, &timeinfo);
|
||||
#ifdef DEBUG_WIFI_LOCATION
|
||||
Serial.println ();
|
||||
Serial.print ("Current time: ");
|
||||
Serial.print (asctime (&timeinfo));
|
||||
#endif
|
||||
}
|
||||
#endif //ARDUINO_ARCH_ESP32 || ARDUINO_ARCH_ESP8266
|
||||
|
||||
// Calls Google Location API to get current location using surrounding WiFi signals inf
|
||||
location_t WifiLocation::getGeoFromWiFi() {
|
||||
|
||||
location_t location;
|
||||
String response = "";
|
||||
#if defined ARDUINO_ARCH_ESP8266 || defined ARDUINO_ARCH_ESP32
|
||||
setClock ();
|
||||
#ifdef ARDUINO_ARCH_ESP8266
|
||||
#if (defined BR_BEARSSL_H__ && not defined USE_CORE_PRE_2_5_0)
|
||||
BearSSL::X509List cert (GlobalSignCA);
|
||||
_client.setTrustAnchors (&cert);
|
||||
#else
|
||||
_client.setCACert (reinterpret_cast<const uint8_t*>(GlobalSignCA), sizeof (GlobalSignCA));
|
||||
#endif
|
||||
#endif // ARDUINO_ARCH_ESP8266
|
||||
#endif
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
_client.setCACert(GlobalSignCA);
|
||||
#endif
|
||||
if (_client.connect(googleApisHost, 443)) {
|
||||
#ifdef DEBUG_WIFI_LOCATION
|
||||
Serial.println("Connected to API endpoint");
|
||||
#endif // DEBUG_WIFI_LOCATION
|
||||
} else {
|
||||
#ifdef DEBUG_WIFI_LOCATION
|
||||
Serial.println("HTTPS error");
|
||||
#endif // DEBUG_WIFI_LOCATION
|
||||
return location;
|
||||
}
|
||||
|
||||
String body = "{\"wifiAccessPoints\":" + getSurroundingWiFiJson() + "}";
|
||||
#ifdef DEBUG_WIFI_LOCATION
|
||||
Serial.println("requesting URL: " + String(googleApiUrl) + "?key=" + _googleApiKey);
|
||||
#endif // DEBUG_WIFI_LOCATION
|
||||
String request = String("POST ") + String(googleApiUrl);
|
||||
if (_googleApiKey != "")
|
||||
request += "?key=" + _googleApiKey;
|
||||
request += " HTTP/1.1\r\n";
|
||||
request += "Host: " + String(googleApisHost) + "\r\n";
|
||||
request += "User-Agent: ESP8266\r\n";
|
||||
request += "Content-Type:application/json\r\n";
|
||||
request += "Content-Length:" + String(body.length()) + "\r\n";
|
||||
request += "Connection: close\r\n\r\n";
|
||||
request += body;
|
||||
#ifdef DEBUG_WIFI_LOCATION
|
||||
Serial.println("request: \n" + request);
|
||||
#endif // DEBUG_WIFI_LOCATION
|
||||
|
||||
_client.println(request);
|
||||
#ifdef DEBUG_WIFI_LOCATION
|
||||
Serial.println("request sent");
|
||||
Serial.print("Free heap: ");
|
||||
Serial.println(ESP.getFreeHeap());
|
||||
#endif // DEBUG_WIFI_LOCATION
|
||||
int timer = millis();
|
||||
|
||||
// Wait for response
|
||||
while (millis() - timer < MAX_CONNECTION_TIMEOUT) {
|
||||
if (_client.available())
|
||||
break;
|
||||
yield ();
|
||||
}
|
||||
while (_client.available()) {
|
||||
#ifdef DEBUG_WIFI_LOCATION
|
||||
Serial.print(".");
|
||||
#endif // DEBUG_WIFI_LOCATION
|
||||
response += _client.readString();
|
||||
yield ();
|
||||
}
|
||||
#ifdef DEBUG_WIFI_LOCATION
|
||||
Serial.println();
|
||||
#endif // DEBUG_WIFI_LOCATION
|
||||
if (response != "") {
|
||||
#ifdef DEBUG_WIFI_LOCATION
|
||||
Serial.println("Got response:");
|
||||
Serial.println(response);
|
||||
#endif // DEBUG_WIFI_LOCATION
|
||||
|
||||
int index = response.indexOf("\"lat\":");
|
||||
if (index != -1) {
|
||||
String tempStr = response.substring(index);
|
||||
//Serial.println(tempStr);
|
||||
tempStr = tempStr.substring(tempStr.indexOf(":") + 1, tempStr.indexOf(","));
|
||||
//Serial.println(tempStr);
|
||||
location.lat = tempStr.toFloat();
|
||||
#ifdef DEBUG_WIFI_LOCATION
|
||||
Serial.println("\nLat: " + String(location.lat, 7));
|
||||
#endif // DEBUG_WIFI_LOCATION
|
||||
}
|
||||
|
||||
index = response.indexOf("\"lng\":");
|
||||
if (index != -1) {
|
||||
String tempStr = response.substring(index);
|
||||
//Serial.println(tempStr);
|
||||
tempStr = tempStr.substring(tempStr.indexOf(":") + 1, tempStr.indexOf(","));
|
||||
//Serial.println(tempStr);
|
||||
location.lon = tempStr.toFloat();
|
||||
#ifdef DEBUG_WIFI_LOCATION
|
||||
Serial.println("Lon: " + String(location.lon, 7));
|
||||
#endif // DEBUG_WIFI_LOCATION
|
||||
}
|
||||
|
||||
index = response.indexOf("\"accuracy\":");
|
||||
if (index != -1) {
|
||||
String tempStr = response.substring(index);
|
||||
//Serial.println(tempStr);
|
||||
tempStr = tempStr.substring(tempStr.indexOf(":") + 1, tempStr.indexOf("\n"));
|
||||
//Serial.println(tempStr);
|
||||
location.accuracy = tempStr.toFloat();
|
||||
#ifdef DEBUG_WIFI_LOCATION
|
||||
Serial.println("Accuracy: " + String(location.accuracy) + "\n");
|
||||
#endif // DEBUG_WIFI_LOCATION
|
||||
}
|
||||
}
|
||||
|
||||
return location;
|
||||
}
|
||||
Reference in New Issue
Block a user