private void ParseInPacket(byte[] buf) { var msgTyp=(MsMessageType)(buf[0]>1?buf[1]:buf[2]); switch(msgTyp) { case MsMessageType.WILLTOPIC: { var msg=new MsWillTopic(buf) { Addr=this.Addr }; Stat(false, msgTyp); PrintPacket(this, msg, buf); if(state==State.WillTopic) { _willPath=msg.Path; _willRetain=msg.Retain; state=State.WillMsg; ProccessAcknoledge(msg); } } break; case MsMessageType.WILLMSG: { Stat(false, msgTyp); var msg=new MsWillMsg(buf) { Addr=this.Addr }; PrintPacket(this, msg, buf); if(state==State.WillMsg) { _wilMsg=msg.Payload; state=State.PreConnect; ProccessAcknoledge(msg); Send(new MsConnack(MsReturnCode.Accepted)); Log.Info("{0} connected", Owner.path); } } break; case MsMessageType.SUBSCRIBE: { var msg=new MsSubscribe(buf) { Addr=this.Addr }; Stat(false, msgTyp, msg.dup); PrintPacket(this, msg, buf); SyncMsgId(msg.MessageId); Topic.Subscription s=null; ushort topicId=msg.topicId; if(msg.topicIdType!=TopicIdType.Normal || msg.path.IndexOfAny(new[] { '+', '#' })<0) { TopicInfo ti=null; if(msg.topicIdType==TopicIdType.Normal) { ti=GetTopicInfo(msg.path, false); } else { ti=GetTopicInfo(msg.topicId, msg.topicIdType); } topicId=ti.TopicId; } Send(new MsSuback(msg.qualityOfService, topicId, msg.MessageId, MsReturnCode.Accepted)); if(state==State.PreConnect) { state=State.Connected; } s=Owner.Subscribe(msg.path, PublishTopic, msg.qualityOfService); _subsscriptions.Add(s); } break; case MsMessageType.REGISTER: { var msg=new MsRegister(buf) { Addr=this.Addr }; Stat(false, msgTyp); PrintPacket(this, msg, buf); ResetTimer(); try { TopicInfo ti = GetTopicInfo(msg.TopicPath, false); if(ti.topic!=null && ti.topic.valueType==typeof(SmartTwi)) { if(ti.topic.GetValue()==null) { ti.topic.SetValue(new SmartTwi(ti.topic), new TopicChanged(TopicChanged.ChangeArt.Value, Owner)); } else { (ti.topic as DVar<SmartTwi>).value.Reset(); } } Send(new MsRegAck(ti.TopicId, msg.MessageId, MsReturnCode.Accepted)); } catch(Exception) { Send(new MsRegAck(0, msg.MessageId, MsReturnCode.NotSupportes)); Log.Warning("Unknown variable type by register {0}, {1}", Owner.path, msg.TopicPath); } } break; case MsMessageType.REGACK: { var msg=new MsRegAck(buf) { Addr=this.Addr }; Stat(false, msgTyp); PrintPacket(this, msg, buf); ProccessAcknoledge(msg); TopicInfo ti=_topics.FirstOrDefault(z => z.TopicId==msg.TopicId); if(ti==null) { if(msg.TopicId!=0) { Log.Warning("{0} RegAck({1:X4}) for unknown variable", Owner.path, msg.TopicId); } return; } if(msg.RetCode==MsReturnCode.Accepted) { ti.registred=true; if(ti.it!=TopicIdType.PreDefined) { Send(new MsPublish(ti.topic, ti.TopicId, QoS.AtLeastOnce)); } } else { Log.Warning("{0} registred failed: {1}", ti.path, msg.RetCode.ToString()); ti.it=TopicIdType.NotUsed; //_topics.Remove(ti); //ti.topic.Remove(); } } break; case MsMessageType.PUBLISH: { var msg=new MsPublish(buf) { Addr=this.Addr }; Stat(false, msgTyp, msg.Dup); PrintPacket(this, msg, buf); TopicInfo ti=_topics.Find(z => z.TopicId==msg.TopicId && z.it==msg.topicIdType); if(ti==null && msg.topicIdType!=TopicIdType.Normal) { ti=GetTopicInfo(msg.TopicId, msg.topicIdType, false); } if(msg.qualityOfService==QoS.AtMostOnce) { ResetTimer(); } else if(msg.qualityOfService==QoS.AtLeastOnce) { SyncMsgId(msg.MessageId); Send(new MsPubAck(msg.TopicId, msg.MessageId, ti!=null?MsReturnCode.Accepted:MsReturnCode.InvalidTopicId)); } else if(msg.qualityOfService==QoS.ExactlyOnce) { SyncMsgId(msg.MessageId); // QoS2 not supported, use QoS1 Send(new MsPubAck(msg.TopicId, msg.MessageId, ti!=null?MsReturnCode.Accepted:MsReturnCode.InvalidTopicId)); } else { throw new NotSupportedException("QoS -1 not supported "+Owner.path); } if(msg.topicIdType==TopicIdType.PreDefined && msg.TopicId>=LOG_D_ID && msg.TopicId<=LOG_E_ID) { string str=string.Format("{0}:{1} msg={2} msgId={3} ", this.Owner.path, BitConverter.ToString(msg.Addr), msg.Data==null?"null":BitConverter.ToString(msg.Data), msg.MessageId); switch(msg.TopicId) { case LOG_D_ID: Log.Debug(str); break; case LOG_I_ID: Log.Info(str); break; case LOG_W_ID: Log.Warning(str); break; case LOG_E_ID: Log.Error(str); break; } } else if(ti!=null) { SetValue(ti, msg.Data); } } break; case MsMessageType.PUBACK: { var msg=new MsPubAck(buf) { Addr=this.Addr }; Stat(false, msgTyp); PrintPacket(this, msg, buf); ProccessAcknoledge(msg); } break; case MsMessageType.PINGREQ: { var msg=new MsPingReq(buf) { Addr=this.Addr }; Stat(false, msgTyp); PrintPacket(this, msg, buf); if(state==State.ASleep) { if(string.IsNullOrEmpty(msg.ClientId) || msg.ClientId==Owner.name) { //if(++_reconnectCnt>1024) { // _reconnectCnt=0; // Send(new MsDisconnect()); // state=State.Disconnected; // Log.Info("{0} refresh connection", Owner.path); //} else { state=State.AWake; ProccessAcknoledge(msg); // resume send proccess //} } else { Send(new MsDisconnect()); state=State.Lost; Log.Warning("{0} PingReq from unknown device: {1}", Owner.path, msg.ClientId); } } else { ResetTimer(); if(_gate!=null) { _gate.Send(new MsMessage(MsMessageType.PINGRESP) { Addr=this.Addr }); Stat(true, MsMessageType.PINGRESP, false); } } } break; case MsMessageType.DISCONNECT: { var msg=new MsDisconnect(buf) { Addr=this.Addr }; Stat(false, msgTyp); PrintPacket(this, msg, buf); Disconnect(msg.Duration); } break; default: Log.Warning("{0} unknown packet: {1}", Owner!=null?Owner.path:"null", BitConverter.ToString(buf)); break; } }