Ejemplo n.º 1
0
 private void Disconnect(ushort duration=0) {
   if(duration==0 && !string.IsNullOrEmpty(_willPath)) {
     TopicInfo ti = GetTopicInfo(_willPath, false);
     SetValue(ti, _wilMsg, false);
   }
   if(duration>0) {
     if(state==State.ASleep) {
       state=State.AWake;
     }
     ResetTimer(3100+duration*1550);  // t_wakeup
     this.Send(new MsDisconnect());
     _tryCounter=0;
     state=State.ASleep;
     var st=Owner.Get<long>(".cfg/XD_SleepTime", Owner);
     st.saved=true;
     st.SetValue((short)duration, new TopicChanged(TopicChanged.ChangeArt.Value, Owner) { Source=st });
   } else {
     _activeTimer.Change(Timeout.Infinite, Timeout.Infinite);
     this._gate=null;
     if(state!=State.Lost) {
       state=State.Disconnected;
       if(Owner!=null) {
         Log.Info("{0} Disconnected", Owner.path);
       }
     }
   }
   _waitAck=false;
 }
Ejemplo n.º 2
0
 public static void ProcessInPacket(IMsGate gate, byte[] addr, byte[] buf, int start, int end) {
   var msg=MsMessage.Parse(buf, start, end);
   if(msg==null) {
     if(_verbose.value) {
       Log.Warning("r {0}: {1}  bad message", gate.Addr2If(addr), BitConverter.ToString(buf, start, end-start));
     }
     return;
   }
   if(msg.MsgTyp==MsMessageType.ADVERTISE || msg.MsgTyp==MsMessageType.GWINFO) {
     return;
   }
   if(_verbose.value) {
     Log.Debug("r {0}: {1}  {2}", gate.Addr2If(addr), BitConverter.ToString(buf, start, end-start), msg.ToString());
   }
   if(msg.MsgTyp==MsMessageType.SEARCHGW && ((msg as MsSearchGW).radius==0 || (msg as MsSearchGW).radius==1)) {
     gate.SendGw((MsDevice)null, new MsGwInfo(gate.gwIdx));
     return;
   }
   Topic devR=Topic.root.Get("/dev");
   if(msg.MsgTyp==MsMessageType.DHCP_REQ) {
     var dr=msg as MsDhcpReq;
     if((dr.radius==0 || dr.radius==1)) {
       var r=new Random((int)DateTime.Now.Ticks);
       List<byte> ackAddr=new List<byte>();
       byte[] respPrev=null;
       foreach(byte hLen in dr.hLen) {
         if(hLen==0) {
           continue;
         } else if(hLen<=8) {
           byte[] resp;
           if(respPrev!=null && respPrev.Length==hLen) {
             resp=respPrev;
           } else {
             resp=new byte[hLen];
             for(int i=0; i<5; i++) {
               for(int j=0; j<resp.Length; j++) {
                 resp[j]=(byte)r.Next(j==0?4:0, (i<3 && hLen==1)?31:(j==0?254:255));
               }
               if(devR.children.Select(z => z as DVar<MsDevice>).Where(z => z!=null && z.value!=null).All(z => !z.value.CheckAddr(resp))) {
                 break;
               } else if(i==4) {
                 for(int j=0; j<resp.Length; j++) {
                   resp[j]=0xFF;
                 }
               }
             }
             respPrev=resp;
           }
           ackAddr.AddRange(resp);
         } else {
           if(_verbose.value) {
             Log.Warning("r {0}: {1}  DhcpReq.hLen is too high", gate.Addr2If(addr), BitConverter.ToString(buf, start, end-start));
           }
           ackAddr=null;
           break;
         }
       }
       if(ackAddr!=null) {
         gate.SendGw((MsDevice)null, new MsDhcpAck(gate.gwIdx, dr.xId, ackAddr.ToArray()));
       }
     }
     return;
   }
   if(msg.MsgTyp==MsMessageType.CONNECT) {
     var cm=msg as MsConnect;
     DVar<MsDevice> dDev=devR.Get<MsDevice>(cm.ClientId);
     if(dDev.value==null) {
       dDev.value=new MsDevice(gate, addr);
       Thread.Sleep(0);
       dDev.value.Owner=dDev;
     } else {
       gate.RemoveNode(dDev.value);
       dDev.value._gate=gate;
       dDev.value.Addr=addr;
     }
     gate.AddNode(dDev.value);
     dDev.value.Connect(cm);
     foreach(var dub in devR.children.Select(z => z.GetValue() as MsDevice).Where(z => z!=null && z!=dDev.value && z.Addr!=null && z.Addr.SequenceEqual(addr) && z._gate==gate).ToArray()) {
       dub.Addr=null;
       dub._gate=null;
       dub.state=State.Disconnected;
     }
   } else {
     MsDevice dev=devR.children.Select(z => z.GetValue() as MsDevice).FirstOrDefault(z => z!=null && z.Addr!=null && z.Addr.SequenceEqual(addr) && z._gate==gate);
     if(dev!=null && ((dev.state!=State.Disconnected && dev.state!=State.Lost) || msg.MsgTyp==MsMessageType.CONNECT)) {
       dev.ProcessInPacket(msg);
     } else {
       if(dev==null || dev.Owner==null) {
         Log.Debug("{0} unknown device", gate.Addr2If(addr));
         gate.SendGw(addr, new MsDisconnect());
       } else {
         Log.Debug("{0} inactive device: {1}", gate.Addr2If(addr), dev.Owner.path);
         gate.SendGw(dev, new MsDisconnect());
       }
     }
   }
 }
