Example #1
0
        public async Task InterceptApplicationMessagePublishAsync(MqttApplicationMessageInterceptorContext context)
        {
            context.AcceptPublish = true;
            if (context.ApplicationMessage == null)
            {
                return;
            }

            var payload = context.ApplicationMessage.Payload == null
                ? null
                : Encoding.UTF8.GetString(context.ApplicationMessage?.Payload);

            if (context.ApplicationMessage.Retain)
            {
                if (context.ApplicationMessage.Topic.StartsWith("mcu/"))
                {
                    return;
                }

                var msg = _repo.AddMessage(new MqttMessage
                {
                    Created     = DateTime.Now,
                    Message     = payload,
                    Topic       = context.ApplicationMessage.Topic,
                    ContentType = context.ApplicationMessage.ContentType
                });
                await _repo.SaveChangesAsync();
            }

            // _logger.LogInformation(
            //     $"Message: ClientId = {context.ClientId}, Topic = {context.ApplicationMessage?.Topic},"
            //     + $" Payload = {payload}, QoS = {context.ApplicationMessage?.QualityOfServiceLevel},"
            //     + $" Retain-Flag = {context.ApplicationMessage?.Retain}");
        }
Example #2
0
        public async Task InterceptApplicationMessagePublishAsync(MqttApplicationMessageInterceptorContext context)
        {
            //context.AcceptPublish = true;
            if (context.ApplicationMessage == null)
            {
                return;
            }

            var payload = context.ApplicationMessage.Payload == null
                ? null
                : Encoding.ASCII.GetString(context.ApplicationMessage?.Payload, 0, context.ApplicationMessage.Payload.Count());

            if (payload == null)
            {
                _logger.LogError(
                    $"Payload is null Message: ClientId = {context.ClientId}, Topic = {context.ApplicationMessage?.Topic},"
                    + $" Payload = {payload}, QoS = {context.ApplicationMessage?.QualityOfServiceLevel},"
                    + $" Retain-Flag = {context.ApplicationMessage?.Retain}");
                return;
            }

            var afterPars = Functions.GetPayload(context.ApplicationMessage?.Payload);

            if (context.ApplicationMessage.Retain)
            {
                var msg = _repo.AddMessage(new MqttMessage
                {
                    Created     = DateTime.Now,
                    Message     = JsonConvert.SerializeObject(afterPars, Formatting.Indented),
                    Topic       = context.ApplicationMessage.Topic,
                    ContentType = context.ApplicationMessage.ContentType
                });
                //var tree = context.ApplicationMessage.Topic.Split('/');

                if (await _repo.SaveChangesAsync())
                {
                    context.AcceptPublish = true;
                }
            }

            _logger.LogInformation(
                $"Message: ClientId = {context.ClientId}, Topic = {context.ApplicationMessage?.Topic},"
                + $" Payload = {payload}, QoS = {context.ApplicationMessage?.QualityOfServiceLevel},"
                + $" Retain-Flag = {context.ApplicationMessage?.Retain}");
        }
        private async Task LogMessage(MqttConnectionValidatorContext context, bool newConnection = false,
                                      bool showPassword = false)
        {
            if (context == null)
            {
                return;
            }

            if (newConnection)
            {
                var connection = new Connection
                {
                    ClientId     = context.ClientId,
                    CleanSession = context.CleanSession,
                    Endpoint     = context.Endpoint,
                    Password     = context.Password,
                    Username     = context.Username
                };
                _repo.AddConnection(connection);
                await _repo.SaveChangesAsync();
            }

            if (showPassword)
            {
                _logger.LogInformation(
                    $"New connection: ClientId = {context.ClientId}, Endpoint = {context.Endpoint},"
                    + $" Username = {context.Username}, Password = {context.Password},"
                    + $" CleanSession = {context.CleanSession}");
            }
            else
            {
                _logger.LogInformation(
                    $"New connection: ClientId = {context.ClientId}, Endpoint = {context.Endpoint},"
                    + $" Username = {context.Username}, CleanSession = {context.CleanSession}");
            }
        }
