예제 #1
0
        public GPacketReceived ReceivePacket()
        {
            GPacketReceived packetIn = new GPacketReceived();

            m_physLayer.Receive(packetIn);
            return(packetIn);
        }
        public void Receive(GPacketReceived packetIn)
        {
            //log("Receive() - waiting...");
            TransFlag.Reset();
            if (!TransFlag.WaitOne((int)TransTimeout, false))
            {
                string str = "Timeout: receive state=" + packetState;
                if (arxPacket != null)
                {
                    byte packetId = arxPacket.RxBuffer[0];
                    // packet body structure: byte[] { pid, count, ...data... }
                    string hdr = arxPacket.RxBufferP > 0 ? ("<" + pidToString(packetId) + ">") : "";
                    str += "  received so far: " + hdr + " RxBufferP=" + arxPacket.RxBufferP + " :";
                    for (int i = 1; i < arxPacket.RxBufferP && i < 20; i++)
                    {
                        str += " " + arxPacket.RxBuffer[i];
                    }
                }
                logError(str);

                ThrowException("Timeout - check GPS cable and baud rate");
            }
            lock (rxPacket)
            {
                packetIn.isGood = !rxPacket.RxBadPacket;
                packetIn.pid    = rxPacket.RxPacketId;
                packetIn.size   = (int)rxPacket.RxBufferP;
                packetIn.bytes  = new byte[packetIn.size];
                Array.Copy(rxPacket.RxBuffer, packetIn.bytes, packetIn.size);
            }
            rxPacket.Dispose();
            //log("Receive() - received good packet - pid=" + packetIn.pid);
        }
예제 #3
0
        // send, wait for response and return received packet:
        public GPacketReceived Transact(GPacket packet)
        {
            byte[]          bytes    = packet.toBytes();
            GPacketReceived packetIn = new GPacketReceived();

            m_physLayer.Transact(bytes, packetIn);
            return(packetIn);
        }
