/// <summary>
        /// Process a raw message
        /// </summary>
        /// <param name="rxpk"><see cref="Rxpk"/> representing incoming message</param>
        /// <param name="startTimeProcessing">Starting time counting from the moment the message was received</param>
        /// <returns>A <see cref="DownlinkPktFwdMessage"/> if a message has to be sent back to device</returns>
        public async Task <DownlinkPktFwdMessage> ProcessMessageAsync(Rxpk rxpk, DateTime startTimeProcessing)
        {
            if (!LoRaPayload.TryCreateLoRaPayload(rxpk, out LoRaPayload loRaPayload))
            {
                Logger.Log("There was a problem in decoding the Rxpk", LogLevel.Error);
                return(null);
            }

            if (this.loraRegion == null)
            {
                if (!RegionFactory.TryResolveRegion(rxpk))
                {
                    // log is generated in Region factory
                    // move here once V2 goes GA
                    return(null);
                }

                this.loraRegion = RegionFactory.CurrentRegion;
            }

            if (loRaPayload.LoRaMessageType == LoRaMessageType.JoinRequest)
            {
                return(await this.ProcessJoinRequestAsync(rxpk, (LoRaPayloadJoinRequest)loRaPayload, startTimeProcessing));
            }
            else if (loRaPayload.LoRaMessageType == LoRaMessageType.UnconfirmedDataUp || loRaPayload.LoRaMessageType == LoRaMessageType.ConfirmedDataUp)
            {
                return(await this.ProcessDataMessageAsync(rxpk, (LoRaPayloadData)loRaPayload, startTimeProcessing));
            }

            Logger.Log("Unknwon message type in rxpk, message ignored", LogLevel.Error);
            return(null);
        }