Ejemplo n.º 3
0
        internal bool ProcessInPacket(IMsGate gate, byte[] addr, byte[] buf, int start, int end)
        {
            var msg = MsMessage.Parse(buf, start, end);

            if (msg == null)
            {
                if (verbose)
                {
                    Log.Warning("r {0}: {1}  bad message", gate.Addr2If(addr), BitConverter.ToString(buf, start, end - start));
                }
                return(false);
            }
            if (msg.MsgTyp == MsMessageType.ADVERTISE || msg.MsgTyp == MsMessageType.GWINFO)
            {
                return(true);
            }
            if (verbose)
            {
                Log.Debug("r {0}: {1}  {2}", gate.Addr2If(addr), BitConverter.ToString(buf, start, end - start), msg.ToString());
            }
            if (msg.MsgTyp == MsMessageType.SEARCHGW)
            {
                if ((msg as MsSearchGW).radius == 0 || (msg as MsSearchGW).radius == gate.gwRadius)
                {
                    gate.SendGw((MsDevice)null, new MsGwInfo(gate.gwIdx));
                }
                return(true);
            }
            if (msg.MsgTyp == MsMessageType.DHCP_REQ)
            {
                var dr = msg as MsDhcpReq;
                if ((dr.radius == 0 || dr.radius == 1))
                {
                    List <byte> ackAddr  = new List <byte>();
                    byte[]      respPrev = null;
                    foreach (byte hLen in dr.hLen)
                    {
                        if (hLen == 0)
                        {
                            continue;
                        }
                        else if (hLen <= 8)
                        {
                            byte[] resp;
                            if (respPrev != null && respPrev.Length == hLen)
                            {
                                resp = respPrev;
                            }
                            else
                            {
                                resp = new byte[hLen];
                                for (int i = 0; i < 5; i++)
                                {
                                    for (int j = 0; j < resp.Length; j++)
                                    {
                                        resp[j] = (byte)_rand.Next(j == 0 ? 4 : 0, (i < 3 && hLen == 1) ? 31 : (j == 0 ? 254 : 255));
                                    }
                                    if (!_devs.Any(z => z.gwIdx == gate.gwIdx && z.CheckAddr(resp)))
                                    {
                                        break;
                                    }
                                    else if (i == 4)
                                    {
                                        for (int j = 0; j < resp.Length; j++)
                                        {
                                            resp[j] = 0xFF;
                                        }
                                    }
                                }
                                respPrev = resp;
                            }
                            ackAddr.AddRange(resp);
                        }
                        else
                        {
                            if (verbose)
                            {
                                Log.Warning("r {0}: {1}  DhcpReq.hLen is too high", gate.Addr2If(addr), BitConverter.ToString(buf, start, end - start));
                            }
                            ackAddr = null;
                            break;
                        }
                    }
                    if (ackAddr != null)
                    {
                        gate.SendGw((MsDevice)null, new MsDhcpAck(gate.gwIdx, dr.xId, ackAddr.ToArray()));
                    }
                }
                return(true);
            }
            if (msg.MsgTyp == MsMessageType.CONNECT)
            {
                var      cm  = msg as MsConnect;
                MsDevice dev = _devs.FirstOrDefault(z => z.owner != null && z.owner.name == cm.ClientId);
                if (dev == null)
                {
                    var dt = Topic.root.Get("/dev/" + cm.ClientId, true, _owner);
                    dev = new MsDevice(this, dt);
                    _devs.Add(dev);
                    dt.SetAttribute(Topic.Attribute.Readonly);
                    dt.SetField("editor", "MsStatus", _owner);
                    dt.SetField("cctor.MqsDev", string.Empty, _owner);
                }
                dev._gate = gate;
                dev.addr  = addr;
                dev.Connect(cm);
                foreach (var dub in _devs.Where(z => z != dev && z.CheckAddr(addr) && z._gate == gate).ToArray())
                {
                    dub.addr  = null;
                    dub._gate = null;
                    dub.state = State.Disconnected;
                }
            }
            else
            {
                MsDevice dev = _devs.FirstOrDefault(z => z.addr != null && z.addr.SequenceEqual(addr) && z._gate == gate);
                if (dev != null && (dev.state != State.Disconnected && dev.state != State.Lost))
                {
                    dev.ProcessInPacket(msg);
                }
                else
                {
                    if (verbose)
                    {
                        if (dev == null || dev.owner == null)
                        {
                            Log.Debug("{0} unknown device", gate.Addr2If(addr));
                        }
                        else
                        {
                            Log.Debug("{0} inactive device: {1}", gate.Addr2If(addr), dev.owner.path);
                        }
                    }
                    gate.SendGw(addr, new MsDisconnect());
                }
            }
            return(true);
        }
