in nmxact/mtech_lora/mtech_lora_xport.go [164:256]
func (lx *LoraXport) reass(dev string, port uint8, data []byte) {
lx.Lock()
defer lx.Unlock()
var err error
_, l := lx.reassMap.FindListener(dev, port, "reass")
if l == nil {
_, l = lx.msgMap.FindListener("", port, "req")
if l == nil {
log.Debugf("No LoRa listener for %s", dev)
return
}
lx.Unlock()
s, err := lx.acceptServerSesn(l, dev, port)
lx.Lock()
if err != nil {
log.Errorf("Cannot create server sesn: %v", err)
return
}
l = s.reassListener
}
str := hex.Dump(data)
log.Debugf("Raw data: %s", str)
bufR := bytes.NewReader(data)
var frag lora.CoapLoraFrag
var sFrag lora.CoapLoraFragStart
err = binary.Read(bufR, binary.LittleEndian, &frag)
if err != nil {
log.Debugf("Can't read header")
return
}
fragNum := frag.FragNum &^ lora.COAP_LORA_LAST_FRAG
if l.Data.Len() == 0 {
if fragNum != 0 {
log.Debugf("frag num != 0 with empty queue")
return
}
bufR.Seek(0, 0)
err = binary.Read(bufR, binary.LittleEndian, &sFrag)
if err != nil {
log.Debugf("Can't read in start header")
return
}
l.Crc = sFrag.Crc
l.Data.Write(data[3:])
l.NextFrag = 1
} else {
if fragNum != l.NextFrag {
log.Debugf("Frag out of sequence")
l.Data.Reset()
return
}
l.Data.Write(data[1:])
l.NextFrag++
}
if (frag.FragNum & lora.COAP_LORA_LAST_FRAG) != 0 {
data := l.Data.Bytes()
l.Data.Reset()
code := coap.COAPCode(data[1])
if code <= coap.DELETE {
_, l = lx.msgMap.FindListener(dev, port, "req")
if l == nil {
_, l = lx.msgMap.FindListener("", port, "req")
if l == nil {
log.Debugf("No LoRa listener for %s", dev)
return
}
lx.Unlock()
s, err := lx.acceptServerSesn(l, dev, port)
lx.Lock()
if err != nil {
log.Errorf("Cannot create server sesn: %v", err)
return
}
l = s.msgListener
}
} else {
_, l = lx.msgMap.FindListener(dev, port, "rsp")
}
if l != nil {
l.MsgChan <- data
} else {
log.Debugf("No LoRa listener for %s", dev)
}
}
}