Browse Source

add support for replying last message if it was lost..

irr_shared
John-Mark Gurney 3 years ago
parent
commit
c4b6360695
5 changed files with 72 additions and 3 deletions
  1. +6
    -0
      PROTOCOL.md
  2. +37
    -1
      comms.c
  3. +8
    -0
      comms.h
  4. +13
    -0
      lora.py
  5. +8
    -2
      lora_comms.py

+ 6
- 0
PROTOCOL.md View File

@@ -10,6 +10,12 @@ initiator does not receive a response to it's query, it will resend the
request until it does. It is required that the responder be able to request until it does. It is required that the responder be able to
detect this, and resend the last response. detect this, and resend the last response.


The respondent will cache message responses after the session has been
confirmed, but before that, it is unneccessary, as there is no harm to
reprocess the messages. The more complicated part is dealing w/ a
missed confirmed reply, as the state will need to be back tracked (saved)
to decode the repeated confirm request.

both sides: both sides:
meta-AD('com.funkthat.lora.irrigation.<type>.v0.0.1') meta-AD('com.funkthat.lora.irrigation.<type>.v0.0.1')
key(<defined by type>) key(<defined by type>)


+ 37
- 1
comms.c View File

@@ -5,6 +5,19 @@ static const size_t MAC_LEN = 8;
static const size_t CHALLENGE_LEN = 16; static const size_t CHALLENGE_LEN = 16;
static const uint8_t domain[] = "com.funkthat.lora.irrigation.shared.v0.0.1"; static const uint8_t domain[] = "com.funkthat.lora.irrigation.shared.v0.0.1";


static int comms_pktbuf_equal(struct pktbuf a, struct pktbuf b);

/* returns 1 if equal, 0 if not equal */
static int
comms_pktbuf_equal(struct pktbuf a, struct pktbuf b)
{

if (a.pktlen != b.pktlen)
return 0;

return memcmp(a.pkt, b.pkt, a.pktlen) == 0;
}

size_t size_t
_strobe_state_size() _strobe_state_size()
{ {
@@ -48,6 +61,14 @@ comms_process(struct comms_state *cs, struct pktbuf pbin, struct pktbuf *pbout)
struct pktbuf pbmsg, pbrep; struct pktbuf pbmsg, pbrep;
ssize_t cnt, ret, msglen; ssize_t cnt, ret, msglen;


/* if the current msg matches the previous */
if (comms_pktbuf_equal(pbin, cs->cs_prevmsg)) {
/* send the previous response */
pbout->pktlen = cs->cs_prevmsgresp.pktlen;
memcpy(pbout->pkt, cs->cs_prevmsgresp.pkt, pbout->pktlen);
return;
}

strobe_attach_buffer(&cs->cs_state, pbin.pkt, pbin.pktlen); strobe_attach_buffer(&cs->cs_state, pbin.pkt, pbin.pktlen);


cnt = strobe_get(&cs->cs_state, APP_CIPHERTEXT, buf, pbin.pktlen - cnt = strobe_get(&cs->cs_state, APP_CIPHERTEXT, buf, pbin.pktlen -
@@ -108,8 +129,23 @@ comms_process(struct comms_state *cs, struct pktbuf pbin, struct pktbuf *pbout)
ret += strobe_put(&cs->cs_state, MAC, NULL, MAC_LEN); ret += strobe_put(&cs->cs_state, MAC, NULL, MAC_LEN);


break; break;
}
}
} }


/* set the output buffer length */
pbout->pktlen = ret; pbout->pktlen = ret;

if (ret != 0) {
/* we accepted a new message store it */

/* store the req */
cs->cs_prevmsg.pkt = cs->cs_prevmsgbuf;
cs->cs_prevmsg.pktlen = pbin.pktlen;
memcpy(cs->cs_prevmsg.pkt, pbin.pkt, pbin.pktlen);

/* store the response */
cs->cs_prevmsgresp.pkt = cs->cs_prevmsgrespbuf;
cs->cs_prevmsgresp.pktlen = pbout->pktlen;
memcpy(cs->cs_prevmsgresp.pkt, pbout->pkt, pbout->pktlen);
}
} }

+ 8
- 0
comms.h View File

@@ -3,6 +3,8 @@


#include <strobe.h> #include <strobe.h>


#define COMMS_MAXMSG 64

struct pktbuf { struct pktbuf {
uint8_t *pkt; uint8_t *pkt;
uint16_t pktlen; uint16_t pktlen;
@@ -23,6 +25,12 @@ struct comms_state {
strobe_s cs_start; /* special starting state cache */ strobe_s cs_start; /* special starting state cache */


process_msgfunc_t cs_procmsg; process_msgfunc_t cs_procmsg;

struct pktbuf cs_prevmsg;
struct pktbuf cs_prevmsgresp;

uint8_t cs_prevmsgbuf[COMMS_MAXMSG];
uint8_t cs_prevmsgrespbuf[COMMS_MAXMSG];
}; };


size_t _strobe_state_size(); size_t _strobe_state_size();


+ 13
- 0
lora.py View File

@@ -311,6 +311,19 @@ class TestLORANode(unittest.IsolatedAsyncioTestCase):
_self.assertEqual(expectlen, _self.assertEqual(expectlen,
outbuf.pktlen) outbuf.pktlen)


# save what was originally replied
origmsg = outbuf._from()

# pretend that the reply didn't make it
r = make_pktbuf(gb)
outbuf = make_pktbuf(outbytes)

lora_comms.comms_process(commstate, r,
outbuf)

# make sure that the reply matches previous
_self.assertEqual(origmsg, outbuf._from())

# pass the reply back # pass the reply back
await self.put(outbytes[:outbuf.pktlen]) await self.put(outbytes[:outbuf.pktlen])




+ 8
- 2
lora_comms.py View File

@@ -1,5 +1,5 @@
from ctypes import Structure, POINTER, CFUNCTYPE, pointer from ctypes import Structure, POINTER, CFUNCTYPE, pointer
from ctypes import c_uint8, c_uint16, c_ssize_t, c_size_t, c_uint64
from ctypes import c_uint8, c_uint16, c_ssize_t, c_size_t, c_uint64, c_int
from ctypes import CDLL from ctypes import CDLL


class PktBuf(Structure): class PktBuf(Structure):
@@ -21,7 +21,6 @@ def make_pktbuf(s):
if isinstance(s, bytearray): if isinstance(s, bytearray):
obj = s obj = s
pb.pkt = pointer(c_uint8.from_buffer(s)) pb.pkt = pointer(c_uint8.from_buffer(s))
#print('mp:', repr(pb.pkt))
else: else:
obj = (c_uint8 * len(s))(*s) obj = (c_uint8 * len(s))(*s)
pb.pkt = obj pb.pkt = obj
@@ -44,8 +43,15 @@ class CommsState(Structure):
_fields_ = [ _fields_ = [
# The alignment of these may be off # The alignment of these may be off
('cs_state', c_uint64 * _strobe_state_u64_cnt), ('cs_state', c_uint64 * _strobe_state_u64_cnt),
('cs_comm_state', c_int),
('cs_start', c_uint64 * _strobe_state_u64_cnt), ('cs_start', c_uint64 * _strobe_state_u64_cnt),
('cs_procmsg', process_msgfunc_t), ('cs_procmsg', process_msgfunc_t),

('cs_prevmsg', PktBuf),
('cs_prevmsgresp', PktBuf),

('cs_prevmsgbuf', c_uint8 * 64),
('cs_prevmsgrespbuf', c_uint8 * 64),
] ]


for func, ret, args in [ for func, ret, args in [


Loading…
Cancel
Save