Connection lost on Embedded Linux system
by contact@dsiekmeier.de
Hello,
I am currently working with oFono for a wireless modem on an Embedded Linux.
Things are working okay if the signal strength is quite good. Nevertheless, if I alter
the signal strength by for example removing the antenna, my device often comes
into a strange state:
For debugging I am using mainly "dbus-send" to see the current information about
oFono. Sometimes the device is registered in the network, I have an IP adress and
a fairly good signal strength (40-60). But doing a ping request does not work (no
outgoing traffic),
If I restart oFono manually, everything is working fine again. Is there any known bug
regarding some blocking state changes or something like this? Are there known
limitations using connman and oFono together?
Kind Regards
2 years, 7 months
[PATCH] xmm7modem: fix for crash after receiving MT SMS after SIM swap
by Antara Borwankar
Earlier SMS atom was being created based on +XSIMSTATE command,
which is a proprietary command for intel modems.
But this logic fails in case of SIM hot swap when +XSIMSTATE
value received is not handled in notify function.
There can be other such scenarios as well. Therefore SMS atom
will now be created in post_online function which anyways gets
called after +XSIMSTATE SMS READY and PB READY is received.
---
plugins/xmm7xxx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plugins/xmm7xxx.c b/plugins/xmm7xxx.c
index a544798..876f614 100644
--- a/plugins/xmm7xxx.c
+++ b/plugins/xmm7xxx.c
@@ -1003,7 +1003,6 @@ static void switch_sim_state_status(struct ofono_modem *modem, int status)
if (data->sms_phonebook_added == FALSE) {
ofono_phonebook_create(modem, 0, "atmodem", data->chat);
- ofono_sms_create(modem, 0, "atmodem", data->chat);
data->sms_phonebook_added = TRUE;
}
@@ -1281,6 +1280,7 @@ static void xmm7xxx_post_online(struct ofono_modem *modem)
ofono_ims_create(modem, "xmm7modem", data->chat);
ofono_netmon_create(modem, 0, "xmm7modem", data->chat);
+ ofono_sms_create(modem, 0, "atmodem", data->chat);
}
static int xmm7xxx_probe(struct ofono_modem *modem)
--
1.9.1
2 years, 7 months
With QCOM android device, How do I test ofono
by khlee9228@naver.com
Hi.
I have a currently QCOM android device and developer. I want to test ofono integration and some tests based on this device.
How do I start ofono integration first
Thanks
paul.
2 years, 7 months
Telit HE910-d failed to activate context
by nick83ola
Hello
I'm working with a telit HE910-D with the latest ofono 1.30 and latest connman
I do the following:
systemctl start ofono
root@bumblebee-21c24c:~# cd /usr/lib/ofono/test/
root@bumblebee-21c24c:/usr/lib/ofono/test# ./list-modems
[ /telit_0 ]
Online = 0
Powered = 0
Lockdown = 0
Emergency = 0
SystemPath =
/sys/devices/soc0/soc/30800000.aips-bus/30b30000.usb/ci_hdrc.1/usb2/2-1/2-1.1
Interfaces =
Features =
Type = hardware
root@bumblebee-21c24c:/usr/lib/ofono/test# ./enable-modem
Connecting modem /telit_0...
root@bumblebee-21c24c:/usr/lib/ofono/test# ./list-modems
[ /telit_0 ]
Online = 1
Powered = 1
Lockdown = 0
Emergency = 0
Manufacturer = Telit
Model = HE910-D
Revision = 12.00.024
Serial = 351579052975024
SystemPath =
/sys/devices/soc0/soc/30800000.aips-bus/30b30000.usb/ci_hdrc.1/usb2/2-1/2-1.1
Interfaces = org.ofono.SmartMessaging org.ofono.PushNotification
org.ofono.MessageManager org.ofono.Phonebook
org.ofono.NetworkRegistration org.ofono.ConnectionManager
org.ofono.AllowedAccessPoints org.ofono.SimManager
Features = sms net gprs sim
Type = hardware
[ org.ofono.SmartMessaging ]
[ org.ofono.PushNotification ]
[ org.ofono.MessageManager ]
ServiceCenterAddress = +353868002000
UseDeliveryReports = 0
Bearer = cs-preferred
Alphabet = default
[ org.ofono.Phonebook ]
[ org.ofono.NetworkRegistration ]
Status = registered
Mode = auto
LocationAreaCode = 32500
CellId = 47189919
Technology = umts
MobileCountryCode = 272
MobileNetworkCode = 02
Name = 3
Strength = 40
[ org.ofono.ConnectionManager ]
Attached = 1
Bearer = hsdpa
RoamingAllowed = 0
Powered = 1
Suspended = 0
[ org.ofono.AllowedAccessPoints ]
[ org.ofono.SimManager ]
Present = 1
CardIdentifier = 8935302173240104694
SubscriberIdentity = 272023119202599
FixedDialing = 0
BarredDialing = 0
MobileCountryCode = 272
MobileNetworkCode = 02
SubscriberNumbers = +353864633764
LockedPins =
PinRequired = none
Retries = [pin = 3] [pin2 = 3] [puk = 10] [puk2 = 10]
CardSlotCount = 1
ActiveCardSlot = 1
root@bumblebee-21c24c:/usr/lib/ofono/test# ./list-contexts
[ /telit_0 ]
[ /telit_0/context1 ]
Name = Internet
Active = 0
Type = internet
Protocol = ip
AccessPointName =
Username =
Password =
AuthenticationMethod = chap
Settings = { }
IPv6.Settings = { }
root@bumblebee-21c24c:/usr/lib/ofono/test# ./remove-contexts
Removed: [ /telit_0/context1 ]
root@bumblebee-21c24c:/usr/lib/ofono/test# ./create-internet-context
Created new context /telit_0/context1
root@bumblebee-21c24c:/usr/lib/ofono/test# ./online-modem
Setting modem /telit_0 online...
root@bumblebee-21c24c:/usr/lib/ofono/test# ./activate-context
root@bumblebee-21c24c:/usr/lib/ofono/test# ./list-modems
[ /telit_0 ]
Online = 1
Powered = 1
Lockdown = 0
Emergency = 0
Manufacturer = Telit
Model = HE910-D
Revision = 12.00.024
Serial = 351579052975024
SystemPath =
/sys/devices/soc0/soc/30800000.aips-bus/30b30000.usb/ci_hdrc.1/usb2/2-1/2-1.1
Interfaces = org.ofono.SmartMessaging org.ofono.PushNotification
org.ofono.MessageManager org.ofono.Phonebook
org.ofono.NetworkRegistration org.ofono.ConnectionManager
org.ofono.AllowedAccessPoints org.ofono.SimManager
Features = sms net gprs sim
Type = hardware
[ org.ofono.SmartMessaging ]
[ org.ofono.PushNotification ]
[ org.ofono.MessageManager ]
ServiceCenterAddress = +353868002000
UseDeliveryReports = 0
Bearer = cs-preferred
Alphabet = default
[ org.ofono.Phonebook ]
[ org.ofono.NetworkRegistration ]
Status = registered
Mode = auto
LocationAreaCode = 32500
CellId = 47192005
Technology = umts
MobileCountryCode = 272
MobileNetworkCode = 02
Name = 3
Strength = 40
[ org.ofono.ConnectionManager ]
Attached = 1
Bearer = hsdpa
RoamingAllowed = 0
Powered = 1
Suspended = 0
[ org.ofono.AllowedAccessPoints ]
[ org.ofono.SimManager ]
Present = 1
CardIdentifier = 8935302173240104694
SubscriberIdentity = 272023119202599
FixedDialing = 0
BarredDialing = 0
MobileCountryCode = 272
MobileNetworkCode = 02
SubscriberNumbers = +353864633764
LockedPins =
PinRequired = none
Retries = [pin = 3] [pin2 = 3] [puk = 10] [puk2 = 10]
CardSlotCount = 1
ActiveCardSlot = 1
root@bumblebee-21c24c:/usr/lib/ofono/test# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state
DOWN qlen 1000
link/ether 00:01:c0:21:c2:4c brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:01:c0:21:c2:53 brd ff:ff:ff:ff:ff:ff
inet 10.32.234.43/24 brd 10.32.234.255 scope global dynamic eth1
valid_lft 6899sec preferred_lft 6899sec
inet6 fe80::201:c0ff:fe21:c253/64 scope link
valid_lft forever preferred_lft forever
4: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN qlen 1000
link/sit 0.0.0.0 brd 0.0.0.0
5: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc
pfifo_fast state UNKNOWN qlen 500
link/[65534]
inet6 fe80::cfa:2a85:a32a:9967/64 scope link
valid_lft forever preferred_lft forever
The problem is that the ppp0 interface doesn't get an ip while on te
log I can clearly see it
Oct 16 14:24:46 bumblebee-21c24c ofonod[551]: ofonod[551]: PPP:
../../../../../../workspace/sources/ofono/gatchat/gatppp.c:ppp_enter_phase()
4
Oct 16 14:24:46 bumblebee-21c24c ofonod[551]: ofonod[551]:
../../../../../../workspace/sources/ofono/drivers/atmodem/gprs-context.c:ppp_connect()
Oct 16 14:24:46 bumblebee-21c24c ofonod[551]: ofonod[551]: IP: 100.88.174.61
Oct 16 14:24:46 bumblebee-21c24c ofonod[551]: ofonod[551]: DNS:
83.136.46.138, 62.40.32.33
Oct 16 14:24:46 bumblebee-21c24c ofonod[551]: ofonod[551]:
../../../../../../workspace/sources/ofono/src/gprs.c:pri_activate_callback()
0x2201620
Oct 16 14:24:46 bumblebee-21c24c ofonod[551]: ofonod[551]:
../../../../../../workspace/sources/ofono/plugins/udevng.c:add_serial_device()
Device is missing required OFONO_DRIVER property
Oct 16 14:24:47 bumblebee-21c24c ofonod[551]: ofonod[551]:
../../../../../../workspace/sources/ofono/plugins/udevng.c:check_modem_list()
Oct 16 14:24:50 bumblebee-21c24c ofonod[551]: ofonod[551]:
../../../../../../workspace/sources/ofono/src/modem.c:get_modem_property()
modem 0x76c5f530 property SystemPath
Can you help me to debug this?
Thanks
Nicola Lunghi
2 years, 7 months
Hi. I am starting new job with ofono with linux
by khlee9228@naver.com
Hello.
I am working with ofono on top of linux platform.
Until now, I am using android based modem like as Qualcomm QMI based modem.
I'd like to start with QT APP with ofono and linux
How do I start ofono ?
Please let me know how do I start ofono job
Paul.
2 years, 7 months
[PATCH] gprs: update attached on netreg updates when running LTE
by richard.rojfors@gmail.com
From: Richard Röjfors <richard(a)puffinpack.se>
There was a race condition where a context might be
registered before the netreg status updates to LTE.
The code took for granted the context is activated after
the technology update. With this change, any order is
is accepted.
---
src/gprs.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/gprs.c b/src/gprs.c
index a8702958..a1e52572 100644
--- a/src/gprs.c
+++ b/src/gprs.c
@@ -1721,12 +1721,18 @@ static void gprs_netreg_update(struct ofono_gprs *gprs)
DBG("attach: %u, driver_attached: %u", attach, gprs->driver_attached);
- if (on_lte(gprs))
+ if (on_lte(gprs)) {
/*
* For LTE we set attached status only on successful
* context activation.
+ *
+ * The context could potentially be registered before the netreg
+ * update is received.
*/
- return;
+ gprs_attached_update(gprs);
+
+ return;
+ }
if (gprs->driver_attached == attach)
return;
--
2.20.1
2 years, 7 months
[PATCHv3 1/2] quectel: rework sim detection
by Martin Hundebøll
Use at_util_sim_state_query_new() to query the sim inserted state. Once
that returns, the locked state is queried by issuing a AT+CPIN? command.
If not locked, a timer is started to query the quectel init status of
the sim. Once the init status is ready, the sim atom is created, and the
modem is set to powered, and the sim is signaled both inserted, and
initialized.
If locked, the modem is set to powered, and the sim atom is created.
This allows users to enter the pin to unlock the sim. Once the sim is
unlocked, a +CPIN: READY indication is caught to query the quectel
init status. Once the init status is ready, the sim is signaled
initialized.
All the above is needed, because the modem indicated +CPIN: READY before
the sim is really ready. The only way to be certain, is to wait for the
quectel init status to be ready. Even signaling the sim inserted
prematurely can cause to modem to hang during the initial AT+CRSM
commands.
---
Changes since v2:
* None
plugins/quectel.c | 255 +++++++++++++++++-----------------------------
1 file changed, 94 insertions(+), 161 deletions(-)
diff --git a/plugins/quectel.c b/plugins/quectel.c
index a0e435b5..f19065b2 100644
--- a/plugins/quectel.c
+++ b/plugins/quectel.c
@@ -84,22 +84,15 @@ enum quectel_model {
QUECTEL_MC60,
};
-enum quectel_state {
- QUECTEL_STATE_INITIALIZING = 0,
- QUECTEL_STATE_POST_SIM,
- QUECTEL_STATE_READY,
- QUECTEL_STATE_INITIALIZED,
-};
-
struct quectel_data {
GAtChat *modem;
GAtChat *aux;
enum ofono_vendor vendor;
enum quectel_model model;
- enum quectel_state state;
- struct ofono_sim *sim;
- enum ofono_sim_state sim_state;
+ struct at_util_sim_state_query *sim_state_query;
unsigned int sim_watch;
+ bool sim_locked;
+ bool sim_ready;
/* used by quectel uart driver */
GAtChat *uart;
@@ -195,6 +188,7 @@ static void quectel_remove(struct ofono_modem *modem)
ofono_modem_set_data(modem, NULL);
l_timeout_remove(data->init_timeout);
l_gpio_writer_free(data->gpio);
+ at_util_sim_state_query_free(data->sim_state_query);
g_at_chat_unref(data->aux);
g_at_chat_unref(data->modem);
g_at_chat_unref(data->uart);
@@ -238,6 +232,9 @@ static void close_serial(struct ofono_modem *modem)
DBG("%p", modem);
+ at_util_sim_state_query_free(data->sim_state_query);
+ data->sim_state_query = NULL;
+
g_at_chat_unref(data->aux);
data->aux = NULL;
@@ -534,6 +531,7 @@ static void dbus_hw_enable(struct ofono_modem *modem)
static void qinistat_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
struct ofono_modem *modem = user_data;
+ struct ofono_sim *sim = ofono_modem_get_sim(modem);
struct quectel_data *data = ofono_modem_get_data(modem);
GAtResultIter iter;
int ready = 0;
@@ -574,42 +572,13 @@ static void qinistat_cb(gboolean ok, GAtResult *result, gpointer user_data)
l_timeout_remove(data->init_timeout);
data->init_timeout = NULL;
- if (data->sim_state == OFONO_SIM_STATE_READY) {
- /*
- * when initializing with a non-locked sim card, the sim atom
- * isn't created until now to avoid accessing it before the
- * modem is ready.
- *
- * call ofono_modem_set_powered() to make ofono call
- * quectel_pre_sim() where the sim atom is created.
- */
- ofono_modem_set_powered(modem, true);
- } else {
- /*
- * When initialized with a locked sim card, the modem is already
- * powered up, and the inserted signal has been sent to allow
- * the pin to be entered. So simply update the state, and notify
- * about the finished initialization below.
- */
- data->sim_state = OFONO_SIM_STATE_READY;
- }
-
- ofono_sim_initialized_notify(data->sim);
-
- /*
- * If quectel_post_sim() has not yet been called, then postpone atom
- * creation until it is called. Otherwise create the atoms now.
- */
- if (data->state != QUECTEL_STATE_POST_SIM) {
- data->state = QUECTEL_STATE_READY;
+ if (data->sim_locked) {
+ ofono_sim_initialized_notify(sim);
return;
}
- ofono_sms_create(modem, data->vendor, "atmodem", data->aux);
- ofono_phonebook_create(modem, data->vendor, "atmodem", data->aux);
- ofono_voicecall_create(modem, data->vendor, "atmodem", data->aux);
- ofono_call_volume_create(modem, data->vendor, "atmodem", data->aux);
- data->state = QUECTEL_STATE_INITIALIZED;
+ data->sim_ready = true;
+ ofono_modem_set_powered(modem, TRUE);
}
static void init_timer_cb(struct l_timeout *timeout, void *user_data)
@@ -627,118 +596,94 @@ static void sim_watch_cb(GAtResult *result, void *user_data)
{
struct ofono_modem *modem = user_data;
struct quectel_data *data = ofono_modem_get_data(modem);
+ GAtResultIter iter;
+ const char *cpin;
DBG("%p", modem);
- g_at_chat_unregister(data->aux, data->sim_watch);
- data->sim_watch = 0;
+ g_at_result_iter_init(&iter, result);
- data->init_timeout = l_timeout_create_ms(500, init_timer_cb, modem, NULL);
- if (!data->init_timeout) {
- close_serial(modem);
+ if (!g_at_result_iter_next(&iter, "+CPIN:"))
return;
- }
-}
-static enum ofono_sim_state cme_parse(GAtResult *result)
-{
- struct ofono_error error;
+ g_at_result_iter_next_unquoted_string(&iter, &cpin);
- decode_at_error(&error, g_at_result_final_response(result));
+ if (g_strcmp0(cpin, "READY") != 0)
+ return;
- if (error.type != OFONO_ERROR_TYPE_CME)
- return OFONO_SIM_STATE_RESETTING;
-
- switch (error.error) {
- case 5:
- case 6:
- case 7:
- case 11:
- case 12:
- case 17:
- case 18:
- return OFONO_SIM_STATE_LOCKED_OUT;
- case 10:
- return OFONO_SIM_STATE_NOT_PRESENT;
- case 13:
- case 14:
- case 15:
- return OFONO_SIM_STATE_RESETTING;
- default:
- ofono_error("unknown cpin error: %i", error.error);
- return OFONO_SIM_STATE_RESETTING;
- }
+ g_at_chat_unregister(data->aux, data->sim_watch);
+ data->sim_watch = 0;
+
+ data->init_timeout = l_timeout_create_ms(500, init_timer_cb, modem, NULL);
}
-static enum ofono_sim_state cpin_parse(GAtResult *result)
+static void cpin_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
+ struct ofono_modem *modem = user_data;
+ struct quectel_data *data = ofono_modem_get_data(modem);
+ const char *path = ofono_modem_get_path(modem);
GAtResultIter iter;
const char *cpin;
+ DBG("%p", modem);
+
+ if (!ok) {
+ close_serial(modem);
+ return;
+ }
+
g_at_result_iter_init(&iter, result);
- if (!g_at_result_iter_next(&iter, "+CPIN:"))
- return OFONO_SIM_STATE_RESETTING;
+ if (!g_at_result_iter_next(&iter, "+CPIN:")) {
+ close_serial(modem);
+ return;
+ }
g_at_result_iter_next_unquoted_string(&iter, &cpin);
- if (g_strcmp0(cpin, "NOT INSERTED") == 0)
- return OFONO_SIM_STATE_NOT_PRESENT;
+ if (g_strcmp0(cpin, "READY") == 0) {
+ data->init_timeout = l_timeout_create_ms(500, init_timer_cb,
+ modem, NULL);
+ return;
+ }
- if (g_strcmp0(cpin, "READY") == 0)
- return OFONO_SIM_STATE_READY;
+ if (g_strcmp0(cpin, "SIM PIN") != 0) {
+ close_serial(modem);
+ return;
+ }
- return OFONO_SIM_STATE_LOCKED_OUT;
+ ofono_info("%s: sim locked", path);
+ data->sim_locked = true;
+ data->sim_watch = g_at_chat_register(data->aux, "+CPIN:",
+ sim_watch_cb, FALSE,
+ modem, NULL);
+ ofono_modem_set_powered(modem, TRUE);
}
-static void cpin_query(gboolean ok, GAtResult *result, gpointer user_data)
+static void sim_state_cb(gboolean present, gpointer user_data)
{
struct ofono_modem *modem = user_data;
struct quectel_data *data = ofono_modem_get_data(modem);
+ const char *path = ofono_modem_get_path(modem);
- DBG("%p ok %i", modem, ok);
+ DBG("%p present %d", modem, present);
- if (ok)
- data->sim_state = cpin_parse(result);
- else
- data->sim_state = cme_parse(result);
-
- /* Turn off the radio. */
- g_at_chat_send(data->aux, "AT+CFUN=4", none_prefix, NULL, NULL, NULL);
-
- switch (data->sim_state) {
- case OFONO_SIM_STATE_LOCKED_OUT:
- ofono_modem_set_powered(modem, true);
- data->sim_watch = g_at_chat_register(data->aux, "+CPIN: READY",
- sim_watch_cb, FALSE,
- modem, NULL);
- if (!data->sim_watch) {
- ofono_error("failed to create sim watch");
- close_serial(modem);
- return;
- }
- break;
- case OFONO_SIM_STATE_READY:
- data->init_timeout = l_timeout_create_ms(500, init_timer_cb,
- modem, NULL);
- if (!data->init_timeout) {
- ofono_error("failed to create qinitstat timer");
- close_serial(modem);
- return;
- }
- break;
- case OFONO_SIM_STATE_RESETTING:
- case OFONO_SIM_STATE_INSERTED:
- g_at_chat_send(data->aux, "AT+CPIN?", cpin_prefix, cpin_query,
- modem, NULL);
- break;
- case OFONO_SIM_STATE_NOT_PRESENT:
- ofono_warn("%s: sim not present", ofono_modem_get_path(modem));
- ofono_modem_set_powered(modem, true);
+ at_util_sim_state_query_free(data->sim_state_query);
+ data->sim_state_query = NULL;
+ data->sim_locked = false;
+ data->sim_ready = false;
+
+ if (!present) {
+ ofono_modem_set_powered(modem, TRUE);
+ ofono_warn("%s: sim not present", path);
+ return;
}
+
+ g_at_chat_send(data->aux, "AT+CPIN?", cpin_prefix, cpin_cb, modem,
+ NULL);
}
-static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data)
+static void cfun_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
struct ofono_modem *modem = user_data;
struct quectel_data *data = ofono_modem_get_data(modem);
@@ -751,8 +696,24 @@ static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data)
}
dbus_hw_enable(modem);
+ data->sim_state_query = at_util_sim_state_query_new(data->aux,
+ 2, 20, sim_state_cb, modem,
+ NULL);
+}
+
+static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct quectel_data *data = ofono_modem_get_data(modem);
- g_at_chat_send(data->aux, "AT+CPIN?", cpin_prefix, cpin_query, modem,
+ DBG("%p ok %d", modem, ok);
+
+ if (!ok) {
+ close_serial(modem);
+ return;
+ }
+
+ g_at_chat_send(data->aux, "AT+CFUN=4", none_prefix, cfun_cb, modem,
NULL);
}
@@ -1108,8 +1069,6 @@ static int quectel_disable(struct ofono_modem *modem)
g_at_chat_send(data->aux, "AT+CFUN=0", cfun_prefix, cfun_disable, modem,
NULL);
- data->state = QUECTEL_STATE_INITIALIZING;
-
return -EINPROGRESS;
}
@@ -1146,22 +1105,18 @@ static void quectel_set_online(struct ofono_modem *modem, ofono_bool_t online,
static void quectel_pre_sim(struct ofono_modem *modem)
{
struct quectel_data *data = ofono_modem_get_data(modem);
+ struct ofono_sim *sim;
DBG("%p", modem);
- ofono_devinfo_create(modem, 0, "atmodem", data->aux);
- data->sim = ofono_sim_create(modem, data->vendor, "atmodem", data->aux);
- if (!data->sim)
- return;
+ ofono_voicecall_create(modem, data->vendor, "atmodem", data->aux);
+ sim = ofono_sim_create(modem, data->vendor, "atmodem", data->aux);
- switch (data->sim_state) {
- case OFONO_SIM_STATE_LOCKED_OUT:
- case OFONO_SIM_STATE_READY:
- ofono_sim_inserted_notify(data->sim, true);
- break;
- default:
- break;
- }
+ if (data->sim_locked || data->sim_ready)
+ ofono_sim_inserted_notify(sim, true);
+
+ if (data->sim_ready)
+ ofono_sim_initialized_notify(sim);
}
static void quectel_post_sim(struct ofono_modem *modem)
@@ -1179,31 +1134,9 @@ static void quectel_post_sim(struct ofono_modem *modem)
if (gprs && gc)
ofono_gprs_add_context(gprs, gc);
- /*
- * the sim related atoms must not be created until the modem is really
- * ready, so check the state here
- */
- switch (data->state) {
- case QUECTEL_STATE_INITIALIZING:
- /*
- * the modem is still initializing, so postpone the atom
- * creation until qinistat_cb() determines the modem is
- * ready
- */
- data->state = QUECTEL_STATE_POST_SIM;
- return;
- case QUECTEL_STATE_READY:
- /* the modem is ready, so create atoms below */
- break;
- default:
- return;
- }
-
ofono_sms_create(modem, data->vendor, "atmodem", data->aux);
ofono_phonebook_create(modem, data->vendor, "atmodem", data->aux);
- ofono_voicecall_create(modem, data->vendor, "atmodem", data->aux);
ofono_call_volume_create(modem, data->vendor, "atmodem", data->aux);
- data->state = QUECTEL_STATE_INITIALIZED;
}
static void quectel_post_online(struct ofono_modem *modem)
--
2.23.0
2 years, 7 months
[PATCHv3 1/2] gatmux: take reference to mux object while processing incoming data
by Martin Hundebøll
When closing down a cmux object, the address sanitizer detects a
use-after-free in gatmux.c (see below).
Avoid this by taking a reference to the mux object during the processing
in received_data().
ofonod[3640549]: ../git/plugins/quectel.c:cfun_disable() 0x610000000b40
ofonod[3640549]: ../git/plugins/quectel.c:close_serial() 0x610000000b40
ofonod[3640549]: ../git/plugins/quectel.c:close_mux() 0x610000000b40
ofonod[3640549]: ../git/examples/emulator.c:powered_watch() Removing modem 0x610000000b40 from the list
ofonod[3640549]: ../git/examples/emulator.c:powered_watch() Removing server watch: 106
ofonod[3640549]: ../git/src/modem.c:modem_change_state() old state: 0, new state: 0
=================================================================
==3640549==ERROR: AddressSanitizer: heap-use-after-free on address 0x62100073dd28 at pc 0x5566b6402a21 bp 0x7ffe7a2db0e0 sp 0x7ffe7a2db0d0
READ of size 8 at 0x62100073dd28 thread T0
#0 0x5566b6402a20 in debug ../git/gatchat/gatmux.c:109
#1 0x5566b6404bd7 in channel_close ../git/gatchat/gatmux.c:525
#2 0x7fa0516e44a6 in g_io_channel_shutdown (/usr/lib/libglib-2.0.so.0+0x774a6)
#3 0x7fa0516e4644 in g_io_channel_unref (/usr/lib/libglib-2.0.so.0+0x77644)
#4 0x5566b64048a4 in watch_finalize ../git/gatchat/gatmux.c:474
#5 0x7fa0516d6f6f (/usr/lib/libglib-2.0.so.0+0x69f6f)
#6 0x7fa0516ac6a7 in g_slist_foreach (/usr/lib/libglib-2.0.so.0+0x3f6a7)
#7 0x7fa0516b277b in g_slist_free_full (/usr/lib/libglib-2.0.so.0+0x4577b)
#8 0x5566b6403413 in dispatch_sources ../git/gatchat/gatmux.c:224
#9 0x5566b64039ea in received_data ../git/gatchat/gatmux.c:268
#10 0x7fa0516d727e in g_main_context_dispatch (/usr/lib/libglib-2.0.so.0+0x6a27e)
#11 0x7fa0516d91c0 (/usr/lib/libglib-2.0.so.0+0x6c1c0)
#12 0x7fa0516da0d2 in g_main_loop_run (/usr/lib/libglib-2.0.so.0+0x6d0d2)
#13 0x5566b6429b1b in main ../git/src/main.c:286
#14 0x7fa05147fee2 in __libc_start_main (/usr/lib/libc.so.6+0x26ee2)
#15 0x5566b62531ad in _start (/home/martin/projects/ofono/x86/src/ofonod+0xfc1ad)
0x62100073dd28 is located 40 bytes inside of 4672-byte region [0x62100073dd00,0x62100073ef40)
freed by thread T0 here:
#0 0x7fa0519256c0 in __interceptor_free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:122
#1 0x5566b64052d7 in g_at_mux_unref ../git/gatchat/gatmux.c:645
#2 0x5566b63d6d19 in close_mux ../git/plugins/quectel.c:199
#3 0x5566b63d7047 in close_serial ../git/plugins/quectel.c:223
#4 0x5566b63db62a in cfun_disable ../git/plugins/quectel.c:1056
#5 0x5566b63f6ae1 in at_chat_finish_command ../git/gatchat/gatchat.c:459
#6 0x5566b63f701b in at_chat_handle_command_response ../git/gatchat/gatchat.c:521
#7 0x5566b63f785b in have_line ../git/gatchat/gatchat.c:600
#8 0x5566b63f87f1 in new_bytes ../git/gatchat/gatchat.c:759
#9 0x5566b640174c in received_data ../git/gatchat/gatio.c:122
#10 0x5566b64047b4 in watch_dispatch ../git/gatchat/gatmux.c:464
#11 0x5566b640313b in dispatch_sources ../git/gatchat/gatmux.c:183
#12 0x5566b64039ea in received_data ../git/gatchat/gatmux.c:268
#13 0x7fa0516d727e in g_main_context_dispatch (/usr/lib/libglib-2.0.so.0+0x6a27e)
previously allocated by thread T0 here:
#0 0x7fa051925ce8 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:153
#1 0x5566b6405009 in g_at_mux_new ../git/gatchat/gatmux.c:606
#2 0x5566b6407f6b in g_at_mux_new_gsm0710_basic ../git/gatchat/gatmux.c:1165
#3 0x5566b63da9ba in cmux_cb ../git/plugins/quectel.c:882
#4 0x5566b63f6ae1 in at_chat_finish_command ../git/gatchat/gatchat.c:459
#5 0x5566b63f701b in at_chat_handle_command_response ../git/gatchat/gatchat.c:521
#6 0x5566b63f785b in have_line ../git/gatchat/gatchat.c:600
#7 0x5566b63f87f1 in new_bytes ../git/gatchat/gatchat.c:759
#8 0x5566b640174c in received_data ../git/gatchat/gatio.c:122
#9 0x7fa0516d727e in g_main_context_dispatch (/usr/lib/libglib-2.0.so.0+0x6a27e)
SUMMARY: AddressSanitizer: heap-use-after-free ../git/gatchat/gatmux.c:109 in debug
Shadow bytes around the buggy address:
0x0c42800dfb50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c42800dfb60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c42800dfb70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c42800dfb80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c42800dfb90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c42800dfba0: fd fd fd fd fd[fd]fd fd fd fd fd fd fd fd fd fd
0x0c42800dfbb0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c42800dfbc0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c42800dfbd0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c42800dfbe0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c42800dfbf0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==3640549==ABORTING
---
Changes since v2:
* narrow the scope of the taken reference to the for loop
* defer removal of destroy notification callback to separate patch
gatchat/gatmux.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/gatchat/gatmux.c b/gatchat/gatmux.c
index 757a5123..d50e5361 100644
--- a/gatchat/gatmux.c
+++ b/gatchat/gatmux.c
@@ -231,6 +231,7 @@ static gboolean received_data(GIOChannel *channel, GIOCondition cond,
int i;
GIOStatus status;
gsize bytes_read;
+ gboolean buffer_full = FALSE;
if (cond & G_IO_NVAL)
return FALSE;
@@ -255,6 +256,8 @@ static gboolean received_data(GIOChannel *channel, GIOCondition cond,
if (mux->buf_used > 0)
memmove(mux->buf, mux->buf + nread, mux->buf_used);
+ g_at_mux_ref(mux);
+
for (i = 1; i <= MAX_CHANNELS; i++) {
int offset = i / 8;
int bit = i % 8;
@@ -267,6 +270,10 @@ static gboolean received_data(GIOChannel *channel, GIOCondition cond,
dispatch_sources(mux->dlcs[i-1], G_IO_IN);
}
+
+ buffer_full = mux->buf_used == sizeof(mux->buf);
+
+ g_at_mux_unref(mux);
}
if (cond & (G_IO_HUP | G_IO_ERR))
@@ -275,7 +282,7 @@ static gboolean received_data(GIOChannel *channel, GIOCondition cond,
if (status != G_IO_STATUS_NORMAL && status != G_IO_STATUS_AGAIN)
return FALSE;
- if (mux->buf_used == sizeof(mux->buf))
+ if (buffer_full)
return FALSE;
return TRUE;
--
2.23.0
2 years, 7 months
[PATCH] gatmux: don't free cmux data until watchers are destroyed
by Martin Hundebøll
When closing down a cmux object, the address sanitizer detects a
use-after-free in gatmux.c (see below).
Avoid this by taking a reference to the mux object during the processing
in received_data().
ofonod[3640549]: ../git/plugins/quectel.c:cfun_disable() 0x610000000b40
ofonod[3640549]: ../git/plugins/quectel.c:close_serial() 0x610000000b40
ofonod[3640549]: ../git/plugins/quectel.c:close_mux() 0x610000000b40
ofonod[3640549]: ../git/examples/emulator.c:powered_watch() Removing modem 0x610000000b40 from the list
ofonod[3640549]: ../git/examples/emulator.c:powered_watch() Removing server watch: 106
ofonod[3640549]: ../git/src/modem.c:modem_change_state() old state: 0, new state: 0
=================================================================
==3640549==ERROR: AddressSanitizer: heap-use-after-free on address 0x62100073dd28 at pc 0x5566b6402a21 bp 0x7ffe7a2db0e0 sp 0x7ffe7a2db0d0
READ of size 8 at 0x62100073dd28 thread T0
#0 0x5566b6402a20 in debug ../git/gatchat/gatmux.c:109
#1 0x5566b6404bd7 in channel_close ../git/gatchat/gatmux.c:525
#2 0x7fa0516e44a6 in g_io_channel_shutdown (/usr/lib/libglib-2.0.so.0+0x774a6)
#3 0x7fa0516e4644 in g_io_channel_unref (/usr/lib/libglib-2.0.so.0+0x77644)
#4 0x5566b64048a4 in watch_finalize ../git/gatchat/gatmux.c:474
#5 0x7fa0516d6f6f (/usr/lib/libglib-2.0.so.0+0x69f6f)
#6 0x7fa0516ac6a7 in g_slist_foreach (/usr/lib/libglib-2.0.so.0+0x3f6a7)
#7 0x7fa0516b277b in g_slist_free_full (/usr/lib/libglib-2.0.so.0+0x4577b)
#8 0x5566b6403413 in dispatch_sources ../git/gatchat/gatmux.c:224
#9 0x5566b64039ea in received_data ../git/gatchat/gatmux.c:268
#10 0x7fa0516d727e in g_main_context_dispatch (/usr/lib/libglib-2.0.so.0+0x6a27e)
#11 0x7fa0516d91c0 (/usr/lib/libglib-2.0.so.0+0x6c1c0)
#12 0x7fa0516da0d2 in g_main_loop_run (/usr/lib/libglib-2.0.so.0+0x6d0d2)
#13 0x5566b6429b1b in main ../git/src/main.c:286
#14 0x7fa05147fee2 in __libc_start_main (/usr/lib/libc.so.6+0x26ee2)
#15 0x5566b62531ad in _start (/home/martin/projects/ofono/x86/src/ofonod+0xfc1ad)
0x62100073dd28 is located 40 bytes inside of 4672-byte region [0x62100073dd00,0x62100073ef40)
freed by thread T0 here:
#0 0x7fa0519256c0 in __interceptor_free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:122
#1 0x5566b64052d7 in g_at_mux_unref ../git/gatchat/gatmux.c:645
#2 0x5566b63d6d19 in close_mux ../git/plugins/quectel.c:199
#3 0x5566b63d7047 in close_serial ../git/plugins/quectel.c:223
#4 0x5566b63db62a in cfun_disable ../git/plugins/quectel.c:1056
#5 0x5566b63f6ae1 in at_chat_finish_command ../git/gatchat/gatchat.c:459
#6 0x5566b63f701b in at_chat_handle_command_response ../git/gatchat/gatchat.c:521
#7 0x5566b63f785b in have_line ../git/gatchat/gatchat.c:600
#8 0x5566b63f87f1 in new_bytes ../git/gatchat/gatchat.c:759
#9 0x5566b640174c in received_data ../git/gatchat/gatio.c:122
#10 0x5566b64047b4 in watch_dispatch ../git/gatchat/gatmux.c:464
#11 0x5566b640313b in dispatch_sources ../git/gatchat/gatmux.c:183
#12 0x5566b64039ea in received_data ../git/gatchat/gatmux.c:268
#13 0x7fa0516d727e in g_main_context_dispatch (/usr/lib/libglib-2.0.so.0+0x6a27e)
previously allocated by thread T0 here:
#0 0x7fa051925ce8 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:153
#1 0x5566b6405009 in g_at_mux_new ../git/gatchat/gatmux.c:606
#2 0x5566b6407f6b in g_at_mux_new_gsm0710_basic ../git/gatchat/gatmux.c:1165
#3 0x5566b63da9ba in cmux_cb ../git/plugins/quectel.c:882
#4 0x5566b63f6ae1 in at_chat_finish_command ../git/gatchat/gatchat.c:459
#5 0x5566b63f701b in at_chat_handle_command_response ../git/gatchat/gatchat.c:521
#6 0x5566b63f785b in have_line ../git/gatchat/gatchat.c:600
#7 0x5566b63f87f1 in new_bytes ../git/gatchat/gatchat.c:759
#8 0x5566b640174c in received_data ../git/gatchat/gatio.c:122
#9 0x7fa0516d727e in g_main_context_dispatch (/usr/lib/libglib-2.0.so.0+0x6a27e)
SUMMARY: AddressSanitizer: heap-use-after-free ../git/gatchat/gatmux.c:109 in debug
Shadow bytes around the buggy address:
0x0c42800dfb50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c42800dfb60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c42800dfb70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c42800dfb80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c42800dfb90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c42800dfba0: fd fd fd fd fd[fd]fd fd fd fd fd fd fd fd fd fd
0x0c42800dfbb0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c42800dfbc0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c42800dfbd0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c42800dfbe0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c42800dfbf0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==3640549==ABORTING
---
gatchat/gatmux.c | 32 +++++++++++++++++++++++++++-----
1 file changed, 27 insertions(+), 5 deletions(-)
diff --git a/gatchat/gatmux.c b/gatchat/gatmux.c
index 757a5123..eabaa4db 100644
--- a/gatchat/gatmux.c
+++ b/gatchat/gatmux.c
@@ -227,12 +227,15 @@ static void dispatch_sources(GAtMuxChannel *channel, GIOCondition condition)
static gboolean received_data(GIOChannel *channel, GIOCondition cond,
gpointer data)
{
- GAtMux *mux = data;
+ GAtMux *mux = g_at_mux_ref(data);
int i;
GIOStatus status;
gsize bytes_read;
if (cond & G_IO_NVAL)
+ goto out_done;
+
+ if (mux->shutdown)
return FALSE;
debug(mux, "received data");
@@ -270,15 +273,22 @@ static gboolean received_data(GIOChannel *channel, GIOCondition cond,
}
if (cond & (G_IO_HUP | G_IO_ERR))
- return FALSE;
+ goto out_done;
if (status != G_IO_STATUS_NORMAL && status != G_IO_STATUS_AGAIN)
- return FALSE;
+ goto out_done;
if (mux->buf_used == sizeof(mux->buf))
- return FALSE;
+ goto out_done;
+
+ g_at_mux_unref(mux);
return TRUE;
+
+out_done:
+ g_at_mux_unref(mux);
+
+ return FALSE;
}
static void write_watcher_destroy_notify(gpointer user_data)
@@ -286,6 +296,9 @@ static void write_watcher_destroy_notify(gpointer user_data)
GAtMux *mux = user_data;
mux->write_watch = 0;
+
+ if (mux->read_watch <= 0 && mux->write_watch <= 0)
+ g_free(mux);
}
static gboolean can_write_data(GIOChannel *chan, GIOCondition cond,
@@ -297,6 +310,9 @@ static gboolean can_write_data(GIOChannel *chan, GIOCondition cond,
if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
return FALSE;
+ if (mux->shutdown)
+ return FALSE;
+
debug(mux, "can write data");
for (dlc = 0; dlc < MAX_CHANNELS; dlc += 1) {
@@ -607,6 +623,7 @@ GAtMux *g_at_mux_new(GIOChannel *channel, const GAtMuxDriver *driver)
if (mux == NULL)
return NULL;
+
mux->ref_count = 1;
mux->driver = driver;
mux->shutdown = TRUE;
@@ -642,7 +659,8 @@ void g_at_mux_unref(GAtMux *mux)
if (mux->driver->remove)
mux->driver->remove(mux);
- g_free(mux);
+ if (mux->read_watch <= 0 && mux->write_watch <= 0)
+ g_free(mux);
}
}
@@ -651,6 +669,9 @@ static void read_watcher_destroy_notify(gpointer user_data)
GAtMux *mux = user_data;
mux->read_watch = 0;
+
+ if (mux->read_watch <= 0 && mux->write_watch <= 0)
+ g_free(mux);
}
gboolean g_at_mux_start(GAtMux *mux)
@@ -695,6 +716,7 @@ gboolean g_at_mux_shutdown(GAtMux *mux)
continue;
channel_close((GIOChannel *) mux->dlcs[i], NULL);
+ mux->dlcs[i] = NULL;
}
if (mux->driver->shutdown)
--
2.23.0
2 years, 7 months