[PATCH 1/1] udev: devnode is not a required modem property
A devnode does not always exist; the Nokia N900, for example, does not provide one for its modem. This patch relaxes the check on device properties to exclude the requirement of a devnode. The "Device" property is not used by the n900 or u8500 drivers, so drop setting this property when setting up these devices. --- Hi Clayton, Could you try this patch and see if the N900 is detected? Thanks, Jonas plugins/udevng.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/udevng.c b/plugins/udevng.c index 518eda8..241fcda 100644 --- a/plugins/udevng.c +++ b/plugins/udevng.c @@ -1013,8 +1013,6 @@ static gboolean setup_isi_serial(struct modem_info* modem) if (value) ofono_modem_set_integer(modem->modem, "Address", atoi(value)); - ofono_modem_set_string(modem->modem, "Device", info->devnode); - return TRUE; } @@ -1325,7 +1323,7 @@ static void add_serial_device(struct udev_device *dev) devnode = udev_device_get_devnode(dev); - if (!syspath || !devname || !devpath || !devnode) + if (!syspath || !devpath) return; modem = g_hash_table_lookup(modem_list, syspath); -- 2.9.3 ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH 1/7] qmi: provide AvailableTechnologies in radio-settings
This provides the list of available technologies in the radio-settings atom. The list is queried by the DMS Get Capabilities method; ofono takes care of caching the available technologies for us so we don't need to worry about this method being called excessively. --- I forgot to edit the commit message in the first submission. Here's a patch with a correct description. /Jonas drivers/qmimodem/radio-settings.c | 77 +++ 1 file changed, 77 insertions(+) diff --git a/drivers/qmimodem/radio-settings.c b/drivers/qmimodem/radio-settings.c index 3a2b068..5e76bc5 100644 --- a/drivers/qmimodem/radio-settings.c +++ b/drivers/qmimodem/radio-settings.c @@ -29,11 +29,13 @@ #include "qmi.h" #include "nas.h" +#include "dms.h" #include "qmimodem.h" struct settings_data { struct qmi_service *nas; + struct qmi_service *dms; uint16_t major; uint16_t minor; }; @@ -150,6 +152,78 @@ static void qmi_set_rat_mode(struct ofono_radio_settings *rs, g_free(cbd); } +static void get_caps_cb(struct qmi_result *result, void *user_data) +{ + struct cb_data *cbd = user_data; + ofono_radio_settings_available_rats_query_cb_t cb = cbd->cb; + const struct qmi_dms_device_caps *caps; + unsigned int available_rats; + uint16_t len; + uint8_t i; + + DBG(""); + + if (qmi_result_set_error(result, NULL)) + goto error; + + caps = qmi_result_get(result, QMI_DMS_RESULT_DEVICE_CAPS, ); + if (!caps) + goto error; + + available_rats = 0; +for (i = 0; i < caps->radio_if_count; i++) { + switch (caps->radio_if[i]) { + case QMI_DMS_RADIO_IF_GSM: + available_rats |= OFONO_RADIO_ACCESS_MODE_GSM; + break; + case QMI_DMS_RADIO_IF_UMTS: + available_rats |= OFONO_RADIO_ACCESS_MODE_UMTS; + break; + case QMI_DMS_RADIO_IF_LTE: + available_rats |= OFONO_RADIO_ACCESS_MODE_LTE; + } + } + + CALLBACK_WITH_SUCCESS(cb, available_rats, cbd->data); + + return; + +error: + CALLBACK_WITH_FAILURE(cb, -1, cbd->data); +} + +static void qmi_query_available_rats(struct ofono_radio_settings *rs, + ofono_radio_settings_available_rats_query_cb_t cb, + void *data) +{ + struct settings_data *rsd = ofono_radio_settings_get_data(rs); + struct cb_data *cbd = cb_data_new(cb, data); + + if (!rsd->dms) + goto error; + + if (qmi_service_send(rsd->dms, QMI_DMS_GET_CAPS, NULL, + get_caps_cb, cbd, g_free) > 0) + return; + +error: + g_free(cbd); + CALLBACK_WITH_FAILURE(cb, -1, data); +} + +static void create_dms_cb(struct qmi_service *service, void *user_data) +{ + struct ofono_radio_settings *rs = user_data; + struct settings_data *data = ofono_radio_settings_get_data(rs); + + DBG(""); + + if (!service) + return; + + data->dms = qmi_service_ref(service); +} + static void create_nas_cb(struct qmi_service *service, void *user_data) { struct ofono_radio_settings *rs = user_data; @@ -186,6 +260,8 @@ static int qmi_radio_settings_probe(struct ofono_radio_settings *rs, ofono_radio_settings_set_data(rs, data); + qmi_service_create_shared(device, QMI_SERVICE_DMS, + create_dms_cb, rs, NULL); qmi_service_create_shared(device, QMI_SERVICE_NAS, create_nas_cb, rs, NULL); @@ -213,6 +289,7 @@ static struct ofono_radio_settings_driver driver = { .remove = qmi_radio_settings_remove, .set_rat_mode = qmi_set_rat_mode, .query_rat_mode = qmi_query_rat_mode, + .query_available_rats = qmi_query_available_rats, }; void qmi_radio_settings_init(void) -- 2.9.3 ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH 7/7] gobi: add location-reporting atom
This patch is submitted as a request for advice: where should these changes go??? The patch is required for Quectel QMI modems to get location-reporting working: the 'aux' AT interface needs to be set up and passed to the location-reporting atom. But this is very Quectel specific and has nothing to do with Gobi at all. So what's the best approach here...? --- plugins/gobi.c | 33 + 1 file changed, 33 insertions(+) diff --git a/plugins/gobi.c b/plugins/gobi.c index bc2b068..962c947 100644 --- a/plugins/gobi.c +++ b/plugins/gobi.c @@ -29,6 +29,10 @@ #include #include +#include +#include +#include + #define OFONO_API_SUBJECT_TO_CHANGE #include #include @@ -319,10 +323,18 @@ static void discover_cb(uint8_t count, const struct qmi_version *list, create_dms_cb, modem, NULL); } +static void q_debug(const char* str, void *user_data) +{ + const char* prefix = user_data; + + ofono_info("%s%s", prefix, str); +} + static int gobi_enable(struct ofono_modem *modem) { struct gobi_data *data = ofono_modem_get_data(modem); const char *device; + const char *gps, *aux; int fd; DBG("%p", modem); @@ -348,6 +360,27 @@ static int gobi_enable(struct ofono_modem *modem) qmi_device_discover(data->device, discover_cb, modem, NULL); + aux = ofono_modem_get_string(modem, "Aux"); + gps = ofono_modem_get_string(modem, "GPS"); + DBG("aux = %s, gps = %s", aux, gps); + if (aux && gps) { + GAtChat *chat; + GAtSyntax *syntax; + GHashTable *options; + GIOChannel *channel; + DBG("Setting up location service"); + options = g_hash_table_new(g_str_hash, g_str_equal); + g_hash_table_insert(options, "Baud", "115200"); + channel = g_at_tty_open(aux, options); + syntax = g_at_syntax_new_gsm_permissive(); + chat = g_at_chat_new(channel, syntax); + g_at_syntax_unref(syntax); + g_io_channel_unref(channel); + if (getenv("OFONO_AT_DEBUG")) + g_at_chat_set_debug(chat, q_debug, "Aux: "); + ofono_location_reporting_create(modem, 0, "quectelmodem", chat); + } + return -EINPROGRESS; } -- 2.9.3 ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH 1/7] qmi: provide AvailableTechnologies in radio-settings
This provides the list of available technologies in the radio-settings atom. Note that this list is hard-coded and includes LTE unconditionally which is probably not correct for all QMI devices. --- drivers/qmimodem/radio-settings.c | 77 +++ 1 file changed, 77 insertions(+) diff --git a/drivers/qmimodem/radio-settings.c b/drivers/qmimodem/radio-settings.c index 3a2b068..5e76bc5 100644 --- a/drivers/qmimodem/radio-settings.c +++ b/drivers/qmimodem/radio-settings.c @@ -29,11 +29,13 @@ #include "qmi.h" #include "nas.h" +#include "dms.h" #include "qmimodem.h" struct settings_data { struct qmi_service *nas; + struct qmi_service *dms; uint16_t major; uint16_t minor; }; @@ -150,6 +152,78 @@ static void qmi_set_rat_mode(struct ofono_radio_settings *rs, g_free(cbd); } +static void get_caps_cb(struct qmi_result *result, void *user_data) +{ + struct cb_data *cbd = user_data; + ofono_radio_settings_available_rats_query_cb_t cb = cbd->cb; + const struct qmi_dms_device_caps *caps; + unsigned int available_rats; + uint16_t len; + uint8_t i; + + DBG(""); + + if (qmi_result_set_error(result, NULL)) + goto error; + + caps = qmi_result_get(result, QMI_DMS_RESULT_DEVICE_CAPS, ); + if (!caps) + goto error; + + available_rats = 0; +for (i = 0; i < caps->radio_if_count; i++) { + switch (caps->radio_if[i]) { + case QMI_DMS_RADIO_IF_GSM: + available_rats |= OFONO_RADIO_ACCESS_MODE_GSM; + break; + case QMI_DMS_RADIO_IF_UMTS: + available_rats |= OFONO_RADIO_ACCESS_MODE_UMTS; + break; + case QMI_DMS_RADIO_IF_LTE: + available_rats |= OFONO_RADIO_ACCESS_MODE_LTE; + } + } + + CALLBACK_WITH_SUCCESS(cb, available_rats, cbd->data); + + return; + +error: + CALLBACK_WITH_FAILURE(cb, -1, cbd->data); +} + +static void qmi_query_available_rats(struct ofono_radio_settings *rs, + ofono_radio_settings_available_rats_query_cb_t cb, + void *data) +{ + struct settings_data *rsd = ofono_radio_settings_get_data(rs); + struct cb_data *cbd = cb_data_new(cb, data); + + if (!rsd->dms) + goto error; + + if (qmi_service_send(rsd->dms, QMI_DMS_GET_CAPS, NULL, + get_caps_cb, cbd, g_free) > 0) + return; + +error: + g_free(cbd); + CALLBACK_WITH_FAILURE(cb, -1, data); +} + +static void create_dms_cb(struct qmi_service *service, void *user_data) +{ + struct ofono_radio_settings *rs = user_data; + struct settings_data *data = ofono_radio_settings_get_data(rs); + + DBG(""); + + if (!service) + return; + + data->dms = qmi_service_ref(service); +} + static void create_nas_cb(struct qmi_service *service, void *user_data) { struct ofono_radio_settings *rs = user_data; @@ -186,6 +260,8 @@ static int qmi_radio_settings_probe(struct ofono_radio_settings *rs, ofono_radio_settings_set_data(rs, data); + qmi_service_create_shared(device, QMI_SERVICE_DMS, + create_dms_cb, rs, NULL); qmi_service_create_shared(device, QMI_SERVICE_NAS, create_nas_cb, rs, NULL); @@ -213,6 +289,7 @@ static struct ofono_radio_settings_driver driver = { .remove = qmi_radio_settings_remove, .set_rat_mode = qmi_set_rat_mode, .query_rat_mode = qmi_query_rat_mode, + .query_available_rats = qmi_query_available_rats, }; void qmi_radio_settings_init(void) -- 2.9.3 ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH 6/7] udev: fix quectelqmi gps interface
Using location-reporting requires both the 'aux' and 'gps' interfaces; the GPS interface is interface 1, not 2. --- plugins/udevng.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/plugins/udevng.c b/plugins/udevng.c index 4a11cd1..518eda8 100644 --- a/plugins/udevng.c +++ b/plugins/udevng.c @@ -876,7 +876,7 @@ static gboolean setup_quectel(struct modem_info *modem) static gboolean setup_quectelqmi(struct modem_info *modem) { - const char *qmi = NULL, *net = NULL, *gps = NULL; + const char *qmi = NULL, *net = NULL, *gps = NULL, *aux = NULL; GSList *list; DBG("%s", modem->syspath); @@ -894,8 +894,11 @@ static gboolean setup_quectelqmi(struct modem_info *modem) else if (g_strcmp0(info->subsystem, "usbmisc") == 0) qmi = info->devnode; } else if (g_strcmp0(info->interface, "255/0/0") == 0 && - g_strcmp0(info->number, "02") == 0) { + g_strcmp0(info->number, "01") == 0) { gps = info->devnode; + } else if (g_strcmp0(info->interface, "255/0/0") == 0 && + g_strcmp0(info->number, "02") == 0) { + aux = info->devnode; } } @@ -909,8 +912,12 @@ static gboolean setup_quectelqmi(struct modem_info *modem) ofono_modem_set_string(modem->modem, "Device", qmi); ofono_modem_set_string(modem->modem, "NetworkInterface", net); + DBG("gps=%s aux=%s", gps, aux); + if (gps) ofono_modem_set_string(modem->modem, "GPS", gps); + if (aux) + ofono_modem_set_string(modem->modem, "Aux", aux); ofono_modem_set_driver(modem->modem, "gobi"); -- 2.9.3 ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH 5/7] Add Quectel location-reporting
This adds Quectel-specific functionality for initializing and getting the GPS/NMEA file descriptor. This is common to both AT and QMI modems as the GPS functionality needs to be set up via AT commands in both cases. --- Makefile.am | 6 + drivers/quectelmodem/location-reporting.c | 227 ++ drivers/quectelmodem/quectelmodem.c | 50 +++ drivers/quectelmodem/quectelmodem.h | 25 4 files changed, 308 insertions(+) create mode 100644 drivers/quectelmodem/location-reporting.c create mode 100644 drivers/quectelmodem/quectelmodem.c create mode 100644 drivers/quectelmodem/quectelmodem.h diff --git a/Makefile.am b/Makefile.am index 4b68beb..4941b4c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -319,6 +319,12 @@ builtin_sources += drivers/atmodem/atutil.h \ drivers/mbmmodem/stk.c \ drivers/mbmmodem/location-reporting.c +builtin_modules += quectelmodem +builtin_sources += drivers/atmodem/atutil.h \ + drivers/quectelmodem/quectelmodem.h \ + drivers/quectelmodem/quectelmodem.c \ + drivers/quectelmodem/location-reporting.c + builtin_modules += telitmodem builtin_sources += drivers/atmodem/atutil.h \ drivers/telitmodem/telitmodem.h \ diff --git a/drivers/quectelmodem/location-reporting.c b/drivers/quectelmodem/location-reporting.c new file mode 100644 index 000..2ed19cd --- /dev/null +++ b/drivers/quectelmodem/location-reporting.c @@ -0,0 +1,227 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2008-2014 Intel Corporation. All rights reserved. + * Copyright (C) 2017 Jonas Bonn. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "gatchat.h" +#include "gatresult.h" +#include "gattty.h" + +#include "quectelmodem.h" + +static const char *none_prefix[] = { NULL }; + +struct gps_data { + GAtChat *chat; +}; + +static void quectel_gps_disable_cb(gboolean ok, GAtResult *result, + gpointer user_data) +{ + struct cb_data *cbd = user_data; + struct ofono_location_reporting *lr = cbd->user; + ofono_location_reporting_disable_cb_t cb = cbd->cb; + + DBG("lr=%p, ok=%d", lr, ok); + + if (!ok) { + struct ofono_error error; + + decode_at_error(, g_at_result_final_response(result)); + cb(, cbd->data); + + return; + } + + CALLBACK_WITH_SUCCESS(cb, cbd->data); +} + +static void quectel_location_reporting_disable( + struct ofono_location_reporting *lr, + ofono_location_reporting_disable_cb_t cb, + void *data) +{ + struct gps_data *gd = ofono_location_reporting_get_data(lr); + struct cb_data *cbd = cb_data_new(cb, data); + + DBG("lr=%p", lr); + + cbd->user = lr; + + if (g_at_chat_send(gd->chat, "AT+QGPSEND", none_prefix, + quectel_gps_disable_cb, cbd, g_free) > 0) + return; + + CALLBACK_WITH_FAILURE(cb, data); + + g_free(cbd); +} + +static int enable_data_stream(struct ofono_location_reporting *lr) +{ + struct ofono_modem *modem; + const char *gps_dev; + GHashTable *options; + GIOChannel *channel; + int fd; + + modem = ofono_location_reporting_get_modem(lr); + gps_dev = ofono_modem_get_string(modem, "GPS"); + + options = g_hash_table_new(g_str_hash, g_str_equal); + if (options == NULL) + return -1; + + g_hash_table_insert(options, "Baud", "115200"); + + channel = g_at_tty_open(gps_dev, options); + + g_hash_table_destroy(options); + + if (channel == NULL) + return -1; + + fd = g_io_channel_unix_get_fd(channel); + + g_io_channel_set_close_on_unref(channel, FALSE); + g_io_channel_unref(channel); + + return fd; +} + +static void quectel_gps_enable_cb(gboolean ok, GAtResult *result, +
[PATCH 4/7] gobi: create NetworkMonitor atom
--- plugins/gobi.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/gobi.c b/plugins/gobi.c index a498599..bc2b068 100644 --- a/plugins/gobi.c +++ b/plugins/gobi.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -493,8 +494,10 @@ static void gobi_post_online(struct ofono_modem *modem) DBG("%p", modem); - if (data->features & GOBI_NAS) + if (data->features & GOBI_NAS) { ofono_netreg_create(modem, 0, "qmimodem", data->device); + ofono_netmon_create(modem, 0, "qmimodem", data->device); + } if (data->features & GOBI_VOICE) ofono_ussd_create(modem, 0, "qmimodem", data->device); -- 2.9.3 ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH 3/7] qmi: add NetworkMonitor interface
This is a rudimentary implementation that contains technology and RSSI and BitErrorRate, plus RSRQ/RSRP for LTE networks. More data can be added as needed. This implementations uses the 'Get Signal Strength' QMI method to retrieve the data. Operator fields (MNC, LAC, etc) can be gotten from the 'Serving Cell' method if needed, but since this data is already provided in the NetworkRegistration object it doesn't seem necessary to repeat it here when an additional communication to the modem is required. --- Makefile.am | 3 +- drivers/qmimodem/netmon.c | 283 drivers/qmimodem/qmimodem.c | 2 + drivers/qmimodem/qmimodem.h | 3 + 4 files changed, 290 insertions(+), 1 deletion(-) create mode 100644 drivers/qmimodem/netmon.c diff --git a/Makefile.am b/Makefile.am index 658e152..4b68beb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -233,7 +233,8 @@ builtin_sources += $(qmi_sources) \ drivers/qmimodem/gprs.c \ drivers/qmimodem/gprs-context.c \ drivers/qmimodem/radio-settings.c \ - drivers/qmimodem/location-reporting.c + drivers/qmimodem/location-reporting.c \ + drivers/qmimodem/netmon.c builtin_modules += gobi builtin_sources += plugins/gobi.c diff --git a/drivers/qmimodem/netmon.c b/drivers/qmimodem/netmon.c new file mode 100644 index 000..7d8e937 --- /dev/null +++ b/drivers/qmimodem/netmon.c @@ -0,0 +1,283 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2017 Jonas Bonn. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "qmi.h" +#include "nas.h" + +#include "qmimodem.h" +#include "src/common.h" + +struct netmon_data { + struct qmi_service *nas; +}; + +static void get_rssi_cb(struct qmi_result *result, void *user_data) +{ + struct cb_data *cbd = user_data; + struct ofono_netmon *netmon = cbd->user; + ofono_netmon_cb_t cb = cbd->cb; + struct { + enum ofono_netmon_cell_type type; + int rssi; + int ber; + int rsrq; + int rsrp; + } props; + uint16_t len; + int16_t rsrp; + const struct { + int8_t value; + int8_t rat; + } __attribute__((__packed__)) *rsrq; + const struct { + uint16_t count; + struct { + uint8_t rssi; + int8_t rat; + } __attribute__((__packed__)) info[0]; + } __attribute__((__packed__)) *rssi; + const struct { + uint16_t count; + struct { + uint16_t rate; + int8_t rat; + } __attribute__((__packed__)) info[0]; + } __attribute__((__packed__)) *ber; + int i; + + DBG(""); + + if (qmi_result_set_error(result, NULL)) { + CALLBACK_WITH_FAILURE(cb, cbd->data); + return; + } + + /* RSSI */ + rssi = qmi_result_get(result, 0x11, ); + if (rssi) { + for (i = 0; i < rssi->count; i++) { + DBG("RSSI: %hhu on RAT %hhd", + rssi->info[i].rssi, + rssi->info[i].rat); + } + + /* Get cell type from RSSI info... it will be the same +* for all the other entries +*/ + props.type = qmi_nas_rat_to_tech(rssi->info[0].rat); + switch (rssi->info[0].rat) { + case QMI_NAS_NETWORK_RAT_GSM: + props.type = OFONO_NETMON_CELL_TYPE_GSM; + break; + case QMI_NAS_NETWORK_RAT_UMTS: + props.type = OFONO_NETMON_CELL_TYPE_UMTS; + break; + case QMI_NAS_NETWORK_RAT_LTE: + props.type = OFONO_NETMON_CELL_TYPE_LTE; + break; + default: + props.type = OFONO_NETMON_CELL_TYPE_GSM; +
Re: nokia-modem (N900) not detected after migration to udevng
On 09/08/2017 03:38 AM, Clayton Craft wrote: Here's the info you requested, please let me know if I can gather anything else to help! OK, good. It's not a driver issue in any case. Now we need to figure out why ofono is rejecting the device. The debug output from ofonod would be useful. Try running ofono as: ofonod -d -n and paste the output here. /Jonas localhost:/home/user# udevadm info --query all --path /sys/bus/hsi/devices/n900-modem P: /devices/platform/6800.ocp/48058000.ssi-controller/ssi0/port0/n900-modem E: DEVPATH=/devices/platform/6800.ocp/48058000.ssi-controller/ssi0/port0/n900-modem E: DRIVER=nokia-modem E: MODALIAS=hsi:n900-modem E: OFONO_DRIVER=n900 E: OFONO_ISI_ADDRESS=108 E: OF_COMPATIBLE_0=nokia,n900-modem E: OF_COMPATIBLE_N=1 E: OF_FULLNAME=/ocp@6800/ssi-controller@48058000/ssi-port@4805a000/hsi-client E: OF_NAME=hsi-client E: SUBSYSTEM=hsi E: USEC_INITIALIZED=337086386 localhost:/home/user# udevadm info --attribute-walk --path /sys/bus/hsi/devices/n900-modem Udevadm info starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device. looking at device '/devices/platform/6800.ocp/48058000.ssi-controller/ssi0/port0/n900-modem': KERNEL=="n900-modem" SUBSYSTEM=="hsi" DRIVER=="nokia-modem" looking at parent device '/devices/platform/6800.ocp/48058000.ssi-controller/ssi0/port0': KERNELS=="port0" SUBSYSTEMS=="" DRIVERS=="" looking at parent device '/devices/platform/6800.ocp/48058000.ssi-controller/ssi0': KERNELS=="ssi0" SUBSYSTEMS=="" DRIVERS=="" looking at parent device '/devices/platform/6800.ocp/48058000.ssi-controller': KERNELS=="48058000.ssi-controller" SUBSYSTEMS=="platform" DRIVERS=="omap_ssi" ATTRS{driver_override}=="(null)" looking at parent device '/devices/platform/6800.ocp': KERNELS=="6800.ocp" SUBSYSTEMS=="platform" DRIVERS=="omap_l3_smx" ATTRS{driver_override}=="(null)" looking at parent device '/devices/platform': KERNELS=="platform" SUBSYSTEMS=="" DRIVERS=="" -Clayton On Fri, Sep 08, 2017 at 03:29:27AM +0200, Jonas Bonn wrote: On 09/08/2017 03:17 AM, Clayton Craft wrote: This is on HSI bus. I am running ofono on the N900 (not tethering). OK, from what I understand, you should be able to find this device under /sys/class/net/ See if you can find the device there and run: udevadm info --query all --path /sys/class/net/ and udevadm info --attribute-walk --path /sys/class/net. Post that output here if it's sane so that we can see what info udev is giving you for the device. /Jonas From what I understand, I am loading all of the necessary drivers for this to work (nokia-modem, which pulls in its dependencies automaticall). As I stated in my original note, before moving 'legacy device' initialization to udevng, ofono would at least 'see' the modem. The test script 'list-modems' would list it, now it does not list anything. -Clayton On Fri, Sep 08, 2017 at 03:13:03AM +0200, Jonas Bonn wrote: On 09/08/2017 02:51 AM, Clayton Craft wrote: Hi, I've been debugging why the n900 modem is not recognized by ofono for a few days now, and have determined that the cause is because the calls in udevng to udev_device_get_devnode return NULL. It seems that the nokia-modem driver does not create any device nodes under /dev. What bus does this modem sit on? Are you running ofono _on_ the N900 or are you trying to tether the N900 to some system with ofono? If you are tethering, what udev events do you get when you plug in the modem? Try running "udevadm monitor" and watch what happens when you plug the modem in. Not getting a device node sounds mostly like there's a driver missing, though... /Jonas This seems to be a regression in functionality since the move to udevng as previous versions of ofono seem to detect the n900 modem correctly (right before this commit 3ac449e25fc8cb9880c48b8f309189c6a644f200) This issue occurs from this commit onwards, including the latest commit as of this mail. https://git.kernel.org/pub/scm/network/ofono/ofono.git/tree/plugins/udevng.c#n1316 -Clayton ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono ___ ofono mailing list
Re: nokia-modem (N900) not detected after migration to udevng
Here's the info you requested, please let me know if I can gather anything else to help! localhost:/home/user# udevadm info --query all --path /sys/bus/hsi/devices/n900-modem P: /devices/platform/6800.ocp/48058000.ssi-controller/ssi0/port0/n900-modem E: DEVPATH=/devices/platform/6800.ocp/48058000.ssi-controller/ssi0/port0/n900-modem E: DRIVER=nokia-modem E: MODALIAS=hsi:n900-modem E: OFONO_DRIVER=n900 E: OFONO_ISI_ADDRESS=108 E: OF_COMPATIBLE_0=nokia,n900-modem E: OF_COMPATIBLE_N=1 E: OF_FULLNAME=/ocp@6800/ssi-controller@48058000/ssi-port@4805a000/hsi-client E: OF_NAME=hsi-client E: SUBSYSTEM=hsi E: USEC_INITIALIZED=337086386 localhost:/home/user# udevadm info --attribute-walk --path /sys/bus/hsi/devices/n900-modem Udevadm info starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device. looking at device '/devices/platform/6800.ocp/48058000.ssi-controller/ssi0/port0/n900-modem': KERNEL=="n900-modem" SUBSYSTEM=="hsi" DRIVER=="nokia-modem" looking at parent device '/devices/platform/6800.ocp/48058000.ssi-controller/ssi0/port0': KERNELS=="port0" SUBSYSTEMS=="" DRIVERS=="" looking at parent device '/devices/platform/6800.ocp/48058000.ssi-controller/ssi0': KERNELS=="ssi0" SUBSYSTEMS=="" DRIVERS=="" looking at parent device '/devices/platform/6800.ocp/48058000.ssi-controller': KERNELS=="48058000.ssi-controller" SUBSYSTEMS=="platform" DRIVERS=="omap_ssi" ATTRS{driver_override}=="(null)" looking at parent device '/devices/platform/6800.ocp': KERNELS=="6800.ocp" SUBSYSTEMS=="platform" DRIVERS=="omap_l3_smx" ATTRS{driver_override}=="(null)" looking at parent device '/devices/platform': KERNELS=="platform" SUBSYSTEMS=="" DRIVERS=="" -Clayton On Fri, Sep 08, 2017 at 03:29:27AM +0200, Jonas Bonn wrote: On 09/08/2017 03:17 AM, Clayton Craft wrote: This is on HSI bus. I am running ofono on the N900 (not tethering). OK, from what I understand, you should be able to find this device under /sys/class/net/ See if you can find the device there and run: udevadm info --query all --path /sys/class/net/ and udevadm info --attribute-walk --path /sys/class/net. Post that output here if it's sane so that we can see what info udev is giving you for the device. /Jonas From what I understand, I am loading all of the necessary drivers for this to work (nokia-modem, which pulls in its dependencies automaticall). As I stated in my original note, before moving 'legacy device' initialization to udevng, ofono would at least 'see' the modem. The test script 'list-modems' would list it, now it does not list anything. -Clayton On Fri, Sep 08, 2017 at 03:13:03AM +0200, Jonas Bonn wrote: On 09/08/2017 02:51 AM, Clayton Craft wrote: Hi, I've been debugging why the n900 modem is not recognized by ofono for a few days now, and have determined that the cause is because the calls in udevng to udev_device_get_devnode return NULL. It seems that the nokia-modem driver does not create any device nodes under /dev. What bus does this modem sit on? Are you running ofono _on_ the N900 or are you trying to tether the N900 to some system with ofono? If you are tethering, what udev events do you get when you plug in the modem? Try running "udevadm monitor" and watch what happens when you plug the modem in. Not getting a device node sounds mostly like there's a driver missing, though... /Jonas This seems to be a regression in functionality since the move to udevng as previous versions of ofono seem to detect the n900 modem correctly (right before this commit 3ac449e25fc8cb9880c48b8f309189c6a644f200) This issue occurs from this commit onwards, including the latest commit as of this mail. https://git.kernel.org/pub/scm/network/ofono/ofono.git/tree/plugins/udevng.c#n1316 -Clayton ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: nokia-modem (N900) not detected after migration to udevng
On 09/08/2017 03:17 AM, Clayton Craft wrote: This is on HSI bus. I am running ofono on the N900 (not tethering). OK, from what I understand, you should be able to find this device under /sys/class/net/ See if you can find the device there and run: udevadm info --query all --path /sys/class/net/ and udevadm info --attribute-walk --path /sys/class/net. Post that output here if it's sane so that we can see what info udev is giving you for the device. /Jonas From what I understand, I am loading all of the necessary drivers for this to work (nokia-modem, which pulls in its dependencies automaticall). As I stated in my original note, before moving 'legacy device' initialization to udevng, ofono would at least 'see' the modem. The test script 'list-modems' would list it, now it does not list anything. -Clayton On Fri, Sep 08, 2017 at 03:13:03AM +0200, Jonas Bonn wrote: On 09/08/2017 02:51 AM, Clayton Craft wrote: Hi, I've been debugging why the n900 modem is not recognized by ofono for a few days now, and have determined that the cause is because the calls in udevng to udev_device_get_devnode return NULL. It seems that the nokia-modem driver does not create any device nodes under /dev. What bus does this modem sit on? Are you running ofono _on_ the N900 or are you trying to tether the N900 to some system with ofono? If you are tethering, what udev events do you get when you plug in the modem? Try running "udevadm monitor" and watch what happens when you plug the modem in. Not getting a device node sounds mostly like there's a driver missing, though... /Jonas This seems to be a regression in functionality since the move to udevng as previous versions of ofono seem to detect the n900 modem correctly (right before this commit 3ac449e25fc8cb9880c48b8f309189c6a644f200) This issue occurs from this commit onwards, including the latest commit as of this mail. https://git.kernel.org/pub/scm/network/ofono/ofono.git/tree/plugins/udevng.c#n1316 -Clayton ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: nokia-modem (N900) not detected after migration to udevng
This is on HSI bus. I am running ofono on the N900 (not tethering). From what I understand, I am loading all of the necessary drivers for this to work (nokia-modem, which pulls in its dependencies automaticall). As I stated in my original note, before moving 'legacy device' initialization to udevng, ofono would at least 'see' the modem. The test script 'list-modems' would list it, now it does not list anything. -Clayton On Fri, Sep 08, 2017 at 03:13:03AM +0200, Jonas Bonn wrote: On 09/08/2017 02:51 AM, Clayton Craft wrote: Hi, I've been debugging why the n900 modem is not recognized by ofono for a few days now, and have determined that the cause is because the calls in udevng to udev_device_get_devnode return NULL. It seems that the nokia-modem driver does not create any device nodes under /dev. What bus does this modem sit on? Are you running ofono _on_ the N900 or are you trying to tether the N900 to some system with ofono? If you are tethering, what udev events do you get when you plug in the modem? Try running "udevadm monitor" and watch what happens when you plug the modem in. Not getting a device node sounds mostly like there's a driver missing, though... /Jonas This seems to be a regression in functionality since the move to udevng as previous versions of ofono seem to detect the n900 modem correctly (right before this commit 3ac449e25fc8cb9880c48b8f309189c6a644f200) This issue occurs from this commit onwards, including the latest commit as of this mail. https://git.kernel.org/pub/scm/network/ofono/ofono.git/tree/plugins/udevng.c#n1316 -Clayton ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: nokia-modem (N900) not detected after migration to udevng
On 09/08/2017 02:51 AM, Clayton Craft wrote: Hi, I've been debugging why the n900 modem is not recognized by ofono for a few days now, and have determined that the cause is because the calls in udevng to udev_device_get_devnode return NULL. It seems that the nokia-modem driver does not create any device nodes under /dev. What bus does this modem sit on? Are you running ofono _on_ the N900 or are you trying to tether the N900 to some system with ofono? If you are tethering, what udev events do you get when you plug in the modem? Try running "udevadm monitor" and watch what happens when you plug the modem in. Not getting a device node sounds mostly like there's a driver missing, though... /Jonas This seems to be a regression in functionality since the move to udevng as previous versions of ofono seem to detect the n900 modem correctly (right before this commit 3ac449e25fc8cb9880c48b8f309189c6a644f200) This issue occurs from this commit onwards, including the latest commit as of this mail. https://git.kernel.org/pub/scm/network/ofono/ofono.git/tree/plugins/udevng.c#n1316 -Clayton ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: [PATCH][v2 1/2] voicecall, common: move call_status_to_string() to common
Hi Alexander, On 09/07/2017 05:27 PM, Alexander Couzens wrote: call_status_to_string() is useful for debug output. Change signature to contain enum call_status Replace default case to get compiler warning when new enums added --- src/common.c| 22 ++ src/common.h| 1 + src/voicecall.c | 20 3 files changed, 23 insertions(+), 20 deletions(-) Both applied, thanks. Regards, -Denis ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH][v2 2/2] voicecall: use ofono_call_status_name in DBG messages
status names are more readable then integer values. --- src/voicecall.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/voicecall.c b/src/voicecall.c index 408c72162ca7..e5b9f505fbd3 100644 --- a/src/voicecall.c +++ b/src/voicecall.c @@ -2250,9 +2250,10 @@ void ofono_voicecall_notify(struct ofono_voicecall *vc, struct voicecall *v = NULL; struct ofono_call *newcall; - DBG("Got a voicecall event, status: %d, id: %u, number: %s" - " called_number: %s, called_name %s", call->status, - call->id, call->phone_number.number, + DBG("Got a voicecall event, status: %s (%d), id: %u, number: %s" + " called_number: %s, called_name %s", + call_status_to_string(call->status), + call->status, call->id, call->phone_number.number, call->called_number.number, call->name); l = g_slist_find_custom(vc->call_list, GUINT_TO_POINTER(call->id), -- 2.14.1 ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: [PATCH 1/6] voicecall, common: promote call_status_to_string() to be public
Hi Alexander, On 09/07/2017 03:22 PM, Alexander Couzens wrote: call_status_to_string() is useful for debug output. Change signature to contain enum call_status Replace default case to get compiler warning when new enums added --- src/common.c| 21 + src/common.h| 1 + src/voicecall.c | 24 ++-- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/common.c b/src/common.c index ce07b934970d..d99647998a6f 100644 --- a/src/common.c +++ b/src/common.c @@ -743,3 +743,24 @@ void ofono_call_init(struct ofono_call *call) call->cnap_validity = CNAP_VALIDITY_NOT_AVAILABLE; call->clip_validity = CLIP_VALIDITY_NOT_AVAILABLE; } + +const char *ofono_call_status_to_string(enum call_status status) +{ + switch (status) { + case CALL_STATUS_ACTIVE: + return "active"; + case CALL_STATUS_HELD: + return "held"; + case CALL_STATUS_DIALING: + return "dialing"; + case CALL_STATUS_ALERTING: + return "alerting"; + case CALL_STATUS_INCOMING: + return "incoming"; + case CALL_STATUS_WAITING: + return "waiting"; + case CALL_STATUS_DISCONNECTED: + return "disconnected"; + } + return "unknown"; doc/coding-style.txt item M1 +} diff --git a/src/common.h b/src/common.h index 05f2a851bd57..de72bd418792 100644 --- a/src/common.h +++ b/src/common.h @@ -184,3 +184,4 @@ const char *registration_tech_to_string(int tech); const char *packet_bearer_to_string(int bearer); gboolean is_valid_apn(const char *apn); +const char *ofono_call_status_to_string(enum call_status status); This API is still private as it is not placed inside include/ anywhere. So please call it call_status_to_string or properly expose it inside include/voicecall.h, though I'm not sure if that would be useful. diff --git a/src/voicecall.c b/src/voicecall.c index 6907b5025cb4..c99f11fabc01 100644 --- a/src/voicecall.c +++ b/src/voicecall.c @@ -174,26 +174,6 @@ static const char *disconnect_reason_to_string(enum ofono_disconnect_reason r) } } -static const char *call_status_to_string(int status) -{ - switch (status) { - case CALL_STATUS_ACTIVE: - return "active"; - case CALL_STATUS_HELD: - return "held"; - case CALL_STATUS_DIALING: - return "dialing"; - case CALL_STATUS_ALERTING: - return "alerting"; - case CALL_STATUS_INCOMING: - return "incoming"; - case CALL_STATUS_WAITING: - return "waiting"; - default: - return "disconnected"; - } -} - static const char *phone_and_clip_to_string(const struct ofono_phone_number *n, int clip_validity) { @@ -421,7 +401,7 @@ static void append_voicecall_properties(struct voicecall *v, ofono_bool_t mpty; dbus_bool_t emergency_call; - status = call_status_to_string(call->status); + status = ofono_call_status_to_string(call->status); ofono_dbus_dict_append(dict, "State", DBUS_TYPE_STRING, ); @@ -920,7 +900,7 @@ static void voicecall_set_call_status(struct voicecall *call, int status) call->call->status = status; - status_str = call_status_to_string(status); + status_str = ofono_call_status_to_string(status); path = voicecall_build_path(call->vc, call->call); ofono_dbus_signal_property_changed(conn, path, Regards, -Denis ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: [PATCH 6/6] plugins/udevng: use else if instead of if
Hi Alexander, On 09/07/2017 03:23 PM, Alexander Couzens wrote: The same variable is checked in two `if's. --- plugins/udevng.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Applied, thanks. Regards, -Denis ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: [PATCH 5/6] gprs: use registration_status_to_string in debug messages
Hi Alexander, On 09/07/2017 03:22 PM, Alexander Couzens wrote: --- src/gprs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) Applied, thanks. Regards, -Denis ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: [PATCH 4/6] qmimodem: extract network time from serving system
Hi Alexander, On 09/07/2017 03:22 PM, Alexander Couzens wrote: --- drivers/qmimodem/nas.h | 12 +++ drivers/qmimodem/network-registration.c | 37 + 2 files changed, 49 insertions(+) Applied, thanks. Regards, -Denis ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: [PATCH 3/6] qmimodem: add strength (in %) to the debug output
Hi Alexander, On 09/07/2017 03:22 PM, Alexander Couzens wrote: --- drivers/qmimodem/network-registration.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) Applied, thanks. Regards, -Denis ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: [PATCH] udevng/Sierra: use first cdc-wdm interface
Hi Alexander, On 09/07/2017 02:33 PM, Alexander Couzens wrote: Using the voice firmware on a mc7304 the modem stopped accepting qmi messages on the second cdc-wdm interface. --- plugins/udevng.c | 24 1 file changed, 20 insertions(+), 4 deletions(-) Applied, thanks. Regards, -Denis ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: [PATCH 3/3] qmi/discovery: sync the qmi state with the modem
Hi Alexander, On 09/07/2017 02:23 PM, Alexander Couzens wrote: The qmi sync call release all previous resources. Only call sync when the CTL service is >= 1.5 --- drivers/qmimodem/qmi.c | 47 +++ drivers/qmimodem/qmi.h | 5 - plugins/gobi.c | 24 ++-- 3 files changed, 73 insertions(+), 3 deletions(-) Please see HACKING, Submitting Patches section diff --git a/drivers/qmimodem/qmi.c b/drivers/qmimodem/qmi.c index 7ea22992f8f0..fedfb9666c08 100644 --- a/drivers/qmimodem/qmi.c +++ b/drivers/qmimodem/qmi.c @@ -1317,6 +1317,53 @@ bool qmi_device_shutdown(struct qmi_device *device, qmi_shutdown_func_t func, return true; } +struct sync_data { + qmi_sync_func_t func; + void *user_data; +}; + +static void qmi_device_sync_callback(uint16_t message, uint16_t length, +const void *buffer, void *user_data) +{ + struct sync_data *data = user_data; + + if (data->func) + data->func(data->user_data); + + g_free(data); +} + +/* sync will release all previous clients */ +bool qmi_device_sync(struct qmi_device *device, +qmi_sync_func_t func, void *user_data) +{ + struct qmi_request *req; + struct qmi_control_hdr *hdr; + struct sync_data *func_data; + + if (!device) + return false; + + func_data = g_new0(struct sync_data, 1); + func_data->func = func; + func_data->user_data = user_data; + + req = __request_alloc(QMI_SERVICE_CONTROL, 0x00, + QMI_CTL_SYNC, QMI_CONTROL_HDR_SIZE, + NULL, 0, + qmi_device_sync_callback, func_data, (void **) ); + + if (device->next_control_tid < 1) + device->next_control_tid = 1; + + hdr->type = 0x00; + hdr->transaction = device->next_control_tid++; + + __request_submit(device, req, hdr->transaction); + + return true; +} + static bool get_device_file_name(struct qmi_device *device, char *file_name, int size) { diff --git a/drivers/qmimodem/qmi.h b/drivers/qmimodem/qmi.h index b4955b40b1fb..8a348876edb9 100644 --- a/drivers/qmimodem/qmi.h +++ b/drivers/qmimodem/qmi.h @@ -76,7 +76,7 @@ typedef void (*qmi_destroy_func_t)(void *user_data); struct qmi_device; typedef void (*qmi_debug_func_t)(const char *str, void *user_data); - +typedef void (*qmi_sync_func_t)(void *user_data); typedef void (*qmi_shutdown_func_t)(void *user_data); typedef void (*qmi_discover_func_t)(uint8_t count, const struct qmi_version *list, void *user_data); @@ -96,6 +96,9 @@ bool qmi_device_discover(struct qmi_device *device, qmi_discover_func_t func, bool qmi_device_shutdown(struct qmi_device *device, qmi_shutdown_func_t func, void *user_data, qmi_destroy_func_t destroy); +bool qmi_device_sync(struct qmi_device *device, +qmi_sync_func_t func, void *user_data); + enum qmi_device_expected_data_format qmi_device_get_expected_data_format( struct qmi_device *device); bool qmi_device_set_expected_data_format(struct qmi_device *device, diff --git a/plugins/gobi.c b/plugins/gobi.c index a49859901f2f..40eefdfc867b 100644 --- a/plugins/gobi.c +++ b/plugins/gobi.c @@ -252,6 +252,15 @@ error: shutdown_device(modem); } +static void create_shared_dms(void *user_data) +{ + struct ofono_modem *modem = user_data; + struct gobi_data *data = ofono_modem_get_data(modem); + + qmi_service_create_shared(data->device, QMI_SERVICE_DMS, + create_dms_cb, modem, NULL); +} + static void discover_cb(uint8_t count, const struct qmi_version *list, void *user_data) { @@ -266,6 +275,15 @@ static void discover_cb(uint8_t count, const struct qmi_version *list, list[i].type); switch (list[i].type) { + case QMI_SERVICE_CONTROL: + /* sync command resets the QMI state */ + if (list[i].major > 1 || + (list[i].major == 1 && +list[i].minor >= 5)) + ofono_modem_set_boolean(modem, + "SupportQMISync", + TRUE); + break; This really belongs as an API on qmi_device and not some property on the modem. E.g. qmi_device_get_control_version or qmi_device_is_sync_supported case QMI_SERVICE_DMS: data->features |= GOBI_DMS; break; @@ -314,8 +332,10 @@ static void discover_cb(uint8_t count, const struct
Re: [PATCH 2/3] qmi/discovery: include control service into service list
Hi Alexander, On 09/07/2017 02:23 PM, Alexander Couzens wrote: There is no need to exclude it. It helps debugging because the service is now logged. --- drivers/qmimodem/qmi.c | 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/qmimodem/qmi.c b/drivers/qmimodem/qmi.c index 1af86aaccb08..7ea22992f8f0 100644 --- a/drivers/qmimodem/qmi.c +++ b/drivers/qmimodem/qmi.c @@ -1136,15 +1136,12 @@ static void discover_callback(uint16_t message, uint16_t length, if (type == QMI_SERVICE_CONTROL) { device->control_major = major; device->control_minor = minor; - continue; } - list[count].type = type; - list[count].major = major; - list[count].minor = minor; - list[count].name = name; - - count++; + list[i].type = type; + list[i].major = major; + list[i].minor = minor; + list[i].name = name; We store the CONTROL service minor and major numbers and generally treat it specially. If you care about logging it, why not just add an extra debug statement? if (name) __debug_device(device, "found service [%s %d.%d]", @@ -1154,6 +1151,8 @@ static void discover_callback(uint16_t message, uint16_t length, type, major, minor); } + count = service_list->count; + ptr = tlv_get(buffer, length, 0x10, ); if (!ptr) goto done; Regards, -Denis ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: [PATCH 1/3] qmi/discovery: remove useless code
Hi Alexander, On 09/07/2017 02:23 PM, Alexander Couzens wrote: --- drivers/qmimodem/qmi.c | 5 - 1 file changed, 5 deletions(-) diff --git a/drivers/qmimodem/qmi.c b/drivers/qmimodem/qmi.c index c538cb978393..1af86aaccb08 100644 --- a/drivers/qmimodem/qmi.c +++ b/drivers/qmimodem/qmi.c @@ -1162,11 +1162,6 @@ static void discover_callback(uint16_t message, uint16_t length, service_list = ptr + *((uint8_t *) ptr) + 1; Why don't you also take out that service_list assignment as well? - for (i = 0; i < service_list->count; i++) { - if (service_list->services[i].type == QMI_SERVICE_CONTROL) - continue; - } - done: device->version_list = list; device->version_count = count; Regards, -Denis ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: how to handle ofono_netreg_status_notify() without valid LAC or cellid or status
Hi Alexander, On 09/07/2017 03:49 PM, Alexander Couzens wrote: Hi, I've noticed when using a Quectel EC20 (qmimodem) sometimes I see a LAC and a cellid, sometimes I do not. After looking into it, the problems lies in the ofono plugin api or in the qmimodem driver. I'm unsure where I should fix this issue. The problem: The qmimodem notifies ofono about any change of lac, ci, tech or status. But the qmimodem will only include those items which have been changed, not all. But ofono doesn't allow only to update one single item, only all of them at the same time. void ofono_netreg_status_notify(struct ofono_netreg *netreg, int status, int lac, int ci, int tech) If lac or ci is `-1` it seems to mean invalid (TODO: create a define or enum) So how to fix this? a) when something change, do another call to get all values from the modem That sounds expensive, why do you want to incur extra round-trips? b) extend the ofono api to allow `#define NO_CHANGE -2` for lac ci tech, status Eww, please don't ;) FYI, we long time ago decided to base the driver API on what is mandated by 27.007. In the case where things are skipped by 27.007 we improvise. However, in this case all the parameters are updated via +CREG, so I don't really want to introduce new semantics. The driver has to handle this. c) unlikely: buffer the old values in the driver/qmimodem code This sounds best so far. What don't you like about this approach? Regards, -Denis ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
how to handle ofono_netreg_status_notify() without valid LAC or cellid or status
Hi, I've noticed when using a Quectel EC20 (qmimodem) sometimes I see a LAC and a cellid, sometimes I do not. After looking into it, the problems lies in the ofono plugin api or in the qmimodem driver. I'm unsure where I should fix this issue. The problem: The qmimodem notifies ofono about any change of lac, ci, tech or status. But the qmimodem will only include those items which have been changed, not all. But ofono doesn't allow only to update one single item, only all of them at the same time. void ofono_netreg_status_notify(struct ofono_netreg *netreg, int status, int lac, int ci, int tech) If lac or ci is `-1` it seems to mean invalid (TODO: create a define or enum) So how to fix this? a) when something change, do another call to get all values from the modem b) extend the ofono api to allow `#define NO_CHANGE -2` for lac ci tech, status c) unlikely: buffer the old values in the driver/qmimodem code d) ?? Regards, Alexander -- Alexander Couzens mail: lyn...@fe80.eu jabber: lyn...@fe80.eu mobile: +4915123277221 gpg: 390D CF78 8BF9 AA50 4F8F F1E2 C29E 9DA6 A0DF 8604 pgpyqTWnid96P.pgp Description: OpenPGP digital signature ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH 6/6] plugins/udevng: use else if instead of if
The same variable is checked in two `if's. --- plugins/udevng.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/udevng.c b/plugins/udevng.c index aa28bcb8911e..0f6ab2b21d77 100644 --- a/plugins/udevng.c +++ b/plugins/udevng.c @@ -261,7 +261,7 @@ static gboolean setup_sierra(struct modem_info *modem) if (g_strcmp0(info->interface, "255/255/255") == 0) { if (g_strcmp0(info->number, "01") == 0) diag = info->devnode; - if (g_strcmp0(info->number, "03") == 0) + else if (g_strcmp0(info->number, "03") == 0) mdm = info->devnode; else if (g_strcmp0(info->number, "04") == 0) app = info->devnode; -- 2.14.1 ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH 5/6] gprs: use registration_status_to_string in debug messages
--- src/gprs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gprs.c b/src/gprs.c index a4132cc06760..420c96f92238 100644 --- a/src/gprs.c +++ b/src/gprs.c @@ -2596,7 +2596,8 @@ void ofono_gprs_detached_notify(struct ofono_gprs *gprs) void ofono_gprs_status_notify(struct ofono_gprs *gprs, int status) { - DBG("%s status %d", __ofono_atom_get_path(gprs->atom), status); + DBG("%s status %s (%d)", __ofono_atom_get_path(gprs->atom), + registration_status_to_string(status), status); gprs->status = status; -- 2.14.1 ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH 1/6] voicecall, common: promote call_status_to_string() to be public
call_status_to_string() is useful for debug output. Change signature to contain enum call_status Replace default case to get compiler warning when new enums added --- src/common.c| 21 + src/common.h| 1 + src/voicecall.c | 24 ++-- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/common.c b/src/common.c index ce07b934970d..d99647998a6f 100644 --- a/src/common.c +++ b/src/common.c @@ -743,3 +743,24 @@ void ofono_call_init(struct ofono_call *call) call->cnap_validity = CNAP_VALIDITY_NOT_AVAILABLE; call->clip_validity = CLIP_VALIDITY_NOT_AVAILABLE; } + +const char *ofono_call_status_to_string(enum call_status status) +{ + switch (status) { + case CALL_STATUS_ACTIVE: + return "active"; + case CALL_STATUS_HELD: + return "held"; + case CALL_STATUS_DIALING: + return "dialing"; + case CALL_STATUS_ALERTING: + return "alerting"; + case CALL_STATUS_INCOMING: + return "incoming"; + case CALL_STATUS_WAITING: + return "waiting"; + case CALL_STATUS_DISCONNECTED: + return "disconnected"; + } + return "unknown"; +} diff --git a/src/common.h b/src/common.h index 05f2a851bd57..de72bd418792 100644 --- a/src/common.h +++ b/src/common.h @@ -184,3 +184,4 @@ const char *registration_tech_to_string(int tech); const char *packet_bearer_to_string(int bearer); gboolean is_valid_apn(const char *apn); +const char *ofono_call_status_to_string(enum call_status status); diff --git a/src/voicecall.c b/src/voicecall.c index 6907b5025cb4..c99f11fabc01 100644 --- a/src/voicecall.c +++ b/src/voicecall.c @@ -174,26 +174,6 @@ static const char *disconnect_reason_to_string(enum ofono_disconnect_reason r) } } -static const char *call_status_to_string(int status) -{ - switch (status) { - case CALL_STATUS_ACTIVE: - return "active"; - case CALL_STATUS_HELD: - return "held"; - case CALL_STATUS_DIALING: - return "dialing"; - case CALL_STATUS_ALERTING: - return "alerting"; - case CALL_STATUS_INCOMING: - return "incoming"; - case CALL_STATUS_WAITING: - return "waiting"; - default: - return "disconnected"; - } -} - static const char *phone_and_clip_to_string(const struct ofono_phone_number *n, int clip_validity) { @@ -421,7 +401,7 @@ static void append_voicecall_properties(struct voicecall *v, ofono_bool_t mpty; dbus_bool_t emergency_call; - status = call_status_to_string(call->status); + status = ofono_call_status_to_string(call->status); ofono_dbus_dict_append(dict, "State", DBUS_TYPE_STRING, ); @@ -920,7 +900,7 @@ static void voicecall_set_call_status(struct voicecall *call, int status) call->call->status = status; - status_str = call_status_to_string(status); + status_str = ofono_call_status_to_string(status); path = voicecall_build_path(call->vc, call->call); ofono_dbus_signal_property_changed(conn, path, -- 2.14.1 ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH 2/6] voicecall: use ofono_call_status_name in DBG messages
status names are more readable then integer values. --- src/voicecall.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/voicecall.c b/src/voicecall.c index c99f11fabc01..e3ae80cfd914 100644 --- a/src/voicecall.c +++ b/src/voicecall.c @@ -2250,9 +2250,10 @@ void ofono_voicecall_notify(struct ofono_voicecall *vc, struct voicecall *v = NULL; struct ofono_call *newcall; - DBG("Got a voicecall event, status: %d, id: %u, number: %s" - " called_number: %s, called_name %s", call->status, - call->id, call->phone_number.number, + DBG("Got a voicecall event, status: %s (%d), id: %u, number: %s" + " called_number: %s, called_name %s", + ofono_call_status_to_string(call->status), + call->status, call->id, call->phone_number.number, call->called_number.number, call->name); l = g_slist_find_custom(vc->call_list, GUINT_TO_POINTER(call->id), -- 2.14.1 ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH 3/6] qmimodem: add strength (in %) to the debug output
--- drivers/qmimodem/network-registration.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/qmimodem/network-registration.c b/drivers/qmimodem/network-registration.c index 04de5a5b87f9..41caa414477b 100644 --- a/drivers/qmimodem/network-registration.c +++ b/drivers/qmimodem/network-registration.c @@ -450,10 +450,11 @@ static void event_notify(struct qmi_result *result, void *user_data) if (ss) { int strength; - DBG("signal with %d dBm on %d", ss->dbm, ss->rat); - strength = dbm_to_strength(ss->dbm); + DBG("signal with %d%%(%d dBm) on %d", + strength, ss->dbm, ss->rat); + ofono_netreg_strength_notify(netreg, strength); } -- 2.14.1 ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH 4/6] qmimodem: extract network time from serving system
--- drivers/qmimodem/nas.h | 12 +++ drivers/qmimodem/network-registration.c | 37 + 2 files changed, 49 insertions(+) diff --git a/drivers/qmimodem/nas.h b/drivers/qmimodem/nas.h index c3e7546bbfa1..9f67707ea721 100644 --- a/drivers/qmimodem/nas.h +++ b/drivers/qmimodem/nas.h @@ -152,6 +152,18 @@ struct qmi_nas_current_plmn { #define QMI_NAS_REGISTRATION_STATE_DENIED 0x03 #define QMI_NAS_REGISTRATION_STATE_UNKNOWN 0x04 +#define QMI_NAS_RESULT_3GGP_DST 0x1b +#define QMI_NAS_RESULT_3GPP_TIME 0x1c +struct qmi_nas_3gpp_time { + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t minute; + uint8_t second; + uint8_t timezone; +} __attribute__((__packed__)); + /* cs_state/ps_state */ #define QMI_NAS_ATTACH_STATE_INVALID 0x00 #define QMI_NAS_ATTACH_STATE_ATTACHED 0x01 diff --git a/drivers/qmimodem/network-registration.c b/drivers/qmimodem/network-registration.c index 41caa414477b..c88e80bdf711 100644 --- a/drivers/qmimodem/network-registration.c +++ b/drivers/qmimodem/network-registration.c @@ -23,6 +23,7 @@ #include #endif +#include #include #include #include @@ -43,6 +44,38 @@ struct netreg_data { uint8_t current_rat; }; +static bool extract_ss_info_time( + struct qmi_result *result, + struct ofono_network_time *time) +{ + const struct qmi_nas_3gpp_time *time_3gpp = NULL; + uint8_t dst_3gpp; + bool dst_3gpp_valid; + uint16_t len; + + /* parse 3gpp time & dst */ + dst_3gpp_valid = qmi_result_get_uint8(result, QMI_NAS_RESULT_3GGP_DST, + _3gpp); + + time_3gpp = qmi_result_get(result, QMI_NAS_RESULT_3GPP_TIME, ); + if (time_3gpp && len == sizeof(struct qmi_nas_3gpp_time) && + dst_3gpp_valid) { + time->year = le16toh(time_3gpp->year); + time->mon = time_3gpp->month; + time->mday = time_3gpp->day; + time->hour = time_3gpp->hour; + time->min = time_3gpp->minute; + time->sec = time_3gpp->second; + time->utcoff = time_3gpp->timezone * 15 * 60; + time->dst = dst_3gpp; + return true; + } + + /* TODO: 3gpp2 */ + + return false; +} + static bool extract_ss_info(struct qmi_result *result, int *status, int *lac, int *cellid, int *tech, struct ofono_network_operator *operator) @@ -124,11 +157,15 @@ static bool extract_ss_info(struct qmi_result *result, int *status, static void ss_info_notify(struct qmi_result *result, void *user_data) { struct ofono_netreg *netreg = user_data; + struct ofono_network_time net_time; struct netreg_data *data = ofono_netreg_get_data(netreg); int status, lac, cellid, tech; DBG(""); + if (extract_ss_info_time(result, _time)) + ofono_netreg_time_notify(netreg, _time); + if (!extract_ss_info(result, , , , , >operator)) return; -- 2.14.1 ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH] udevng/Sierra: use first cdc-wdm interface
Using the voice firmware on a mc7304 the modem stopped accepting qmi messages on the second cdc-wdm interface. --- plugins/udevng.c | 24 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/plugins/udevng.c b/plugins/udevng.c index aa28bcb8911e..1e716a60334b 100644 --- a/plugins/udevng.c +++ b/plugins/udevng.c @@ -267,12 +267,28 @@ static gboolean setup_sierra(struct modem_info *modem) app = info->devnode; else if (g_strcmp0(info->number, "07") == 0) net = info->devnode; - else if (g_strcmp0(info->number, "0a") == 0) { - if (g_strcmp0(info->subsystem, "net") == 0) + else if (g_strcmp0(info->subsystem, "net") == 0) { + /* +* When using the voice firmware on a mc7304 +* the second cdc-wdm interface doesn't handle +* qmi messages properly. +* Some modems still have a working second +* cdc-wdm interface, some are not. But always +* the first interface works. +*/ + if (g_strcmp0(info->number, "08") == 0) { net = info->devnode; - else if (g_strcmp0(info->subsystem, - "usbmisc") == 0) + } else if (g_strcmp0(info->number, "0a") == 0) { + if (net == NULL) + net = info->devnode; + } + } else if (g_strcmp0(info->subsystem, "usbmisc") == 0) { + if (g_strcmp0(info->number, "08") == 0) { qmi = info->devnode; + } else if (g_strcmp0(info->number, "0a") == 0) { + if (qmi == NULL) + qmi = info->devnode; + } } } } -- 2.14.1 ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH 1/3] qmi/discovery: remove useless code
--- drivers/qmimodem/qmi.c | 5 - 1 file changed, 5 deletions(-) diff --git a/drivers/qmimodem/qmi.c b/drivers/qmimodem/qmi.c index c538cb978393..1af86aaccb08 100644 --- a/drivers/qmimodem/qmi.c +++ b/drivers/qmimodem/qmi.c @@ -1162,11 +1162,6 @@ static void discover_callback(uint16_t message, uint16_t length, service_list = ptr + *((uint8_t *) ptr) + 1; - for (i = 0; i < service_list->count; i++) { - if (service_list->services[i].type == QMI_SERVICE_CONTROL) - continue; - } - done: device->version_list = list; device->version_count = count; -- 2.14.1 ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH 3/3] qmi/discovery: sync the qmi state with the modem
The qmi sync call release all previous resources. Only call sync when the CTL service is >= 1.5 --- drivers/qmimodem/qmi.c | 47 +++ drivers/qmimodem/qmi.h | 5 - plugins/gobi.c | 24 ++-- 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/drivers/qmimodem/qmi.c b/drivers/qmimodem/qmi.c index 7ea22992f8f0..fedfb9666c08 100644 --- a/drivers/qmimodem/qmi.c +++ b/drivers/qmimodem/qmi.c @@ -1317,6 +1317,53 @@ bool qmi_device_shutdown(struct qmi_device *device, qmi_shutdown_func_t func, return true; } +struct sync_data { + qmi_sync_func_t func; + void *user_data; +}; + +static void qmi_device_sync_callback(uint16_t message, uint16_t length, +const void *buffer, void *user_data) +{ + struct sync_data *data = user_data; + + if (data->func) + data->func(data->user_data); + + g_free(data); +} + +/* sync will release all previous clients */ +bool qmi_device_sync(struct qmi_device *device, +qmi_sync_func_t func, void *user_data) +{ + struct qmi_request *req; + struct qmi_control_hdr *hdr; + struct sync_data *func_data; + + if (!device) + return false; + + func_data = g_new0(struct sync_data, 1); + func_data->func = func; + func_data->user_data = user_data; + + req = __request_alloc(QMI_SERVICE_CONTROL, 0x00, + QMI_CTL_SYNC, QMI_CONTROL_HDR_SIZE, + NULL, 0, + qmi_device_sync_callback, func_data, (void **) ); + + if (device->next_control_tid < 1) + device->next_control_tid = 1; + + hdr->type = 0x00; + hdr->transaction = device->next_control_tid++; + + __request_submit(device, req, hdr->transaction); + + return true; +} + static bool get_device_file_name(struct qmi_device *device, char *file_name, int size) { diff --git a/drivers/qmimodem/qmi.h b/drivers/qmimodem/qmi.h index b4955b40b1fb..8a348876edb9 100644 --- a/drivers/qmimodem/qmi.h +++ b/drivers/qmimodem/qmi.h @@ -76,7 +76,7 @@ typedef void (*qmi_destroy_func_t)(void *user_data); struct qmi_device; typedef void (*qmi_debug_func_t)(const char *str, void *user_data); - +typedef void (*qmi_sync_func_t)(void *user_data); typedef void (*qmi_shutdown_func_t)(void *user_data); typedef void (*qmi_discover_func_t)(uint8_t count, const struct qmi_version *list, void *user_data); @@ -96,6 +96,9 @@ bool qmi_device_discover(struct qmi_device *device, qmi_discover_func_t func, bool qmi_device_shutdown(struct qmi_device *device, qmi_shutdown_func_t func, void *user_data, qmi_destroy_func_t destroy); +bool qmi_device_sync(struct qmi_device *device, +qmi_sync_func_t func, void *user_data); + enum qmi_device_expected_data_format qmi_device_get_expected_data_format( struct qmi_device *device); bool qmi_device_set_expected_data_format(struct qmi_device *device, diff --git a/plugins/gobi.c b/plugins/gobi.c index a49859901f2f..40eefdfc867b 100644 --- a/plugins/gobi.c +++ b/plugins/gobi.c @@ -252,6 +252,15 @@ error: shutdown_device(modem); } +static void create_shared_dms(void *user_data) +{ + struct ofono_modem *modem = user_data; + struct gobi_data *data = ofono_modem_get_data(modem); + + qmi_service_create_shared(data->device, QMI_SERVICE_DMS, + create_dms_cb, modem, NULL); +} + static void discover_cb(uint8_t count, const struct qmi_version *list, void *user_data) { @@ -266,6 +275,15 @@ static void discover_cb(uint8_t count, const struct qmi_version *list, list[i].type); switch (list[i].type) { + case QMI_SERVICE_CONTROL: + /* sync command resets the QMI state */ + if (list[i].major > 1 || + (list[i].major == 1 && +list[i].minor >= 5)) + ofono_modem_set_boolean(modem, + "SupportQMISync", + TRUE); + break; case QMI_SERVICE_DMS: data->features |= GOBI_DMS; break; @@ -314,8 +332,10 @@ static void discover_cb(uint8_t count, const struct qmi_version *list, return; } - qmi_service_create_shared(data->device, QMI_SERVICE_DMS, - create_dms_cb, modem, NULL); + if (ofono_modem_get_boolean(modem, "SupportQMISync") == TRUE) +
Re: [PATCH 5/5] qmi: add NetworkMonitor interface
Hi Jonas, On 09/07/2017 07:11 AM, Jonas Bonn wrote: This is a rudimentary implementation that contains technology, RSSI, and BitErrorRate, plus RSRQ/RSRP for LTE networks. More data can be added as needed. This implementations uses the 'Get Signal Strength' QMI method to retrieve the data. Operator fields (MNC, LAC, etc) can be gotten from the 'Serving Cell' method if needed, but since this data is already provided in the NetworkRegistration object it doesn't seem necessary to repeat it here when an additional communication to the modem is required. --- Makefile.am | 3 +- doc/networkmonitor-api.txt | 2 +- separate patch please drivers/qmimodem/netmon.c | 285 drivers/qmimodem/qmimodem.c | 2 + drivers/qmimodem/qmimodem.h | 3 + plugins/gobi.c | 5 +- separate patch. see HACKING, 'Submitting Patches'. 6 files changed, 297 insertions(+), 3 deletions(-) create mode 100644 drivers/qmimodem/netmon.c diff --git a/Makefile.am b/Makefile.am index 658e152..4b68beb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -233,7 +233,8 @@ builtin_sources += $(qmi_sources) \ drivers/qmimodem/gprs.c \ drivers/qmimodem/gprs-context.c \ drivers/qmimodem/radio-settings.c \ - drivers/qmimodem/location-reporting.c + drivers/qmimodem/location-reporting.c \ + drivers/qmimodem/netmon.c builtin_modules += gobi builtin_sources += plugins/gobi.c diff --git a/doc/networkmonitor-api.txt b/doc/networkmonitor-api.txt index ddace7e..8d73af0 100644 --- a/doc/networkmonitor-api.txt +++ b/doc/networkmonitor-api.txt @@ -77,7 +77,7 @@ byte TimingAdvance [optional, gsm] Contains the Timing Advance. Valid range of values is 0-219. -byte Strength [optional, gsm, umts] +byte Strength [optional, gsm, umts, lte] Contains the signal strength. Valid values are 0-31. Refer to in 27.007, Section 8.5. diff --git a/drivers/qmimodem/netmon.c b/drivers/qmimodem/netmon.c new file mode 100644 index 000..9fef0d4 --- /dev/null +++ b/drivers/qmimodem/netmon.c @@ -0,0 +1,285 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2017 Jonas Bonn. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +//#include "common.h" ?? + +#include "qmi.h" +#include "nas.h" + +#include "qmimodem.h" +#include "src/common.h" + +struct netmon_data { + struct qmi_service *nas; +}; + +static void get_rssi_cb(struct qmi_result *result, void *user_data) +{ + struct cb_data *cbd = user_data; + struct ofono_netmon *netmon = cbd->user; + ofono_netmon_cb_t cb = cbd->cb; + struct { + enum ofono_netmon_cell_type type; + int rssi; + int ber; + int rsrq; + int rsrp; + } props; + uint16_t len; + int16_t rsrp; + const struct { + int8_t value; + int8_t rat; + } __attribute__((__packed__)) *rsrq; + const struct { + uint16_t count; + struct { + uint8_t rssi; + int8_t rat; + } __attribute__((__packed__)) info[0]; + } __attribute__((__packed__)) *rssi; + const struct { + uint16_t count; + struct { + uint16_t rate; + int8_t rat; + } __attribute__((__packed__)) info[0]; + } __attribute__((__packed__)) *ber; + int i; + + DBG(""); + + if (qmi_result_set_error(result, NULL)) { + CALLBACK_WITH_FAILURE(cb, cbd->data); + return; + } + + /* RSSI */ + rssi = qmi_result_get(result, 0x11, ); + if (rssi) { + for (i = 0; i < rssi->count; i++) { + DBG("RSSI: %hhu on RAT %hhd", + rssi->info[i].rssi, + rssi->info[i].rat); + } + + /* Get cell type from RSSI info... it
Re: [PATCH 1/7] netmon: modified api.txt for network monitor agent
Hi Slava, In the Sailfish OS case, one is the positioning helper, and there's the factory test app. That makes it at least two. The factory test app often plays the role of the second client since it's touching pretty much all the important interfaces in the system. And there are 3rd party apps which we don't control. See? This wasn't that hard ;) How does the factory test app use this info? Does it need actual periodic updates or can it simply obtain this via the method call? I'm open to the idea of supporting multiple agents. We do have to figure out who dictates the periodic update interval. One approach might be to have a single master agent and multiple observer agents. Feel free to propose something. Regards, -Denis ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: [PATCH 1/7] netmon: modified api.txt for network monitor agent
On 07/09/17 19:05, Denis Kenzior wrote: Hi Slava, On 09/07/2017 08:06 AM, Slava Monich wrote: On 07/09/17 12:47, Jonas Bonn wrote: On 09/07/2017 06:23 AM, Nishanth V wrote: added new DBUS methods RegisterAgent and UnregisterAgent to Networkmonitor interface so that any client of ofono can register for serving cell updates. Added new agent interface NetworkMonitorAgent with two methods, ServingCellInformationChanged and Release. My spontaneous reaction to this is that it feels like the wrong approach. Why not make the properties actual DBus properties and provide PropertiesChanged events for them? That begets you the same functionality for "free". The implementation also seems to limit the number of clients receiving those cell change notifications to just one. Why? In real life more than one process may need those. You keep saying that, but never provide concrete scenarios how this could be 'useful'? I am tempted to simply ignore such feedback in the future. In the Sailfish OS case, one is the positioning helper, and there's the factory test app. That makes it at least two. The factory test app often plays the role of the second client since it's touching pretty much all the important interfaces in the system. And there are 3rd party apps which we don't control. For now I don't see why we would want to have multiple agents registered and to keep the implementation simple we will only support one. That's fine, we are using a different interface for getting cell information anyway. Go ahead and ignore the feedback. Cheers, -Slava Regards, -Denis ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: [PATCH 3/5] qmi: provide AvailableTechnologies in radio-settings
Hi Jonas, On 09/07/2017 07:11 AM, Jonas Bonn wrote: This provides the list of available technologies in the radio-settings atom. Note that this list is hard-coded and includes LTE unconditionally which is probably not correct for all QMI devices. I don't like this idea. There has to be a way to figure out the capability, either from udev or QMI protocol. Does the command Christophe mentioned work for this? --- drivers/qmimodem/radio-settings.c | 14 ++ 1 file changed, 14 insertions(+) Regards, -Denis ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: [PATCH 2/5] qmi: implement RAT selection
Hi Jonas, On 09/07/2017 07:11 AM, Jonas Bonn wrote: The QMI radio-settings atom was just a skeleton and did not even implement the mandtory property TechnologyPreference. As such, it probably should never even have been registered for the modem. Nonetheless, this patch puts this mandatory property into place. This is implemented via the 'Set System Selection' method by way of the 'mode' parameter. This seems to best reflect the intention of the Ofono API and works as expected when tested with a Quectel EC21. Some notes: i) There is an alternative function called 'Set Technology Preference' which provides similar functionality. This 'technology preference' is updated automatically when the 'system selection mode' is modified so everything seems to be in order. ii) For the EC21, switching the underlying technology works seamlessly. There are indications, however, that some modems _might_ require a reset before changes take effect; that bridge will need to be crossed if reached. --- drivers/qmimodem/nas.h| 11 drivers/qmimodem/radio-settings.c | 119 ++ 2 files changed, 130 insertions(+) I squashed a couple of extraneous empty lines and applied this patch. Thanks! Regards, -Denis ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: [PATCH 2/2] atmodem: correctly report lte bearer for huawei modems
Hi Christophe, On 09/06/2017 04:42 AM, Christophe Ronco wrote: --- drivers/atmodem/gprs.c | 22 ++ drivers/atmodem/network-registration.c | 25 + 2 files changed, 47 insertions(+) Applied, thanks. Regards, -Denis ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: [PATCH 1/2] huawei: add LTE support
Hi Christophe, On 09/06/2017 04:42 AM, Christophe Ronco wrote: Huawei LTE modems use AT^SYSCFGEX and AT^SYSINFOEX instead of AT^SYSCFG and AT^SYSINFO. If we want to be able to attach on LTE with this modem, we must use AT^SYSCFGEX to configure rat mode and band. Using AT^SYSCFG, mode any means UMTS or GSM. --- drivers/huaweimodem/radio-settings.c | 213 --- 1 file changed, 197 insertions(+), 16 deletions(-) diff --git a/drivers/huaweimodem/radio-settings.c b/drivers/huaweimodem/radio-settings.c index c34653a..5eb93f6 100644 --- a/drivers/huaweimodem/radio-settings.c +++ b/drivers/huaweimodem/radio-settings.c @@ -42,11 +42,13 @@ static const char *none_prefix[] = { NULL }; static const char *syscfg_prefix[] = { "^SYSCFG:", NULL }; +static const char *syscfgex_prefix[] = { "^SYSCFGEX:", NULL }; #define HUAWEI_BAND_ANY 0x3FFF struct radio_settings_data { GAtChat *chat; + ofono_bool_t syscfgex_cap; }; static const struct huawei_band_gsm_table { @@ -176,20 +178,81 @@ error: CALLBACK_WITH_FAILURE(cb, -1, cbd->data); } +static void syscfgex_query_mode_cb(gboolean ok, GAtResult *result, + gpointer user_data) +{ + struct cb_data *cbd = user_data; + ofono_radio_settings_rat_mode_query_cb_t cb = cbd->cb; + enum ofono_radio_access_mode mode; + struct ofono_error error; + GAtResultIter iter; + const char *acqorder; + + decode_at_error(, g_at_result_final_response(result)); + + if (!ok) { + cb(, -1, cbd->data); + return; + } + + g_at_result_iter_init(, result); + + if (g_at_result_iter_next(, "^SYSCFGEX:") == FALSE) + goto error; + + if (g_at_result_iter_next_string(, ) == FALSE) + goto error; + + mode = OFONO_RADIO_ACCESS_MODE_ANY; + if (strstr(acqorder, "01")) + mode |= OFONO_RADIO_ACCESS_MODE_GSM; + if (strstr(acqorder, "02")) + mode |= OFONO_RADIO_ACCESS_MODE_UMTS; + if (strstr(acqorder, "03")) + mode |= OFONO_RADIO_ACCESS_MODE_LTE; So what happens if we get back something like "030201" (e.g. LTE->WCDMA->GSM)? We will get a value of '7' being reported to the core, which isn't handled by src/radio-settings.c:radio_access_mode_to_string(). oFono does not support ordered technology preferences. Maybe this is something we should add in the future, but some firmware doesn't support this. + + if (mode == OFONO_RADIO_ACCESS_MODE_ANY) { + if (strstr(acqorder, "00") == NULL) { strcmp? + DBG("Can't interpret SYSCFGEX mode: %s", + acqorder); + goto error; + } + } + + cb(, mode, cbd->data); + + return; + +error: + CALLBACK_WITH_FAILURE(cb, -1, cbd->data); +} + static void huawei_query_rat_mode(struct ofono_radio_settings *rs, ofono_radio_settings_rat_mode_query_cb_t cb, void *data) { struct radio_settings_data *rsd = ofono_radio_settings_get_data(rs); struct cb_data *cbd = cb_data_new(cb, data); - if (g_at_chat_send(rsd->chat, "AT^SYSCFG?", syscfg_prefix, - syscfg_query_mode_cb, cbd, g_free) == 0) { - CALLBACK_WITH_FAILURE(cb, -1, data); - g_free(cbd); + if (rsd->syscfgex_cap) { + if (g_at_chat_send(rsd->chat, "AT^SYSCFGEX?", + syscfgex_prefix, + syscfgex_query_mode_cb, + cbd, g_free) == 0) { + CALLBACK_WITH_FAILURE(cb, -1, data); + g_free(cbd); if (rsd->syscfgex_cap && g_at_chat_send(...) > 0) return; if (!rsd->syscfgex_cap && g_at_chat_send(...) > 0) return; CALLBACK... g_free() + } + } else { + if (g_at_chat_send(rsd->chat, "AT^SYSCFG?", + syscfg_prefix, + syscfg_query_mode_cb, + cbd, g_free) == 0) { + CALLBACK_WITH_FAILURE(cb, -1, data); + g_free(cbd); + } } } -static void syscfg_modify_mode_cb(gboolean ok, GAtResult *result, +static void syscfgxx_modify_mode_cb(gboolean ok, GAtResult *result, gpointer user_data) { struct cb_data *cbd = user_data; @@ -200,12 +263,11 @@ static void syscfg_modify_mode_cb(gboolean ok, GAtResult *result, cb(, cbd->data); } -static void huawei_set_rat_mode(struct ofono_radio_settings *rs, +static void syscfg_set_rat_mode(struct radio_settings_data *rsd, enum
Re: [PATCH 1/7] netmon: modified api.txt for network monitor agent
Hi Slava, On 09/07/2017 08:06 AM, Slava Monich wrote: On 07/09/17 12:47, Jonas Bonn wrote: On 09/07/2017 06:23 AM, Nishanth V wrote: added new DBUS methods RegisterAgent and UnregisterAgent to Networkmonitor interface so that any client of ofono can register for serving cell updates. Added new agent interface NetworkMonitorAgent with two methods, ServingCellInformationChanged and Release. My spontaneous reaction to this is that it feels like the wrong approach. Why not make the properties actual DBus properties and provide PropertiesChanged events for them? That begets you the same functionality for "free". The implementation also seems to limit the number of clients receiving those cell change notifications to just one. Why? In real life more than one process may need those. You keep saying that, but never provide concrete scenarios how this could be 'useful'? I am tempted to simply ignore such feedback in the future. For now I don't see why we would want to have multiple agents registered and to keep the implementation simple we will only support one. Regards, -Denis ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: [PATCH 1/7] netmon: modified api.txt for network monitor agent
Hi Jonas, On 09/07/2017 04:47 AM, Jonas Bonn wrote: On 09/07/2017 06:23 AM, Nishanth V wrote: added new DBUS methods RegisterAgent and UnregisterAgent to Networkmonitor interface so that any client of ofono can register for serving cell updates. Added new agent interface NetworkMonitorAgent with two methods, ServingCellInformationChanged and Release. My spontaneous reaction to this is that it feels like the wrong approach. Why not make the properties actual DBus properties and provide PropertiesChanged events for them? That begets you the same functionality for "free". Because most clients don't care about these properties, so there's no sense in broadcasting them out to the wide world. Even if nobody actually subscribes to the PropertyChanged signal on this interface we still must send messages to the dbus daemon, and that means extra context switches, extra cpu time, etc. Besides, this interface will be eventually expanded to cover neighbor cells as well. And that can get quite chatty. It's interesting that you posted this now because I've spent the last week grumbling over this API myself as I'm putting support for the NetworkMonitor interface into the QMI modem class. My thoughts: i) There's duplicate information all over the place. MNC, LAC, etc. are provided in three different interefaces: NetworkRegistration, NetworkMonitor, and NetworkOperator. Why is this a problem? And strictly speaking NetworkOperator only provides MNC/MCC which can be different from the current serving cell. This can be used by the user to select a particular operator to register with. ii) The NetworkOperator interface caught me off guard as it appeared out of nowhere! There is no documentation for the interface and the implementation seems to be missing from most device classes. You might want to read doc/network-api.txt more carefully then :) It has been documented since 2009. Note that there is no 1:1 correspondence between atoms and interfaces. NetworkOperator does not have an underlying atom and is managed entirely by netreg. iii) The polled nature of the NetworkMonitor object surprised me. This seems like a natural case for notifications and the patch series in this email thread underscores this fact. Polled? The GetServingCellInformation() method call is polled. But it isn't meant to be used often. The agent version leaves it up to the driver on how to implement the periodic update. We looked at a few AT command specifications for this and while some of them support true unsolicited notifications, most don't. For example, XMM 71xx modems only support direct query and periodic mode while others only support direct query. The interface is quite experimental and the exact semantics of the period parameter need to be figured out. I suspect it is mostly going to be a hint that the application can provide for how often the updates are needed. If true unsolicited notifications are supported then the driver can ignore it. iv) For QMI, at least, the NetworkRegistration atom is monitoring asynchronous events that contain essentially all the information needed by the NetworkMonitor atom. The NetworkRegistration atom could just save these values and provide the NetworkMonitor interface in the same module instead of having an additional netmon module, but: Unfortunately we have more than QMI modems to worry about. All this is generally done via proprietary AT commands, so having it inside the netreg atom will not work. Also consider that we will not be able to support this for all hardware, either due to lack of support in the firmware or lack of documentation. So having this on a separate atom/interface makes it easy for applications to adjust their behavior. E.g. if the interface is present, then one can count on the functionality being there. If not present, then behave accordingly. a) We end up monitoring unnecessary state in case nobody is actually listening to the NetworkMonitor updates. This seems to have a negligible impact on performance so it probably does not matter. Well, you could enable / register to these notifications only if periodic updates have been enabled... b) ofono does not use this approach anywhere else that I can see... every atom/interface is provided in it's own module. This is preferred. Besides, qmi_service_register can support multiple clients, no? v) Point iv) applies to the NetworkOperator interface, as well, if we decide to implement it... should we? I won't comment until you familiarize yourself with src/netreg.c vi) I suspect that other device classes (AT, etc.) provide asynchronous network quality updates, as well; if they do not, however, then it seems natural to move the polling of this state into the device class driver. See above. Many of them don't. Sorry for hijacking this for a bit of QMI implementation discussion but it seems relevant in trying
Re: [PATCH 1/7] netmon: modified api.txt for network monitor agent
On 07/09/17 12:47, Jonas Bonn wrote: On 09/07/2017 06:23 AM, Nishanth V wrote: added new DBUS methods RegisterAgent and UnregisterAgent to Networkmonitor interface so that any client of ofono can register for serving cell updates. Added new agent interface NetworkMonitorAgent with two methods, ServingCellInformationChanged and Release. My spontaneous reaction to this is that it feels like the wrong approach. Why not make the properties actual DBus properties and provide PropertiesChanged events for them? That begets you the same functionality for "free". The implementation also seems to limit the number of clients receiving those cell change notifications to just one. Why? In real life more than one process may need those. Cheers, -Slava ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
Re: [PATCH 3/5] qmi: provide AvailableTechnologies in radio-settings
Hi Jonas, On 09/07/2017 02:11 PM, Jonas Bonn wrote: This provides the list of available technologies in the radio-settings atom. Note that this list is hard-coded and includes LTE unconditionally which is probably not correct for all QMI devices. You might want to use QMI_DMS_GET_CAPS message from dms service to do that. This is already used in plugins/gobi.c (even if returned information seems to be used only for debug). On an MC7304 (Sierra), I have: root@klk-lpbs-0504B4:~ # qmicli -d /dev/cdc-wdm0 --dms-get-capabilities [07 Sep 2017, 12:49:11] -Warning ** [/dev/cdc-wdm0] requested auto mode but no MBIM QMUX support available [/dev/cdc-wdm0] Device capabilities retrieved: Max TX channel rate: '5000' Max RX channel rate: '1' Data Service: 'non-simultaneous-cs-ps' SIM: 'supported' Networks: 'gsm, umts, lte' Best Regards, Christophe --- drivers/qmimodem/radio-settings.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/qmimodem/radio-settings.c b/drivers/qmimodem/radio-settings.c index ed578f8..fecde82 100644 --- a/drivers/qmimodem/radio-settings.c +++ b/drivers/qmimodem/radio-settings.c @@ -155,6 +155,19 @@ static void qmi_set_rat_mode(struct ofono_radio_settings *rs, } +static void qmi_query_available_rats(struct ofono_radio_settings *rs, + ofono_radio_settings_available_rats_query_cb_t cb, + void *data) +{ + unsigned int available_rats; + + available_rats = OFONO_RADIO_ACCESS_MODE_GSM + | OFONO_RADIO_ACCESS_MODE_UMTS + | OFONO_RADIO_ACCESS_MODE_LTE; + + CALLBACK_WITH_SUCCESS(cb, available_rats, data); +} + static void create_nas_cb(struct qmi_service *service, void *user_data) { struct ofono_radio_settings *rs = user_data; @@ -219,6 +232,7 @@ static struct ofono_radio_settings_driver driver = { .remove = qmi_radio_settings_remove, .set_rat_mode = qmi_set_rat_mode, .query_rat_mode = qmi_query_rat_mode, + .query_available_rats = qmi_query_available_rats, }; void qmi_radio_settings_init(void) ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH 1/5] autotools: enable maintainer mode by default
Disabling "maintainer mode" is not particularly useful as it really only saves people who accidentally touch a build system file in an unrealistically constrained system where the build tools are uninstalled and unavailable. This patch just changes the default to 'enabled' so that the changes to build system files have the desired effect. Passing --disable-maintainer-mode to ./configure restores the previous behaviour for the (likely non-existant) users who actually require to do so. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 29a01c2..ecd2165 100644 --- a/configure.ac +++ b/configure.ac @@ -6,7 +6,7 @@ AC_CONFIG_HEADERS(config.h) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) -AM_MAINTAINER_MODE +AM_MAINTAINER_MODE([enable]) AC_PREFIX_DEFAULT(/usr/local) -- 2.9.3 ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH 5/5] qmi: add NetworkMonitor interface
This is a rudimentary implementation that contains technology, RSSI, and BitErrorRate, plus RSRQ/RSRP for LTE networks. More data can be added as needed. This implementations uses the 'Get Signal Strength' QMI method to retrieve the data. Operator fields (MNC, LAC, etc) can be gotten from the 'Serving Cell' method if needed, but since this data is already provided in the NetworkRegistration object it doesn't seem necessary to repeat it here when an additional communication to the modem is required. --- Makefile.am | 3 +- doc/networkmonitor-api.txt | 2 +- drivers/qmimodem/netmon.c | 285 drivers/qmimodem/qmimodem.c | 2 + drivers/qmimodem/qmimodem.h | 3 + plugins/gobi.c | 5 +- 6 files changed, 297 insertions(+), 3 deletions(-) create mode 100644 drivers/qmimodem/netmon.c diff --git a/Makefile.am b/Makefile.am index 658e152..4b68beb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -233,7 +233,8 @@ builtin_sources += $(qmi_sources) \ drivers/qmimodem/gprs.c \ drivers/qmimodem/gprs-context.c \ drivers/qmimodem/radio-settings.c \ - drivers/qmimodem/location-reporting.c + drivers/qmimodem/location-reporting.c \ + drivers/qmimodem/netmon.c builtin_modules += gobi builtin_sources += plugins/gobi.c diff --git a/doc/networkmonitor-api.txt b/doc/networkmonitor-api.txt index ddace7e..8d73af0 100644 --- a/doc/networkmonitor-api.txt +++ b/doc/networkmonitor-api.txt @@ -77,7 +77,7 @@ byte TimingAdvance [optional, gsm] Contains the Timing Advance. Valid range of values is 0-219. -byte Strength [optional, gsm, umts] +byte Strength [optional, gsm, umts, lte] Contains the signal strength. Valid values are 0-31. Refer to in 27.007, Section 8.5. diff --git a/drivers/qmimodem/netmon.c b/drivers/qmimodem/netmon.c new file mode 100644 index 000..9fef0d4 --- /dev/null +++ b/drivers/qmimodem/netmon.c @@ -0,0 +1,285 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2017 Jonas Bonn. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +//#include "common.h" + +#include "qmi.h" +#include "nas.h" + +#include "qmimodem.h" +#include "src/common.h" + +struct netmon_data { + struct qmi_service *nas; +}; + +static void get_rssi_cb(struct qmi_result *result, void *user_data) +{ + struct cb_data *cbd = user_data; + struct ofono_netmon *netmon = cbd->user; + ofono_netmon_cb_t cb = cbd->cb; + struct { + enum ofono_netmon_cell_type type; + int rssi; + int ber; + int rsrq; + int rsrp; + } props; + uint16_t len; + int16_t rsrp; + const struct { + int8_t value; + int8_t rat; + } __attribute__((__packed__)) *rsrq; + const struct { + uint16_t count; + struct { + uint8_t rssi; + int8_t rat; + } __attribute__((__packed__)) info[0]; + } __attribute__((__packed__)) *rssi; + const struct { + uint16_t count; + struct { + uint16_t rate; + int8_t rat; + } __attribute__((__packed__)) info[0]; + } __attribute__((__packed__)) *ber; + int i; + + DBG(""); + + if (qmi_result_set_error(result, NULL)) { + CALLBACK_WITH_FAILURE(cb, cbd->data); + return; + } + + /* RSSI */ + rssi = qmi_result_get(result, 0x11, ); + if (rssi) { + for (i = 0; i < rssi->count; i++) { + DBG("RSSI: %hhu on RAT %hhd", + rssi->info[i].rssi, + rssi->info[i].rat); + } + + /* Get cell type from RSSI info... it will be the same +* for all the other entries +*/ + props.type = qmi_nas_rat_to_tech(rssi->info[0].rat); +
[PATCH 3/5] qmi: provide AvailableTechnologies in radio-settings
This provides the list of available technologies in the radio-settings atom. Note that this list is hard-coded and includes LTE unconditionally which is probably not correct for all QMI devices. --- drivers/qmimodem/radio-settings.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/qmimodem/radio-settings.c b/drivers/qmimodem/radio-settings.c index ed578f8..fecde82 100644 --- a/drivers/qmimodem/radio-settings.c +++ b/drivers/qmimodem/radio-settings.c @@ -155,6 +155,19 @@ static void qmi_set_rat_mode(struct ofono_radio_settings *rs, } +static void qmi_query_available_rats(struct ofono_radio_settings *rs, + ofono_radio_settings_available_rats_query_cb_t cb, + void *data) +{ + unsigned int available_rats; + + available_rats = OFONO_RADIO_ACCESS_MODE_GSM + | OFONO_RADIO_ACCESS_MODE_UMTS + | OFONO_RADIO_ACCESS_MODE_LTE; + + CALLBACK_WITH_SUCCESS(cb, available_rats, data); +} + static void create_nas_cb(struct qmi_service *service, void *user_data) { struct ofono_radio_settings *rs = user_data; @@ -219,6 +232,7 @@ static struct ofono_radio_settings_driver driver = { .remove = qmi_radio_settings_remove, .set_rat_mode = qmi_set_rat_mode, .query_rat_mode = qmi_query_rat_mode, + .query_available_rats = qmi_query_available_rats, }; void qmi_radio_settings_init(void) -- 2.9.3 ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH 4/5] qmi: add helper to get int16_t result
--- drivers/qmimodem/qmi.c | 21 + drivers/qmimodem/qmi.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/drivers/qmimodem/qmi.c b/drivers/qmimodem/qmi.c index 17c6a6f..c538cb9 100644 --- a/drivers/qmimodem/qmi.c +++ b/drivers/qmimodem/qmi.c @@ -1720,6 +1720,27 @@ bool qmi_result_get_uint8(struct qmi_result *result, uint8_t type, return true; } +bool qmi_result_get_int16(struct qmi_result *result, uint8_t type, + int16_t *value) +{ + const unsigned char *ptr; + uint16_t len, tmp; + + if (!result || !type) + return false; + + ptr = tlv_get(result->data, result->length, type, ); + if (!ptr) + return false; + + memcpy(, ptr, 2); + + if (value) + *value = GINT16_FROM_LE(tmp); + + return true; +} + bool qmi_result_get_uint16(struct qmi_result *result, uint8_t type, uint16_t *value) { diff --git a/drivers/qmimodem/qmi.h b/drivers/qmimodem/qmi.h index bfe8e6b..b4955b4 100644 --- a/drivers/qmimodem/qmi.h +++ b/drivers/qmimodem/qmi.h @@ -130,6 +130,8 @@ const void *qmi_result_get(struct qmi_result *result, uint8_t type, char *qmi_result_get_string(struct qmi_result *result, uint8_t type); bool qmi_result_get_uint8(struct qmi_result *result, uint8_t type, uint8_t *value); +bool qmi_result_get_int16(struct qmi_result *result, uint8_t type, + int16_t *value); bool qmi_result_get_uint16(struct qmi_result *result, uint8_t type, uint16_t *value); bool qmi_result_get_uint32(struct qmi_result *result, uint8_t type, -- 2.9.3 ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono
[PATCH 2/5] qmi: implement RAT selection
The QMI radio-settings atom was just a skeleton and did not even implement the mandtory property TechnologyPreference. As such, it probably should never even have been registered for the modem. Nonetheless, this patch puts this mandatory property into place. This is implemented via the 'Set System Selection' method by way of the 'mode' parameter. This seems to best reflect the intention of the Ofono API and works as expected when tested with a Quectel EC21. Some notes: i) There is an alternative function called 'Set Technology Preference' which provides similar functionality. This 'technology preference' is updated automatically when the 'system selection mode' is modified so everything seems to be in order. ii) For the EC21, switching the underlying technology works seamlessly. There are indications, however, that some modems _might_ require a reset before changes take effect; that bridge will need to be crossed if reached. --- drivers/qmimodem/nas.h| 11 drivers/qmimodem/radio-settings.c | 119 ++ 2 files changed, 130 insertions(+) diff --git a/drivers/qmimodem/nas.h b/drivers/qmimodem/nas.h index d2feb46..c3e7546 100644 --- a/drivers/qmimodem/nas.h +++ b/drivers/qmimodem/nas.h @@ -35,6 +35,8 @@ #define QMI_NAS_SS_INFO_IND36 /* Current serving system info indication */ #define QMI_NAS_GET_HOME_INFO 37 /* Get info about home network */ +#define QMI_NAS_SET_SYSTEM_SELECTION_PREF 51 +#define QMI_NAS_GET_SYSTEM_SELECTION_PREF 52 /* Set NAS state report conditions */ #define QMI_NAS_PARAM_REPORT_SIGNAL_STRENGTH 0x10 @@ -164,4 +166,13 @@ struct qmi_nas_home_network { char desc[0]; } __attribute__((__packed__)); +#define QMI_NAS_RAT_MODE_PREF_ANY (-1) +#define QMI_NAS_RAT_MODE_PREF_GSM (1 << 2) +#define QMI_NAS_RAT_MODE_PREF_UMTS (1 << 3) +#define QMI_NAS_RAT_MODE_PREF_LTE (1 << 4) + +#define QMI_NAS_PARAM_SYSTEM_SELECTION_PREF_MODE 0x11 + +#define QMI_NAS_RESULT_SYSTEM_SELECTION_PREF_MODE 0x11 + int qmi_nas_rat_to_tech(uint8_t rat); diff --git a/drivers/qmimodem/radio-settings.c b/drivers/qmimodem/radio-settings.c index 04106ea..ed578f8 100644 --- a/drivers/qmimodem/radio-settings.c +++ b/drivers/qmimodem/radio-settings.c @@ -38,6 +38,123 @@ struct settings_data { uint16_t minor; }; +static void get_system_selection_pref_cb(struct qmi_result *result, + void* user_data) +{ + struct cb_data *cbd = user_data; + ofono_radio_settings_rat_mode_query_cb_t cb = cbd->cb; + enum ofono_radio_access_mode mode = OFONO_RADIO_ACCESS_MODE_ANY; + uint16_t pref; + + DBG(""); + + if (qmi_result_set_error(result, NULL)) { + CALLBACK_WITH_FAILURE(cb, -1, cbd->data); + return; + } + + qmi_result_get_uint16(result, + QMI_NAS_RESULT_SYSTEM_SELECTION_PREF_MODE, ); + + switch (pref) { + case QMI_NAS_RAT_MODE_PREF_GSM: + mode = OFONO_RADIO_ACCESS_MODE_GSM; + break; + case QMI_NAS_RAT_MODE_PREF_UMTS: + mode = OFONO_RADIO_ACCESS_MODE_UMTS; + break; + case QMI_NAS_RAT_MODE_PREF_LTE: + mode = OFONO_RADIO_ACCESS_MODE_LTE; + break; + } + + CALLBACK_WITH_SUCCESS(cb, mode, cbd->data); +} + + +static void qmi_query_rat_mode(struct ofono_radio_settings *rs, + ofono_radio_settings_rat_mode_query_cb_t cb, + void *user_data) +{ + struct settings_data *data = ofono_radio_settings_get_data(rs); + struct cb_data *cbd = cb_data_new(cb, user_data); + + DBG(""); + + if (qmi_service_send(data->nas, + QMI_NAS_GET_SYSTEM_SELECTION_PREF, NULL, + get_system_selection_pref_cb, cbd, g_free) > 0) + return; + + CALLBACK_WITH_FAILURE(cb, -1, data); +} + +static void set_system_selection_pref_cb(struct qmi_result *result, + void* user_data) +{ + struct cb_data *cbd = user_data; + ofono_radio_settings_rat_mode_set_cb_t cb = cbd->cb; + + DBG(""); + + if (qmi_result_set_error(result, NULL)) { + CALLBACK_WITH_FAILURE(cb, cbd->data); + return; + } + + CALLBACK_WITH_SUCCESS(cb, cbd->data); +} + +static void qmi_set_rat_mode(struct ofono_radio_settings *rs, + enum ofono_radio_access_mode mode, + ofono_radio_settings_rat_mode_set_cb_t cb, + void *user_data) +{ + struct settings_data *data = ofono_radio_settings_get_data(rs); + struct cb_data *cbd = cb_data_new(cb, user_data); + uint16_t pref = QMI_NAS_RAT_MODE_PREF_ANY; + struct qmi_param
Re: [PATCH 1/7] netmon: modified api.txt for network monitor agent
On 09/07/2017 06:23 AM, Nishanth V wrote: added new DBUS methods RegisterAgent and UnregisterAgent to Networkmonitor interface so that any client of ofono can register for serving cell updates. Added new agent interface NetworkMonitorAgent with two methods, ServingCellInformationChanged and Release. My spontaneous reaction to this is that it feels like the wrong approach. Why not make the properties actual DBus properties and provide PropertiesChanged events for them? That begets you the same functionality for "free". It's interesting that you posted this now because I've spent the last week grumbling over this API myself as I'm putting support for the NetworkMonitor interface into the QMI modem class. My thoughts: i) There's duplicate information all over the place. MNC, LAC, etc. are provided in three different interefaces: NetworkRegistration, NetworkMonitor, and NetworkOperator. ii) The NetworkOperator interface caught me off guard as it appeared out of nowhere! There is no documentation for the interface and the implementation seems to be missing from most device classes. iii) The polled nature of the NetworkMonitor object surprised me. This seems like a natural case for notifications and the patch series in this email thread underscores this fact. iv) For QMI, at least, the NetworkRegistration atom is monitoring asynchronous events that contain essentially all the information needed by the NetworkMonitor atom. The NetworkRegistration atom could just save these values and provide the NetworkMonitor interface in the same module instead of having an additional netmon module, but: a) We end up monitoring unnecessary state in case nobody is actually listening to the NetworkMonitor updates. This seems to have a negligible impact on performance so it probably does not matter. b) ofono does not use this approach anywhere else that I can see... every atom/interface is provided in it's own module. v) Point iv) applies to the NetworkOperator interface, as well, if we decide to implement it... should we? vi) I suspect that other device classes (AT, etc.) provide asynchronous network quality updates, as well; if they do not, however, then it seems natural to move the polling of this state into the device class driver. Sorry for hijacking this for a bit of QMI implementation discussion but it seems relevant in trying to understand what it is that the NetworkMonitor interface is supposed to be. Thoughts? /Jonas --- doc/networkmonitor-api.txt | 28 1 file changed, 28 insertions(+) diff --git a/doc/networkmonitor-api.txt b/doc/networkmonitor-api.txt index ddace7e..0855329 100644 --- a/doc/networkmonitor-api.txt +++ b/doc/networkmonitor-api.txt @@ -22,6 +22,34 @@ Methods a{sv} GetServingCellInformation() are available, their valid value ranges and applicability to different cell types. + void RegisterAgent(object path) + + Registers an agent which will be called whenever the + modem registers to or moves to a new cell. + + void UnregisterAgent(object path) + + Unregisters an agent. + +NetworkMonitorAgent Hierarchy [experimental] += + +Serviceunique name +Interface org.ofono.NetworkMonitorAgent +Object pathfreely definable + +Methodsvoid ServingCellInformationChanged(a{sv}) + + This method is called whenever the serving cell + information has been updated. + + Possible Errors: None + + void Release() [noreply] + + Agent is being released, possibly because of oFono + terminating, NetworkMonitor interface is being torn + down or modem off. No UnregisterAgent call is needed. Network Monitor Property Types == ___ ofono mailing list ofono@ofono.org https://lists.ofono.org/mailman/listinfo/ofono