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; }
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()); } } } }
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); }
internal MsDevice(IMsGate gate, byte[] addr) : this() { _gate=gate; Addr=addr; }
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; }