Added netmon changes for xmm7modem driver to fetch neighbouring
cell information.
---
drivers/xmm7modem/netmon.c | 160 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 160 insertions(+)
diff --git a/drivers/xmm7modem/netmon.c b/drivers/xmm7modem/netmon.c
index ba70e2b..b9aac3e 100644
--- a/drivers/xmm7modem/netmon.c
+++ b/drivers/xmm7modem/netmon.c
@@ -205,6 +205,165 @@ static void xmm7modem_netmon_request_update(struct ofono_netmon
*netmon,
CALLBACK_WITH_FAILURE(cb, data);
}
+static void xmci_neighbouring_cell_cb
+ (gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ struct ofono_netmon *netmon = cbd->data;
+ ofono_netmon_cb_t cb = cbd->cb;
+ struct ofono_error error;
+ GAtResultIter iter;
+ int number;
+ int rxlev = -1;
+ int ber = -1;
+ int rscp = -1;
+ int rsrp = -1;
+ int ecn0 = -1;
+ int rsrq = -1;
+ int tech = -1;
+ int mcc = -1;
+ int mnc = -1;
+ int ci = -1;
+ GList *list = NULL;
+ struct ofono_netmon_neighbouring_cell *cell;
+ int list_size = 0;
+
+ DBG("ok %d", ok);
+
+ decode_at_error(&error, g_at_result_final_response(result));
+
+ if (!ok) {
+ cb(&error, cbd->data);
+ return;
+ }
+
+ g_at_result_iter_init(&iter, result);
+
+ while (g_at_result_iter_next(&iter, "+XMCI:")) {
+ if (!g_at_result_iter_next_number(&iter, &number))
+ break;
+
+ tech = xmm7modem_map_radio_access_technology(number);
+
+ switch (number) {
+ case XMCI_GSM_NEIGH_CELL:
+ /* skip <MCC>,<MNC>,<LAC>,<CI>,<BSIC> */
+ g_at_result_iter_next_number(&iter, &mcc);
+ g_at_result_iter_next_number(&iter, &mnc);
+ g_at_result_iter_skip_next(&iter);
+ g_at_result_iter_next_number(&iter, &ci);
+ g_at_result_iter_skip_next(&iter);
+
+ g_at_result_iter_next_number(&iter, &number);
+ rxlev = number != 99 ? number : rxlev;
+
+ g_at_result_iter_next_number(&iter, &number);
+ ber = number != 99 ? number : ber;
+
+ cell = g_new0(struct ofono_netmon_neighbouring_cell,
+ 1);
+ cell->cell_type = tech;
+ cell->mcc = mcc;
+ cell->mnc = mnc;
+ cell->cell_id = ci;
+ cell->cell_meas.gsm.rssi = rxlev;
+ cell->cell_meas.gsm.ber = ber;
+
+ list = g_list_append(list, cell);
+ break;
+ case XMCI_UMTS_NEIGH_CELL:
+ /*
+ * skip <MCC>,<MNC>,<LAC>,<CI><PSC>,<DLUARFNC>,
+ * <ULUARFCN>,<PATHLOSS>,<RSSI>
+ */
+ g_at_result_iter_next_number(&iter, &mcc);
+ g_at_result_iter_next_number(&iter, &mnc);
+ g_at_result_iter_skip_next(&iter);
+ g_at_result_iter_next_number(&iter, &ci);
+ g_at_result_iter_skip_next(&iter);
+ g_at_result_iter_skip_next(&iter);
+ g_at_result_iter_skip_next(&iter);
+ g_at_result_iter_skip_next(&iter);
+ g_at_result_iter_skip_next(&iter);
+
+ g_at_result_iter_next_number(&iter, &number);
+ rscp = number != 255 ? number : rscp;
+
+ g_at_result_iter_next_number(&iter, &number);
+ ecn0 = number != 255 ? number : ecn0;
+
+ cell = g_new0(struct ofono_netmon_neighbouring_cell,
+ 1);
+ cell->cell_type = tech;
+ cell->mcc = mcc;
+ cell->mnc = mnc;
+ cell->cell_id = ci;
+ cell->cell_meas.umts.rscp = rscp;
+ cell->cell_meas.umts.ecno = ecn0;
+
+ list = g_list_append(list, cell);
+ break;
+ case XMCI_LTE_NEIGH_CELL:
+ /*
+ * skip <MCC>,<MNC>,<TAC>,<CI>,<PCI>,<DLUARFNC>,
+ * <ULUARFCN>,<PATHLOSS_LTE>
+ */
+ g_at_result_iter_next_number(&iter, &mcc);
+ g_at_result_iter_next_number(&iter, &mnc);
+ g_at_result_iter_skip_next(&iter);
+ g_at_result_iter_next_number(&iter, &ci);
+ g_at_result_iter_skip_next(&iter);
+ g_at_result_iter_skip_next(&iter);
+ g_at_result_iter_skip_next(&iter);
+ g_at_result_iter_skip_next(&iter);
+
+ g_at_result_iter_next_number(&iter, &number);
+ rsrq = number != 255 ? number : rsrq;
+
+ g_at_result_iter_next_number(&iter, &number);
+ rsrp = number != 255 ? number : rsrp;
+
+ cell = g_new0(struct ofono_netmon_neighbouring_cell,
+ 1);
+ cell->cell_type = tech;
+ cell->mcc = mcc;
+ cell->mnc = mnc;
+ cell->cell_id = ci;
+ cell->cell_meas.lte.rsrq = rsrq;
+ cell->cell_meas.lte.rsrp = rsrp;
+
+ list = g_list_append(list, cell);
+ break;
+ default:
+ break;
+ }
+ }
+
+ list_size = g_list_length(list);
+
+ if(list_size)
+ ofono_netmon_neighbouring_cell_notify(netmon, list);
+
+ CALLBACK_WITH_SUCCESS(cb, cbd->data);
+ g_list_free(list);
+}
+
+static void xmm7modem_neighbouring_cell_update(struct ofono_netmon *netmon,
+ ofono_netmon_cb_t cb, void *data)
+{
+ struct netmon_driver_data *nmd = ofono_netmon_get_data(netmon);
+ struct cb_data *cbd = cb_data_new(cb, data);
+
+ DBG("xmm7modem netmon request neighbouring cell update");
+
+ if (g_at_chat_send(nmd->chat, "AT+XMCI=0", xmci_prefix,
+ xmci_neighbouring_cell_cb, cbd, g_free) > 0)
+ return;
+
+ g_free(cbd);
+ CALLBACK_WITH_FAILURE(cb, data);
+}
+
static gboolean ril_delayed_register(gpointer user_data)
{
struct ofono_netmon *netmon = user_data;
@@ -250,6 +409,7 @@ static const struct ofono_netmon_driver driver = {
.probe = xmm7modem_netmon_probe,
.remove = xmm7modem_netmon_remove,
.request_update = xmm7modem_netmon_request_update,
+ .neighbouring_cell_update = xmm7modem_neighbouring_cell_update,
};
void xmm_netmon_init(void)
--
1.9.1