Files
2026-09-22 09:38:26 +08:00

317 lines
9.8 KiB
C

/*
* 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;
}
}