+static void satellite_callback(GVariant *param, void *user_data)
+{
+ ModPassiveData *module = (ModPassiveData *)user_data;
+ g_return_if_fail(module);
+ g_return_if_fail(module->sat_cb);
+
+ guint idx;
+ guint used_idx;
+ guint *used_prn_array = NULL;
+ gboolean ret = FALSE;
+ int timestamp = 0, satellite_used = 0, satellite_visible = 0;
+
+ LocationSatellite *sat = NULL;
+ GVariant *used_prn = NULL;
+ GVariantIter *used_prn_iter = NULL;
+ GVariant *sat_info = NULL;
+ GVariantIter *sat_iter = NULL;
+ int prn = 0, elev = 0, azim = 0, snr = 0;
+
+ g_variant_get(param, "(iii@ai@a(iiii))", ×tamp, &satellite_used, &satellite_visible, &used_prn, &sat_info);
+ g_variant_get(used_prn, "ai", &used_prn_iter);
+ g_variant_get(sat_info, "a(iiii)", &sat_iter);
+ MOD_LOGD("timestamp [%d], satellite_used [%d], satellite_visible[%d]", timestamp, satellite_used, satellite_visible);
+ int tmp_prn = 0;
+ int num_of_used_prn = g_variant_iter_n_children(used_prn_iter);
+ if (num_of_used_prn > 0) {
+ used_prn_array = (guint *)g_new0(guint, num_of_used_prn);
+ for (idx = 0; idx < num_of_used_prn; idx++) {
+ ret = g_variant_iter_next(used_prn_iter, "i", &tmp_prn);
+ if (ret == FALSE)
+ break;
+ used_prn_array[idx] = tmp_prn;
+ }
+ }
+ sat = location_satellite_new(satellite_visible);
+
+ sat->timestamp = timestamp;
+ sat->num_of_sat_inview = satellite_visible;
+ sat->num_of_sat_used = satellite_used;
+
+ GVariant *tmp_var = NULL;
+ for (idx = 0; idx < satellite_visible; idx++) {
+ gboolean used = FALSE;
+ tmp_var = g_variant_iter_next_value(sat_iter);
+ g_variant_get(tmp_var, "(iiii)", &prn, &elev, &azim, &snr);
+ if (used_prn_array != NULL) {
+ for (used_idx = 0; used_idx < satellite_used; used_idx++) {
+ if (prn == used_prn_array[used_idx]) {
+ used = TRUE;
+ break;
+ }
+ }
+ }
+ location_satellite_set_satellite_details(sat, idx, prn, used, elev, azim, snr);
+ g_variant_unref(tmp_var);
+ }
+
+ module->sat_cb(TRUE, sat, module->userdata);
+ location_satellite_free(sat);
+ g_variant_iter_free(used_prn_iter);
+ g_variant_iter_free(sat_iter);
+ g_variant_unref(used_prn);
+ g_variant_unref(sat_info);
+
+ if (used_prn_array) {
+ g_free(used_prn_array);
+ used_prn_array = NULL;
+ }
+}
+
+static void position_callback(GVariant *param, void *user_data)
+{
+ ModPassiveData *module = (ModPassiveData *)user_data;
+ g_return_if_fail(module);
+ g_return_if_fail(module->pos_cb);
+
+ int method = 0, fields = 0 , timestamp = 0 , level = 0;
+ double latitude = 0.0, longitude = 0.0, altitude = 0.0, speed = 0.0, direction = 0.0, climb = 0.0, horizontal = 0.0, vertical = 0.0;
+ GVariant *accuracy = NULL;
+
+ g_variant_get(param, "(iiidddddd@(idd))", &method, &fields, ×tamp, &latitude, &longitude, &altitude, &speed, &direction, &climb, &accuracy);
+ g_variant_get(accuracy, "(idd)", &level, &horizontal, &vertical);
+
+ LocationPosition *pos = NULL;
+ LocationVelocity *vel = NULL;
+ LocationAccuracy *acc = NULL;
+
+ pos = location_position_new(timestamp, latitude, longitude, altitude, LOCATION_STATUS_3D_FIX);
+ vel = location_velocity_new(timestamp, speed, direction, climb);
+ acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_DETAILED, horizontal, vertical);
+
+ module->pos_cb(TRUE, pos, vel, acc, module->userdata);
+
+ location_position_free(pos);
+ location_velocity_free(vel);
+ location_accuracy_free(acc);
+ g_variant_unref(accuracy);
+}
+
+static void on_signal_callback(const gchar *sig, GVariant *param, gpointer user_data)
+{
+ if (!g_strcmp0(sig, "SatelliteChanged"))
+ satellite_callback(param, user_data);
+ else if (!g_strcmp0(sig, "PositionChanged"))
+ position_callback(param, user_data);
+ else
+ MOD_LOGD("Invaild signal[%s]", sig);
+}
+
+static int start(gpointer handle, guint pos_update_interval, LocModStatusCB status_cb, LocModPositionExtCB pos_cb, LocModSatelliteCB sat_cb, gpointer userdata)
+{
+ MOD_LOGD("start");
+ ModPassiveData *module = (ModPassiveData *) handle;
+ g_return_val_if_fail(module, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(pos_cb, LOCATION_ERROR_NOT_AVAILABLE);
+
+ module->pos_cb = pos_cb;
+ module->sat_cb = sat_cb;
+ module->userdata = userdata;
+
+ int ret = LBS_CLIENT_ERROR_NONE;
+ ret = lbs_client_create(LBS_CLIENT_METHOD_PASSIVE , &(module->lbs_client));
+ if (ret != LBS_CLIENT_ERROR_NONE || !module->lbs_client) {
+ MOD_LOGE("Fail to create lbs_client_h. Error[%d]", ret);
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+ MOD_LOGD("fused handle(%p) pos_cb(%p) user_data(%p)", module, module->pos_cb, module->userdata);
+
+ ret = lbs_client_start(module->lbs_client, UNNECESSARY_INTERVAL, LBS_CLIENT_LOCATION_CB | LBS_CLIENT_SATELLITE_CB, on_signal_callback, module);
+ if (ret != LBS_CLIENT_ERROR_NONE) {
+ if (ret == LBS_CLIENT_ERROR_ACCESS_DENIED) {
+ MOD_LOGE("Access denied[%d]", ret);
+ return LOCATION_ERROR_NOT_ALLOWED;
+ }
+ MOD_LOGE("Fail to start lbs_client_h. Error[%d]", ret);
+ lbs_client_destroy(module->lbs_client);
+ module->lbs_client = NULL;
+
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ return LOCATION_ERROR_NONE;
+}
+
+static int stop(gpointer handle)
+{
+ MOD_LOGD("stop");
+ ModPassiveData *module = (ModPassiveData *) handle;
+ g_return_val_if_fail(module, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(module->lbs_client, LOCATION_ERROR_NOT_AVAILABLE);
+
+ int ret = LBS_CLIENT_ERROR_NONE;
+
+ ret = lbs_client_stop(module->lbs_client, UNNECESSARY_INTERVAL);
+ MOD_LOGE("stop gps interval [%d]", UNNECESSARY_INTERVAL);
+ if (ret != LBS_CLIENT_ERROR_NONE) {
+ MOD_LOGE("Fail to stop. Error[%d]", ret);
+ lbs_client_destroy(module->lbs_client);
+ module->lbs_client = NULL;
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ ret = lbs_client_destroy(module->lbs_client);
+ if (ret != LBS_CLIENT_ERROR_NONE) {
+ MOD_LOGE("Fail to destroy. Error[%d]", ret);
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+ module->lbs_client = NULL;
+
+ module->pos_cb = NULL;
+ module->sat_cb = NULL;
+
+ return LOCATION_ERROR_NONE;
+}
+