/// <summary> /// Processes the packet within the context. Returns true whether the packet was processed or throttled. /// </summary> /// <param name="channel">The through which the packet is coming/going out.</param> /// <param name="context">The packet context for this operation.</param> /// <returns>True whether the packet was processed or throttled, false otherwise.</returns> public static ProcessingState Process(Emitter.Connection channel, ProcessingContext context) { return(ProcessingState.Failure); }
/// <summary> /// Processes the packet within the context. Returns true whether the packet was processed or throttled. /// </summary> /// <param name="channel">The through which the packet is coming/going out.</param> /// <param name="context">The packet context for this operation.</param> /// <returns>True whether the packet was processed or throttled, false otherwise.</returns> public static ProcessingState Process(Connection channel, ProcessingContext context) { // Get the buffer var buffer = context.Buffer; // Extract the message type first var pBuffer = buffer.AsBytePointer(); if (!ValidMqtt(pBuffer)) { return(ProcessingState.Failure); } // Do we have a full header? if (buffer.Length < MqttPacket.HeaderSize) { return(ProcessingState.InsufficientData); } // Get the length of the packet int headerSize; var length = PeekLength(pBuffer + 1, buffer.Length, out headerSize); if (length > MqttPacket.MaxPayloadSize) { return(ProcessingState.Failure); } // Do we have enough data? if (length == -1 || (headerSize + length) > buffer.Length) { return(ProcessingState.InsufficientData); } // There might be several packets in the same segment. We need to specify // that one is decoded and forward only that one to the next decoder. // However, we must not discard the segment completely as we might loose data! context.Throttle(headerSize + length); // Acquire the appropriate packet var msgType = (MqttPacketType)((*pBuffer & MqttPacket.MSG_TYPE_MASK) >> MqttPacket.MSG_TYPE_OFFSET); var packet = Acquire(msgType, channel.Client); if (packet == null) { return(ProcessingState.Stop); } // If we don't have enough data... //if (length > buffer.Length) // return ProcessingState.InsufficientData; // If we have protocol version set, add it to the packet var mqttCtx = channel.Client.Context; if (mqttCtx != null) { packet.ProtocolVersion = mqttCtx.Version; packet.IsEmitter = mqttCtx.IsEmitter; } try { // Read the packet packet.TryRead(context.Buffer, headerSize, length); // Call the appropriate handler switch (msgType) { case MqttPacketType.Connect: return(MqttHandler.OnConnect(channel.Client, packet as MqttConnectPacket)); case MqttPacketType.Subscribe: return(MqttHandler.OnSubscribe(channel.Client, packet as MqttSubscribePacket)); case MqttPacketType.Unsubscribe: return(MqttHandler.OnUnsubscribe(channel.Client, packet as MqttUnsubscribePacket)); case MqttPacketType.PingReq: return(MqttHandler.OnPing(channel.Client, packet as MqttPingReqPacket)); case MqttPacketType.Disconnect: return(MqttHandler.OnDisconnect(channel.Client, packet as MqttDisconnectPacket)); case MqttPacketType.Publish: return(MqttHandler.OnPublish(channel.Client, packet as MqttPublishPacket)); case MqttPacketType.PubAck: return(MqttHandler.OnPublishAck(channel.Client, packet as MqttPubackPacket)); default: break; } } catch (Exception ex) { // Log the exception Service.Logger.Log(ex); } finally { // Release the packet now if (packet.Lifetime == PacketLifetime.Automatic) { packet.TryRelease(); } } // We're really done handling this, do not queue additional processors return(ProcessingState.Stop); }