Example #1
0
        public async Task <PodCommandResult> PerformExchange(IMessage requestMessage, IMessageExchangeParameters messageExchangeParameters,
                                                             IMessageProgress messageProgress, CancellationToken ct)
        {
            var previousContext = SynchronizationContext.Current;

            try
            {
                // SynchronizationContext.SetSynchronizationContext(MessageSynchronizationContext);
                var messageExchange = await MessageExchangeProvider.GetMessageExchanger(messageExchangeParameters, Pod, messageProgress, ct).ConfigureAwait(false);

                var response = await messageExchange.GetResponse(requestMessage, messageProgress, ct);

                return(messageExchange.ParseResponse(response, Pod));
            }
            catch (Exception e)
            {
                return(new PodCommandResult()
                {
                    Success = false
                });
            }
            finally
            {
                // SynchronizationContext.SetSynchronizationContext(previousContext);
            }
        }
Example #2
0
        public override async Task CancelBolus(IMessageProgress progress, CancellationToken ct)
        {
            try
            {
                await UpdateStatusInternal(progress, ct);

                AssertRunningStatus();

                if (BolusState != BolusState.Immediate)
                {
                    throw new PdmException("Immediate bolus is not running");
                }

                // await send_request(ProtocolHelper.request_cancel_bolus(), true);

                if (BolusState == BolusState.Immediate)
                {
                    throw new PdmException("Failed to cancel running bolus");
                }
            }
            catch (OmniCoreException) { throw; }
            catch (Exception e)
            {
                throw new PdmException("Unexpected error", e);
            }
        }
Example #3
0
        //private async Task send_request(IRequest request, bool with_nonce = false)
        //{
        //if (with_nonce)
        //{
        //    var nonce_val = this.Nonce.GetNext();
        //    request.set_nonce(nonce_val);
        //    nonce_syncword = null;
        //}

        //var me = new MessageExchange(request, this.packetRadio, this.Pod);

        //var response = await me.GetPodResponse();
        //ProtocolHelper.response_parse(response, this.Pod);

        //if (with_nonce && nonce_syncword != null)
        //{
        //    Debug.WriteLine("Nonce resync requested");
        //    this.Nonce.Sync(request.sequence.Value);
        //    var nonce_val = this.Nonce.GetNext();
        //    request.set_nonce(nonce_val);
        //    nonce_syncword = null;
        //    radio_message_sequence = request.sequence.Value;
        //    response = await me.GetPodResponse();
        //    ProtocolHelper.response_parse(response, this.Pod);
        //    if (nonce_syncword != null)
        //    {
        //        this.Nonce.Reset();
        //        throw new PdmException("Nonce sync failed");
        //    }
        //}
        //}

        private async Task <PodCommandResult> UpdateStatusInternal(IMessageProgress progress, CancellationToken ct,
                                                                   StatusRequestType update_type = StatusRequestType.Standard)
        {
            var request = new ErosMessageBuilder().WithStatus(update_type).Build();

            return(await MessageHandler.PerformExchange(request, StandardParameters, progress, ct));
        }
        public async Task InitializeExchange(IMessageProgress messageProgress, CancellationToken ct)
        {
            if (FinalAckTask != null)
            {
                await FinalAckTask;
            }

            await RileyLink.Connect();
        }
Example #5
0
 public override async Task UpdateStatus(IMessageProgress progress, CancellationToken ct,
                                         StatusRequestType update_type = StatusRequestType.Standard)
 {
     try
     {
         Debug.WriteLine($"Updating pod status, request type {update_type}");
         await this.UpdateStatusInternal(progress, ct, update_type);
     }
     catch (OmniCoreException) { throw; }
     catch (Exception e)
     {
         throw new PdmException("Unexpected error", e);
     }
 }
Example #6
0
        public override async Task AcknowledgeAlerts(IMessageProgress progress, CancellationToken ct, byte alert_mask)
        {
            try
            {
                Debug.WriteLine($"Acknowledging alerts, bitmask: {alert_mask}");
                await UpdateStatusInternal(progress, ct);

                AssertImmediateBolusInactive();
                if (Progress < PodProgress.PairingSuccess)
                {
                    throw new PdmException("Pod not paired completely yet.");
                }

                if (Progress == PodProgress.ErrorShuttingDown)
                {
                    throw new PdmException("Pod is shutting down, cannot acknowledge alerts.");
                }

                if (Progress == PodProgress.AlertExpiredShuttingDown)
                {
                    throw new PdmException("Acknowledgement period expired, pod is shutting down");
                }

                if (Progress > PodProgress.AlertExpiredShuttingDown)
                {
                    throw new PdmException("Pod is not active");
                }

                if ((AlertMask & alert_mask) != alert_mask)
                {
                    throw new PdmException("Bitmask is invalid for current alert state");
                }

                // await send_request(ProtocolHelper.request_acknowledge_alerts(alert_mask));
            }
            catch (OmniCoreException) { throw; }
            catch (Exception e)
            {
                throw new PdmException("Unexpected error", e);
            }
        }
Example #7
0
        public async Task <IMessageExchange> GetMessageExchanger(IMessageExchangeParameters messageExchangeParameters, IPod pod,
                                                                 IMessageProgress messageProgress, CancellationToken ct)
        {
            if (RileyLinkInstance == null)
            {
                RileyLinkInstance = new RileyLink();
            }

            if (RileyLinkMessageExchange == null)
            {
                RileyLinkMessageExchange = new RileyLinkMessageExchange(messageExchangeParameters, pod, RileyLinkInstance);
            }
            else
            {
                RileyLinkMessageExchange.UpdateParameters(messageExchangeParameters, pod, RileyLinkInstance);
            }

            await RileyLinkMessageExchange.InitializeExchange(messageProgress, ct);

            return(RileyLinkMessageExchange);
        }
