From 90c312484f9ff1fcf22f1e12e65fd0a62ec2c163 Mon Sep 17 00:00:00 2001 From: Antara Borwankar Date: Fri, 7 Jun 2019 11:17:52 +0530 Subject: [PATCH] netmon: adding get functionality for neighbouring cell information Handled the get neighbouring cell information function which returns an array of signal strength of all neighbouring cells. --- src/netmon.c | 403 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 259 insertions(+), 144 deletions(-) diff --git a/src/netmon.c b/src/netmon.c index 6c19df52..9eacb3ca 100644 --- a/src/netmon.c +++ b/src/netmon.c @@ -50,6 +50,8 @@ struct ofono_netmon { const struct ofono_netmon_driver *driver; DBusMessage *pending; DBusMessage *reply; + DBusMessageIter iter; + DBusMessageIter arr; void *driver_data; struct ofono_atom *atom; struct netmon_agent *agent; @@ -69,6 +71,156 @@ static const char *cell_type_to_tech_name(enum ofono_netmon_cell_type type) return NULL; } +static void netmon_cell_info_dict_append(DBusMessageIter *dict, + va_list *arglist, int info_type) +{ + char *mcc; + char *mnc; + int intval; + enum ofono_netmon_info next_info_type = info_type; + + while (next_info_type != OFONO_NETMON_INFO_INVALID) { + switch (next_info_type) { + case OFONO_NETMON_INFO_MCC: + mcc = va_arg(*arglist, char *); + + if (mcc && strlen(mcc)) + ofono_dbus_dict_append(dict, + "MobileCountryCode", + DBUS_TYPE_STRING, &mcc); + break; + + case OFONO_NETMON_INFO_MNC: + mnc = va_arg(*arglist, char *); + + if (mnc && strlen(mnc)) + ofono_dbus_dict_append(dict, + "MobileNetworkCode", + DBUS_TYPE_STRING, &mnc); + break; + + case OFONO_NETMON_INFO_LAC: + intval = va_arg(*arglist, int); + + CELL_INFO_DICT_APPEND(dict, "LocationAreaCode", + intval, uint16_t, DBUS_TYPE_UINT16); + break; + + case OFONO_NETMON_INFO_CI: + intval = va_arg(*arglist, int); + + CELL_INFO_DICT_APPEND(dict, "CellId", + intval, uint32_t, DBUS_TYPE_UINT32); + break; + + case OFONO_NETMON_INFO_ARFCN: + intval = va_arg(*arglist, int); + + CELL_INFO_DICT_APPEND(dict, "ARFCN", + intval, uint16_t, DBUS_TYPE_UINT16); + break; + + case OFONO_NETMON_INFO_BSIC: + intval = va_arg(*arglist, int); + + CELL_INFO_DICT_APPEND(dict, "BSIC", + intval, uint8_t, DBUS_TYPE_BYTE); + break; + + case OFONO_NETMON_INFO_RXLEV: + intval = va_arg(*arglist, int); + + CELL_INFO_DICT_APPEND(dict, "ReceivedSignalStrength", + intval, uint8_t, DBUS_TYPE_BYTE); + break; + + case OFONO_NETMON_INFO_TIMING_ADVANCE: + intval = va_arg(*arglist, int); + + CELL_INFO_DICT_APPEND(dict, "TimingAdvance", + intval, uint8_t, DBUS_TYPE_BYTE); + break; + + case OFONO_NETMON_INFO_PSC: + intval = va_arg(*arglist, int); + + CELL_INFO_DICT_APPEND(dict, "PrimaryScramblingCode", + intval, uint16_t, DBUS_TYPE_UINT16); + break; + + case OFONO_NETMON_INFO_BER: + intval = va_arg(*arglist, int); + + CELL_INFO_DICT_APPEND(dict, "BitErrorRate", + intval, uint8_t, DBUS_TYPE_BYTE); + break; + + case OFONO_NETMON_INFO_RSSI: + intval = va_arg(*arglist, int); + + CELL_INFO_DICT_APPEND(dict, "Strength", + intval, uint8_t, DBUS_TYPE_BYTE); + break; + + case OFONO_NETMON_INFO_RSCP: + intval = va_arg(*arglist, int); + + CELL_INFO_DICT_APPEND(dict, "ReceivedSignalCodePower", + intval, uint8_t, DBUS_TYPE_BYTE); + break; + + case OFONO_NETMON_INFO_ECN0: + intval = va_arg(*arglist, int); + + CELL_INFO_DICT_APPEND(dict, "ReceivedEnergyRatio", + intval, uint8_t, DBUS_TYPE_BYTE); + break; + + case OFONO_NETMON_INFO_RSRQ: + intval = va_arg(*arglist, int); + + CELL_INFO_DICT_APPEND(dict, + "ReferenceSignalReceivedQuality", + intval, uint8_t, DBUS_TYPE_BYTE); + break; + + case OFONO_NETMON_INFO_RSRP: + intval = va_arg(*arglist, int); + + CELL_INFO_DICT_APPEND(dict, + "ReferenceSignalReceivedPower", + intval, uint8_t, DBUS_TYPE_BYTE); + break; + + case OFONO_NETMON_INFO_EARFCN: + intval = va_arg(*arglist, int); + + CELL_INFO_DICT_APPEND(dict, "EARFCN", + intval, uint16_t, DBUS_TYPE_UINT16); + break; + + case OFONO_NETMON_INFO_EBAND: + intval = va_arg(*arglist, int); + + CELL_INFO_DICT_APPEND(dict, "EBand", + intval, uint8_t, DBUS_TYPE_BYTE); + break; + + case OFONO_NETMON_INFO_CQI: + intval = va_arg(*arglist, int); + + CELL_INFO_DICT_APPEND(dict, "ChannelQualityIndicator", + intval, uint8_t, DBUS_TYPE_BYTE); + break; + + case OFONO_NETMON_INFO_INVALID: + break; + } + + next_info_type = va_arg(*arglist, int); + } +} + void ofono_netmon_serving_cell_notify(struct ofono_netmon *netmon, enum ofono_netmon_cell_type type, int info_type, ...) @@ -77,11 +229,7 @@ void ofono_netmon_serving_cell_notify(struct ofono_netmon *netmon, DBusMessage *agent_notify = NULL; DBusMessageIter iter; DBusMessageIter dict; - enum ofono_netmon_info next_info_type = info_type; const char *technology = cell_type_to_tech_name(type); - char *mcc; - char *mnc; - int intval; if (netmon->pending != NULL) { netmon->reply = dbus_message_new_method_return(netmon->pending); @@ -106,146 +254,7 @@ void ofono_netmon_serving_cell_notify(struct ofono_netmon *netmon, ofono_dbus_dict_append(&dict, "Technology", DBUS_TYPE_STRING, &technology); - while (next_info_type != OFONO_NETMON_INFO_INVALID) { - switch (next_info_type) { - case OFONO_NETMON_INFO_MCC: - mcc = va_arg(arglist, char *); - - if (mcc && strlen(mcc)) - ofono_dbus_dict_append(&dict, - "MobileCountryCode", - DBUS_TYPE_STRING, &mcc); - break; - - case OFONO_NETMON_INFO_MNC: - mnc = va_arg(arglist, char *); - - if (mnc && strlen(mnc)) - ofono_dbus_dict_append(&dict, - "MobileNetworkCode", - DBUS_TYPE_STRING, &mnc); - break; - - case OFONO_NETMON_INFO_LAC: - intval = va_arg(arglist, int); - - CELL_INFO_DICT_APPEND(&dict, "LocationAreaCode", - intval, uint16_t, DBUS_TYPE_UINT16); - break; - - case OFONO_NETMON_INFO_CI: - intval = va_arg(arglist, int); - - CELL_INFO_DICT_APPEND(&dict, "CellId", - intval, uint32_t, DBUS_TYPE_UINT32); - break; - - case OFONO_NETMON_INFO_ARFCN: - intval = va_arg(arglist, int); - - CELL_INFO_DICT_APPEND(&dict, "ARFCN", - intval, uint16_t, DBUS_TYPE_UINT16); - break; - - case OFONO_NETMON_INFO_BSIC: - intval = va_arg(arglist, int); - - CELL_INFO_DICT_APPEND(&dict, "BSIC", - intval, uint8_t, DBUS_TYPE_BYTE); - break; - - case OFONO_NETMON_INFO_RXLEV: - intval = va_arg(arglist, int); - - CELL_INFO_DICT_APPEND(&dict, "ReceivedSignalStrength", - intval, uint8_t, DBUS_TYPE_BYTE); - break; - - case OFONO_NETMON_INFO_TIMING_ADVANCE: - intval = va_arg(arglist, int); - - CELL_INFO_DICT_APPEND(&dict, "TimingAdvance", - intval, uint8_t, DBUS_TYPE_BYTE); - break; - - case OFONO_NETMON_INFO_PSC: - intval = va_arg(arglist, int); - - CELL_INFO_DICT_APPEND(&dict, "PrimaryScramblingCode", - intval, uint16_t, DBUS_TYPE_UINT16); - break; - - case OFONO_NETMON_INFO_BER: - intval = va_arg(arglist, int); - - CELL_INFO_DICT_APPEND(&dict, "BitErrorRate", - intval, uint8_t, DBUS_TYPE_BYTE); - break; - - case OFONO_NETMON_INFO_RSSI: - intval = va_arg(arglist, int); - - CELL_INFO_DICT_APPEND(&dict, "Strength", - intval, uint8_t, DBUS_TYPE_BYTE); - break; - - case OFONO_NETMON_INFO_RSCP: - intval = va_arg(arglist, int); - - CELL_INFO_DICT_APPEND(&dict, "ReceivedSignalCodePower", - intval, uint8_t, DBUS_TYPE_BYTE); - break; - - case OFONO_NETMON_INFO_ECN0: - intval = va_arg(arglist, int); - - CELL_INFO_DICT_APPEND(&dict, "ReceivedEnergyRatio", - intval, uint8_t, DBUS_TYPE_BYTE); - break; - - case OFONO_NETMON_INFO_RSRQ: - intval = va_arg(arglist, int); - - CELL_INFO_DICT_APPEND(&dict, - "ReferenceSignalReceivedQuality", - intval, uint8_t, DBUS_TYPE_BYTE); - break; - - case OFONO_NETMON_INFO_RSRP: - intval = va_arg(arglist, int); - - CELL_INFO_DICT_APPEND(&dict, - "ReferenceSignalReceivedPower", - intval, uint8_t, DBUS_TYPE_BYTE); - break; - - case OFONO_NETMON_INFO_EARFCN: - intval = va_arg(arglist, int); - - CELL_INFO_DICT_APPEND(&dict, "EARFCN", - intval, uint16_t, DBUS_TYPE_UINT16); - break; - - case OFONO_NETMON_INFO_EBAND: - intval = va_arg(arglist, int); - - CELL_INFO_DICT_APPEND(&dict, "EBand", - intval, uint8_t, DBUS_TYPE_BYTE); - break; - - case OFONO_NETMON_INFO_CQI: - intval = va_arg(arglist, int); - - CELL_INFO_DICT_APPEND(&dict, "ChannelQualityIndicator", - intval, uint8_t, DBUS_TYPE_BYTE); - break; - - case OFONO_NETMON_INFO_INVALID: - break; - } - - next_info_type = va_arg(arglist, int); - } + netmon_cell_info_dict_append(&dict, &arglist, info_type); done: va_end(arglist); @@ -403,6 +412,109 @@ static DBusMessage *netmon_unregister_agent(DBusConnection *conn, return dbus_message_new_method_return(msg); } + +void ofono_netmon_neighbouring_cell_notify(struct ofono_netmon *netmon, + enum ofono_netmon_cell_type type, + int info_type, ...) +{ + va_list arglist; + DBusMessageIter dict; + DBusMessageIter strct; + const char *tech = cell_type_to_tech_name(type); + + if (netmon->pending == NULL) + return; + + if (!netmon->reply) { + netmon->reply = dbus_message_new_method_return(netmon->pending); + dbus_message_iter_init_append(netmon->reply, &netmon->iter); + + dbus_message_iter_open_container(&netmon->iter, DBUS_TYPE_ARRAY, + DBUS_STRUCT_BEGIN_CHAR_AS_STRING + DBUS_TYPE_ARRAY_AS_STRING + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING + DBUS_STRUCT_END_CHAR_AS_STRING, + &netmon->arr); + } + + tech = cell_type_to_tech_name(type); + + dbus_message_iter_open_container(&netmon->arr, DBUS_TYPE_STRUCT, + NULL, &strct); + dbus_message_iter_open_container(&strct, DBUS_TYPE_ARRAY, + OFONO_PROPERTIES_ARRAY_SIGNATURE, + &dict); + + va_start(arglist, info_type); + + if (tech == NULL) + goto done; + + ofono_dbus_dict_append(&dict, "Technology", + DBUS_TYPE_STRING, &tech); + + netmon_cell_info_dict_append(&dict, &arglist, info_type); + +done: + va_end(arglist); + + dbus_message_iter_close_container(&strct, &dict); + dbus_message_iter_close_container(&netmon->arr, &strct); +} + +static void neighbouring_cell_info_callback(const struct ofono_error *error, + void *data) +{ + struct ofono_netmon *netmon = data; + DBusMessage *reply = netmon->reply; + + DBG(""); + + if (error->type != OFONO_ERROR_TYPE_NO_ERROR) { + if (reply) + dbus_message_unref(reply); + + reply = __ofono_error_failed(netmon->pending); + } else if (!reply) { + DBusMessageIter iter; + DBusMessageIter dict; + + reply = dbus_message_new_method_return(netmon->pending); + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, + OFONO_PROPERTIES_ARRAY_SIGNATURE, + &dict); + dbus_message_iter_close_container(&iter, &dict); + } else { + dbus_message_iter_close_container(&netmon->iter, &netmon->arr); + } + + netmon->reply = NULL; + __ofono_dbus_pending_reply(&netmon->pending, reply); +} + +static DBusMessage *netmon_get_neighbouring_cell_info(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + struct ofono_netmon *netmon = data; + + if (!netmon->driver->neighbouring_cell_update) + return __ofono_error_not_implemented(msg); + + if (netmon->pending) + return __ofono_error_busy(msg); + + netmon->pending = dbus_message_ref(msg); + + netmon->driver->neighbouring_cell_update(netmon, + neighbouring_cell_info_callback, netmon); + + return NULL; +} + static const GDBusMethodTable netmon_methods[] = { { GDBUS_ASYNC_METHOD("GetServingCellInformation", NULL, GDBUS_ARGS({ "cellinfo", "a{sv}" }), @@ -413,6 +525,9 @@ static const GDBusMethodTable netmon_methods[] = { { GDBUS_METHOD("UnregisterAgent", GDBUS_ARGS({ "agent", "o" }), NULL, netmon_unregister_agent) }, + { GDBUS_ASYNC_METHOD("GetNeighbouringCellInformation", + NULL, GDBUS_ARGS({ "cellinfo", "a(a{sv})" }), + netmon_get_neighbouring_cell_info) }, { } };