예제 #1
0
        protected bool ValidGlobalsatPort(SerialPort port)
        {
            GlobalsatPacket packet = PacketFactory.GetWhoAmI();
            bool            res    = false;
            //If "probe" packet fails, this is not a Globalsat port
            //If some distinction needed (other device?), set some flag here
            GhPacketBase response = null;

            try
            {
                response = SendPacket(packet);
            }
            catch (Exception)
            {
            }
            if (response != null && response.CommandId == packet.CommandId && response.PacketLength > 1)
            {
                string devId = response.ByteArr2String(0, 8);
                if (!string.IsNullOrEmpty(devId))
                {
                    lastDevId = devId;
                    if (this.FitnessDevice.configInfo.AllowedIds == null || this.FitnessDevice.configInfo.AllowedIds.Count == 0)
                    {
                        this.devId = devId;
                        res        = true;
                    }
                    else
                    {
                        foreach (string aId in this.FitnessDevice.configInfo.AllowedIds)
                        {
                            if (devId.StartsWith(aId))
                            {
                                this.devId = devId;
                                res        = true;
                                break;
                            }
                        }
                    }
                }
            }
            if (!res)
            {
                this.Close();
            }
            return(res);
        }
예제 #2
0
        //This routine has a lot of try-catch-rethrow to simplify debugging
        //Globalsat device communication is tricky...
        public virtual GhPacketBase SendPacket(GlobalsatPacket packet)
        {
            //Use packet factory, to make sure the packet matches the device
            GhPacketBase received = this.PacketFactory;

            //sending occasionally fails, retry
            int remainingAttempts = 3;

            while (remainingAttempts > 0)
            {
                try
                {
                    if (!port.IsOpen)
                    {
                        //Physical port should be closed
                        port.Open();
                    }

                    if (packet.CommandId == GhPacketBase.CommandWhoAmI)
                    {
                        //Speed-up device detection, keep this as short as possible.
                        //625XT seem to work with 5ms, 505 needs more than 100
                        port.ReadTimeout = this.FitnessDevice.ReadTimeoutDetect;
                    }
                    else if (packet.CommandId == GhPacketBase.CommandGetScreenshot)
                    {
                        port.ReadTimeout = 5000;
                    }
                    else
                    {
                        port.ReadTimeout = this.FitnessDevice.ReadTimeout;
                    }

                    //Override from device config?
                    if (this.FitnessDevice.configInfo.ReadTimeout > 0 &&
                        (packet.CommandId != GhPacketBase.CommandGetScreenshot ||
                         this.FitnessDevice.configInfo.ReadTimeout > port.ReadTimeout))
                    {
                        port.ReadTimeout = this.FitnessDevice.configInfo.ReadTimeout;
                    }

                    byte[] sendPayload = packet.ConstructPayload(this.FitnessDevice.BigEndianPacketLength);
                    try
                    {
                        /*
                         * Console.Write("Write:");
                         *              for(int i = 0; i < sendPayload.Length;i++)
                         *              {
                         *                  Console.Write(" " + sendPayload[i].ToString() );
                         *              }
                         *              Console.WriteLine("");
                         */
                        port.Write(sendPayload, 0, sendPayload.Length);
                    }
                    catch (Exception e)
                    {
                        string s = string.Format("Error occurred, sending {0} bytes.",
                                                 sendPayload.Length);
                        ReportError(s, packet.CommandId == GhPacketBase.CommandWhoAmI, e);
                        port.Close();
                        throw;
                    }

                    try
                    {
                        int data = port.ReadByte();
                        received.CommandId = (byte)data;
                        if (data < 0 || data > 255)
                        {
                            //Special handling for first byte -1 is stream closed
                            throw new TimeoutException(string.Format("No data received for {0},{1}", packet.CommandId, data));
                        }
                        if (packet.CommandId == GhPacketBase.CommandWhoAmI)
                        {
                            this.DataRecieved = false;
                        }
                        else
                        {
                            this.DataRecieved = true;
                        }
                        int hiPacketLen = port.ReadByte();
                        int loPacketLen = port.ReadByte();
                        //Note: The endian for size (except for 561) from the device always seem to be the same (not so when sending)
                        received.PacketLength = (Int16)((hiPacketLen << 8) + loPacketLen);
                    }
                    catch (Exception e)
                    {
                        string s = string.Format("Error occurred, receiving {0} bytes ({1},{2}).",
                                                 received.PacketLength, packet.CommandId, received.CommandId);
                        ReportError(s, packet.CommandId == GhPacketBase.CommandWhoAmI, e);
                        port.Close();
                        throw;
                    }

                    if (packet.CommandId != GhPacketBase.CommandGetScreenshot && received.PacketLength > this.FitnessDevice.configInfo.MaxPacketPayload ||
                        received.PacketLength > 0x1000)
                    {
                        string s = string.Format("Error occurred, bad response receiving {0} bytes ({1},{2}).",
                                                 received.PacketLength, packet.CommandId, received.CommandId);
                        ReportError(s, packet.CommandId == GhPacketBase.CommandWhoAmI);
                        port.Close();
                        throw new Exception(Properties.Resources.Device_OpenDevice_Error);
                    }

                    received.PacketData = new byte[received.PacketLength];
                    byte checksum      = 0;
                    int  receivedBytes = 0; //debug timeouts

                    try
                    {
                        for (Int16 b = 0; b < received.PacketLength; b++)
                        {
                            int data = port.ReadByte();
                            if (data < 0 || data > 255)
                            {
                                //-1 is stream closed
                                throw new TimeoutException(string.Format("All data not received for {0}({4},{1}) bytes ({2},{3}).",
                                                                         received.PacketLength, receivedBytes, packet.CommandId, received.CommandId, data));
                            }
                            received.PacketData[b] = (byte)data;
                            receivedBytes++;
                        }
                        checksum = (byte)port.ReadByte();
                        receivedBytes++;

                        /*
                         *          Console.Write("Read: id:" + received.CommandId + " length:" + received.PacketLength);
                         *          for(int i = 0; i < received.PacketLength;i++)
                         *          {
                         *              Console.Write(" " + received.PacketData[i].ToString() );
                         *          }
                         *          Console.WriteLine(" checksum:" + checksum);
                         */
                    }
                    catch (Exception e)
                    {
                        string s = string.Format("Error occurred, receiving {0}({1}) bytes ({2},{3}).",
                                                 received.PacketLength, receivedBytes, packet.CommandId, received.CommandId);
                        ReportError(s, packet.CommandId == GhPacketBase.CommandWhoAmI, e);
                        port.Close();
                        throw;

                        //Debug template, if the device is corrupted
                        //Should use resend
                        //Ignore the exception, just to get data from the device
                        //if (!(this is Gh505Device &&
                        //    (receivedBytes == 2005 && received.PacketLength == 2068 ||
                        //    receivedBytes == 913 && received.PacketLength == 976)))
                        //{
                        //    throw e;
                        //}
                        //received.PacketLength = (Int16)receivedBytes;
                        //checksum = 0;
                        //overrideException = true;
                    }

                    if (!received.ValidResponseCrc(checksum))
                    {
                        string s = string.Format("Error occurred, invalid checksum receiving {0}({1}) bytes ({2},{3}).",
                                                 received.PacketLength, receivedBytes, packet.CommandId, received.CommandId);
                        ReportError(s, packet.CommandId == GhPacketBase.CommandWhoAmI);
                        port.Close();
                        throw new Exception(Properties.Resources.Device_OpenDevice_Error);
                    }
                    else if (received.CommandId == GhPacketBase.ResponseResendTrackSection && remainingAttempts > 0)
                    {
                        //retry sending
                        remainingAttempts--;
                    }
                    else if (received.CommandId != packet.CommandId &&
                             //TODO: Cleanup in allowed sender/response allowed (probably overload)
                             !((received.CommandId == GhPacketBase.CommandGetTrackFileSections ||
                                received.CommandId == GhPacketBase.CommandId_FINISH ||
                                received.CommandId == GhPacketBase.ResponseSendTrackFinish) &&
                               (packet.CommandId == GhPacketBase.CommandGetNextTrackSection ||
                                packet.CommandId == GhPacketBase.CommandGetTrackFileSections ||
                                packet.CommandId == GhPacketBase.CommandSendTrackSection))
                             )
                    {
                        string s = string.Format("Error occurred, invalid response {0}({1}) bytes ({2},{3}).",
                                                 received.PacketLength, receivedBytes, packet.CommandId, received.CommandId);
                        ReportError(s, packet.CommandId == GhPacketBase.CommandWhoAmI);
                        if (received.CommandId == GhPacketBase.ResponseInsuficientMemory)
                        {
                            throw new InsufficientMemoryException(Properties.Resources.Device_InsuficientMemory_Error);
                        }
                        throw new Exception(Properties.Resources.Device_OpenDevice_Error);
                    }
                    else
                    {
                        //Assume OK response, no more tries
                        remainingAttempts = 0;
                    }
                }

#pragma warning disable CS0168 // Variable is declared but never used
                catch (Exception e)
#pragma warning restore CS0168 // Variable is declared but never used
                {
                    remainingAttempts--;
                    if (packet.CommandId == GhPacketBase.CommandWhoAmI || remainingAttempts <= 0)
                    {
                        //No need retry
                        this.Close();
                        throw;
                    }
                }
            }
            return(received);
        }
