Add TimeZone and VPN Wireguard

This commit is contained in:
Atten 2022-06-06 10:46:21 +07:00
parent 56a10c78a6
commit 6537fd115b
15 changed files with 1148 additions and 42 deletions

View File

@ -2,21 +2,21 @@
Name: ESP32 APRS Internet Gateway
Created: 1-Nov-2021 14:27:23
Author: HS5TQA/Atten
Support IS: host:aprs.dprns.com port:14580
Support IS monitor: http://aprs.dprns.com:14501
Support IS: host:aprs.dprns.com port:14580 or aprs.hs5tqa.ampr.org:14580
Support IS monitor: http://aprs.dprns.com:14501 or http://aprs.hs5tqa.ampr.org:14501
Support in LINE Group APRS Only
*/
#ifndef MAIN_H
#define MAIN_H
#define VERSION "0.6a"
#define VERSION "0.7"
#define DEBUG
//#define DEBUG_IS
//#define SDCARD
//#define SA818
#define SA818
//#define SR_FRS
#ifdef SR_FRS
@ -98,10 +98,10 @@ typedef struct Config_Struct
char aprs_filter[30];
char aprs_comment[50];
char aprs_path[72];
char wifi_ssid[20];
char wifi_pass[15];
char wifi_ap_ssid[20];
char wifi_ap_pass[15];
char wifi_ssid[32];
char wifi_pass[63];
char wifi_ap_ssid[32];
char wifi_ap_pass[63];
char tnc_path[50];
char tnc_btext[50];
char tnc_comment[50];
@ -125,6 +125,17 @@ typedef struct Config_Struct
bool rf_power;
uint8_t volume;
#endif
bool vpn;
bool modem;
uint16_t wg_port;
char wg_peer_address[16];
char wg_local_address[16];
char wg_netmask_address[16];
char wg_gw_address[16];
char wg_public_key[45];
char wg_private_key[45];
int8_t timeZone;
} Configuration;
typedef struct igateTLM_struct
@ -182,7 +193,7 @@ typedef struct txQueue_struct
char Info[300];
} txQueueType;
const char PARM[] = {"PARM.RF->INET,INET->RF,RxPkts,TxPkts,IGateDropRx"};
const char PARM[] = {"PARM.RF->INET,INET->RF,TxPkts,RxPkts,IGateDropRx"};
const char UNIT[] = {"UNIT.Pkts,Pkts,Pkts,Pkts,Pkts"};
const char EQNS[] = {"EQNS.0,1,0,0,1,0,0,1,0,0,1,0,0,1,0"};

56
include/wireguard_vpn.h Normal file
View File

@ -0,0 +1,56 @@
//==============================================================================
// Wireguard VPN Client demo for LwIP/ESP32
//==============================================================================
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
//==============================================================================
// Multi-include guard
//==============================================================================
#ifndef INC_WIREGUARD_VPN_H
#define INC_WIREGUARD_VPN_H
//==============================================================================
// Includes
//==============================================================================
//==============================================================================
// Defines
//==============================================================================
#define WG_LOCAL_ADDRESS IPADDR4_INIT_BYTES(192, 168, 44, 202)
#define WG_LOCAL_NETMASK IPADDR4_INIT_BYTES(255, 255, 255, 255)
#define WG_GATEWAY_ADDRESS IPADDR4_INIT_BYTES(192, 168, 44, 195)
#define WG_CLIENT_PRIVATE_KEY "gH2YqDa+St6x5eFhomVQDwtV1F0YMQd3HtOElPkZgVY="
//#define WG_CLIENT_PRIVATE_KEY "sHueMvT+zVP7Pm/zoRptYcDkCERaBoJc/oUi9n0bmGE="
#define WG_CLIENT_PORT 51821
#define WG_PEER_PUBLIC_KEY "ZEFr+/B/T5+k0DhVG/GOTvAOjeOiuFKmwtu/cy23xVs="
#define WG_PEER_PORT 51820
#define WG_PEER_ADDRESS IPADDR4_INIT_BYTES(203, 150, 19, 23)
//==============================================================================
// Exported types
//==============================================================================
//==============================================================================
// Exported data
//==============================================================================
//==============================================================================
// Exported functions
//==============================================================================
bool wireguard_active();
void wireguard_remove();
void wireguard_setup();
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // INC_WIREGUARD_VPN_H

21
lib/ESP32_PPPoS/LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Volodymyr Shymanskyy
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,2 @@
# ESP32_PPPoS
PPP over Serial for ESP32

View File

@ -0,0 +1,78 @@
#include <PPPoS.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include "TTGO_TCall.h"
#define PPP_APN "internet"
#define PPP_USER ""
#define PPP_PASS ""
PPPoS ppp;
void setup()
{
Serial.begin(115200);
delay(100);
setupModem();
Serial1.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
Serial1.setTimeout(10);
Serial1.setRxBufferSize(2048);
ppp.begin(&Serial1);
Serial.print("Connecting PPPoS");
ppp.connect(PPP_APN, PPP_USER, PPP_PASS);
while (!ppp.status()) {
delay(500);
Serial.print(".");
}
Serial.println("OK");
// Check plain TCP connection
requestJSON("http://httpbin.org/anything?client=ESP32_PPPoS");
// Check secure SSL/TLS connection
requestJSON("https://www.howsmyssl.com/a/check");
ppp.end();
}
void loop() {
/* do nothing */
delay(1000);
}
void requestJSON(String url)
{
Serial.print("Requesting "); Serial.println(url);
HTTPClient http;
if (!http.begin(url)) {
Serial.println("Cannot initiate request");
return;
}
int httpCode = http.GET();
if (httpCode != HTTP_CODE_OK) {
Serial.print("Status code: ");
Serial.println(httpCode);
if (httpCode < 0) {
return;
}
}
// Parse JSON
DynamicJsonDocument doc(1024*10);
DeserializationError error = deserializeJson(doc, http.getStream());
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.print(error.f_str());
} else {
serializeJsonPretty(doc, Serial);
}
http.end();
Serial.println();
}

View File