Example #4
0
        public async Task StartAsync(
            CancellationToken cancellationToken)
        {
            _appLifetime.ApplicationStarted.Register(OnStarted);
            _appLifetime.ApplicationStopping.Register(OnStopping);
            _appLifetime.ApplicationStopped.Register(OnStopped);

            using var scope = _serviceProvider.CreateScope();
            var serverBuilder = scope.ServiceProvider.GetRequiredService <IServerBuilder>();
            var options       = serverBuilder.GetOptionsBuilder(_interceptor, _messageInterceptor);

            Server = serverBuilder.GetServer();
            await Server.StartAsync(options.Build());

            Server.StartedHandler = new MqttServerStartedHandlerDelegate(e =>
            {
                Console.WriteLine("Mqtt Broker start " + e);
            });

            Server.StoppedHandler = new MqttServerStoppedHandlerDelegate(e =>
            {
                Console.WriteLine("Mqtt Broker stop " + e);
            });

            Server.ClientSubscribedTopicHandler = new MqttServerClientSubscribedHandlerDelegate(e =>
            {
                var vehicleId = e.TopicFilter.Topic
                                .Replace("platooning/", "").Replace("/#", "");

                _logger.LogInformation("Client subscribed " + e.ClientId + " topic " + e.TopicFilter.Topic + "Vehicle Id " +
                                       vehicleId);
                try
                {
                    var audit = new Audit
                    {
                        ClientId = e.ClientId,
                        Type     = "Sub",
                        Topic    = e.TopicFilter.Topic,
                        Payload  = JsonConvert.SerializeObject(e.TopicFilter, Formatting.Indented)
                    };
                    _repo.AddAudit(audit);
                    var sub = _repo.GetSubscribeByTopic(e.ClientId, e.TopicFilter.Topic,
                                                        e.TopicFilter.QualityOfServiceLevel.ToString());
                    if (sub != null)
                    {
                        _logger.LogInformation($"There is a subcribe like ClientID {e.ClientId}.");
                        return;
                    }

                    var subClient = new Subscribe
                    {
                        Topic    = e.TopicFilter.Topic,
                        Enable   = true,
                        ClientId = e.ClientId,
                        QoS      = e.TopicFilter.QualityOfServiceLevel.ToString()
                    };
                    _repo.AddSubscribe(subClient);
                }
                catch (Exception exception)
                {
                    var log = new Log
                    {
                        Exception = exception.StackTrace
                    };
                    _repo.AddLogAsync(log);
                    _logger.LogError("Error = MqttServerClientSubscribedHandlerDelegate ", exception.StackTrace);
                }
                finally
                {
                    _repo.SaveChangesAsync(cancellationToken);
                }
            });

            Server.ClientUnsubscribedTopicHandler = new MqttServerClientUnsubscribedTopicHandlerDelegate(e =>
            {
                try
                {
                    var clientId    = e.ClientId;
                    var topicFilter = e.TopicFilter;
                    _logger.LogInformation($"[{DateTime.Now}] Client '{clientId}' un-subscribed to {topicFilter}.");
                    try
                    {
                        var sub        = _repo.GetSubscribeById(e.ClientId).Where(s => s.Topic == topicFilter);
                        var subscribes = sub as List <Subscribe> ?? sub.ToList();
                        if (subscribes.All(a => a.Topic != topicFilter))
                        {
                            return;
                        }
                        subscribes
                        .ForEach(a => a.Enable = false);
                    }
                    catch (Exception exception)
                    {
                        var log = new Log
                        {
                            Exception = exception.StackTrace
                        };
                        _repo.AddLogAsync(log);
                        _logger.LogError("Error = MqttServerClientSubscribedHandlerDelegate ", exception.StackTrace);

                        Console.WriteLine(exception);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"[{DateTime.Now}] Client get error " + ex.Message);
                }
                finally
                {
                    _repo.SaveChangesAsync(cancellationToken);
                }
            });

            Server.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(e =>
            {
                try
                {
                    var payload    = Functions.GetPayload(e.ApplicationMessage.Payload);
                    var payloadser = JsonConvert.SerializeObject(payload, Formatting.Indented);
                    var tree       = e.ApplicationMessage.Topic.Split('/');
                    var audit      = new Audit
                    {
                        ClientId = e.ClientId,
                        Type     = "Pub",
                        Topic    = e.ApplicationMessage.Topic,
                        Payload  = payloadser
                    };
                    _repo.AddAudit(audit);
                    if (e.ClientId == null)
                    {
                        var log = new Log
                        {
                            Exception = new string("Broker publish message itself " +
                                                   payloadser + " " +
                                                   e.ClientId)
                        };
                        _repo.AddLogAsync(log);
                        //_repo.SaveChangesAsync(cancellationToken);
                        return;
                    }

                    if (!tree.First().Contains("platooning"))
                    {
                        var log = new Log
                        {
                            Exception = new string("Mqtt broker just only response with starting \"platoon\" " +
                                                   payloadser + " " +
                                                   e.ClientId)
                        };
                        _repo.AddLogAsync(log);
                        //_repo.SaveChangesAsync(cancellationToken);
                        return;
                    }

                    if (payload.PlatoonDissolveStatus)
                    {
                        if (_repo.GetPlatoon().Any(a => a.ClientId == e.ClientId && a.IsLead))
                        {
                            Console.WriteLine(
                                $"[{DateTime.Now}] This is lead Vehicle PlatoonDissolveStatus is true all platoon infor must be deleted" +
                                " Client Id " + e.ClientId + " payload " +
                                payload);

                            var platoonlist      = _repo.GetPlatoon().Where(a => a.IsFollower);
                            var platoonlistArray = platoonlist as Platoon[] ?? platoonlist.ToArray();
                            foreach (var platoon in platoonlistArray)
                            {
                                Server.UnsubscribeAsync(platoon.ClientId, "platooning/broadcast/" + platoon.PlatoonRealId);
                                Server.UnsubscribeAsync(platoon.ClientId, "platooning/" + platoon.ClientId);
                            }

                            _repo.DeletePlatoonRange(platoonlistArray);
                        }
                        else
                        {
                            Console.WriteLine(
                                $"[{DateTime.Now}] This is following Vehicle PlatoonDissolveStatus is true all platoon infor must be deleted" +
                                " Client Id " + e.ClientId + " payload " +
                                payload);

                            var followingVehicle = _repo.GetPlatoon().FirstOrDefault(a => a.IsFollower && a.ClientId == e.ClientId);
                            Server.UnsubscribeAsync(followingVehicle.ClientId, "platooning/" + followingVehicle.ClientId);
                            _repo.DeletePlatoon(followingVehicle);
                        }
                    }

                    if (payload.Maneuver == Maneuver.CreatePlatoon)
                    {
                        if (tree.Length != 4)
                        {
                            var log = new Log
                            {
                                Exception = new string("For creating platoon, topic must 4 length 1. \"platooning\" " +
                                                       " 2.  \"message\" " +
                                                       " 3.  \"leadvehicleID\" " +
                                                       " 4.  \"platoonID\" " +

                                                       " payload " +
                                                       payloadser + " " +
                                                       " client ID " + e.ClientId +
                                                       " topic " + e.ApplicationMessage.Topic)
                            };
                            _repo.AddLogAsync(log);
                            //_repo.SaveChangesAsync(cancellationToken);
                            return;
                        }

                        var platoonId     = tree[3];
                        var platoonList   = _repo.GetPlatoon().ToList();
                        var leadVehicleId = tree[2];
                        var leadVehicle   = _repo.GetSubscribeById(leadVehicleId);
                        var pla           = platoonList
                                            .FirstOrDefault(f => f.Enable && f.PlatoonRealId == platoonId);
                        if (leadVehicle != null && pla == null)
                        {
                            var platoon = new Platoon()
                            {
                                Enable        = true,
                                ClientId      = e.ClientId,
                                IsLead        = true,
                                VechicleId    = tree[2],
                                PlatoonRealId = tree[3]
                            };
                            _repo.AddPlatoon(platoon);
                            Console.WriteLine($"[{DateTime.Now}] Creating new Platoon Client Id " + e.ClientId +
                                              " platooning Id" + platoon.PlatoonRealId + " payload " + payloadser);
                        }
                        else
                        {
                            Console.WriteLine($"[{DateTime.Now}] Platoon is already created Client Id " + e.ClientId +
                                              " platooning Id" + platoonId + " payload " + payloadser);
                        }
                    }
                    else if (payload.Maneuver == Maneuver.JoinRequest)
                    {
                        if (tree.Length != 3)
                        {
                            var log = new Log
                            {
                                Exception = new string("For joining platoon, topic must 3 length 1. \"platooning\" " +
                                                       " 2.  \"message\" " +
                                                       " 3.  \"followingVehicleId\" " +
                                                       " 4.  \"#\" " +
                                                       " payload " +
                                                       payloadser + " " +
                                                       " client ID " + e.ClientId +
                                                       " topic " + e.ApplicationMessage.Topic)
                            };
                            _repo.AddLogAsync(log);
                            //_repo.SaveChangesAsync();
                            return;
                        }

                        var isFollowing = _repo.GetPlatoon()
                                          .FirstOrDefault(f => f.IsFollower && f.VechicleId == tree[2] && f.Enable);
                        if (isFollowing != null)
                        {
                            return;
                        }
                        var platoonLead = _repo.GetPlatoon().FirstOrDefault(f => f.IsLead && f.Enable);
                        if (platoonLead != null)
                        {
                            var platoon = new Platoon()
                            {
                                Enable        = false,
                                ClientId      = e.ClientId,
                                IsLead        = false,
                                IsFollower    = true,
                                VechicleId    = tree[2],
                                PlatoonRealId = platoonLead.PlatoonRealId
                            };
                            _repo.AddPlatoon(platoon);
                            Console.WriteLine($"[{DateTime.Now}] Join Platoon Client Id " + e.ClientId +
                                              " platooning Id" + platoon.PlatoonRealId + " payload " + payloadser);
                            var message = new BitArray(_dataLenght);
                            message.Set(0, false);
                            message.Set(1, false);
                            message.Set(2, true);

                            Server.PublishAsync("platooning/" + platoonLead.ClientId + "/" + tree[2],
                                                Encoding.ASCII.GetString(Functions.BitArrayToByteArray(message)));
                        }
                    }
                    else if (payload.Maneuver == Maneuver.JoinAccepted)
                    {
                        Console.WriteLine($"[{DateTime.Now}] Join accepted Client Id " + e.ClientId + " payload " +
                                          payloadser);
                        var followvehicleId = tree[1];
                        var leadVehicle     = tree[2];
                        var plattonId       = tree[3];
                        var allplatoon      = _repo.GetPlatoon();

                        if (allplatoon != null)
                        {
                            var enumerable    = allplatoon as Platoon[] ?? allplatoon.ToArray();
                            var platoonfollow = enumerable.FirstOrDefault(f => f.IsFollower && f.ClientId == followvehicleId);
                            if (platoonfollow != null)
                            {
                                platoonfollow.Enable        = true;
                                platoonfollow.PlatoonRealId = plattonId;
                                _repo.UpdatePlatoon(platoonfollow);
                            }
                            else
                            {
                                var platoonlead = enumerable
                                                  .FirstOrDefault(f => f.IsLead && f.Enable && f.ClientId == leadVehicle);
                                if (platoonlead != null)
                                {
                                    var platoon = new Platoon()
                                    {
                                        Enable        = true,
                                        ClientId      = e.ClientId,
                                        IsLead        = false,
                                        IsFollower    = true,
                                        VechicleId    = followvehicleId,
                                        PlatoonRealId = platoonlead.PlatoonRealId
                                    };
                                    _repo.AddPlatoon(platoon);
                                }
                            }
                        }
                    }
                    else if (payload.Maneuver == Maneuver.JoinRejected)
                    {
                        Console.WriteLine($"[{DateTime.Now}] Join rejected Client Id " + e.ClientId + " payload " +
                                          payloadser);
                        var platoonfollow = _repo.GetPlatoon()
                                            .FirstOrDefault(f => f.IsFollower && f.ClientId == tree[1]);

                        if (platoonfollow != null)
                        {
                            _repo.DeletePlatoon(platoonfollow);
                        }
                    }
                    else
                    {
                        var log = new Log
                        {
                            Exception = new string("Unknown Maneuver " +
                                                   payloadser + " " +
                                                   e.ClientId)
                        };
                        _repo.AddLogAsync(log);
                    }
                }
                catch (Exception exception)
                {
                    Console.WriteLine(exception);
                    var log = new Log
                    {
                        Exception = exception.StackTrace
                    };
                    _repo.AddLogAsync(log);
                }
                finally
                {
                    _repo.SaveChangesAsync(cancellationToken);
                }


                OnDataReceived(e.ApplicationMessage.Payload);
            });
        }
