bool EWDevice::TryConnect() { int retries=10; while (--retries){ port->Write("##\r\n"); // send IO Mode command if (port->ExpectString("IO Mode.\r")) return true; port->ExpectString("$$$"); // empty input buffer } return false; }
bool EWMicroRecorderDevice::Declare(const Declaration *decl) { // Must have at least two, max 12 waypoints if (decl->size() < 2 || decl->size() > 12) return false; port->StopRxThread(); port->SetRxTimeout(500); // set RX timeout to 500[ms] if (!TryConnect()) return false; port->Write('\x18'); // start to upload file port->Write(user_data); EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"), _T("Pilot Name:"), decl->PilotName); EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"), _T("Competition ID:"), decl->AircraftRego); EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"), _T("Aircraft Type:"), decl->AircraftType); port->Write("Description: Declaration\r\n"); for (unsigned i = 0; i < 11; i++) { if (i+1>= decl->size()) { EWMicroRecorderPrintf(port, _T("%-17s %s\r\n"), _T("TP LatLon:"), _T("0000000N00000000E TURN POINT\r\n")); } else { const Waypoint &wp = decl->waypoints[i]; if (i == 0) { EWMicroRecorderWriteWayPoint(port, wp, _T("Take Off LatLong:")); EWMicroRecorderWriteWayPoint(port, wp, _T("Start LatLon:")); } else if (i + 1 < decl->size()) { EWMicroRecorderWriteWayPoint(port, wp, _T("TP LatLon:")); } } } const Waypoint &wp = decl->waypoints[decl->size() - 1]; EWMicroRecorderWriteWayPoint(port, wp, _T("Finish LatLon:")); EWMicroRecorderWriteWayPoint(port, wp, _T("Land LatLon:")); port->Write('\x03'); // finish sending user file bool success = port->ExpectString("uploaded successfully"); port->Write("!!\r\n"); // go back to NMEA mode port->SetRxTimeout(0); // clear timeout port->StartRxThread(); // restart RX thread return success; }
bool AltairProDevice::PropertySetGet(Port *port, char *Buffer, size_t size) { assert(port != NULL); assert(Buffer != NULL); // eg $PDVSC,S,FOO,BAR*<cr>\r\n PortWriteNMEA(port, Buffer); Buffer[6] = _T('A'); char *comma = strchr(&Buffer[8], ','); if (comma != NULL){ comma[1] = '\0'; // expect eg $PDVSC,A,FOO, if (port->ExpectString(Buffer)){ // read value eg bar while(--size){ int ch = port->GetChar(); if (ch == -1) break; if (ch == '*'){ Buffer = '\0'; return true; } *Buffer++ = (char) ch; } } } *Buffer = '\0'; return false; }
static bool DeclareInner(Port &port, const Declaration &declaration, OperationEnvironment &env) { assert(declaration.Size() >= 2); assert(declaration.Size() <= 12); char user_data[2500]; if (!TryConnectRetry(port, user_data, sizeof(user_data), env)) return false; char *p = strstr(user_data, "USER DETAILS"); if (p != NULL) *p = 0; port.Write('\x18'); // start to upload file if (!port.FullWriteString(user_data, env, 5000) || !port.FullWriteString("USER DETAILS\r\n--------------\r\n\r\n", env, 1000)) return false; WritePair(port, "Pilot Name", declaration.pilot_name.c_str(), env); WritePair(port, "Competition ID", declaration.competition_id.c_str(), env); WritePair(port, "Aircraft Type", declaration.aircraft_type.c_str(), env); WritePair(port, "Aircraft ID", declaration.aircraft_registration.c_str(), env); if (!port.FullWriteString("\r\nFLIGHT DECLARATION\r\n-------------------\r\n\r\n", env, 1000)) return false; WritePair(port, "Description", _T("XCSoar task declaration"), env); for (unsigned i = 0; i < 11; i++) { if (env.IsCancelled()) return false; if (i+1>= declaration.Size()) { port.FullWriteString("TP LatLon: 0000000N00000000E TURN POINT\r\n", env, 1000); } else { const Waypoint &wp = declaration.GetWaypoint(i); if (i == 0) { if (!EWMicroRecorderWriteWaypoint(port, "Take Off LatLong", wp, env) || !EWMicroRecorderWriteWaypoint(port, "Start LatLon", wp, env)) return false; } else if (i + 1 < declaration.Size()) { if (!EWMicroRecorderWriteWaypoint(port, "TP LatLon", wp, env)) return false; } } } const Waypoint &wp = declaration.GetLastWaypoint(); if (!EWMicroRecorderWriteWaypoint(port, "Finish LatLon", wp, env) || !EWMicroRecorderWriteWaypoint(port, "Land LatLon", wp, env) || env.IsCancelled()) return false; port.Write('\x03'); // finish sending user file return port.ExpectString("uploaded successfully", env, 5000); }
bool EWDevice::AddWaypoint(const Waypoint &way_point) { char EWRecord[100]; TCHAR IDString[12]; int DegLat, DegLon; double tmp, MinLat, MinLon; char NoS, EoW; short EoW_Flag, NoS_Flag, EW_Flags; if (ewDecelTpIndex > 6){ // check for max 6 TP's return false; } CopyString(IDString, way_point.Name.c_str(), 7); // copy at most 6 chars while (_tcslen(IDString) < 6) // fill up with spaces _tcscat(IDString, _T(" ")); #if USESHORTTPNAME > 0 _tcscpy(&IDString[3], _T(" ")); // truncate to short name #endif // prepare lat tmp = way_point.Location.Latitude.value_degrees(); NoS = 'N'; if (tmp < 0) { NoS = 'S'; tmp = -tmp; } DegLat = (int)tmp; MinLat = (tmp - DegLat) * 60 * 1000; // prepare long tmp = way_point.Location.Longitude.value_degrees(); EoW = 'E'; if (tmp < 0) { EoW = 'W'; tmp = -tmp; } DegLon = (int)tmp; MinLon = (tmp - DegLon) * 60 * 1000; // Calc E/W and N/S flags // Clear flags EoW_Flag = 0; // prepare flags NoS_Flag = 0; EW_Flags = 0; if (EoW == 'W') { EoW_Flag = 0x08; } else { EoW_Flag = 0x04; } if (NoS == 'N') { NoS_Flag = 0x01; } else { NoS_Flag = 0x02; } // Do the calculation EW_Flags = (short)(EoW_Flag | NoS_Flag); // setup command string sprintf(EWRecord, "#STP%02X%02X%02X%02X%02X%02X%02X%02X%02X%04X%02X%04X", ewDecelTpIndex, IDString[0], IDString[1], IDString[2], IDString[3], IDString[4], IDString[5], EW_Flags, DegLat, (int)MinLat/10, DegLon, (int)MinLon/10); WriteWithChecksum(port, EWRecord); if (!port->ExpectString("OK\r")) // wait for response return false; ewDecelTpIndex = ewDecelTpIndex + 1; // increase TP index return true; }
bool EWDevice::DeclareInner(const struct Declaration &declaration, OperationEnvironment &env) { char sTmp[72]; ewDecelTpIndex = 0; if (!TryConnect()) return false; WriteWithChecksum(port, "#SPI"); // send SetPilotInfo env.Sleep(50); char sPilot[13], sGliderType[9], sGliderID[9]; convert_string(sPilot, sizeof(sPilot), declaration.PilotName); convert_string(sGliderType, sizeof(sGliderType), declaration.AircraftType); convert_string(sGliderID, sizeof(sGliderID), declaration.AircraftReg); // build string (field 4-5 are GPS info, no idea what to write) sprintf(sTmp, "%-12s%-8s%-8s%-12s%-12s%-6s\r", sPilot, sGliderType, sGliderID, "", // GPS Model "", // GPS Serial No. "" // Flight Date, // format unknown, // left blank (GPS // has a RTC) ); port->Write(sTmp); if (!port->ExpectString("OK\r")) return false; /* sprintf(sTmp, "#SUI%02d", 0); // send pilot name WriteWithChecksum(port, sTmp); env.Sleep(50); port->Write(PilotsName); port->Write('\r'); if (!port->ExpectString("OK\r")) return false; sprintf(sTmp, "#SUI%02d", 1); // send type of aircraft WriteWithChecksum(port, sTmp); env.Sleep(50); port->Write(Class); port->Write('\r'); if (!port->ExpectString("OK\r")) nDeclErrorCode = 1; sprintf(sTmp, "#SUI%02d", 2); // send aircraft ID WriteWithChecksum(port, sTmp); env.Sleep(50); port->Write(ID); port->Write('\r'); if (!port->ExpectString("OK\r")) return false; */ for (int i=0; i<6; i++){ // clear all 6 TP's sprintf(sTmp, "#CTP%02d", i); WriteWithChecksum(port, sTmp); if (!port->ExpectString("OK\r")) return false; } for (unsigned j = 0; j < declaration.size(); ++j) if (!AddWaypoint(declaration.get_waypoint(j))) return false; return true; }
static bool WaitUploadPrompt(Port &port, OperationEnvironment &env, unsigned timeout_ms=2000) { return port.ExpectString("up>", env, timeout_ms); }
static inline bool ExpectACK(Port &port) { return port.ExpectString(LX_ACK_STRING); }
static bool WaitUploadPrompt(Port &port, OperationEnvironment &env, std::chrono::steady_clock::duration timeout=std::chrono::seconds(2)) { return port.ExpectString("up>", env, timeout); }
static bool DeclareInner(Port &port, const Declaration &declaration, OperationEnvironment &env) { assert(declaration.size() >= 2); assert(declaration.size() <= 12); char user_data[2500]; if (!TryConnect(port, user_data) || env.IsCancelled()) return false; char *p = strstr(user_data, "USER DETAILS"); if (p != NULL) *p = 0; port.Write('\x18'); // start to upload file port.Write(user_data); port.Write("USER DETAILS\r\n--------------\r\n\r\n"); EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"), _T("Pilot Name:"), declaration.PilotName.c_str()); EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"), _T("Competition ID:"), declaration.CompetitionId.c_str()); EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"), _T("Aircraft Type:"), declaration.AircraftType.c_str()); EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"), _T("Aircraft ID:"), declaration.AircraftReg.c_str()); port.Write("\r\nFLIGHT DECLARATION\r\n-------------------\r\n\r\n"); EWMicroRecorderPrintf(port, _T("%-15s %s\r\n"), _T("Description:"), _T("XCSoar task declaration")); for (unsigned i = 0; i < 11; i++) { if (env.IsCancelled()) return false; if (i+1>= declaration.size()) { EWMicroRecorderPrintf(port, _T("%-17s %s\r\n"), _T("TP LatLon:"), _T("0000000N00000000E TURN POINT")); } else { const Waypoint &wp = declaration.get_waypoint(i); if (i == 0) { EWMicroRecorderWriteWaypoint(port, wp, _T("Take Off LatLong:")); EWMicroRecorderWriteWaypoint(port, wp, _T("Start LatLon:")); } else if (i + 1 < declaration.size()) { EWMicroRecorderWriteWaypoint(port, wp, _T("TP LatLon:")); } } } const Waypoint &wp = declaration.get_last_waypoint(); EWMicroRecorderWriteWaypoint(port, wp, _T("Finish LatLon:")); EWMicroRecorderWriteWaypoint(port, wp, _T("Land LatLon:")); if (env.IsCancelled()) return false; port.Write('\x03'); // finish sending user file return port.ExpectString("uploaded successfully"); }