public override void Decode(IByteBuffer buffer) { base.Decode(buffer); var returnCodes = new SubscribeReturnCode[RemaingLength]; for (int i = 0; i < RemaingLength; i++) { var returnCode = (SubscribeReturnCode)buffer.ReadByte(); if (returnCode > SubscribeReturnCode.SuccessMaximumQoS2 && returnCode != SubscribeReturnCode.Failure) { throw new DecoderException($"[MQTT-3.9.3-2]. Invalid return code: {returnCode}"); } returnCodes[i] = returnCode; } ReturnCodes = returnCodes; FixedHeader.RemaingLength = 0; }
internal static SubscribeReturnCode ToReturnCode(this MqttQualityOfService qos) { SubscribeReturnCode returnCode = default; switch (qos) { case MqttQualityOfService.AtMostOnce: returnCode = SubscribeReturnCode.MaximumQoS0; break; case MqttQualityOfService.AtLeastOnce: returnCode = SubscribeReturnCode.MaximumQoS1; break; case MqttQualityOfService.ExactlyOnce: returnCode = SubscribeReturnCode.MaximumQoS2; break; } return(returnCode); }
public async Task ExecuteAsync(string clientId, IPacket input, IMqttChannel <IPacket> channel) { if (input.Type != MqttPacketType.Subscribe) { return; } Subscribe subscribe = input as Subscribe; ClientSession session = _sessionRepository.Read(clientId); if (session == null) { throw new MqttException(ServerProperties.SessionRepository_ClientSessionNotFound(clientId)); } List <SubscribeReturnCode> returnCodes = new List <SubscribeReturnCode>(); foreach (Subscription subscription in subscribe.Subscriptions) { try { if (!_topicEvaluator.IsValidTopicFilter(subscription.TopicFilter)) { _tracer.Error(ServerProperties.ServerSubscribeFlow_InvalidTopicSubscription(subscription.TopicFilter, clientId)); returnCodes.Add(SubscribeReturnCode.Failure); continue; } ClientSubscription clientSubscription = session .GetSubscriptions() .FirstOrDefault(s => s.TopicFilter == subscription.TopicFilter); if (clientSubscription != null) { clientSubscription.MaximumQualityOfService = subscription.MaximumQualityOfService; } else { clientSubscription = new ClientSubscription { ClientId = clientId, TopicFilter = subscription.TopicFilter, MaximumQualityOfService = subscription.MaximumQualityOfService }; session.AddSubscription(clientSubscription); } await SendRetainedMessagesAsync(clientSubscription, channel); MqttQualityOfService supportedQos = _configuration.GetSupportedQos(subscription.MaximumQualityOfService); SubscribeReturnCode returnCode = supportedQos.ToReturnCode(); returnCodes.Add(returnCode); } catch (RepositoryException repoEx) { _tracer.Error(repoEx, ServerProperties.ServerSubscribeFlow_ErrorOnSubscription(clientId, subscription.TopicFilter)); returnCodes.Add(SubscribeReturnCode.Failure); } } _sessionRepository.Update(session); await channel.SendAsync(new SubscribeAck( subscribe.PacketId, returnCodes.ToArray())); }