loraserver 源码解析 (五) lora-gateway-bridge 与 gateway 通信协议的具体实现

详细的协议内容请参考前文 loraserver 源码解析 (四) lora-gateway-bridge

bridge 启动后会开启3个 routine

1, cleanup 间隔一分钟,不断地清理 非active得gateway

2.    readPackets,侦听默认1700的udp端口,收到的udp报文 就再新建 routine 来处理,保证接收routine不阻塞。

3.    sendPackets,不断侦听 udpSendChan channel上是否有待发送的报文,有就发送出去

先看 readPackets routine

func (b *Backend) readPackets() error {
	buf := make([]byte, 65507) // max udp data size
	for {
		i, addr, err := b.conn.ReadFromUDP(buf)
		if err != nil {
			if b.closed {
				return nil
			}

			log.WithError(err).Error("gateway: read from udp error")
			continue
		}
		data := make([]byte, i)
		copy(data, buf[:i])
		go func(data []byte) {
			if err := b.handlePacket(addr, data); err != nil {
				log.WithFields(log.Fields{
					"data_base64": base64.StdEncoding.EncodeToString(data),
					"addr":        addr,
				}).Errorf("gateway: could not handle packet: %s", err)
			}
		}(data)
	}
}

b.conn.ReadFromUDP(buf) 后 buf拿到了gateway上传的 packet

拷贝到 data 后 再开启新的 routine 处理data,然后继续接收新的 udp 报文

如果没有新的报文到达  readPackets 就阻塞在 b.conn.ReadFromUDP(buf) 这里


再来看看怎么解析 data 报文

 Bytes  | Function
:------:|---------------------------------------------------------------------
 0      | protocol version = 2
 1-2    | random token
 3      | PUSH_DATA identifier 0x00
 4-11   | Gateway unique identifier (MAC address)
 12-end | JSON object, starting with {, ending with }, see section 4

取出data[3],看看是啥类型的包?

#define PKT_PUSH_DATA   0
#define PKT_PUSH_ACK    1
#define PKT_PULL_DATA   2
#define PKT_PULL_RESP   3
#define PKT_PULL_ACK    4
#define PKT_TX_ACK      5

gateway上传数据是 PKT_PUSH_DAT, 相当于 brige代码里的 PushData

func (b *Backend) handlePacket(addr *net.UDPAddr, data []byte) error {
	pt, err := GetPacketType(data)
	if err != nil {
		return err
	}
	switch pt {
	case PushData:
		return b.handlePushData(addr, data)
	case PullData:
		return b.handlePullData(addr, data)
	case TXACK:
		return b.handleTXACK(addr, data)
	default:
		return fmt.Errorf("gateway: unknown packet type: %s", pt)
	}
}

稍后, data被转解析成 brige的 PushDataPacket 结构

然后生成这个PUSH相应的 ack 包 推送到 udpSendChan 管道中, 文章开头提到的 sendPackets routine 是一直侦听 udpSendChan 管道的,它收到数据后发回给 gateway

data接着被处理,若是多个终端数据打包成的包,则解析后一一拆分,解析成一个个的packets后逐个 转交给 rxChan 管道

bridge 还有个专门等待 rxChan数据的 routine,这个rourine接收到 rxChan 传过来的 packet后, 转发给 mqtt broker

话题即为 gateway/ node 的 mac /rx

由于 loraserver 订阅了 这个 话题,mqtt broker 转发给 loraserver


从日志上也能反馈出一些处理流程

INFO[61640] gateway: received udp packet from gateway     addr="127.0.0.1:48878" protocol_version=2 type=PushData
INFO[61640] gateway: rxpk packet received                 addr="127.0.0.1:48878" data="gCSa8QZQZQAMliBl0jg75+2lgQvFcA==" mac=1234567812345678
INFO[61640] backend: publishing packet                    qos=0 topic=gateway/1234567812345678/rx





猜你喜欢

转载自blog.csdn.net/wangjunsheng/article/details/80921824
今日推荐