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}"); } } }
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); }