/// <summary> /// Subscribe for message topics /// </summary> /// <param name="topics">List of topics to subscribe</param> /// <param name="qosLevels">QOS levels related to topics</param> /// <returns>Granted QoS Levels in SUBACK message from broker</returns> public byte[] Subscribe(string[] topics, byte[] qosLevels) { int attempts = 0; bool acknowledged = false; MqttMsgSubscribe subscribe = new MqttMsgSubscribe(topics, qosLevels); MqttMsgSuback suback = null; do { try { // try subscribe suback = (MqttMsgSuback)this.SendReceive(subscribe.GetBytes()); acknowledged = true; } catch (MqttTimeoutException) { // no SUBACK message received in time, retry with duplicate flag attempts++; subscribe.DupFlag = true; // delay before retry if (attempts < MQTT_ATTEMPTS_RETRY) { Thread.Sleep(MQTT_DELAY_RETRY); } } } while ((attempts < MQTT_ATTEMPTS_RETRY) && !acknowledged); // return granted QoS Levels or null return(acknowledged ? suback.GrantedQoSLevels : null); }
protected void DecodeMultiplePacketsByteArray(uint clientIndex, byte[] data, bool isWebSocketClient) { lock (oldDecodedFrame) { int numberOfBytesProcessed = 0; int numberOfBytesToProcess = 0; int numberOfBytesReceived = data.Length; byte[] packetByteArray; List <byte> packets = new List <byte>(); MqttMsgBase tmpPacket = new MqttMsgSubscribe(); try { 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); MqttMsgBase packet = PacketDecoder.DecodeControlPacket(packetByteArray); OnPacketReceived(clientIndex, packet, isWebSocketClient); { byte[] tmp = new byte[data.Length - numberOfBytesToProcess]; Array.Copy(data, numberOfBytesToProcess, tmp, 0, tmp.Length); data = tmp; } numberOfBytesProcessed += numberOfBytesToProcess; } } catch (Exception e) { oldDecodedFrame[clientIndex].AddRange(data); } } }
/// <summary> /// <description>Subscribes a client to defined topic</description> /// </summary> /// <param name="topics">the topic the client subscribes to</param> /// <param name="qosLevels">The level of quality service the message is sent with</param> /// <returns></returns> public override ushort Subscribe(string [] topics, byte [] qosLevels) { MqttMsgSubscribe subscribe = new MqttMsgSubscribe(topics, qosLevels); subscribe.MessageId = this.GetMessageId(); // enqueue subscribe request into the inflight queue this.EnqueueInflight(subscribe, MqttMsgFlow.ToPublish); if (topicList.Count == 0) { for (int i = 0; i < topics.Length; i++) { AddButton(topics, i); } } else { for (int j = 0; j < topics.Length; j++) { for (int i = 0; i < topicList.Count; i++) { if (topicList[i].Equals(topics[j])) { return(subscribe.MessageId); } } //Debug.Log (topicList [i]); Debug.Log(topics[j]); AddButton(topics, j); } } return(subscribe.MessageId); }
public void SubscribeDecodeAvanceTestsv5() { // Arrange byte[] encodedCorrect = new byte[] { 249, 1, 0, 42, 223, 1, 11, 253, 255, 255, 127, 38, 0, 8, 108, 111, 110, 103, 32, 111, 110, 101, 0, 210, 111, 110, 101, 32, 118, 101, 114, 121, 32, 108, 111, 110, 103, 32, 111, 110, 101, 32, 116, 111, 32, 116, 101, 115, 116, 32, 102, 111, 114, 32, 111, 110, 99, 101, 32, 104, 111, 119, 32, 116, 104, 105, 115, 32, 119, 105, 108, 108, 32, 101, 110, 99, 111, 100, 101, 32, 97, 110, 100, 32, 109, 97, 107, 101, 32, 105, 116, 32, 114, 101, 97, 108, 108, 108, 108, 108, 108, 121, 121, 121, 121, 121, 121, 121, 32, 115, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 32, 115, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 32, 115, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 32, 115, 111, 111, 111, 111, 111, 111, 111, 111, 111, 32, 108, 111, 110, 103, 46, 32, 89, 101, 97, 44, 32, 116, 104, 97, 116, 32, 115, 104, 111, 117, 108, 100, 32, 98, 101, 32, 116, 101, 115, 116, 101, 100, 32, 102, 111, 114, 32, 114, 101, 97, 108, 32, 105, 110, 32, 116, 104, 101, 32, 114, 101, 97, 108, 32, 108, 105, 102, 101, 32, 97, 115, 32, 119, 101, 108, 108, 0, 5, 102, 105, 114, 115, 116, 1, 0, 6, 115, 101, 99, 111, 110, 100, 2 }; MokChannel mokChannel = new MokChannel(encodedCorrect); // Act MqttMsgSubscribe subscribe = MqttMsgSubscribe.Parse(130, MqttProtocolVersion.Version_5, mokChannel); // Assert Assert.Equal(subscribe.MessageId, (ushort)42); Assert.Equal(subscribe.QoSLevels, new MqttQoSLevel[] { MqttQoSLevel.AtLeastOnce, MqttQoSLevel.ExactlyOnce }); Assert.Equal(subscribe.Topics, new string[] { "first", "second" }); Assert.Equal(subscribe.SubscriptionIdentifier, 268435453); var prop = new UserProperty("long one", "one very long one to test for once how this will encode and make it reallllllyyyyyyy soooooooooooo soooooooooooooo soooooooooooooooo sooooooooo long. Yea, that should be tested for real in the real life as well"); Assert.Equal(((UserProperty)subscribe.UserProperties[0]).Name, prop.Name); Assert.Equal(((UserProperty)subscribe.UserProperties[0]).Value, prop.Value); }
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); } }
public void Subscribe(string clientId, MqttMsgSubscribe packet) { try { Session session = SessionManager.sessions.First(ss => ss.ClientId == clientId); List <Subscription> subs = session.Subscriptions; lock (subs) { for (int i = 0; i < packet.Topics.Length; i++) { string topicReplaced = packet.Topics[i].Replace(PLUS_WILDCARD, PLUS_WILDCARD_REPLACE).Replace(SHARP_WILDCARD, SHARP_WILDCARD_REPLACE); topicReplaced = "^" + topicReplaced + "$"; Subscription existingSubscription = subs.FirstOrDefault(sub => sub.Topic == packet.Topics[i]); if (existingSubscription == null) { Subscription s = new Subscription(clientId, topicReplaced, packet.QoSLevels[i]); subs.Add(s); } } OnClientSubscribed(packet.Topics, clientId); } } catch (Exception) { throw; } }
private void HandleSUBSCRIBEType(uint clientIndex, MqttMsgSubscribe packet, bool isWebSocketClient) { CrestronLogger.WriteToLog("MQTTSERVER - HandleSUBSCRIBEType - Subscription Received" + packet.ToString(), 6); sessionManager.AddSubscription(GetClientByIndex(clientIndex, isWebSocketClient).ClientId, packet); byte[] subAckBytes = MsgBuilder.BuildSubAck(packet.MessageId, packet.QoSLevels).GetBytes(); Send(clientIndex, subAckBytes, subAckBytes.Length, isWebSocketClient); }
internal static MqttMsgSubscribe BuildSubscribe(string[] topics, byte[] qosLevels, ushort messageId) { MqttMsgSubscribe subscribe = new MqttMsgSubscribe(); subscribe.Topics = topics.ToArray(); subscribe.QoSLevels = qosLevels; subscribe.MessageId = messageId; return(subscribe); }
public void SubscribeDecodeBasicTestsv5() { // Arrange byte[] encodedCorrect = new byte[] { 20, 0, 42, 0, 0, 5, 102, 105, 114, 115, 116, 1, 0, 6, 115, 101, 99, 111, 110, 100, 2 }; MokChannel mokChannel = new MokChannel(encodedCorrect); // Act MqttMsgSubscribe subscribe = MqttMsgSubscribe.Parse(130, MqttProtocolVersion.Version_5, mokChannel); // Assert Assert.Equal(subscribe.MessageId, (ushort)42); Assert.Equal(subscribe.QoSLevels, new MqttQoSLevel[] { MqttQoSLevel.AtLeastOnce, MqttQoSLevel.ExactlyOnce }); Assert.Equal(subscribe.Topics, new string[] { "first", "second" }); }
public static MqttMsgBase DecodeControlPacket(byte[] data) { byte fixedHeaderFirstByte = (byte)(data[0] >> MqttMsgBase.MSG_TYPE_OFFSET); switch (fixedHeaderFirstByte) { case MqttMsgBase.MQTT_MSG_CONNECT_TYPE: { return(MqttMsgConnect.Parse(data)); } case MqttMsgBase.MQTT_MSG_CONNACK_TYPE: { return(MqttMsgConnack.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE: { return(MqttMsgPublish.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBACK_TYPE: { return(MqttMsgPuback.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBREC_TYPE: { return(MqttMsgPubrec.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBREL_TYPE: { return(MqttMsgPubrel.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE: { return(MqttMsgPubcomp.Parse(data)); } case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE: { return(MqttMsgSubscribe.Parse(data)); } case MqttMsgBase.MQTT_MSG_SUBACK_TYPE: { return(MqttMsgSuback.Parse(data)); } case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE: { return(MqttMsgUnsubscribe.Parse(data)); } case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE: { return(MqttMsgUnsuback.Parse(data)); } case MqttMsgBase.MQTT_MSG_PINGREQ_TYPE: { return(MqttMsgPingReq.Parse(data)); } case MqttMsgBase.MQTT_MSG_PINGRESP_TYPE: { return(MqttMsgPingResp.Parse(data)); } case MqttMsgBase.MQTT_MSG_DISCONNECT_TYPE: { CrestronLogger.WriteToLog("PACKETDECODER - Riconosciuto DISCONNNECT: ", 1); return(MqttMsgDisconnect.Parse(data)); } default: { throw new FormatException(); } } }
internal void AddSubscription(string clientId, MqttMsgSubscribe packet) { subscriptionManager.Subscribe(clientId, packet); }
public MqttMsgBase DecodeControlPacket(byte[] data) { byte fixedHeaderFirstByte = (byte)(data[0] >> MSG_TYPE_OFFSET); switch (fixedHeaderFirstByte) { case MqttMsgBase.MQTT_MSG_CONNECT_TYPE: { return(MqttMsgConnect.Parse(data)); } case MqttMsgBase.MQTT_MSG_CONNACK_TYPE: { return(MqttMsgConnack.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE: { return(MqttMsgPublish.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBACK_TYPE: { return(MqttMsgPuback.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBREC_TYPE: { return(MqttMsgPubrec.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBREL_TYPE: { return(MqttMsgPubrel.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE: { return(MqttMsgPubcomp.Parse(data)); } case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE: { return(MqttMsgSubscribe.Parse(data)); } case MqttMsgBase.MQTT_MSG_SUBACK_TYPE: { return(MqttMsgSuback.Parse(data)); } case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE: { return(MqttMsgUnsubscribe.Parse(data)); } case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE: { return(MqttMsgUnsuback.Parse(data)); } case MqttMsgBase.MQTT_MSG_PINGREQ_TYPE: { return(MqttMsgPingReq.Parse(data)); } case MqttMsgBase.MQTT_MSG_PINGRESP_TYPE: { return(MqttMsgPingResp.Parse(data)); } case MqttMsgBase.MQTT_MSG_DISCONNECT_TYPE: { return(MqttMsgDisconnect.Parse(data)); } default: { throw new FormatException(" First byte shifted : " + fixedHeaderFirstByte); } } }
public void ProcessReceivedMessage(MqttRawMessage rawMessage) { if (!rawMessage.Connection.IsRunning) { return; } // update last message received ticks rawMessage.Connection.LastCommunicationTime = Environment.TickCount; // extract message type from received byte var msgType = (byte)((rawMessage.MessageType & MqttMsgBase.MSG_TYPE_MASK) >> MqttMsgBase.MSG_TYPE_OFFSET); var protocolVersion = (byte)rawMessage.Connection.ProtocolVersion; switch (msgType) { case MqttMsgBase.MQTT_MSG_CONNECT_TYPE: var connect = MqttMsgConnect.Parse( rawMessage.MessageType, protocolVersion, rawMessage.PayloadBuffer); rawMessage.Connection.EnqueueInternalEvent(new InternalEvent(connect)); break; case MqttMsgBase.MQTT_MSG_PINGREQ_TYPE: var pingReqest = MqttMsgPingReq.Parse(rawMessage.MessageType, protocolVersion); outgoingMessageHandler.PingResp(rawMessage.Connection); break; case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE: var subscribe = MqttMsgSubscribe.Parse( rawMessage.MessageType, protocolVersion, rawMessage.PayloadBuffer, rawMessage.PayloadLength); rawMessage.Connection.EnqueueInternalEvent(new InternalEvent(subscribe)); break; case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE: var publish = MqttMsgPublish.Parse( rawMessage.MessageType, protocolVersion, rawMessage.PayloadBuffer, rawMessage.PayloadLength); EnqueueInflight(rawMessage.Connection, publish, MqttMsgFlow.ToAcknowledge); break; case MqttMsgBase.MQTT_MSG_PUBACK_TYPE: // enqueue PUBACK message received (for QoS Level 1) into the internal queue var puback = MqttMsgPuback.Parse( rawMessage.MessageType, protocolVersion, rawMessage.PayloadBuffer); EnqueueInternal(rawMessage.Connection, puback); break; case MqttMsgBase.MQTT_MSG_PUBREC_TYPE: // enqueue PUBREC message received (for QoS Level 2) into the internal queue var pubrec = MqttMsgPubrec.Parse( rawMessage.MessageType, protocolVersion, rawMessage.PayloadBuffer); EnqueueInternal(rawMessage.Connection, pubrec); break; case MqttMsgBase.MQTT_MSG_PUBREL_TYPE: // enqueue PUBREL message received (for QoS Level 2) into the internal queue var pubrel = MqttMsgPubrel.Parse( rawMessage.MessageType, protocolVersion, rawMessage.PayloadBuffer); EnqueueInternal(rawMessage.Connection, pubrel); break; case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE: // enqueue PUBCOMP message received (for QoS Level 2) into the internal queue var pubcomp = MqttMsgPubcomp.Parse( rawMessage.MessageType, protocolVersion, rawMessage.PayloadBuffer); EnqueueInternal(rawMessage.Connection, pubcomp); break; case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE: var unsubscribe = MqttMsgUnsubscribe.Parse( rawMessage.MessageType, protocolVersion, rawMessage.PayloadBuffer, rawMessage.PayloadLength); rawMessage.Connection.EnqueueInternalEvent(new InternalEvent(unsubscribe)); break; case MqttMsgBase.MQTT_MSG_DISCONNECT_TYPE: var disconnect = MqttMsgDisconnect.Parse(rawMessage.MessageType, protocolVersion); rawMessage.Connection.EnqueueInternalEvent(new InternalEvent(disconnect)); break; case MqttMsgBase.MQTT_MSG_CONNACK_TYPE: case MqttMsgBase.MQTT_MSG_PINGRESP_TYPE: case MqttMsgBase.MQTT_MSG_SUBACK_TYPE: case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE: throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage); default: throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage); } }
public MqttMsgBase DecodeControlPacket(byte[] data) { #if PACKET_DEBUG CrestronLogger.WriteToLog("MQTTCLIENT - RECEIVE - " + BitConverter.ToString(data), 2); #endif byte fixedHeaderFirstByte = (byte)(data[0] >> MSG_TYPE_OFFSET); switch (fixedHeaderFirstByte) { case MqttMsgBase.MQTT_MSG_CONNECT_TYPE: { return(MqttMsgConnect.Parse(data)); } case MqttMsgBase.MQTT_MSG_CONNACK_TYPE: { return(MqttMsgConnack.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE: { return(MqttMsgPublish.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBACK_TYPE: { return(MqttMsgPuback.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBREC_TYPE: { return(MqttMsgPubrec.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBREL_TYPE: { return(MqttMsgPubrel.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE: { return(MqttMsgPubcomp.Parse(data)); } case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE: { return(MqttMsgSubscribe.Parse(data)); } case MqttMsgBase.MQTT_MSG_SUBACK_TYPE: { return(MqttMsgSuback.Parse(data)); } case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE: { return(MqttMsgUnsubscribe.Parse(data)); } case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE: { return(MqttMsgUnsuback.Parse(data)); } case MqttMsgBase.MQTT_MSG_PINGREQ_TYPE: { return(MqttMsgPingReq.Parse(data)); } case MqttMsgBase.MQTT_MSG_PINGRESP_TYPE: { return(MqttMsgPingResp.Parse(data)); } case MqttMsgBase.MQTT_MSG_DISCONNECT_TYPE: { return(MqttMsgDisconnect.Parse(data)); } default: { throw new FormatException(" First byte shifted : " + fixedHeaderFirstByte); } } }
public static void ProcessInternalEventQueue(MqttClientConnection clientConnection) { if (!clientConnection.IsRunning) { return; } InternalEvent internalEvent; if (clientConnection.EventQueue.TryDequeue(out internalEvent)) { MqttMsgBase msg = ((MsgInternalEvent)internalEvent).Message; if (msg != null) { switch (msg.Type) { // CONNECT message received case MqttMsgBase.MQTT_MSG_CONNECT_TYPE: clientConnection.OnMqttMsgConnected((MqttMsgConnect)msg); break; // SUBSCRIBE message received case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE: MqttMsgSubscribe subscribe = (MqttMsgSubscribe)msg; clientConnection.OnMqttMsgSubscribeReceived(subscribe.MessageId, subscribe.Topics, subscribe.QoSLevels); break; // SUBACK message received case MqttMsgBase.MQTT_MSG_SUBACK_TYPE: OnMqttMsgSubscribed(clientConnection, (MqttMsgSuback)msg); break; // PUBLISH message received case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE: // PUBLISH message received in a published internal event, no publish succeeded if (internalEvent.GetType() == typeof(MsgPublishedInternalEvent)) { OnMqttMsgPublished(clientConnection, msg.MessageId, false); } else { // raise PUBLISH message received event clientConnection.OnMqttMsgPublishReceived((MqttMsgPublish)msg); } break; // (PUBACK received for QoS Level 1) case MqttMsgBase.MQTT_MSG_PUBACK_TYPE: OnMqttMsgPublished(clientConnection, msg.MessageId, true); break; // (PUBREL received for QoS Level 2) case MqttMsgBase.MQTT_MSG_PUBREL_TYPE: clientConnection.OnMqttMsgPublishReceived((MqttMsgPublish)msg); break; // (PUBCOMP received for QoS Level 2) case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE: OnMqttMsgPublished(clientConnection, msg.MessageId, true); break; // UNSUBSCRIBE message received from client case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE: MqttMsgUnsubscribe unsubscribe = (MqttMsgUnsubscribe)msg; OnMqttMsgUnsubscribeReceived(clientConnection, unsubscribe.MessageId, unsubscribe.Topics); break; // UNSUBACK message received case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE: OnMqttMsgUnsubscribed(clientConnection, msg.MessageId); break; // DISCONNECT message received from client case MqttMsgBase.MQTT_MSG_DISCONNECT_TYPE: OnMqttMsgDisconnected(clientConnection); break; } } } // all events for received messages dispatched, check if there is closing connection if ((clientConnection.EventQueue.Count == 0) && clientConnection.IsConnectionClosing) { // client raw disconnection clientConnection.OnConnectionClosed(); } }