예제 #4
0
        public GarminProductType IdentifyDeviceType()
        {
            m_productType = null;               // make sure we can't have a stale product data instance,
            // and return null if no positive identification

            GPacketReceived received = Transact(new GPacketBasic(BasicPids.Pid_Product_Rqst));

            /* this works fine too:
             * SendPacketWaitAck(new GPacketBasic(BasicPids.Pid_Product_Rqst));
             * GPacketReceived received = ReceivePacket();
             */

            if (received.pid != (int)BasicPids.Pid_Product_Data)
            {
                throw new GpsException("GPS did not reply with product data - check GPS cable");
            }

            if (received.size < 5)
            {
                throw new GpsException("Product data packet is too small");
            }

            A000Product_Data_Type productData = (A000Product_Data_Type)received.fromBytes(0);

            m_productType = new GarminProductType();

            m_productType.product_ID       = productData.product_ID;
            m_productType.software_version = productData.software_version;
            m_productType.descriptions     = new string[productData.strings.Count];
            int i = 0;

            foreach (string s in productData.strings)
            {
                m_productType.descriptions[i++] = s;
                StatusBar.Trace(s);
            }

            // most models send also protocol capabilities (A001) data, wait for those to come.
            // this is what GPS V sends:
            //      P000 L001 A010 T001 A100 D109 A201 D202 D109 D210 A301 D310 D301
            //      A400 D109 A500 D501 A600 D600 A700 D700 A800 D800 A900 A902 A903 A904
            //
            // this is eTrex Vista response:
            //      P000 L001 A010 A100 D108 A201 D202 D108 D210 A301 D310 D301
            //      A500 D501 A600 D600 A700 D700 A800 D800 A900 A902 A903
            try
            {
                while (true)
                {
                    received = ReceivePacket();
                    int packetId = received.pid;
                    // packet body structure: byte[] { pid, count, ...data... }
                    string str = "<" + packetId + "> cnt=" + received.size + " :";
                    if (packetId == (int)BasicPids.Pid_Protocol_Array)
                    {
                        for (int ii = 0; ii < received.size; ii += 3)
                        {
                            int    iProt = received.bytes[ii + 1] + received.bytes[ii + 2] * 256;
                            string sProt = "" + ((char)received.bytes[ii]) + string.Format("{0:D3}", iProt);
                            str += " " + sProt;
                            m_productType.supported_protocols.Add(sProt);
                        }
                        StatusBar.Trace("IP: device ID=" + m_productType.product_ID + " " + m_productType.product_description + " Firmware " +
                                        m_productType.software_version + " received Protocol Capabilities data: " + str);
                        break;
                    }
                }
            }
            catch
            {
                // DEBUG:
                //m_productType.product_ID = 73;
                //m_productType.software_version = 200;

                m_productType.supported_protocols.Clear();

                StatusBar.Trace("FYI: legacy device ID=" + m_productType.product_ID + " Firmware " +
                                m_productType.software_version + " doesn't send Protocol Capabilities data");

                string legacyProtos = devices.tryUseLegacyDevice(m_productType.product_ID,
                                                                 m_productType.software_version, m_productType.supported_protocols);

                if (m_productType.supported_protocols.Count > 0)
                {
                    StatusBar.Trace("OK: reconstructed Protocol Capabilities data: " + legacyProtos);
                }
                else
                {
                    StatusBar.Error("unknown legacy device, couldn't reconstruct Protocol Capabilities data");
                }
            }

            if (m_productType.supports("A010") || m_productType.supports("A011"))
            {
                // make sure that whatever transfer has been going on is terminated:
                SendPacketWaitAck(new GPacketA010Commands(A010Commands.Cmnd_Abort_Transfer));
            }

            // prepare all protocols here, as making them on the fly may overrun serial connection:
            if (m_productType.supports("A100"))
            {
                log("FYI: supports A100 protocol for waypoints transfer");
                m_waypointTransferProtocol = new WaypointTransferProtocol(this);
            }

            if (m_productType.supports("A201"))
            {
                log("FYI: will use A201 protocol for transferring routes");
                m_routeTransferProtocol = new RouteTransferProtocol(this, "A201");
            }
            else
            {
                log("FYI: will use A200 protocol for transferring routes");
                m_routeTransferProtocol = new RouteTransferProtocol(this, "A200");
            }

            if (m_productType.supports("A301"))
            {
                log("FYI: will use A301 protocol for uploading tracks");
                m_trackLogTransferProtocol = new TrackLogTransferProtocol(this, "A301");
            }
            else
            {
                log("FYI: will use A300 protocol for uploading tracks");
                m_trackLogTransferProtocol = new TrackLogTransferProtocol(this, "A300");
            }

            // none of the legacy devices implement A800 protocol (PVT data transfer), so we need explicit indication.
            if (m_productType.supports("A800"))
            {
                log("FYI: will use A800 protocol for real time data");
                m_pvtTransferProtocol = new PvtTransferProtocol(this);
            }

            return(m_productType);
        }
        public void Transact(byte[] packetBodyOut, GPacketReceived packetIn)
        {
            //log("Transact --------------------------- started");
            int tries = 0;

            while (tries++ <= 3)
            {
                if (tries > 1)
                {
                    logError("Transact - try " + tries);
                }
                Send(packetBodyOut);
                TransFlag.Reset();
                if (!TransFlag.WaitOne((int)TransTimeout, false))
                {
                    logError("Transact - Timeout waiting for ACK");
                    if (tries == 3)
                    {
                        ThrowException("Timeout - check GPS cable and baud rate");
                    }
                    else
                    {
                        // just send the packet again
                        continue;
                    }
                }

                // analyze response, hopefully should be ACK (for our Send()):
                if (rxPacket.RxPacketId != (int)BasicPids.Pid_Nak_Byte)
                {
                    // if this is ACK, wait for the real packet to come.
                    // if not, assume we received the response packet
                    if (rxPacket.RxPacketId == (int)BasicPids.Pid_Ack_Byte)
                    {
                        //log("Transact - got ACK");
                        // receive actual response:
                        TransFlag.Reset();
                        if (!TransFlag.WaitOne((int)TransTimeout, false))
                        {
                            logError("Transact - Timeout");
                            if (tries == 3)
                            {
                                ThrowException("Timeout - check GPS cable and baud rate");
                            }
                            else
                            {
                                // just send the packet again
                                continue;
                            }
                        }
                    }
                    if (rxPacket.RxBadPacket)
                    {
                        logError("Transact - received bad packet - pid=" + rxPacket.RxPacketId);
                        continue;
                    }
                    else
                    {
                        //log("Transact - received good packet - pid=" + rxPacket.RxPacketId);
                        lock (rxPacket)
                        {
                            packetIn.isGood = !rxPacket.RxBadPacket;
                            packetIn.size   = (int)rxPacket.RxBufferP;
                            packetIn.pid    = rxPacket.RxPacketId;
                            packetIn.bytes  = new byte[packetIn.size];
                            Array.Copy(rxPacket.RxBuffer, packetIn.bytes, packetIn.size);
                        }
                        rxPacket.Dispose();
                        break;
                    }
                }
                else                 // NAK
                {
                    // just send the packet again
                    logError("Transact - got NAK for my packet (id=" + pidToString(packetBodyOut[0]) + ")");
                    continue;
                }

                /*
                 * else
                 * {
                 *      RxBufferP = 0;
                 *      logError("Transact - expected ACK for my packet (id=" + packetBodyOut[0] + ") -- came RxPacketId=" + RxPacketId);
                 *      // may be we missed ACK, instead next packet came.
                 * }
                 */
            }
            //log("Transact --------------------------- finished");
        }