/*! * \file gnss_sdr_supl_client.c * \brief class that implements a C++ interface to external Secure User Location Protocol (SUPL) client library. * \author Javier Arribas, 2013. jarribas(at)cttc.es * * TODO: put here supl.c author info * class that implements a C++ interface to external Secure User Location Protocol (SUPL) client library. * * ------------------------------------------------------------------------- * * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver * * This file is part of GNSS-SDR. * * GNSS-SDR is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * at your option) any later version. * * GNSS-SDR is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- */ #include "gnss_sdr_supl_client.h" #include gnss_sdr_supl_client::gnss_sdr_supl_client() {} gnss_sdr_supl_client::~gnss_sdr_supl_client() {} void gnss_sdr_supl_client::print_assistance() { if (assist.set & SUPL_RRLP_ASSIST_REFTIME) { fprintf(stdout, "T %ld %ld %ld %ld\n", assist.time.gps_week, assist.time.gps_tow, assist.time.stamp.tv_sec, assist.time.stamp.tv_usec); } if (assist.set & SUPL_RRLP_ASSIST_UTC) { fprintf(stdout, "U %d %d %d %d %d %d %d %d\n", assist.utc.a0, assist.utc.a1, assist.utc.delta_tls, assist.utc.tot, assist.utc.wnt, assist.utc.wnlsf, assist.utc.dn, assist.utc.delta_tlsf); } if (assist.set & SUPL_RRLP_ASSIST_REFLOC) { fprintf(stdout, "L %f %f %d\n", assist.pos.lat, assist.pos.lon, assist.pos.uncertainty); } if (assist.set & SUPL_RRLP_ASSIST_IONO) { fprintf(stdout, "I %d %d %d %d %d %d %d %d\n", assist.iono.a0, assist.iono.a1, assist.iono.a2, assist.iono.a3, assist.iono.b0, assist.iono.b1, assist.iono.b2, assist.iono.b3); } if (assist.cnt_eph) { int i; fprintf(stdout, "E %d\n", assist.cnt_eph); for (i = 0; i < assist.cnt_eph; i++) { struct supl_ephemeris_s *e = &assist.eph[i]; fprintf(stdout, "e %d %d %d %d %d %d %d %d %d %d", e->prn, e->delta_n, e->M0, e->A_sqrt, e->OMEGA_0, e->i0, e->w, e->OMEGA_dot, e->i_dot, e->e); fprintf(stdout, " %d %d %d %d %d %d", e->Cuc, e->Cus, e->Crc, e->Crs, e->Cic, e->Cis); fprintf(stdout, " %d %d %d %d %d %d", e->toe, e->IODC, e->toc, e->AF0, e->AF1, e->AF2); fprintf(stdout, " %d %d %d %d %d\n", e->bits, e->ura, e->health, e->tgd, e->AODA); } } if (assist.cnt_alm) { int i; fprintf(stdout, "A %d\n", assist.cnt_alm); for (i = 0; i < assist.cnt_alm; i++) { struct supl_almanac_s *a = &assist.alm[i]; fprintf(stdout, "a %d %d %d %d %d ", a->prn, a->e, a->toa, a->Ksii, a->OMEGA_dot); fprintf(stdout, "%d %d %d %d %d %d\n", a->A_sqrt, a->OMEGA_0, a->w, a->M0, a->AF0, a->AF1); } } if (assist.cnt_acq) { int i; fprintf(stdout, "Q %d %d\n", assist.cnt_acq, assist.acq_time); for (i = 0; i < assist.cnt_acq; i++) { struct supl_acquis_s *q = &assist.acq[i]; fprintf(stdout, "q %d %d %d ", q->prn, q->parts, q->doppler0); if (q->parts & SUPL_ACQUIS_DOPPLER) { fprintf(stdout, "%d %d ", q->doppler1, q->d_win); } else { fprintf(stdout, "0 0 "); } fprintf(stdout, "%d %d %d %d ", q->code_ph, q->code_ph_int, q->bit_num, q->code_ph_win); if (q->parts & SUPL_ACQUIS_ANGLE) { fprintf(stdout, "%d %d\n", q->az, q->el); } else { fprintf(stdout, "0 0\n"); } } } } int gnss_sdr_supl_client::get_assistance(int i_mcc, int i_mns, int i_lac, int i_ci) { // SET SUPL CLIENT INFORMATION // GSM CELL PARAMETERS mcc = i_mcc; mns = i_mns; lac = i_lac; ci = i_ci; supl_set_gsm_cell(&ctx, mcc, mns, lac, ci); // PERFORM SUPL COMMUNICATION char *cstr = new char[server_name.length() + 1]; strcpy(cstr, server_name.c_str()); int err; ctx.p.request = request; // select assistance info request from a pre-defined set //std::cout<<"mcc="<::iterator gps_almanac_iterator; for (int i = 0; i < assist.cnt_alm; i++) { struct supl_almanac_s *a = &assist.alm[i]; // Check if the SV is present in the map gps_almanac_iterator = this->gps_almanac_map.find(a->prn); // the SV is not present in the almanac data -> insert new SV register if (gps_almanac_iterator==gps_almanac_map.end()) { Gps_Almanac gps_almanac_entry; gps_almanac_map.insert(std::pair(a->prn, gps_almanac_entry)); gps_almanac_iterator = this->gps_almanac_map.find(a->prn); } gps_almanac_iterator->second.i_satellite_PRN = a->prn; gps_almanac_iterator->second.d_A_f0 = ((double)a->AF0)*pow(2.0, -20); gps_almanac_iterator->second.d_A_f1 = ((double)a->AF1)*pow(2.0, -38); gps_almanac_iterator->second.d_Delta_i = ((double)a->Ksii)*pow(2.0, -19); gps_almanac_iterator->second.d_OMEGA = ((double)a->w)*pow(2.0, -23); gps_almanac_iterator->second.d_OMEGA0 = ((double)a->OMEGA_0)*pow(2.0, -23); gps_almanac_iterator->second.d_sqrt_A = ((double)a->A_sqrt)*pow(2.0, -11); gps_almanac_iterator->second.d_OMEGA_DOT = ((double)a->OMEGA_dot)*pow(2.0, -38); gps_almanac_iterator->second.d_Toa = ((double)a->toa)*pow(2.0, 12); gps_almanac_iterator->second.d_e_eccentricity = ((double)a->toa)*pow(2.0, -21); gps_almanac_iterator->second.d_M_0 = ((double)a->M0)*pow(2.0, -23); } } // READ SV EPHEMERIS if (assist.cnt_eph) { std::map::iterator gps_eph_iterator; for (int i = 0; i < assist.cnt_eph; i++) { struct supl_ephemeris_s *e = &assist.eph[i]; // Check if the SV is present in the map gps_eph_iterator = this->gps_ephemeris_map.find(e->prn); // the SV is not present in the assistance data -> insert new SV register if (gps_eph_iterator == gps_ephemeris_map.end()) { Gps_Ephemeris gps_eph; gps_ephemeris_map.insert(std::pair(e->prn, gps_eph)); gps_eph_iterator = this->gps_ephemeris_map.find(e->prn); } if (gps_time.valid) { gps_eph_iterator->second.i_GPS_week = assist.time.gps_week; /* TS 44.031: GPSTOW, range 0-604799.92, resolution 0.08 sec, 23-bit presentation */ gps_eph_iterator->second.d_TOW = ((double)assist.time.gps_tow)*0.08; } else { gps_eph_iterator->second.i_GPS_week = 0; gps_eph_iterator->second.d_TOW = 0; } gps_eph_iterator->second.i_satellite_PRN = e->prn; // SV navigation model gps_eph_iterator->second.i_code_on_L2 = e->bits; gps_eph_iterator->second.i_SV_accuracy = e->ura; //User Range Accuracy (URA) gps_eph_iterator->second.i_SV_health = e->health; gps_eph_iterator->second.d_IODC = (double)e->IODC; //miss P flag (1 bit) //miss SF1 Reserved (87 bits) gps_eph_iterator->second.d_TGD = ((double)e->tgd)*T_GD_LSB; gps_eph_iterator->second.d_Toc = ((double)e->toc)*T_OC_LSB; gps_eph_iterator->second.d_A_f0 = ((double)e->AF0)*A_F0_LSB; gps_eph_iterator->second.d_A_f1 = ((double)e->AF1)*A_F1_LSB; gps_eph_iterator->second.d_A_f2 = ((double)e->AF2)*A_F2_LSB; gps_eph_iterator->second.d_Crc = ((double)e->Crc)*C_RC_LSB; gps_eph_iterator->second.d_Delta_n = ((double)e->delta_n)*DELTA_N_LSB; gps_eph_iterator->second.d_M_0 = ((double)e->M0)*M_0_LSB; gps_eph_iterator->second.d_Cuc = ((double)e->Cuc)*C_UC_LSB; gps_eph_iterator->second.d_e_eccentricity = ((double)e->e)*E_LSB; gps_eph_iterator->second.d_Cus = ((double)e->Cus)*C_US_LSB; gps_eph_iterator->second.d_sqrt_A = ((double)e->A_sqrt)*SQRT_A_LSB; gps_eph_iterator->second.d_Toe = ((double)e->toe)*T_OE_LSB; //miss fit interval flag (1 bit) gps_eph_iterator->second.i_AODO = e->AODA * AODO_LSB; gps_eph_iterator->second.d_Cic = ((double)e->Cic)*C_IC_LSB; gps_eph_iterator->second.d_OMEGA0 = ((double)e->OMEGA_0)*OMEGA_0_LSB; gps_eph_iterator->second.d_Cis = ((double)e->Cis)*C_IS_LSB; gps_eph_iterator->second.d_i_0 = ((double)e->i0)*I_0_LSB; gps_eph_iterator->second.d_Crs = ((double)e->Crs)*C_RS_LSB; gps_eph_iterator->second.d_OMEGA = ((double)e->w)*OMEGA_LSB; gps_eph_iterator->second.d_OMEGA_DOT = (double)e->OMEGA_dot*OMEGA_DOT_LSB; gps_eph_iterator->second.d_IDOT = ((double)e->i_dot)*I_DOT_LSB; } } // READ SV ACQUISITION ASSISTANCE if (assist.cnt_acq) { std::map::iterator gps_acq_iterator; for (int i = 0; i < assist.cnt_acq; i++) { struct supl_acquis_s *e = &assist.acq[i]; // Check if the SV is present in the map gps_acq_iterator=this->gps_acq_map.find(e->prn); // the SV is not present in the assistance data -> insert new SV register if (gps_acq_iterator == gps_acq_map.end()) { Gps_Acq_Assist gps_acq_assist; gps_acq_map.insert(std::pair(e->prn, gps_acq_assist)); gps_acq_iterator = this->gps_acq_map.find(e->prn); } // fill the acquisition assistance structure gps_acq_iterator->second.i_satellite_PRN = e->prn; gps_acq_iterator->second.d_TOW = (double)assist.acq_time; gps_acq_iterator->second.d_Doppler0 = (double)e->doppler0; gps_acq_iterator->second.d_Doppler1 = (double)e->doppler1; gps_acq_iterator->second.dopplerUncertainty = (double)e->d_win; gps_acq_iterator->second.Code_Phase = (double)e->code_ph; gps_acq_iterator->second.Code_Phase_int = (double)e->code_ph_int; gps_acq_iterator->second.Code_Phase_window = (double)e->code_ph_win; gps_acq_iterator->second.Azimuth = (double)e->az; gps_acq_iterator->second.Elevation = (double)e->el; gps_acq_iterator->second.GPS_Bit_Number = (double)e->bit_num; } } } bool gnss_sdr_supl_client::load_ephemeris_xml(const std::string file_name) { try { std::ifstream ifs(file_name.c_str(), std::ifstream::binary | std::ifstream::in); boost::archive::xml_iarchive xml(ifs); gps_ephemeris_map.clear(); xml >> boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", gps_ephemeris_map); ifs.close(); } catch (std::exception& e) { LOG_AT_LEVEL(ERROR) << e.what() << "File: " << file_name; return false; } return true; } bool gnss_sdr_supl_client::save_ephemeris_xml(const std::string file_name) { try { std::ofstream ofs(file_name.c_str(), std::ofstream::trunc | std::ofstream::out); boost::archive::xml_oarchive xml(ofs); xml << boost::serialization::make_nvp("GNSS-SDR_ephemeris_map", gps_ephemeris_map); ofs.close(); } catch (std::exception& e) { LOG_AT_LEVEL(ERROR) << e.what(); return false; } return true; }