/* * SPDX-FileCopyrightText: 2022 Unisoc (Shanghai) Technologies Co., Ltd. * * SPDX-License-Identifier: LicenseRef-Unisoc-General-1.0 */ #include "agps.h" uint32_t sim_request_flag = 0; void fetch_agps_connection(){ DBusMessage *msg_wifi; DBusMessage *msg_data; dh_querymethod_sync(DBUS_BUS_SYSTEM, NETCON_BUS_NAME, NETCON_BUS_PATH, NETCON_BUS_INTERFACE, "NetconGetWifiState", &msg_wifi, NULL, NULL, NULL); ALOGD("%s NetconGetWifiState.", __func__); if (msg_wifi == NULL) { ALOGE("%s msg_wifi is NULL", __func__); return; } if (dbus_message_get_type(msg_wifi) == DBUS_MESSAGE_TYPE_ERROR) { ALOGE("%s %s", __func__, dbus_message_get_error_name(msg_wifi)); return; } DBusMessageIter iter; int state = -1; if (!dbus_message_iter_init(msg_wifi, &iter)) { ALOGE("%s Message has no arguments!", __func__); } else if (DBUS_TYPE_INT32 != dbus_message_iter_get_arg_type(&iter)) { ALOGE("%s Message arguments type is error!", __func__); } else { dbus_message_iter_get_basic(&iter, &state); ALOGD("%s Got Reply receive:%d\n", __func__, state); } dbus_message_unref(msg_wifi); if(state == 0) { gnssmgt_agps_ril_updateNwState(1, 1, 0, "dummy-apn"); } else { int type_array[] = { DBUS_TYPE_INT32 }; dh_querymethod_sync(DBUS_BUS_SYSTEM, NETCON_BUS_NAME, NETCON_BUS_PATH, NETCON_BUS_INTERFACE, "NetconIsDataConnected", &msg_data, NULL, type_array, 1, 1); ALOGD("%s NetconIsDataConnected.", __func__); if (dbus_message_get_type(msg_data) == DBUS_MESSAGE_TYPE_ERROR) { ALOGE("%s %s", __func__, dbus_message_get_error_name(msg_data)); return -1; } DBusMessageIter iter; bool state = false; if (!dbus_message_iter_init(msg_data, &iter)) { ALOGE("%s Message has no arguments!", __func__); } else if (DBUS_TYPE_BOOLEAN != dbus_message_iter_get_arg_type(&iter)) { ALOGE("%s Message arguments type is error!", __func__); } else { dbus_message_iter_get_basic(&iter, &state); ALOGD("%s Got Reply receive:%d\n", __func__, state); } if(state ) { gnssmgt_agps_ril_updateNwState(1, 0, 0, NULL); gnssmgt_agps_openConn("default"); } } } void drop_agps_connection(){ ALOGD("%s called, do nothing here.", __func__); } void fetch_array_variant(DBusMessageIter *entry, int type, void *value) { DBusMessageIter variant, array; int i; dbus_message_iter_next(entry); dbus_message_iter_recurse(entry, &array); ALOGD("%s dbus_message_iter_get_element_count=%d", __func__, dbus_message_iter_get_element_count(&array)); if(dbus_message_iter_get_element_count(&array)) { ALOGD("%s dbus_message_iter_get_element_type=%d", __func__, dbus_message_iter_get_element_type(&array)); dbus_message_iter_recurse(&array, &variant); dbus_message_iter_get_basic(&variant, value); } } int dbus_sim_info_callback(DBusMessage* msg, DBusConnection* conn) { if (dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_ERROR) { ALOGE("%s %s", __func__, dbus_message_get_error_name(msg)); return -1; } DBusMessageIter iter; DBusMessageIter dict; DBusMessageIter entry; char* key; char* imsi; char* msisdn; dbus_message_iter_init(msg, &iter); dbus_message_iter_recurse(&iter, &dict); int count = 0; while(dbus_message_iter_has_next(&dict)) { dbus_message_iter_recurse(&dict, &entry); dbus_message_iter_get_basic(&entry, &key); if(strcmp(key, "SubscriberIdentity") == 0 ){ fetch_variant(&entry, DBUS_TYPE_STRING, &imsi); count++; } else if(strcmp(key, "SubscriberNumbers") == 0 ){ fetch_array_variant(&entry, DBUS_TYPE_STRING, &msisdn); count++; } if(count<2) { dbus_message_iter_next(&dict); } else { if(sim_request_flag & AGPS_RIL_REQUEST_SETID_IMSI) { gnssmgt_agps_ril_setSetID(AGPS_SETID_TYPE_IMSI, imsi); } else if(sim_request_flag & AGPS_RIL_REQUEST_SETID_MSISDN) { gnssmgt_agps_ril_setSetID(AGPS_SETID_TYPE_MSISDN, msisdn); } break; } } } int feed_agps_sim_info(uint32_t flags) { sim_request_flag = flags; if((AGPS_RIL_REQUEST_SETID_IMSI & flags) || (AGPS_RIL_REQUEST_SETID_MSISDN & flags)) { dh_querymethod(DBUS_BUS_SYSTEM, OFONO_BUS_NAME, OFONO_BUS_PATH, OFONO_BUS_SIMMGR_INTERFACE, "GetProperties", dbus_sim_info_callback, NULL); ALOGD("%s GetProperties.", __func__); return 0; } else { ALOGD("%s flag=%d not support", __func__, flags); return -1; } return 0; } void fetch_variant(DBusMessageIter *entry, int type, void *value) { char sig[2]; DBusMessageIter valueiter; dbus_message_iter_next(entry); dbus_message_iter_recurse(entry, &valueiter); dbus_message_iter_get_basic(&valueiter, value); } uint16_t get_cell_type_value(char* type) { if (strcmp(type, "nr") == 0) { return AGPS_REF_LOCATION_TYPE_NR_CELLID; } return AGPS_REF_LOCATION_TYPE_GSM_CELLID; } int dbus_cell_info_callback(DBusMessage* msg, DBusConnection* conn) { if (dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_ERROR) { ALOGE("%s %s", __func__, dbus_message_get_error_name(msg)); return -1; } AGpsRefLocation refLoc; DBusMessageIter iter; DBusMessageIter dict; DBusMessageIter entry; char* chrVal; char* key; dbus_message_iter_init(msg, &iter); dbus_message_iter_recurse(&iter, &dict); char* cell_type; uint16_t mcc = 0; uint16_t mnc = 0; uint16_t lac = 0; uint32_t cid = 0; uint64_t nr_cid = 0; uint32_t tac = 0; uint16_t pcid = 0; uint32_t arfcn_nr = 0; while(dbus_message_iter_has_next(&dict)) { dbus_message_iter_recurse(&dict, &entry); dbus_message_iter_get_basic(&entry, &key); ALOGD("%s: Key = %s", __func__, key); if (strcmp(key, "Technology") == 0) { fetch_variant(&entry, DBUS_TYPE_STRING, &cell_type); refLoc.type = get_cell_type_value(cell_type); ALOGD("%s: Cell type is %s, loaction cell type value is %d.", __func__, cell_type, refLoc.type); } else if (strcmp(key, "MobileCountryCode") == 0 ){ fetch_variant(&entry, DBUS_TYPE_STRING, &chrVal); mcc = atoi(chrVal); } else if (strcmp(key, "MobileNetworkCode") == 0 ){ fetch_variant(&entry, DBUS_TYPE_STRING, &chrVal); mnc = atoi(chrVal); } else if (strcmp(key, "LocationAreaCode") == 0 ){ fetch_variant(&entry, DBUS_TYPE_UINT16, &lac); } else if (strcmp(key, "CellId") == 0 ){ fetch_variant(&entry, DBUS_TYPE_UINT32, &cid); } else if (strcmp(key, "NRCellID") == 0) { fetch_variant(&entry, DBUS_TYPE_STRING, &chrVal); ALOGD("%s, NRCellID = %s", __func__, chrVal); // NR Cell Id is a hexadecimal number, witch is the uint64_t that uses %llX to covent // NrCellID string to hexadecimal if (sscanf(chrVal, "%llX", &nr_cid) < 0) { ALOGE("%s: Resolve NrCellId string to uint64_t failed!", __func__); } } else if (strcmp(key, "TrackingAreaCode") == 0) { fetch_variant(&entry, DBUS_TYPE_UINT32, &tac); } else if (strcmp(key, "PhysicalCellId") == 0) { fetch_variant(&entry, DBUS_TYPE_UINT32, &pcid); } else if (strcmp(key, "NRARFCN") == 0) { fetch_variant(&entry, DBUS_TYPE_UINT32, &arfcn_nr); } dbus_message_iter_next(&dict); } if (refLoc.type == AGPS_REF_LOCATION_TYPE_NR_CELLID) { refLoc.u.cellID_nr.mcc = mcc; refLoc.u.cellID_nr.mnc = mnc; refLoc.u.cellID_nr.cid = nr_cid; refLoc.u.cellID_nr.tac = tac; refLoc.u.cellID_nr.pcid = pcid; refLoc.u.cellID_nr.arfcn_nr = arfcn_nr; ALOGD("%s: MCC = %d, MNC = %d, CID = %llX, TAC = %d, PCID = %d, NR_ARFCN = %d", __func__, refLoc.u.cellID_nr.mcc, refLoc.u.cellID_nr.mnc, refLoc.u.cellID_nr.cid, refLoc.u.cellID_nr.tac, refLoc.u.cellID_nr.pcid, refLoc.u.cellID_nr.arfcn_nr); } else if (refLoc.type == AGPS_REF_LOCATION_TYPE_GSM_CELLID) { refLoc.u.cellID.type = AGPS_REF_LOCATION_TYPE_GSM_CELLID; refLoc.u.cellID.mcc = mcc; refLoc.u.cellID.mnc = mnc; refLoc.u.cellID.lac = lac; refLoc.u.cellID.cid = cid; ALOGD("%s: MCC = %d, MNC = %d, LAC = %d, CID = %d", __func__, refLoc.u.cellID.mcc, refLoc.u.cellID.mnc, refLoc.u.cellID.lac, refLoc.u.cellID.cid); } else { ALOGE("%s: Get refLoc type failed", __func__); return -1; } gnssmgt_agps_ril_setRefLoc(&refLoc, sizeof(AGpsRefLocation)); return 0; } int feed_agps_cell_info(uint32_t flags){ if(AGPS_RIL_REQUEST_REFLOC_CELLID & flags) { dh_querymethod(DBUS_BUS_SYSTEM, OFONO_BUS_NAME, OFONO_BUS_PATH, OFONO_BUS_NETMON_INTERFACE, "GetServingCellInformation", dbus_cell_info_callback, NULL); ALOGD("%s GetServingCellInformation.", __func__); return 0; } else { ALOGD("%s flag=%d not support", __func__, flags); return -1; } }