Example #1
0
func (db *DB) PutRFMessage(m gears.RFMessage) error {
	if m.At == 0 {
		// Add the time in milliseconds since the epoch
		m.At = time.Now().UnixNano() / 1000000
	}
	glog.V(2).Infof("Put: %d %+v", m.At, m)
	// Form the key
	key := genRFKey(m.At)
	// Write data
	err := db.Put(key, m)
	if err != nil {
		return err
	}
	// Publish to subscribers
	db.RFPublish(m)
	return nil
}
Example #2
0
// Receive UDP packets, decode them, and output them
// The packet format is (by byte): flags, group, node_id, kind, data...
func (u *UDPGateway) Receiver() {
	for {
		glog.V(2).Infoln("******************************")
		pkt := make([]byte, 1600)
		pktLen, pktSrc, err := u.sock.ReadFromUDP(pkt)
		if err != nil {
			glog.Warning("UDP error: " + err.Error())
			continue
		}
		if pktLen < 3 {
			glog.Infof("UDP: got too short a packet (%d) from %v", pktLen, pktSrc)
			continue
		}
		if pktLen > 66+3 {
			glog.Infof("UDP: got too long a packet (%d) from %v", pktLen, pktSrc)
			continue
		}
		// got a reasonable packet
		data := pkt[0:pktLen]
		flags := data[0]
		groupId := data[1]
		nodeId := data[2]

		// Record the groupId -> addr mapping
		_ = u.groupMap.saveGroupToAddr(groupId, pktSrc)

		switch flags {
		// CTL + ACK + DST -> boot protocol pairing request
		// I.e: a node sends us its HW ID and we reply with groupId/nodeId/nodeType
		case 8:
			u.handlePairingRequest(pktSrc, groupId, nodeId, data)

		// CTL + ACK -> boot protocol upgrade or download request
		// I.e.: a node asks for the software Id & checksum or downloads a chunk
		case 5:
			switch pktLen {
			case UpgradeRequestLen + 3:
				u.handleUpgradeRequest(pktSrc, groupId, nodeId, data)
			case DownloadRequestLen + 3:
				u.handleDownloadRequest(pktSrc, groupId, nodeId, data)
			default:
				glog.Warningf("  Incorrect length=%d (!= %d)",
					pktLen, PairingRequestLen+3)
			}

		// Special packet to log from UDP GW itself
		case 9:
			glog.Infof("UDP-GW %d: %s", groupId, string(data[3:]))
			m := gears.RFMessage{
				Group: groupId,
				Node:  nodeId,
				At:    time.Now().UnixNano() / 1000000,
				Kind:  2, // LOG module
				Data:  append([]byte("GW "), data[3:]...),
			}
			u.Recv <- m
		// Standard data packet, produce a Message
		case 0, 1:
			m := gears.RFMessage{
				Group: groupId,
				Node:  nodeId,
				At:    time.Now().UnixNano() / 1000000,
			}
			if nodeId == 31 && len(m.Data)&1 == 0 {
				// hack to handle the fact that the early versions of the UDP GW node
				// don't use a _kind_ byte in the messages
				m.Kind = 8 // GW_RSSI_MODULE
				m.Data = data[3:]
			} else if pktLen > 3 {
				m.Kind = data[3]
				m.Data = data[4:]
			} else {
				m.Data = data[3:]
			}
			glog.Infof("UDP Recv: %s len=%d", m.RfTag(), pktLen)
			glog.V(4).Infof("  src=%v Pkt=%+v", pktSrc, m.Data[0:min(len(m.Data), 10)])
			// If an ACK is requested we should send that asap
			if flags&1 != 0 {
				u.sendPacket(groupId, nodeId, 0x6, []byte{})
			}
			// Now process what we got
			u.Recv <- m
		}
	}
}