sforkowany z mirror/meshtastic-firmware
add support for network ping testing
rodzic
bf347aad91
commit
b9438357b6
3
TODO.md
3
TODO.md
|
@ -1,6 +1,8 @@
|
|||
# High priority
|
||||
Items to complete before the first alpha release.
|
||||
|
||||
* rx signal measurements -3 marginal, -9 bad, 10 great
|
||||
* only send 10% of phone gps positions on the network
|
||||
* post sample video to signal forum
|
||||
* support non US frequencies
|
||||
* make an install script to let novices install software on their boards
|
||||
|
@ -178,3 +180,4 @@ Items after the first final candidate release.
|
|||
* don't send our times to other nodes
|
||||
* don't trust times from other nodes
|
||||
* draw compass rose based off local walking track
|
||||
* add requestResponse optional bool - use for location broadcasts when sending tests
|
|
@ -58,7 +58,7 @@ lib_deps =
|
|||
; RadioHead - I now use a custom build of this library
|
||||
; file:///home/kevinh/development/meshtastic/RadioHead
|
||||
TinyGPSPlus
|
||||
ESP8266_SSD1306
|
||||
https://github.com/geeksville/esp8266-oled-ssd1306.git ; ESP8266_SSD1306
|
||||
AXP202X_Library
|
||||
SPI
|
||||
OneButton
|
||||
|
|
21
src/GPS.cpp
21
src/GPS.cpp
|
@ -50,6 +50,8 @@ void GPS::perhapsSetRTC(const struct timeval *tv)
|
|||
}
|
||||
}
|
||||
|
||||
#include <time.h>
|
||||
|
||||
// for the time being we need to rapidly read from the serial port to prevent overruns
|
||||
void GPS::loop()
|
||||
{
|
||||
|
@ -65,11 +67,20 @@ void GPS::loop()
|
|||
{
|
||||
struct timeval tv;
|
||||
|
||||
// FIXME, this is a shit not right version of the standard def of unix time!!!
|
||||
tv.tv_sec = time.second() + time.minute() * 60 + time.hour() * 60 * 60 +
|
||||
24 * 60 * 60 * (date.month() * 31 + date.day() + 365 * (date.year() - 1970));
|
||||
|
||||
tv.tv_usec = time.centisecond() * (10 / 1000);
|
||||
/* Convert to unix time
|
||||
The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
|
||||
*/
|
||||
struct tm t;
|
||||
t.tm_sec = time.second();
|
||||
t.tm_min = time.minute();
|
||||
t.tm_hour = time.hour();
|
||||
t.tm_mday = date.day();
|
||||
t.tm_mon = date.month() - 1;
|
||||
t.tm_year = date.year() - 1900;
|
||||
t.tm_isdst = false;
|
||||
time_t res = mktime(&t);
|
||||
tv.tv_sec = res;
|
||||
tv.tv_usec = 0; // time.centisecond() * (10 / 1000);
|
||||
|
||||
perhapsSetRTC(&tv);
|
||||
}
|
||||
|
|
|
@ -145,6 +145,9 @@ void MeshService::handleFromRadio(MeshPacket *mp)
|
|||
releaseToPool(d);
|
||||
}
|
||||
assert(toPhoneQueue.enqueue(mp, 0) == pdTRUE); // FIXME, instead of failing for full queue, delete the oldest mssages
|
||||
|
||||
if(mp->payload.want_response)
|
||||
sendNetworkPing(mp->from);
|
||||
}
|
||||
else
|
||||
DEBUG_MSG("Dropping vetoed User message\n");
|
||||
|
@ -237,12 +240,18 @@ void MeshService::sendToMesh(MeshPacket *p)
|
|||
nodeDB.updateFrom(*p); // update our local DB for this packet (because phone might have sent position packets etc...)
|
||||
|
||||
// Strip out any time information before sending packets to other nodes - to keep the wire size small (and because other nodes shouldn't trust it anyways)
|
||||
if(p->has_payload && p->payload.which_variant == SubPacket_position_tag)
|
||||
if (p->has_payload && p->payload.which_variant == SubPacket_position_tag)
|
||||
p->payload.variant.position.time = 0;
|
||||
|
||||
// If the phone sent a packet just to us, don't send it out into the network
|
||||
if (p->to == nodeDB.getNodeNum())
|
||||
DEBUG_MSG("Dropping locally processed message\n");
|
||||
else
|
||||
{
|
||||
// Note: We might return !OK if our fifo was full, at that point the only option we have is to drop it
|
||||
if (radio.send(p) != ERRNO_OK)
|
||||
DEBUG_MSG("Dropped packet because send queue was full!\n");
|
||||
}
|
||||
}
|
||||
|
||||
MeshPacket *MeshService::allocForSending()
|
||||
|
@ -257,18 +266,18 @@ MeshPacket *MeshService::allocForSending()
|
|||
return p;
|
||||
}
|
||||
|
||||
void MeshService::sendNetworkPing()
|
||||
void MeshService::sendNetworkPing(NodeNum dest)
|
||||
{
|
||||
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
||||
assert(node);
|
||||
|
||||
if (node->has_position)
|
||||
sendOurPosition();
|
||||
sendOurPosition(dest);
|
||||
else
|
||||
sendOurOwner();
|
||||
sendOurOwner(dest);
|
||||
}
|
||||
|
||||
void MeshService::sendOurPosition()
|
||||
void MeshService::sendOurPosition(NodeNum dest)
|
||||
{
|
||||
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
||||
assert(node);
|
||||
|
@ -276,6 +285,7 @@ void MeshService::sendOurPosition()
|
|||
|
||||
// Update our local node info with our position (even if we don't decide to update anyone else)
|
||||
MeshPacket *p = allocForSending();
|
||||
p->to = dest;
|
||||
p->payload.which_variant = SubPacket_position_tag;
|
||||
p->payload.variant.position = node->position;
|
||||
// FIXME - for now we are leaving this in the sent packets (for debugging)
|
||||
|
|
|
@ -61,13 +61,13 @@ public:
|
|||
MeshPacket *allocForSending();
|
||||
|
||||
/// Called when the user wakes up our GUI, normally sends our latest location to the mesh (if we have it), otherwise at least sends our owner
|
||||
void sendNetworkPing();
|
||||
void sendNetworkPing(NodeNum dest = NODENUM_BROADCAST);
|
||||
|
||||
/// Send our owner info to a particular node
|
||||
void sendOurOwner(NodeNum dest = NODENUM_BROADCAST);
|
||||
private:
|
||||
/// Broadcasts our last known position
|
||||
void sendOurPosition();
|
||||
void sendOurPosition(NodeNum dest = NODENUM_BROADCAST);
|
||||
|
||||
/// Send a packet into the mesh - note p must have been allocated from packetPool. We will return it to that pool after sending.
|
||||
/// This is the ONLY function you should use for sending messages into the mesh, because it also updates the nodedb cache
|
||||
|
|
|
@ -106,6 +106,7 @@ typedef struct _SubPacket {
|
|||
Data data;
|
||||
User user;
|
||||
} variant;
|
||||
bool want_response;
|
||||
} SubPacket;
|
||||
|
||||
typedef struct _MeshPacket {
|
||||
|
@ -170,7 +171,7 @@ typedef struct _ToRadio {
|
|||
#define Position_init_default {0, 0, 0, 0, 0, 0}
|
||||
#define Data_init_default {_Data_Type_MIN, {0, {0}}}
|
||||
#define User_init_default {"", "", "", {0}}
|
||||
#define SubPacket_init_default {0, {Position_init_default}}
|
||||
#define SubPacket_init_default {0, {Position_init_default}, 0}
|
||||
#define MeshPacket_init_default {0, 0, false, SubPacket_init_default, 0}
|
||||
#define ChannelSettings_init_default {0, 0, _ChannelSettings_ModemConfig_MIN, {0}, ""}
|
||||
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default, false, ChannelSettings_init_default}
|
||||
|
@ -183,7 +184,7 @@ typedef struct _ToRadio {
|
|||
#define Position_init_zero {0, 0, 0, 0, 0, 0}
|
||||
#define Data_init_zero {_Data_Type_MIN, {0, {0}}}
|
||||
#define User_init_zero {"", "", "", {0}}
|
||||
#define SubPacket_init_zero {0, {Position_init_zero}}
|
||||
#define SubPacket_init_zero {0, {Position_init_zero}, 0}
|
||||
#define MeshPacket_init_zero {0, 0, false, SubPacket_init_zero, 0}
|
||||
#define ChannelSettings_init_zero {0, 0, _ChannelSettings_ModemConfig_MIN, {0}, ""}
|
||||
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero, false, ChannelSettings_init_zero}
|
||||
|
@ -230,6 +231,7 @@ typedef struct _ToRadio {
|
|||
#define SubPacket_position_tag 1
|
||||
#define SubPacket_data_tag 3
|
||||
#define SubPacket_user_tag 4
|
||||
#define SubPacket_want_response_tag 5
|
||||
#define MeshPacket_from_tag 1
|
||||
#define MeshPacket_to_tag 2
|
||||
#define MeshPacket_payload_tag 3
|
||||
|
@ -273,7 +275,8 @@ X(a, STATIC, SINGULAR, FIXED_LENGTH_BYTES, macaddr, 4)
|
|||
#define SubPacket_FIELDLIST(X, a) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,position,variant.position), 1) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,data,variant.data), 3) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,user,variant.user), 4)
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,user,variant.user), 4) \
|
||||
X(a, STATIC, SINGULAR, BOOL, want_response, 5)
|
||||
#define SubPacket_CALLBACK NULL
|
||||
#define SubPacket_DEFAULT NULL
|
||||
#define SubPacket_variant_position_MSGTYPE Position
|
||||
|
@ -396,16 +399,16 @@ extern const pb_msgdesc_t ToRadio_msg;
|
|||
#define Position_size 48
|
||||
#define Data_size 256
|
||||
#define User_size 72
|
||||
#define SubPacket_size 259
|
||||
#define MeshPacket_size 290
|
||||
#define SubPacket_size 261
|
||||
#define MeshPacket_size 292
|
||||
#define ChannelSettings_size 50
|
||||
#define RadioConfig_size 78
|
||||
#define RadioConfig_UserPreferences_size 24
|
||||
#define NodeInfo_size 157
|
||||
#define MyNodeInfo_size 24
|
||||
#define DeviceState_size 14971
|
||||
#define FromRadio_size 299
|
||||
#define ToRadio_size 293
|
||||
#define DeviceState_size 15037
|
||||
#define FromRadio_size 301
|
||||
#define ToRadio_size 295
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
|
@ -320,6 +320,10 @@ float estimatedHeading(double lat, double lon)
|
|||
return b;
|
||||
}
|
||||
|
||||
/// Sometimes we will have Position objects that only have a time, so check for valid lat/lon
|
||||
bool hasPosition(NodeInfo *n) {
|
||||
return n->has_position && (n->position.latitude != 0 || n->position.longitude != 0);
|
||||
}
|
||||
#define COMPASS_DIAM 44
|
||||
|
||||
/// We will skip one node - the one for us, so we just blindly loop over all nodes
|
||||
|
@ -370,7 +374,7 @@ void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, in
|
|||
*distStr = 0; // might not have location data
|
||||
float headingRadian = simRadian;
|
||||
NodeInfo *ourNode = nodeDB.getNode(nodeDB.getNodeNum());
|
||||
if (ourNode && ourNode->has_position && node->has_position)
|
||||
if (ourNode && hasPosition(ourNode) && hasPosition(node))
|
||||
{
|
||||
Position &op = ourNode->position, &p = node->position;
|
||||
float d = latLongToMeter(p.latitude, p.longitude, op.latitude, op.longitude);
|
||||
|
|
Ładowanie…
Reference in New Issue