@ -0,0 +1,63 @@
#include <Wire.h>
#define MODEM_RST 5
#define MODEM_PWRKEY 4
#define MODEM_POWER_ON 23
#define MODEM_TX 27
#define MODEM_RX 26
#define I2C_SDA 21
#define I2C_SCL 22
#define LED_GPIO 13
#define LED_ON HIGH
#define LED_OFF LOW
#define IP5306_ADDR 0x75
#define IP5306_REG_SYS_CTL0 0x00
// setPowerBoostKeepOn
bool setupPMU()
{
bool en = true;
Wire.begin(I2C_SDA, I2C_SCL);
Wire.beginTransmission(IP5306_ADDR);
Wire.write(IP5306_REG_SYS_CTL0);
if (en) {
Wire.write(0x37); // Set bit1: 1 enable 0 disable boost keep on
} else {
Wire.write(0x35); // 0x37 is default reg value
}
return Wire.endTransmission() == 0;
}
void setupModem()
{
// Start power management
if (setupPMU() == false) {
Serial.println("Setting power error");
}
#ifdef MODEM_RST
// Keep reset high
pinMode(MODEM_RST, OUTPUT);
digitalWrite(MODEM_RST, HIGH);
#endif
pinMode(MODEM_PWRKEY, OUTPUT);
pinMode(MODEM_POWER_ON, OUTPUT);
// Turn on the Modem power first
digitalWrite(MODEM_POWER_ON, HIGH);
// Pull down PWRKEY for more than 1 second according to manual requirements
digitalWrite(MODEM_PWRKEY, HIGH);
delay(100);
digitalWrite(MODEM_PWRKEY, LOW);
delay(1000);
digitalWrite(MODEM_PWRKEY, HIGH);
// Initialize the indicator as an output
pinMode(LED_GPIO, OUTPUT);
digitalWrite(LED_GPIO, LED_OFF);
}

View File

@ -0,0 +1,16 @@
#######################################
# Data types (KEYWORD1)
#######################################
PPPoS KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
connect KEYWORD2
begin KEYWORD2
status KEYWORD2
#######################################
# Literals (LITERAL1)
#######################################
PPP_CONNECTED LITERAL1

View File

@ -0,0 +1,21 @@
{
"name": "PPPoS",
"version": "0.1.0",
"description": "PPP over Serial for ESP32",
"keywords": "esp32, GSM, ppp, PPPoS",
"authors": [
{
"name": "Volodymyr Shymanskyy",
"url": "https://github.com/vshymanskyy",
"maintainer": true
}
],
"repository":
{
"type": "git",
"url": "https://github.com/vshymanskyy/ESP32_PPPoS.git"
},
"homepage": "https://github.com/vshymanskyy/ESP32_PPPoS",
"frameworks": "*",
"platforms": "esp32"
}

View File

@ -0,0 +1,12 @@
name=PPPoS
version=0.1.0
author=Volodymyr Shymanskyy <vshymanskyi@gmail.com>
license=MIT
maintainer=Volodymyr Shymanskyy <vshymanskyi@gmail.com>
sentence=
paragraph=
category=Connectivity
url=https://github.com/vshymanskyy/ESP32_PPPoS
repository=https://github.com/vshymanskyy/ESP32_PPPoS.git
architectures=esp32
includes=gsm.h

View File

