Пример #1
0
        public override async Task <MqttMessage> ProcessAsync()
        {
            if (!Session.IsConnected)
            {
                Session.Disconnect(Message);
                return(null);
            }

            Session.IncrementKeepAlive();
            List <QualityOfServiceLevelType> list = new List <QualityOfServiceLevelType>();
            SubscribeMessage msg = Message as SubscribeMessage;

            List <string> validSubs = Session.Subscribe(Message);
            IEnumerator <KeyValuePair <string, QualityOfServiceLevelType> > en = msg.Topics.GetEnumerator();

            while (en.MoveNext())
            {
                MqttUri uri = new MqttUri(en.Current.Key);
                QualityOfServiceLevelType qos = validSubs.Contains(uri.ToString())
                    ? en.Current.Value
                    : QualityOfServiceLevelType.Failure;
                list.Add(qos);
                Session.AddQosLevel(uri.Resource, qos);
            }

            return(await Task.FromResult <MqttMessage>(new SubscriptionAckMessage(Message.MessageId, list)));
        }
Пример #2
0
        public static byte[] ConvertToCoap(CoapSession session, EventMessage message, byte[] observableToken = null)
        {
            CoapMessage coapMessage = null;
            CoapToken   token       = CoapToken.Create();

            ushort id = observableToken == null?session.CoapSender.NewId(token.TokenBytes) : session.CoapSender.NewId(observableToken);

            string uriString = CoapUri.Create(session.Config.Authority, message.ResourceUri, IsEncryptedChannel);

            if (message.Protocol == ProtocolType.MQTT)
            {
                MqttMessage    msg = MqttMessage.DecodeMessage(message.Message);
                PublishMessage pub = msg as PublishMessage;
                MqttUri        uri = new MqttUri(pub.Topic);
                if (observableToken == null)
                {
                    RequestMessageType messageType = msg.QualityOfService == QualityOfServiceLevelType.AtMostOnce ? RequestMessageType.NonConfirmable : RequestMessageType.Confirmable;
                    //request
                    coapMessage = new CoapRequest(id, messageType, MethodType.POST, new Uri(uriString), MediaTypeConverter.ConvertToMediaType(message.ContentType));
                }
                else
                {
                    //response
                    coapMessage = new CoapResponse(id, ResponseMessageType.NonConfirmable, ResponseCodeType.Content, observableToken, MediaTypeConverter.ConvertToMediaType(uri.ContentType), msg.Payload);
                }
            }
            else if (message.Protocol == ProtocolType.COAP)
            {
                CoapMessage msg = CoapMessage.DecodeMessage(message.Message);
                if (observableToken == null)
                {
                    //request
                    coapMessage = new CoapRequest(id, msg.MessageType == CoapMessageType.Confirmable ? RequestMessageType.Confirmable : RequestMessageType.NonConfirmable, MethodType.POST, new Uri(uriString), MediaTypeConverter.ConvertToMediaType(message.ContentType), msg.Payload);
                }
                else
                {
                    //response
                    coapMessage = new CoapResponse(id, ResponseMessageType.NonConfirmable, ResponseCodeType.Content, observableToken, MediaTypeConverter.ConvertToMediaType(message.ContentType), msg.Payload);
                }
            }
            else
            {
                if (observableToken == null)
                {
                    //request
                    coapMessage = new CoapRequest(id, RequestMessageType.NonConfirmable, MethodType.POST, new Uri(uriString), MediaTypeConverter.ConvertToMediaType(message.ContentType), message.Message);
                }
                else
                {
                    //response
                    coapMessage = new CoapResponse(id, ResponseMessageType.NonConfirmable, ResponseCodeType.Content, observableToken, MediaTypeConverter.ConvertToMediaType(message.ContentType), message.Message);
                }
            }

            return(coapMessage.Encode());
        }
Пример #3
0
        private async Task PublishAsync(PublishMessage message)
        {
            MessageAuditRecord record   = null;
            EventMetadata      metadata = null;

            try
            {
                MqttUri mqttUri = new MqttUri(message.Topic);
                metadata = await graphManager.GetPiSystemMetadataAsync(mqttUri.Resource);

                if (EventValidator.Validate(true, metadata, Channel, graphManager, context).Validated)
                {
                    EventMessage msg = new EventMessage(mqttUri.ContentType, mqttUri.Resource, ProtocolType.MQTT,
                                                        message.Encode(), DateTime.UtcNow, metadata.Audit);
                    if (!string.IsNullOrEmpty(mqttUri.CacheKey))
                    {
                        msg.CacheKey = mqttUri.CacheKey;
                    }

                    if (mqttUri.Indexes != null)
                    {
                        List <KeyValuePair <string, string> > list = GetIndexes(mqttUri);
                        await adapter.PublishAsync(msg, list);
                    }
                    else
                    {
                        await adapter.PublishAsync(msg);
                    }
                }
                else
                {
                    if (metadata.Audit)
                    {
                        record = new MessageAuditRecord("XXXXXXXXXXXX", session.Identity, Channel.TypeId, "MQTT",
                                                        message.Payload.Length, MessageDirectionType.In, false, DateTime.UtcNow,
                                                        "Not authorized, missing resource metadata, or channel encryption requirements");
                    }

                    throw new SecurityException(string.Format("'{0}' not authorized to publish to '{1}'",
                                                              session.Identity, metadata.ResourceUriString));
                }
            }
            catch (Exception ex)
            {
                await logger?.LogErrorAsync(ex, $"MQTT adapter PublishAsync error on channel '{Channel.Id}'.");

                OnError?.Invoke(this, new ProtocolAdapterErrorEventArgs(Channel.Id, ex));
            }
            finally
            {
                if (metadata != null && metadata.Audit && record != null)
                {
                    await messageAuditor?.WriteAuditRecordAsync(record);
                }
            }
        }
