Skip to content

Commit

Permalink
Fix CoAP over serial fragmentation problem
Browse files Browse the repository at this point in the history
When sending large packets over serial newtmgr was fragmenting
them twice in case of using CoAP over serial. First fragmentation
was performed inside Transceiver's TxCoap method,
before passing data to Tx method from SerialXport module.
Tx method from SerialXport then would once again fragment
data with the same MTU, but on this stage each fragment would get
a packet stat designator, which is necessary to determine if
a specific fragment is a start of new packet or continuing one.
Because of previous data fragmentation, each fragment was passed
to SerialXport Tx method individualy and each of this fragments
was incorrectly interpreted as a starting of a new packet.

To solve this issue, the fragmentation was moved from
Transceiver's TxCoap method to txCb functions, so now every
kind of transport can implement it's own fragmentation.
  • Loading branch information
m-gorecki committed Jun 5, 2024
1 parent cf9985f commit 1e2b81b
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 18 deletions.
10 changes: 8 additions & 2 deletions newtmgr/bll/bll_sesn.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,10 +415,16 @@ func (s *BllSesn) TxRxMgmtAsync(m *nmp.NmpMsg,

func (s *BllSesn) TxCoap(m coap.Message) error {
txRaw := func(b []byte) error {
return s.txWriteCharacteristic(s.resReqChr, b, !s.cfg.WriteRsp)
frags := nmxutil.Fragment(b, s.MtuOut())
for _, frag := range frags {
if err := s.txWriteCharacteristic(s.resReqChr, frag, !s.cfg.WriteRsp); err != nil {
return err
}
}
return nil
}

return s.txvr.TxCoap(txRaw, m, s.MtuOut())
return s.txvr.TxCoap(txRaw, m)
}

func (s *BllSesn) ListenCoap(mc nmcoap.MsgCriteria) (*nmcoap.Listener, error) {
Expand Down
10 changes: 4 additions & 6 deletions nmxact/mgmt/transceiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,18 +284,16 @@ func (t *Transceiver) TxRxMgmtAsync(txCb TxFn, req *nmp.NmpMsg, mtu int,
}
}

func (t *Transceiver) TxCoap(txCb TxFn, req coap.Message, mtu int) error {
func (t *Transceiver) TxCoap(txCb TxFn, req coap.Message) error {
b, err := nmcoap.Encode(req)
if err != nil {
return err
}

log.Debugf("tx CoAP request: %s", hex.Dump(b))
frags := nmxutil.Fragment(b, mtu)
for _, frag := range frags {
if err := txCb(frag); err != nil {
return err
}

if err := txCb(b); err != nil {
return err
}

return nil
Expand Down
2 changes: 1 addition & 1 deletion nmxact/mtech_lora/mtech_lora_sesn.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ func (s *LoraSesn) TxCoap(m coap.Message) error {
"Attempt to transmit over closed Lora session")
}

return s.txvr.TxCoap(s.sendFragments, m, s.MtuOut())
return s.txvr.TxCoap(s.sendFragments, m)
}

func (s *LoraSesn) ListenCoap(mc nmcoap.MsgCriteria) (*nmcoap.Listener, error) {
Expand Down
18 changes: 13 additions & 5 deletions nmxact/nmble/naked_sesn.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,14 +384,22 @@ func (s *NakedSesn) TxCoap(m coap.Message) error {
}

txRaw := func(b []byte) error {
if s.cfg.Ble.WriteRsp {
return s.conn.WriteChr(chr, b, "coap")
} else {
return s.conn.WriteChrNoRsp(chr, b, "coap")
frags := nmxutil.Fragment(b, s.MtuOut())
for _, frag := range frags {
if s.cfg.Ble.WriteRsp {
if err := s.conn.WriteChr(chr, frag, "coap"); err != nil {
return err
}
} else {
if err := s.conn.WriteChrNoRsp(chr, frag, "coap"); err != nil {
return err
}
}
}
return nil
}

return s.txvr.TxCoap(txRaw, m, s.MtuOut())
return s.txvr.TxCoap(txRaw, m)
}

return s.runTask(fn)
Expand Down
2 changes: 1 addition & 1 deletion nmxact/nmserial/serial_sesn.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ func (s *SerialSesn) TxCoap(m coap.Message) error {
return err
}

return s.txvr.TxCoap(s.sx.Tx, m, s.MtuOut())
return s.txvr.TxCoap(s.sx.Tx, m)
}

func (s *SerialSesn) ListenCoap(
Expand Down
11 changes: 8 additions & 3 deletions nmxact/udp/udp_sesn.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,16 @@ func (s *UdpSesn) AbortRx(seq uint8) error {

func (s *UdpSesn) TxCoap(m coap.Message) error {
txRaw := func(b []byte) error {
_, err := s.conn.WriteToUDP(b, s.addr)
return err
frags := nmxutil.Fragment(b, s.MtuOut())
for _, frag := range frags {
if _, err := s.conn.WriteToUDP(frag, s.addr); err != nil {
return err
}
}
return nil
}

return s.txvr.TxCoap(txRaw, m, s.MtuOut())
return s.txvr.TxCoap(txRaw, m)
}

func (s *UdpSesn) MgmtProto() sesn.MgmtProto {
Expand Down

0 comments on commit 1e2b81b

Please sign in to comment.