@ -0,0 +1,237 @@
#include "PPPoS.h"
extern "C" {
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "tcpip_adapter.h"
#include "netif/ppp/pppos.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/netdb.h"
#include "lwip/dns.h"
#include "netif/ppp/pppapi.h"
}
#define BUF_SIZE (1024)
/* The PPP control block */
static ppp_pcb *ppp;
/* The PPP IP interface */
static struct netif ppp_netif;
static const char *TAG = "pppos";
static void ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx)
{
PPPoS* pppos = (PPPoS*)ctx;
struct netif *pppif = ppp_netif(pcb);
switch (err_code) {
case PPPERR_NONE: {
ESP_LOGE(TAG, "status_cb: Connected\n");
#if PPP_IPV4_SUPPORT
ESP_LOGE(TAG, " our_ipaddr = %s\n", ipaddr_ntoa(&pppif->ip_addr));
ESP_LOGE(TAG, " his_ipaddr = %s\n", ipaddr_ntoa(&pppif->gw));
ESP_LOGE(TAG, " netmask = %s\n", ipaddr_ntoa(&pppif->netmask));
#endif /* PPP_IPV4_SUPPORT */
#if PPP_IPV6_SUPPORT
ESP_LOGE(TAG, " our6_ipaddr = %s\n", ip6addr_ntoa(netif_ip6_addr(pppif, 0)));
#endif /* PPP_IPV6_SUPPORT */
pppos->mConnected = true;
break;
}
case PPPERR_PARAM: {
ESP_LOGE(TAG, "status_cb: Invalid parameter\n");
break;
}
case PPPERR_OPEN: {
ESP_LOGE(TAG, "status_cb: Unable to open PPP session\n");
break;
}
case PPPERR_DEVICE: {
ESP_LOGE(TAG, "status_cb: Invalid I/O device for PPP\n");
break;
}
case PPPERR_ALLOC: {
ESP_LOGE(TAG, "status_cb: Unable to allocate resources\n");
break;
}
case PPPERR_USER: {
ESP_LOGE(TAG, "status_cb: User interrupt\n");
pppos->mStarted = false;
pppos->mConnected = false;
break;
}
case PPPERR_CONNECT: {
ESP_LOGE(TAG, "status_cb: Connection lost\n");
pppos->mStarted = false;
pppos->mConnected = false;
break;
}
case PPPERR_AUTHFAIL: {
ESP_LOGE(TAG, "status_cb: Failed authentication challenge\n");
break;
}
case PPPERR_PROTOCOL: {
ESP_LOGE(TAG, "status_cb: Failed to meet protocol\n");
break;
}
case PPPERR_PEERDEAD: {
ESP_LOGE(TAG, "status_cb: Connection timeout\n");
break;
}
case PPPERR_IDLETIMEOUT: {
ESP_LOGE(TAG, "status_cb: Idle Timeout\n");
break;
}
case PPPERR_CONNECTTIME: {
ESP_LOGE(TAG, "status_cb: Max connect time reached\n");
break;
}
case PPPERR_LOOPBACK: {
ESP_LOGE(TAG, "status_cb: Loopback detected\n");
break;
}
default: {
ESP_LOGE(TAG, "status_cb: Unknown error code %d\n", err_code);
break;
}
}
}
static u32_t ppp_output_callback(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx)
{
PPPoS* pppos = (PPPoS*)ctx;
return pppos->mStream->write(data, len);
}
static void pppos_client_task(void *ctx)
{
PPPoS* pppos = (PPPoS*)ctx;
u8_t* data = (u8_t*)malloc(BUF_SIZE);
while (1) {
while (pppos->mStarted) {
//while (pppos->mStream->available()) {
int len = pppos->mStream->readBytes(data, BUF_SIZE);
if (len > 0) {
pppos_input_tcpip(ppp, data, len);
}
//}
vTaskDelay(10 / portTICK_PERIOD_MS);
}
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
void PPPoS::begin(Stream* stream)
{
mStream = stream;
// This is needed, because WiFiClient and WiFiClientSecure are used to handle connections
WiFi.begin();
xTaskCreate(&pppos_client_task, "pppos_client_task", 10048, this, 5, NULL);
}
bool PPPoS::waitResponse(String& data)
{
unsigned timeout_ms = 500;
data.reserve(64);
uint8_t index = 0;
uint32_t startMillis = millis();
do {
while (mStream->available() > 0) {
int8_t a = mStream->read();
if (a <= 0) continue; // Skip 0x00 bytes, just in case
data += static_cast<char>(a);
if (data.endsWith("OK\r\n")) {
index = 1;
goto finish;
} else if (data.endsWith("ERROR\r\n")) {
index = 2;
goto finish;
} else if (data.endsWith("NO CARRIER\r\n")) {
index = 3;
goto finish;
} else if (data.endsWith("CONNECT\r\n")) {
index = 4;
goto finish;
}
}
} while (millis() - startMillis < timeout_ms);
finish:
if (!index) {
data = "";
}
return index > 0;
}
bool PPPoS::connect(const char* apn, const char* user, const char* pass)
{
while (mStream->available()) {
mStream->read();
}
while (1) {
mStream->print("AT+CGDCONT=1,\"IP\",\"");
mStream->print(apn);
mStream->print("\"\r\n");
mStream->flush();
String data;
waitResponse(data);
data.trim();
if (data == "OK") break;
delay(1000);
}
while (1) {
mStream->print("ATD*99***1#\r\n");
mStream->flush();
String data;
waitResponse(data);
data.trim();
if (data == "CONNECT") break;
delay(1000);
}
if (!mFirstStart) {
ppp = pppapi_pppos_create(&ppp_netif, ppp_output_callback, ppp_status_cb, this);
if (ppp == NULL) {
return false;
}
pppapi_set_default(ppp);
pppapi_set_auth(ppp, PPPAUTHTYPE_PAP, user, pass);
ppp_set_usepeerdns(ppp, 1);
}
pppapi_connect(ppp, 0);
mStarted = true;
mFirstStart = true;
return true;
}
void PPPoS::end() {
pppapi_close(ppp, 0);
}

View File

@ -0,0 +1,35 @@
#ifndef _PPPOS_H_
#define _PPPOS_H_
#ifndef ESP32
#error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
#endif
#include <Arduino.h>
#include <WiFi.h>
class PPPoS {
public:
void begin(Stream* stream);
bool connect(const char* apn = "", const char* user = "", const char* pass = "");
bool status() {
return mConnected;
}
void end();
private:
bool waitResponse(String& data);
public:
Stream* mStream;
bool mFirstStart = false;
bool mConnected = false;
bool mStarted = false;
};
#endif

View File

@ -22,4 +22,9 @@ board_build.partitions = min_spiffs.csv
monitor_speed = 9600
upload_protocol = esptool
monitor_filters = esp32_exception_decoder
lib_deps = densaugeo/base64@^1.2.1
lib_deps =
densaugeo/base64@^1.2.1
; ciniml/WireGuard-ESP32@^0.1.5
zmeiresearch/Wireguard client for LwIP on ESP32@^1.0.1
build_flags =
-L./lib

View File

@ -21,11 +21,18 @@
#include "BluetoothSerial.h"
#include "digirepeater.h"
#include "igate.h"
#include "wireguardif.h"
#include "wireguard.h"
#include "wireguard_vpn.h"
#include <WiFiUdp.h>
#include <WiFiClientSecure.h>
#include "AFSK.h"
#include <PPPoS.h>
#define DEBUG_TNC
#define EEPROM_SIZE 1024
@ -49,6 +56,16 @@
HardwareSerial SerialRF(1);
#endif
#define MODEM_PWRKEY 5
#define MODEM_TX 17
#define MODEM_RX 16
#define PPP_APN "internet"
#define PPP_USER ""
#define PPP_PASS ""
PPPoS ppp;
time_t systemUptime = 0;
time_t wifiUptime = 0;
@ -88,6 +105,8 @@ IPAddress local_IP(192, 168, 4, 1);
IPAddress gateway(192, 168, 4, 254);
IPAddress subnet(255, 255, 255, 0);
IPAddress vpn_IP(192, 168, 44, 195);
int pkgTNC_count = 0;
String getValue(String data, char separator, int index)
@ -203,8 +222,18 @@ void defaultConfig()
config.volume = 4;
config.input_hpf = false;
#endif
saveEEPROM();
input_HPF = config.input_hpf;
config.vpn = false;
config.modem = false;
config.wg_port = 51820;
sprintf(config.wg_peer_address, "203.150.19.23");
sprintf(config.wg_local_address, "192.168.44.200");
sprintf(config.wg_netmask_address, "255.255.255.255");
sprintf(config.wg_gw_address, "192.168.44.254");
sprintf(config.wg_public_key, "");
sprintf(config.wg_private_key, "");
config.timeZone = 7;
saveEEPROM();
}
unsigned long NTP_Timeout;
@ -661,8 +690,8 @@ void setup()
SA818_INIT(true);
#endif
enableLoopWDT();
enableCore0WDT();
// enableLoopWDT();
// enableCore0WDT();
enableCore1WDT();
// Task 1
@ -673,17 +702,17 @@ void setup()
NULL, /* Task input parameter */
1, /* Priority of the task */
&taskAPRSHandle, /* Task handle. */
1); /* Core where the task should run */
0); /* Core where the task should run */
// Task 2
xTaskCreatePinnedToCore(
taskNetwork, /* Function to implement the task */
"taskNetwork", /* Name of the task */
20000, /* Stack size in words */
32768, /* Stack size in words */
NULL, /* Task input parameter */
1, /* Priority of the task */
&taskNetworkHandle, /* Task handle. */
0); /* Core where the task should run */
1); /* Core where the task should run */
}
int pkgCount = 0;
@ -776,9 +805,17 @@ int packet2Raw(String &tnc2, AX25Msg &Packet)
long sendTimer = 0;
bool AFSKInitAct = false;
int btn_count = 0;
long timeCheck = 0;
void loop()
{
vTaskDelay(5 / portTICK_PERIOD_MS);
if (millis() > timeCheck)
{
timeCheck = millis() + 10000;
if (ESP.getFreeHeap() < 70000)
esp_restart();
// Serial.println(String(ESP.getFreeHeap()));
}
#ifdef SA818
// if (SerialRF.available())
// {
@ -817,7 +854,7 @@ void sendIsPkgMsg(char *raw)
String tnc2Raw = String(str);
if (aprsClient.connected())
aprsClient.println(tnc2Raw); // Send packet to Inet
if (config.tnc)
if (config.tnc && config.tnc_digi)
pkgTxUpdate(str, 0);
// APRS_sendTNC2Pkt(tnc2Raw); // Send packet to RF
}
@ -964,7 +1001,7 @@ void taskAPRS(void *pvParameters)
if (aprsClient.connected())
aprsClient.println(String(rawTlm)); // Send packet to Inet
if (config.tnc)
if (config.tnc && config.tnc_digi)
pkgTxUpdate(rawTlm, 0);
// APRS_sendTNC2Pkt(String(rawTlm)); // Send packet to RF
igateTLM.Sequence++;
@ -1069,6 +1106,26 @@ void taskNetwork(void *pvParameters)
{
int c = 0;
Serial.println("Task Network has been start");
// pinMode(MODEM_PWRKEY, OUTPUT);
// // Pull down PWRKEY for more than 1 second according to manual requirements
// digitalWrite(MODEM_PWRKEY, HIGH);
// delay(100);
// digitalWrite(MODEM_PWRKEY, LOW);
// delay(1000);
// digitalWrite(MODEM_PWRKEY, HIGH);
// Serial1.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
// Serial1.setTimeout(10);
// Serial1.setRxBufferSize(2048);
// ppp.begin(&Serial1);
// Serial.print("Connecting PPPoS");
// ppp.connect(PPP_APN, PPP_USER, PPP_PASS);
// while (!ppp.status()) {
// delay(500);
// Serial.print(".");
// }
// Serial.println("OK");
if (config.wifi_mode == WIFI_AP_STA_FIX || config.wifi_mode == WIFI_AP_FIX)
{ // AP=false
@ -1105,10 +1162,11 @@ void taskNetwork(void *pvParameters)
}
webService();
pingTimeout = millis() + 10000;
for (;;)
{
// wdtNetworkTimer = millis();
vTaskDelay(10 / portTICK_PERIOD_MS);
vTaskDelay(5 / portTICK_PERIOD_MS);
serviceHandle();
if (config.wifi_mode == WIFI_AP_STA_FIX || config.wifi_mode == WIFI_STA_FIX)
@ -1122,12 +1180,14 @@ void taskNetwork(void *pvParameters)
AFSK_TimerEnable(false);
#endif
wifiTTL = tw + 60000;
Serial.print("WiFi connecting..");
Serial.println("WiFi connecting..");
// udp.endPacket();
WiFi.disconnect();
WiFi.setTxPower((wifi_power_t)config.wifi_power);
WiFi.setHostname("ESP32IGate");
WiFi.begin(config.wifi_ssid, config.wifi_pass);
if (config.vpn)
wireguard_remove();
// Wait up to 1 minute for connection...
for (c = 0; (c < 30) && (WiFi.status() != WL_CONNECTED); c++)
{
@ -1139,12 +1199,17 @@ void taskNetwork(void *pvParameters)
{ // If it didn't connect within 1 min
Serial.println("Failed. Will retry...");
WiFi.disconnect();
// WiFi.mode(WIFI_OFF);
delay(3000);
// WiFi.mode(WIFI_STA);
WiFi.reconnect();
continue;
}
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
vTaskDelay(1000 / portTICK_PERIOD_MS);
NTP_Timeout = millis() + 5000;
// Serial.println("Contacting Time Server");
@ -1157,13 +1222,14 @@ void taskNetwork(void *pvParameters)
}
else
{
if (millis() > NTP_Timeout)
{
NTP_Timeout = millis() + 86400000;
// Serial.println("Config NTP");
// setSyncProvider(getNtpTime);
Serial.println("Contacting Time Server");
configTime(3600 * timeZone, 0, "203.150.19.26", "110.170.126.101", "77.68.122.252");
configTime(3600 * config.timeZone, 0, "203.150.19.26", "110.170.126.101", "77.68.122.252");
vTaskDelay(3000 / portTICK_PERIOD_MS);
time_t systemTime;
time(&systemTime);
@ -1172,6 +1238,15 @@ void taskNetwork(void *pvParameters)
{
systemUptime = now();
}
pingTimeout = millis() + 2000;
if (config.vpn)
{
if (!wireguard_active())
{
Serial.println("Setup Wiregurad VPN!");
wireguard_setup();
}
}
}
if (config.aprs)
@ -1184,7 +1259,7 @@ void taskNetwork(void *pvParameters)
{
if (aprsClient.available())
{
pingTimeout = millis() + 300000; // Reset ping timout
// pingTimeout = millis() + 300000; // Reset ping timout
String line = aprsClient.readStringUntil('\n'); //อ่านค่าที่ Server ตอบหลับมาทีละบรรทัด
#ifdef DEBUG_IS
printTime();
@ -1245,20 +1320,51 @@ void taskNetwork(void *pvParameters)
}
}
// if (millis() > pingTimeout)
// {
// pingTimeout = millis() + 3000;
// Serial.print("Ping to " + vpn_IP.toString());
// if (ping_start(vpn_IP, 3, 0, 0, 10) == true)
// {
// Serial.println("VPN Ping Success!!");
// }
// else
// {
// Serial.println("VPN Ping Fail!");
// }
// }
if (millis() > pingTimeout)
{
pingTimeout = millis() + 300000;
Serial.print("Ping to " + WiFi.gatewayIP().toString());
if (ping_start(WiFi.gatewayIP(), 3, 0, 0, 10) == true)
Serial.println("Ping GW to " + WiFi.gatewayIP().toString());
if (ping_start(WiFi.gatewayIP(), 3, 0, 0, 5) == true)
{
Serial.println(" Success!!");
Serial.println("GW Success!!");
}
else
{
Serial.println(" Fail!");
Serial.println("GW Fail!");
WiFi.disconnect();
wifiTTL = 0;
}
if (config.vpn)
{
IPAddress vpnIP;
vpnIP.fromString(String(config.wg_gw_address));
Serial.println("Ping VPN to " + vpnIP.toString());
if (ping_start(vpnIP, 2, 0, 0, 10) == true)
{
Serial.println("VPN Ping Success!!");
}
else
{
Serial.println("VPN Ping Fail!");
wireguard_remove();
delay(3000);
wireguard_setup();
}
}
}
}
}

View File

@ -164,7 +164,7 @@ void setHTML(byte page)
webString += "timeStamp=Number(json.timeStamp);\n";
webString += "});\n";
webString += "if(active==1){\nleft.update(dBV,false);\nchart.redraw();\n";
webString += "var date=new Date(timeStamp * 1000).toLocaleString();\n";
webString += "var date=new Date(timeStamp * 1000);\n";
webString += "var head=date+\"[\"+Vrms.toFixed(3)+\"Vrms,\"+dBV.toFixed(1)+\"dBV]\\n\";\n";
webString += "document.getElementById(\"raw_txt\").value+=head+atob(raw)+\"\\n\";\n";
webString += "}\n";
@ -181,8 +181,11 @@ void setHTML(byte page)
String strActiveP6 = "";
String strActiveP7 = "";
String strActiveP8 = "";
String strActiveP9 = "";
if (page == 7)
if (page == 8)
strActiveP9 = "class=active";
else if (page == 7)
strActiveP8 = "class=active";
else if (page == 6)
strActiveP7 = "class=active";
@ -199,7 +202,12 @@ void setHTML(byte page)
else if (page == 0)
strActiveP1 = "class=active";
webString += "</head><body>\n";
webString += "<div class='w3-card-2 topnav notranslate' id='topnav'><b>ESP32 APRS Internet Gateway</div>\n";
String myStation;
if (config.aprs_ssid == 0)
myStation = String(config.aprs_mycall);
else
myStation = String(config.aprs_mycall) + "-" + String(config.aprs_ssid);
webString += "<div class='w3-card-2 topnav notranslate' id='topnav'><b>ESP32 APRS Internet Gateway by " + myStation + "</div>\n";
webString += "<div class=\"row\">\n";
webString += "<ul class=\"nav nav-tabs\" style=\"margin: 25px;\">\n";
webString += "<li role=\"presentation\"" + strActiveP1 + ">\n<a href=\"/\" id=\"channel_link_private_view\">Dash Board</a>\n</li>\n";
@ -210,6 +218,7 @@ void setHTML(byte page)
#ifdef SA818
webString += "<li role=\"presentation\"" + strActiveP8 + ">\n<a href=\"/radio\" id=\"channel_link_radio\">Radio</a>\n</li>\n";
#endif
webString += "<li role=\"presentation\"" + strActiveP9 + ">\n<a href=\"/vpn\" id=\"channel_link_radio\">VPN</a>\n</li>\n";
webString += "<li role=\"presentation\"" + strActiveP4 + ">\n<a href=\"/service\" id=\"channel_link_service\">Service</a>\n</li>\n";
webString += "<li role=\"presentation\"" + strActiveP5 + ">\n<a href=\"/system\" id=\"channel_link_system\">System</a>\n</li>\n";
webString += "<li role=\"presentation\"" + strActiveP7 + ">\n<a href=\"/test\" id=\"channel_link_system\">Test</a>\n</li>\n";
@ -621,6 +630,8 @@ void handle_setting()
webString += "</body></html>\n";
server.send(200, "text/html", webString); // send to someones browser when asked
delay(100);
webString.clear();
}
void handle_service()
@ -981,6 +992,8 @@ void handle_service()
webString += "</body></html>\n";
server.send(200, "text/html", webString); // send to someones browser when asked
delay(100);
webString.clear();
}
#ifdef SA818
@ -1117,7 +1130,11 @@ void handle_radio()
webString += "<div class=\"col-xs-10\">\n";
webString += "<form accept-charset=\"UTF-8\" action=\"/radio\" class=\"form-horizontal\" id=\"radio_form\" method=\"post\">\n";
#ifdef SR_FRS
webString += "<div>\n<h3>RF Module SR_FRS_1W</h3>\n";
#else
webString += "<div>\n<h3>RF Module SA818/SA868</h3>\n";
#endif
webString += "<div class=\"form-group\">\n";
webString += "<label class=\"col-sm-3 col-xs-12 control-label\">TX Frequency</label>\n";
webString += "<div class=\"col-sm-2 col-xs-6\"><input type=\"number\" id=\"tx_freq\" name=\"tx_freq\" min=\"144.0000\" max=\"148.0000\" step=\"0.0001\" value=\"" + String(config.freq_tx, 4) + "\" /></div>\n";
@ -1238,14 +1255,198 @@ void handle_radio()
webString += "</body></html>\n";
server.send(200, "text/html", webString); // send to someones browser when asked
// delay(100);
delay(100);
webString.clear();
}
#endif
void handle_vpn()
{
// byte *ptr;
bool vpnEn = false;
// bool taretime = false;
// bool davisEn = false;
// bool moniEn = false;
if (server.args() > 0)
{
// taretime = false;
for (uint8_t i = 0; i < server.args(); i++)
{
// Serial.print("SERVER ARGS ");
// Serial.print(server.argName(i));
// Serial.print("=");
// Serial.println(server.arg(i));
if (server.argName(i) == "vpnEnable")
{
if (server.arg(i) != "")
{
// if (isValidNumber(server.arg(i)))
if (String(server.arg(i)) == "OK")
vpnEn = true;
}
}
// if (server.argName(i) == "taretime") {
// if (server.arg(i) != "")
// {
// //if (isValidNumber(server.arg(i)))
// if (String(server.arg(i)) == "OK")
// taretime = true;
// }
// }
if (server.argName(i) == "wg_port")
{
if (server.arg(i) != "")
{
config.wg_port = server.arg(i).toInt();
}
}
if (server.argName(i) == "wg_public_key")
{
if (server.arg(i) != "")
{
strncpy(config.wg_public_key, server.arg(i).c_str(), 44);
config.wg_public_key[44] = 0;
}
}
if (server.argName(i) == "wg_private_key")
{
if (server.arg(i) != "")
{
strncpy(config.wg_private_key, server.arg(i).c_str(), 44);
config.wg_private_key[44] = 0;
}
}
if (server.argName(i) == "wg_peer_address")
{
if (server.arg(i) != "")
{
strcpy(config.wg_peer_address, server.arg(i).c_str());
}
}
if (server.argName(i) == "wg_local_address")
{
if (server.arg(i) != "")
{
strcpy(config.wg_local_address, server.arg(i).c_str());
}
}
if (server.argName(i) == "wg_netmask_address")
{
if (server.arg(i) != "")
{
strcpy(config.wg_netmask_address, server.arg(i).c_str());
}
}
if (server.argName(i) == "wg_gw_address")
{
if (server.arg(i) != "")
{
strcpy(config.wg_gw_address, server.arg(i).c_str());
}
}
}
config.vpn = vpnEn;
saveEEPROM();
// topBar(WiFi.RSSI());
}
// getMoisture(); // read sensor
// webMessage = "";
setHTML(8);
webString += "<div class=\"col-xs-10\">\n";
webString += "<form accept-charset=\"UTF-8\" action=\"/vpn\" class=\"form-horizontal\" id=\"setting_form\" method=\"post\">\n";
webString += "<div class = \"\">\n<h3>Wireguard Configuration</h3>\n";
String syncFlage = "";
if (config.vpn)
syncFlage = "checked";
webString += "<div class=\"form-group\">\n";
webString += "<label class=\"col-sm-2 col-xs-12 control-label\">Enable</label>\n";
webString += "<div class=\"col-sm-3 col-xs-6\"><input class=\"field_checkbox\" id=\"vpnEnable\" name=\"vpnEnable\" type=\"checkbox\" value=\"OK\" " + syncFlage + "/></div>\n";
webString += "</div>\n";
webString += "<div class=\"form-group\">\n";
webString += "<label class=\"col-sm-2 col-xs-12 control-label\">Server Address</label>\n";
webString += "<div class=\"col-sm-2 col-xs-6\"><input class=\"form-control\" id=\"wg_peer_address\" name=\"wg_peer_address\" type=\"text\" value=\"" + String(config.wg_peer_address) + "\" /></div>\n";
webString += "</div>\n";
webString += "<div class=\"form-group\">\n";
webString += "<label class=\"col-sm-2 col-xs-12 control-label\">Server Port</label>\n";
webString += "<div class=\"col-sm-1 col-xs-2\"><input class=\"form-control\" id=\"wg_port\" name=\"wg_port\" type=\"text\" value=\"" + String(config.wg_port) + "\" /></div>\n";
webString += "</div>\n";
webString += "<div class=\"form-group\">\n";
webString += "<label class=\"col-sm-2 col-xs-12 control-label\">Local Address</label>\n";
webString += "<div class=\"col-sm-2 col-xs-6\"><input class=\"form-control\" id=\"wg_local_address\" name=\"wg_local_address\" type=\"text\" value=\"" + String(config.wg_local_address) + "\" /></div>\n";
webString += "</div>\n";
webString += "<div class=\"form-group\">\n";
webString += "<label class=\"col-sm-2 col-xs-12 control-label\">Netmask</label>\n";
webString += "<div class=\"col-sm-2 col-xs-6\"><input class=\"form-control\" id=\"wg_netmask_address\" name=\"wg_netmask_address\" type=\"text\" value=\"" + String(config.wg_netmask_address) + "\" /></div>\n";
webString += "</div>\n";
webString += "<div class=\"form-group\">\n";
webString += "<label class=\"col-sm-2 col-xs-12 control-label\">Gateway</label>\n";
webString += "<div class=\"col-sm-2 col-xs-6\"><input class=\"form-control\" id=\"wg_gw_address\" name=\"wg_gw_address\" type=\"text\" value=\"" + String(config.wg_gw_address) + "\" /></div>\n";
webString += "</div>\n";
webString += "<div class=\"form-group\">\n";
webString += "<label class=\"col-sm-2 col-xs-12 control-label\">Public Key</label>\n";
webString += "<div class=\"col-sm-7 col-xs-10\"><input class=\"form-control\" id=\"wg_public_key\" name=\"wg_public_key\" type=\"text\" value=\"" + String(config.wg_public_key) + "\" /></div>\n";
webString += "</div>\n";
webString += "<div class=\"form-group\">\n";
webString += "<label class=\"col-sm-2 col-xs-12 control-label\">Private Key</label>\n";
webString += "<div class=\"col-sm-7 col-xs-10\"><input class=\"form-control\" id=\"wg_private_key\" name=\"wg_private_key\" type=\"text\" value=\"" + String(config.wg_private_key) + "\" /></div>\n";
webString += "</div>\n";
webString += "</div>\n"; // div general
webString += "<div class=\"form-group\">\n";
webString += "<label class=\"col-sm-2 col-xs-12 control-label\"></label>\n";
webString += "<div class=\"col-sm-2 col-xs-4\"><input class=\"btn btn-primary\" id=\"setting_form_sumbit\" name=\"commit\" type=\"submit\" value=\"Save Config\" maxlength=\"80\"/></div>\n";
webString += "</form>\n";
webString += "</div>\n";
webString += "</div>\n";
webString += "</body></html>\n";
server.send(200, "text/html", webString); // send to someones browser when asked
delay(100);
webString.clear();
}
void handle_system()
{
if (server.hasArg("updateTimeNtp"))
if (server.hasArg("updateTimeZone"))
{
for (uint8_t i = 0; i < server.args(); i++)
{
if (server.argName(i) == "SetTimeZone")
{
if (server.arg(i) != "")
{
config.timeZone = server.arg(i).toInt();
// Serial.println("WEB Config Time Zone);
configTime(3600 * config.timeZone, 0, "203.150.19.26");
}
break;
}
}
saveEEPROM();
}
else if (server.hasArg("updateTimeNtp"))
{
for (uint8_t i = 0; i < server.args(); i++)
{
@ -1258,7 +1459,7 @@ void handle_system()
if (server.arg(i) != "")
{
Serial.println("WEB Config NTP");
configTime(3600 * timeZone, 0, server.arg(i).c_str());
configTime(3600 * config.timeZone, 0, server.arg(i).c_str());
}
break;
}
@ -1299,9 +1500,9 @@ void handle_system()
// tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1, tmstruct.tm_mday, tmstruct.tm_hour, tmstruct.tm_min, tmstruct.tm_sec
time_t rtc = timeStamp - 25200;
time_t rtc = timeStamp - (config.timeZone * 3600);
timeval tv = {rtc, 0};
timezone tz = {TZ_SEC + DST_MN, 0};
timezone tz = {(0) + DST_MN, 0};
settimeofday(&tv, &tz);
// Serial.println("Update TIME " + server.arg(i));
@ -1429,6 +1630,10 @@ void handle_system()
}
saveEEPROM();
}
else if (server.hasArg("REBOOT"))
{
esp_restart();
}
struct tm tmstruct;
char strTime[20];
@ -1466,7 +1671,22 @@ void handle_system()
webString += "<td><div class=\"input-group\" id='ntp_update'><input class=\"form-control\" name=\"SetTimeNtp\" type=\"text\" value=\"203.150.19.26\" />\n";
webString += "</div></td>\n";
webString += "<td><input class=\"btn btn-primary\" id=\"setting_time_sumbit\" name=\"updateTimeNtp\" type=\"submit\" value=\"NTP Update\" maxlength=\"80\"/></td>\n";
webString += "</div>\n</form>\n</tr><tr>\n";
webString += "<form accept-charset=\"UTF-8\" action=\"/system\" class=\"form-horizontal\" id=\"time_form_ntp\" method=\"post\">\n";
webString += "<div class=\"form-group\">\n";
webString += "<td><label class=\"col-sm-2 col-xs-12 control-label\">Time Zone</label></td>\n";
webString += "<td><div class=\"input-group\" id='timeZone'><input class=\"form-control\" name=\"SetTimeZone\" type=\"text\" value=\"" + String(config.timeZone) + "\" />\n";
webString += "</div></td>\n";
webString += "<td><input class=\"btn btn-primary\" id=\"setting_time_sumbit\" name=\"updateTimeZone\" type=\"submit\" value=\"TZ Update\" maxlength=\"80\"/></td>\n";
webString += "</div>\n</form>\n</tr><tr>\n";
webString += "<form accept-charset=\"UTF-8\" action=\"/system\" class=\"form-horizontal\" id=\"reboot_form\" method=\"post\">\n";
webString += "<div class=\"form-group\">\n";
webString += "<td><label class=\"col-sm-2 col-xs-12 control-label\">SYSTEM</label></td>\n";
webString += "<td><input type='submit' class=\"btn btn-danger\" name=\"REBOOT\" value='REBOOT'></td>\n";
webString += "</div>\n</form>\n</tr></table>\n";
;
webString += "</div><hr>\n";
@ -1482,12 +1702,12 @@ void handle_system()
webString += "<div class=\"form-group\">\n";
webString += "<label class=\"col-sm-4 col-xs-12 control-label\">WiFi AP SSID</label>\n";
webString += "<div class=\"col-sm-4 col-xs-6\"><input class=\"form-control\" id=\"wifi_ssidAP\" name=\"wifi_ssidAP\" type=\"text\" value=\"" + String(config.wifi_ap_ssid) + "\" /></div>\n";
webString += "<div class=\"col-sm-6 col-xs-8\"><input class=\"form-control\" id=\"wifi_ssidAP\" name=\"wifi_ssidAP\" type=\"text\" value=\"" + String(config.wifi_ap_ssid) + "\" /></div>\n";
webString += "</div>\n";
webString += "<div class=\"form-group\">\n";
webString += "<label class=\"col-sm-4 col-xs-12 control-label\">WiFi AP PASSWORD</label>\n";
webString += "<div class=\"col-sm-4 col-xs-6\"><input class=\"form-control\" id=\"wifi_passAP\" name=\"wifi_passAP\" type=\"password\" value=\"" + String(config.wifi_ap_pass) + "\" /></div>\n";
webString += "<div class=\"col-sm-6 col-xs-12\"><input class=\"form-control\" id=\"wifi_passAP\" name=\"wifi_passAP\" type=\"password\" value=\"" + String(config.wifi_ap_pass) + "\" /></div>\n";
webString += "</div><hr width=\"50%\">\n";
webString += "<div class=\"form-group\">\n";
@ -1500,12 +1720,12 @@ void handle_system()
webString += "<div class=\"form-group\">\n";
webString += "<label class=\"col-sm-4 col-xs-12 control-label\">WiFi SSID</label>\n";
webString += "<div class=\"col-sm-4 col-xs-6\"><input class=\"form-control\" id=\"wifi_ssid\" name=\"wifi_ssid\" type=\"text\" value=\"" + String(config.wifi_ssid) + "\" /></div>\n";
webString += "<div class=\"col-sm-6 col-xs-8\"><input class=\"form-control\" id=\"wifi_ssid\" name=\"wifi_ssid\" type=\"text\" value=\"" + String(config.wifi_ssid) + "\" /></div>\n";
webString += "</div>\n";
webString += "<div class=\"form-group\">\n";
webString += "<label class=\"col-sm-4 col-xs-12 control-label\">WiFi PASSWORD</label>\n";
webString += "<div class=\"col-sm-4 col-xs-6\"><input class=\"form-control\" id=\"wifi_pass\" name=\"wifi_pass\" type=\"password\" value=\"" + String(config.wifi_pass) + "\" /></div>\n";
webString += "<div class=\"col-sm-6 col-xs-12\"><input class=\"form-control\" id=\"wifi_pass\" name=\"wifi_pass\" type=\"password\" value=\"" + String(config.wifi_pass) + "\" /></div>\n";
webString += "</div>\n";
webString += "<div class=\"form-group\">\n";
@ -1625,8 +1845,8 @@ void handle_system()
"});\n</script>\n";
webString += "</body></html>\n";
server.send(200, "text/html", webString); // send to someones browser when asked
delay(100);
webString.clear();
}
extern bool afskSync;
@ -1668,12 +1888,17 @@ void handle_realtime()
}
afskSync = false;
server.send(200, "text/html", String(jsonMsg));
delay(100);
free(jsonMsg);
}
void handle_test()
{
if (server.hasArg("REBOOT"))
{
esp_restart();
}
if (server.hasArg("sendBeacon"))
{
String tnc2Raw = send_fix_location();
@ -1707,7 +1932,8 @@ void handle_test()
webString += "<tr><td><form accept-charset=\"UTF-8\" action=\"/test\" class=\"form-horizontal\" id=\"test_form\" method=\"post\">\n";
webString += "<div style=\"margin-left: 20px;\"><input type='submit' class=\"btn btn-danger\" name=\"sendBeacon\" value='SEND BEACON'></div><br />\n";
webString += "<div style=\"margin-left: 20px;\">TNC2 RAW: <input id=\"raw\" name=\"raw\" type=\"text\" size=\"60\" value=\"" + String(config.aprs_mycall) + ">APE32I,WIDE1-1:>Test Status\"/></div>\n";
webString += "<div style=\"margin-left: 20px;\"><input type='submit' class=\"btn btn-primary\" name=\"sendRaw\" value='SEND RAW'></div>\n";
webString += "<div style=\"margin-left: 20px;\"><input type='submit' class=\"btn btn-primary\" name=\"sendRaw\" value='SEND RAW'></div> <br />\n";
webString += "<div style=\"margin-left: 20px;\"><input type='submit' class=\"btn btn-danger\" name=\"REBOOT\" value='REBOOT'></div><br />\n";
webString += "</form></td></tr>\n";
webString += "<tr><td><hr width=\"80%\" /></td></tr>\n";
webString += "<tr><td><div id=\"vumeter\" style=\"width: 300px; height: 200px; margin: 10px;\"></div></td>\n";
@ -1718,6 +1944,7 @@ void handle_test()
server.send(200, "text/html", webString); // send to someones browser when asked
delay(100);
webString.clear();
}
void handle_firmware()
@ -1728,6 +1955,91 @@ void handle_firmware()
// webMessage = "";
setHTML(5);
webString += "<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>\n";
webString += "<b>Current Hardware Version:</b> ESP32DR";
#ifdef SA818
#ifdef SR_FRS
webString += " <b>(MODEL:SR_FRS_1W)</b>";
#else
webString += " <b>(MODEL:SA818/SA868)</b>";
#endif
#else
webString += " <b>(MODEL: Simple)</b>";
#endif
webString += "<br /><b>Current Firmware Version:</b> V" + String(VERSION) + "\n<br/>";
webString += "<b>Develop by:</b> HS5TQA\n<br />";
webString += "<b>Chip ID:</b> " + String(strCID) + "\n<hr>";
webString += "<div class = \"col-pad\">\n<h3>Firmware Update</h3>\n";
webString += "<form method='POST' action='#' enctype='multipart/form-data' id='upload_form' class=\"form-horizontal\">\n";
webString += "<div class=\"form-group\">\n";
webString += "<label class=\"col-sm-2 col-xs-6 control-label\">FILE</label>\n";
webString += "<div class=\"col-sm-4 col-xs-12\"><input id=\"file\" name=\"update\" type=\"file\" onchange='sub(this)' /></div>\n";
// webString += "<div class=\"col-sm-4 col-xs-12\"><label id='file-input' for='file'> Choose file...</label></div>\n";
// webString += "<div class=\"col-sm-3 col-xs-4\"><input type='submit' class=\"btn btn-danger\" id=\"update_sumbit\" value='Firmware Update'></div>\n";
webString += "</div>\n";
webString += "<div class=\"form-group\">\n";
webString += "<label class=\"col-sm-2 col-xs-12 control-label\"></label>\n";
webString += "<div class=\"col-sm-3 col-xs-4\"><input type='submit' class=\"btn btn-danger\" id=\"update_sumbit\" value='Firmware Update'></div>\n";
webString += "</div>\n";
webString += "<div class=\"form-group\">\n";
webString += "<label class=\"col-sm-2 col-xs-12 control-label\"></label>\n";
webString += "<div id='prg'></div>\n";
webString += "<br><div id='prgbar'><div id='bar'></div></div>\n";
webString += "</div>\n";
webString += "</form></div>\n";
webString += "<script>"
"function sub(obj){"
"var fileName = obj.value.split('\\\\');"
"document.getElementById('file-input').innerHTML = ' '+ fileName[fileName.length-1];"
"};"
"$('form').submit(function(e){"
"e.preventDefault();"
"var form = $('#upload_form')[0];"
"var data = new FormData(form);"
"$.ajax({"
"url: '/update',"
"type: 'POST',"
"data: data,"
"contentType: false,"
"processData:false,"
"xhr: function() {"
"var xhr = new window.XMLHttpRequest();"
"xhr.upload.addEventListener('progress', function(evt) {"
"if (evt.lengthComputable) {"
"var per = evt.loaded / evt.total;"
"$('#prg').html('progress: ' + Math.round(per*100) + '%');"
"$('#bar').css('width',Math.round(per*100) + '%');"
"}"
"}, false);"
"return xhr;"
"},"
"success:function(d, s) {"
"console.log('success!') "
"},"
"error: function (a, b, c) {"
"}"
"});"
"});"
"</script>";
webString += "</body></html>\n";
server.send(200, "text/html", webString); // send to someones browser when asked
delay(100);
webString.clear();
}
void handle_upgrade()
{
char strCID[50];
uint64_t chipid = ESP.getEfuseMac();
sprintf(strCID, "%04X%08X", (uint16_t)(chipid >> 32), (uint32_t)chipid);
webString = "<html><body>";
// setHTML(5);
webString += "<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>\n";
webString += "<b>Current Hardware Version:</b> ESP32DR Simple\n<br/>";
webString += "<b>Current Firmware Version:</b> V" + String(VERSION) + "\n<br/>";
@ -1793,6 +2105,7 @@ void handle_firmware()
server.send(200, "text/html", webString); // send to someones browser when asked
delay(100);
webString.clear();
}
void handle_default()
@ -1970,12 +2283,14 @@ void webService()
#ifdef SA818
server.on("/radio", handle_radio);
#endif
server.on("/vpn", handle_vpn);
server.on("/default", handle_default);
server.on("/service", handle_service);
server.on("/system", handle_system);
server.on("/test", handle_test);
server.on("/realtime", handle_realtime);
server.on("/firmware", handle_firmware);
server.on("/upgrade", handle_upgrade);
/*handling uploading firmware file */
server.on(
"/update", HTTP_POST, []()
@ -2001,8 +2316,10 @@ void webService()
disableCore0WDT();
disableCore1WDT();
disableLoopWDT();
#ifdef I2S_INTERNAL
i2s_adc_disable(I2S_NUM_0);
dac_i2s_disable();
#endif
vTaskSuspend(taskAPRSHandle);
// vTaskSuspend(taskNetworkHandle);
config.aprs = false;

126
src/wireguard_vpn.cpp Normal file
View File

@ -0,0 +1,126 @@
//==============================================================================
// Wireguard VPN Client demo for LwIP/ESP32
//==============================================================================
//==============================================================================
// Includes
//==============================================================================
#include <Arduino.h>
#include "main.h"
//ใช้ตัวแปรโกลบอลในไฟล์ main.cpp
extern Configuration config;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include "wireguardif.h"
#include "wireguard.h"
#include "wireguard_vpn.h"
//==============================================================================
// Defines
//==============================================================================
#define CMP_NAME "WG_VPN"
#if !defined(WG_CLIENT_PRIVATE_KEY) || !defined(WG_PEER_PUBLIC_KEY)
#error "Please update configuratiuon with your VPN-specific keys!"
#endif
//==============================================================================
// Local types
//==============================================================================
//==============================================================================
// Local data
//==============================================================================
static struct netif wg_netif_struct = {0};
static struct netif *wg_netif = NULL;
static uint8_t wireguard_peer_index_local = WIREGUARDIF_INVALID_INDEX;
//==============================================================================
// Exported data
//==============================================================================
//==============================================================================
// Local functions
//==============================================================================
//==============================================================================
// Exported functions
//==============================================================================
bool wireguard_active()
{
if(wg_netif!=NULL) return true;
return false;
}
void wireguard_remove()
{
if(wg_netif!=NULL){
wireguardif_disconnect(wg_netif, wireguard_peer_index_local);
wireguardif_remove_peer(wg_netif, wireguard_peer_index_local);
//netif_set_down(wg_netif);
//netif_remove(&wg_netif_struct);
}
}
void wireguard_setup()
{
struct wireguardif_init_data wg;
struct wireguardif_peer peer;
ip_addr_t ipaddr = WG_LOCAL_ADDRESS;
ip_addr_t netmask = WG_LOCAL_NETMASK;
ip_addr_t gateway = WG_GATEWAY_ADDRESS;
ip_addr_t peer_address = WG_PEER_ADDRESS;
ipaddr_aton(config.wg_local_address,&ipaddr);
ipaddr_aton(config.wg_netmask_address,&netmask);
ipaddr_aton(config.wg_gw_address,&gateway);
ipaddr_aton(config.wg_peer_address,&peer_address);
// Setup the WireGuard device structure
// wg.private_key = WG_CLIENT_PRIVATE_KEY;
// wg.listen_port = WG_CLIENT_PORT;
wg.private_key = config.wg_private_key;
wg.listen_port = config.wg_port+1;
wg.bind_netif = NULL; // NB! not working on ESP32 even if set!
if(wg_netif==NULL){
// Register the new WireGuard network interface with lwIP
wg_netif = netif_add(&wg_netif_struct, ip_2_ip4(&ipaddr), ip_2_ip4(&netmask), ip_2_ip4(&gateway), &wg, &wireguardif_init, &ip_input);
// Mark the interface as administratively up, link up flag is set automatically when peer connects
netif_set_up(wg_netif);
}
// Initialise the first WireGuard peer structure
wireguardif_peer_init(&peer);
// peer.public_key = WG_PEER_PUBLIC_KEY;
peer.public_key = config.wg_public_key;
peer.preshared_key = NULL;
// Allow all IPs through tunnel
//peer.allowed_ip = IPADDR4_INIT_BYTES(0, 0, 0, 0);
IP_ADDR4(&peer.allowed_ip, 0, 0, 0, 0);
IP_ADDR4(&peer.allowed_mask, 0, 0, 0, 0);
// If we know the endpoint's address can add here
ip_addr_set(&peer.endpoint_ip, &peer_address);
//peer.endport_port = WG_PEER_PORT;
peer.endport_port = config.wg_port;
// Register the new WireGuard peer with the netwok interface
wireguardif_add_peer(wg_netif, &peer, &wireguard_peer_index_local);
if ((wireguard_peer_index_local != WIREGUARDIF_INVALID_INDEX) && !ip_addr_isany(&peer.endpoint_ip))
{
// Start outbound connection to peer
wireguardif_connect(wg_netif, wireguard_peer_index_local);
}
}
#ifdef __cplusplus
}
#endif // __cplusplus