Пример #4
0
        private void Dispatch(PublishMessage msg)
        {
            MqttUri uri = new MqttUri(msg.Topic);

            if (Dispatcher != null)
            {
                Dispatcher.Dispatch(uri.Resource, uri.ContentType, msg.Payload);
            }
            else
            {
                Session.Publish(msg);
            }
        }
Пример #5
0
        //private Task<bool> CanSubscribe(string resourceUriString)
        //{
        //    TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();

        //    Task t = Task.Factory.StartNew(async () =>
        //    {
        //        try
        //        {
        //            bool r = await adapter.CanSubscribeAsync(resourceUriString, Channel.IsEncrypted);
        //            tcs.SetResult(r);
        //        }
        //        catch (Exception ex)
        //        {
        //            await logger?.LogErrorAsync(ex, $"MQTT adapter CanSubscribe error on channel '{Channel.Id}'.");
        //            tcs.SetException(ex);
        //        }
        //    });

        //    return tcs.Task;
        //}

        private void Session_OnPublish(object sender, MqttMessageEventArgs args)
        {
            try
            {
                PublishMessage message = args.Message as PublishMessage;
                MqttUri        muri    = new MqttUri(message.Topic);
                PublishAsync(message).GetAwaiter();
            }
            catch (Exception ex)
            {
                logger?.LogErrorAsync(ex, $"MQTT adapter Session_OnPublish  error on channel '{Channel.Id}'.").GetAwaiter();
                OnError?.Invoke(this, new ProtocolAdapterErrorEventArgs(Channel.Id, ex));
            }
        }
Пример #6
0
        private static byte[] MqttConversion(MqttSession session, byte[] message, string contentType = null)
        {
            PublishMessage            msg = MqttMessage.DecodeMessage(message) as PublishMessage;
            MqttUri                   uri = new MqttUri(msg.Topic);
            QualityOfServiceLevelType?qos = session.GetQoS(uri.Resource);

            PublishMessage pm = new PublishMessage(false, qos.HasValue ? qos.Value : QualityOfServiceLevelType.AtMostOnce, false, session.NewId(), uri.Resource, msg.Payload);

            if (pm.QualityOfService != QualityOfServiceLevelType.AtMostOnce)
            {
                session.Quarantine(pm, SkunkLab.Protocols.Mqtt.Handlers.DirectionType.Out);
            }

            return(pm.Encode());
        }
Пример #7
0
        private static byte[] MqttConversion(MqttSession session, byte[] message)
        {
            PublishMessage            msg = MqttMessage.DecodeMessage(message) as PublishMessage;
            MqttUri                   uri = new MqttUri(msg.Topic);
            QualityOfServiceLevelType?qos = session.GetQoS(uri.Resource);

            PublishMessage pm = new PublishMessage(false, qos ?? QualityOfServiceLevelType.AtMostOnce, false,
                                                   session.NewId(), uri.Resource, msg.Payload);

            if (pm.QualityOfService != QualityOfServiceLevelType.AtMostOnce)
            {
                session.Quarantine(pm, DirectionType.Out);
            }

            return(pm.Encode());
        }
Пример #8
0
        private List <KeyValuePair <string, string> > GetIndexes(MqttUri mqttUri)
        {
            List <KeyValuePair <string, string> > list = new List <KeyValuePair <string, string> >(mqttUri.Indexes);

            if (mqttUri.Indexes.Contains(new KeyValuePair <string, string>("~", "~")))
            {
                list.Remove(new KeyValuePair <string, string>("~", "~"));
                var query = config.GetClientIndexes().Where((ck) => ck.Key == session.Config.IdentityClaimType);
                if (query.Count() == 1)
                {
                    query.GetEnumerator().MoveNext();
                    list.Add(new KeyValuePair <string, string>(query.GetEnumerator().Current.Value, "~" + session.Identity));
                }
            }

            return(list.Count > 0 ? list : null);
        }
