Inheritance: MsMessage
示例#1
0
      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 });
          }
        }
      }
示例#2
0
 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);
 }
示例#3
0
 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 });
     }
   }
 }