デバイスへudpパケット送信(VPN) (M5Stack)
サンプルソースコード
概要
前回のサンプル 「ラベル機能」を使用することで、サーバからクライアントに向けて指示を出すことができます。しかし、ラベル機能では、クライアント側からサーバにあるラベル(指示内容)を取りに行く必要があり、どうしてもリアルタイム性には欠けます。
今回は、「サーバからクライアントに向けて指示を出す」もう1つの方法である、udpパケット送信APIを利用してみます。
クライアント側でudpのポートを開けて待ち受け状態にしておき、サーバ側からAPIを使用してそこに向けてパケットを送信することで、よりリアルタイム性がある指示を出すことができます。
ソースコード
m5stack_iijiot_vpn_udp.ino
#include <M5Stack.h>
#include <WiFi.h>
#include <WiFiUdp.h>
#include <WireGuard-ESP32.h>
#include "lwip/dns.h"
//--- TODO: WI-Fiルーターの SSIDとパスワードを指定してください
const char* ssid = "YOUR_SSID";
const char* pass = "YOUR_PASSWORD";
//---
//--- TODO: 自身のVPNアクセスの設定に書き換えてください。
const IPAddress local_ip(10, 10, 10, 10); //IPアドレス
const char public_key[] = "YOUR PUBLIC KEY"; //公開鍵
const char private_key[] = "YOUR PRIVATE KEY"; //秘密鍵
const char endpoint_address[] = "vgw001.to.iot.iij.jp"; //接続先アドレス
const int endpoint_port = 9999; //接続先ポート番号
//---
const int udpPort = 9999;
WiFiUDP udp;
static WireGuard wg;
/*
setup関数
*/
void setup() {
//M5Stackを初期化
M5.begin();
M5.Power.begin();
//Wi-Fi接続
WiFi.begin(ssid,pass);
M5.Lcd.printf("Waiting connect to WiFi: %s ", ssid);
while(WiFi.status() != WL_CONNECTED) {
//接続完了まで待つ
delay(1000);
M5.Lcd.print(".");
}
//接続完了したらIPアドレスとMacアドレスを表示する
M5.Lcd.println("\nWiFi connected");
M5.Lcd.print("IP address: ");
M5.Lcd.println(WiFi.localIP());
M5.Lcd.print("MAC address:");
M5.Lcd.println(WiFi.macAddress());
delay(500);
//現在時刻をセット
M5.Lcd.println("Adjusting system time...");
configTime(9 * 60 * 60, 0, "ntp.jst.mfeed.ad.jp", "ntp.nict.jp", "time.google.com");
delay(2000);
//WireGuardでVPN接続する
M5.Lcd.println("Initializing WireGuard...");
if (wg.begin(
local_ip,
private_key,
endpoint_address,
public_key,
endpoint_port)) {
M5.Lcd.println("VPN connected.");
//--- DNS参照先をVPN側に向ける
ip_addr_t dnsserver = IPADDR4_INIT_BYTES(10, 64, 2, 11);
dns_setserver(0, &dnsserver);
} else {
M5.Lcd.println("WireGuard initializing Failed.");
}
delay(2000);
//udp待受開始
udp.begin(udpPort);
M5.Lcd.println("Waiting udp packet...");
}
/*
loop関数
*/
void loop() {
//udpパケットを受信した場合
if (int len = udp.parsePacket()) {
//udpパケットを読み込む
char buff[len + 1];
memset(buff, '\0', sizeof(buff));
udp.read((uint8_t*)buff, len);
//読み込んだudpパケットを表示する
M5.Lcd.printf("Recieved: %d byte(s)\n", len);
M5.Lcd.println(buff);
}
}
実行手順
- M5Stackで上記スケッチをビルドし、実行します。
パケット待受状態の表示になります。
- PCから IoTサービスのコントロールパネルにログインします。
- メニューの「API」を開き、アクセスキー・シークレットアクセスキーをメモします。
同様に、メニューの「デバイス」を開き、対象の「VPN」の Device ID をメモします。 IIJ IoTサービス Web API のページを開き、以下のとおり操作します。
- 画面上部の "AccessKeyID" "SecretAccessKey" に、メモしておいた アクセスキー・シークレットアクセスキー を入力します。
- UDP送信API の欄を開き、画面上の "Try it out" ボタンを押します。
"deviceId" の欄に、メモしておいた Device ID を入力します。
"udpRequest" の欄に、送信先デバイスのポート番号と送信するペイロードをJSON形式で入力します。今回は、M5Stack に対して "udp packet test" という文字列を 9999番ポートに 送信します。
{ "port": 9999, "payload": "udp packet test" }画面上の "Execute" ボタンを押すと API実行結果が表示されます。 202のレスポンスが返ってくればOKです。
- M5Stackの画面に、送信したパケットが表示されます。

各種情報へのリンク
IIJ IoTサービスマニュアル
- Gateway API (UDP送信)
M5Stack
WireGuard-ESP32-Arduino