예제 #3
0
        public virtual int SendRoute(IList <GlobalsatRoute> routes, IJobMonitor jobMonitor)
        {
            int  res          = 0;
            int  totPackets   = routes.Count;
            int  extraPackets = 0; //Open, wpt etc
            bool status       = true;

            if (this.Open())
            {
                try
                {
                    GlobalsatPacket packet;
                    GlobalsatPacket response;
                    if (this.RouteRequiresWaypoints)
                    {
                        packet   = PacketFactory.GetWaypoints();
                        response = (GlobalsatPacket)this.SendPacket(packet);
                        IList <GlobalsatWaypoint> wptDev = response.ResponseGetWaypoints();
                        extraPackets++;
                        jobMonitor.PercentComplete = (float)(res + extraPackets) / (float)(totPackets + extraPackets);

                        //Routes need waypoints - find those missing
                        IList <GlobalsatWaypoint> wptSend = new List <GlobalsatWaypoint>();
                        foreach (GlobalsatRoute route in routes)
                        {
                            foreach (GlobalsatWaypoint wpt1 in route.wpts)
                            {
                                bool found = false;
                                foreach (GlobalsatWaypoint wpt2 in wptDev)
                                {
                                    if (GhPacketBase.ToGlobLatLon(wpt1.Latitude) == GhPacketBase.ToGlobLatLon(wpt2.Latitude) &&
                                        GhPacketBase.ToGlobLatLon(wpt1.Longitude) == GhPacketBase.ToGlobLatLon(wpt2.Longitude))
                                    {
                                        found = true;
                                        break;
                                    }
                                }
                                if (!found)
                                {
                                    wptSend.Add(wpt1);
                                }
                            }
                        }

                        if (wptSend.Count > 0)
                        {
                            //Send with normal protocol, 625XT requires one by one
                            int sent = this.SendWaypoints(wptSend, jobMonitor);
                            if (sent < wptSend.Count)
                            {
                                status = false;
                            }
                            else
                            {
                                extraPackets++;
                                jobMonitor.PercentComplete = (float)(res + extraPackets) / (float)(totPackets + extraPackets);
                                this.Open(); //Reopen
                                extraPackets++;
                                jobMonitor.PercentComplete = (float)(res + extraPackets) / (float)(totPackets + extraPackets);
                            }
                        }
                    }
                    else
                    {
                        //Check if capacity is sufficient. Wpt checked separetly
                        int rtePoint = 0;
                        foreach (GlobalsatRoute route in routes)
                        {
                            rtePoint += route.wpts.Count;
                        }
                        if (rtePoint > this.FitnessDevice.MaxNoRoutePoints)
                        {
                            jobMonitor.ErrorText = string.Format("Need to send {0} route points, the device can only handle {1}.",
                                                                 rtePoint, this.FitnessDevice.MaxNoRoutePoints);
                            status = false;
                        }
                    }

                    if (status)
                    {
                        //Finally the routes...
                        foreach (GlobalsatRoute route in routes)
                        {
                            packet   = PacketFactory.SendRoute(route);
                            response = (GlobalsatPacket)this.SendPacket(packet);
                            //Note: No way to determine that GB-580/GH-505 do not really receive the routes?
                            res++;
                            jobMonitor.PercentComplete = (float)(res + extraPackets) / (float)(totPackets + extraPackets);
                        }
                    }
                }
                catch (Exception e)
                {
                    jobMonitor.ErrorText = Properties.Resources.Device_SendRoute_Error + e;
                    //throw new Exception(Properties.Resources.Device_SendRoute_Error + e);
                    status = false;
                }
                finally
                {
                    this.Close();
                }
            }
            if (status && !this.DataRecieved)
            {
                NoCommunicationError(jobMonitor);
            }
            return(res);
        }