Ejemplo n.º 4
0
 internal MsDevice(IMsGate gate, byte[] addr)
   : this() {
   _gate=gate;
   Addr=addr;
 }
Ejemplo n.º 5
0
 private void Disconnect(ushort duration=0) {
   if(duration==0 && !string.IsNullOrEmpty(_willPath)) {
     TopicInfo ti = GetTopicInfo(_willPath, false);
     SetValue(ti, _wilMsg, false);
   }
   if(duration>0) {
     ResetTimer(duration*1550);
     this.Send(new MsDisconnect());
     _tryCounter=0;
     state=State.ASleep;
     var st=Owner.Get<long>(".cfg/XD_SleepTime", Owner);
     st.saved=true;
     st.SetValue((short)duration, new TopicChanged(TopicChanged.ChangeArt.Value, Owner) { Source=st });
   } else {
     _activeTimer.Change(Timeout.Infinite, Timeout.Infinite);
     this._gate=null;
     if(state!=State.Lost) {
       state=State.Disconnected;
       if(Owner!=null) {
         Log.Info("{0} Disconnected", Owner.path);
       }
     }
     //Topic dev=Topic.root.Get("/dev");
     //IEnumerable<MsDevice> ifs;
     //lock(dev) {
     //  ifs=dev.children.Where(z => z.valueType==typeof(MsDevice)).Cast<DVar<MsDevice>>().Where(z => z.value!=null && z.value._gate==this).Select(z => z.value).ToArray();
     //}
     //foreach(var t in ifs) {
     //  t.Disconnect();
     //}
   }
   _waitAck=false;
 }