[PATCH_v4 0/5] Private network request to ConnMan
by Guillaume Zajac
Hi,
Changelog from v3 is:
- Add private-network source/include
- ConnMan plugin is independant from emulator
- Each application that need VPN will pass a callback as argument
when private network is requested. This callback will contain the
private network settings.
Guillaume Zajac (5):
gatppp: Add new contructor to use external fd
private-network: add callback typedef drivers and settings
private-network: add request/release functions and new feature to
Makefile.am
emulator: add request/release private network calls
connman: add plugin in oFono to request request/release private
network
Makefile.am | 10 +-
gatchat/gatppp.c | 33 +++++-
gatchat/gatppp.h | 1 +
gatchat/ppp.h | 2 +-
gatchat/ppp_net.c | 40 ++++---
include/private-network.h | 59 +++++++++
plugins/connman.c | 297 +++++++++++++++++++++++++++++++++++++++++++++
src/emulator.c | 49 ++++++--
src/ofono.h | 6 +
src/private-network.c | 89 ++++++++++++++
10 files changed, 556 insertions(+), 30 deletions(-)
create mode 100644 include/private-network.h
create mode 100644 plugins/connman.c
create mode 100644 src/private-network.c
1 day, 7 hours
Read/Write EFcfis/EFcphs-cff files
by Jeevaka Badrappan
Hi,
This patch reads and writes the call forwarding unconditional status
from and to the SIM depending on the SIM file availability.
New property needs to be added due to the fact that number won't be
available from the cphs-cff file.
Incase of SIM, EFcphs-cff file holds call forwarding status and it
is represented as a flag. In case of USIM(EFcfis), we have the status
flag and also number.So, adding new property for status and using the
existing VoiceUnconditional with number will work for both SIM and USIM cases.
Other option is to have 2 properties, "VoiceUnconditional" and "Number".
"VoiceUnconditional" will have the status of the call forwarding( "enabled",
"disabled") whereas the "Number" property will have the call forwared number.
offline-online state transitions results in caching the call forwaring status
every time. To avoid this, call forwarding atom is moved to the post sim and
its moved also due to the fact that call forwarding status doesn't change in
roaming.
Regards,
Jeevaka
Jeevaka Badrappan (7):
call-forwarding: Read/Write cfis/cphs-cff
ifx: Move call forwarding to post sim
isigen: Move call forwarding to post sim
plugins/n900: Move call forwarding to post sim
phonesim: Move call forwarding to post sim
doc: Add new property to call forwarding
TODO: Marking the Read/Write EFcfis task as done
TODO | 9 --
doc/call-forwarding-api.txt | 5 +
doc/features.txt | 5 +
plugins/ifx.c | 2 +-
plugins/isigen.c | 2 +-
plugins/n900.c | 2 +-
plugins/phonesim.c | 3 +-
src/call-forwarding.c | 242 ++++++++++++++++++++++++++++++++++++++++++-
8 files changed, 256 insertions(+), 14 deletions(-)
1 day, 11 hours
[PATCH] Simcom support
by Anthony Viallard
Add SIMCOM support.
I developped this with the SIM5216E chipset and ofono 1.12.
- SMS and GPRS work (in the same time) ;
- SIM card presence check ;
- No voice part because I can't test it ;
- Use default characters set instead GSM because it works like that
for what I'm doing (SMS+GPRS) (by default, the set is IRA for SIM5216E).
Also, the SIMCOM doc affraids me about problems when using GSM
(this setting causes easily software flow control (XON /XOFF) problems.).
Signed-off-by: Anthony Viallard <homer242 at gmail.com>
--- ofono-1.12.orig/Makefile.am 2012-04-20 21:06:29.000000000 +0200
+++ ofono-1.12/Makefile.am 2013-01-21 17:17:48.089627277 +0100
@@ -371,6 +371,9 @@ builtin_sources += plugins/samsung.c
builtin_modules += sim900
builtin_sources += plugins/sim900.c
+builtin_modules += simcom
+builtin_sources += plugins/simcom.c
+
if BLUETOOTH
builtin_modules += bluetooth
builtin_sources += plugins/bluetooth.c plugins/bluetooth.h
--- ofono-1.12.orig/drivers/atmodem/sms.c 2012-04-20 21:06:29.000000000 +0200
+++ ofono-1.12/drivers/atmodem/sms.c 2013-01-21 16:48:44.460627485 +0100
@@ -805,6 +807,7 @@ static gboolean build_cnmi_string(char *
case OFONO_VENDOR_NOVATEL:
case OFONO_VENDOR_HUAWEI:
case OFONO_VENDOR_ZTE:
+ case OFONO_VENDOR_SIMCOM:
/* MSM devices advertise support for mode 2, but return an
* error if we attempt to actually use it. */
mode = "1";
diff -pruN ofono-1.12.orig/drivers/atmodem/sim.c ofono-1.12/drivers/atmodem/sim.c
--- ofono-1.12.orig/drivers/atmodem/sim.c 2013-01-23 11:38:22.959609087 +0100
+++ ofono-1.12/drivers/atmodem/sim.c 2013-01-23 11:57:52.602608948 +0100
@@ -1023,12 +1023,18 @@ static void at_pin_send_cb(gboolean ok,
FALSE, cbd, g_free);
return;
case OFONO_VENDOR_ZTE:
case OFONO_VENDOR_ALCATEL:
case OFONO_VENDOR_HUAWEI:
+ case OFONO_VENDOR_SIMCOM:
/*
* On ZTE modems, after pin is entered, SIM state is checked
* by polling CPIN as their modem doesn't provide unsolicited
* notification of SIM readiness.
+ *
+ * On SIMCOM modems, SIM is busy after pin is entered (we've
+ * got an "+CME ERROR: 14" at "AT+CPIN?" request) and ofono
+ * don't catch the "+CPIN: READY" message sent by the modem
+ * when SIM is ready. So, use extra CPIN to check the state.
*/
sd->sim_state_query = at_util_sim_state_query_new(sd->chat,
2, 20, sim_state_cb, cbd,
diff -purN ofono-1.12/drivers/atmodem/network-registration.c ofono-patched/drivers/atmodem/network-registration.c
--- ofono-1.12/drivers/atmodem/network-registration.c 2013-01-18 15:04:03.598659165 +0100
+++ ofono-patched/drivers/atmodem/network-registration.c 2013-01-18 14:54:03.256659236 +0100
@@ -1411,6 +1411,14 @@ static void at_creg_set_cb(gboolean ok,
}
switch (nd->vendor) {
+ case OFONO_VENDOR_SIMCOM:
+ /* Register for CSQ changes */
+ g_at_chat_send(nd->chat, "AT+AUTOCSQ=1,1", none_prefix,
+ NULL, NULL, NULL);
+
+ g_at_chat_register(nd->chat, "+CSQ:",
+ csq_notify, FALSE, netreg, NULL);
+ break;
case OFONO_VENDOR_PHONESIM:
g_at_chat_register(nd->chat, "+CSQ:",
csq_notify, FALSE, netreg, NULL);
@@ -1534,7 +1537,6 @@ static void at_creg_set_cb(gboolean ok,
break;
case OFONO_VENDOR_NOKIA:
case OFONO_VENDOR_SAMSUNG:
- case OFONO_VENDOR_SIMCOM:
/* Signal strength reporting via CIND is not supported */
break;
default:
--- /dev/null 2013-01-28 10:34:59.843091650 +0100
+++ ofono-1.12/plugins/simcom.c 2013-02-15 16:16:38.058552544 +0100
@@ -0,0 +1,401 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2011 Intel Corporation. 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 <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <glib.h>
+#include <gatchat.h>
+#include <gattty.h>
+
+#define OFONO_API_SUBJECT_TO_CHANGE
+#include <ofono/plugin.h>
+#include <ofono/modem.h>
+#include <ofono/devinfo.h>
+#include <ofono/netreg.h>
+#include <ofono/sim.h>
+#include <ofono/cbs.h>
+#include <ofono/sms.h>
+#include <ofono/ussd.h>
+#include <ofono/gprs.h>
+#include <ofono/gprs-context.h>
+#include <ofono/radio-settings.h>
+#include <ofono/phonebook.h>
+#include <ofono/log.h>
+
+#include <drivers/atmodem/atutil.h>
+#include <drivers/atmodem/vendor.h>
+
+#define MAX_IGNITION_POOL_CALL 7
+
+#define CMEERR_SIMBUSY 14
+
+static const char *none_prefix[] = { NULL };
+
+struct simcom_data {
+ GAtChat *modem;
+ GAtChat *data;
+ guint ignition_pool;
+ unsigned int ignition_pool_call;
+ unsigned int at_ignition_pending;
+ ofono_bool_t have_sim;
+};
+
+/* Callback and helpers functions */
+static void simcom_debug(const char *str, void *user_data)
+{
+ const char *prefix = user_data;
+
+ ofono_info("%s%s", prefix, str);
+}
+
+static gboolean simcom_ignition(gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct simcom_data *data = ofono_modem_get_data(modem);
+
+ ++data->ignition_pool_call;
+
+ if(data->at_ignition_pending > 0)
+ {
+ if(data->ignition_pool_call > MAX_IGNITION_POOL_CALL)
+ {
+ ofono_error("Ignition timeout");
+ return FALSE;
+ }
+
+ /* Waiting reply of AT commands */
+ DBG("Waiting AT reply...");
+ return TRUE;
+ }
+
+ ofono_modem_set_powered(modem, TRUE);
+
+ return FALSE;
+}
+
+static void simcom_sim_status(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct ofono_error error;
+ struct simcom_data *data = ofono_modem_get_data(modem);
+
+ --data->at_ignition_pending;
+
+ if(!ok)
+ {
+ decode_at_error(&error, g_at_result_final_response(result));
+ if(error.type == OFONO_ERROR_TYPE_CME)
+ {
+ if(error.error == CMEERR_SIMBUSY)
+ {
+ DBG("System is busy. Retry...");
+ g_at_chat_send(data->data, "AT+CPIN?",
+ none_prefix,
+ simcom_sim_status, modem,
+ NULL);
+ ++data->at_ignition_pending;
+ return;
+ }
+ }
+
+ data->have_sim = FALSE;
+ return;
+ }
+
+ /* If doesn't have an "fatal" error on AT+CPIN request,
+ * we can guess there a SIM card ...
+ */
+ data->have_sim = TRUE;
+}
+
+static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct simcom_data *data = ofono_modem_get_data(modem);
+
+ DBG("");
+
+ if (!ok) {
+ g_at_chat_unref(data->modem);
+ data->modem = NULL;
+
+ g_at_chat_unref(data->data);
+ data->data = NULL;
+
+ ofono_modem_set_powered(modem, FALSE);
+ return;
+ }
+
+ /* Get model and sim card status */
+ data->at_ignition_pending = 0;
+
+ g_at_chat_send(data->data, "AT+CPIN?", none_prefix,
+ simcom_sim_status, modem, NULL);
+ ++data->at_ignition_pending;
+
+ data->ignition_pool = g_timeout_add_seconds(1,
+ simcom_ignition,
+ modem);
+}
+
+static void cfun_disable(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct simcom_data *data = ofono_modem_get_data(modem);
+
+ DBG("");
+
+ g_at_chat_unref(data->data);
+ data->data = NULL;
+
+ if (ok)
+ ofono_modem_set_powered(modem, FALSE);
+}
+
+static GAtChat *open_device(struct ofono_modem *modem,
+ const char *key,
+ char *debug)
+{
+ const char *device;
+ GIOChannel *channel;
+ GAtSyntax *syntax;
+ GAtChat *chat;
+ /* GHashTable *options; */
+
+ device = ofono_modem_get_string(modem, key);
+ if (device == NULL)
+ {
+ ofono_error("Failed to get modem '%s'", key);
+ return NULL;
+ }
+
+ DBG("%s %s", key, device);
+
+ /* options = g_hash_table_new(g_str_hash, g_str_equal); */
+ /* if (options == NULL) */
+ /* return NULL; */
+
+ /* g_hash_table_insert(options, "Baud", "115200"); */
+ /* g_hash_table_insert(options, "Parity", "none"); */
+ /* g_hash_table_insert(options, "StopBits", "1"); */
+ /* g_hash_table_insert(options, "DataBits", "8"); */
+ /* g_hash_table_insert(options, "XonXoff", "off"); */
+ /* g_hash_table_insert(options, "RtsCts", "on"); */
+ /* g_hash_table_insert(options, "Local", "on"); */
+ /* g_hash_table_insert(options, "Read", "on"); */
+
+ channel = g_at_tty_open(device, NULL);
+
+ /* g_hash_table_destroy(options); */
+
+ if (channel == NULL)
+ {
+ ofono_error("Failed to get tty for '%s'", key);
+ return NULL;
+ }
+
+ 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 (chat == NULL)
+ {
+ ofono_error("Failed to get chat for '%s'", key);
+ return NULL;
+ }
+
+ //if (getenv("OFONO_AT_DEBUG"))
+ g_at_chat_set_debug(chat, simcom_debug, debug);
+
+ return chat;
+}
+
+/* Modem interface function */
+static int simcom_probe(struct ofono_modem *modem)
+{
+ struct simcom_data *data;
+
+ DBG("%p", modem);
+
+ data = g_try_new0(struct simcom_data, 1);
+ if (data == NULL)
+ return -ENOMEM;
+
+ ofono_modem_set_data(modem, data);
+
+ return 0;
+}
+
+static void simcom_remove(struct ofono_modem *modem)
+{
+ struct simcom_data *data = ofono_modem_get_data(modem);
+
+ DBG("%p", modem);
+
+ if(data->ignition_pool > 0)
+ {
+ g_source_remove(data->ignition_pool);
+ data->ignition_pool = 0;
+ }
+
+ ofono_modem_set_data(modem, NULL);
+
+ /* Cleanup after hot-unplug */
+ g_at_chat_unref(data->data);
+
+ g_free(data);
+}
+
+static int simcom_enable(struct ofono_modem *modem)
+{
+ struct simcom_data *data = ofono_modem_get_data(modem);
+
+ DBG("%p", modem);
+
+ data->modem = open_device(modem, "Modem", "Modem: ");
+ if (data->modem == NULL)
+ return -EINVAL;
+
+ data->data = open_device(modem, "Data", "Data: ");
+ if (data->data == NULL) {
+ g_at_chat_unref(data->modem);
+ data->modem = NULL;
+ return -EIO;
+ }
+
+ g_at_chat_set_slave(data->modem, data->data);
+
+ g_at_chat_blacklist_terminator(data->data,
+ G_AT_CHAT_TERMINATOR_NO_CARRIER);
+
+ /* init modem */
+ g_at_chat_send(data->modem, "ATE0 +CMEE=1", NULL, NULL, NULL, NULL);
+ g_at_chat_send(data->data, "ATE0 +CMEE=1", NULL, NULL, NULL, NULL);
+
+ g_at_chat_send(data->data, "AT+CFUN=1", none_prefix,
+ cfun_enable, modem, NULL);
+
+ return -EINPROGRESS;
+}
+
+static int simcom_disable(struct ofono_modem *modem)
+{
+ struct simcom_data *data = ofono_modem_get_data(modem);
+
+ DBG("%p", modem);
+
+ g_at_chat_cancel_all(data->modem);
+ g_at_chat_unregister_all(data->modem);
+
+ g_at_chat_unref(data->modem);
+ data->modem = NULL;
+
+ g_at_chat_cancel_all(data->data);
+ g_at_chat_unregister_all(data->data);
+
+ g_at_chat_send(data->data, "AT+CFUN=4", none_prefix,
+ cfun_disable, modem, NULL);
+
+ return -EINPROGRESS;
+}
+
+static void simcom_pre_sim(struct ofono_modem *modem)
+{
+ struct simcom_data *data = ofono_modem_get_data(modem);
+ struct ofono_sim *sim;
+
+ DBG("%p", modem);
+
+ ofono_devinfo_create(modem, 0, "atmodem", data->data);
+ sim = ofono_sim_create(modem, OFONO_VENDOR_SIMCOM, "atmodem",
+ data->data);
+
+ if (sim)
+ ofono_sim_inserted_notify(sim, data->have_sim);
+}
+
+static void simcom_post_sim(struct ofono_modem *modem)
+{
+ struct simcom_data *data = ofono_modem_get_data(modem);
+ struct ofono_message_waiting *mw;
+ struct ofono_gprs *gprs;
+ struct ofono_gprs_context *gc;
+
+ DBG("%p", modem);
+
+ ofono_phonebook_create(modem, 0, "atmodem", data->data);
+
+ ofono_sms_create(modem, OFONO_VENDOR_SIMCOM, "atmodem",
+ data->data);
+
+ /* gprs things */
+ gprs = ofono_gprs_create(modem, 0, "atmodem", data->data);
+ gc = ofono_gprs_context_create(modem, 0, "atmodem", data->modem);
+
+ if(gprs && gc)
+ {
+ ofono_gprs_add_context(gprs, gc);
+ }
+}
+
+static void simcom_post_online(struct ofono_modem *modem)
+{
+ struct simcom_data *data = ofono_modem_get_data(modem);
+
+ DBG("%p", modem);
+
+ ofono_netreg_create(modem, OFONO_VENDOR_SIMCOM, "atmodem", data->data);
+ ofono_cbs_create(modem, 0, "atmodem", data->data);
+ ofono_ussd_create(modem, 0, "atmodem", data->data);
+}
+
+static struct ofono_modem_driver simcom_driver = {
+ .name = "simcom",
+ .probe = simcom_probe,
+ .remove = simcom_remove,
+ .enable = simcom_enable,
+ .disable = simcom_disable,
+ .pre_sim = simcom_pre_sim,
+ .post_sim = simcom_post_sim,
+ .post_online = simcom_post_online,
+};
+
+static int simcom_init(void)
+{
+ return ofono_modem_driver_register(&simcom_driver);
+}
+
+static void simcom_exit(void)
+{
+ ofono_modem_driver_unregister(&simcom_driver);
+}
+
+OFONO_PLUGIN_DEFINE(simcom, "SIMCOM modem driver", VERSION,
+ OFONO_PLUGIN_PRIORITY_DEFAULT,
+ simcom_init, simcom_exit)
1 day, 11 hours
IPV6 question
by Enrico Sau
Hi all,
As far as I understand, ofono doen't support IPV6 over ppp due to the fact
that IPV6 compression protocol implementation is missing.
Is that right?
Thank you,
Enrico
3 weeks, 2 days
Business
by Daser Jnr.
Hi all
>From a business point of view, can some one tell me what i can do with ofono
Cheers
Daser S.
3 months, 4 weeks
ofono with sim5320 module
by David Ashley
Hello, I'm at my wits' end trying to get ofono working with the
sim5320 module. I'm using the plugins/sim900.c module as a starting
point. I think the issue has something to do with the difference
between the MUX functionality between the 900 and the 5320. The sim900
supports the elaborate parameters sent on the
AT+CMUX=0,x,x,x,x, etc.
but the SIM5320 only supports
AT+CMUX=0
There's that... but also the way the sim900 plugin creates a
SETUP_DLC, initiates muxing, then deletes the setup DLC and creates 4
new DLC's... it didn't work for the sim5320 until I remapped the DLC's
somewhat like this:
#define NUM_DLC 4
#define VOICE_DLC 2
#define NETREG_DLC 1
//#define SMS_DLC 2
#define GPRS_DLC 3
#define SETUP_DLC 0
static char *dlc_prefixes[NUM_DLC] = {
[VOICE_DLC]="Voice: ",
[NETREG_DLC]="Net: ",
// [SMS_DLC]= "SMS: ",
[GPRS_DLC]= "GPRS: " ,
[SETUP_DLC]= "Setup: ",
};
Note I have to eliminate the SMS_DLC usage later in sim5320_post_sim:
// ofono_sms_create(modem, OFONO_VENDOR_SIMCOM, "atmodem",
// data->dlcs[SMS_DLC]);
OK everything is *ALMOST* working. ofonod interacts fine with
connmand, connmand tells ofonod to activate the sim5320, which
actually establishes a ppp connection and sets up a ppp device:
ppp0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-0
inet addr:30.97.132.47 P-t-P:30.97.132.47 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:0 (0.0 B) TX bytes:124 (124.0 B)
Here's the rub: No matter what I do, I never get any RX packets from
that ppp device, and even when it appears to TX packets (I'm trying to
ping out) the machine on the internet isn't actually receiving them.
I'm running on a beaglebone with a custom board with a sim5320 module on it.
I have no idea what to try... Any advice would be appreciated...
Thanks very much!!!!
-Dave
4 years, 6 months
[PATCH v2] qmimodem: include shutdown in callback cleanup queue
by Lukasz Nowak
From: Lukasz Nowak <lnowak(a)tycoint.com>
Changes since v1:
- fixed callback->timeout not being saved in qmi_device_shutdown()
Lukasz Nowak (1):
qmimodem: include shutdown in callback cleanup queue
drivers/qmimodem/qmi.c | 401 ++++++++++++++++++++++---------------------------
1 file changed, 180 insertions(+), 221 deletions(-)
--
2.7.4
5 years, 2 months
[RFC hwdb v1 00/28] USB interface labelling via udev
by Jonas Bonn
This series moves the labelling of USB modem interfaces to udev proper.
For most modems we are able to use the udev hwdb to do the labelling, and
for a few special cases we need to add udev rules.
Importantly, the OFONO_DRIVER and OFONO_LABEL properties are set on all
known interfaces. This saves the ofono udev handler from having to figure
these out from parsing udev device properties and doing table lookups.
The reason for doing this is:
i) ofono is currenly re-creating a lot of udev functionality when trying
figure out the driver and label to apply to interfaces
ii) the udev hwdb is an optimized path for setting device properties
iii) labelling interfaces via udev means it can be done for new devices
without code changes (and thus without rebuilding ofono)
iv) the udev implementation gets smaller and simpler; hopefully this
can be made so generic that every new modem won't require changes
to this module
This is an RFC because I'm not quite done with the conversion yet. There
are still some sysattr details to work out for the mbm and telit modems;
and the qmi modems still need to be put into their final form. A follow-up
series will be sent to this one but I wanted to get this sent out now for
some review.
Thanks,
Jonas
Jonas Bonn (28):
zte: remove unused qcdm property
zte: label interfaces via hwdb
novatel: label interfaces via hwdb
alcatel: label interfaces via hwdb
huawei: label interfaces via hwdb
simcom: label interfaces via hwdb
ublox: label interfaces via hwdb
gemalto: label interfaces via hwdb
speedup: label interfaces via hwdb
linktop: label interfaces via hwdb
udevng (hso): remove impossible condition
hso: label interfaces via udev rules
isiusb: label interfaces via udev rules
gobi: label interfaces via udev rules
option: label interfaces via hwdb
nokia: label interfaces via hwdb
samsung: label interfaces via udev rules and hwdb
sierra: label interfaces via udev rules
telitqmi: label interfaces via udev rules
telitqmi: drop unused device rule
telit: label interfaces via hwdb
icera: label interfaces via hwdb
quectel: label interfaces via hwdb
udevng: drop unused headers
mbm: use standard atom names
udevng: remove 'option' driver setup
udevng: push device existence check into drivers
udevng: consolidate setup functions for several USB devices
drivers/mbmmodem/location-reporting.c | 2 +-
plugins/alcatel.c | 9 +
plugins/gobi.c | 9 +
plugins/hso.c | 9 +
plugins/huawei.c | 9 +
plugins/icera.c | 9 +
plugins/linktop.c | 9 +
plugins/mbm.c | 15 +-
plugins/nokia.c | 9 +
plugins/novatel.c | 9 +
plugins/ofono-speedup.rules | 27 --
plugins/ofono.hwdb | 307 +++++++++++++++
plugins/ofono.rules | 51 +++
plugins/quectel.c | 9 +
plugins/speedup.c | 9 +
plugins/telit.c | 9 +
plugins/udevng.c | 687 +++++-----------------------------
plugins/zte.c | 9 +
18 files changed, 577 insertions(+), 620 deletions(-)
delete mode 100644 plugins/ofono-speedup.rules
create mode 100644 plugins/ofono.hwdb
--
2.9.3
5 years, 2 months
[PATCH] qmi: track discovery tasks so clean up is possible
by Denis Kenzior
There are various device & service discovery tasks that are initiated
based on a qmi_device object. qmi_device object does not currently
keep track of these tasks. Unfortunately the qmi_device object can
go away at any time, and these tasks can become orphaned.
The result of this can lead to crashes. E.g. a discovery task timeout fires
after the qmi_device object has been destroyed. Since the object is no
longer valid, any accesses to it will likely result in a SEGFAULT.
This patch attempts to track all discovery tasks on the qmi_device
object itself, so that they can be cleaned up properly. This patch does
not handle the qmi_device_shutdown functionality.
---
drivers/qmimodem/qmi.c | 149 ++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 124 insertions(+), 25 deletions(-)
diff --git a/drivers/qmimodem/qmi.c b/drivers/qmimodem/qmi.c
index 39fbb19..9b80455 100644
--- a/drivers/qmimodem/qmi.c
+++ b/drivers/qmimodem/qmi.c
@@ -43,6 +43,11 @@
typedef void (*qmi_message_func_t)(uint16_t message, uint16_t length,
const void *buffer, void *user_data);
+struct discovery {
+ void *discover_data;
+ qmi_destroy_func_t destroy;
+};
+
struct qmi_device {
int ref_count;
int fd;
@@ -53,6 +58,7 @@ struct qmi_device {
GQueue *req_queue;
GQueue *control_queue;
GQueue *service_queue;
+ GQueue *discovery_queue;
uint8_t next_control_tid;
uint16_t next_service_tid;
qmi_debug_func_t debug_func;
@@ -213,6 +219,24 @@ static gint __request_compare(gconstpointer a, gconstpointer b)
return req->tid - tid;
}
+static void __discovery_free(gpointer data, gpointer user_data)
+{
+ struct discovery *d = data;
+ qmi_destroy_func_t destroy = d->destroy;
+
+ destroy(d->discover_data);
+}
+
+static gint __discovery_compare(gconstpointer a, gconstpointer b)
+{
+ const struct discovery *d = a;
+
+ if (d->discover_data == b)
+ return 0;
+
+ return 1;
+}
+
static void __notify_free(gpointer data, gpointer user_data)
{
struct qmi_notify *notify = data;
@@ -844,6 +868,37 @@ static void read_watch_destroy(gpointer user_data)
device->read_watch = 0;
}
+static void __qmi_device_discovery_started(struct qmi_device *device,
+ void *discover_data,
+ qmi_destroy_func_t destroy)
+{
+ struct discovery *d;
+
+ d = g_new0(struct discovery, 1);
+ d->discover_data = discover_data;
+ d->destroy = destroy;
+
+ g_queue_push_tail(device->discovery_queue, d);
+}
+
+static void __qmi_device_discovery_complete(struct qmi_device *device,
+ void *discover_data)
+{
+ GList *list;
+ struct discovery *d;
+
+ list = g_queue_find_custom(device->req_queue,
+ discover_data, __discovery_compare);
+ if (!list)
+ return;
+
+ d = list->data;
+ g_queue_delete_link(device->discovery_queue, list);
+
+ d->destroy(d->discover_data);
+ __discovery_free(d, NULL);
+}
+
static void service_destroy(gpointer data)
{
struct qmi_service *service = data;
@@ -897,6 +952,7 @@ struct qmi_device *qmi_device_new(int fd)
device->req_queue = g_queue_new();
device->control_queue = g_queue_new();
device->service_queue = g_queue_new();
+ device->discovery_queue = g_queue_new();
device->service_list = g_hash_table_new_full(g_direct_hash,
g_direct_equal, NULL, service_destroy);
@@ -933,6 +989,9 @@ void qmi_device_unref(struct qmi_device *device)
g_queue_foreach(device->req_queue, __request_free, NULL);
g_queue_free(device->req_queue);
+ g_queue_foreach(device->discovery_queue, __discovery_free, NULL);
+ g_queue_free(device->discovery_queue);
+
if (device->write_watch > 0)
g_source_remove(device->write_watch);
@@ -1000,6 +1059,21 @@ struct discover_data {
guint timeout;
};
+static void discover_data_free(gpointer user_data)
+{
+ struct discover_data *data = user_data;
+
+ if (data->timeout) {
+ g_source_remove(data->timeout);
+ data->timeout = 0;
+ }
+
+ if (data->destroy)
+ data->destroy(data->user_data);
+
+ g_free(data);
+}
+
static void discover_callback(uint16_t message, uint16_t length,
const void *buffer, void *user_data)
{
@@ -1013,8 +1087,6 @@ static void discover_callback(uint16_t message, uint16_t length,
uint8_t count;
unsigned int i;
- g_source_remove(data->timeout);
-
count = 0;
list = NULL;
@@ -1085,10 +1157,7 @@ done:
if (data->func)
data->func(count, list, data->user_data);
- if (data->destroy)
- data->destroy(data->user_data);
-
- g_free(data);
+ __qmi_device_discovery_complete(data->device, data);
}
static gboolean discover_reply(gpointer user_data)
@@ -1102,10 +1171,7 @@ static gboolean discover_reply(gpointer user_data)
data->func(device->version_count,
device->version_list, data->user_data);
- if (data->destroy)
- data->destroy(data->user_data);
-
- g_free(data);
+ __qmi_device_discovery_complete(data->device, data);
return FALSE;
}
@@ -1132,7 +1198,9 @@ bool qmi_device_discover(struct qmi_device *device, qmi_discover_func_t func,
data->destroy = destroy;
if (device->version_list) {
- g_timeout_add_seconds(0, discover_reply, data);
+ data->timeout = g_timeout_add_seconds(0, discover_reply, data);
+ __qmi_device_discovery_started(device, data,
+ discover_data_free);
return true;
}
@@ -1153,6 +1221,7 @@ bool qmi_device_discover(struct qmi_device *device, qmi_discover_func_t func,
__request_submit(device, req, hdr->transaction);
data->timeout = g_timeout_add_seconds(5, discover_reply, data);
+ __qmi_device_discovery_started(device, data, discover_data_free);
return true;
}
@@ -1714,16 +1783,29 @@ struct service_create_data {
guint timeout;
};
-static gboolean service_create_reply(gpointer user_data)
+static void service_create_data_free(gpointer user_data)
{
struct service_create_data *data = user_data;
- data->func(NULL, data->user_data);
+ if (data->timeout) {
+ g_source_remove(data->timeout);
+ data->timeout = 0;
+ }
if (data->destroy)
data->destroy(data->user_data);
g_free(data);
+}
+
+static gboolean service_create_reply(gpointer user_data)
+{
+ struct service_create_data *data = user_data;
+
+ data->timeout = 0;
+ data->func(NULL, data->user_data);
+
+ __qmi_device_discovery_complete(data->device, data);
return FALSE;
}
@@ -1739,8 +1821,6 @@ static void service_create_callback(uint16_t message, uint16_t length,
uint16_t len;
unsigned int hash_id;
- g_source_remove(data->timeout);
-
result_code = tlv_get(buffer, length, 0x02, &len);
if (!result_code)
goto done;
@@ -1782,13 +1862,9 @@ static void service_create_callback(uint16_t message, uint16_t length,
done:
data->func(service, data->user_data);
-
qmi_service_unref(service);
- if (data->destroy)
- data->destroy(data->user_data);
-
- g_free(data);
+ __qmi_device_discovery_complete(data->device, data);
}
static void service_create_discover(uint8_t count,
@@ -1819,7 +1895,10 @@ static void service_create_discover(uint8_t count,
if (data->timeout > 0)
g_source_remove(data->timeout);
- g_timeout_add_seconds(0, service_create_reply, data);
+ data->timeout = g_timeout_add_seconds(0,
+ service_create_reply, data);
+ __qmi_device_discovery_started(device, data,
+ service_create_data_free);
return;
}
@@ -1864,6 +1943,8 @@ static bool service_create(struct qmi_device *device, bool shared,
done:
data->timeout = g_timeout_add_seconds(8, service_create_reply, data);
+ __qmi_device_discovery_started(device, data,
+ service_create_data_free);
return true;
}
@@ -1883,16 +1964,21 @@ bool qmi_service_create(struct qmi_device *device,
struct service_create_shared_data {
struct qmi_service *service;
+ struct qmi_device *device;
qmi_create_func_t func;
void *user_data;
qmi_destroy_func_t destroy;
+ guint timeout;
};
-static gboolean service_create_shared_reply(gpointer user_data)
+static void service_create_shared_data_free(gpointer user_data)
{
struct service_create_shared_data *data = user_data;
- data->func(data->service, data->user_data);
+ if (data->timeout) {
+ g_source_remove(data->timeout);
+ data->timeout = 0;
+ }
qmi_service_unref(data->service);
@@ -1900,6 +1986,16 @@ static gboolean service_create_shared_reply(gpointer user_data)
data->destroy(data->user_data);
g_free(data);
+}
+
+static gboolean service_create_shared_reply(gpointer user_data)
+{
+ struct service_create_shared_data *data = user_data;
+
+ data->timeout = 0;
+ data->func(data->service, data->user_data);
+
+ __qmi_device_discovery_complete(data->device, data);
return FALSE;
}
@@ -1927,12 +2023,15 @@ bool qmi_service_create_shared(struct qmi_device *device,
return false;
data->service = qmi_service_ref(service);
-
+ data->device = device;
data->func = func;
data->user_data = user_data;
data->destroy = destroy;
- g_timeout_add(0, service_create_shared_reply, data);
+ data->timeout = g_timeout_add(0,
+ service_create_shared_reply, data);
+ __qmi_device_discovery_started(device, data,
+ service_create_shared_data_free);
return 0;
}
--
2.10.2
5 years, 2 months
[PATCH] qmimodem: include shutdown in callback cleanup queue
by Lukasz Nowak
From: Lukasz Nowak <lnowak(a)tycoint.com>
Create a unified callback_data structure, used for all timeout callbacks.
This allows to maintain a single callback_queue, which cancels any active
timeouts, and frees callback data memory when a usb device is hot unplugged.
---
drivers/qmimodem/qmi.c | 399 ++++++++++++++++++++++---------------------------
1 file changed, 178 insertions(+), 221 deletions(-)
diff --git a/drivers/qmimodem/qmi.c b/drivers/qmimodem/qmi.c
index 9b80455..6e2b55f 100644
--- a/drivers/qmimodem/qmi.c
+++ b/drivers/qmimodem/qmi.c
@@ -43,11 +43,6 @@
typedef void (*qmi_message_func_t)(uint16_t message, uint16_t length,
const void *buffer, void *user_data);
-struct discovery {
- void *discover_data;
- qmi_destroy_func_t destroy;
-};
-
struct qmi_device {
int ref_count;
int fd;
@@ -58,7 +53,7 @@ struct qmi_device {
GQueue *req_queue;
GQueue *control_queue;
GQueue *service_queue;
- GQueue *discovery_queue;
+ GQueue *callback_queue;
uint8_t next_control_tid;
uint16_t next_service_tid;
qmi_debug_func_t debug_func;
@@ -154,6 +149,89 @@ void qmi_free(void *ptr)
free(ptr);
}
+struct discover_data {
+ qmi_discover_func_t func;
+};
+
+struct shutdown_data {
+ qmi_shutdown_func_t func;
+};
+
+struct service_create_data {
+ bool shared;
+ uint8_t type;
+ uint16_t major;
+ uint16_t minor;
+ qmi_create_func_t func;
+};
+
+struct service_create_shared_data {
+ struct qmi_service *service;
+ qmi_create_func_t func;
+};
+
+struct callback_data {
+ struct qmi_device *device;
+ void *user_data;
+ qmi_destroy_func_t user_destroy;
+ qmi_destroy_func_t callback_destroy;
+ guint timeout;
+ union {
+ struct discover_data discover;
+ struct shutdown_data shutdown;
+ struct service_create_data service_create;
+ struct service_create_shared_data service_create_shared;
+ } data;
+};
+
+static void callback_data_free(struct callback_data *callback)
+{
+ if (callback->timeout) {
+ g_source_remove(callback->timeout);
+ callback->timeout = 0;
+ }
+
+ if (callback->callback_destroy)
+ callback->callback_destroy(callback);
+
+ if (callback->user_destroy)
+ callback->user_destroy(callback->user_data);
+
+ g_free(callback);
+}
+
+static void service_create_shared_free(gpointer user_data)
+{
+ struct callback_data *callback = user_data;
+
+ qmi_service_unref(callback->data.service_create_shared.service);
+}
+
+static void __callback_started(struct callback_data *callback)
+{
+ struct qmi_device *device = callback->device;
+
+ g_queue_push_tail(device->callback_queue, callback);
+}
+
+static void __callback_complete(struct callback_data *callback)
+{
+ struct qmi_device *device = callback->device;
+ GList *list;
+
+ list = g_queue_find(device->callback_queue, callback);
+ if (!list)
+ return;
+
+ g_queue_delete_link(device->callback_queue, list);
+ callback_data_free(callback);
+}
+
+static void __callback_free(gpointer data, gpointer user_data)
+{
+ callback_data_free(data);
+}
+
static struct qmi_request *__request_alloc(uint8_t service,
uint8_t client, uint16_t message,
uint16_t headroom, const void *data,
@@ -219,24 +297,6 @@ static gint __request_compare(gconstpointer a, gconstpointer b)
return req->tid - tid;
}
-static void __discovery_free(gpointer data, gpointer user_data)
-{
- struct discovery *d = data;
- qmi_destroy_func_t destroy = d->destroy;
-
- destroy(d->discover_data);
-}
-
-static gint __discovery_compare(gconstpointer a, gconstpointer b)
-{
- const struct discovery *d = a;
-
- if (d->discover_data == b)
- return 0;
-
- return 1;
-}
-
static void __notify_free(gpointer data, gpointer user_data)
{
struct qmi_notify *notify = data;
@@ -868,37 +928,6 @@ static void read_watch_destroy(gpointer user_data)
device->read_watch = 0;
}
-static void __qmi_device_discovery_started(struct qmi_device *device,
- void *discover_data,
- qmi_destroy_func_t destroy)
-{
- struct discovery *d;
-
- d = g_new0(struct discovery, 1);
- d->discover_data = discover_data;
- d->destroy = destroy;
-
- g_queue_push_tail(device->discovery_queue, d);
-}
-
-static void __qmi_device_discovery_complete(struct qmi_device *device,
- void *discover_data)
-{
- GList *list;
- struct discovery *d;
-
- list = g_queue_find_custom(device->req_queue,
- discover_data, __discovery_compare);
- if (!list)
- return;
-
- d = list->data;
- g_queue_delete_link(device->discovery_queue, list);
-
- d->destroy(d->discover_data);
- __discovery_free(d, NULL);
-}
-
static void service_destroy(gpointer data)
{
struct qmi_service *service = data;
@@ -952,7 +981,7 @@ struct qmi_device *qmi_device_new(int fd)
device->req_queue = g_queue_new();
device->control_queue = g_queue_new();
device->service_queue = g_queue_new();
- device->discovery_queue = g_queue_new();
+ device->callback_queue = g_queue_new();
device->service_list = g_hash_table_new_full(g_direct_hash,
g_direct_equal, NULL, service_destroy);
@@ -989,8 +1018,8 @@ void qmi_device_unref(struct qmi_device *device)
g_queue_foreach(device->req_queue, __request_free, NULL);
g_queue_free(device->req_queue);
- g_queue_foreach(device->discovery_queue, __discovery_free, NULL);
- g_queue_free(device->discovery_queue);
+ g_queue_foreach(device->callback_queue, __callback_free, NULL);
+ g_queue_free(device->callback_queue);
if (device->write_watch > 0)
g_source_remove(device->write_watch);
@@ -1051,34 +1080,12 @@ static const void *tlv_get(const void *data, uint16_t size,
return NULL;
}
-struct discover_data {
- struct qmi_device *device;
- qmi_discover_func_t func;
- void *user_data;
- qmi_destroy_func_t destroy;
- guint timeout;
-};
-
-static void discover_data_free(gpointer user_data)
-{
- struct discover_data *data = user_data;
-
- if (data->timeout) {
- g_source_remove(data->timeout);
- data->timeout = 0;
- }
-
- if (data->destroy)
- data->destroy(data->user_data);
-
- g_free(data);
-}
-
static void discover_callback(uint16_t message, uint16_t length,
const void *buffer, void *user_data)
{
- struct discover_data *data = user_data;
- struct qmi_device *device = data->device;
+ struct callback_data *callback = user_data;
+ struct discover_data *data = &callback->data.discover;
+ struct qmi_device *device = callback->device;
const struct qmi_result_code *result_code;
const struct qmi_service_list *service_list;
const void *ptr;
@@ -1155,23 +1162,22 @@ done:
device->version_count = count;
if (data->func)
- data->func(count, list, data->user_data);
+ data->func(count, list, callback->user_data);
- __qmi_device_discovery_complete(data->device, data);
+ __callback_complete(callback);
}
static gboolean discover_reply(gpointer user_data)
{
- struct discover_data *data = user_data;
- struct qmi_device *device = data->device;
-
- data->timeout = 0;
+ struct callback_data *callback = user_data;
+ struct discover_data *data = &callback->data.discover;
+ struct qmi_device *device = callback->device;
if (data->func)
data->func(device->version_count,
- device->version_list, data->user_data);
+ device->version_list, callback->user_data);
- __qmi_device_discovery_complete(data->device, data);
+ __callback_complete(callback);
return FALSE;
}
@@ -1179,7 +1185,7 @@ static gboolean discover_reply(gpointer user_data)
bool qmi_device_discover(struct qmi_device *device, qmi_discover_func_t func,
void *user_data, qmi_destroy_func_t destroy)
{
- struct discover_data *data;
+ struct callback_data *callback;
struct qmi_request *req;
struct qmi_control_hdr *hdr;
@@ -1188,27 +1194,27 @@ bool qmi_device_discover(struct qmi_device *device, qmi_discover_func_t func,
__debug_device(device, "device %p discover", device);
- data = g_try_new0(struct discover_data, 1);
- if (!data)
+ callback = g_try_new0(struct callback_data, 1);
+ if (!callback)
return false;
- data->device = device;
- data->func = func;
- data->user_data = user_data;
- data->destroy = destroy;
+ callback->device = device;
+ callback->user_data = user_data;
+ callback->user_destroy = destroy;
+ callback->data.discover.func = func;
if (device->version_list) {
- data->timeout = g_timeout_add_seconds(0, discover_reply, data);
- __qmi_device_discovery_started(device, data,
- discover_data_free);
+ callback->timeout = g_timeout_add_seconds(0, discover_reply,
+ callback);
+ __callback_started(callback);
return true;
}
req = __request_alloc(QMI_SERVICE_CONTROL, 0x00,
QMI_CTL_GET_VERSION_INFO, QMI_CONTROL_HDR_SIZE,
- NULL, 0, discover_callback, data, (void **) &hdr);
+ NULL, 0, discover_callback, callback, (void **) &hdr);
if (!req) {
- g_free(data);
+ g_free(callback);
return false;
}
@@ -1220,8 +1226,8 @@ bool qmi_device_discover(struct qmi_device *device, qmi_discover_func_t func,
__request_submit(device, req, hdr->transaction);
- data->timeout = g_timeout_add_seconds(5, discover_reply, data);
- __qmi_device_discovery_started(device, data, discover_data_free);
+ callback->timeout = g_timeout_add_seconds(5, discover_reply, callback);
+ __callback_started(callback);
return true;
}
@@ -1252,39 +1258,34 @@ static void release_client(struct qmi_device *device,
__request_submit(device, req, hdr->transaction);
}
-struct shutdown_data {
- struct qmi_device *device;
- qmi_shutdown_func_t func;
- void *user_data;
- qmi_destroy_func_t destroy;
-};
-
static gboolean shutdown_reply(gpointer user_data)
{
- struct shutdown_data *data = user_data;
+ struct callback_data *callback = user_data;
+ struct shutdown_data *data = &callback->data.shutdown;
if (data->func)
- data->func(data->user_data);
+ data->func(callback->user_data);
- g_free(data);
+ __callback_complete(callback);
return FALSE;
}
static gboolean shutdown_timeout(gpointer user_data)
{
- struct shutdown_data *data = user_data;
- struct qmi_device *device = data->device;
+ struct callback_data *callback = user_data;
+ struct qmi_device *device = callback->device;
if (device->release_users > 0)
return TRUE;
- return shutdown_reply(data);
+ return shutdown_reply(callback);
}
bool qmi_device_shutdown(struct qmi_device *device, qmi_shutdown_func_t func,
void *user_data, qmi_destroy_func_t destroy)
{
+ struct callback_data *callback;
struct shutdown_data *data;
if (!device)
@@ -1292,19 +1293,22 @@ bool qmi_device_shutdown(struct qmi_device *device, qmi_shutdown_func_t func,
__debug_device(device, "device %p shutdown", device);
- data = g_try_new0(struct shutdown_data, 1);
- if (!data)
+ callback = g_try_new0(struct callback_data, 1);
+ if (!callback)
return false;
- data->device = device;
+ callback->device = device;
+ callback->user_data = user_data;
+ callback->user_destroy = destroy;
+ data = &callback->data.shutdown;
data->func = func;
- data->user_data = user_data;
- data->destroy = destroy;
if (device->release_users > 0)
- g_timeout_add_seconds(0, shutdown_timeout, data);
+ g_timeout_add_seconds(0, shutdown_timeout, callback);
else
- g_timeout_add_seconds(0, shutdown_reply, data);
+ g_timeout_add_seconds(0, shutdown_reply, callback);
+
+ __callback_started(callback);
return true;
}
@@ -1771,41 +1775,13 @@ bool qmi_result_get_uint64(struct qmi_result *result, uint8_t type,
return true;
}
-struct service_create_data {
- struct qmi_device *device;
- bool shared;
- uint8_t type;
- uint16_t major;
- uint16_t minor;
- qmi_create_func_t func;
- void *user_data;
- qmi_destroy_func_t destroy;
- guint timeout;
-};
-
-static void service_create_data_free(gpointer user_data)
-{
- struct service_create_data *data = user_data;
-
- if (data->timeout) {
- g_source_remove(data->timeout);
- data->timeout = 0;
- }
-
- if (data->destroy)
- data->destroy(data->user_data);
-
- g_free(data);
-}
-
static gboolean service_create_reply(gpointer user_data)
{
- struct service_create_data *data = user_data;
+ struct callback_data *callback = user_data;
- data->timeout = 0;
- data->func(NULL, data->user_data);
+ callback->data.service_create.func(NULL, callback->user_data);
- __qmi_device_discovery_complete(data->device, data);
+ __callback_complete(callback);
return FALSE;
}
@@ -1813,8 +1789,9 @@ static gboolean service_create_reply(gpointer user_data)
static void service_create_callback(uint16_t message, uint16_t length,
const void *buffer, void *user_data)
{
- struct service_create_data *data = user_data;
- struct qmi_device *device = data->device;
+ struct callback_data *callback = user_data;
+ struct service_create_data *data = &callback->data.service_create;
+ struct qmi_device *device = callback->device;
struct qmi_service *service = NULL;
const struct qmi_result_code *result_code;
const struct qmi_client_id *client_id;
@@ -1843,7 +1820,7 @@ static void service_create_callback(uint16_t message, uint16_t length,
goto done;
service->ref_count = 1;
- service->device = data->device;
+ service->device = callback->device;
service->shared = data->shared;
service->type = data->type;
@@ -1861,17 +1838,18 @@ static void service_create_callback(uint16_t message, uint16_t length,
GUINT_TO_POINTER(hash_id), service);
done:
- data->func(service, data->user_data);
+ data->func(service, callback->user_data);
qmi_service_unref(service);
- __qmi_device_discovery_complete(data->device, data);
+ __callback_complete(callback);
}
static void service_create_discover(uint8_t count,
const struct qmi_version *list, void *user_data)
{
- struct service_create_data *data = user_data;
- struct qmi_device *device = data->device;
+ struct callback_data *callback = user_data;
+ struct service_create_data *data = &callback->data.service_create;
+ struct qmi_device *device = callback->device;
struct qmi_request *req;
struct qmi_control_hdr *hdr;
unsigned char client_req[] = { 0x01, 0x01, 0x00, data->type };
@@ -1890,15 +1868,14 @@ static void service_create_discover(uint8_t count,
req = __request_alloc(QMI_SERVICE_CONTROL, 0x00,
QMI_CTL_GET_CLIENT_ID, QMI_CONTROL_HDR_SIZE,
client_req, sizeof(client_req),
- service_create_callback, data, (void **) &hdr);
+ service_create_callback, callback, (void **) &hdr);
if (!req) {
- if (data->timeout > 0)
- g_source_remove(data->timeout);
+ if (callback->timeout > 0)
+ g_source_remove(callback->timeout);
- data->timeout = g_timeout_add_seconds(0,
- service_create_reply, data);
- __qmi_device_discovery_started(device, data,
- service_create_data_free);
+ callback->timeout = g_timeout_add_seconds(0,
+ service_create_reply, callback);
+ __callback_started(callback);
return;
}
@@ -1915,36 +1892,39 @@ static bool service_create(struct qmi_device *device, bool shared,
uint8_t type, qmi_create_func_t func,
void *user_data, qmi_destroy_func_t destroy)
{
+ struct callback_data *callback;
struct service_create_data *data;
- data = g_try_new0(struct service_create_data, 1);
- if (!data)
+ callback = g_try_new0(struct callback_data, 1);
+ if (!callback)
return false;
- data->device = device;
+ callback->device = device;
+ callback->user_data = user_data;
+ callback->user_destroy = destroy;
+ data = &callback->data.service_create;
+ data->func = func;
data->shared = shared;
data->type = type;
- data->func = func;
- data->user_data = user_data;
- data->destroy = destroy;
if (device->version_list) {
service_create_discover(device->version_count,
- device->version_list, data);
+ device->version_list, callback);
goto done;
}
- if (qmi_device_discover(device, service_create_discover, data, NULL))
+ if (qmi_device_discover(device, service_create_discover, callback,
+ NULL))
goto done;
- g_free(data);
+ g_free(callback);
return false;
done:
- data->timeout = g_timeout_add_seconds(8, service_create_reply, data);
- __qmi_device_discovery_started(device, data,
- service_create_data_free);
+ callback->timeout = g_timeout_add_seconds(8, service_create_reply,
+ callback);
+ __callback_started(callback);
return true;
}
@@ -1962,40 +1942,15 @@ bool qmi_service_create(struct qmi_device *device,
return service_create(device, false, type, func, user_data, destroy);
}
-struct service_create_shared_data {
- struct qmi_service *service;
- struct qmi_device *device;
- qmi_create_func_t func;
- void *user_data;
- qmi_destroy_func_t destroy;
- guint timeout;
-};
-
-static void service_create_shared_data_free(gpointer user_data)
-{
- struct service_create_shared_data *data = user_data;
-
- if (data->timeout) {
- g_source_remove(data->timeout);
- data->timeout = 0;
- }
-
- qmi_service_unref(data->service);
-
- if (data->destroy)
- data->destroy(data->user_data);
-
- g_free(data);
-}
-
static gboolean service_create_shared_reply(gpointer user_data)
{
- struct service_create_shared_data *data = user_data;
+ struct callback_data *callback = user_data;
+ struct service_create_shared_data *data =
+ &callback->data.service_create_shared;
- data->timeout = 0;
- data->func(data->service, data->user_data);
+ data->func(data->service, callback->user_data);
- __qmi_device_discovery_complete(data->device, data);
+ __callback_complete(callback);
return FALSE;
}
@@ -2016,22 +1971,24 @@ bool qmi_service_create_shared(struct qmi_device *device,
service = g_hash_table_find(device->service_list,
__service_compare_shared, GUINT_TO_POINTER(type_val));
if (service) {
+ struct callback_data *callback;
struct service_create_shared_data *data;
- data = g_try_new0(struct service_create_shared_data, 1);
- if (!data)
+ callback = g_try_new0(struct callback_data, 1);
+ if (!callback)
return false;
+ callback->device = device;
+ callback->user_data = user_data;
+ callback->user_destroy = destroy;
+ callback->callback_destroy = service_create_shared_free;
+ data = &callback->data.service_create_shared;
data->service = qmi_service_ref(service);
- data->device = device;
data->func = func;
- data->user_data = user_data;
- data->destroy = destroy;
- data->timeout = g_timeout_add(0,
- service_create_shared_reply, data);
- __qmi_device_discovery_started(device, data,
- service_create_shared_data_free);
+ callback->timeout = g_timeout_add(0,
+ service_create_shared_reply, callback);
+ __callback_started(callback);
return 0;
}
--
2.7.4
5 years, 2 months