private void ParseInPacket(byte[] addr, byte[] buf) { if(addr[0]==0) { Log.Warning("Packet with broadcast address via {0}:{1:X2}:{2}", _port.PortName, BitConverter.ToString(addr), BitConverter.ToString(buf)); return; } Topic devR=Topic.root.Get("/dev"); var msgTyp=(MsMessageType)(buf[0]>1?buf[1]:buf[3]); if(msgTyp==MsMessageType.SEARCHGW) { PrintPacket(null, new MsSearchGW(buf) { Addr=addr }, buf); this.Send(new MsGwInfo(_gwAddr) { Addr=new byte[] { 0 } }); } else if(msgTyp==MsMessageType.CONNECT) { var msg=new MsConnect(buf) { Addr=addr }; if(addr[0]==_gwAddr) { _advTick=DateTime.Now.AddSeconds(2.6); // Send Advertise in 2.6 sec. } if(addr[0]==0xFF) { PrintPacket(null, msg, buf); Send(new MsConnack(MsReturnCode.Accepted) { Addr=msg.Addr }); byte[] nAddr=new byte[1]; var r=new Random(DateTime.Now.Millisecond); do { nAddr[0]=(byte)(8+r.Next(0xF6)); //0x08 .. 0xFE } while(devR.children.Select(z => z.GetValue() as MsDevice).Any(z => z!=null && nAddr.SequenceEqual(z.Addr))); Log.Info("{0} new addr={1}", msg.ClientId, BitConverter.ToString(nAddr)); var pm=new MsPublish(null, PredefinedTopics[".cfg/XD_DeviceAddr"], QoS.AtLeastOnce) { Addr=msg.Addr, MessageId=1, Data=nAddr }; Send(pm); } else { // msg.Addr!=0xFF DVar<MsDevice> dev=devR.Get<MsDevice>(msg.ClientId); // if(!msg.CleanSession && (dev.value==null || !dev.value.Addr.SequenceEqual(msg.Addr) || dev.value.state==State.Disconnected || dev.value.state==State.Lost)) { PrintPacket(dev, msg, buf); Send(new MsConnack(MsReturnCode.InvalidTopicId) { Addr=msg.Addr }); return; } if(dev.value==null) { dev.value=new MsDevice(); } dev.value._gate=this; if(dev.value.Addr==null || !msg.Addr.SequenceEqual(dev.value.Addr)) { dev.value.Addr=msg.Addr; } PrintPacket(dev, msg, buf); Thread.Sleep(0); dev.value.Connect(msg); if(msg.Addr[0]==_gwAddr) { dev.value.via=_port.PortName; _gwTopic=dev; } else { dev.value.via= _gwTopic==null?string.Empty:_gwTopic.name; } } // msg.Addr!=0xFF } else { // msgType==Connect MsDevice dev=devR.children.Select(z => z.GetValue() as MsDevice).FirstOrDefault(z => z!=null && z.Addr!=null && addr.SequenceEqual(z.Addr) && z._gate==this); if(dev!=null && dev.state!=State.Disconnected && dev.state!=State.Lost) { dev.ParseInPacket(buf); } else { if(dev==null || dev.Owner==null) { Log.Debug("unknown device: [{0:X2}:{1}]", addr[0], BitConverter.ToString(buf)); } else { Log.Debug("inactive device: [{0}:{1}]", dev.Owner.name, BitConverter.ToString(buf)); } Send(new MsDisconnect() { Addr=addr }); } } }
private void Connect(MsConnect msg) { Addr=msg.Addr; if(msg.CleanSession) { foreach(var s in _subsscriptions) { Owner.Unsubscribe(s.path, s.func); } _subsscriptions.Clear(); _topics.Clear(); lock(_sendQueue) { _sendQueue.Clear(); } _waitAck=false; } _duration=msg.Duration*1100; ResetTimer(); if(msg.Will) { _willPath=string.Empty; _wilMsg=null; if(state!=State.ASleep) { Log.Info("{0}.state {1} => WILLTOPICREQ", Owner.path, state); } state=State.WillTopic; Send(new MsMessage(MsMessageType.WILLTOPICREQ)); } else { if(state!=State.ASleep) { Log.Info("{0}.state {1} => PreConnect", Owner.path, state); state=State.PreConnect; } else { state=State.Connected; } Send(new MsConnack(MsReturnCode.Accepted)); } Stat(false, MsMessageType.CONNECT, msg.CleanSession); }
private void ParseInPacket(byte[] buf, byte[] addr) { Topic devR=Topic.root.Get("/dev"); var msgTyp=(MsMessageType)(buf[0]>1?buf[1]:buf[3]); if(msgTyp==MsMessageType.GWINFO || msgTyp==MsMessageType.ADVERTISE) { return; } else if(msgTyp==MsMessageType.SEARCHGW) { PrintPacket(null, new MsSearchGW(buf) { Addr=addr }, buf); this.Send(new MsGwInfo(gwIdx) { Addr=IPAddress.Broadcast.GetAddressBytes() }); } else if(msgTyp==MsMessageType.CONNECT) { var msg=new MsConnect(buf) { Addr=addr }; DVar<MsDevice> dev=devR.Get<MsDevice>(msg.ClientId); if(!msg.CleanSession && (dev.value==null || dev.value.Addr!=msg.Addr || dev.value.state==State.Disconnected || dev.value.state==State.Lost)) { PrintPacket(dev, msg, buf); Send(new MsConnack(MsReturnCode.NotSupportes) { Addr=msg.Addr }); return; } if(dev.value==null) { dev.value=new MsDevice(); } dev.value._gate=this; if(dev.value.Addr==null || !msg.Addr.SequenceEqual(dev.value.Addr)) { dev.value.Addr=msg.Addr; } PrintPacket(dev, msg, buf); Thread.Sleep(0); dev.value.Connect(msg); dev.value.via="UDP"; } else { // msgType==Connect MsDevice dev=devR.children.Select(z => z.GetValue() as MsDevice).FirstOrDefault(z => z!=null && z.Addr!=null && addr.SequenceEqual(z.Addr) && z._gate==this); if(dev!=null && dev.state!=State.Disconnected && dev.state!=State.Lost) { dev.ParseInPacket(buf); } else { if(_verbose.value) { if(dev==null || dev.Owner==null) { Log.Debug("unknown device: {0}:{1}", BitConverter.ToString(addr), BitConverter.ToString(buf)); } else { Log.Debug("inactive device: [{0}] {1}:{2}", dev.Owner.name, BitConverter.ToString(addr), BitConverter.ToString(buf)); } } Send(new MsDisconnect() { Addr=addr }); } } }