Skip to content

Instantly share code, notes, and snippets.

@sayacom
Last active December 12, 2023 05:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sayacom/2adcfbec8186b4a91a2b393e2dcacd35 to your computer and use it in GitHub Desktop.
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)
#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