Example #5
0
        private async void InsertValues(
            object state)
        {
            if (_running)
            {
                _logger.LogInformation(4444, $"Job is already running");
                return;
            }

            _running = true;

            var lastTimestamp    = _repository.LastTimestamp();
            var currentTimestamp = lastTimestamp.AddMinutes(1);

            while (currentTimestamp < DateTime.Now.CutSeconds())
            {
                _ = _repository.AddTimestamp(currentTimestamp.CutSeconds());
                currentTimestamp = currentTimestamp.AddMinutes(1);
            }

            _ = await _repository.SaveChangesAsync();

            var targets = new List <MeasureValue>();
            var delete  = new List <MqttMessage>();

            // Filter relevant messages
            var messages =
                await _repository
                .GetMessagesAsQueryable()
                .Where(msg => !msg.Topic.EndsWith("neo7m"))
                .OrderBy(msg => msg.Created)
                .ToListAsync();

            foreach (var message in messages)
            {
                if (!double.TryParse(message.Message, out var v))
                {
                    delete.Add(message);
                    continue;
                }

                var fields = message.Topic.Split('/');

                if (fields.Length != 4)
                {
                    delete.Add(message);
                    continue;
                }

                var tmpTimestamp = message.Created.CutSeconds();
                var timestamp    = _repository.GetTimestamp(tmpTimestamp);

                if (timestamp == null)
                {
                    _logger.LogInformation($"Timestamp {tmpTimestamp.ToString()} not exist");
                    continue;
                }

                var room        = _repository.GetRoom(fields[1]);
                var measureType = _repository.GetMeasureType(fields[2]);
                var sensorType  = _repository.GetSensorType(fields[3]);

                if (room == null && measureType == null && sensorType == null)
                {
                    _logger.LogError(6666, $"Error with types");
                    continue;
                }

                var value = new MeasureValue
                {
                    MeasureTimeTimestamp = timestamp.Timestamp,
                    SensorTypeName       = sensorType.Name,
                    RoomName             = room?.Name,
                    MeasureTypeName      = measureType?.Name,
                    Value = v
                };

                if (targets.FirstOrDefault(
                        msg =>
                        msg.RoomName == value.RoomName &&
                        msg.SensorTypeName == value.SensorTypeName &&
                        msg.MeasureTypeName == value.MeasureTypeName &&
                        msg.MeasureTimeTimestamp == value.MeasureTimeTimestamp) != null)
                {
                    _logger.LogError(4444, $"Value are duplicate in MqttMessages");
                    delete.Add(message);
                    continue;
                }
                targets.Add(value);
                delete.Add(message);
            }

            foreach (var target in targets)
            {
                if (!_repository.MeasureExists(
                        target.RoomName,
                        target.MeasureTypeName,
                        target.SensorTypeName,
                        target.MeasureTimeTimestamp))
                {
                    _repository.AddMeasureValue(target);
                }
            }

            foreach (var dMessage in delete)
            {
                _repository.DeleteMessage(dMessage);
            }

            _ = await _repository.SaveChangesAsync();

            _running = false;
        }