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());
}
}
}
}