mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 00:04:28 +01:00
Add option for AP discovery type (#351)
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -31,3 +31,6 @@ $PROJECT_DIR/
|
|||||||
|
|
||||||
# OS generated files
|
# OS generated files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
# Jetbrains IDE
|
||||||
|
.idea/
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ struct Config {
|
|||||||
uint8_t sleepTime1;
|
uint8_t sleepTime1;
|
||||||
uint8_t sleepTime2;
|
uint8_t sleepTime2;
|
||||||
uint8_t ble;
|
uint8_t ble;
|
||||||
|
uint8_t discovery;
|
||||||
String repo;
|
String repo;
|
||||||
String env;
|
String env;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,26 +1,30 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
#include "AsyncUDP.h"
|
#include "AsyncUDP.h"
|
||||||
|
#include "tag_db.h"
|
||||||
#ifndef defudpcomm
|
#ifndef defudpcomm
|
||||||
#define defudpcomm
|
#define defudpcomm
|
||||||
|
|
||||||
|
extern Config config;
|
||||||
|
|
||||||
class UDPcomm {
|
class UDPcomm {
|
||||||
public:
|
public:
|
||||||
UDPcomm();
|
UDPcomm();
|
||||||
~UDPcomm();
|
~UDPcomm();
|
||||||
void init();
|
void init();
|
||||||
void getAPList();
|
void getAPList();
|
||||||
void netProcessDataReq(struct espAvailDataReq* eadr);
|
void netProcessDataReq(struct espAvailDataReq* eadr);
|
||||||
void netProcessXferComplete(struct espXferComplete* xfc);
|
void netProcessXferComplete(struct espXferComplete* xfc);
|
||||||
void netProcessXferTimeout(struct espXferComplete* xfc);
|
void netProcessXferTimeout(struct espXferComplete* xfc);
|
||||||
void netSendDataAvail(struct pendingData* pending);
|
void netSendDataAvail(struct pendingData* pending);
|
||||||
void netTaginfo(struct TagInfo* taginfoitem);
|
void netTaginfo(struct TagInfo* taginfoitem);
|
||||||
private:
|
|
||||||
AsyncUDP udp;
|
private:
|
||||||
void processPacket(AsyncUDPPacket packet);
|
AsyncUDP udp;
|
||||||
|
void processPacket(AsyncUDPPacket packet);
|
||||||
|
void writeUdpPacket(uint8_t* buffer, uint16_t len, IPAddress senderIP);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void init_udp();
|
void init_udp();
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ void clearPending(tagRecord* taginfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void initAPconfig() {
|
void initAPconfig() {
|
||||||
DynamicJsonDocument APconfig(500);
|
DynamicJsonDocument APconfig(768);
|
||||||
File configFile = contentFS->open("/current/apconfig.json", "r");
|
File configFile = contentFS->open("/current/apconfig.json", "r");
|
||||||
if (configFile) {
|
if (configFile) {
|
||||||
DeserializationError error = deserializeJson(APconfig, configFile);
|
DeserializationError error = deserializeJson(APconfig, configFile);
|
||||||
@@ -333,6 +333,7 @@ void initAPconfig() {
|
|||||||
config.sleepTime1 = APconfig.containsKey("sleeptime1") ? APconfig["sleeptime1"] : 0;
|
config.sleepTime1 = APconfig.containsKey("sleeptime1") ? APconfig["sleeptime1"] : 0;
|
||||||
config.sleepTime2 = APconfig.containsKey("sleeptime2") ? APconfig["sleeptime2"] : 0;
|
config.sleepTime2 = APconfig.containsKey("sleeptime2") ? APconfig["sleeptime2"] : 0;
|
||||||
config.ble = APconfig.containsKey("ble") ? APconfig["ble"] : 0;
|
config.ble = APconfig.containsKey("ble") ? APconfig["ble"] : 0;
|
||||||
|
config.discovery = APconfig.containsKey("discovery") ? APconfig["discovery"] : 0;
|
||||||
#ifdef BLE_ONLY
|
#ifdef BLE_ONLY
|
||||||
config.ble = true;
|
config.ble = true;
|
||||||
#endif
|
#endif
|
||||||
@@ -370,6 +371,7 @@ void saveAPconfig() {
|
|||||||
APconfig["ble"] = config.ble;
|
APconfig["ble"] = config.ble;
|
||||||
APconfig["repo"] = config.repo;
|
APconfig["repo"] = config.repo;
|
||||||
APconfig["env"] = config.env;
|
APconfig["env"] = config.env;
|
||||||
|
APconfig["discovery"] = config.discovery;
|
||||||
serializeJsonPretty(APconfig, configFile);
|
serializeJsonPretty(APconfig, configFile);
|
||||||
configFile.close();
|
configFile.close();
|
||||||
xSemaphoreGive(fsMutex);
|
xSemaphoreGive(fsMutex);
|
||||||
|
|||||||
@@ -31,12 +31,22 @@ UDPcomm::~UDPcomm() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UDPcomm::init() {
|
void UDPcomm::init() {
|
||||||
if (udp.listenMulticast(UDPIP, UDPPORT)) {
|
if (config.discovery == 0) {
|
||||||
udp.onPacket([this](AsyncUDPPacket packet) {
|
if (udp.listenMulticast(UDPIP, UDPPORT)) {
|
||||||
if (packet.remoteIP() != WiFi.localIP()) {
|
udp.onPacket([this](AsyncUDPPacket packet) {
|
||||||
this->processPacket(packet);
|
if (packet.remoteIP() != WiFi.localIP()) {
|
||||||
}
|
this->processPacket(packet);
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (udp.listen(UDPPORT)) {
|
||||||
|
udp.onPacket([this](AsyncUDPPacket packet) {
|
||||||
|
if (packet.isBroadcast() && packet.remoteIP() != WiFi.localIP()) {
|
||||||
|
this->processPacket(packet);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setAPchannel();
|
setAPchannel();
|
||||||
}
|
}
|
||||||
@@ -87,7 +97,7 @@ void UDPcomm::processPacket(AsyncUDPPacket packet) {
|
|||||||
uint8_t buffer[sizeof(struct APlist) + 1];
|
uint8_t buffer[sizeof(struct APlist) + 1];
|
||||||
buffer[0] = PKT_APLIST_REPLY;
|
buffer[0] = PKT_APLIST_REPLY;
|
||||||
memcpy(buffer + 1, &APitem, sizeof(struct APlist));
|
memcpy(buffer + 1, &APitem, sizeof(struct APlist));
|
||||||
udp.writeTo(buffer, sizeof(buffer), senderIP, UDPPORT);
|
writeUdpPacket(buffer, sizeof(buffer), senderIP);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PKT_APLIST_REPLY: {
|
case PKT_APLIST_REPLY: {
|
||||||
@@ -158,40 +168,48 @@ void UDPcomm::getAPList() {
|
|||||||
uint8_t buffer[sizeof(struct APlist) + 1];
|
uint8_t buffer[sizeof(struct APlist) + 1];
|
||||||
buffer[0] = PKT_APLIST_REQ;
|
buffer[0] = PKT_APLIST_REQ;
|
||||||
memcpy(buffer + 1, &APitem, sizeof(struct APlist));
|
memcpy(buffer + 1, &APitem, sizeof(struct APlist));
|
||||||
udp.writeTo(buffer, sizeof(buffer), UDPIP, UDPPORT);
|
writeUdpPacket(buffer, sizeof(buffer), UDPIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPcomm::netProcessDataReq(struct espAvailDataReq* eadr) {
|
void UDPcomm::netProcessDataReq(struct espAvailDataReq* eadr) {
|
||||||
uint8_t buffer[sizeof(struct espAvailDataReq) + 1];
|
uint8_t buffer[sizeof(struct espAvailDataReq) + 1];
|
||||||
buffer[0] = PKT_AVAIL_DATA_INFO;
|
buffer[0] = PKT_AVAIL_DATA_INFO;
|
||||||
memcpy(buffer + 1, eadr, sizeof(struct espAvailDataReq));
|
memcpy(buffer + 1, eadr, sizeof(struct espAvailDataReq));
|
||||||
udp.writeTo(buffer, sizeof(buffer), UDPIP, UDPPORT);
|
writeUdpPacket(buffer, sizeof(buffer), UDPIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPcomm::netProcessXferComplete(struct espXferComplete* xfc) {
|
void UDPcomm::netProcessXferComplete(struct espXferComplete* xfc) {
|
||||||
uint8_t buffer[sizeof(struct espXferComplete) + 1];
|
uint8_t buffer[sizeof(struct espXferComplete) + 1];
|
||||||
buffer[0] = PKT_XFER_COMPLETE;
|
buffer[0] = PKT_XFER_COMPLETE;
|
||||||
memcpy(buffer + 1, xfc, sizeof(struct espXferComplete));
|
memcpy(buffer + 1, xfc, sizeof(struct espXferComplete));
|
||||||
udp.writeTo(buffer, sizeof(buffer), UDPIP, UDPPORT);
|
writeUdpPacket(buffer, sizeof(buffer), UDPIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPcomm::netProcessXferTimeout(struct espXferComplete* xfc) {
|
void UDPcomm::netProcessXferTimeout(struct espXferComplete* xfc) {
|
||||||
uint8_t buffer[sizeof(struct espXferComplete) + 1];
|
uint8_t buffer[sizeof(struct espXferComplete) + 1];
|
||||||
buffer[0] = PKT_XFER_TIMEOUT;
|
buffer[0] = PKT_XFER_TIMEOUT;
|
||||||
memcpy(buffer + 1, xfc, sizeof(struct espXferComplete));
|
memcpy(buffer + 1, xfc, sizeof(struct espXferComplete));
|
||||||
udp.writeTo(buffer, sizeof(buffer), UDPIP, UDPPORT);
|
writeUdpPacket(buffer, sizeof(buffer), UDPIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPcomm::netSendDataAvail(struct pendingData* pending) {
|
void UDPcomm::netSendDataAvail(struct pendingData* pending) {
|
||||||
uint8_t buffer[sizeof(struct pendingData) + 1];
|
uint8_t buffer[sizeof(struct pendingData) + 1];
|
||||||
buffer[0] = PKT_AVAIL_DATA_REQ;
|
buffer[0] = PKT_AVAIL_DATA_REQ;
|
||||||
memcpy(buffer + 1, pending, sizeof(struct pendingData));
|
memcpy(buffer + 1, pending, sizeof(struct pendingData));
|
||||||
udp.writeTo(buffer, sizeof(buffer), UDPIP, UDPPORT);
|
writeUdpPacket(buffer, sizeof(buffer), UDPIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPcomm::netTaginfo(struct TagInfo* taginfoitem) {
|
void UDPcomm::netTaginfo(struct TagInfo* taginfoitem) {
|
||||||
uint8_t buffer[sizeof(struct TagInfo) + 1];
|
uint8_t buffer[sizeof(struct TagInfo) + 1];
|
||||||
buffer[0] = PKT_TAGINFO;
|
buffer[0] = PKT_TAGINFO;
|
||||||
memcpy(buffer + 1, taginfoitem, sizeof(struct TagInfo));
|
memcpy(buffer + 1, taginfoitem, sizeof(struct TagInfo));
|
||||||
udp.writeTo(buffer, sizeof(buffer), UDPIP, UDPPORT);
|
writeUdpPacket(buffer, sizeof(buffer), UDPIP);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPcomm::writeUdpPacket(uint8_t *buffer, uint16_t len, IPAddress senderIP) {
|
||||||
|
if (config.discovery == 0) {
|
||||||
|
udp.writeTo(buffer, len, senderIP, UDPPORT);
|
||||||
|
} else {
|
||||||
|
udp.broadcastTo(buffer, len, UDPPORT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -312,7 +312,7 @@ void init_web() {
|
|||||||
Serial.println("getQueueItem: no queue item");
|
Serial.println("getQueueItem: no queue item");
|
||||||
request->send(404, "text/plain", "File not found");
|
request->send(404, "text/plain", "File not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (queueItem->data == nullptr) {
|
if (queueItem->data == nullptr) {
|
||||||
fs::File file = contentFS->open(queueItem->filename);
|
fs::File file = contentFS->open(queueItem->filename);
|
||||||
if (file) {
|
if (file) {
|
||||||
@@ -517,7 +517,7 @@ void init_web() {
|
|||||||
udpsync.getAPList();
|
udpsync.getAPList();
|
||||||
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
||||||
|
|
||||||
response->print("{");
|
response->print("{");
|
||||||
#ifdef C6_OTA_FLASHING
|
#ifdef C6_OTA_FLASHING
|
||||||
response->print("\"C6\": \"1\", ");
|
response->print("\"C6\": \"1\", ");
|
||||||
#else
|
#else
|
||||||
@@ -625,6 +625,9 @@ void init_web() {
|
|||||||
setenv("TZ", config.timeZone, 1);
|
setenv("TZ", config.timeZone, 1);
|
||||||
tzset();
|
tzset();
|
||||||
}
|
}
|
||||||
|
if (request->hasParam("discovery", true)) {
|
||||||
|
config.discovery = static_cast<uint8_t>(request->getParam("discovery", true)->value().toInt());
|
||||||
|
}
|
||||||
if (request->hasParam("repo", true)) {
|
if (request->hasParam("repo", true)) {
|
||||||
config.repo = request->getParam("repo", true)->value();
|
config.repo = request->getParam("repo", true)->value();
|
||||||
}
|
}
|
||||||
@@ -988,4 +991,4 @@ void dotagDBUpload(AsyncWebServerRequest *request, String filename, size_t index
|
|||||||
loadDB("/current/tagDBrestored.json");
|
loadDB("/current/tagDBrestored.json");
|
||||||
request->send(200, "text/plain", "Ok, restored.");
|
request->send(200, "text/plain", "Ok, restored.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -234,7 +234,7 @@
|
|||||||
<h4>Mode</h4>
|
<h4>Mode</h4>
|
||||||
<div style="max-width:400px;">
|
<div style="max-width:400px;">
|
||||||
<button class="button" id="doAutoflash">Automatic flash</button><br><br>
|
<button class="button" id="doAutoflash">Automatic flash</button><br><br>
|
||||||
With automatic flash, a tag is flashed to the latest firmware as soon as you connect it.
|
With automatic flash, a tag is flashed to the latest firmware as soon as you connect it.
|
||||||
It sets the mac automatically, tries to recognize the type, and starts flashing. Currently, Solum M2 tags only.
|
It sets the mac automatically, tries to recognize the type, and starts flashing. Currently, Solum M2 tags only.
|
||||||
<br><br>
|
<br><br>
|
||||||
<button class="button" id="doUSBflash">Command line</button><br><br>
|
<button class="button" id="doUSBflash">Command line</button><br><br>
|
||||||
@@ -375,7 +375,7 @@ options:
|
|||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
title="Stops updates at night, and put the tags to sleep.
|
title="Stops updates at night, and put the tags to sleep.
|
||||||
During the configured night time, this overrides the maximum sleep time.">
|
During the configured night time, this overrides the maximum sleep time.">
|
||||||
<label for="apcnight1">No updates between</label>
|
<label for="apcnight1">No updates between</label>
|
||||||
<select id="apcnight1"></select>
|
<select id="apcnight1"></select>
|
||||||
@@ -400,7 +400,7 @@ options:
|
|||||||
<p
|
<p
|
||||||
title="* Work in progress * When locking the tag inventory, the AP will only
|
title="* Work in progress * When locking the tag inventory, the AP will only
|
||||||
show tags that are already in the database. For now, the AP will still keep answering
|
show tags that are already in the database. For now, the AP will still keep answering
|
||||||
new tags, because that needs to be fixed in the radio firmware.
|
new tags, because that needs to be fixed in the radio firmware.
|
||||||
This will probably change in the future.">
|
This will probably change in the future.">
|
||||||
<label for="apclock">Lock tag inventory</label>
|
<label for="apclock">Lock tag inventory</label>
|
||||||
<select id="apclock">
|
<select id="apclock">
|
||||||
@@ -471,6 +471,13 @@ options:
|
|||||||
</optgroup>
|
</optgroup>
|
||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
|
<p title="Set to Broadcast if using a multi WiFi AP setup that does not support IGMP sniffing">
|
||||||
|
<label for="apcdiscovery">AP discovery method</label>
|
||||||
|
<select id="apcdiscovery">
|
||||||
|
<option value="0" selected>Multicast</option>
|
||||||
|
<option value="1">Broadcast</option>
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<input type="button" value="Save" id="apcfgsave"><span id="apcfgmsg"></span>
|
<input type="button" value="Save" id="apcfgsave"><span id="apcfgmsg"></span>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -784,6 +784,7 @@ document.addEventListener("loadTab", function (event) {
|
|||||||
$("#apctimezone").value = data.timezone;
|
$("#apctimezone").value = data.timezone;
|
||||||
$("#apcnight1").value = data.sleeptime1;
|
$("#apcnight1").value = data.sleeptime1;
|
||||||
$("#apcnight2").value = data.sleeptime2;
|
$("#apcnight2").value = data.sleeptime2;
|
||||||
|
$("#apcdiscovery").value = data.discovery;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
$('#apcfgmsg').innerHTML = '';
|
$('#apcfgmsg').innerHTML = '';
|
||||||
@@ -821,7 +822,7 @@ $('#apcfgsave').onclick = function () {
|
|||||||
formData.append('timezone', $('#apctimezone').value);
|
formData.append('timezone', $('#apctimezone').value);
|
||||||
formData.append('sleeptime1', $('#apcnight1').value);
|
formData.append('sleeptime1', $('#apcnight1').value);
|
||||||
formData.append('sleeptime2', $('#apcnight2').value);
|
formData.append('sleeptime2', $('#apcnight2').value);
|
||||||
|
formData.append('discovery', $('#apcdiscovery').value)
|
||||||
fetch("save_apcfg", {
|
fetch("save_apcfg", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: formData
|
body: formData
|
||||||
|
|||||||
Reference in New Issue
Block a user