Пример #1
0
        public static void response_parse(PodMessage response, Pod pod)
        {
            pod.nonce_syncword = null;
            var parts = response.get_parts();

            foreach (var part in parts)
            {
                var response_type = (PodResponse)part.Item1;
                var response_body = part.Item2;

                switch (response_type)
                {
                case PodResponse.VersionInfo:
                    parse_version_response(response_body, pod);
                    break;

                case PodResponse.DetailInfo:
                    parse_information_response(response_body, pod);
                    break;

                case PodResponse.ResyncRequest:
                    parse_resync_response(response_body, pod);
                    break;

                case PodResponse.Status:
                    parse_status_response(response_body, pod);
                    break;

                default:
                    throw new ProtocolException($"Unknown response type {response_type}");
                }
            }
        }
Пример #2
0
        public async Task <PodMessage> GetPodResponse()
        {
            this.Started = DateTime.UtcNow;
            if (this.PdmMessage.TxLevel.HasValue)
            {
                this.PacketRadio.SetTxLevel(this.PdmMessage.TxLevel.Value);
            }

            if (!this.PdmMessage.address.HasValue)
            {
                this.PdmMessage.address = this.Pod.radio_address;
            }

            if (!this.PdmMessage.AckAddressOverride.HasValue)
            {
                this.PdmMessage.AckAddressOverride = this.Pod.radio_address;
            }

            if (!this.PdmMessage.sequence.HasValue)
            {
                this.PdmMessage.sequence = this.Pod.radio_message_sequence;
            }


            var packets = this.PdmMessage.get_radio_packets(this.Pod.radio_packet_sequence);

            Packet received     = null;
            var    packet_count = packets.Count;

            this.unique_packets = packet_count * 2;

            for (int part = 0; part < packet_count; part++)
            {
                var packet       = packets[part];
                int repeat_count = -1;
                int timeout      = 10000;
                while (true)
                {
                    repeat_count++;
                    if (repeat_count == 0)
                    {
                        this.Logger.Log($"Sending PDM message part {part + 1}/{packet_count}");
                    }
                    else
                    {
                        this.Logger.Log($"Sending PDM message part {part + 1}/{packet_count} (Repeat: {repeat_count})");
                    }

                    RadioPacketType expected_type;
                    if (part == packet_count - 1)
                    {
                        expected_type = RadioPacketType.POD;
                    }
                    else
                    {
                        expected_type = RadioPacketType.ACK;
                    }

                    try
                    {
                        received = await this.ExchangePackets(packet.with_sequence(this.Pod.radio_packet_sequence), expected_type, timeout);

                        break;
                    }
                    catch (OmnipyTimeoutException)
                    {
                        this.Logger.Log("Trying to recover from timeout error");
                        if (part == 0)
                        {
                            if (repeat_count == 0)
                            {
                                timeout = 15000;
                                continue;
                            }
                            else if (repeat_count == 1)
                            {
                                timeout = 10000;
                                Thread.Sleep(2000);
                                continue;
                            }
                            else if (repeat_count == 2)
                            {
                                await this.PacketRadio.Reset();

                                timeout = 15000;
                                continue;
                            }
                            else
                            {
                                this.Logger.Log("Failed recovery");
                                this.reset_sequences();
                                throw;
                            }
                        }
                        else if (part < packet_count - 1)
                        {
                            if (repeat_count < 2)
                            {
                                timeout = 20000;
                                continue;
                            }
                            else
                            {
                                throw;
                            }
                        }
                        else
                        {
                            if (repeat_count < 10)
                            {
                                timeout = 20000;
                                continue;
                            }
                            else
                            {
                                throw;
                            }
                        }
                    }
                    catch (PacketRadioException)
                    {
                        this.Logger.Log("Trying to recover from radio error");
                        this.radio_errors++;
                        if (part == 0)
                        {
                            if (repeat_count < 2)
                            {
                                await this.PacketRadio.Reset();

                                continue;
                            }
                            else if (repeat_count < 4)
                            {
                                await this.PacketRadio.Reset();

                                timeout = 10000;
                                Thread.Sleep(2000);
                                continue;
                            }
                            else
                            {
                                this.Logger.Log("Failed recovery");
                                throw;
                            }
                        }
                        else if (part < packet_count - 1)
                        {
                            if (repeat_count < 6)
                            {
                                await this.PacketRadio.Reset();

                                timeout = 10000;
                                Thread.Sleep(2000);
                                continue;
                            }
                            else
                            {
                                this.Logger.Log("Failed recovery");
                                throw;
                            }
                        }
                        else
                        {
                            if (repeat_count < 10)
                            {
                                await this.PacketRadio.Reset();

                                timeout = 10000;
                                Thread.Sleep(2000);
                                continue;
                            }
                            else
                            {
                                this.Logger.Log("Failed recovery");
                                this.reset_sequences();
                                throw;
                            }
                        }
                    }
                    catch (ProtocolException pe)
                    {
                        if (pe.ReceivedPacket != null && expected_type == RadioPacketType.POD && pe.ReceivedPacket.type == RadioPacketType.ACK)
                        {
                            this.Logger.Log("Trying to recover from protocol error");
                            //this.Pod.radio_packet_sequence++;
                            this.Pod.radio_message_sequence++;
                            this.PdmMessage.sequence = this.Pod.radio_message_sequence;

                            return(await GetPodResponse());
                        }
                        else
                        {
                            throw pe;
                        }
                    }
                    //catch (ProtocolException pe)
                    //{
                    //    if (pe.ReceivedPacket != null && expected_type == RadioPacketType.POD && pe.ReceivedPacket.type == RadioPacketType.ACK)
                    //    {
                    //        this.Logger.Log("Trying to recover from protocol error");
                    //        received = pe.ReceivedPacket;
                    //        while(true)
                    //        {
                    //            this.Pod.radio_packet_sequence = (received.sequence + 1) % 32;
                    //            var interimAck = this.interim_ack(this.PdmMessage.AckAddressOverride.Value, this.Pod.radio_packet_sequence);
                    //            try
                    //            {
                    //                received = await this.ExchangePackets(interimAck, RadioPacketType.POD, timeout);
                    //                break;
                    //            }
                    //            catch (ProtocolException)
                    //            {
                    //                this.Pod.radio_packet_sequence = (this.Pod.radio_packet_sequence + 1) % 32;
                    //                continue;
                    //            }
                    //            catch (OmnipyTimeoutException)
                    //            {
                    //                this.Pod.radio_packet_sequence = (this.Pod.radio_packet_sequence + 1) % 32;
                    //                throw new StatusUpdateRequiredException(pe);
                    //            }
                    //            catch(Exception)
                    //            {
                    //                throw;
                    //            }
                    //        }
                    //        continue;
                    //    }
                    //    if (pe.ReceivedPacket != null)
                    //    {
                    //        this.Logger.Log("Trying to recover from protocol error");
                    //        this.Pod.radio_packet_sequence = (pe.ReceivedPacket.sequence + 1) % 32;
                    //        this.Pod.radio_message_sequence = (this.Pod.radio_message_sequence + 1) % 16;
                    //        if (pe.ReceivedPacket != null && expected_type == RadioPacketType.POD && pe.ReceivedPacket.type == RadioPacketType.ACK)
                    //        {
                    //            throw new StatusUpdateRequiredException(pe);
                    //        }
                    //    }
                    //    else
                    //        throw;
                    //}
                    catch (Exception) { throw; }
                }
                part++;
                this.Pod.radio_packet_sequence = (received.sequence + 1) % 32;
            }

            this.PacketLogger.Log($"SENT MSG {this.PdmMessage}");

            var part_count = 0;

            if (received.type == RadioPacketType.POD)
            {
                part_count = 1;
                this.Logger.Log($"Received POD message part {part_count}");
            }
            var pod_response = new PodMessage();

            while (!pod_response.add_radio_packet(received))
            {
                var ack_packet = this.interim_ack(this.PdmMessage.AckAddressOverride.Value, (received.sequence + 1) % 32);
                received = await this.ExchangePackets(ack_packet, RadioPacketType.CON);

                part_count++;
                this.Logger.Log($"Received POD message part {part_count}");
            }

            this.PacketLogger.Log($"RCVD MSG {pod_response}");
            this.Logger.Log("Send and receive completed.");
            this.Pod.radio_message_sequence = (pod_response.sequence.Value + 1) % 16;
            this.Pod.radio_packet_sequence  = (received.sequence + 1) % 32;

            return(pod_response);
        }