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