Пример #9
0
 private void Session_OnUnsubscribe(object sender, MqttMessageEventArgs args)
 {
     try
     {
         UnsubscribeMessage msg = (UnsubscribeMessage)args.Message;
         foreach (var item in msg.Topics)
         {
             MqttUri uri = new MqttUri(item.ToLowerInvariant());
             if (adapter.CanSubscribeAsync(uri.Resource, Channel.IsEncrypted).GetAwaiter().GetResult())
             {
                 adapter.UnsubscribeAsync(uri.Resource).GetAwaiter();
             }
         }
     }
     catch (Exception ex)
     {
         logger.LogError(ex, $"MQTT adapter Session_OnUnsubscribe error on channel '{Channel.Id}'.");
         OnError?.Invoke(this, new ProtocolAdapterErrorEventArgs(Channel.Id, ex));
     }
 }
Пример #10
0
        public override async Task <MqttMessage> ProcessAsync()
        {
            Session.IncrementKeepAlive();
            MqttMessage message = Session.GetHeldMessage(Message.MessageId);

            if (message != null)
            {
                PublishMessage msg = message as PublishMessage;
                MqttUri        uri = new MqttUri(msg.Topic);
                if (Dispatcher != null)
                {
                    Dispatcher.Dispatch(uri.Resource, uri.ContentType, msg.Payload);
                }
                else
                {
                    Session.Publish(msg, true);
                }
            }

            return(await Task.FromResult <MqttMessage>(new PublishAckMessage(PublishAckType.PUBCOMP, Message.MessageId)));
        }
Пример #11
0
        private List <string> Session_OnSubscribe(object sender, MqttMessageEventArgs args)
        {
            List <string> list = new List <string>();

            try
            {
                SubscribeMessage message = args.Message as SubscribeMessage;

                SubscriptionMetadata metadata = new SubscriptionMetadata()
                {
                    Identity    = session.Identity,
                    Indexes     = session.Indexes,
                    IsEphemeral = true
                };

                foreach (var item in message.Topics)
                {
                    MqttUri uri = new MqttUri(item.Key);
                    string  resourceUriString = uri.Resource;

                    Task <bool> t         = CanSubscribe(resourceUriString);
                    bool        subscribe = t.Result;

                    if (subscribe)
                    {
                        Task <string> subTask = Subscribe(resourceUriString, metadata);
                        string        subscriptionUriString = subTask.Result;
                        list.Add(resourceUriString);
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, $"MQTT adapter Session_OnSubscribe error on channel '{Channel.Id}'.");
                OnError?.Invoke(this, new ProtocolAdapterErrorEventArgs(Channel.Id, ex));
            }

            return(list);
        }
Пример #12
0
        private void Session_OnUnsubscribe(object sender, MqttMessageEventArgs args)
        {
            try
            {
                UnsubscribeMessage msg = (UnsubscribeMessage)args.Message;
                foreach (var item in msg.Topics)
                {
                    MqttUri uri = new MqttUri(item.ToLowerInvariant());

                    if (EventValidator.Validate(false, uri.Resource, Channel, graphManager, context).Validated)
                    {
                        adapter.UnsubscribeAsync(uri.Resource).GetAwaiter();
                        logger?.LogInformationAsync($"MQTT adapter unsubscribed {uri.ToString()}");
                    }
                }
            }
            catch (Exception ex)
            {
                logger?.LogErrorAsync(ex, $"MQTT adapter Session_OnUnsubscribe error on channel '{Channel.Id}'.").GetAwaiter();
                OnError?.Invoke(this, new ProtocolAdapterErrorEventArgs(Channel.Id, ex));
            }
        }
Пример #13
0
        private List <string> Session_OnSubscribe(object sender, MqttMessageEventArgs args)
        {
            List <string> list = new List <string>();

            try
            {
                SubscribeMessage message = args.Message as SubscribeMessage;

                SubscriptionMetadata metadata = new SubscriptionMetadata
                {
                    Identity    = session.Identity,
                    Indexes     = session.Indexes,
                    IsEphemeral = true
                };

                foreach (var item in message.Topics)
                {
                    MqttUri uri = new MqttUri(item.Key);
                    string  resourceUriString = uri.Resource;

                    if (EventValidator.Validate(false, resourceUriString, Channel, graphManager, context).Validated)
                    {
                        Task <string> subTask = Subscribe(resourceUriString, metadata);
                        string        subscriptionUriString = subTask.Result;
                        list.Add(resourceUriString);
                    }
                }
            }
            catch (Exception ex)
            {
                logger?.LogErrorAsync(ex, $"MQTT adapter Session_OnSubscribe error on channel '{Channel.Id}'.")
                .GetAwaiter();
                OnError?.Invoke(this, new ProtocolAdapterErrorEventArgs(Channel.Id, ex));
            }

            return(list);
        }