Last active
December 12, 2023 05:56
-
-
Save sayacom/2adcfbec8186b4a91a2b393e2dcacd35 to your computer and use it in GitHub Desktop.
Example implementation for M5Stack Core2 to use metadata service on SORACOM Air (or Arc)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define TINY_GSM_MODEM_SIM7080 | |
#define CONSOLE Serial | |
#include <M5Core2.h> | |
#include <Wire.h> | |
#include <WiFi.h> | |
#include <WireGuard-ESP32.h> | |
#include <TinyGsmClient.h> | |
#include <ArduinoHttpClient.h> | |
#include <ArduinoJson.h> | |
#include "Client.h" | |
// #define ENABLE_DUMP_AT_COMMANDS | |
#ifdef ENABLE_DUMP_AT_COMMANDS | |
StreamDebugger debugger(Serial2, CONSOLE); | |
TinyGsm gsmModem(debugger); | |
#else | |
TinyGsm gsmModem(Serial2); | |
#endif | |
WireGuard wg; | |
char ssid[] = "[REPLACE YOUR WIFI SSID]"; | |
char password[] = "[REPLACE YOUR WIFI PASSWORD]"; | |
// WireGuard configuration --- UPDATE this configuration from JSON | |
char private_key[] = "[REPLACE YOUR WIREGUARD PRIVATE KEY]"; // [Interface] PrivateKey | |
IPAddress local_ip(0, 0, 0, 0); // [Interface] Address | |
char public_key[] = "[REPLACE YOUR WIREGUARD PUBLIC KEY]"; // [Peer] PublicKey | |
char endpoint_address[] = "XXX.arc.soracom.io"; // [Peer] Endpoint | |
int endpoint_port = 11010; | |
char ERR_MSG_BUF[100] = { '\0' }; | |
TinyGsmClient initializeGsmModem(TinyGsm GsmModem) { | |
TinyGsmClient client(GsmModem); | |
// Begin GSM modem initialization process | |
CONSOLE.println("Initializing GSM modem..."); | |
// Open Serial2 as Cellular Module | |
Serial2.begin(115200, SERIAL_8N1, 13, 14); | |
// Start GSM Modem | |
GsmModem.restart(); | |
CONSOLE.println("--- Modem Info ---"); | |
String info = GsmModem.getModemInfo(); | |
CONSOLE.println(info); | |
CONSOLE.println("--- End Info ---"); | |
// Wait for catch cellular netwoek | |
CONSOLE.println("Waiting cellular network..."); | |
while(!GsmModem.waitForNetwork()) CONSOLE.print("."); | |
// Connect SORACOM network | |
CONSOLE.println("Connecting SORACOM..."); | |
GsmModem.gprsConnect("soracom.io", "sora", "sora"); | |
while(!GsmModem.isNetworkConnected()) CONSOLE.print("."); | |
// Show device IP address | |
CONSOLE.println("Device IP Address: "); | |
IPAddress ipaddr = GsmModem.localIP(); | |
CONSOLE.println(ipaddr); | |
return client; | |
} | |
String httpRequest(Client& client, String host, int port, String path, String method, String contentType, String requestBody) { | |
CONSOLE.println("Requesting " + host); | |
HttpClient httpClient(client, host, port); | |
int err = httpClient.startRequest(path.c_str(), method.c_str(), contentType.c_str(), requestBody.length(), (const byte*)requestBody.c_str()); | |
if (err != 0) { | |
sprintf(ERR_MSG_BUF, "[Failed to get userdata; err code %d]\n", err); | |
CONSOLE.println(ERR_MSG_BUF); | |
httpClient.stop(); | |
return ""; | |
} | |
int statusCode = httpClient.responseStatusCode(); | |
if (!statusCode) { | |
sprintf(ERR_MSG_BUF, "[Status code does not provided]"); | |
CONSOLE.println(ERR_MSG_BUF); | |
httpClient.stop(); | |
return ""; | |
} | |
CONSOLE.print("Status code returned "); CONSOLE.println(statusCode); | |
CONSOLE.println(F("Response Headers:")); | |
while (httpClient.headerAvailable()) { | |
String headerName = httpClient.readHeaderName(); | |
String headerValue = httpClient.readHeaderValue(); | |
CONSOLE.println(" " + headerName + " : " + headerValue); | |
} | |
int length = httpClient.contentLength(); | |
if (length >= 0) { | |
CONSOLE.print(F("Content length is: ")); | |
CONSOLE.println(length); | |
} | |
if (httpClient.isResponseChunked()) { | |
CONSOLE.println(F("The response is chunked")); | |
} | |
String responseBody = httpClient.responseBody(); | |
CONSOLE.println(F("Response:")); | |
CONSOLE.println(responseBody); | |
CONSOLE.print(F("Body length is: ")); | |
CONSOLE.println(responseBody.length()); | |
CONSOLE.println(); | |
httpClient.stop(); | |
return responseBody; | |
} | |
String getUserdata(Client& client) { | |
CONSOLE.println("Getting userdata..."); | |
String responseBody = httpRequest(client, "metadata.soracom.io", 80, "/v1/userdata", "GET", "", ""); | |
return responseBody; | |
} | |
String getSubscriberTagValue(Client& client, String tagName) { | |
CONSOLE.println("Getting specific tag value [" + tagName + "]..."); | |
String responseBody = httpRequest(client, "metadata.soracom.io", 80, "/v1/subscriber.tags." + tagName, "GET", "", ""); | |
return responseBody; | |
} | |
String putSubscriberTagValue(Client& client, String tagName, String tagValue) { | |
CONSOLE.println("Putting specific tag [" + tagName + "] as [" + tagValue + "]..."); | |
String requestBody = "[{\"tagName\": \"" + tagName + "\", \"tagValue\": \"" + tagValue + "\"}]"; | |
String responseBody = httpRequest(client, "metadata.soracom.io", 80, "/v1/subscriber/tags", "PUT", "application/json", requestBody); | |
return responseBody; | |
} | |
String deleteSubscriberTag(Client& client, String tagName) { | |
CONSOLE.println("Deleting specific tag value [" + tagName + "]..."); | |
String responseBody = httpRequest(client, "metadata.soracom.io", 80, "/v1/subscriber/tags/" + tagName, "DELETE", "", ""); | |
return responseBody; | |
} | |
void setupWiFiAndWireguard() { | |
CONSOLE.print("Connecting to Wi-Fi..."); | |
bool done = true; | |
WiFi.begin(ssid, password); | |
while (done) | |
{ | |
CONSOLE.print("WiFi connecting"); | |
auto last = millis(); | |
while (WiFi.status() != WL_CONNECTED && last + 5000 > millis()) | |
{ | |
delay(500); | |
CONSOLE.print("."); | |
} | |
if (WiFi.status() == WL_CONNECTED) | |
{ | |
done = false; | |
} | |
else | |
{ | |
CONSOLE.println("retry"); | |
WiFi.disconnect(); | |
WiFi.reconnect(); | |
} | |
} | |
CONSOLE.println("\nWiFi connected."); | |
CONSOLE.println(); | |
CONSOLE.print("IP address: "); | |
CONSOLE.println(WiFi.localIP()); | |
CONSOLE.print("DNS: "); | |
CONSOLE.println(WiFi.dnsIP()); | |
CONSOLE.println("Adjusting system time..."); | |
configTime(9 * 60 * 60, 0, "ntp.nict.jp", "ntp.jst.mfeed.ad.jp", "time.google.com"); | |
unsigned long m; | |
struct tm timeInfo; | |
m = millis(); | |
getLocalTime(&timeInfo); | |
CONSOLE.printf("getLocalTime() %luMS\n", millis() - m); | |
CONSOLE.printf("%04d/%02d/%02d %02d:%02d:%02d\n", timeInfo.tm_year + 1900, timeInfo.tm_mon + 1, timeInfo.tm_mday, timeInfo.tm_hour, timeInfo.tm_min, timeInfo.tm_sec); | |
CONSOLE.println("Connected. Initializing WireGuard..."); | |
wg.begin( | |
local_ip, | |
private_key, | |
endpoint_address, | |
public_key, | |
endpoint_port); | |
} | |
void useMetadataServiceDemo(Client& client) { | |
// Get userdata from metadata service | |
String userData = getUserdata(client); | |
CONSOLE.print("USERDATA : "); | |
CONSOLE.println(userData); | |
// Get subscriber specific tag value | |
String tagValue = getSubscriberTagValue(client, "TAGS_TO_DEVICE"); | |
CONSOLE.print("TAGS_TO_DEVICE : "); | |
CONSOLE.println(tagValue); | |
// Put subscriber specific tag value | |
tagValue = getSubscriberTagValue(client, "TAGS_FROM_DEVICE"); | |
CONSOLE.print("TAGS_FROM_DEVICE : "); | |
CONSOLE.println(tagValue); | |
String testTagValue = String(millis()); | |
String updatedTagResult = putSubscriberTagValue(client, "TAGS_FROM_DEVICE", testTagValue); | |
CONSOLE.print("Updated TAGS_FROM_DEVICE: "); | |
CONSOLE.println(updatedTagResult); | |
// Delete subscriber specific tag value | |
result = deleteSubscriberTag(client, "TAGS_FROM_DEVICE"); | |
tagValue = getSubscriberTagValue(client, "TAGS_FROM_DEVICE"); | |
CONSOLE.print("TAGS_FROM_DEVICE : "); | |
CONSOLE.println(tagValue); | |
} | |
void setup() { | |
M5.begin(); | |
CONSOLE.println("*** Setting up Wi-Fi ***"); | |
setupWiFiAndWireguard(); | |
delay(1000); | |
// Use Wi-Fi client | |
WiFiClient wifiClient; | |
CONSOLE.println("*** Setting up cellular module ***"); | |
// Initialize GSM client | |
TinyGsmClient cellularClient = initializeGsmModem(gsmModem); | |
CONSOLE.println("\n\n"); | |
CONSOLE.println("*********************"); | |
CONSOLE.println("* USE VIRTUAL SIM *"); | |
CONSOLE.println("*********************"); | |
useMetadataServiceDemo(wifiClient); | |
CONSOLE.println("\n\n"); | |
CONSOLE.println("*********************"); | |
CONSOLE.println("* USE CELLULAR *"); | |
CONSOLE.println("*********************"); | |
useMetadataServiceDemo(cellularClient); | |
} | |
void loop() | |
{ | |
while (Serial2.available()) CONSOLE.write(Serial2.read()); | |
while (CONSOLE.available()) Serial2.write(CONSOLE.read()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment