-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Expand file tree
/
Copy pathPacketAPI.cpp
More file actions
137 lines (123 loc) · 4.35 KB
/
Copy pathPacketAPI.cpp
File metadata and controls
137 lines (123 loc) · 4.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#ifdef USE_PACKET_API
#include "api/PacketAPI.h"
#include "MeshService.h"
#include "PowerFSM.h"
#include "RadioInterface.h"
#include "modules/NodeInfoModule.h"
#ifdef MESHTASTIC_PHONEAPI_ACCESS_CONTROL
// receivePacket() dispatches ToRadio straight to MeshService, bypassing handleToRadioPacket and so
// the lockdown admin gate. Fail the build rather than silently ship an admin-auth bypass.
#error "USE_PACKET_API is incompatible with MESHTASTIC_PHONEAPI_ACCESS_CONTROL (PacketAPI bypasses the lockdown admin gate)"
#endif
PacketAPI *packetAPI = nullptr;
PacketAPI *PacketAPI::create(PacketServer *_server)
{
if (!packetAPI) {
packetAPI = new PacketAPI(_server);
}
return packetAPI;
}
PacketAPI::PacketAPI(PacketServer *_server)
: concurrency::OSThread("PacketAPI"), isConnected(false), programmingMode(false), server(_server)
{
api_type = TYPE_PACKET;
}
int32_t PacketAPI::runOnce()
{
bool success = false;
#ifndef ARCH_PORTDUINO
if (config.bluetooth.enabled) {
if (!programmingMode) {
// in programmingMode we don't send any packets to the client except this one notify
programmingMode = true;
success = notifyProgrammingMode();
}
} else
#endif
{
success = sendPacket();
}
success |= receivePacket();
return success ? 10 : 50;
}
bool PacketAPI::receivePacket(void)
{
bool data_received = false;
while (server->hasData()) {
isConnected = true;
data_received = true;
powerFSM.trigger(EVENT_INPUT);
lastContactMsec = millis();
meshtastic_ToRadio *mr;
auto p = server->receivePacket()->move();
int id = p->getPacketId();
LOG_DEBUG("Received packet id=%u", id);
mr = (meshtastic_ToRadio *)&static_cast<DataPacket<meshtastic_ToRadio> *>(p.get())->getData();
switch (mr->which_payload_variant) {
case meshtastic_ToRadio_packet_tag: {
meshtastic_MeshPacket *mp = &mr->packet;
mp->transport_mechanism = meshtastic_MeshPacket_TransportMechanism_TRANSPORT_API;
printPacket("PACKET FROM QUEUE", mp);
service->handleToRadio(*mp);
break;
}
case meshtastic_ToRadio_want_config_id_tag: {
uint32_t config_nonce = mr->want_config_id;
LOG_INFO("Screen wants config, nonce=%u", config_nonce);
handleStartConfig();
break;
}
case meshtastic_ToRadio_heartbeat_tag:
if (mr->heartbeat.nonce == 1) {
if (nodeInfoModule) {
LOG_INFO("Broadcasting nodeinfo ping");
nodeInfoModule->sendOurNodeInfo(NODENUM_BROADCAST, true, 0, true);
}
} else {
LOG_DEBUG("Got client heartbeat");
}
break;
default:
LOG_ERROR("Error: unhandled meshtastic_ToRadio variant: %d", mr->which_payload_variant);
break;
}
}
return data_received;
}
bool PacketAPI::sendPacket(void)
{
if (server->available()) {
// fill dummy buffer; we don't use it, we directly send the fromRadio structure
uint32_t len = getFromRadio(txBuf);
if (len != 0) {
static uint32_t id = 0;
fromRadioScratch.id = ++id;
bool result = server->sendPacket(DataPacket<meshtastic_FromRadio>(id, fromRadioScratch));
if (!result) {
LOG_ERROR("send queue full");
}
return result;
}
}
return false;
}
bool PacketAPI::notifyProgrammingMode(void)
{
// tell the client we are in programming mode by sending only the bluetooth config state
LOG_INFO("force client into programmingMode");
memset(&fromRadioScratch, 0, sizeof(fromRadioScratch));
fromRadioScratch.id = nodeDB->getNodeNum();
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_tag;
fromRadioScratch.config.which_payload_variant = meshtastic_Config_bluetooth_tag;
fromRadioScratch.config.payload_variant.bluetooth = config.bluetooth;
return server->sendPacket(DataPacket<meshtastic_FromRadio>(0, fromRadioScratch));
}
/**
* return true if we got (once!) contact from our client and the server send queue is not full
*/
bool PacketAPI::checkIsConnected()
{
isConnected |= server->hasData();
return isConnected && server->available();
}
#endif