private void OnPacketToSend(MqttMsgBase packet) { if (PacketToSend != null) { PacketToSend(this, new PacketToSendEventArgs(packet)); } }
public void DecodeMultiplePacketsByteArray(byte[] data) { List <MqttMsgBase> packetsInTheByteArray = new List <MqttMsgBase>(); int numberOfBytesProcessed = 0; int numberOfBytesToProcess = 0; int numberOfBytesReceived = data.Length; byte[] packetByteArray; MqttMsgBase tmpPacket = new MqttMsgSubscribe(); while (numberOfBytesProcessed != numberOfBytesReceived) { int remainingLength = MqttMsgBase.decodeRemainingLength(data); int remainingLenghtIndex = tmpPacket.encodeRemainingLength(remainingLength, data, 1); numberOfBytesToProcess = remainingLength + remainingLenghtIndex; packetByteArray = new byte[numberOfBytesToProcess]; Array.Copy(data, 0, packetByteArray, 0, numberOfBytesToProcess); { byte[] tmp = new byte[data.Length - numberOfBytesToProcess]; Array.Copy(data, numberOfBytesToProcess, tmp, 0, tmp.Length); data = tmp; } numberOfBytesProcessed += numberOfBytesToProcess; MqttMsgBase packet = PacketDecoder.DecodeControlPacket(packetByteArray); //RouteControlPacketDelegate r = new RouteControlPacketDelegate(RouteControlPacketToMethodHandler); //r.Invoke(packet); CrestronInvoke.BeginInvoke(RouteControlPacketToMethodHandler, packet); } }
/// <summary> /// Parse bytes for a PUBCOMP message /// </summary> /// <param name="fixedHeaderFirstByte">First fixed header byte</param> /// <param name="protocolVersion">Protocol Version</param> /// <param name="channel">Channel connected to the broker</param> /// <returns>PUBCOMP message instance</returns> public static MqttMsgPubcomp Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel) { byte[] buffer; int index = 0; MqttMsgPubcomp msg = new MqttMsgPubcomp(); if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1) { // [v3.1.1] check flag bits if ((fixedHeaderFirstByte & MSG_FLAG_BITS_MASK) != MQTT_MSG_PUBCOMP_FLAG_BITS) { throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits); } } // get remaining length and allocate buffer int remainingLength = MqttMsgBase.decodeRemainingLength(channel); buffer = new byte[remainingLength]; // read bytes from socket... channel.Receive(buffer); // message id msg.messageId = (ushort)((buffer[index++] << 8) & 0xFF00); msg.messageId |= (buffer[index++]); return(msg); }
private void ConnectToServerCallback(SecureTCPClient myTCPClient) { try { if (myTCPClient.ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED) { MqttMsgConnect connect = MsgBuilder.BuildConnect(this.ClientId, MqttSettings.Instance.Username, MqttSettings.Instance.Password, this.WillRetain, this.WillQosLevel, this.WillFlag, this.WillTopic, this.WillMessage, this.CleanSession, this.KeepAlivePeriod, ProtocolVersion); Send(connect); //TODO: timer for connack tcpClient.ReceiveData(); MqttMsgBase packet = PacketDecoder.DecodeControlPacket(tcpClient.IncomingDataBuffer); if (packet.Type == MqttMsgBase.MQTT_MSG_CONNACK_TYPE) { RouteControlPacketToMethodHandler(packet); } else { throw new MqttConnectionException("MQTTCLIENT - ConnectToServerCallback - " + PayloadMapper.ClientType + " , Expected CONNACK , received " + packet, new ArgumentException()); } } } catch (MqttClientException e) { CrestronLogger.WriteToLog("MQTTCLIENT - ConnectToServerCallback - Error occured : " + e.ErrorCode, 7); CrestronLogger.WriteToLog("MQTTCLIENT - ConnectToServerCallback - Error occured : " + e.StackTrace, 7); } catch (Exception e) { CrestronLogger.WriteToLog("MQTTCLIENT - ConnectToServerCallback - Error occured : " + e.Message, 7); CrestronLogger.WriteToLog("MQTTCLIENT - ConnectToServerCallback - Error occured : " + e.StackTrace, 7); //Disconnect from server , signal error at module lvl; } }
override protected void ConnectionCallback(SecureTCPServer server, uint clientIndex) { try { Server.WaitForConnectionAsync(IPAddress.Parse("0.0.0.0"), this.ConnectionCallback); if (Server.ClientConnected(clientIndex)) { oldDecodedFrame.Add(clientIndex, new List <byte>()); int lenghtOfData = Server.ReceiveData(clientIndex); byte[] data = Server.GetIncomingDataBufferForSpecificClient(clientIndex); MqttMsgBase packet = PacketDecoder.DecodeControlPacket(data); if (packet.Type == MqttMsgBase.MQTT_MSG_CONNECT_TYPE) { OnPacketReceived(clientIndex, packet, false); } else { throw new ArgumentException("Attempted connection with a non CONNECT packet"); } } } catch (Exception e) { DisconnectClient(clientIndex, false); } }
/// <summary> /// Parse bytes for a PUBREL message /// </summary> /// <param name="fixedHeaderFirstByte">First fixed header byte</param> /// <param name="channel">Channel connected to the broker</param> /// <returns>PUBREL message instance</returns> public static MqttMsgPubrel Parse(byte fixedHeaderFirstByte, IMqttNetworkChannel channel) { byte[] buffer; int index = 0; MqttMsgPubrel msg = new MqttMsgPubrel(); // get remaining length and allocate buffer int remainingLength = MqttMsgBase.decodeRemainingLength(channel); buffer = new byte[remainingLength]; // read bytes from socket... channel.Receive(buffer); // read QoS level from fixed header (would be QoS Level 1) msg.qosLevel = (byte)((fixedHeaderFirstByte & QOS_LEVEL_MASK) >> QOS_LEVEL_OFFSET); // read DUP flag from fixed header msg.dupFlag = (((fixedHeaderFirstByte & DUP_FLAG_MASK) >> DUP_FLAG_OFFSET) == 0x01); // message id msg.messageId = (ushort)((buffer[index++] << 8) & 0xFF00); msg.messageId |= (buffer[index++]); return(msg); }
private int SendPubrel( MqttConnection connection, MqttMsgContext msgContext, MqttMsgBase msgInflight, int timeout) { // QoS 2, PUBREL message to send to broker, state change to wait PUBCOMP if (msgContext.Flow == MqttMsgFlow.ToPublish) { msgContext.State = MqttMsgState.WaitForPubcomp; msgContext.Timestamp = Environment.TickCount; msgContext.Attempt++; // retry ? set dup flag [v3.1.1] no needed if (connection.ProtocolVersion == MqttProtocolVersion.Version_3_1 && msgContext.Attempt > 1) { outgoingMessageHandler.Pubrel(connection, msgInflight.MessageId, true); } else { outgoingMessageHandler.Pubrel(connection, msgInflight.MessageId, false); } // update timeout : minimum between delay (based on current message sent) or current timeout timeout = connection.Settings.DelayOnRetry < timeout ? connection.Settings.DelayOnRetry : timeout; // re-enqueue message connection.EnqueueInflight(msgContext); } return(timeout); }
public void OnPacketReceived(uint clientIndex, MqttMsgBase packet, bool isWebSocketClient) { if (PacketReceived != null) { PacketReceived(this, new PacketReceivedEventHandler(clientIndex, packet, isWebSocketClient)); } }
public void Send(MqttMsgBase packet) { CrestronLogger.WriteToLog("MQTTCLIENT - SEND - Sending packet type " + packet, 2); #if PACKET_DEBUG CrestronLogger.WriteToLog("MQTTCLIENT - SEND - " + BitConverter.ToString(packet.GetBytes(ProtocolVersion)), 2); #endif ClientSendDataAsync(packet.GetBytes(ProtocolVersion)); }
private int HandleQueuedQos1SendSubscribeAndSendUnsubscribe( MqttConnection connection, MqttMsgContext msgContext, MqttMsgBase msgInflight, int timeout) { InternalEvent internalEvent; // QoS 1, PUBLISH or SUBSCRIBE/UNSUBSCRIBE message to send to broker, state change to wait PUBACK or SUBACK/UNSUBACK if (msgContext.Flow == MqttMsgFlow.ToPublish) { msgContext.Timestamp = Environment.TickCount; msgContext.Attempt++; if (msgInflight.Type == MqttMsgBase.MQTT_MSG_PUBLISH_TYPE) { // PUBLISH message to send, wait for PUBACK msgContext.State = MqttMsgState.WaitForPuback; // retry ? set dup flag [v3.1.1] only for PUBLISH message if (msgContext.Attempt > 1) { msgInflight.DupFlag = true; } } else if (msgInflight.Type == MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE) { // SUBSCRIBE message to send, wait for SUBACK msgContext.State = MqttMsgState.WaitForSuback; } else if (msgInflight.Type == MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE) { // UNSUBSCRIBE message to send, wait for UNSUBACK msgContext.State = MqttMsgState.WaitForUnsuback; } outgoingMessageHandler.Send(connection, msgInflight); // update timeout : minimum between delay (based on current message sent) or current timeout timeout = connection.Settings.DelayOnRetry < timeout ? connection.Settings.DelayOnRetry : timeout; // re-enqueue message (I have to re-analyze for receiving PUBACK, SUBACK or UNSUBACK) connection.EnqueueInflight(msgContext); } // QoS 1, PUBLISH message received from broker to acknowledge, send PUBACK else if (msgContext.Flow == MqttMsgFlow.ToAcknowledge) { outgoingMessageHandler.Puback(connection, msgInflight.MessageId); internalEvent = new InternalEvent(msgInflight); // notify published message from broker and acknowledged connection.EnqueueInternalEvent(internalEvent); } return(timeout); }
private MqttMsgBase WaitForPubrel( MqttConnection connection, MqttMsgContext msgContext, MqttMsgBase msgInflight, ref bool msgReceivedProcessed) { // QoS 2, waiting for PUBREL of a PUBREC message sent if (msgContext.Flow != MqttMsgFlow.ToAcknowledge) { return(null); } if (!connection.InternalQueue.TryPeek(out MqttMsgBase msgReceived)) { return(null); } InternalEvent internalEvent; // it is a PUBREL message if (msgReceived != null && msgReceived.Type == MqttMsgBase.MQTT_MSG_PUBREL_TYPE) { if (msgReceived.MessageId == msgInflight.MessageId) { // received message processed connection.InternalQueue.TryDequeue(out MqttMsgBase dequeuedMsg); msgReceivedProcessed = true; outgoingMessageHandler.Pubcomp(connection, msgInflight.MessageId); internalEvent = new InternalEvent(msgInflight); // notify published message from broker and acknowledged connection.EnqueueInternalEvent(internalEvent); // PUBREL received (and PUBCOMP sent) for PUBLISH message with QoS Level 2, remove from session state if (msgInflight.Type == MqttMsgBase.MQTT_MSG_PUBLISH_TYPE && connection.Session != null && connection.Session.InflightMessages.ContainsKey(msgContext.Key)) { connection.Session.InflightMessages.TryRemove( msgContext.Key, out MqttMsgContext contextToBeRemoved); } } else { // re-enqueue message connection.EnqueueInflight(msgContext); } } else { connection.EnqueueInflight(msgContext); } return(msgReceived); }
public void AddInflightMessage(MqttMsgBase packet) { MqttMsgContext context = new MqttMsgContext(); Del d = delegate() { return(packet.QosLevel == (byte)0x01 ? MqttMsgState.QueuedQos1 : MqttMsgState.QueuedQos2); }; MqttMsgState state = packet.QosLevel == (byte)0x00 ? MqttMsgState.QueuedQos0 : d(); context.State = state; context.Message = packet; session.InflightMessages.Add(packet.MessageId, context); }
/// <summary> /// Parse bytes for a PINGREQ message /// </summary> /// <param name="fixedHeaderFirstByte">First fixed header byte</param> /// <param name="channel">Channel connected to the broker</param> /// <returns>PINGREQ message instance</returns> public static MqttMsgPingReq Parse(byte fixedHeaderFirstByte, IMqttNetworkChannel channel) { MqttMsgPingReq msg = new MqttMsgPingReq(); // already know remaininglength is zero (MQTT specification), // so it isn't necessary to read other data from socket int remainingLength = MqttMsgBase.decodeRemainingLength(channel); return(msg); }
/// <summary> /// Parse bytes for a DISCONNECT message /// </summary> /// <param name="fixedHeaderFirstByte">First fixed header byte</param> /// <param name="channel">Channel connected to the broker</param> /// <returns>DISCONNECT message instance</returns> public static MqttMsgDisconnect Parse(byte fixedHeaderFirstByte, IMqttNetworkChannel channel) { MqttMsgDisconnect msg = new MqttMsgDisconnect(); // get remaining length and allocate buffer int remainingLength = MqttMsgBase.decodeRemainingLength(channel); // NOTE : remainingLength must be 0 return(msg); }
private static void HandleQueuedQos0( MqttClientConnection clientConnection, MqttMsgContext msgContext, MqttMsgBase msgInflight) { // QoS 0, PUBLISH message to send to broker, no state change, no acknowledge if (msgContext.Flow == MqttMsgFlow.ToPublish) { MqttOutgoingMessageManager.Send(clientConnection, msgInflight); } // QoS 0, no need acknowledge else if (msgContext.Flow == MqttMsgFlow.ToAcknowledge) { var internalEvent = new MsgInternalEvent(msgInflight); clientConnection.EnqueueInternalEvent(internalEvent); } }
/// <summary> /// Parse bytes for a PINGREQ message /// </summary> /// <param name="fixedHeaderFirstByte">First fixed header byte</param> /// <param name="protocolVersion">Protocol Version</param> /// <param name="channel">Channel connected to the broker</param> /// <returns>PINGREQ message instance</returns> public static MqttMsgPingReq Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel) { MqttMsgPingReq msg = new MqttMsgPingReq(); if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1) { // [v3.1.1] check flag bits if ((fixedHeaderFirstByte & MSG_FLAG_BITS_MASK) != MQTT_MSG_PINGREQ_FLAG_BITS) { throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits); } } // already know remaininglength is zero (MQTT specification), // so it isn't necessary to read other data from socket int remainingLength = MqttMsgBase.decodeRemainingLength(channel); return(msg); }
/// <summary> /// Parse bytes for a DISCONNECT message /// </summary> /// <param name="fixedHeaderFirstByte">First fixed header byte</param> /// <param name="protocolVersion">Protocol Version</param> /// <param name="channel">Channel connected to the broker</param> /// <returns>DISCONNECT message instance</returns> public static MqttMsgDisconnect Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel) { MqttMsgDisconnect msg = new MqttMsgDisconnect(); if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1) { // [v3.1.1] check flag bits if ((fixedHeaderFirstByte & MSG_FLAG_BITS_MASK) != MQTT_MSG_DISCONNECT_FLAG_BITS) { throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits); } } // get remaining length and allocate buffer int remainingLength = MqttMsgBase.decodeRemainingLength(channel); // NOTE : remainingLength must be 0 return(msg); }
/// <summary> /// Parse bytes for a PUBCOMP message /// </summary> /// <param name="fixedHeaderFirstByte">First fixed header byte</param> /// <param name="channel">Channel connected to the broker</param> /// <returns>PUBCOMP message instance</returns> public static MqttMsgPubcomp Parse(byte fixedHeaderFirstByte, IMqttNetworkChannel channel) { byte[] buffer; int index = 0; MqttMsgPubcomp msg = new MqttMsgPubcomp(); // get remaining length and allocate buffer int remainingLength = MqttMsgBase.decodeRemainingLength(channel); buffer = new byte[remainingLength]; // read bytes from socket... channel.Receive(buffer); // message id msg.messageId = (ushort)((buffer[index++] << 8) & 0xFF00); msg.messageId |= (buffer[index++]); return(msg); }
private int HandleQueuedQos2( MqttConnection connection, MqttMsgContext msgContext, MqttMsgBase msgInflight, int timeout) { // QoS 2, PUBLISH message to send to broker, state change to wait PUBREC if (msgContext.Flow == MqttMsgFlow.ToPublish) { msgContext.Timestamp = Environment.TickCount; msgContext.Attempt++; msgContext.State = MqttMsgState.WaitForPubrec; // retry ? set dup flag if (msgContext.Attempt > 1) { msgInflight.DupFlag = true; } outgoingMessageHandler.Send(connection, msgInflight); // update timeout : minimum between delay (based on current message sent) or current timeout timeout = connection.Settings.DelayOnRetry < timeout ? connection.Settings.DelayOnRetry : timeout; // re-enqueue message (I have to re-analyze for receiving PUBREC) connection.EnqueueInflight(msgContext); } // QoS 2, PUBLISH message received from broker to acknowledge, send PUBREC, state change to wait PUBREL else if (msgContext.Flow == MqttMsgFlow.ToAcknowledge) { msgContext.State = MqttMsgState.WaitForPubrel; outgoingMessageHandler.Pubrec(connection, msgInflight.MessageId); // re-enqueue message (I have to re-analyze for receiving PUBREL) connection.EnqueueInflight(msgContext); } return(timeout); }
/// <summary> /// Parse bytes for a PUBREL message /// </summary> /// <param name="fixedHeaderFirstByte">First fixed header byte</param> /// <param name="protocolVersion">Protocol Version</param> /// <param name="channel">Channel connected to the broker</param> /// <returns>PUBREL message instance</returns> public static MqttMsgPubrel Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel) { byte[] buffer; int index = 0; MqttMsgPubrel msg = new MqttMsgPubrel(); if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1) { // [v3.1.1] check flag bits if ((fixedHeaderFirstByte & MSG_FLAG_BITS_MASK) != MQTT_MSG_PUBREL_FLAG_BITS) { throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits); } } // get remaining length and allocate buffer int remainingLength = MqttMsgBase.decodeRemainingLength(channel); buffer = new byte[remainingLength]; // read bytes from socket... channel.Receive(buffer); if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1) { // only 3.1.0 // read QoS level from fixed header (would be QoS Level 1) msg.qosLevel = (byte)((fixedHeaderFirstByte & QOS_LEVEL_MASK) >> QOS_LEVEL_OFFSET); // read DUP flag from fixed header msg.dupFlag = (((fixedHeaderFirstByte & DUP_FLAG_MASK) >> DUP_FLAG_OFFSET) == 0x01); } // message id msg.messageId = (ushort)((buffer[index++] << 8) & 0xFF00); msg.messageId |= (buffer[index++]); return(msg); }
/// <summary> /// Constructor /// </summary> /// <param name="msg">Message published</param> /// <param name="isPublished">Publish flag</param> public MsgPublishedInternalEvent(MqttMsgBase msg, bool isPublished) : base(msg) { this.isPublished = isPublished; }
/// <summary> /// Constructor /// </summary> /// <param name="message">Related message</param> public InternalEvent(MqttMsgBase message) { this.Message = message; }
private static MqttMsgBase HandleWaitForPubrec( MqttClientConnection clientConnection, MqttMsgContext msgContext, MqttMsgBase msgInflight, ref bool msgReceivedProcessed, ref int timeout) { // QoS 2, waiting for PUBREC of a PUBLISH message sent if (msgContext.Flow != MqttMsgFlow.ToPublish) { return(null); } MqttMsgBase msgReceived; if (!clientConnection.InternalQueue.TryPeek(out msgReceived)) { return(null); } bool acknowledge = false; InternalEvent internalEvent; // it is a PUBREC message if (msgReceived.Type == MqttMsgBase.MQTT_MSG_PUBREC_TYPE) { // PUBREC message for the current PUBLISH message, send PUBREL, wait for PUBCOMP if (msgReceived.MessageId == msgInflight.MessageId) { // received message processed MqttMsgBase dequeuedMsg; clientConnection.InternalQueue.TryDequeue(out dequeuedMsg); acknowledge = true; msgReceivedProcessed = true; MqttOutgoingMessageManager.Pubrel(clientConnection, msgInflight.MessageId, false); msgContext.State = MqttMsgState.WaitForPubcomp; msgContext.Timestamp = Environment.TickCount; msgContext.Attempt = 1; // update timeout : minimum between delay (based on current message sent) or current timeout timeout = (clientConnection.Settings.DelayOnRetry < timeout) ? clientConnection.Settings.DelayOnRetry : timeout; // re-enqueue message clientConnection.EnqueueInflight(msgContext); } } // current message not acknowledged if (!acknowledge) { var delta = Environment.TickCount - msgContext.Timestamp; // check timeout for receiving PUBREC since PUBLISH was sent if (delta >= clientConnection.Settings.DelayOnRetry) { // max retry not reached, resend if (msgContext.Attempt < clientConnection.Settings.AttemptsOnRetry) { msgContext.State = MqttMsgState.QueuedQos2; // re-enqueue message clientConnection.EnqueueInflight(msgContext); // update timeout (0 -> reanalyze queue immediately) timeout = 0; } else { // PUBREC not received in time, PUBLISH retries failed, need to remove from session inflight messages too if ((clientConnection.Session != null) && (clientConnection.Session.InflightMessages.ContainsKey(msgContext.Key))) { MqttMsgContext contextToBeRemoved; clientConnection.Session.InflightMessages.TryRemove(msgContext.Key, out contextToBeRemoved); } // if PUBREC for a PUBLISH message not received after retries, raise event for not published internalEvent = new MsgPublishedInternalEvent(msgInflight, false); // notify not received acknowledge from broker and message not published clientConnection.EnqueueInternalEvent(internalEvent); } } else { // re-enqueue message clientConnection.EnqueueInflight(msgContext); // update timeout int msgTimeout = (clientConnection.Settings.DelayOnRetry - delta); timeout = (msgTimeout < timeout) ? msgTimeout : timeout; } } return(msgReceived); }
public void Send(MqttConnection connection, MqttMsgBase msg) { Send(connection, msg.GetBytes((byte)connection.ProtocolVersion)); }
private void RouteControlPacketToMethodHandler(object source, PacketReceivedEventHandler args) { MqttMsgBase packet = args.Packet; uint clientIndex = args.ClientIndex; bool isWebSocketClient = args.IsWebSocketClient; try { switch (packet.Type) { case MqttMsgBase.MQTT_MSG_CONNECT_TYPE: { HandleCONNECTType(clientIndex, (MqttMsgConnect)packet, args.IsWebSocketClient); break; } case MqttMsgBase.MQTT_MSG_CONNACK_TYPE: { CrestronLogger.WriteToLog("MQTTSERVER - ROUTE PACKET - conack packet to broker is not allowed , Disconnecting client", 8); DisconnectClient(clientIndex, false, isWebSocketClient); break; } case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE: { HandlePUBLISHType(clientIndex, (MqttMsgPublish)packet); break; } case MqttMsgBase.MQTT_MSG_PUBACK_TYPE: { HandlePUBACKType(clientIndex, (MqttMsgPuback)packet); break; } case MqttMsgBase.MQTT_MSG_PUBREC_TYPE: { HandlePUBRECType(clientIndex, (MqttMsgPubrec)packet); break; } case MqttMsgBase.MQTT_MSG_PUBREL_TYPE: { HandlePUBRELType(clientIndex, (MqttMsgPubrel)packet); break; } case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE: { HandlePUBCOMPType(clientIndex, (MqttMsgPubcomp)packet, isWebSocketClient); break; } case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE: { HandleSUBSCRIBEType(clientIndex, (MqttMsgSubscribe)packet, isWebSocketClient); break; } case MqttMsgBase.MQTT_MSG_SUBACK_TYPE: { DisconnectClient(clientIndex, false, isWebSocketClient); break; } case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE: { HandleUNSUBSCRIBEType(clientIndex, (MqttMsgUnsubscribe)packet, isWebSocketClient); break; } case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE: { DisconnectClient(clientIndex, false, isWebSocketClient); break; } case MqttMsgBase.MQTT_MSG_PINGREQ_TYPE: { HandlePINGREQType(clientIndex, (MqttMsgPingReq)packet, isWebSocketClient); break; } case MqttMsgBase.MQTT_MSG_PINGRESP_TYPE: { HandlePINGRESPType(clientIndex, (MqttMsgPingResp)packet, isWebSocketClient); break; } case MqttMsgBase.MQTT_MSG_DISCONNECT_TYPE: { HandleDISCONNECTType(clientIndex, (MqttMsgDisconnect)packet, isWebSocketClient); break; } default: { throw new MqttCommunicationException(new FormatException("MQTTSERVER -Pacchetto non valido" + packet)); } } } catch (Exception e) { CrestronLogger.WriteToLog("MQTTSERVER - RouteControlPacketToMethodHandler - Exception occured trying route packet : " + e.Message, 8); CrestronLogger.WriteToLog("MQTTSERVER - RouteControlPacketToMethodHandler - Stack trace : " + e.StackTrace, 8); } }
public PacketToSendEventArgs(MqttMsgBase packet) { this.Packet = packet; }
public PacketReceivedEventHandler(uint clientIndex, MqttMsgBase packet, bool isWebSocketClient) { this.ClientIndex = clientIndex; this.Packet = packet; this.IsWebSocketClient = isWebSocketClient; }
private static MqttMsgBase HandleWaitForPubackSubackUbsuback( MqttClientConnection clientConnection, MqttMsgContext msgContext, MqttMsgBase msgInflight, ref bool msgReceivedProcessed, ref int timeout) { // QoS 1, waiting for PUBACK of a PUBLISH message sent or // waiting for SUBACK of a SUBSCRIBE message sent or // waiting for UNSUBACK of a UNSUBSCRIBE message sent or if (msgContext.Flow != MqttMsgFlow.ToPublish) { return(null); } MqttMsgBase msgReceived; if (!clientConnection.InternalQueue.TryPeek(out msgReceived)) { return(null); } bool acknowledge = false; InternalEvent internalEvent; // PUBACK message or SUBACK/UNSUBACK message for the current message if (((msgReceived.Type == MqttMsgBase.MQTT_MSG_PUBACK_TYPE) && (msgInflight.Type == MqttMsgBase.MQTT_MSG_PUBLISH_TYPE) && (msgReceived.MessageId == msgInflight.MessageId)) || ((msgReceived.Type == MqttMsgBase.MQTT_MSG_SUBACK_TYPE) && (msgInflight.Type == MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE) && (msgReceived.MessageId == msgInflight.MessageId)) || ((msgReceived.Type == MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE) && (msgInflight.Type == MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE) && (msgReceived.MessageId == msgInflight.MessageId))) { // received message processed MqttMsgBase dequeuedMsg; clientConnection.InternalQueue.TryDequeue(out dequeuedMsg); acknowledge = true; msgReceivedProcessed = true; // if PUBACK received, confirm published with flag if (msgReceived.Type == MqttMsgBase.MQTT_MSG_PUBACK_TYPE) { internalEvent = new MsgPublishedInternalEvent(msgReceived, true); } else { internalEvent = new MsgInternalEvent(msgReceived); } // notify received acknowledge from broker of a published message or subscribe/unsubscribe message clientConnection.EnqueueInternalEvent(internalEvent); // PUBACK received for PUBLISH message with QoS Level 1, remove from session state if ((msgInflight.Type == MqttMsgBase.MQTT_MSG_PUBLISH_TYPE) && (clientConnection.Session != null) && (clientConnection.Session.InflightMessages.ContainsKey(msgContext.Key))) { MqttMsgContext contextToBeRemoved; clientConnection.Session.InflightMessages.TryRemove(msgContext.Key, out contextToBeRemoved); } } // current message not acknowledged, no PUBACK or SUBACK/UNSUBACK or not equal messageid if (!acknowledge) { var delta = Environment.TickCount - msgContext.Timestamp; // check timeout for receiving PUBACK since PUBLISH was sent or // for receiving SUBACK since SUBSCRIBE was sent or // for receiving UNSUBACK since UNSUBSCRIBE was sent if (delta >= clientConnection.Settings.DelayOnRetry) { // max retry not reached, resend if (msgContext.Attempt < clientConnection.Settings.AttemptsOnRetry) { msgContext.State = MqttMsgState.QueuedQos1; // re-enqueue message clientConnection.EnqueueInflight(msgContext); // update timeout (0 -> reanalyze queue immediately) timeout = 0; } else { // if PUBACK for a PUBLISH message not received after retries, raise event for not published if (msgInflight.Type == MqttMsgBase.MQTT_MSG_PUBLISH_TYPE) { // PUBACK not received in time, PUBLISH retries failed, need to remove from session inflight messages too if ((clientConnection.Session != null) && (clientConnection.Session.InflightMessages.ContainsKey(msgContext.Key))) { MqttMsgContext contextToBeRemoved; clientConnection.Session.InflightMessages.TryRemove(msgContext.Key, out contextToBeRemoved); } internalEvent = new MsgPublishedInternalEvent(msgInflight, false); // notify not received acknowledge from broker and message not published clientConnection.EnqueueInternalEvent(internalEvent); } // NOTE : not raise events for SUBACK or UNSUBACK not received // for the user no event raised means subscribe/unsubscribe failed } } else { // re-enqueue message (I have to re-analyze for receiving PUBACK, SUBACK or UNSUBACK) clientConnection.EnqueueInflight(msgContext); // update timeout int msgTimeout = (clientConnection.Settings.DelayOnRetry - delta); timeout = (msgTimeout < timeout) ? msgTimeout : timeout; } } return(msgReceived); }