s_sim: Fix multiple sim facility status query
[platform/core/telephony/tel-plugin-imc.git] / src / s_gps.c
1 /*
2  * tel-plugin-imc
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: sharanayya mathapati <sharan.m@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <glib.h>
29
30 #include <tcore.h>
31 #include <hal.h>
32 #include <core_object.h>
33 #include <plugin.h>
34 #include <queue.h>
35 #include <co_gps.h>
36 #include <user_request.h>
37 #include <util.h>
38 #include <server.h>
39 #include <at.h>
40 #include <libxml/xmlreader.h>
41 #include <libxml/parser.h>
42 #include <libxml/tree.h>
43
44 #include "s_common.h"
45 #include "s_gps.h"
46
47
48 #define FILE_NAME   "/opt/home/root/sample.xml"
49 #define POSITION_NODE   "pos"
50 #define POSITION_NODE_ATTR_XSI  "xsi:noNamespaceSchemaLocation"
51 #define POSITION_NODE_ATTR_VAL_XSI  "pos.xsd"
52 #define POSITION_NODE_ATTR_XMLNS    "xmlns:xsi"
53 #define POSITION_NODE_ATTR_VAL_XMLNS    "http://www.w3.org/2001/XMLSchema-instance"
54
55 #define MAX_NUM_OF_GPS_REF_TIME_ELEMENT 12 // max number of gps satalite
56 #define MAX_NUM_OF_GPS_NAV_ELEMENT  16 // max num of navigation gps element.
57 #define MAX_NUM_OF_GPS_ALMANC_ELEMENTS  64 // Max num of almanc elements.
58
59 #define NUM_OF_ELEMENTS(array)  (sizeof(array) / sizeof(*(array)))
60
61 static char node_name[128]; // max len of xml node
62 static char node_value[128]; // max len of xml node value.
63
64 // node type of gps assist data
65 enum gps_assist_element_type {
66         REF_TIME = 1,
67         LOCATION_PARM,
68         DGPS_CORRECTION,
69         NAV_MODEL_ELEM,
70         IONOSPHERIC_MODEL,
71         UTC_MODEL,
72         ALMANAC,
73         ACQU_ASSIST,
74 };
75
76 // Ref_time
77 typedef struct {
78         unsigned char valid;
79         unsigned short bcchCarrier;
80         unsigned short bsic;
81         unsigned long int frameNumber;
82         unsigned short timeSlot;
83         unsigned short bitNumber;
84 } __attribute__((packed)) gps_gsm_time_t;
85
86 typedef struct {
87         unsigned char valid;
88         unsigned long int gpsTimeUncertainty;
89 } __attribute__((packed)) gps_utran_gps_unc_t;
90
91 typedef struct {
92         unsigned char valid;
93         signed long int driftRate;
94 } __attribute__((packed)) gps_drift_rate_t;
95
96 typedef struct {
97         unsigned char valid;
98         unsigned long int cellFrames;
99         unsigned char choice_mode;
100         unsigned long int UtranFdd; // FDD Primary Scrambling Code
101         unsigned long int UtranTdd; // TDD Cell Parameter ID
102         unsigned long int sfn; // SFN
103 } __attribute__((packed)) gps_utran_gps_ref_time_t;
104
105 typedef struct {
106         gps_utran_gps_ref_time_t UtranGpsRefTime;
107         gps_utran_gps_unc_t UtranGpsUncertainty;
108         unsigned char UtranSfnUncertainty;
109         gps_drift_rate_t UtranDriftRate;
110 } __attribute__((packed)) gps_utran_time_t;
111
112 typedef struct {
113         unsigned short satID;
114         unsigned short tlmWord;
115         unsigned char antiSpoofFlag;
116         unsigned char alertFlag;
117         unsigned char tmlReservedBits;
118 } __attribute__((packed)) gps_gps_tow_assist_t;
119
120 typedef struct {
121         unsigned long int gpsTow;
122         unsigned long int gpsWeek;
123         unsigned char nrOfSats;
124         union {                     // Not supported.
125                 gps_gsm_time_t gsm_time;
126                 gps_utran_time_t UtranTime;
127         } networkTimeInfo;
128         gps_gps_tow_assist_t GpsTowAssist[12];
129 } __attribute__((packed)) gps_ref_time_t;
130
131
132 // Ref - Location.
133 typedef struct {
134         unsigned char shapeType;
135         unsigned char hemisphere;
136         unsigned short altitude;
137         unsigned long int latitude;
138         signed long int longitude;
139         unsigned char directionOfAlt;
140         unsigned char semiMajorUncert;
141         unsigned char semiMinorUncert;
142         unsigned char majorAxis;
143         unsigned char altUncert;
144         unsigned char confidence;
145 } __attribute__((packed)) gps_ref_loc_t;
146
147 // DGPS corrections
148 typedef enum {
149         GPS_DGPS_INVALID,
150         GPS_DGPS_UDRE_SCALE_1_0,
151         GPS_DGPS_UDRE_SCALE_0_75,
152         GPS_DGPS_UDRE_SCALE_0_5,
153         GPS_DGPS_UDRE_SCALE_0_3,
154         GPS_DGPS_UDRE_SCALE_0_2,
155         GPS_DGPS_UDRE_SCALE_0_1,
156         GPS_DGPS_NO_DATA
157 } __attribute__((packed)) gps_dgps_status_e_type;
158
159 typedef struct {
160         unsigned char satId; // Satellite ID
161         unsigned short iode;
162         unsigned char udre;
163         signed short pseudoRangeCor;
164         signed short rangeRateCor;
165 } gps_dgps_sat_list_t;
166
167 typedef struct {
168         unsigned long int gpsTow;
169         gps_dgps_status_e_type status;
170         unsigned long int numberOfSat;
171         gps_dgps_sat_list_t seqOfSatElement[16];
172 } __attribute__((packed)) gps_dgps_correction_t;
173
174 // Navi model
175 typedef struct {
176         unsigned long int rsv1; // 0~838860
177         unsigned long int rsv2; // 0~16777215
178         unsigned long int rsv3; // 0~16777215
179         unsigned long int rsv4; // 0~65535
180 } __attribute__((packed)) gps_navi_subframe_rsv_t;
181
182 typedef struct {
183         unsigned char ephemCodeOnL2;                   // 0~3
184         unsigned char ephemUra;                   // 0~15
185         unsigned char ephemSvHealth;                   // 0~63
186         unsigned short ephemIodc;              // 0~1023
187         unsigned char ephemL2PFlag;                   // 0~1
188         gps_navi_subframe_rsv_t NavigationSubFrameRsv;
189         signed char ephemTgd;                 // -128~127
190         unsigned short ephemToc;              // 0~37799
191         signed char ephemAf2;                 // -128~12
192         signed short ephemAf1;                    // -32768~32767
193         signed long int ephemAf0;                 // -2097152~2097151
194         signed short ephemCrs;                    // -32768~32767
195         signed short ephemDeltaN;                    // -32768~32767
196         signed long int ephemM0;                 // -2147483648~2147483647
197         signed short ephemCuc;                    // -32768~32767
198         unsigned long int ephemE;               // 0~4294967295
199         signed short ephemCus;                    // -32768~32767
200         unsigned long int ephemAPowrHalf;               // 0~4294967295
201         unsigned short ephemToe;              // 0~37799
202         signed char ephemFitFlag;                 // 0~1
203         unsigned char ephemAoda;                   // 0~31
204         signed short ephemCic;                    // -32768~32767
205         signed long int ephemOmegaA0;                 // -2147483648~2147483647
206         signed short ephemCis;                    // -32768~32767
207         signed long int ephemI0;                 // -2147483648~2147483647
208         signed short ephemCrc;                    // -32768~32767
209         signed long int ephemW;                 // -2147483648~2147483647
210         signed long int ephemOmegaADot;                 // -8388608~8388607
211         signed short ephemIDot;                    // -8192~8191
212 } __attribute__((packed)) gps_navi_ephe_t;
213
214 typedef enum {
215         GPS_NAVIGATION_MODEL_NEW_SATELLITE_NEW_NAVIGATION,
216         GPS_NAVIGATION_MODEL_EXIST_SATELLITE_EXIST_NAVIGATION,
217         GPS_NAVIGATION_MODEL_EXIST_SATELLITE_NEW_NAVIGATION,
218         GPS_NAVIGATION_MODEL_RESERVED
219 } gps_navigation_sat_status_e_type;
220
221 typedef struct {
222         unsigned char satId;
223         gps_navigation_sat_status_e_type NavigationSatStatus;
224         gps_navi_ephe_t NavigationEphemeris;
225 } __attribute__((packed)) gps_navi_sat_info_t;
226
227 typedef struct {
228         unsigned long int numberOfSat;
229         gps_navi_sat_info_t NavigationSatInfo[16];
230 } __attribute__((packed)) gps_navi_model_t;
231
232 // Iono_model
233 typedef struct {
234         signed char alfa0; // -128~127
235         signed char alfa1; // -128~127
236         signed char alfa2; // -128~127
237         signed char alfa3; // -128~127
238         signed char beta0; // -128~127
239         signed char beta1; // -128~127
240         signed char beta2; // -128~127
241         signed char beta3; // -128~127
242 } __attribute__((packed)) gps_iono_model_t;
243
244 // UTC_model
245 typedef struct {
246         signed long int utcA1; // -8388608~8388607
247         signed long int utcA0; // -2147483648~2147483647
248         unsigned char utcTot; // 0~255
249         unsigned char utcWNt; // 0~255
250         signed char utcDeltaTls; // -128~127
251         unsigned char utcWNlsf; // 0~255
252         signed char utcDN; // -128~127
253         signed char utcDeltaTlsf; // -128~127
254 } __attribute__((packed)) gps_utc_model_t;
255
256 // Almanac-model
257 typedef struct {
258         signed char dataId; // only for 3G, 0~3, if this value is -1, it means this value is invalid
259         unsigned char satId;
260         unsigned short almanacE; // 0~65536
261         unsigned char almanacToa;   // 0~255
262         signed short almanacKsii;    // -32768~3276
263         signed short almanacOmegaDot;    // -32768~3276
264         unsigned char almanacSvHealth;   // 0~255
265         unsigned long int almanacAPowerHalf; // 0~16777215
266         signed long int almanacOmega0; // -8388608~8388607
267         signed long int almanacW; // -8388608~8388607
268         signed long int almanacM0; // -8388608~8388607
269         signed short almanacAf0;    // -1024~1023
270         signed short almanacAf1;    // -1024~1023
271 } __attribute__((packed)) gps_almanac_sat_info_t;
272
273 typedef struct {
274         unsigned char almanacWNa; // 0~255
275         unsigned long int numberOfSat;
276         gps_almanac_sat_info_t AlmanacSatInfo[64];
277 } __attribute__((packed)) gps_almanac_model_t;
278
279 // acq_assist
280 typedef struct {
281         unsigned char satId;
282         signed short doppler0; // -2048~2047 (real value is from -5120 to 5117.5 by step of 2.5)
283         unsigned char doppler1; // 0~63 (real value is from -0.966 to 0.483 by step of 0.023)
284         unsigned char dopplerUncertainty; // 0~7 (12.5, 25, 50, 100, 200)
285         unsigned short codePhase; // 0~1022
286         unsigned char intCodePhase; // 0~19
287         unsigned char gpsBitNumber; // 0~3
288         unsigned char codePhaseSearchWindow; // 0~15 (1023, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192)
289         unsigned char azimuth; // 0~31, 11.25 degree resolution
290         unsigned char elevation; // 0~7, 11.25 degree resolution
291 } __attribute__((packed)) gps_acq_sat_info_t;
292
293 typedef struct {
294         gps_utran_gps_ref_time_t AcqUtranGpsRefTime;
295         gps_utran_gps_unc_t AcqUtranGpsUncertainty;
296 } __attribute__((packed)) gps_acq_utran_time_t;
297
298 typedef struct {
299         unsigned long int gpsTow;
300         union   {
301                 gps_gsm_time_t gsm_time;
302                 gps_acq_utran_time_t AcqUtranTime;
303         } acquisitionTimeInfo;                      // --- not supported.
304         unsigned long int numberOfSat;
305         gps_acq_sat_info_t lcsAcquisitionSatInfo[16];
306 } __attribute__((packed)) gps_acq_assist_t;
307
308 typedef struct {
309         unsigned char satId[16];
310         unsigned char numOfSat;
311 } __attribute__((packed)) gps_r_time_int_t;
312
313
314 // Assist-data
315 typedef struct {
316         unsigned long int flag;
317         gps_ref_time_t ref_time;
318         gps_ref_loc_t ref_loc;
319         gps_dgps_correction_t dgps_corrections;
320         gps_navi_model_t navi_model;
321         gps_iono_model_t iono_model;
322         gps_utc_model_t utc_model;
323         gps_almanac_model_t almanac;
324         gps_acq_assist_t acq_assist;
325         gps_r_time_int_t r_time_int; // not supported
326 } __attribute__((packed)) gps_assist_data_noti_t; // APGPS -  GPS Assist Data Message - Notification
327
328 typedef struct {
329         char *psat_status;
330         int stat_status;
331 } __attribute__((packed)) sat_status_info_t;
332
333 const sat_status_info_t sat_status_info_table[] = {
334         { "NS_NN-U", 0}, {"NS_NN", 0}, {"ES_NN-U", 1}, {"ES_SN", 2},
335         { "REVD", 3},
336 };
337
338 typedef struct {
339         char *pdoppler_status;
340         int doppler_status;
341 } __attribute__((packed)) doppler_status_info_t;
342
343 const doppler_status_info_t doppler_status_info_table[] = {
344         { "hz12-5", 12.5}, {"hz25", 25}, {"hz50", 50}, {"hz100", 100},
345         {"hz200", 200},
346 };
347
348 // postion measurement data structure.
349 // gps_method_e_type
350 typedef enum {
351         GPS_METHODTYPE_INVALID,
352         GPS_METHODTYPE_MS_ASSISTED,
353         GPS_METHODTYPE_MS_BASED,
354         GPS_METHODTYPE_MS_BASED_PREF,
355         GPS_METHODTYPE_MS_ASSISTED_PREF
356 } gps_method_e_type;
357
358 // gps_accuracy_t
359 typedef struct {
360         unsigned int flag;
361         unsigned char horizontalAccuracy;
362         unsigned char vertcalAccuracy;
363 } __attribute__((packed)) gps_accuracy_t;
364
365 // gps_use_multi_sets_e_type
366 typedef enum {
367         GPS_MULTIPLESETS_INVALID,
368         GPS_MULTIPLESETS_MULTIPLESETS,
369         GPS_MULTIPLESETS_ONESET
370 } gps_use_multi_sets_e_type;
371
372 // gps_env_char_e_type
373 typedef enum {
374         GPS_ENVIRONMENT_INVALID,
375         GPS_ENVIRONMENT_BAD_AREA,
376         GPS_ENVIRONMENT_NOT_BAD_AREA,
377         GPS_ENVIRONMENT_MIXED_AREA
378 } gps_env_char_e_type;
379
380 // gps_cell_timing_wnt_e_type
381 typedef enum {
382         GPS_CELLTIMING_INVALID,
383         GPS_CELLTIMING_WANTED,
384         GPS_CELLTIMING_NOT_WANTED
385 } gps_cell_timing_wnt_e_type;
386
387 // gps_add_assit_req_e_type
388 typedef enum {
389         GPS_ADDITIONAL_ASSISREQ_INVALID,
390         GPS_ADDITIONAL_ASSISREQ_REQ,
391         GPS_ADDITIONAL_ASSISREQ_NOT_REQ
392 } gps_add_assit_req_e_type;
393
394 // gps measure position.
395 typedef struct {
396         gps_method_e_type method_type;
397         gps_accuracy_t accuracy;
398         unsigned char rsp_time;
399         gps_use_multi_sets_e_type use_multi_sets;
400         gps_env_char_e_type environment_char;
401         gps_cell_timing_wnt_e_type cell_timing_wnt;
402         gps_add_assit_req_e_type add_assist_req;
403 } __attribute__((packed)) gps_measure_position_indi_t;
404
405
406 // APGPS - Measure Position message - confirm
407 typedef enum {
408         GPS_MSR_POS_RES_LOCATION,
409         GPS_MSR_POS_RES_GPS_MEASUREMENTS,
410         GPS_MSR_POS_RES_AID_REQ,
411         GPS_MSR_POS_RES_ERROR
412 } gps_msr_pos_res_e_type;
413
414 typedef struct {
415         unsigned char sat_id;
416         unsigned char iode;
417 } __attribute__((packed)) gps_sat_info_t;
418
419 typedef struct {
420         unsigned char beginWeek;
421         unsigned char endWeek;
422         unsigned char beginTow;
423         unsigned char endTow;
424 } __attribute__((packed)) gps_ext_ephe_chk_t;
425
426 typedef struct {
427         unsigned long int assistanceFlag;
428         unsigned short gpsWeek;
429         unsigned char gpsToe;
430         unsigned char nSat;
431         unsigned char toeLimit;
432         gps_sat_info_t satInfo[15];
433         unsigned char gpsExtendedEphemeris;
434         gps_ext_ephe_chk_t extEphemerisChk;
435 } __attribute__((packed)) gps_assistance_data_t;
436
437 // Measure Position message
438 typedef struct {
439         unsigned char satId; // Satellite ID
440         unsigned char cno; // 0~63, unit of dB-Hz
441         signed short doppler; // -32768~32767, Hz and scale factor 0.2
442         unsigned short wholeChips; // 0~1022
443         unsigned short fracChips; // 0~1024
444         unsigned char lcsMultiPath;
445         unsigned char pseuRangeRmsErr; // 0~63
446 } __attribute__((packed)) gps_measuremet_element_t;
447
448 typedef struct {
449         unsigned long int gpsTow; // /< GPS time of week [msec]
450         unsigned short gpsWeek; // /< GPS week [0 .. 1023]
451         unsigned char nrOfSats; // /< number of satellites [1 .. 16]
452         gps_measuremet_element_t GpsMeasure[16];
453 } __attribute__((packed)) gps_measure_t;
454
455 typedef struct {
456         signed long int latitude;
457         signed long int longitude;
458 } __attribute__((packed)) gps_ellipsoid_po_t;
459
460 typedef struct {
461         gps_ellipsoid_po_t point;
462         unsigned char uncertainRadius;
463 } __attribute__((packed)) gps_po_unc_circle_t;
464
465 typedef struct {
466         gps_ellipsoid_po_t point;
467         unsigned char semiMajorAxis;
468         unsigned char semiMinorAxis;
469         unsigned char orientationAngle;
470         unsigned char confidence;
471 } __attribute__((packed)) gps_po_unc_ellipse_t;
472
473 typedef struct {
474         gps_ellipsoid_po_t point;
475         signed short altitude;
476         unsigned char semiMajorAxis;
477         unsigned char semiMinorAxis;
478         unsigned char orientationAngle;
479         unsigned char uncertainAltitude;
480         unsigned char confidence;
481 } __attribute__((packed)) gps_po_alt_unc_ellipse_t;
482
483 typedef struct {
484         gps_ellipsoid_po_t point;
485         unsigned short innerRadius;
486         unsigned char uncertainRadius;
487         unsigned char offsetAngle;
488         unsigned char includedAngle;
489         unsigned char confidence;
490 } __attribute__((packed)) gps_ellipsoid_arc_t;
491
492 typedef struct {
493         gps_ellipsoid_po_t point;
494         signed short altitude;
495 } __attribute__((packed)) gps_ellipsoid_alt_t;
496
497 typedef struct {
498         unsigned char noOfPoints;
499         gps_ellipsoid_po_t points[15];
500 } __attribute__((packed)) gps_polygon_t;
501
502
503 typedef struct {
504         unsigned char shape_type;
505         gps_po_unc_circle_t p_unc_clrcle;
506         gps_po_unc_ellipse_t p_unc_ellipse;
507         gps_po_alt_unc_ellipse_t p_alt_unc_ellipse;
508         gps_ellipsoid_arc_t ellipsoid_arc;
509         gps_ellipsoid_po_t ellipsoid_po;
510         gps_ellipsoid_alt_t ellipsoid_alt;
511         gps_polygon_t polygon;
512 } __attribute__((packed)) gps_loc_info_t;
513
514
515 typedef struct {
516         unsigned long int gpsTow; // /< GPS time of week [msec]
517         unsigned short gpsWeek; // /< GPS week [0 .. 1023]
518         unsigned char fixType; // /< Fix type. 2D(0x01) or 3D(0x02)
519         gps_loc_info_t measured_loc_info;
520 } __attribute__((packed)) gps_measure_loc_info_t;
521
522 typedef struct {
523         unsigned char valid;
524         unsigned long int cellFrames;
525         unsigned char choice_mode;
526         unsigned long int UtranFdd; // FDD Primary Scrambling Code
527         unsigned long int UtranTdd; // TDD Cell Parameter ID
528         unsigned long int sfn; // SFN
529 } __attribute__((packed)) gps_utrangps_ref_time_t;
530
531 typedef struct {
532         unsigned char result; // 0x00 : SUCCESS, 0x01 : Fail
533         gps_msr_pos_res_e_type response_type; // should be 4 byte
534         gps_measure_t gps_measure;
535         gps_measure_loc_info_t loc_info;
536         gps_assistance_data_t measured_assit_data;
537         gps_utrangps_ref_time_t UtranGpsRefTime; // only for 3G
538 } __attribute__((packed)) gps_measure_position_confirm_t; // APGPS - Measure Position message - confirm
539
540 typedef struct {
541         char *name;
542         int type;
543 } t_element;
544
545 static t_element elements[] = {
546         {"ref_time", REF_TIME},
547         {"location_parameters", LOCATION_PARM},
548         {"DGPS_corrections", DGPS_CORRECTION},
549         {"nav_model_elem", NAV_MODEL_ELEM},
550         {"ionospheric_model", IONOSPHERIC_MODEL},
551         {"UTC_model", UTC_MODEL},
552         {"almanac", ALMANAC},
553         {"acqu_assist", ACQU_ASSIST},
554 };
555
556
557 /**************************************************************************
558 *                                                       Local Function Prototypes
559 **************************************************************************/
560
561 static inline int _modem_sat_status_info_2_tel_sat_info(char *sat_info);
562
563 static inline int _modem_acqa_assit_doppler_2_tel_doppler(char *doppler_info);
564
565 static int _gps_element_compare(char *element[], char *element_str, int nelem);
566
567 static enum gps_assist_element_type _get_element_type(char *element_str);
568
569 static void _parse_ref_time_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist, gboolean GPS_TOW_assist, int count);
570
571 static void _parse_location_parameters(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist);
572
573 static void _parse_dgps_correction_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist);
574
575 static void _parse_ionospheric_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist);
576
577 static void _parse_utc_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist);
578
579 static void _parse_almanc_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist, gboolean alm_elem, int count);
580
581 static void _parse_acqu_assist_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist);
582
583 static void _parse_nav_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist, gboolean ephem_and_clock, int element_count);
584
585 static void _set_coordinate(xmlNodePtr node, gps_ellipsoid_po_t *point, int isalt, int altitude);
586
587 static void _set_loc_info_ellipse_elements(xmlNodePtr node, void *elliplse, int is_unc_ellipse);
588
589 static xmlChar* _generate_confirm_measure_pos_xml_text(gps_measure_position_confirm_t *gps_measure_position_confirm);
590
591 static gboolean on_notification_gps_measure_position_from_modem(CoreObject *o, char *file_name, void *user_data);
592
593 /**************************************************************************
594 *                                                       Local Function Definitions
595  **************************************************************************/
596
597 static inline int _modem_sat_status_info_2_tel_sat_info(char *sat_info)
598 {
599         int count;
600
601         for (count = 0; count < (int) (sizeof(sat_status_info_table) / sizeof(sat_status_info_t)); count++) {
602                 if (strcmp(sat_status_info_table[count].psat_status, sat_info) == 0)
603                         return (sat_status_info_table[count].stat_status);
604         }
605         return (-1);
606 }
607
608 static inline int _modem_acqa_assit_doppler_2_tel_doppler(char *doppler_info)
609 {
610         int count;
611
612         for (count = 0; count < (int) (sizeof(doppler_status_info_table) / sizeof(doppler_status_info_t)); count++) {
613                 if (strcmp(doppler_status_info_table[count].pdoppler_status, doppler_info) == 0)
614                         return (doppler_status_info_table[count].doppler_status);
615         }
616         return (-1);
617 }
618
619 static int _gps_element_compare(char *element[], char *element_str, int nelem)
620 {
621         int count;
622
623         for (count = 0; count < nelem; count++) {
624                 if (strcmp(element[count], element_str) == 0)
625                         return count;
626         }
627
628         return -1;
629 }
630
631
632 static enum gps_assist_element_type _get_element_type(char *element_str)
633 {
634         unsigned int index;
635
636         for (index = 0; index < sizeof(elements) / sizeof(t_element); index++) {
637                 if (strcmp(elements[index].name, element_str) == 0)
638                         return elements[index].type;
639         }
640         return -1;
641 }
642
643 static void _parse_ref_time_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist, gboolean GPS_TOW_assist, int count)
644 {
645         int node_count;
646         int nelem;
647         static char *element[] = {"GPS_TOW_msec", "GPS_week", "sat_id", "tlm_word", "anti_sp", "alert", "tlm_res"};
648
649         dbg("Enter")
650         if (count < 0 || count >= MAX_NUM_OF_GPS_REF_TIME_ELEMENT) {
651                 dbg("invalid count");
652                 return;
653         }
654         nelem = (int) NUM_OF_ELEMENTS(element);
655         node_count = _gps_element_compare(element, element_str, nelem);
656
657         if (node_count == 0) {
658                 gpsdata_assist->ref_time.gpsTow = atoi(element_value);
659                 dbg("gpsTow - %d\n", gpsdata_assist->ref_time.gpsTow);
660                 gpsdata_assist->dgps_corrections.gpsTow = gpsdata_assist->ref_time.gpsTow;
661                 return;
662         } else if (node_count == 1) {
663                 gpsdata_assist->ref_time.gpsWeek = atoi(element_value);
664                 dbg("gpsWeek - %d\n", gpsdata_assist->ref_time.gpsWeek);
665                 return;
666         }
667
668         if (GPS_TOW_assist) {
669                 switch (node_count) {
670                 case 2:
671                 {
672                         gpsdata_assist->ref_time.GpsTowAssist[count].satID = atoi(element_value);
673                         dbg("GpsTowAssist[%d].satID  = %d\n", count, gpsdata_assist->ref_time.GpsTowAssist[count].satID);
674                         gpsdata_assist->ref_time.nrOfSats = count + 1;
675                 }
676                 break;
677
678                 case 3:
679                 {
680                         gpsdata_assist->ref_time.GpsTowAssist[count].tlmWord = atoi(element_value);
681                         dbg("GpsTowAssist[%d]-tlmWord  = %d\n", count, gpsdata_assist->ref_time.GpsTowAssist[count].tlmWord);
682                         gpsdata_assist->ref_time.nrOfSats = count + 1;
683                 }
684                 break;
685
686                 case 4:
687                 {
688                         gpsdata_assist->ref_time.GpsTowAssist[count].antiSpoofFlag = *element_value;
689                         dbg("GpsTowAssist[%d]-antiSpoofFlag  = 0x%X\n", count, gpsdata_assist->ref_time.GpsTowAssist[count].antiSpoofFlag);
690                         gpsdata_assist->ref_time.nrOfSats = count + 1;
691                 }
692                 break;
693
694                 case 5:
695                 {
696                         gpsdata_assist->ref_time.GpsTowAssist[count].alertFlag = *element_value;
697                         dbg("GpsTowAssist[%d]-alertFlag  = 0x%X\n", count, gpsdata_assist->ref_time.GpsTowAssist[count].alertFlag);
698                         gpsdata_assist->ref_time.nrOfSats = count + 1;
699                 }
700                 break;
701
702                 case 6:
703                 {
704                         gpsdata_assist->ref_time.GpsTowAssist[count].tmlReservedBits = *element_value;
705                         dbg("GpsTowAssist[%d]-tmlReservedBits  = 0x%X\n", count, gpsdata_assist->ref_time.GpsTowAssist[count].tmlReservedBits);
706                         gpsdata_assist->ref_time.nrOfSats = count + 1;
707                 }
708                 break;
709
710                 default:
711                         dbg("Invalid  gps element");
712                 }
713         }
714 }
715
716 static void _parse_location_parameters(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist)
717 {
718         // unsigned char shapeType;  and unsigned char hemisphere not supported.
719
720         static char *element[] = {
721                 "north", "degrees", "height_above_surface", "height", "longitude", "uncert_semi_major", "uncert_semi_minor",
722                 "orient_major", "confidence", "uncert_alt"
723         };
724
725         int nelem = (int) NUM_OF_ELEMENTS(element);
726         int count;
727
728         count = _gps_element_compare(element, element_str, nelem);
729
730         dbg("Enter")
731
732         switch (count) {
733         case 0:
734         {
735                 // gpsdata_assist.ref_loc.latitude_data.north = atoi(element_str_text);
736                 // dbg("gpsdata_assist.ref_loc.latitude_data.north  - %d\n",gpsdata_assist.ref_loc.latitude_data.north);
737         }
738         break;
739
740         case 1:
741         {
742                 gpsdata_assist->ref_loc.latitude = atoi(element_value);
743                 dbg("latitude_data.degrees - %d\n", gpsdata_assist->ref_loc.latitude);
744         }
745         break;
746
747         case 2:
748         {
749                 // gpsdata_assist.ref_loc.altitude_data.height_above_surface = atoi(element_str_text);
750                 // dbg("altitude_data.height_above_surface  - %d\n",gpsdata_assist.ref_loc.altitude_data.height_above_surface);
751         }
752         break;
753
754         case 3:
755         {
756                 gpsdata_assist->ref_loc.altitude = atoi(element_value);      // todo- need to confirm
757                 dbg("altitude_data.height - %d\n", gpsdata_assist->ref_loc.altitude);
758         }
759         break;
760
761         case 4:
762         {
763                 gpsdata_assist->ref_loc.longitude = atoi(element_value);
764                 dbg("longitude  - %d\n", gpsdata_assist->ref_loc.longitude);
765         }
766         break;
767
768         case 5:
769         {
770                 gpsdata_assist->ref_loc.semiMajorUncert = *element_value;
771                 dbg("semiMajorUncert  - 0x%X\n", gpsdata_assist->ref_loc.semiMajorUncert);
772         }
773         break;
774
775         case 6:
776         {
777                 gpsdata_assist->ref_loc.semiMinorUncert = *element_value;
778                 dbg("uncert_semi_minor - 0x%X\n", gpsdata_assist->ref_loc.semiMinorUncert);
779         }
780         break;
781
782         case 7:
783         {
784                 gpsdata_assist->ref_loc.majorAxis = *element_value;
785                 dbg("orient_major - 0x%X\n", gpsdata_assist->ref_loc.majorAxis);
786         }
787         break;
788
789         case 8:
790         {
791                 gpsdata_assist->ref_loc.confidence = *element_value;
792                 dbg("confidence - 0x%X\n", gpsdata_assist->ref_loc.confidence);
793         }
794         break;
795
796         case 9:
797         {
798                 gpsdata_assist->ref_loc.altUncert = *element_value;
799                 dbg("altUncert - 0x%X\n", gpsdata_assist->ref_loc.altUncert);
800         }
801         break;
802
803         default:
804                 dbg("invalid element");
805         }
806 }
807
808 static void _parse_dgps_correction_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist)
809 {
810         dbg("Enter");
811
812         if (strcmp(element_str, "sat_id") == 0) {
813                 gpsdata_assist->dgps_corrections.seqOfSatElement[0].satId = *element_value;
814                 dbg("seqOfSatElement[0].satId  - %d\n", gpsdata_assist->dgps_corrections.seqOfSatElement[0].satId);
815         } else if (strcmp(element_str, "IODE") == 0) {
816                 gpsdata_assist->dgps_corrections.seqOfSatElement[0].iode = atoi(element_value);
817                 dbg("seqOfSatElement[0].iode - %d\n", gpsdata_assist->dgps_corrections.seqOfSatElement[0].iode);
818         } else if (strcmp(element_str, "UDRE") == 0) {
819                 gpsdata_assist->dgps_corrections.seqOfSatElement[0].udre = *element_value;
820                 dbg("seqOfSatElement[0].udre- %d\n", gpsdata_assist->dgps_corrections.seqOfSatElement[0].udre);
821         } else if (strcmp(element_str, "PRC") == 0) {
822                 gpsdata_assist->dgps_corrections.seqOfSatElement[0].pseudoRangeCor = atoi(element_value);
823                 dbg("seqOfSatElement[0].pseudoRangeCor - %d\n", gpsdata_assist->dgps_corrections.seqOfSatElement[0].pseudoRangeCor);
824         } else if (strcmp(element_str, "RRC") == 0) {
825                 gpsdata_assist->dgps_corrections.seqOfSatElement[0].rangeRateCor = atoi(element_value);
826                 dbg("seqOfSatElement[0].rangeRateCor - %d\n", gpsdata_assist->dgps_corrections.seqOfSatElement[0].rangeRateCor);
827         }
828 }
829
830 static void _parse_ionospheric_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist)
831 {
832         static char *element[] = {"alfa0", "alfa1", "alfa2", "alfa3", "beta0", "beta1", "beta2", "beta3" };
833         int nelem = (int) NUM_OF_ELEMENTS(element);
834         int count;
835
836         count = _gps_element_compare(element, element_str, nelem);
837         dbg("enter");
838         switch (count) {
839         case 0:
840         {
841                 gpsdata_assist->iono_model.alfa0 = *element_value;
842                 dbg("alfa0  - 0x%X\n", gpsdata_assist->iono_model.alfa0);
843         }
844         break;
845
846         case 1:
847         {
848                 gpsdata_assist->iono_model.alfa1 = *element_value;
849                 dbg("alfa1 - 0x%X\n", gpsdata_assist->iono_model.alfa1);
850         }
851         break;
852
853         case 2:
854         {
855                 gpsdata_assist->iono_model.alfa2 = *element_value;
856                 dbg("alfa2  - 0x%X\n", gpsdata_assist->iono_model.alfa2);
857         }
858         break;
859
860         case 3:
861         {
862                 gpsdata_assist->iono_model.alfa3 = *element_value;
863                 dbg("alfa3  - 0x%X\n", gpsdata_assist->iono_model.alfa3);
864         }
865         break;
866
867         case 4:
868         {
869                 gpsdata_assist->iono_model.beta0 = *element_value;
870                 dbg("beta0  - 0x%X\n", gpsdata_assist->iono_model.beta0);
871         }
872         break;
873
874         case 5:
875         {
876                 gpsdata_assist->iono_model.beta1 = *element_value;
877                 dbg("beta1  -0x%X\n", gpsdata_assist->iono_model.beta1);
878         }
879         break;
880
881         case 6:
882         {
883                 gpsdata_assist->iono_model.beta2 = *element_value;
884                 dbg("beta2  - 0x%X\n", gpsdata_assist->iono_model.beta2);
885         }
886         break;
887
888         case 7:
889         {
890                 gpsdata_assist->iono_model.beta3 = *element_value;
891                 dbg("beta3  - 0x%X\n", gpsdata_assist->iono_model.beta3);
892         }
893         break;
894
895         default:
896                 dbg("invalid gps element");
897         }
898 }
899
900 void _parse_utc_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist)
901 {
902         static char *element[] = {"a1", "a0", "tot", "wnt", "dtls", "wnlsf", "dn", "dtlsf"};
903         int nelem = (int) NUM_OF_ELEMENTS(element);
904         int count;
905
906         count = _gps_element_compare(element, element_str, nelem);
907         dbg("Enter");
908
909         switch (count) {
910         case 0:
911         {
912                 gpsdata_assist->utc_model.utcA1 = atoi(element_value);
913                 dbg("utcA1  - %d\n", gpsdata_assist->utc_model.utcA1);
914         }
915         break;
916
917         case 1:
918         {
919                 gpsdata_assist->utc_model.utcA0 = atoi(element_value);
920                 dbg("utcA0  - %d\n", gpsdata_assist->utc_model.utcA0);
921         }
922         break;
923
924         case 2:
925         {
926                 gpsdata_assist->utc_model.utcTot = *element_value;
927                 dbg("utcTot  - 0x%X\n", gpsdata_assist->utc_model.utcTot);
928         }
929         break;
930
931         case 3:
932         {
933                 gpsdata_assist->utc_model.utcWNt = *element_value;
934                 dbg("utcWNt  - 0x%X\n", gpsdata_assist->utc_model.utcWNt);
935         }
936         break;
937
938         case 4:
939         {
940                 gpsdata_assist->utc_model.utcDeltaTls = *element_value;
941                 dbg("utcDeltaTls  -0x%X\n", gpsdata_assist->utc_model.utcDeltaTls);
942         }
943         break;
944
945         case 5:
946         {
947                 gpsdata_assist->utc_model.utcWNlsf = *element_value;
948                 dbg("utcWNlsf  - 0x%X\n", gpsdata_assist->utc_model.utcWNlsf);
949         }
950         break;
951
952         case 6:
953         {
954                 gpsdata_assist->utc_model.utcDN = *element_value;
955                 dbg("utcDN  - 0x%X\n", gpsdata_assist->utc_model.utcDN);
956         }
957         break;
958
959         case 7:
960         {
961                 gpsdata_assist->utc_model.utcDeltaTlsf = *element_value;
962                 dbg("utcDeltaTlsf  - 0x%X\n", gpsdata_assist->utc_model.utcDeltaTlsf);
963         }
964         break;
965
966         default:
967                 dbg("invalid gps element");
968         }
969 }
970
971 static void _parse_almanc_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist,
972                                                                                          gboolean alm_elem, int count)
973 {
974         int nelem;
975         int node_count;
976         static char *element[] = {
977                 "wna", "data_id", "sat_id", "alm_ecc", "alm_toa", "alm_ksii", "alm_omega_dot", "alm_sv_health", "alm_power_half",
978                 "alm_omega0", "alm_omega", "alm_m0", "alm_af0", "alm_af1"
979         };
980
981         dbg("Enter");
982         if (count < 0 || count >= MAX_NUM_OF_GPS_ALMANC_ELEMENTS) {
983                 dbg("invalid count");
984                 return;
985         }
986         nelem = (int) NUM_OF_ELEMENTS(element);
987
988         node_count = _gps_element_compare(element, element_str, nelem);
989         if (node_count == 0) {
990                 gpsdata_assist->almanac.almanacWNa = *element_value;
991                 dbg("almanacWNa  - %d\n", gpsdata_assist->almanac.almanacWNa);
992                 return;
993         }
994
995         if (alm_elem) {
996                 switch (node_count) {
997                 case 1:
998                 {
999                         gpsdata_assist->almanac.AlmanacSatInfo[count].dataId = *element_value;
1000                         dbg("AlmanacSatInfo[%d].data_id  - 0x%X\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].dataId);
1001                 }
1002                 break;
1003
1004                 case 2:
1005                 {
1006                         gpsdata_assist->almanac.AlmanacSatInfo[count].satId = *element_value;
1007                         dbg("AlmanacSatInfo[%d].sat_id  - 0x%X\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].satId);
1008                 }
1009                 break;
1010
1011                 case 3:
1012                 {
1013                         gpsdata_assist->almanac.AlmanacSatInfo[count].almanacE = atoi(element_value);
1014                         dbg("AlmanacSatInfo[%d].almanacE  - %d\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacE);
1015                 }
1016                 break;
1017
1018                 case 4:
1019                 {
1020                         gpsdata_assist->almanac.AlmanacSatInfo[count].almanacToa = *element_value;
1021                         dbg("AlmanacSatInfo[%d].almanacToa  - 0x%X\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacToa);
1022                 }
1023                 break;
1024
1025                 case 5:
1026                 {
1027                         gpsdata_assist->almanac.AlmanacSatInfo[count].almanacKsii = *element_value;
1028                         dbg("AlmanacSatInfo[%d].almanacKsii  - 0x%X\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacKsii);
1029                 }
1030                 break;
1031
1032                 case 6:
1033                 {
1034                         gpsdata_assist->almanac.AlmanacSatInfo[count].almanacOmegaDot = *element_value;
1035                         dbg("AlmanacSatInfo[%d].almanacOmegaDot  - 0x%X\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacOmegaDot);
1036                 }
1037                 break;
1038
1039                 case 7:
1040                 {
1041                         gpsdata_assist->almanac.AlmanacSatInfo[count].almanacSvHealth = *element_value;
1042                         dbg("AlmanacSatInfo[%d].almanacSvHealth  - 0x%X\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacSvHealth);
1043                 }
1044                 break;
1045
1046                 case 8:
1047                 {
1048                         gpsdata_assist->almanac.AlmanacSatInfo[count].almanacAPowerHalf = atoi(element_value);
1049                         dbg("AlmanacSatInfo[%d].almanacAPowerHalf  - %d\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacAPowerHalf);
1050                 }
1051                 break;
1052
1053                 case 9:
1054                 {
1055                         gpsdata_assist->almanac.AlmanacSatInfo[count].almanacOmega0 = atoi(element_value);
1056                         dbg("AlmanacSatInfo[%d].almanacOmega0  - %d\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacOmega0);
1057                 }
1058                 break;
1059
1060                 case 10:
1061                 {
1062                         gpsdata_assist->almanac.AlmanacSatInfo[count].almanacW = atoi(element_value);
1063                         dbg("AlmanacSatInfo[%d].almanacW  - %d\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacW);
1064                 }
1065                 break;
1066
1067                 case 11:
1068                 {
1069                         gpsdata_assist->almanac.AlmanacSatInfo[count].almanacM0 = atoi(element_value);
1070                         dbg("AlmanacSatInfo[%d].almanacM0  - %d\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacM0);
1071                 }
1072                 break;
1073
1074                 case 12:
1075                 {
1076                         gpsdata_assist->almanac.AlmanacSatInfo[count].almanacAf0 = atoi(element_value);
1077                         dbg("AlmanacSatInfo[%d].almanacAf0  - %d\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacAf0);
1078                 }
1079                 break;
1080
1081                 case 13:
1082                 {
1083                         gpsdata_assist->almanac.AlmanacSatInfo[count].almanacAf1 = atoi(element_value);
1084                         dbg("AlmanacSatInfo[%d].almanacAf1  - %d\n", count, gpsdata_assist->almanac.AlmanacSatInfo[count].almanacAf1);
1085                 }
1086                 break;
1087
1088                 default:
1089                         dbg("invalid gps element");
1090                 }
1091         }
1092         return;
1093 }
1094
1095 static void _parse_acqu_assist_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t *gpsdata_assist)
1096 {
1097         static char *element[] = {"tow_msec", "sat_id", "dopl0", "dopl1", "code_ph", "code_ph_int", "GPS_bitno", "srch_w", "az", "elev"};
1098         int nelem = (int) NUM_OF_ELEMENTS(element);
1099         int count;
1100
1101         count = _gps_element_compare(element, element_str, nelem);
1102         dbg("Enter");
1103
1104         switch (count) {
1105         case 0:
1106                 gpsdata_assist->acq_assist.gpsTow = atoi(element_value);
1107                 dbg("acq_assist.gpsTow  - %d\n", gpsdata_assist->acq_assist.gpsTow);
1108                 break;
1109
1110         case 1:
1111                 gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].satId = *element_value;
1112                 dbg("lcsAcquisitionSatInfo[0].satId  - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].satId);
1113                 break;
1114
1115         case 2:
1116                 gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].doppler0 = atoi(element_value);
1117                 dbg("lcsAcquisitionSatInfo[0].dopl0  - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].doppler0);
1118                 break;
1119
1120         case 3:
1121                 gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].doppler1 = *element_value;
1122                 dbg("lcsAcquisitionSatInfo[0].doppler1  - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].doppler1);
1123                 break;
1124
1125         case 4:
1126                 gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].codePhase = atoi(element_value);
1127                 dbg("lcsAcquisitionSatInfo[0].codePhase  - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].codePhase);
1128                 break;
1129
1130         case 5:
1131                 gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].intCodePhase = *element_value;
1132                 dbg("lcsAcquisitionSatInfo[0].intCodePhase  - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].intCodePhase);
1133                 break;
1134
1135         case 6:
1136                 gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].gpsBitNumber = *element_value;
1137                 dbg("lcsAcquisitionSatInfo[0].GPS_bitno  - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].gpsBitNumber);
1138                 break;
1139
1140         case 7:
1141                 gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].codePhaseSearchWindow = *element_value;
1142                 dbg("lcsAcquisitionSatInfo[0].codePhaseSearchWindow  - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].codePhaseSearchWindow);
1143                 break;
1144
1145         case 8:
1146                 gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].azimuth = *element_value;
1147                 dbg("lcsAcquisitionSatInfo[0].azimuth  - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].azimuth);
1148                 break;
1149
1150         case 9:
1151                 gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].elevation = *element_value;
1152                 dbg("lcsAcquisitionSatInfo[0].elevation  - 0x%X\n", gpsdata_assist->acq_assist.lcsAcquisitionSatInfo[0].elevation);
1153                 break;
1154
1155         default:
1156                 dbg("invalid gps element");
1157         }
1158 }
1159
1160 static void _parse_nav_model_gps_elements(char *element_str, char *element_value, gps_assist_data_noti_t
1161                                                                                   *gpsdata_assist, gboolean ephem_and_clock, int element_count)
1162 {
1163         static char *element[] = {
1164                 "sat_id", "l2_code", "ura", "sv_health", "iodc", "l2p_flag", "esr1", "esr2", "esr3", "esr4", "tgd", "toc", "af2", "af0",
1165                 "crs", "delta_n", "m0", "cuc", "ecc", "cus", "power_half", "toe", "fit_flag", "aoda", "cic", "omega0", "cis", "i0", "crc", "omega", "idot", "omega_dot"
1166         };
1167
1168         int nelem = (int) NUM_OF_ELEMENTS(element);
1169         int count;
1170
1171         if (element_count < 0 || element_count >= MAX_NUM_OF_GPS_NAV_ELEMENT) {
1172                 dbg("invalid count");
1173                 return;
1174         }
1175         count = _gps_element_compare(element, element_str, nelem);
1176
1177         dbg("Enter");
1178         if (count == 0) {
1179                 gpsdata_assist->navi_model.NavigationSatInfo[element_count].satId = *element_value;
1180                 dbg("NavigationSatInfo[%d].satId  - 0x%X\n", element_count, gpsdata_assist->navi_model.NavigationSatInfo[element_count].satId);
1181                 return;
1182         }
1183
1184         if (ephem_and_clock) {
1185                 switch (count) {
1186                 case 1:
1187                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemCodeOnL2 = *element_value;
1188                         break;
1189
1190                 case 2:
1191                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemUra = *element_value;
1192                         break;
1193
1194                 case 3:
1195                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemSvHealth = *element_value;
1196                         break;
1197
1198                 case 4:
1199                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemIodc = atoi(element_value);
1200                         break;
1201
1202                 case 5:
1203                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemL2PFlag = *element_value;
1204                         break;
1205
1206                 case 6:
1207                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.NavigationSubFrameRsv.rsv1 = atoi(element_value);
1208                         break;
1209
1210                 case 7:
1211                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.NavigationSubFrameRsv.rsv2 = atoi(element_value);
1212                         break;
1213
1214                 case 8:
1215                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.NavigationSubFrameRsv.rsv3 = atoi(element_value);
1216                         break;
1217
1218                 case 9:
1219                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.NavigationSubFrameRsv.rsv4 = atoi(element_value);
1220                         break;
1221
1222                 case 10:
1223                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemTgd = *element_value;
1224                         break;
1225
1226                 case 11:
1227                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemToc = atoi(element_value);
1228                         break;
1229
1230                 case 12:
1231                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemAf2 = *element_value;
1232                         break;
1233
1234                 case 13:
1235                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemAf1 = atoi(element_value);
1236                         break;
1237
1238                 case 14:
1239                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemAf0 = atoi(element_value);
1240                         break;
1241
1242                 case 15:
1243                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemCrs = atoi(element_value);
1244                         break;
1245
1246                 case 16:
1247                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemDeltaN = atoi(element_value);
1248                         break;
1249
1250                 case 17:
1251                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemM0 = atoi(element_value);
1252                         break;
1253
1254                 case 18:
1255                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemCuc = atoi(element_value);
1256                         break;
1257
1258                 case 19:
1259                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemE = atoi(element_value);
1260                         break;
1261
1262                 case 20:
1263                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemCus = atoi(element_value);
1264                         break;
1265
1266                 case 21:
1267                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemAPowrHalf = atoi(element_value);
1268                         break;
1269
1270                 case 22:
1271                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemToe = atoi(element_value);
1272                         break;
1273
1274                 case 23:
1275                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemFitFlag = *element_value;
1276                         break;
1277
1278                 case 24:
1279                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemAoda = *element_value;
1280                         break;
1281
1282                 case 25:
1283                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemCic = atoi(element_value);
1284                         break;
1285
1286                 case 26:
1287                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemI0 = atoi(element_value);
1288                         break;
1289
1290                 case 27:
1291                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemCrc = atoi(element_value);
1292                         break;
1293
1294                 case 28:
1295                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemW = atoi(element_value);
1296                         break;
1297
1298                 case 29:
1299                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemIDot = atoi(element_value);
1300                         break;
1301
1302                 case 30:
1303                         gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemOmegaADot = atoi(element_value);
1304                         dbg("NavigationSatInfo[%d].NavigationEphemeris.ephemOmegaADot - 0x%X\n", element_count, gpsdata_assist->navi_model.NavigationSatInfo[element_count].NavigationEphemeris.ephemOmegaADot);
1305                         break;
1306
1307                 default:
1308                         dbg("invalid gps element");
1309                 }
1310         }
1311 }
1312
1313
1314 // Set coordinate elements  : <latitude> <longitude> <altitude>
1315 static void _set_coordinate(xmlNodePtr node, gps_ellipsoid_po_t *point, int isalt, int altitude)
1316 {
1317         // <parent_node> .. .. (xmlNodePtr node)
1318         // <coordinate>  <latitude>  <north>0</north>  <degrees>0</degrees> </latitude> <longitude>0</longitude> </coordinate>
1319         // <altitude>  <height_above_surface>0</height_above_surface>  <height>0</height> </altitude>
1320         // .. .. <\parent_node>
1321
1322         xmlNodePtr coordinate_node = NULL, temp_node = NULL;
1323
1324         memset(node_name, 0x00, sizeof(node_name));
1325         memset(node_value, 0x00, sizeof(node_value));
1326
1327         sprintf(node_name, "%s", "coordinate");
1328         coordinate_node = xmlNewChild(node, NULL, BAD_CAST node_name, NULL);
1329
1330         sprintf(node_name, "%s", "latitude");
1331         temp_node = xmlNewChild(coordinate_node, NULL, BAD_CAST node_name, NULL);
1332
1333         sprintf(node_name, "%s", "north");
1334         sprintf(node_value, "%d", 0);
1335         xmlNewChild(temp_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1336
1337         sprintf(node_name, "%s", "degrees");
1338         sprintf(node_value, "%d", (int) point->latitude);
1339         xmlNewChild(temp_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1340
1341         sprintf(node_name, "%s", "longitude");
1342         sprintf(node_value, "%d", (int) point->longitude);
1343         xmlNewChild(coordinate_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1344
1345         if (isalt) {
1346                 sprintf(node_name, "%s", "altitude");
1347                 temp_node = xmlNewChild(node, NULL, BAD_CAST node_name, NULL);
1348                 sprintf(node_name, "%s", "height_above_surface");
1349                 sprintf(node_value, "%d", 0);
1350                 xmlNewChild(temp_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1351                 sprintf(node_name, "%s", "height");
1352                 sprintf(node_value, "%d", altitude);
1353                 xmlNewChild(temp_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1354         }
1355         return;
1356 }
1357
1358 static void _set_loc_info_ellipse_elements(xmlNodePtr node, void *elliplse, int is_unc_ellipse)
1359 {
1360         gps_po_unc_ellipse_t *p_unc_ellipse;
1361         gps_po_alt_unc_ellipse_t *p_alt_unc_ellipse;
1362         unsigned char semiMajorAxis, semiMinorAxis, orientationAngle, confidence;
1363
1364         memset(node_name, 0x00, sizeof(node_name));
1365         memset(node_value, 0x00, sizeof(node_value));
1366
1367         if (is_unc_ellipse) {
1368                 p_unc_ellipse = (gps_po_unc_ellipse_t *) elliplse;
1369                 semiMajorAxis = p_unc_ellipse->semiMajorAxis;
1370                 semiMinorAxis = p_unc_ellipse->semiMinorAxis;
1371                 orientationAngle = p_unc_ellipse->orientationAngle;
1372                 confidence = p_unc_ellipse->confidence;
1373         } else {
1374                 p_alt_unc_ellipse = (gps_po_alt_unc_ellipse_t *) elliplse;
1375                 semiMajorAxis = p_alt_unc_ellipse->semiMajorAxis;
1376                 semiMinorAxis = p_alt_unc_ellipse->semiMinorAxis;
1377                 orientationAngle = p_alt_unc_ellipse->orientationAngle;
1378                 confidence = p_alt_unc_ellipse->confidence;
1379         }
1380
1381         sprintf(node_name, "%s", "uncert_semi_major");
1382         sprintf(node_value, "%d", semiMajorAxis);
1383         xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1384
1385         sprintf(node_name, "%s", "uncert_semi_minor");
1386         sprintf(node_value, "%d", semiMinorAxis);
1387         xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1388
1389         sprintf(node_name, "%s", "orient_major");
1390         sprintf(node_value, "%d", orientationAngle);
1391         xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1392
1393         sprintf(node_name, "%s", "confidence");
1394         sprintf(node_value, "%d", confidence);
1395         xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1396 }
1397
1398 static xmlChar* _generate_confirm_measure_pos_xml_text(gps_measure_position_confirm_t *gps_measure_position_confirm)
1399 {
1400         xmlDocPtr doc = NULL;
1401         xmlNodePtr root_node = NULL, node = NULL;
1402         xmlNodePtr gps_msr_node = NULL, shape_data_node = NULL, loc_child_node = NULL;
1403         xmlChar *xml = NULL;
1404         int count = 0, altitude, size;
1405
1406 /*
1407      Creates a new XML document
1408 ================================================================================================================================
1409
1410
1411     <?xml version="1.0"?>
1412     <pos xsi:noNamespaceSchemaLocation="pos.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1413         <GPS_meas>
1414             <ref_time_only>
1415                 <tow_msec></tow_msec>
1416             </ref_time_only>
1417             <meas_params>
1418                 <sat_id></sat_id><carr2_noise></carr2_noise><dopl></dopl><whole_chips></whole_chips><fract_chips></fract_chips>
1419                 <multi_path literal="xx"></multi_path> <psr_rms_err></psr_rms_err>
1420             </meas_params>
1421         </GPS_meas>
1422         <location>
1423             <time_of_fix></time_of_fix><
1424             <location_parameters>
1425             <shape_data>
1426              <ellipsoid_point>
1427                 <coordinate>
1428                     <latitude><north></north><degrees></degrees></latitude><longitude></longitude>
1429                  </coordinate>
1430              </ellipsoid_point>
1431             <ellipsoid_point_uncert_circle>
1432                 <uncert_circle></uncert_circle>
1433                 <coordinate>
1434                 <latitude> <> <\> ...</latitude> <longitude></longitude>
1435                 </coordinate>
1436             </ellipsoid_point_uncert_circle>
1437             <ellipsoid_point_uncert_ellipse>
1438                 <coordinate>
1439                     <latitude><> <\>..<longitude></longitude>
1440                 </coordinate>
1441                 <uncert_ellipse><uncert_semi_major></uncert_semi_major><uncert_semi_minor></uncert_semi_minor>
1442                 <orient_major></orient_major><confidence></confidence></uncert_ellipse>
1443             </ellipsoid_point_uncert_ellipse>
1444             <polygon>
1445                 <coordinate*>
1446                     <latitude><> <\>...</latitude><longitude></longitude>
1447                 </coordinate>
1448             </polygon>
1449              <ellipsoid_point_alt>
1450                 <coordinate>
1451                      <latitude><> <\>..</latitude><longitude></longitude>
1452                 </coordinate>
1453             <altitude>
1454                 <height_above_surface></height_above_surface><height></height>
1455             </altitude>
1456             </ellipsoid_point_alt>
1457             <ellipsoid_point_alt_uncertellipse>
1458             <coordinate>
1459                 <latitude> <> <\>.. ..</latitude><longitude></longitude>
1460             </coordinate>
1461             <altitude>
1462                 <height_above_surface></height_above_surface><height></height>
1463             </altitude>
1464             <uncert_semi_major></uncert_semi_major><uncert_semi_minor></uncert_semi_minor><orient_major></orient_major>
1465             <confidence></confidence><uncert_alt></uncert_alt>
1466             </ellipsoid_point_alt_uncertellipse>
1467             <ellips_arc>
1468                 <coordinate>
1469                     <latitude><> <\> .. </latitude><longitude></longitude>
1470                 </coordinate><
1471                 <inner_rad></inner_rad>
1472                 <uncert_rad></uncert_rad><offset_angle></offset_angle><included_angle></included_angle>
1473                 <confidence></confidence>
1474             </ellips_arc>
1475             </shape_data>
1476             </location_parameters>
1477             </location>
1478             <assist_data>
1479                 <msr_assist_data/>
1480             </assist_data>
1481          </pos>
1482  ================================================================================================================================
1483  */
1484
1485         doc = xmlNewDoc(BAD_CAST "1.0");
1486         dbg("Enter");
1487
1488         memset(node_name, 0x00, sizeof(node_name));
1489         memset(node_value, 0x00, sizeof(node_value));
1490         // root element
1491         sprintf(node_name, "%s", POSITION_NODE);
1492         // Creation of a new node element
1493         root_node = xmlNewNode(NULL, BAD_CAST node_name);
1494         // Set the root element of the document
1495         xmlDocSetRootElement(doc, root_node);
1496         sprintf(node_name, "%s", POSITION_NODE_ATTR_XSI);
1497         sprintf(node_value, "%s", POSITION_NODE_ATTR_VAL_XSI);
1498         // Create a new property carried by a node
1499         xmlNewProp(root_node, BAD_CAST node_name, BAD_CAST node_value);
1500
1501         sprintf(node_name, "%s", POSITION_NODE_ATTR_XMLNS);
1502         sprintf(node_value, "%s", POSITION_NODE_ATTR_VAL_XMLNS);
1503         xmlNewProp(root_node, BAD_CAST node_name, BAD_CAST node_value);
1504
1505         // 1.GPS measure.
1506         // Creation of a new child element, added at the end of @parent children list
1507         sprintf(node_name, "%s", "GPS_meas");
1508         gps_msr_node = xmlNewChild(root_node, NULL, BAD_CAST node_name, NULL);
1509
1510         sprintf(node_name, "%s", "ref_time_only");
1511         node = xmlNewChild(gps_msr_node, NULL, BAD_CAST node_name, NULL);
1512
1513         sprintf(node_name, "%s", "tow_msec");
1514         sprintf(node_value, "%d", (int) gps_measure_position_confirm->gps_measure.gpsTow);
1515         xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1516
1517         // creatation of <meas_params> elements.
1518         for (count = 0; count < gps_measure_position_confirm->gps_measure.nrOfSats; count++) {
1519                 xmlNodePtr multipath_node = NULL;
1520                 sprintf(node_name, "%s", "meas_params");
1521                 node = xmlNewChild(gps_msr_node, NULL, BAD_CAST node_name, NULL);
1522
1523                 sprintf(node_name, "%s", "sat_id");
1524                 sprintf(node_value, "%d", gps_measure_position_confirm->gps_measure.GpsMeasure[count].satId);
1525                 xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1526
1527                 sprintf(node_name, "%s", "carr2_noise");
1528                 sprintf(node_value, "%d", gps_measure_position_confirm->gps_measure.GpsMeasure[count].cno);
1529                 xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1530
1531                 sprintf(node_name, "%s", "dopl");
1532                 sprintf(node_value, "%d", gps_measure_position_confirm->gps_measure.GpsMeasure[count].doppler);
1533                 xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1534
1535                 sprintf(node_name, "%s", "whole_chips");
1536                 sprintf(node_value, "%d", gps_measure_position_confirm->gps_measure.GpsMeasure[count].wholeChips);
1537                 xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1538
1539                 sprintf(node_name, "%s", "fract_chips");
1540                 sprintf(node_value, "%d", gps_measure_position_confirm->gps_measure.GpsMeasure[count].fracChips);
1541                 xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1542
1543                 sprintf(node_name, "%s", "multi_path");
1544                 sprintf(node_value, "%d", gps_measure_position_confirm->gps_measure.GpsMeasure[count].lcsMultiPath);
1545                 multipath_node = xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1546                 xmlNewProp(multipath_node, BAD_CAST "literal", BAD_CAST "not_measured");
1547
1548                 sprintf(node_name, "%s", "psr_rms_err");
1549                 sprintf(node_value, "%d", gps_measure_position_confirm->gps_measure.GpsMeasure[count].pseuRangeRmsErr);
1550                 xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1551         }
1552
1553         // 2.Location.
1554         sprintf(node_name, "%s", "location");
1555         node = xmlNewChild(root_node, NULL, BAD_CAST node_name, NULL);
1556
1557         sprintf(node_name, "%s", "time_of_fix");
1558         sprintf(node_value, "%d", gps_measure_position_confirm->loc_info.fixType);
1559         xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1560
1561         // location_parameters
1562         sprintf(node_name, "%s", "location_parameters");
1563         node = xmlNewChild(node, NULL, BAD_CAST node_name, NULL);
1564
1565         // shape_data
1566         sprintf(node_name, "%s", "shape_data");
1567         shape_data_node = xmlNewChild(node, NULL, BAD_CAST node_name, NULL);
1568
1569         // ellipsoid_point
1570         sprintf(node_name, "%s", "ellipsoid_point");
1571         node = xmlNewChild(shape_data_node, NULL, BAD_CAST node_name, NULL);
1572         // set coordinate.
1573         _set_coordinate(node, &(gps_measure_position_confirm->loc_info.measured_loc_info.ellipsoid_po), 0, 0);
1574
1575         // ellipsoid_point_uncert_circle
1576         sprintf(node_name, "%s", "ellipsoid_point_uncert_circle");
1577         node = xmlNewChild(shape_data_node, NULL, BAD_CAST node_name, NULL);
1578         sprintf(node_name, "%s", "uncert_circle");
1579         sprintf(node_value, "%d", gps_measure_position_confirm->loc_info.measured_loc_info.p_unc_clrcle.uncertainRadius);
1580         xmlNewChild(node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1581         // set coordinate parameters.
1582         _set_coordinate(node, &(gps_measure_position_confirm->loc_info.measured_loc_info.p_unc_clrcle.point), 0, 0);
1583
1584         // ellipsoid_point_uncert_ellipse
1585         sprintf(node_name, "%s", "ellipsoid_point_uncert_ellipse");
1586         loc_child_node = xmlNewChild(shape_data_node, NULL, BAD_CAST node_name, NULL);
1587         // set coordinate parameters.
1588         _set_coordinate(loc_child_node, &(gps_measure_position_confirm->loc_info.measured_loc_info.p_unc_clrcle.point), 0, 0);
1589
1590         sprintf(node_name, "%s", "uncert_ellipse");
1591         node = xmlNewChild(loc_child_node, NULL, BAD_CAST node_name, NULL);
1592         // set location ellipse parametes.
1593         _set_loc_info_ellipse_elements(node, &(gps_measure_position_confirm->loc_info.measured_loc_info.p_unc_ellipse), 1);
1594
1595         sprintf(node_name, "%s", "polygon");
1596         loc_child_node = xmlNewChild(shape_data_node, NULL, BAD_CAST node_name, NULL);
1597         for (count = 0; count < gps_measure_position_confirm->loc_info.measured_loc_info.polygon.noOfPoints; count++) {
1598                 // set coordinate parameters.
1599                 _set_coordinate(loc_child_node, &(gps_measure_position_confirm->loc_info.measured_loc_info.polygon.points[count]), 0, 0);
1600         }
1601
1602         // ellipsoid_point_alt
1603         sprintf(node_name, "%s", "ellipsoid_point_alt");
1604         loc_child_node = xmlNewChild(shape_data_node, NULL, BAD_CAST node_name, NULL);
1605         altitude = gps_measure_position_confirm->loc_info.measured_loc_info.ellipsoid_alt.altitude;
1606         // set coordinate parameters.
1607         _set_coordinate(loc_child_node, &(gps_measure_position_confirm->loc_info.measured_loc_info.ellipsoid_alt.point), 1, altitude);
1608
1609         // ellipsoid_point_alt_uncertellipse
1610         sprintf(node_name, "%s", "ellipsoid_point_alt_uncertellipse");
1611         loc_child_node = xmlNewChild(shape_data_node, NULL, BAD_CAST node_name, NULL);
1612         altitude = gps_measure_position_confirm->loc_info.measured_loc_info.p_alt_unc_ellipse.altitude;
1613         // set coordinate parameters.
1614         _set_coordinate(loc_child_node, &(gps_measure_position_confirm->loc_info.measured_loc_info.p_alt_unc_ellipse.point), 1, altitude);
1615         // set location ellipse parametes.
1616         _set_loc_info_ellipse_elements(loc_child_node, &(gps_measure_position_confirm->loc_info.measured_loc_info.p_alt_unc_ellipse), 0);
1617
1618         sprintf(node_name, "%s", "uncert_alt");
1619         sprintf(node_value, "%d", gps_measure_position_confirm->loc_info.measured_loc_info.p_alt_unc_ellipse.uncertainAltitude);
1620         xmlNewChild(loc_child_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1621
1622         // ellipsoid_point_alt_uncertellipse
1623         sprintf(node_name, "%s", "ellips_arc");
1624         loc_child_node = xmlNewChild(shape_data_node, NULL, BAD_CAST node_name, NULL);
1625         _set_coordinate(loc_child_node, &(gps_measure_position_confirm->loc_info.measured_loc_info.ellipsoid_arc.point), 0, 0);
1626
1627         sprintf(node_name, "%s", "inner_rad");
1628         sprintf(node_value, "%d", gps_measure_position_confirm->loc_info.measured_loc_info.ellipsoid_arc.innerRadius);
1629         xmlNewChild(loc_child_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1630
1631         sprintf(node_name, "%s", "uncert_rad");
1632         sprintf(node_value, "%d", gps_measure_position_confirm->loc_info.measured_loc_info.ellipsoid_arc.uncertainRadius);
1633         xmlNewChild(loc_child_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1634
1635         sprintf(node_name, "%s", "offset_angle");
1636         sprintf(node_value, "%d", gps_measure_position_confirm->loc_info.measured_loc_info.ellipsoid_arc.offsetAngle);
1637         xmlNewChild(loc_child_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1638
1639         sprintf(node_name, "%s", "included_angle");
1640         sprintf(node_value, "%d", gps_measure_position_confirm->loc_info.measured_loc_info.ellipsoid_arc.includedAngle);
1641         xmlNewChild(loc_child_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1642
1643         sprintf(node_name, "%s", "confidence");
1644         sprintf(node_value, "%d", gps_measure_position_confirm->loc_info.measured_loc_info.ellipsoid_arc.confidence);
1645         xmlNewChild(loc_child_node, NULL, BAD_CAST node_name, BAD_CAST node_value);
1646
1647         // 3. assist data /msr_assist_data
1648         sprintf(node_name, "%s", "assist_data");
1649         node = xmlNewChild(root_node, NULL, BAD_CAST node_name, NULL);
1650         sprintf(node_name, "%s", "msr_assist_data");
1651         xmlNewChild(node, NULL, BAD_CAST node_name, NULL);
1652
1653         // Dump an XML document in memory and return the #xmlChar * and it's size in bytes
1654         xmlDocDumpMemory(doc, &xml, &size);
1655         dbg("xmlcontetnt:\n");
1656         dbg("%s", (char *) xml);
1657         // Free up all the structures used by a document, tree included.
1658         xmlFreeDoc(doc);
1659         xmlCleanupParser();
1660         return xml;
1661 }
1662
1663 static gboolean on_notification_gps_assist_data(CoreObject *o, const void *event_info, void *user_data)
1664 {
1665         int fd;
1666         gps_assist_data_noti_t gps_data_assist;
1667         char *node = NULL, *node_value = NULL;
1668         char *attribute = NULL, *attr_value = NULL;
1669         enum gps_assist_element_type node_type = -1, set_element_type = -1;
1670         int nav_model_node_count = -1;
1671         int alm_node_count = -1;
1672         int gps_tow_assist_count = -1;
1673         char *line = NULL, *pos = NULL;
1674         char *xml_line = NULL;
1675         gboolean ret;
1676         xmlTextReaderPtr reader;
1677         gboolean _gps_assist_data = FALSE, gps_tow_assist = FALSE;
1678         gboolean ephem_and_clock = FALSE, alm_elem = FALSE;
1679
1680         dbg("enter");
1681
1682 /*
1683     Example:GPS assist XML data will be in below format.
1684 ================================================================================================================================
1685     +CPOSR:<?xml version="1.0" encoding="UTF-8"?>
1686     <pos xsi:noNamespaceSchemaLocation="pos.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1687     <assist_data>
1688     <GPS_assist>
1689         <ref_time>
1690             <GPS_time> <> <\>..<\GPS_time> <GPS_TOW_assist*> <> <\> ..<\GPS_TOW_assist>
1691         </ref_time>
1692
1693         <location_parameters>
1694             <shape_data> <ellipsoid_point_alt_uncertellipse> </coordinate> <> <\>...</coordinate> <altitude> <\altitude>
1695              <uncert_semi_major> </uncert_semi_major> <uncert_semi_minor> </uncert_semi_minor> <orient_major> </orient_major> <confidence> </confidence>
1696             <uncert_alt> </uncert_alt>  </ellipsoid_point_alt_uncertellipse> </shape_data>
1697         </location_parameters>
1698
1699         <DGPS_corrections>
1700             <sat_id> </sat_id> <IODE> </IODE> <UDRE></UDRE> <PRC></PRC> <RRC></RRC>
1701         </DGPS_corrections>
1702
1703         <nav_model_elem*>
1704             <sat_id> </sat_id> <sat_status literal="xx"></sat_status>
1705             <ephem_and_clock?> <l2_code></l2_code> <> <\> .. ..  <\ephem_and_clock>
1706         </nav_model_elem>
1707
1708         <ionospheric_model> <alfa0> </alfa0> <alfa1> </alfa1> <alfa2> </alfa2>  <alfa3></alfa3>
1709             <beta0></beta0> <beta1></beta1> <beta2></beta2>  <beta3> </beta3>
1710         </ionospheric_model>
1711
1712         <UTC_model>
1713             <a1></a1><a0></a0><tot></tot><wnt></wnt> <dtls></dtls> <wnlsf></wnlsf> <dn></dn><dtlsf></dtlsf>
1714         </UTC_model>
1715         <almanac>
1716             <wna>0</wna> <alm_elem*> <> <\> ...<\alm_elem>
1717         </almanac>
1718
1719         <acqu_assist>
1720             <tow_msec></tow_msec>  <sat_info> <> <\> ...  <\sat_info>
1721         </acqu_assist>
1722
1723     </GPS_assist>
1724     </assist_data>
1725     </pos>
1726 ================================================================================================================================
1727 */
1728
1729         memset((void *) &gps_data_assist, 0x00, sizeof(gps_data_assist));
1730         xml_line = (char *) ((GSList *) event_info)->data;
1731
1732         if (g_str_has_prefix((char *) xml_line, "+CPOSR:")) {
1733                 dbg("notification line with prefix");
1734                 pos = (char *) xml_line + strlen("+CPOSR:");
1735         } else {
1736                 pos = (char *) xml_line;
1737         }
1738         line = g_strdup((char *) pos);
1739         // open file.
1740         if ((fd = open(FILE_NAME, O_WRONLY | O_CREAT | O_TRUNC | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, S_IRWXU)) == -1) {
1741                 dbg("Cannot open file\n");
1742                 g_free(line);
1743                 return FALSE;
1744         }
1745         // write gps xml data into file.
1746         if (write(fd, (const void *) line, strlen(line)) == -1) {
1747                 dbg("Cannot write into file\n");
1748                 close(fd);
1749                 g_free(line);
1750                 return FALSE;
1751         }
1752         // free the memory pointed to by line.
1753         g_free(line);
1754
1755         dbg("read xml file");
1756         reader = xmlReaderForFile(FILE_NAME, NULL, 0);
1757
1758         while (xmlTextReaderRead(reader)) {
1759                 // Get the node type of the current node
1760                 switch (xmlTextReaderNodeType(reader)) {
1761                 case XML_READER_TYPE_ELEMENT:
1762                 {
1763                         // Read the qualified name of the node.
1764                         node = (char *) xmlTextReaderConstName(reader);
1765                         dbg("Element: %s\n ", node);
1766                         if (node != NULL) {
1767                                 // check type of sub element of <GPS_assist>
1768                                 set_element_type = _get_element_type(node);
1769                                 if ((int) set_element_type != -1)     // ignore negative value as excepted element type not set.
1770                                         node_type = set_element_type;
1771
1772                                 dbg("xml node type  : %d", node_type);
1773
1774                                 // Check for position measurement data.
1775                                 if (strcmp(node, "pos_meas") == 0) {
1776                                         // Deallocate all the resources associated to the reader
1777                                         xmlFreeTextReader(reader);
1778                                         xmlCleanupParser();
1779                                         dbg("gps postion measurement notification ");
1780                                         // GPS position measurement notification.
1781                                         ret = on_notification_gps_measure_position_from_modem(o, FILE_NAME, user_data);
1782                                         // remove file.
1783                                         close(fd);
1784                                         if (access(FILE_NAME, F_OK) == 0) {
1785                                                 if (remove(FILE_NAME))
1786                                                         dbg("file removed");
1787                                         }
1788                                         return ret;
1789                                 }
1790
1791                                 // Moves the position of the current instance to the next attribute associated with the current node.
1792                                 while (xmlTextReaderMoveToNextAttribute(reader)) {
1793                                         // Read the qualified name of the node
1794                                         attribute = (char *) xmlTextReaderConstName(reader);
1795                                         dbg("attribute value - %s\n", attribute);
1796
1797                                         // Provides the text value of the node if present.
1798                                         attr_value = (char *) xmlTextReaderConstValue(reader);
1799                                         dbg("=\"%s\"\n", attr_value);
1800
1801                                         // Read attribute value of <nav_model_elem>
1802                                         if (node_type == NAV_MODEL_ELEM) {
1803                                                 if (strcmp(node, "sat_status") == 0 && strcmp(attribute, "literal") == 0) {
1804                                                         gps_data_assist.navi_model.NavigationSatInfo[nav_model_node_count].NavigationSatStatus = _modem_sat_status_info_2_tel_sat_info(attr_value);
1805                                                         dbg("navigation sat status of nav model element - %d\n", gps_data_assist.navi_model.NavigationSatInfo[nav_model_node_count].NavigationSatStatus);
1806                                                 }
1807                                         }
1808                                         // Read attribute value of <acqu_assist>
1809                                         else if (node_type == ACQU_ASSIST) {
1810                                                 if (strcmp(node, "dopl1_uncert") == 0 && strcmp(attribute, "literal") == 0) {
1811                                                         gps_data_assist.acq_assist.lcsAcquisitionSatInfo[0].dopplerUncertainty = _modem_acqa_assit_doppler_2_tel_doppler(attr_value);
1812                                                         dbg("doppler uncertainty of acqu assist data- %d", gps_data_assist.acq_assist.lcsAcquisitionSatInfo[0].dopplerUncertainty);
1813                                                 }
1814                                         }
1815                                 }        // end of attribute check.
1816
1817                                 // check GPS data is having GPS_assist data.
1818                                 if (strcmp(node, "GPS_assist") == 0) {
1819                                         _gps_assist_data = TRUE;
1820                                 }
1821
1822                                 if (_gps_assist_data == TRUE) {
1823                                         // number of GPS_TOW_assist elements.
1824                                         if (strcmp(node, "GPS_TOW_assist") == 0) {
1825                                                 gps_tow_assist_count++;
1826                                                 gps_tow_assist = TRUE;
1827                                         } else if (strcmp(node, "nav_model_elem") == 0) {
1828                                                 // number of nav_model_elem.
1829                                                 nav_model_node_count++;
1830                                         } else if (strcmp(node, "alm_elem") == 0) {
1831                                                 // number of alm_elem elements.
1832                                                 alm_node_count++;
1833                                                 dbg("alm_elem_count - %d", alm_node_count);
1834                                                 if (node_type == ALMANAC)
1835                                                         alm_elem = TRUE;
1836                                         } else if (strcmp(node, "ephem_and_clock") == 0 && node_type == NAV_MODEL_ELEM) {
1837                                                 ephem_and_clock = TRUE;
1838                                         }
1839                                 }
1840                         }
1841                         xmlTextReaderMoveToElement(reader);
1842                 }     // end of reading node type.
1843                 break;
1844
1845                 case XML_READER_TYPE_TEXT:
1846                 {
1847                         // Provides the text value of the node if present
1848                         node_value = (char *) xmlTextReaderConstValue(reader);
1849                         dbg("node_value: %s\n", node_value);
1850
1851                         if (node_value != NULL) {
1852                                 switch (node_type) {
1853                                 case REF_TIME:
1854                                         _parse_ref_time_gps_elements(node, node_value, &gps_data_assist, gps_tow_assist, gps_tow_assist_count);
1855                                         break;
1856
1857                                 case LOCATION_PARM:
1858                                         _parse_location_parameters(node, node_value, &gps_data_assist);
1859                                         break;
1860
1861                                 case DGPS_CORRECTION:
1862                                         _parse_dgps_correction_gps_elements(node, node_value, &gps_data_assist);
1863                                         break;
1864
1865                                 case NAV_MODEL_ELEM:
1866                                         _parse_nav_model_gps_elements(node, node_value, &gps_data_assist, ephem_and_clock, nav_model_node_count);
1867                                         break;
1868
1869                                 case IONOSPHERIC_MODEL:
1870                                         _parse_ionospheric_model_gps_elements(node, node_value, &gps_data_assist);
1871                                         break;
1872
1873                                 case UTC_MODEL:
1874                                         _parse_utc_model_gps_elements(node, node_value, &gps_data_assist);
1875                                         break;
1876
1877                                 case ALMANAC:
1878                                         _parse_almanc_model_gps_elements(node, node_value, &gps_data_assist, alm_elem, alm_node_count);
1879                                         break;
1880
1881                                 case ACQU_ASSIST:
1882                                         _parse_acqu_assist_gps_elements(node, node_value, &gps_data_assist);
1883                                         break;
1884
1885                                 default:
1886                                         dbg("invalid element");
1887                                 }
1888                         }
1889                 }     // end of reading node value.
1890                 break;
1891                 }
1892         } // end of parsing.
1893
1894         // Deallocate all the resources associated to the reader
1895         xmlFreeTextReader(reader);
1896         xmlCleanupParser();
1897
1898         // remove xml file.
1899         close(fd);
1900         if (access(FILE_NAME, F_OK) == 0) {
1901                 if (remove(FILE_NAME))
1902                         dbg("file removed");
1903         }
1904
1905         tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
1906                                                                    o, TNOTI_GPS_ASSIST_DATA, sizeof(gps_data_assist), &gps_data_assist);
1907         return TRUE;
1908 }
1909
1910 static gboolean on_notification_gps_measure_position_from_modem(CoreObject *o, char *file_name, void *user_data)
1911 {
1912         char *node = NULL, *node_value = NULL;
1913         char *attribute = NULL;
1914         char *attr_value = NULL;
1915         gps_measure_position_indi_t gps_measure_position_indi;
1916         gboolean rep_quant = FALSE;
1917         xmlTextReaderPtr reader;
1918
1919         memset(&gps_measure_position_indi, 0x00, sizeof(gps_measure_position_indi));
1920         reader = xmlReaderForFile(file_name, NULL, 0);
1921
1922         while (xmlTextReaderRead(reader)) {
1923                 switch (xmlTextReaderNodeType(reader)) {
1924                 case XML_READER_TYPE_ELEMENT:
1925                 {
1926                         node = (char *) xmlTextReaderConstName(reader);
1927                         dbg("Element: %s", node);
1928                         if (node != NULL) {
1929                                 // Read attribute value.
1930                                 while (xmlTextReaderMoveToNextAttribute(reader)) {
1931                                         attribute = (char *) xmlTextReaderConstName(reader);
1932                                         dbg("Attribute value - %s\n", attribute);
1933                                         attr_value = (char *) xmlTextReaderConstValue(reader);
1934                                         dbg("=\"%s\"\n", attr_value);
1935
1936                                         if (strcmp(node, "mult_sets") == 0) {
1937                                                 if (strcmp(attribute, "literal") == 0) {
1938                                                         if (strcmp(attr_value, "one") == 0)
1939                                                                 gps_measure_position_indi.use_multi_sets = GPS_MULTIPLESETS_ONESET;
1940                                                         else if (strcmp(attr_value, "multiple") == 0)
1941                                                                 gps_measure_position_indi.use_multi_sets = GPS_MULTIPLESETS_MULTIPLESETS;
1942                                                 }
1943                                                 dbg("gps_measure_position_indi.use_multi_sets - 0x%x\n", gps_measure_position_indi.use_multi_sets);
1944                                         } else if (strcmp(node, "rep_quant") == 0) {
1945                                                 rep_quant = TRUE;
1946                                                 if (strcmp(attribute, "addl_assist_data_req") == 0) {
1947                                                         if (strcmp(attr_value, "true") == 0)
1948                                                                 gps_measure_position_indi.add_assist_req = GPS_ADDITIONAL_ASSISREQ_REQ;
1949                                                         else
1950                                                                 gps_measure_position_indi.add_assist_req = GPS_ADDITIONAL_ASSISREQ_NOT_REQ;
1951                                                 } else if (strcmp(attribute, "gps_timing_of_cell_wanted") == 0) {
1952                                                         if (strcmp(attr_value, "true") == 0)
1953                                                                 gps_measure_position_indi.cell_timing_wnt = GPS_CELLTIMING_WANTED;
1954                                                         else
1955                                                                 gps_measure_position_indi.cell_timing_wnt = GPS_CELLTIMING_NOT_WANTED;
1956                                                 }
1957                                         }
1958                                 }        // end of attribute check
1959
1960                                 if (strcmp(node, "ms_assisted") == 0) {
1961                                         gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_ASSISTED;
1962                                 } else if (strcmp(node, "ms_assisted_no_accuracy") == 0) {
1963                                         gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_ASSISTED;
1964                                 } else if (strcmp(node, "ms_based") == 0) {
1965                                         gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_BASED;
1966                                 } else if (strcmp(node, "ms_based_pref") == 0) {
1967                                         gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_BASED_PREF;
1968                                 } else if (strcmp(node, "ms_assisted_pref") == 0) {
1969                                         gps_measure_position_indi.method_type = GPS_METHODTYPE_MS_ASSISTED_PREF;
1970                                 }
1971                         }
1972                         xmlTextReaderMoveToElement(reader);
1973                 }
1974                 break;
1975
1976                 case XML_READER_TYPE_TEXT:
1977                 {
1978                         node_value = (char *) xmlTextReaderConstValue(reader);
1979                         dbg("element-value: %s", node_value);
1980                         if (node_value != NULL) {
1981                                 if (strcmp(node, "resp_time_seconds") == 0) {
1982                                         gps_measure_position_indi.rsp_time = *node_value;
1983                                         dbg("gps_measure_position_indi.rsp_time - 0x%x", gps_measure_position_indi.rsp_time);
1984                                 }
1985                                 if (rep_quant == TRUE) {
1986                                         if (strcmp(node, "hor_acc") == 0)
1987                                                 gps_measure_position_indi.accuracy.horizontalAccuracy = *node_value;
1988                                         else if (strcmp(node, "vert_acc") == 0)
1989                                                 gps_measure_position_indi.accuracy.vertcalAccuracy = *node_value;
1990                                 }
1991                         }
1992                 }
1993                 break;
1994                 }
1995         }
1996         xmlFreeTextReader(reader);
1997         xmlCleanupParser();
1998
1999         tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
2000                                                                    o, TNOTI_GPS_MEASURE_POSITION, sizeof(gps_measure_position_indi), &gps_measure_position_indi);
2001         return TRUE;
2002 }
2003
2004
2005 // CONFIRMATION
2006 static void on_confirmation_gps_message_send(TcorePending *p, gboolean result, void *user_data)
2007 {
2008         dbg("Entry");
2009
2010         if (result == FALSE) {  // Fail
2011                 dbg("SEND FAIL");
2012         } else {
2013                 dbg("SEND OK");
2014         }
2015
2016         dbg("Exit");
2017         return;
2018 }
2019
2020 static gboolean on_notification_reset_assist_data(CoreObject *o, const void *event_info, void *user_data)
2021 {
2022         dbg("enter!\n");
2023         tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)),
2024                                                                    o, TNOTI_GPS_RESET_ASSIST_DATA, 0, NULL);
2025
2026         return TRUE;
2027 }
2028 static void on_confirmation_gps_measure_position(TcorePending *p, int data_len, const void *data, void *user_data)
2029 {
2030         //GPS server does not except confirmation for GPS measure position request.
2031         dbg("enter");
2032
2033         dbg("exit");
2034 }
2035
2036 static TReturn gps_confirm_measure_pos(CoreObject *o, UserRequest *ur)
2037 {
2038         char *raw_str = NULL;
2039         char *cmd_str = NULL;
2040         TcorePending *pending = NULL;
2041         TcoreATRequest *req = NULL;
2042         TcoreHal *hal = NULL;
2043         gboolean ret = FALSE;
2044         xmlChar *xml = NULL;
2045         unsigned char *data = NULL;
2046         unsigned int data_len;
2047         gps_measure_position_confirm_t gps_measure_pos_confirm;
2048
2049         dbg("enter!");
2050         if (!o || !ur)
2051                 return TCORE_RETURN_EINVAL;
2052
2053         data = (unsigned char *) tcore_user_request_ref_data(ur, &data_len);
2054         memcpy(&gps_measure_pos_confirm, data, data_len);
2055
2056         // make confirm measure postion request in xml format.
2057         xml = _generate_confirm_measure_pos_xml_text(&gps_measure_pos_confirm);
2058         if (!xml) {
2059                 err("xml text generation failed");
2060                 return TCORE_RETURN_EINVAL;
2061         }
2062
2063         // AT+CPOS<cr>text is entered<ctrl-z/esc>
2064         raw_str = g_strdup_printf("AT+CPOS%s", "\r");
2065         cmd_str = g_strdup_printf("%s%s\x1A", raw_str, xml);
2066
2067         dbg("command string : %s", cmd_str);
2068         pending = tcore_pending_new(o, 0);
2069         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
2070         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
2071         tcore_pending_set_request_data(pending, strlen(cmd_str), req);
2072         tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
2073         tcore_pending_set_send_callback(pending, on_confirmation_gps_message_send, NULL);
2074         tcore_pending_set_response_callback(pending, on_confirmation_gps_measure_position, NULL);
2075         tcore_pending_link_user_request(pending, ur);
2076
2077         // HAL
2078         hal = tcore_object_get_hal(o);
2079         // Send request to HAL
2080         ret = tcore_hal_send_request(hal, pending);
2081         if (TCORE_RETURN_SUCCESS != ret) {
2082                 err("Request send failed");
2083                 ret = FALSE;
2084         }
2085
2086         dbg("exit");
2087         g_free(raw_str);
2088         g_free(cmd_str);
2089         xmlFree(xml);
2090         return ret;
2091 }
2092
2093 static struct tcore_gps_operations gps_ops = {
2094         .confirm_measure_pos = gps_confirm_measure_pos,
2095 };
2096
2097 gboolean s_gps_init(TcorePlugin *cp, CoreObject *co_gps)
2098 {
2099         dbg("Enter");
2100
2101         tcore_gps_override_ops(co_gps, &gps_ops);
2102
2103         tcore_object_override_callback(co_gps, "+CPOSR", on_notification_gps_assist_data, NULL);
2104         tcore_object_override_callback(co_gps, "+XCPOSR", on_notification_reset_assist_data, NULL);
2105
2106         dbg("Exit");
2107
2108         return TRUE;
2109 }
2110
2111 void s_gps_exit(TcorePlugin *cp, CoreObject *co_gps)
2112 {
2113         dbg("Exit");
2114 }