From d647f8d89f68c286f56a6504678558f032da53cb Mon Sep 17 00:00:00 2001 From: Oskari Lemmela Date: Sun, 25 Mar 2018 19:23:06 +0300 Subject: [PATCH] uqmi: add more diagnostics commands Useful diagnostic commands for measuring connection info. Implemented cell location, carrier aggregation and MIMO chain info in easily parsable json format. Compressed package size increased by 9kB. Signed-off-by: Oskari Lemmela --- commands-nas.c | 663 ++++++++++++++++++++++++++++++++++++++++++++++++- commands-nas.h | 10 +- 2 files changed, 671 insertions(+), 2 deletions(-) diff --git a/commands-nas.c b/commands-nas.c index 1f7445d..123ba63 100644 --- a/commands-nas.c +++ b/commands-nas.c @@ -21,12 +21,78 @@ #include "qmi-message.h" +static struct qmi_nas_get_tx_rx_info_request tx_rx_req; static struct qmi_nas_set_system_selection_preference_request sel_req; static struct { bool mcc_is_set; bool mnc_is_set; } plmn_code_flag; +static void +print_earfcn_info(uint32_t earfcn) +{ + /* https://www.sqimway.com/lte_band.php */ + static const struct { + uint32_t min; + uint32_t max; + uint16_t band; + uint16_t freq; + const char *duplex; + } earfcn_ranges[] = { + { 0, 599, 1, 2100, "FDD" }, + { 600, 1199, 2, 1800, "FDD" }, + { 1200, 1949, 3, 1800, "FDD" }, + { 1950, 2399, 4, 1700, "FDD" }, + { 2400, 2649, 5, 850, "FDD" }, + { 2650, 2749, 6, 800, "FDD" }, + { 2750, 3449, 7, 2600, "FDD" }, + { 3450, 3799, 8, 900, "FDD" }, + { 3800, 4149, 9, 1800, "FDD" }, + { 4150, 4749, 10, 1700, "FDD" }, + { 4750, 4999, 11, 1500, "FDD" }, + { 5000, 5179, 12, 700, "FDD" }, + { 5180, 5279, 13, 700, "FDD" }, + { 5280, 5379, 14, 700, "FDD" }, + { 5730, 5849, 17, 700, "FDD" }, + { 5850, 5999, 18, 850, "FDD" }, + { 6000, 6149, 19, 850, "FDD" }, + { 6150, 6449, 20, 800, "FDD" }, + { 6450, 6599, 21, 1500, "FDD" }, + { 6600, 7399, 22, 3500, "FDD" }, + { 7500, 7699, 23, 2000, "FDD" }, + { 7700, 8039, 24, 1600, "FDD" }, + { 8040, 8689, 25, 1900, "FDD" }, + { 8690, 9039, 26, 850, "FDD" }, + { 9040, 9209, 27, 800, "FDD" }, + { 9210, 9659, 28, 700, "FDD" }, + { 9660, 9769, 29, 700, "SDL" }, + { 9770, 9869, 30, 2300, "FDD" }, + { 9870, 9919, 31, 450, "FDD" }, + { 9920, 10359, 32, 1500, "SDL" }, + { 36000, 36199, 33, 1900, "TDD" }, + { 36200, 36349, 34, 2000, "TDD" }, + { 36350, 36949, 35, 1900, "TDD" }, + { 36950, 37549, 36, 1900, "TDD" }, + { 37550, 37749, 37, 1900, "TDD" }, + { 37750, 38249, 38, 2600, "TDD" }, + { 38250, 38649, 39, 1900, "TDD" }, + { 38650, 39649, 40, 2300, "TDD" }, + { 39650, 41589, 41, 2500, "TDD" }, + { 41590, 43589, 42, 3500, "TDD" }, + { 43590, 45589, 43, 3700, "TDD" }, + { 45590, 46589, 44, 700, "TDD" }, + }; + + for (int i = 0; i < sizeof(earfcn_ranges); i++) { + if (earfcn <= earfcn_ranges[i].max && earfcn >= earfcn_ranges[i].min) { + blobmsg_add_u32(&status, "band", earfcn_ranges[i].band); + blobmsg_add_u32(&status, "frequency", earfcn_ranges[i].freq); + blobmsg_add_string(&status, "duplex", earfcn_ranges[i].duplex); + return; + } + } +} + #define cmd_nas_do_set_system_selection_cb no_cb static enum qmi_cmd_result cmd_nas_do_set_system_selection_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg) @@ -230,7 +296,7 @@ cmd_nas_get_signal_info_cb(struct qmi_dev *qmi, struct qmi_request *req, struct blobmsg_add_u32(&status, "rssi", (int32_t) res.data.lte_signal_strength.rssi); blobmsg_add_u32(&status, "rsrq", (int32_t) res.data.lte_signal_strength.rsrq); blobmsg_add_u32(&status, "rsrp", (int32_t) res.data.lte_signal_strength.rsrp); - blobmsg_add_u32(&status, "snr", (int32_t) res.data.lte_signal_strength.snr); + blobmsg_add_double(&status, "snr", (double) res.data.lte_signal_strength.snr*0.1); } if (res.set.tdma_signal_strength) { @@ -241,6 +307,601 @@ cmd_nas_get_signal_info_cb(struct qmi_dev *qmi, struct qmi_request *req, struct blobmsg_close_table(&status, c); } +static void +print_system_info(uint8_t svc_status, uint8_t tsvc_status, bool preferred, bool system_info, + bool domain_valid, uint8_t domain, + bool service_cap_valid, uint8_t service_cap, + bool roaming_status_valid, uint8_t roaming_status, + bool forbidden_valid, bool forbidden, + bool lac_valid, uint16_t lac, + bool cid_valid, uint32_t cid, + bool network_id_valid, char *mcc, char *mnc) +{ + static const char *map_service[] = { + [QMI_NAS_SERVICE_STATUS_NONE] = "none", + [QMI_NAS_SERVICE_STATUS_LIMITED] = "limited", + [QMI_NAS_SERVICE_STATUS_AVAILABLE] = "available", + [QMI_NAS_SERVICE_STATUS_LIMITED_REGIONAL] = "limited regional", + [QMI_NAS_SERVICE_STATUS_POWER_SAVE] = "power save", + }; + + static const char *map_roaming[] = { + [QMI_NAS_ROAMING_STATUS_OFF] = "off", + [QMI_NAS_ROAMING_STATUS_ON] = "on", + [QMI_NAS_ROAMING_STATUS_BLINK] = "blink", + [QMI_NAS_ROAMING_STATUS_OUT_OF_NEIGHBORHOOD] = "out of neighborhood", + [QMI_NAS_ROAMING_STATUS_OUT_OF_BUILDING] = "out of building", + [QMI_NAS_ROAMING_STATUS_PREFERRED_SYSTEM] = "preferred system", + [QMI_NAS_ROAMING_STATUS_AVAILABLE_SYSTEM] = "available system", + [QMI_NAS_ROAMING_STATUS_ALLIANCE_PARTNER] = "alliance partner", + [QMI_NAS_ROAMING_STATUS_PREMIUM_PARTNER] = "premium partner", + [QMI_NAS_ROAMING_STATUS_FULL_SERVICE] = "full service", + [QMI_NAS_ROAMING_STATUS_PARTIAL_SERVICE] = "partial service", + [QMI_NAS_ROAMING_STATUS_BANNER_ON] = "banner on", + [QMI_NAS_ROAMING_STATUS_BANNER_OFF] = "banner off", + }; + + static const char *map_network[] = { + [QMI_NAS_NETWORK_SERVICE_DOMAIN_NONE] = "none", + [QMI_NAS_NETWORK_SERVICE_DOMAIN_CS] = "cs", + [QMI_NAS_NETWORK_SERVICE_DOMAIN_PS] = "ps", + [QMI_NAS_NETWORK_SERVICE_DOMAIN_CS_PS] = "cs-ps", + [QMI_NAS_NETWORK_SERVICE_DOMAIN_UNKNOWN] = "unknown", + }; + + blobmsg_add_string(&status, "service_status", map_service[svc_status]); + blobmsg_add_string(&status, "true_service_status", map_service[tsvc_status]); + blobmsg_add_u8(&status, "preferred_data_path", preferred); + + if (system_info) { + if (domain_valid) + blobmsg_add_string(&status, "domain", map_network[domain]); + if (service_cap_valid) + blobmsg_add_string(&status, "service", map_network[service_cap]); + if (roaming_status_valid) + blobmsg_add_string(&status, "roaming_status", map_roaming[roaming_status]); + if (forbidden_valid) + blobmsg_add_u8(&status, "forbidden", forbidden); + if (lac_valid) + blobmsg_add_u32(&status, "location_area_code", (int32_t) lac); + if (cid_valid) + blobmsg_add_u32(&status, "cell_id", (int32_t) cid); + if (network_id_valid) { + blobmsg_add_string(&status, "mcc", mcc); + if ((uint8_t)mnc[2] == 255) + mnc[2] = 0; + blobmsg_add_string(&status, "mnc", mnc); + } + } +} + +static void +cmd_nas_get_system_info_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg) +{ + static const char *cell_status[] = { + [QMI_NAS_CELL_ACCESS_STATUS_NORMAL_ONLY] = "normal", + [QMI_NAS_CELL_ACCESS_STATUS_EMERGENCY_ONLY] = "emergency", + [QMI_NAS_CELL_ACCESS_STATUS_NO_CALLS] = "no calls", + [QMI_NAS_CELL_ACCESS_STATUS_ALL_CALLS] = "all calls", + [QMI_NAS_CELL_ACCESS_STATUS_UNKNOWN] = "unknown", + }; + + struct qmi_nas_get_system_info_response res; + void *c, *t; + + qmi_parse_nas_get_system_info_response(msg, &res); + t = blobmsg_open_table(&status, NULL); + if (res.set.gsm_service_status) { + c = blobmsg_open_table(&status, "gsm"); + print_system_info(res.data.gsm_service_status.service_status, + res.data.gsm_service_status.true_service_status, + res.data.gsm_service_status.preferred_data_path, + res.set.gsm_system_info_v2, + res.data.gsm_system_info_v2.domain_valid, + res.data.gsm_system_info_v2.domain, + res.data.gsm_system_info_v2.service_capability_valid, + res.data.gsm_system_info_v2.service_capability, + res.data.gsm_system_info_v2.roaming_status_valid, + res.data.gsm_system_info_v2.roaming_status, + res.data.gsm_system_info_v2.forbidden_valid, + res.data.gsm_system_info_v2.forbidden, + res.data.gsm_system_info_v2.lac_valid, + res.data.gsm_system_info_v2.lac, + res.data.gsm_system_info_v2.cid_valid, + res.data.gsm_system_info_v2.cid, + res.data.gsm_system_info_v2.network_id_valid, + res.data.gsm_system_info_v2.mcc, + res.data.gsm_system_info_v2.mnc); + if (res.set.additional_gsm_system_info && + res.data.additional_gsm_system_info.geo_system_index != 0xFFFF) + blobmsg_add_u32(&status, "geo_system_index", + res.data.additional_gsm_system_info.geo_system_index); + blobmsg_close_table(&status, c); + } + + if (res.set.wcdma_service_status) { + c = blobmsg_open_table(&status, "wcdma"); + print_system_info(res.data.wcdma_service_status.service_status, + res.data.wcdma_service_status.true_service_status, + res.data.wcdma_service_status.preferred_data_path, + res.set.wcdma_system_info_v2, + res.data.wcdma_system_info_v2.domain_valid, + res.data.wcdma_system_info_v2.domain, + res.data.wcdma_system_info_v2.service_capability_valid, + res.data.wcdma_system_info_v2.service_capability, + res.data.wcdma_system_info_v2.roaming_status_valid, + res.data.wcdma_system_info_v2.roaming_status, + res.data.wcdma_system_info_v2.forbidden_valid, + res.data.wcdma_system_info_v2.forbidden, + res.data.wcdma_system_info_v2.lac_valid, + res.data.wcdma_system_info_v2.lac, + res.data.wcdma_system_info_v2.cid_valid, + res.data.wcdma_system_info_v2.cid, + res.data.wcdma_system_info_v2.network_id_valid, + res.data.wcdma_system_info_v2.mcc, + res.data.wcdma_system_info_v2.mnc); + if (res.set.additional_wcdma_system_info && + res.data.additional_wcdma_system_info.geo_system_index != 0xFFFF) + blobmsg_add_u32(&status, "geo_system_index", + res.data.additional_wcdma_system_info.geo_system_index); + blobmsg_close_table(&status, c); + } + + if (res.set.lte_service_status) { + c = blobmsg_open_table(&status, "lte"); + print_system_info(res.data.lte_service_status.service_status, + res.data.lte_service_status.true_service_status, + res.data.lte_service_status.preferred_data_path, + res.set.lte_system_info_v2, + res.data.lte_system_info_v2.domain_valid, + res.data.lte_system_info_v2.domain, + res.data.lte_system_info_v2.service_capability_valid, + res.data.lte_system_info_v2.service_capability, + res.data.lte_system_info_v2.roaming_status_valid, + res.data.lte_system_info_v2.roaming_status, + res.data.lte_system_info_v2.forbidden_valid, + res.data.lte_system_info_v2.forbidden, + res.data.lte_system_info_v2.lac_valid, + res.data.lte_system_info_v2.lac, + res.data.lte_system_info_v2.cid_valid, + res.data.lte_system_info_v2.cid, + res.data.lte_system_info_v2.network_id_valid, + res.data.lte_system_info_v2.mcc, + res.data.lte_system_info_v2.mnc); + if (res.set.lte_system_info_v2 && res.data.lte_system_info_v2.tac_valid) + blobmsg_add_u32(&status, "tracking_area_code", + res.data.lte_system_info_v2.tac); + if (res.set.additional_lte_system_info && + res.data.additional_lte_system_info.geo_system_index != 0xFFFF) + blobmsg_add_u32(&status, "geo_system_index", + res.data.additional_lte_system_info.geo_system_index); + if (res.set.lte_voice_support) + blobmsg_add_u8(&status, "voice_support", res.data.lte_voice_support); + if (res.set.ims_voice_support) + blobmsg_add_u8(&status, "ims_voice_support", res.data.ims_voice_support); + if (res.set.lte_cell_access_status) + blobmsg_add_string(&status, "cell_access_status", + cell_status[res.data.lte_cell_access_status]); + if (res.set.network_selection_registration_restriction) + blobmsg_add_u32(&status, "registration_restriction", + res.data.network_selection_registration_restriction); + if (res.set.lte_registration_domain) + blobmsg_add_u32(&status, "registration_domain", + res.data.lte_registration_domain); + if (res.set.eutra_with_nr5g_availability) + blobmsg_add_u8(&status, "5g_nsa_available", + res.data.eutra_with_nr5g_availability); + if (res.set.dcnr_restriction_info) + blobmsg_add_u8(&status, "dcnr_restriction", res.data.dcnr_restriction_info); + + blobmsg_close_table(&status, c); + } + blobmsg_close_table(&status, t); +} + +static enum qmi_cmd_result +cmd_nas_get_system_info_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg) +{ + qmi_set_nas_get_system_info_request(msg); + return QMI_CMD_REQUEST; +} + +static void +print_channel_info(int32_t cell_id, int32_t channel, uint32_t bw) +{ + static const char *map_bandwidth[] = { + [QMI_NAS_DL_BANDWIDTH_1_4] = "1.4", + [QMI_NAS_DL_BANDWIDTH_3] = "3", + [QMI_NAS_DL_BANDWIDTH_5] = "5", + [QMI_NAS_DL_BANDWIDTH_10] = "10", + [QMI_NAS_DL_BANDWIDTH_15] = "15", + [QMI_NAS_DL_BANDWIDTH_20] = "20", + [QMI_NAS_DL_BANDWIDTH_INVALID] = "invalid", + [QMI_NAS_DL_BANDWIDTH_UNKNOWN] = "unknown", + }; + + blobmsg_add_u32(&status, "cell_id", cell_id); + blobmsg_add_u32(&status, "channel", channel); + print_earfcn_info(channel); + blobmsg_add_string(&status, "bandwidth", map_bandwidth[bw]); +} + +static void +cmd_nas_get_lte_cphy_ca_info_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg) +{ + struct qmi_nas_get_lte_cphy_ca_info_response res; + static const char *scell_state[] = { + [QMI_NAS_SCELL_STATE_DECONFIGURED] = "deconfigured", + [QMI_NAS_SCELL_STATE_DEACTIVATED] = "deactivated", + [QMI_NAS_SCELL_STATE_ACTIVATED] = "activated", + }; + char idx_buf[16]; + void *t, *c; + int i; + + qmi_parse_nas_get_lte_cphy_ca_info_response(msg, &res); + t = blobmsg_open_table(&status, NULL); + if (res.set.phy_ca_agg_pcell_info) { + c = blobmsg_open_table(&status, "primary"); + print_channel_info(res.data.phy_ca_agg_pcell_info.physical_cell_id, + res.data.phy_ca_agg_pcell_info.rx_channel, + res.data.phy_ca_agg_pcell_info.dl_bandwidth); + blobmsg_close_table(&status, c); + } + if (res.set.phy_ca_agg_scell_info && res.data.phy_ca_agg_secondary_cells_n) { + for (i = 0; i < res.data.phy_ca_agg_secondary_cells_n; i++) { + if (res.data.phy_ca_agg_secondary_cells[i].rx_channel == 0) + break; + sprintf(idx_buf, "secondary_%d", + res.data.phy_ca_agg_secondary_cells[i].cell_index); + c = blobmsg_open_table(&status, idx_buf); + print_channel_info(res.data.phy_ca_agg_secondary_cells[i].physical_cell_id, + res.data.phy_ca_agg_secondary_cells[i].rx_channel, + res.data.phy_ca_agg_secondary_cells[i].dl_bandwidth); + blobmsg_add_string(&status, "state", + scell_state[res.data.phy_ca_agg_secondary_cells[i].state]); + blobmsg_close_table(&status, c); + } + } else { + if (res.set.scell_index) + sprintf(idx_buf, "secondary_%d", res.data.scell_index); + else + sprintf(idx_buf, "secondary"); + if (res.set.phy_ca_agg_scell_info && res.data.phy_ca_agg_scell_info.rx_channel != 0) { + c = blobmsg_open_table(&status, idx_buf); + print_channel_info(res.data.phy_ca_agg_scell_info.physical_cell_id, + res.data.phy_ca_agg_scell_info.rx_channel, + res.data.phy_ca_agg_scell_info.dl_bandwidth); + blobmsg_add_string(&status, "state", + scell_state[res.data.phy_ca_agg_scell_info.state]); + blobmsg_close_table(&status, c); + } + } + blobmsg_close_table(&status, t); +} + +static enum qmi_cmd_result +cmd_nas_get_lte_cphy_ca_info_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg) +{ + qmi_set_nas_get_lte_cphy_ca_info_request(msg); + return QMI_CMD_REQUEST; +} + +static void +print_chain_info(int8_t radio, bool tuned, int32_t rssi, int32_t ecio, int32_t rsrp, int32_t rscp, uint32_t phase) +{ + blobmsg_add_u8(&status, "tuned", tuned); + blobmsg_add_double(&status, "rssi", (double) rssi*0.1); + if (radio == QMI_NAS_RADIO_INTERFACE_LTE) { + blobmsg_add_double(&status, "rsrq", (double) ecio*-0.1); + blobmsg_add_double(&status, "rsrp", (double) rsrp*-0.1); + } + if (radio == QMI_NAS_RADIO_INTERFACE_UMTS) { + blobmsg_add_double(&status, "ecio", (double) ecio*-0.1); + blobmsg_add_double(&status, "rscp", (double) rscp*-0.1); + } + if (phase != 0xFFFFFFFF) + blobmsg_add_double(&status, "phase", (double) phase*0.01); +} + +static void +cmd_nas_get_tx_rx_info_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg) +{ + struct qmi_nas_get_tx_rx_info_response res; + void *c, *t; + + qmi_parse_nas_get_tx_rx_info_response(msg, &res); + t = blobmsg_open_table(&status, NULL); + if (res.set.rx_chain_0_info) { + c = blobmsg_open_table(&status, "rx_chain_0"); + print_chain_info(tx_rx_req.data.radio_interface, + res.data.rx_chain_0_info.is_radio_tuned, + res.data.rx_chain_0_info.rx_power, + res.data.rx_chain_0_info.ecio, + res.data.rx_chain_0_info.rsrp, + res.data.rx_chain_0_info.rscp, + res.data.rx_chain_0_info.phase); + blobmsg_close_table(&status, c); + } + if (res.set.rx_chain_1_info) { + c = blobmsg_open_table(&status, "rx_chain_1"); + print_chain_info(tx_rx_req.data.radio_interface, + res.data.rx_chain_1_info.is_radio_tuned, + res.data.rx_chain_1_info.rx_power, + res.data.rx_chain_1_info.ecio, + res.data.rx_chain_1_info.rsrp, + res.data.rx_chain_1_info.rscp, + res.data.rx_chain_1_info.phase); + blobmsg_close_table(&status, c); + } + if (res.set.rx_chain_2_info) { + c = blobmsg_open_table(&status, "rx_chain_2"); + print_chain_info(tx_rx_req.data.radio_interface, + res.data.rx_chain_2_info.is_radio_tuned, + res.data.rx_chain_2_info.rx_power, + res.data.rx_chain_2_info.ecio, + res.data.rx_chain_2_info.rsrp, + res.data.rx_chain_2_info.rscp, + res.data.rx_chain_2_info.phase); + blobmsg_close_table(&status, c); + } + if (res.set.rx_chain_3_info) { + c = blobmsg_open_table(&status, "rx_chain_3"); + print_chain_info(tx_rx_req.data.radio_interface, + res.data.rx_chain_3_info.is_radio_tuned, + res.data.rx_chain_3_info.rx_power, + res.data.rx_chain_3_info.ecio, + res.data.rx_chain_3_info.rsrp, + res.data.rx_chain_3_info.rscp, + res.data.rx_chain_3_info.phase); + blobmsg_close_table(&status, c); + } + if (res.set.tx_info) { + c = blobmsg_open_table(&status, "tx"); + blobmsg_add_u8(&status, "traffic", res.data.tx_info.is_in_traffic); + if (res.data.tx_info.is_in_traffic) + blobmsg_add_double(&status, "tx_power", + (double) res.data.tx_info.tx_power*0.1); + blobmsg_close_table(&status, c); + } + blobmsg_close_table(&status, t); +} + + +static enum qmi_cmd_result +cmd_nas_get_tx_rx_info_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg) +{ + int radio = 0; + + if (!strcmp(arg, "lte")) + radio = QMI_NAS_RADIO_INTERFACE_LTE; + else if (!strcmp(arg, "umts")) + radio = QMI_NAS_RADIO_INTERFACE_UMTS; + else if (!strcmp(arg, "gsm")) + radio = QMI_NAS_RADIO_INTERFACE_GSM; + else + return uqmi_add_error("Invalid argument"); + + qmi_set(&tx_rx_req, radio_interface, radio); + qmi_set_nas_get_tx_rx_info_request(msg, &tx_rx_req); + return QMI_CMD_REQUEST; +} + +static void +print_lte_info(int32_t cell_id, int16_t rsrp, int16_t rsrq, int16_t rssi) +{ + blobmsg_add_u32(&status, "physical_cell_id", cell_id); + blobmsg_add_double(&status, "rsrq", ((double)rsrq)/10); + blobmsg_add_double(&status, "rsrp", ((double)rsrp)/10); + blobmsg_add_double(&status, "rssi", ((double)rssi)/10); +} + +static void +print_sel_info(int32_t priority, int32_t high, int32_t low) +{ + blobmsg_add_u32(&status, "cell_reselection_priority", priority); + blobmsg_add_u32(&status, "cell_reselection_low", low); + blobmsg_add_u32(&status, "cell_reselection_high", high); +} + +static void +cmd_nas_get_cell_location_info_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg) +{ + struct qmi_nas_get_cell_location_info_response res; + void *c, *t, *cell, *freq; + int i, j; + + qmi_parse_nas_get_cell_location_info_response(msg, &res); + t = blobmsg_open_table(&status, NULL); + + if (res.set.umts_info_v2) { + c = blobmsg_open_table(&status, "umts_info"); + blobmsg_add_u32(&status, "cell_id", res.data.umts_info_v2.cell_id); + blobmsg_add_u32(&status, "location_area_code", res.data.umts_info_v2.lac); + blobmsg_add_u32(&status, "channel", + res.data.umts_info_v2.utra_absolute_rf_channel_number); + blobmsg_add_u32(&status, "primary_scrambling_code", + res.data.umts_info_v2.primary_scrambling_code); + blobmsg_add_u32(&status, "rscp", res.data.umts_info_v2.rscp); + blobmsg_add_u32(&status, "ecio", res.data.umts_info_v2.ecio); + for (j = 0; j < res.data.umts_info_v2.cell_n; j++) { + cell = blobmsg_open_table(&status, NULL); + blobmsg_add_u32(&status, "channel", + res.data.umts_info_v2.cell[j].utra_absolute_rf_channel_number); + blobmsg_add_u32(&status, "primary_scrambling_code", + res.data.umts_info_v2.cell[j].primary_scrambling_code); + blobmsg_add_u32(&status, "rscp", res.data.umts_info_v2.cell[j].rscp); + blobmsg_add_u32(&status, "ecio", res.data.umts_info_v2.cell[j].ecio); + blobmsg_close_table(&status, cell); + } + for (j = 0; j < res.data.umts_info_v2.neighboring_geran_n; j++) { + cell = blobmsg_open_table(&status, "neighboring_geran"); + blobmsg_add_u32(&status, "channel", + res.data.umts_info_v2.neighboring_geran[j].geran_absolute_rf_channel_number); + blobmsg_add_u8(&status, "network_color_code", + res.data.umts_info_v2.neighboring_geran[j].network_color_code); + blobmsg_add_u8(&status, "base_station_color_code", + res.data.umts_info_v2.neighboring_geran[j].base_station_color_code); + blobmsg_add_u32(&status, "rssi", + res.data.umts_info_v2.neighboring_geran[j].rssi); + blobmsg_close_table(&status, cell); + } + blobmsg_close_table(&status, c); + } + if (res.set.intrafrequency_lte_info_v2) { + c = blobmsg_open_table(&status, "intrafrequency_lte_info"); + blobmsg_add_u32(&status, "tracking_area_code", + res.data.intrafrequency_lte_info_v2.tracking_area_code); + blobmsg_add_u32(&status, "global_cell_id", + res.data.intrafrequency_lte_info_v2.global_cell_id); + blobmsg_add_u32(&status, "channel", + res.data.intrafrequency_lte_info_v2.eutra_absolute_rf_channel_number); + print_earfcn_info(res.data.intrafrequency_lte_info_v2.eutra_absolute_rf_channel_number); + blobmsg_add_u32(&status, "serving_cell_id", + res.data.intrafrequency_lte_info_v2.serving_cell_id); + if (res.data.intrafrequency_lte_info_v2.ue_in_idle) { + blobmsg_add_u32(&status, "cell_reselection_priority", + res.data.intrafrequency_lte_info_v2.cell_reselection_priority); + blobmsg_add_u32(&status, "s_non_intra_search_threshold", + res.data.intrafrequency_lte_info_v2.s_non_intra_search_threshold); + blobmsg_add_u32(&status, "serving_cell_low_threshold", + res.data.intrafrequency_lte_info_v2.serving_cell_low_threshold); + blobmsg_add_u32(&status, "s_intra_search_threshold", + res.data.intrafrequency_lte_info_v2.s_intra_search_threshold); + } + for (i = 0; i < res.data.intrafrequency_lte_info_v2.cell_n; i++) { + cell = blobmsg_open_table(&status, NULL); + print_lte_info(res.data.intrafrequency_lte_info_v2.cell[i].physical_cell_id, + res.data.intrafrequency_lte_info_v2.cell[i].rsrq, + res.data.intrafrequency_lte_info_v2.cell[i].rsrp, + res.data.intrafrequency_lte_info_v2.cell[i].rssi); + if (res.data.intrafrequency_lte_info_v2.ue_in_idle) + blobmsg_add_u32(&status, "cell_selection_rx_level", + res.data.intrafrequency_lte_info_v2.cell[i].cell_selection_rx_level); + blobmsg_close_table(&status, cell); + } + blobmsg_close_table(&status, c); + } + if (res.set.interfrequency_lte_info) { + if (res.data.interfrequency_lte_info.frequency_n > 0) + c = blobmsg_open_table(&status, "interfrequency_lte_info"); + for (i = 0; i < res.data.interfrequency_lte_info.frequency_n; i++) { + freq = blobmsg_open_table(&status, NULL); + blobmsg_add_u32(&status, "channel", + res.data.interfrequency_lte_info.frequency[i].eutra_absolute_rf_channel_number); + print_earfcn_info(res.data.interfrequency_lte_info.frequency[i].eutra_absolute_rf_channel_number); + if (res.data.interfrequency_lte_info.ue_in_idle) { + print_sel_info(res.data.interfrequency_lte_info.frequency[i].cell_reselection_priority, + res.data.interfrequency_lte_info.frequency[i].cell_selection_rx_level_high_threshold, + res.data.interfrequency_lte_info.frequency[i].cell_selection_rx_level_low_threshold); + } + for (j = 0; j < res.data.interfrequency_lte_info.frequency[i].cell_n; j++) { + cell = blobmsg_open_table(&status, NULL); + print_lte_info(res.data.interfrequency_lte_info.frequency[i].cell[j].physical_cell_id, + res.data.interfrequency_lte_info.frequency[i].cell[j].rsrq, + res.data.interfrequency_lte_info.frequency[i].cell[j].rsrp, + res.data.interfrequency_lte_info.frequency[i].cell[j].rssi); + if (res.data.interfrequency_lte_info.ue_in_idle) + blobmsg_add_u32(&status, "cell_selection_rx_level", + res.data.interfrequency_lte_info.frequency[i].cell[j].cell_selection_rx_level); + blobmsg_close_table(&status, cell); + } + blobmsg_close_table(&status, freq); + } + if (res.data.interfrequency_lte_info.frequency_n > 0) + blobmsg_close_table(&status, c); + } + if (res.set.lte_info_neighboring_gsm) { + if (res.data.lte_info_neighboring_gsm.frequency_n > 0) + c = blobmsg_open_table(&status, "lte_info_neighboring_gsm"); + for (i = 0; i < res.data.lte_info_neighboring_gsm.frequency_n; i++) { + freq = blobmsg_open_table(&status, NULL); + blobmsg_add_u32(&status, "ncc_permitted", + res.data.lte_info_neighboring_gsm.frequency[i].ncc_permitted); + if (res.data.lte_info_neighboring_gsm.ue_in_idle) { + print_sel_info(res.data.lte_info_neighboring_gsm.frequency[i].cell_reselection_priority, + res.data.lte_info_neighboring_gsm.frequency[i].cell_reselection_high_threshold, + res.data.lte_info_neighboring_gsm.frequency[i].cell_reselection_low_threshold); + } + for (j = 0; j < res.data.lte_info_neighboring_gsm.frequency[i].cell_n; j++) { + cell = blobmsg_open_table(&status, NULL); + blobmsg_add_u32(&status, "channel", + res.data.lte_info_neighboring_gsm.frequency[i].cell[j].geran_absolute_rf_channel_number); + blobmsg_add_u32(&status, "base_station_identity_code", + res.data.lte_info_neighboring_gsm.frequency[i].cell[j].base_station_identity_code); + blobmsg_add_double(&status, "rssi", + ((double)res.data.lte_info_neighboring_gsm.frequency[i].cell[j].rssi)/10); + if (res.data.lte_info_neighboring_gsm.ue_in_idle) + blobmsg_add_u32(&status, "cell_selection_rx_level", + res.data.lte_info_neighboring_gsm.frequency[i].cell[j].cell_selection_rx_level); + blobmsg_close_table(&status, cell); + } + blobmsg_close_table(&status, freq); + } + if (res.data.lte_info_neighboring_gsm.frequency_n > 0) + blobmsg_close_table(&status, c); + } + if (res.set.lte_info_neighboring_wcdma) { + if (res.data.lte_info_neighboring_wcdma.frequency_n > 0) + c = blobmsg_open_table(&status, "lte_info_neighboring_wcdma"); + for (i = 0; i < res.data.lte_info_neighboring_wcdma.frequency_n; i++) { + freq = blobmsg_open_table(&status, NULL); + blobmsg_add_u32(&status, "channel", + res.data.lte_info_neighboring_wcdma.frequency[i].utra_absolute_rf_channel_number); + if (res.data.lte_info_neighboring_wcdma.ue_in_idle) { + print_sel_info(res.data.lte_info_neighboring_wcdma.frequency[i].cell_reselection_priority, + res.data.lte_info_neighboring_wcdma.frequency[i].cell_reselection_high_threshold, + res.data.lte_info_neighboring_wcdma.frequency[i].cell_reselection_low_threshold); + } + for (j = 0; j < res.data.lte_info_neighboring_wcdma.frequency[i].cell_n; j++) { + cell = blobmsg_open_table(&status, NULL); + blobmsg_add_u32(&status, "primary_scrambling_code", + res.data.lte_info_neighboring_wcdma.frequency[i].cell[j].primary_scrambling_code); + blobmsg_add_double(&status, "rscp", + ((double)res.data.lte_info_neighboring_wcdma.frequency[i].cell[j].cpich_rscp)/10); + blobmsg_add_double(&status, "ecno", + ((double)res.data.lte_info_neighboring_wcdma.frequency[i].cell[j].cpich_ecno)/10); + if (res.data.lte_info_neighboring_wcdma.ue_in_idle) + blobmsg_add_u32(&status, "cell_selection_rx_level", + res.data.lte_info_neighboring_wcdma.frequency[i].cell[j].cell_selection_rx_level); + blobmsg_close_table(&status, cell); + } + blobmsg_close_table(&status, freq); + } + if (res.data.lte_info_neighboring_wcdma.frequency_n > 0) + blobmsg_close_table(&status, c); + } + if (res.set.umts_info_neighboring_lte) { + if (res.data.umts_info_neighboring_lte.frequency_n > 0) + c = blobmsg_open_table(&status, "umts_info_neighboring_lte"); + for (i = 0; i < res.data.umts_info_neighboring_lte.frequency_n; i++) { + freq = blobmsg_open_table(&status, NULL); + blobmsg_add_u32(&status, "channel", + res.data.umts_info_neighboring_lte.frequency[i].eutra_absolute_rf_channel_number); + print_earfcn_info(res.data.umts_info_neighboring_lte.frequency[i].eutra_absolute_rf_channel_number); + blobmsg_add_u32(&status, "physical_cell_id", + res.data.umts_info_neighboring_lte.frequency[i].physical_cell_id); + blobmsg_add_double(&status, "rsrp", + (double) res.data.umts_info_neighboring_lte.frequency[i].rsrp); + blobmsg_add_double(&status, "rsrq", + (double) res.data.umts_info_neighboring_lte.frequency[i].rsrq); + blobmsg_add_u32(&status, "cell_selection_rx_level", + res.data.umts_info_neighboring_lte.frequency[i].cell_selection_rx_level); + blobmsg_close_table(&status, freq); + } + if (res.data.umts_info_neighboring_lte.frequency_n > 0) + blobmsg_close_table(&status, c); + } + blobmsg_close_table(&status, t); +} + +static enum qmi_cmd_result +cmd_nas_get_cell_location_info_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg) +{ + qmi_set_nas_get_cell_location_info_request(msg); + return QMI_CMD_REQUEST; +} + static enum qmi_cmd_result cmd_nas_get_signal_info_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg) { diff --git a/commands-nas.h b/commands-nas.h index 4b175f9..2426caa 100644 --- a/commands-nas.h +++ b/commands-nas.h @@ -31,7 +31,11 @@ __uqmi_command(nas_get_signal_info, get-signal-info, no, QMI_SERVICE_NAS), \ __uqmi_command(nas_get_serving_system, get-serving-system, no, QMI_SERVICE_NAS), \ __uqmi_command(nas_set_network_preference, set-network-preference, required, CMD_TYPE_OPTION), \ - __uqmi_command(nas_set_roaming, set-network-roaming, required, CMD_TYPE_OPTION) \ + __uqmi_command(nas_set_roaming, set-network-roaming, required, CMD_TYPE_OPTION), \ + __uqmi_command(nas_get_system_info, get-system-info, no, QMI_SERVICE_NAS), \ + __uqmi_command(nas_get_lte_cphy_ca_info, get-lte-cphy-ca-info, no, QMI_SERVICE_NAS), \ + __uqmi_command(nas_get_cell_location_info, get-cell-location-info, no, QMI_SERVICE_NAS), \ + __uqmi_command(nas_get_tx_rx_info, get-tx-rx-info, required, QMI_SERVICE_NAS) \ #define nas_helptext \ " --set-network-modes : Set usable network modes (Syntax: [,,...])\n" \ @@ -48,4 +52,8 @@ " --get-plmn: Get preferred network selection info\n" \ " --get-signal-info: Get signal strength info\n" \ " --get-serving-system: Get serving system info\n" \ + " --get-system-info: Get system info\n" \ + " --get-lte-cphy-ca-info: Get LTE Cphy CA Info\n" \ + " --get-cell-location-info: Get Cell Location Info\n" \ + " --get-tx-rx-info : Get TX/RX Info (gsm, umts, lte)\n" \ -- 2.30.2