Example #8
0
        public override async Task Bolus(IMessageProgress progress, CancellationToken ct, decimal bolusAmount)
        {
            try
            {
                Debug.WriteLine($"Bolusing {bolusAmount}U");
                await UpdateStatusInternal(progress, ct);

                AssertRunningStatus();
                AssertImmediateBolusInactive();

                if (bolusAmount < 0.05m)
                {
                    throw new PdmException("Cannot bolus less than 0.05U");
                }

                if (bolusAmount % 0.05m != 0)
                {
                    throw new PdmException("Bolus must be multiples of 0.05U");
                }

                if (bolusAmount > 30m)
                {
                    throw new PdmException("Cannot bolus more than 30U");
                }

                // await send_request(ProtocolHelper.request_bolus(bolusAmount), true);

                if (BolusState != BolusState.Immediate)
                {
                    throw new PdmException("Pod did not start bolusing");
                }
            }
            catch (OmniCoreException) { throw; }
            catch (Exception e)
            {
                throw new PdmException("Unexpected error", e);
            }
        }
        public async Task <IMessage> GetResponse(IMessage requestMessage, IMessageProgress messageExchangeProgress, CancellationToken ct)
        {
            this.Started = DateTime.UtcNow;
            if (MessageExchangeParameters.TransmissionLevelOverride.HasValue)
            {
                RileyLink.SetTxLevel(MessageExchangeParameters.TransmissionLevelOverride.Value);
            }

            var erosRequestMessage = requestMessage as ErosMessage;
            var packets            = GetRadioPackets(erosRequestMessage);

            RadioPacket 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)
                    {
                        Debug.WriteLine($"Sending PDM message part {part + 1}/{packet_count}");
                    }
                    else
                    {
                        Debug.WriteLine($"Sending PDM message part {part + 1}/{packet_count} (Repeat: {repeat_count})");
                    }

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

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

                        break;
                    }
                    catch (OmniCoreTimeoutException)
                    {
                        Debug.WriteLine("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 RileyLink.Reset();

                                timeout = 15000;
                                continue;
                            }
                            else
                            {
                                Debug.WriteLine("Failed recovery");
                                Pod.PacketSequence = 0;
                                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)
                    {
                        Debug.WriteLine("Trying to recover from radio error");
                        this.radio_errors++;
                        if (part == 0)
                        {
                            if (repeat_count < 2)
                            {
                                await RileyLink.Reset();

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

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

                                timeout = 10000;
                                Thread.Sleep(2000);
                                continue;
                            }
                            else
                            {
                                Debug.WriteLine("Failed recovery");
                                throw;
                            }
                        }
                        else
                        {
                            if (repeat_count < 10)
                            {
                                await RileyLink.Reset();

                                timeout = 10000;
                                Thread.Sleep(2000);
                                continue;
                            }
                            else
                            {
                                Debug.WriteLine("Failed recovery");
                                Pod.PacketSequence = 0;
                                throw;
                            }
                        }
                    }
                    catch (ErosProtocolException pe)
                    {
                        if (pe.ReceivedPacket != null && expected_type == PacketType.POD && pe.ReceivedPacket.type == PacketType.ACK)
                        {
                            Debug.WriteLine("Trying to recover from protocol error");
                            this.Pod.PacketSequence++;

                            return(await GetResponse(requestMessage, messageExchangeProgress, ct));
                        }
                        else
                        {
                            throw pe;
                        }
                    }
                    catch (Exception) { throw; }
                }
                part++;
                this.Pod.PacketSequence = (received.sequence + 1) % 32;
            }

            Debug.WriteLine($"SENT MSG {requestMessage}");

            var part_count = 0;

            if (received.type == PacketType.POD)
            {
                part_count = 1;
                Debug.WriteLine($"Received POD message part {part_count}");
            }
            var responseBuilder = new ErosResponseBuilder();

            var radioAddress = Pod.RadioAddress;

            if (MessageExchangeParameters.AddressOverride.HasValue)
            {
                radioAddress = MessageExchangeParameters.AddressOverride.Value;
            }

            var ackAddress = radioAddress;

            if (MessageExchangeParameters.AckAddressOverride.HasValue)
            {
                ackAddress = MessageExchangeParameters.AckAddressOverride.Value;
            }

            while (!responseBuilder.WithRadioPacket(received))
            {
                var ackPacket = this.InterimAckPacket(ackAddress, (received.sequence + 1) % 32);
                received = await this.ExchangePackets(ackPacket, PacketType.CON);

                part_count++;
                Debug.WriteLine($"Received POD message part {part_count}");
            }

            var podResponse = responseBuilder.Build();

            Debug.WriteLine($"RCVD MSG {podResponse}");
            Debug.WriteLine("Send and receive completed.");
            this.Pod.MessageSequence = (podResponse.sequence.Value + 1) % 16;
            this.Pod.PacketSequence  = (received.sequence + 1) % 32;

            var finalAckPacket = this.FinalAckPacket(ackAddress, (received.sequence + 1) % 32);

            FinalAckTask = Task.Run(() => AcknowledgeEndOfMessage(finalAckPacket));
            return(podResponse);
        }
Example #10
0
 public abstract Task CancelBolus(IMessageProgress progress, CancellationToken ct);
Example #11
0
 public abstract Task Bolus(IMessageProgress progress, CancellationToken ct, decimal bolusAmount);
Example #12
0
 public abstract Task AcknowledgeAlerts(IMessageProgress progress, CancellationToken ct, byte alertMask);
Example #13
0
 public abstract Task UpdateStatus(IMessageProgress progress, CancellationToken ct, StatusRequestType requestType);