[RFC] HFP support into oFono and BlueZ
by Gustavo F. Padovan
Hi,
These patches implement the new API for the Audio Gateway in BlueZ. It
follows the last version of the HandsfreeGateway and HandsfreeAgent
Intefaces API.
The first two patches is for BlueZ and the other for oFono. You can
test it with using enable-modem and test-voicecall scripts into the
test dir of oFono.
Feel free to test it and send me your comments. We have some bugs yet.
The audio part is not working yet. We are going to work on pulseaudio
this week to get this done soon.
Regards,
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
8 years, 6 months
CDMA SMS Handling
by Rajesh.Nagaiah@elektrobit.com
Hi,
There was a discussion about the CDMA SMS handling and CDMA PDUs in the
IRC channel couple of days before. I would like to highlight the
differences between CDMA and GSM PDU and how we should proceed with this
from my understanding. Let me know your opinion.
Even though oFono supports +CMT and +CMTI, if we feed the incoming CDMA
PDUs to the SMS core it wont get decoded correctly, as there is
substantial differences between the GSM and CDMA SMS PDUs as described
in 3GPP2 specification C.S0015-B Short Message Service (SMS) for
Wideband Spread Spectrum Systems
For eg, the incoming PDU example that was mentioned in the IRC
discussion
+CMT: , 40,
00000210020207028CE95DCC65800601FC08150003168D30010610241830608003061010
04044847
40 - Length of the PDU in bytes
00 - Message Type ( 00 - SMS Point-to-Point)
00 - TeleService Identifier Tag (SMS Parameter Indentifier)
02 - TeleService Identifier Length (SMS Parameter Length)
10 - TeleService Identifier Value - First 8 bits
02 - TeleService Identifier Value - Second 8 bits
TeleService Identifier - 0x1002 - CDMA Messaging Teleservice
(CMT-95)
02 - Originating Address Tag
07 - Originating Address Length
02 - Originating Address 1st 8 Bits
8C - Originating Address 2nd 8 Bits
E9 - Originating Address 3rd 8 Bits
5D - Originating Address 4th 8 Bits
CC - Originating Address 5th 8 Bits
65 - Originating Address 6th 8 Bits
80 - Originating Address 7th 8 Bits
Digit Mode - 1 Bit
Number Mode - 1 Bit
Number Type - 0 or 3 bits
Number Plan - 0 or 4 bits
Number Fields - 8 Bits
Number Field occurrence of CHARi
CHARi - 4 or 8 bits ( 4 - in case of DTMF encoding, 8 - incase
of ASCII encoding)
Reserved - 0-7 bits
Lets take the 1st and 2nd 8 bits
02 - 0000 0010 ( Digit Mode bit - 0, Number Mode bit - 0)
8C - 1000 1100
As Digit mode bit is set to 0, Number Plan and Number Type is void
(0 bits) in this case.
So the remaining 6 bits of 1st 8bits and the first 2 bits of 2nd
8bit is Number fields
Number fields - 00 0010 10 - 0000 1010 - 0x0A (10 digits)
As Digit mode bit is set to 0, each address digit here is
represented as 4bit DTMF digit
0x8C 0xE9 0x5D 0xCC 0x65 0X80
1000 1100 1110 1001 0101 1101 1100 1100 0110 0101 1000 0000
10 0011 0011 1010 0101 0111 0111 0011 0001 1001 0110 0000 00
3 3 0 5 7 7 3 1 9 6 Last 6 bits
are reserved bits
Originating Address - 3305773196
06 - Bearer Reply Option Tag
01 - Bearer Reply Option Length
FC - First 6 bits Reply Sequence number and last 2 bits reserved set to
0
1111 1100 - 111111 REPLY_SEQ
00 Reserved
08 - Bearer Data Tag
15 - Bearer Data Length
00 - Message Indentifier Tag ( Bearer Data Sub parameter )
03 - Message Indentifier Length
16 - Message Type 4 bits Message Id 4 Bits
8D - Message Id 8 Bits
30 - Message Id 4 Bits, UDH Header indicator 1 Bit, Reserved 3 Bits
How Message Identifier value 16 8D 30 was formed ?
Message type ( 4 bits ) - 1( 0001 - Deliver)
Message Identifier ( 16 bits ) - 26835( 0x68D3)
Header Indicator (1 bit) - 0 (UDH not present in User Data
Subparameter)
Reserved ( 3bits) - 0 (000)
01 - User Data Tag ( Bearer Data Sub parameter )
06 - User Data Length
10 - Message Encoding 5 bits ( 0001 0000 ( 00010 = 2 -> 7-bit ASCII )) &
Number Fields 3 bits ( 000)
24 - Number Fields 5 Bits + User char field 1's 3 bits ( 0010 0100 )
18 - User char field 1's remaining 5 bits + User char field 2's 3 bits
(0001 1000)
30 - User char field 2's remaining 5 bits + User char field 3's 3 bits
(0011 0000)
60 - User char field 3's remaining 5 bits + User char field 4's 3 bits
(0110 0000)
80 - User char field 4's remaining 5 bits + Reserved 3 Bits (1000 0000)
Number Fields: 000 00100 - 04 (4 Character fields)
User Char [1] - 100 00011 - 0x83
User Char [2] - 000 00110 - 0x06
User Char [3] - 000 01100 - 0x0C
User Char [4] - 000 10000 - 0x10
Hex 0x83 0x06 0x0C 0x10
Octets 1000 0011 0000 0110 0000 1100 0001 0000
Septets 1000 001 10000 01 100000 1 1000001
Character A(0x41) A(0x41) A(0x41) A(0x41)
Message content: AAAA
Message Encoding - 2 (00010 - 5 bits)
Number Fields - 4 (0000 0100 - 8 bits)
User characters - 0x83 0x06 0x0C 0x10 ( 8 bits each)
00010 0000 0100 1000 0011 0000 0110 0000 1100 0001 0000
0001 0000 - 0x10
0010 0100 - 0x24
0001 1000 - 0x18
0011 0000 - 0x30
0110 0000 - 0x60
1000 0000 - 0x80 (Last 3 bits set to 0's(reserved bit) to complete
the octets)
03 - Message Center Time Stamp Tag ( Bearer Data Sub parameter )
06 - Message Center Time Stamp Length
all date and time fields contain two 4-bit BCD numbers giving the
decimal value of the field.
10 - Year (2010)
10 - Month (10 - October)
04 - Day
04 - Hour
48 - Minutes
47 - Seconds
Time Stamp 04:48:47 04/10/2010
Decoded Information:
Message Type: Deliver (Incoming Message)
Teleservice: CMT-95
Message Identifier: 26835
Originating Address: 3305773196
Message content: AAAA
Message Center Time Stamp: 04:48:47 04/10/2010
As from the above decoding example we can see there is substantial
differences between the GSM and CDMA SMS specifications and so the SMS
atom needs many additions and needs to be heavily modified to support
also CDMA SMS handling. Currently the oFono sms file unit handles the
common and the GSM technology aspects of the SMS stack along with the
smsutils. The SMS atom has the GSM specific members, segmentation and
queuing logic. The smsutils mainly takes care of encoding/decoding of
the PDUs, which is GSM specific. As the segmentation and queuing logic
and the interface is common for both GSM and CDMA, we could reuse this
common code and add the CDMA handling into it and create a new
cdmasmsutils unit to support the CDMA SMS specifics, much like the
smsutils does already for GSM.
BR,
Rajesh
8 years, 8 months
[PATCH] udevng: use huaweicdma driver for olive V-ME101
by Nicolas Bertrand
---
plugins/udevng.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/plugins/udevng.c b/plugins/udevng.c
index be87320..8d478cf 100644
--- a/plugins/udevng.c
+++ b/plugins/udevng.c
@@ -800,11 +800,10 @@ static struct {
{ "hso", "hso" },
{ "gobi", "qcserial" },
{ "sierra", "sierra" },
- { "huawei", "option", "201e", "2009" },
+ { "huaweicdma", "option", "201e", "2009" },
{ "huawei", "cdc_ether", "12d1" },
{ "huawei", "option", "12d1" },
{ "huaweicdma", "option", "12d1", "140b" },
- { "huaweicdma", "option", "201e" },
{ "speedupcdma","option", "1c9e", "9e00" },
{ "speedup", "option", "1c9e" },
{ "speedup", "option", "2020" },
--
1.7.4.1
9 years, 1 month
[PATCH 0/5] udev rules update
by Philippe Nunes
This set of patches have been sent this summer but not upstreamed.
As few bugs have been opened which could be fixed by those patches, I resend them
for review.
- For Speedup dongles, the logic in udevng is to assign the modem port on the
latest interface. This is not true for SpeedUp SU-7300U (BUG #23168) and
SpeedUp 9800 (BUG #23167). So, I added 2 specific rules for both dongles.
- For dongle ZTE MF190, 6 interfaces are present and we shall use the interface
ttyUSB4 for modem channel. The logic in udevng is to assign the modem channel
on the latest interface. To not break the support of ZTE modems with 5
interfaces (which are using the 4th one for PPP, like K3570), I can't extend
the current logic to take into account the ttyUSB4. So, I added a specific rule
for ZTE MF190.
I added also a specific rule for the dongle ZTE MF668 as the modem channel is
not on the latest interface (BUG #23683)
- I modified also udevng.c in order to avoid aux/modem channel assignment done
according OFONO_LABEL to be overridden by the default assignment.
Philippe Nunes (5):
udev: Add rules to support ZTE MF668 dongle
udev: Add rules to support ZTE MF190 dongle
udevng.c: tty assignment according OFONO_LABEL should take precedence
udev: Add rules to support Speedup 7300 dongle
udev: Add rules to support SpeedUp 9800 dongle
plugins/ofono.rules | 20 ++++++++++++++++
plugins/udevng.c | 61 +++++++++++++++++++++++++++++++-------------------
2 files changed, 58 insertions(+), 23 deletions(-)
9 years, 2 months
[PATCH 0/5] Provider name and SID
by Philippe Nunes
With this set of patches:
- cdma-providers.c is introducing an abstracted API to retrieve the provider
name from the SID.
This abstraction layer provides the ability to support multiple database for
the provider name lookup.
- As an example, the new plugin "providers" is based on the Mobile Broadband
Provider Info database.
- The lookup for the provider name is performed only if the system identifier
has changed.
Philippe Nunes (5):
cdma-providers: add driver APIs header
ofono.h: add cdma-providers
cdma-providers: add driver APIs implementation
providers: add cdma provider name plugin
cdma-netreg: Add provider name and SID support
Makefile.am | 4 +-
include/cdma-providers.h | 44 +++++++++++++++++++++++++
plugins/providers.c | 79 +++++++++++++++++++++++++++++++++++++++++++++
src/cdma-netreg.c | 40 +++++++++++++++++++++++
src/cdma-providers.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++
src/ofono.h | 4 ++
6 files changed, 249 insertions(+), 2 deletions(-)
create mode 100644 include/cdma-providers.h
create mode 100644 plugins/providers.c
create mode 100644 src/cdma-providers.c
9 years, 3 months
[RFC v1] dunmodem: Add support for DUN
by Daniel Wagner
From: Daniel Wagner <daniel.wagner(a)bmw-carit.de>
WIP
---
Makefile.am | 7 +-
drivers/dunmodem/devinfo.c | 110 ++++++++
drivers/dunmodem/dunmodem.c | 8 +-
drivers/dunmodem/dunmodem.h | 8 +-
drivers/dunmodem/gprs-context.c | 221 +++++++++++++++
drivers/dunmodem/gprs.c | 8 +-
drivers/dunmodem/network-registration.c | 126 +++++++++-
plugins/dun_dt.c | 447 +++++++++++++++++++++++++++++++
8 files changed, 924 insertions(+), 11 deletions(-)
create mode 100644 drivers/dunmodem/devinfo.c
create mode 100644 drivers/dunmodem/gprs-context.c
create mode 100644 plugins/dun_dt.c
diff --git a/Makefile.am b/Makefile.am
index 337aeb7..164f790 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -244,7 +244,9 @@ builtin_sources += drivers/atmodem/atutil.h \
drivers/dunmodem/dunmodem.h \
drivers/dunmodem/dunmodem.c \
drivers/dunmodem/network-registration.c \
- drivers/dunmodem/gprs.c
+ drivers/dunmodem/gprs.c \
+ drivers/dunmodem/gprs-context.c \
+ drivers/dunmodem/devinfo.c
builtin_modules += hfpmodem
builtin_sources += drivers/atmodem/atutil.h \
@@ -370,6 +372,9 @@ builtin_sources += plugins/hfp_ag.c plugins/bluetooth.h
builtin_modules += dun_gw
builtin_sources += plugins/dun_gw.c plugins/bluetooth.h
+builtin_modules += dun_dt
+builtin_sources += plugins/dun_dt.c plugins/bluetooth.h
+
builtin_modules += sap
builtin_sources += plugins/sap.c plugins/bluetooth.h
diff --git a/drivers/dunmodem/devinfo.c b/drivers/dunmodem/devinfo.c
new file mode 100644
index 0000000..8798554
--- /dev/null
+++ b/drivers/dunmodem/devinfo.c
@@ -0,0 +1,110 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
+ * Copyright (C) 2011 BMW Car IT GmbH. 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 <string.h>
+
+#include <glib.h>
+#include <gatchat.h>
+#include <gatresult.h>
+
+#include <ofono/log.h>
+#include <ofono/modem.h>
+#include <ofono/devinfo.h>
+
+#include "dunmodem.h"
+
+struct devinfo_data {
+ char *device_address;
+ guint register_source;
+};
+
+static void dun_query_serial(struct ofono_devinfo *info,
+ ofono_devinfo_query_cb_t cb,
+ void *data)
+{
+ struct devinfo_data *dev = ofono_devinfo_get_data(info);
+
+ CALLBACK_WITH_SUCCESS(cb, dev->device_address, data);
+}
+
+static gboolean dun_devinfo_register(gpointer user_data)
+{
+ struct ofono_devinfo *info = user_data;
+ struct devinfo_data *dd = ofono_devinfo_get_data(info);
+
+ dd->register_source = 0;
+
+ ofono_devinfo_register(info);
+
+ return FALSE;
+}
+
+static int dun_devinfo_probe(struct ofono_devinfo *info, unsigned int vendor,
+ void *user)
+{
+ const char *device_address = user;
+ struct devinfo_data *dd;
+
+ dd = g_new0(struct devinfo_data, 1);
+ dd->device_address = g_strdup(device_address);
+
+ ofono_devinfo_set_data(info, dd);
+
+ dd->register_source = g_idle_add(dun_devinfo_register, info);
+ return 0;
+}
+
+static void dun_devinfo_remove(struct ofono_devinfo *info)
+{
+ struct devinfo_data *dd = ofono_devinfo_get_data(info);
+
+ ofono_devinfo_set_data(info, NULL);
+ if (dd == NULL)
+ return;
+
+ if (dd->register_source != 0)
+ g_source_remove(dd->register_source);
+
+ g_free(dd->device_address);
+ g_free(dd);
+}
+
+static struct ofono_devinfo_driver driver = {
+ .name = "dunmodem",
+ .probe = dun_devinfo_probe,
+ .remove = dun_devinfo_remove,
+ .query_serial = dun_query_serial
+};
+
+void dun_devinfo_init(void)
+{
+ ofono_devinfo_driver_register(&driver);
+}
+
+void dun_devinfo_exit(void)
+{
+ ofono_devinfo_driver_unregister(&driver);
+}
diff --git a/drivers/dunmodem/dunmodem.c b/drivers/dunmodem/dunmodem.c
index 35a7dbb..6df345c 100644
--- a/drivers/dunmodem/dunmodem.c
+++ b/drivers/dunmodem/dunmodem.c
@@ -2,7 +2,7 @@
*
* oFono - Open Source Telephony
*
- * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
+ * Copyright (C) 2011 BMW Car IT GmbH. 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
@@ -36,14 +36,18 @@ static int dunmodem_init(void)
{
dun_netreg_init();
dun_gprs_init();
+ dun_gprs_context_init();
+ dun_devinfo_init();
return 0;
}
static void dunmodem_exit(void)
{
- dun_netreg_exit();
+ dun_devinfo_exit();
+ dun_gprs_context_exit();
dun_gprs_exit();
+ dun_netreg_exit();
}
OFONO_PLUGIN_DEFINE(dunmodem, "Dialup modem driver", VERSION,
diff --git a/drivers/dunmodem/dunmodem.h b/drivers/dunmodem/dunmodem.h
index 4fbd4a5..e35d6ae 100644
--- a/drivers/dunmodem/dunmodem.h
+++ b/drivers/dunmodem/dunmodem.h
@@ -2,7 +2,7 @@
*
* oFono - Open Source Telephony
*
- * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
+ * Copyright (C) 2011 BMW Car IT GbmH. 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
@@ -26,3 +26,9 @@ extern void dun_netreg_exit(void);
extern void dun_gprs_init(void);
extern void dun_gprs_exit(void);
+
+extern void dun_gprs_context_init(void);
+extern void dun_gprs_context_exit(void);
+
+extern void dun_devinfo_init(void);
+extern void dun_devinfo_exit(void);
diff --git a/drivers/dunmodem/gprs-context.c b/drivers/dunmodem/gprs-context.c
new file mode 100644
index 0000000..9b4f6c1
--- /dev/null
+++ b/drivers/dunmodem/gprs-context.c
@@ -0,0 +1,221 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2010 Intel Corporation. All rights reserved.
+ * Copyright (C) 2011 BMW Car IT GmbH. 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
+
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <errno.h>
+
+#include <glib.h>
+#include <gatchat.h>
+#include <gatppp.h>
+
+#include <ofono/log.h>
+#include <ofono/modem.h>
+#include <ofono/gprs-context.h>
+
+#include "dunmodem.h"
+
+#define STATIC_IP_NETMASK "255.255.255.255"
+
+struct gprs_context_data {
+ GAtChat *chat;
+ GAtPPP *ppp;
+ ofono_gprs_context_cb_t cb;
+ void *cb_data;
+};
+
+static void dun_debug(const char *str, void *data)
+{
+ ofono_info("%s: %s", (const char *) data, str);
+}
+
+static void ppp_connect(const char *interface, const char *local,
+ const char *remote,
+ const char *dns1, const char *dns2,
+ gpointer user_data)
+{
+ struct ofono_gprs_context *gc = user_data;
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+ const char *dns[3] = {dns1, dns2, 0};
+
+ DBG("gc %p, interface %s, local %s, remote %s, dns1 %s, dns2 %s",
+ gc, interface, local, remote, dns1, dns2);
+
+ ofono_gprs_context_set_interface(gc, interface);
+ ofono_gprs_context_set_ipv4_address(gc, local, TRUE);
+ ofono_gprs_context_set_ipv4_netmask(gc, STATIC_IP_NETMASK);
+ ofono_gprs_context_set_ipv4_dns_servers(gc, dns);
+
+ CALLBACK_WITH_SUCCESS(gcd->cb, gcd->cb_data);
+}
+
+static void ppp_disconnect(GAtPPPDisconnectReason reason, gpointer user_data)
+{
+ struct ofono_gprs_context *gc = user_data;
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+
+ DBG("");
+
+ g_at_ppp_unref(gcd->ppp);
+ gcd->ppp = NULL;
+
+ g_at_chat_resume(gcd->chat);
+
+ CALLBACK_WITH_SUCCESS(gcd->cb, gcd->cb_data);
+}
+
+static gboolean setup_ppp(struct ofono_gprs_context *gc)
+{
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+ GAtIO *io;
+
+ DBG("");
+
+ io = g_at_chat_get_io(gcd->chat);
+
+ g_at_chat_suspend(gcd->chat);
+
+ /* open ppp */
+ gcd->ppp = g_at_ppp_new();
+
+ if (gcd->ppp == NULL)
+ return FALSE;
+
+ /* set connect and disconnect callbacks */
+ g_at_ppp_set_connect_function(gcd->ppp, ppp_connect, gc);
+ g_at_ppp_set_disconnect_function(gcd->ppp, ppp_disconnect, gc);
+
+ if (getenv("OFONO_PPP_DEBUG"))
+ g_at_ppp_set_debug(gcd->ppp, dun_debug, "DunModem (PPP):");
+
+ /* open the ppp connection */
+ g_at_ppp_open(gcd->ppp, io);
+
+ return TRUE;
+}
+
+static void dialup_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct ofono_gprs_context *gc = user_data;
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+
+ DBG("");
+
+ if (setup_ppp(gc))
+ return;
+
+ CALLBACK_WITH_FAILURE(gcd->cb, gcd->cb_data);
+}
+
+static void dun_gprs_activate_primary(struct ofono_gprs_context *gc,
+ const struct ofono_gprs_primary_context *ctx,
+ ofono_gprs_context_cb_t cb, void *data)
+{
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+
+ DBG("");
+
+ gcd->cb = cb;
+ gcd->cb_data = data;
+
+ if (g_at_chat_send(gcd->chat, "ATD*99#", NULL,
+ dialup_cb, gc , NULL))
+ return;
+
+ CALLBACK_WITH_FAILURE(gcd->cb, gcd->cb_data);
+}
+
+static void dun_gprs_deactivate_primary(struct ofono_gprs_context *gc,
+ unsigned int cid,
+ ofono_gprs_context_cb_t cb,
+ void *data)
+{
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+
+ DBG("");
+
+ gcd->cb = cb;
+ gcd->cb_data = data;
+
+ if (gcd->ppp == NULL)
+ return;
+
+ g_at_ppp_shutdown(gcd->ppp);
+}
+
+static int dun_gprs_context_probe(struct ofono_gprs_context *gc,
+ unsigned int vendor, void *data)
+{
+ GAtChat *chat = data;
+ struct gprs_context_data *gcd;
+
+ DBG("");
+
+ gcd = g_try_new0(struct gprs_context_data, 1);
+ if (gcd == NULL)
+ return -ENOMEM;
+
+ gcd->chat = g_at_chat_clone(chat);
+
+ ofono_gprs_context_set_data(gc, gcd);
+
+ return 0;
+}
+
+static void dun_gprs_context_remove(struct ofono_gprs_context *gc)
+{
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+
+ DBG("%p", gc);
+
+ if (gcd->ppp) {
+ g_at_ppp_unref(gcd->ppp);
+ g_at_chat_resume(gcd->chat);
+ }
+
+ ofono_gprs_context_set_data(gc, NULL);
+
+ g_at_chat_unref(gcd->chat);
+ g_free(gcd);
+}
+
+static struct ofono_gprs_context_driver driver = {
+ .name = "dunmodem",
+ .probe = dun_gprs_context_probe,
+ .remove = dun_gprs_context_remove,
+ .activate_primary = dun_gprs_activate_primary,
+ .deactivate_primary = dun_gprs_deactivate_primary,
+};
+
+void dun_gprs_context_init(void)
+{
+ ofono_gprs_context_driver_register(&driver);
+}
+
+void dun_gprs_context_exit(void)
+{
+ ofono_gprs_context_driver_unregister(&driver);
+}
diff --git a/drivers/dunmodem/gprs.c b/drivers/dunmodem/gprs.c
index edfe803..77f6f62 100644
--- a/drivers/dunmodem/gprs.c
+++ b/drivers/dunmodem/gprs.c
@@ -29,7 +29,9 @@
#include <ofono/log.h>
#include <ofono/modem.h>
#include <ofono/gprs.h>
+#include <ofono/netreg.h>
+#include "common.h"
#include "dunmodem.h"
static void dun_gprs_set_attached(struct ofono_gprs *gprs, int attached,
@@ -44,6 +46,8 @@ static gboolean dun_gprs_finish_registration(gpointer user_data)
{
struct ofono_gprs *gprs = user_data;
+ DBG("");
+
ofono_gprs_register(gprs);
return FALSE;
@@ -68,9 +72,11 @@ static void dun_gprs_attached_status(struct ofono_gprs *gprs,
ofono_gprs_status_cb_t cb,
void *data)
{
+ int status = NETWORK_REGISTRATION_STATUS_REGISTERED;
+
DBG("");
- CALLBACK_WITH_SUCCESS(cb, 1, data);
+ CALLBACK_WITH_SUCCESS(cb, status, data);
}
static struct ofono_gprs_driver driver = {
diff --git a/drivers/dunmodem/network-registration.c b/drivers/dunmodem/network-registration.c
index df24b5c..35629d9 100644
--- a/drivers/dunmodem/network-registration.c
+++ b/drivers/dunmodem/network-registration.c
@@ -24,6 +24,7 @@
#endif
#include <errno.h>
+#include <string.h>
#include <glib.h>
#include <gatchat.h>
@@ -32,6 +33,7 @@
#include <ofono/log.h>
#include <ofono/modem.h>
#include <ofono/netreg.h>
+#include <ofono/gprs.h>
#include "common.h"
#include "dunmodem.h"
@@ -42,6 +44,17 @@ struct netreg_data {
GAtChat *chat;
};
+static void extract_mcc_mnc(const char *str, char *mcc, char *mnc)
+{
+ /* Three digit country code */
+ strncpy(mcc, str, OFONO_MAX_MCC_LENGTH);
+ mcc[OFONO_MAX_MCC_LENGTH] = '\0';
+
+ /* Usually a 2 but sometimes 3 digit network code */
+ strncpy(mnc, str + OFONO_MAX_MCC_LENGTH, OFONO_MAX_MNC_LENGTH);
+ mnc[OFONO_MAX_MNC_LENGTH] = '\0';
+}
+
static void dun_registration_status(struct ofono_netreg *netreg,
ofono_netreg_status_cb_t cb, void *data)
{
@@ -52,26 +65,123 @@ static void dun_registration_status(struct ofono_netreg *netreg,
CALLBACK_WITH_SUCCESS(cb, status, -1, -1, -1, data);
}
-static void dun_current_operator(struct ofono_netreg *netreg,
- ofono_netreg_operator_cb_t cb, void *data)
+static void current_operator_cb(gboolean ok, GAtResult *result,
+ gpointer user_data)
{
+ struct cb_data *cbd = user_data;
+ ofono_netreg_operator_cb_t cb = cbd->cb;
struct ofono_network_operator op;
+ GAtResultIter iter;
+ struct ofono_error error;
- DBG("");
+ int status, act, len;
+ const char *l, *s, *n;
+ gboolean have_long = FALSE;
+ char mcc[OFONO_MAX_MCC_LENGTH + 1];
+ char mnc[OFONO_MAX_MNC_LENGTH + 1];
+
+ decode_at_error(&error, g_at_result_final_response(result));
+
+ if (!ok) {
+ cb(&error, NULL, cbd->data);
+ return;
+ }
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+COPS:"))
+ goto error;
- op.name[0] = '\0';
op.mcc[0] = '\0';
op.mnc[0] = '\0';
- op.status = 2;
op.tech = -1;
- CALLBACK_WITH_SUCCESS(cb, &op, data);
+ while (1) {
+ if (!g_at_result_iter_open_list(&iter))
+ break;
+
+ if (!g_at_result_iter_next_number(&iter, &status))
+ goto error;
+
+ op.status = status;
+
+ if (!g_at_result_iter_next_string(&iter, &l))
+ goto error;
+
+ if (strlen(l) > 0) {
+ have_long = TRUE;
+ strncpy(op.name, l, OFONO_MAX_OPERATOR_NAME_LENGTH);
+ }
+
+ if (!g_at_result_iter_next_string(&iter, &s))
+ goto error;
+
+ if (strlen(s) > 0 && !have_long)
+ strncpy(op.name, s, OFONO_MAX_OPERATOR_NAME_LENGTH);
+
+ op.name[OFONO_MAX_OPERATOR_NAME_LENGTH] = '\0';
+
+ if (!g_at_result_iter_next_string(&iter, &n))
+ goto error;
+
+ len = strspn(n, "0123456789");
+
+ if (len != 5 && len != 6)
+ goto error;
+
+ extract_mcc_mnc(n, mcc, mnc);
+
+ strncpy(op.mcc, mcc, OFONO_MAX_MCC_LENGTH);
+ op.mcc[OFONO_MAX_MCC_LENGTH] = '\0';
+
+ strncpy(op.mnc, mnc, OFONO_MAX_MNC_LENGTH);
+ op.mnc[OFONO_MAX_MNC_LENGTH] = '\0';
+
+ if (!g_at_result_iter_next_number(&iter, &act))
+ goto error;
+
+ if (!g_at_result_iter_close_list(&iter))
+ goto error;
+
+ if (op.status == 2)
+ break;
+ }
+
+ if (op.status == 2)
+ cb(&error, &op, cbd->data);
+ else
+ cb(&error, NULL, cbd->data);
+
+ return;
+
+error:
+ CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
+
+}
+
+static void dun_current_operator(struct ofono_netreg *netreg,
+ ofono_netreg_operator_cb_t cb, void *data)
+{
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ struct cb_data *cbd = cb_data_new(cb, data);
+
+ DBG("");
+
+ if (g_at_chat_send(nd->chat, "AT+COPS=?", cops_prefix,
+ current_operator_cb, cbd, g_free) > 0)
+ return;
+
+ g_free(cbd);
+
+ CALLBACK_WITH_FAILURE(cb, NULL, data);
}
static void cops_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
struct ofono_netreg *netreg = user_data;
+ DBG("");
+
if (!ok)
return;
@@ -84,6 +194,8 @@ static int dun_netreg_probe(struct ofono_netreg *netreg,
GAtChat *chat = user_data;
struct netreg_data *nd;
+ DBG("");
+
nd = g_try_new0(struct netreg_data, 1);
if (nd == NULL)
return -ENOMEM;
@@ -102,6 +214,8 @@ static void dun_netreg_remove(struct ofono_netreg *netreg)
{
struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ DBG("");
+
ofono_netreg_set_data(netreg, NULL);
g_free(nd);
diff --git a/plugins/dun_dt.c b/plugins/dun_dt.c
new file mode 100644
index 0000000..ef1424c
--- /dev/null
+++ b/plugins/dun_dt.c
@@ -0,0 +1,447 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2011 BMW Car IT GmbH. 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 <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <glib.h>
+#include <gatchat.h>
+#include <gattty.h>
+#include <ofono.h>
+
+#define OFONO_API_SUBJECT_TO_CHANGE
+#include <ofono/plugin.h>
+#include <ofono/log.h>
+#include <ofono/modem.h>
+#include <ofono/gprs.h>
+
+#include <drivers/dunmodem/dunmodem.h>
+
+#include <ofono/dbus.h>
+
+#include "bluetooth.h"
+
+#define BLUEZ_SERIAL_INTERFACE BLUEZ_SERVICE ".Serial"
+
+#ifndef DBUS_TYPE_UNIX_FD
+#define DBUS_TYPE_UNIX_FD -1
+#endif
+
+static DBusConnection *connection;
+static GHashTable *modem_hash;
+
+struct dun_data {
+ char *dun_path;
+ char *address;
+ char *tty;
+ GAtChat *chat;
+ DBusPendingCall *call;
+};
+
+static void dun_debug(const char *str, void *data)
+{
+ ofono_info("%s %s", (const char *) data, str);
+}
+
+static int dun_probe(struct ofono_modem *modem)
+{
+ DBG("%p", modem);
+
+ return 0;
+}
+
+static void dun_remove(struct ofono_modem *modem)
+{
+ struct dun_data *data = ofono_modem_get_data(modem);
+
+ if (data->call != NULL)
+ dbus_pending_call_cancel(data->call);
+
+ g_hash_table_remove(modem_hash, data->dun_path);
+
+ g_at_chat_unref(data->chat);
+ data->chat = NULL;
+
+ g_free(data->dun_path);
+ g_free(data->address);
+ g_free(data->tty);
+ g_free(data->chat);
+ g_free(data);
+
+ ofono_modem_set_data(modem, NULL);
+}
+
+static void dun_disconnected_cb(gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct dun_data *data = ofono_modem_get_data(modem);
+
+ DBG("%p", modem);
+
+ ofono_modem_set_powered(modem, FALSE);
+
+ g_at_chat_unref(data->chat);
+ data->chat = NULL;
+}
+
+static GAtChat *open_chat(struct dun_data *dd)
+{
+ GIOChannel *io;
+ GAtSyntax *syntax;
+ GAtChat *chat;
+
+ DBG("");
+
+ io = g_at_tty_open(dd->tty, NULL);
+ if (io == NULL) {
+ ofono_error("Connection failed: %s (%d)",
+ strerror(errno), errno);
+ return NULL;
+ }
+
+ syntax = g_at_syntax_new_gsm_permissive();
+ chat = g_at_chat_new(io, syntax);
+
+ g_at_syntax_unref(syntax);
+ g_io_channel_unref(io);
+
+ if (getenv("OFONO_AT_DEBUG"))
+ g_at_chat_set_debug(chat, dun_debug, "DunModem");
+
+ return chat;
+}
+
+static void bt_connect_reply(DBusPendingCall *call, gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct dun_data *data = ofono_modem_get_data(modem);
+ DBusMessage *reply;
+ DBusError derr;
+ char *tty;
+ GAtChat *chat;
+
+ DBG("%p", modem);
+
+ reply = dbus_pending_call_steal_reply(call);
+
+ data->call = NULL;
+
+ dbus_error_init(&derr);
+ if (dbus_set_error_from_message(&derr, reply)) {
+ DBG("Connection to bt serial returned with error: %s, %s",
+ derr.name, derr.message);
+
+ dbus_error_free(&derr);
+ goto done;
+ }
+
+ dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &tty,
+ DBUS_TYPE_INVALID);
+
+ DBG("%p tty %s", modem, tty);
+
+ data->tty = g_strdup(tty);
+
+ chat = open_chat(data);
+ if (chat == NULL)
+ goto done;
+
+ data->chat = chat;
+ g_at_chat_set_disconnect_function(data->chat,
+ dun_disconnected_cb, modem);
+
+ ofono_modem_set_powered(modem, TRUE);
+
+done:
+ dbus_message_unref(reply);
+}
+
+static int dun_enable(struct ofono_modem *modem)
+{
+ struct dun_data *data = ofono_modem_get_data(modem);
+ DBusPendingCall *call;
+ int status;
+ char *profile = "dun";
+
+ DBG("%p", modem);
+
+ status = bluetooth_send_with_reply(data->dun_path,
+ BLUEZ_SERIAL_INTERFACE, "Connect",
+ &call, bt_connect_reply,
+ modem, NULL, DBUS_TIMEOUT,
+ DBUS_TYPE_STRING, &profile,
+ DBUS_TYPE_INVALID);
+ if (status < 0)
+ return -EINVAL;
+
+ data->call = call;
+
+ return -EINPROGRESS;
+}
+
+static void bt_disconnect_reply(DBusPendingCall *call, gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct dun_data *data = ofono_modem_get_data(modem);
+ DBusMessage *reply;
+
+ DBG("%p", modem);
+
+ reply = dbus_pending_call_steal_reply(call);
+ dbus_message_unref(reply);
+
+ data->call = NULL;
+
+ ofono_modem_set_powered(modem, FALSE);
+
+ g_at_chat_unref(data->chat);
+ data->chat = NULL;
+
+ g_free(data->tty);
+ data->tty = NULL;
+}
+
+static int dun_disable(struct ofono_modem *modem)
+{
+ struct dun_data *data = ofono_modem_get_data(modem);
+ DBusPendingCall *call;
+ int status;
+
+ DBG("%p", modem);
+
+ if (data->tty == NULL)
+ return 0;
+
+ status = bluetooth_send_with_reply(data->dun_path,
+ BLUEZ_SERIAL_INTERFACE, "Disconnect",
+ &call, bt_disconnect_reply,
+ modem, NULL, DBUS_TIMEOUT,
+ DBUS_TYPE_STRING, &data->tty,
+ DBUS_TYPE_INVALID);
+ if (status < 0)
+ return -EINVAL;
+
+ data->call = call;
+
+ return -EINPROGRESS;
+}
+
+static void dun_set_online(struct ofono_modem *modem, ofono_bool_t online,
+ ofono_modem_online_cb_t cb, void *data) {
+ DBG("%p online: %d", modem, online);
+
+ CALLBACK_WITH_SUCCESS(cb, data);
+}
+
+static void dun_pre_sim(struct ofono_modem *modem)
+{
+ struct dun_data *data = ofono_modem_get_data(modem);
+ struct ofono_gprs *gprs;
+ struct ofono_gprs_context *gc;
+
+ DBG("%p", modem);
+
+ ofono_devinfo_create(modem, 0, "dunmodem", data->address);
+ ofono_netreg_create(modem, 0, "dunmodem", data->chat);
+ gprs = ofono_gprs_create(modem, 0, "dunmodem", data->chat);
+ ofono_gprs_set_cid_range(gprs, 1, 1);
+ gc = ofono_gprs_context_create(modem, 0, "dunmodem", data->chat);
+
+ if (gprs && gc)
+ ofono_gprs_add_context(gprs, gc);
+}
+
+static void dun_post_online(struct ofono_modem *modem)
+{
+ DBG("%p", modem);
+}
+
+static void dun_post_sim(struct ofono_modem *modem)
+{
+ DBG("%p", modem);
+}
+
+static struct ofono_modem_driver dun_driver = {
+ .name = "dun_dt",
+ .probe = dun_probe,
+ .remove = dun_remove,
+ .enable = dun_enable,
+ .disable = dun_disable,
+ .set_online = dun_set_online,
+ .pre_sim = dun_pre_sim,
+ .post_sim = dun_post_sim,
+ .post_online = dun_post_online
+};
+
+static int dun_bt_probe(const char *device, const char *dev_addr,
+ const char *adapter_addr, const char *alias)
+{
+ struct ofono_modem *modem;
+ struct dun_data *data;
+ char buf[256];
+
+ DBG("");
+
+ /* We already have this device in our hash, ignore */
+ if (g_hash_table_lookup(modem_hash, device) != NULL)
+ return -EALREADY;
+
+ ofono_info("Using device: %s, devaddr: %s, adapter: %s",
+ device, dev_addr, adapter_addr);
+
+ strcpy(buf, "dun/");
+ bluetooth_create_path(dev_addr, adapter_addr, buf + 4, sizeof(buf) - 4);
+
+ modem = ofono_modem_create(buf, "dun_dt");
+ if (modem == NULL) {
+ DBG("Failed to create modem");
+ return -ENOMEM;
+ }
+
+ DBG("modem %p", modem);
+
+ data = g_try_new0(struct dun_data, 1);
+ if (data == NULL)
+ goto free;
+
+ data->dun_path = g_strdup(device);
+ if (data->dun_path == NULL)
+ goto free;
+
+ data->address = g_strdup(dev_addr);
+ if (data->address == NULL)
+ goto free;
+
+ ofono_modem_set_data(modem, data);
+ ofono_modem_set_name(modem, alias);
+ ofono_modem_register(modem);
+
+ g_hash_table_insert(modem_hash, g_strdup(device), modem);
+ return 0;
+
+free:
+ g_free(data->dun_path);
+ data->dun_path = NULL;
+ g_free(data);
+ ofono_modem_remove(modem);
+
+ return -ENOMEM;
+}
+
+static gboolean dun_bt_remove_modem(gpointer key, gpointer value,
+ gpointer user_data)
+{
+ struct ofono_modem *modem = value;
+ struct dun_data *data = ofono_modem_get_data(modem);
+ const char *device = key;
+ const char *prefix = user_data;
+
+ DBG("%p", modem);
+
+ if (data->call != NULL)
+ dbus_pending_call_cancel(data->call);
+
+ if (prefix && g_str_has_prefix(device, prefix) == FALSE)
+ return FALSE;
+
+ ofono_modem_remove(modem);
+
+ return TRUE;
+}
+
+static void dun_bt_remove(const char *prefix)
+{
+ DBG("%s", prefix);
+
+ if (modem_hash == NULL)
+ return;
+
+ g_hash_table_foreach_remove(modem_hash, dun_bt_remove_modem,
+ (gpointer) prefix);
+}
+
+static void dun_bt_set_alias(const char *device, const char *alias)
+{
+ struct ofono_modem *modem;
+
+ DBG("");
+
+ if (device == NULL || alias == NULL)
+ return;
+
+ modem = g_hash_table_lookup(modem_hash, device);
+ if (modem == NULL)
+ return;
+
+ ofono_modem_set_name(modem, alias);
+}
+
+static struct bluetooth_profile dun_profile = {
+ .name = "dun_dt",
+ .probe = dun_bt_probe,
+ .remove = dun_bt_remove,
+ .set_alias = dun_bt_set_alias,
+};
+
+static int dun_init(void)
+{
+ int err;
+
+ DBG("");
+
+ if (DBUS_TYPE_UNIX_FD < 0)
+ return -EBADF;
+
+ connection = ofono_dbus_get_connection();
+
+ err = ofono_modem_driver_register(&dun_driver);
+ if (err < 0)
+ return err;
+
+ err = bluetooth_register_uuid(DUN_GW_UUID, &dun_profile);
+ if (err < 0) {
+ ofono_modem_driver_unregister(&dun_driver);
+ return err;
+ }
+
+ modem_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
+
+ return 0;
+}
+
+static void dun_exit(void)
+{
+ DBG("");
+
+ bluetooth_unregister_uuid(DUN_GW_UUID);
+ ofono_modem_driver_unregister(&dun_driver);
+
+ g_hash_table_destroy(modem_hash);
+}
+
+OFONO_PLUGIN_DEFINE(dun_dt, "Dial-up Networking Data Terminal Profile Plugins",
+ VERSION, OFONO_PLUGIN_PRIORITY_DEFAULT,
+ dun_init, dun_exit)
--
1.7.8.rc1.14.g248db
9 years, 3 months
[PATCH_v2 0/4] Use sim atom with cdma modems
by Guillaume Zajac
Hi,
Changelog from v1:
- Implement sim specific cdmamodem drivers.
- If no read drivers are implemented, call callback with failure
to continue with sim initialization routines.
- If SIM is embedded but AT+CPIN? answers SIM not inserted, continue
with sim_initialize_after_pin() to get the IMSI.
Kind regards,
Guillaume
Guillaume Zajac (4):
cdmamodem: Add sim driver implementation
simfs: Call callback with failure if driver is not implemented
huaweicdma: Add SIM creation and set_online method driver
sim: Get IMSI if sim state is OFONO_SIM_STATE_INSERTED
Makefile.am | 3 +-
drivers/cdmamodem/cdmamodem.c | 2 +
drivers/cdmamodem/cdmamodem.h | 3 +
drivers/cdmamodem/sim.c | 582 +++++++++++++++++++++++++++++++++++++++++
plugins/huaweicdma.c | 283 +++++++++++++++++++-
src/sim.c | 2 +
src/simfs.c | 4 +-
7 files changed, 870 insertions(+), 9 deletions(-)
create mode 100644 drivers/cdmamodem/sim.c
9 years, 3 months
[RFC v0] dunmodem: Add support for DUN
by Daniel Wagner
From: Mario Tokarz <mario.tokarz(a)bmw-carit.de>
WIP
---
Hi,
I have picked up the patches from Mario. This still needs some more
love but it is working. ConnMan will even display the network operator
name(*) :)
Have a nice weekend.
cheers,
daniel
(*) Obviously you need to apply the rewrite ofono patches posted
on ConnMan mailing list.
Makefile.am | 7 +-
drivers/dunmodem/dunmodem.c | 6 +-
drivers/dunmodem/dunmodem.h | 6 +
drivers/dunmodem/gprs-context.c | 220 ++++++++++++++++
drivers/dunmodem/gprs.c | 9 +-
drivers/dunmodem/network-registration.c | 133 +++++++++-
plugins/dun_dt.c | 426 +++++++++++++++++++++++++++++++
7 files changed, 798 insertions(+), 9 deletions(-)
create mode 100644 drivers/dunmodem/gprs-context.c
create mode 100644 plugins/dun_dt.c
diff --git a/Makefile.am b/Makefile.am
index 337aeb7..164f790 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -244,7 +244,9 @@ builtin_sources += drivers/atmodem/atutil.h \
drivers/dunmodem/dunmodem.h \
drivers/dunmodem/dunmodem.c \
drivers/dunmodem/network-registration.c \
- drivers/dunmodem/gprs.c
+ drivers/dunmodem/gprs.c \
+ drivers/dunmodem/gprs-context.c \
+ drivers/dunmodem/devinfo.c
builtin_modules += hfpmodem
builtin_sources += drivers/atmodem/atutil.h \
@@ -370,6 +372,9 @@ builtin_sources += plugins/hfp_ag.c plugins/bluetooth.h
builtin_modules += dun_gw
builtin_sources += plugins/dun_gw.c plugins/bluetooth.h
+builtin_modules += dun_dt
+builtin_sources += plugins/dun_dt.c plugins/bluetooth.h
+
builtin_modules += sap
builtin_sources += plugins/sap.c plugins/bluetooth.h
diff --git a/drivers/dunmodem/dunmodem.c b/drivers/dunmodem/dunmodem.c
index 35a7dbb..b508cf6 100644
--- a/drivers/dunmodem/dunmodem.c
+++ b/drivers/dunmodem/dunmodem.c
@@ -36,14 +36,18 @@ static int dunmodem_init(void)
{
dun_netreg_init();
dun_gprs_init();
+ dun_gprs_context_init();
+ dun_devinfo_init();
return 0;
}
static void dunmodem_exit(void)
{
- dun_netreg_exit();
+ dun_devinfo_exit();
+ dun_gprs_context_exit();
dun_gprs_exit();
+ dun_netreg_exit();
}
OFONO_PLUGIN_DEFINE(dunmodem, "Dialup modem driver", VERSION,
diff --git a/drivers/dunmodem/dunmodem.h b/drivers/dunmodem/dunmodem.h
index 4fbd4a5..423c778 100644
--- a/drivers/dunmodem/dunmodem.h
+++ b/drivers/dunmodem/dunmodem.h
@@ -26,3 +26,9 @@ extern void dun_netreg_exit(void);
extern void dun_gprs_init(void);
extern void dun_gprs_exit(void);
+
+extern void dun_gprs_context_init(void);
+extern void dun_gprs_context_exit(void);
+
+extern void dun_devinfo_init(void);
+extern void dun_devinfo_exit(void);
diff --git a/drivers/dunmodem/gprs-context.c b/drivers/dunmodem/gprs-context.c
new file mode 100644
index 0000000..c5bd182
--- /dev/null
+++ b/drivers/dunmodem/gprs-context.c
@@ -0,0 +1,220 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2010 Intel Corporation. All rights reserved.
+ * Copyright (C) 2011 BMW Car IT GmbH. 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
+
+#define _GNU_SOURCE
+#include <errno.h>
+
+#include <glib.h>
+#include <gatchat.h>
+#include <gatppp.h>
+
+#include <ofono/log.h>
+#include <ofono/modem.h>
+#include <ofono/gprs-context.h>
+
+#include "dunmodem.h"
+
+#define STATIC_IP_NETMASK "255.255.255.255"
+
+struct gprs_context_data {
+ GAtChat *chat;
+ GAtPPP *ppp;
+ ofono_gprs_context_cb_t cb;
+ void* cb_data;
+};
+
+static void dun_debug(const char *str, void *data)
+{
+ ofono_info("%s: %s", (const char *) data, str);
+}
+
+static void ppp_connect(const char *interface, const char *local,
+ const char *remote,
+ const char *dns1, const char *dns2,
+ gpointer user_data)
+{
+ struct ofono_gprs_context *gc = user_data;
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+ const char* dns[3] = {dns1, dns2, 0};
+
+ DBG("gc %p, interface %s, local %s, remote %s, dns1 %s, dns2 %s",
+ gc, interface, local, remote, dns1, dns2);
+
+ ofono_gprs_context_set_interface(gc, interface);
+ ofono_gprs_context_set_ipv4_address(gc, local, TRUE);
+ ofono_gprs_context_set_ipv4_netmask(gc, STATIC_IP_NETMASK);
+ ofono_gprs_context_set_ipv4_dns_servers(gc, dns);
+
+ CALLBACK_WITH_SUCCESS(gcd->cb, gcd->cb_data);
+}
+
+static void ppp_disconnect(GAtPPPDisconnectReason reason, gpointer user_data)
+{
+ struct ofono_gprs_context *gc = user_data;
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+
+ DBG("");
+
+ g_at_ppp_unref(gcd->ppp);
+ gcd->ppp = NULL;
+
+ g_at_chat_resume(gcd->chat);
+
+ DBG("Io %p", g_at_chat_get_io(gcd->chat));
+
+ CALLBACK_WITH_SUCCESS(gcd->cb, gcd->cb_data);
+}
+
+static gboolean setup_ppp(struct ofono_gprs_context *gc)
+{
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+ GAtIO *io;
+
+ DBG("");
+
+ io = g_at_chat_get_io(gcd->chat);
+
+ g_at_chat_suspend(gcd->chat);
+
+ gcd->ppp = g_at_ppp_new();
+ if (gcd->ppp == NULL)
+ return FALSE;
+
+ g_at_ppp_set_connect_function(gcd->ppp, ppp_connect, gc);
+ g_at_ppp_set_disconnect_function(gcd->ppp, ppp_disconnect, gc);
+
+ if (TRUE)
+ g_at_ppp_set_debug(gcd->ppp, dun_debug, "DunModem (PPP):");
+
+ g_at_ppp_open(gcd->ppp, io);
+
+ return TRUE;
+}
+
+static void dialup_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct ofono_gprs_context *gc = user_data;
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+
+ DBG("");
+
+ if (setup_ppp(gc))
+ return;
+
+ CALLBACK_WITH_FAILURE(gcd->cb, gcd->cb_data);
+}
+
+static void dun_gprs_activate_primary(struct ofono_gprs_context *gc,
+ const struct ofono_gprs_primary_context *ctx,
+ ofono_gprs_context_cb_t cb, void *data)
+{
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+ GAtIO *io = g_at_chat_get_io(gcd->chat);
+
+ DBG("");
+
+ gcd->cb = cb;
+ gcd->cb_data = data;
+
+ DBG("chat %p, Io %p", gcd->chat, io);
+
+ if(g_at_chat_send(gcd->chat, "ATD*99#", NULL,
+ dialup_cb, gc , NULL))
+ return;
+
+ CALLBACK_WITH_FAILURE(gcd->cb, gcd->cb_data);
+}
+
+static void dun_gprs_deactivate_primary(struct ofono_gprs_context *gc,
+ unsigned int cid,
+ ofono_gprs_context_cb_t cb,
+ void *data)
+{
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+
+ DBG("");
+
+ gcd->cb = cb;
+ gcd->cb_data = data;
+
+ if (gcd->ppp == NULL)
+ return;
+
+ g_at_ppp_shutdown(gcd->ppp);
+}
+
+static int dun_gprs_context_probe(struct ofono_gprs_context *gc,
+ unsigned int vendor, void *data)
+{
+ GAtChat *chat = data;
+ struct gprs_context_data *gcd;
+
+ DBG("");
+
+ gcd = g_try_new0(struct gprs_context_data, 1);
+ if (gcd == NULL)
+ return -ENOMEM;
+
+ gcd->chat = g_at_chat_clone(chat);
+
+ ofono_gprs_context_set_data(gc, gcd);
+
+ return 0;
+}
+
+static void dun_gprs_context_remove(struct ofono_gprs_context *gc)
+{
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+
+ DBG("%p", gc);
+
+ if (gcd->ppp)
+ g_at_ppp_unref(gcd->ppp);
+
+ g_at_chat_unref(gcd->chat);
+
+ ofono_gprs_context_set_data(gc, NULL);
+
+ g_free(gcd);
+}
+
+static struct ofono_gprs_context_driver driver = {
+ .name = "dunmodem",
+ .probe = dun_gprs_context_probe,
+ .remove = dun_gprs_context_remove,
+ .activate_primary = dun_gprs_activate_primary,
+ .deactivate_primary = dun_gprs_deactivate_primary,
+};
+
+void dun_gprs_context_init(void)
+{
+ ofono_gprs_context_driver_register(&driver);
+}
+
+void dun_gprs_context_exit(void)
+{
+ ofono_gprs_context_driver_unregister(&driver);
+}
diff --git a/drivers/dunmodem/gprs.c b/drivers/dunmodem/gprs.c
index edfe803..c9ba34c 100644
--- a/drivers/dunmodem/gprs.c
+++ b/drivers/dunmodem/gprs.c
@@ -29,7 +29,9 @@
#include <ofono/log.h>
#include <ofono/modem.h>
#include <ofono/gprs.h>
+#include <ofono/netreg.h>
+#include "common.h"
#include "dunmodem.h"
static void dun_gprs_set_attached(struct ofono_gprs *gprs, int attached,
@@ -44,7 +46,10 @@ static gboolean dun_gprs_finish_registration(gpointer user_data)
{
struct ofono_gprs *gprs = user_data;
+ DBG("");
+
ofono_gprs_register(gprs);
+ //ofono_gprs_status_notify(gprs, NETWORK_REGISTRATION_STATUS_REGISTERED);
return FALSE;
}
@@ -68,9 +73,11 @@ static void dun_gprs_attached_status(struct ofono_gprs *gprs,
ofono_gprs_status_cb_t cb,
void *data)
{
+ int status = NETWORK_REGISTRATION_STATUS_REGISTERED;
+
DBG("");
- CALLBACK_WITH_SUCCESS(cb, 1, data);
+ CALLBACK_WITH_SUCCESS(cb, status, data);
}
static struct ofono_gprs_driver driver = {
diff --git a/drivers/dunmodem/network-registration.c b/drivers/dunmodem/network-registration.c
index df24b5c..e807af1 100644
--- a/drivers/dunmodem/network-registration.c
+++ b/drivers/dunmodem/network-registration.c
@@ -24,6 +24,7 @@
#endif
#include <errno.h>
+#include <string.h>
#include <glib.h>
#include <gatchat.h>
@@ -32,10 +33,13 @@
#include <ofono/log.h>
#include <ofono/modem.h>
#include <ofono/netreg.h>
+#include <ofono/gprs.h>
#include "common.h"
#include "dunmodem.h"
+#define DUN_MAX_OPERATOR_NAME_LENGTH 16
+
static const char *cops_prefix[] = { "+COPS:", NULL };
struct netreg_data {
@@ -52,26 +56,123 @@ static void dun_registration_status(struct ofono_netreg *netreg,
CALLBACK_WITH_SUCCESS(cb, status, -1, -1, -1, data);
}
-static void dun_current_operator(struct ofono_netreg *netreg,
- ofono_netreg_operator_cb_t cb, void *data)
+static void current_operator_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
+ struct cb_data *cbd = user_data;
+ ofono_netreg_operator_cb_t cb = cbd->cb;
struct ofono_network_operator op;
+ GAtResultIter iter;
+ struct ofono_error error;
- DBG("");
+ int status, unknown;
+ const char *l, *s, *n;
+ gboolean have_long = FALSE;
+
+ /*
+
+ ofonod[14948]: DunModem: < AT+COPS=?\r
+ ofonod[14948]: DunModem: < \r\n+COPS: (2,"T-Mobile D",,"26201",0)
+ ofonod[14948]: DunModem: < ,\r\n(3,"Vodafone.de",,"26202",0)
+ ofonod[14948]: DunModem: < ,\r\n(3,"E-Plus",,"26203",0)
+ ofonod[14948]: DunModem: < ,\r\n(3,"o2 - de",,"26207",0)
+ ofonod[14948]: DunModem: < ,,(0,1,3),(0,2)\r\n\r\nOK\r\n
+
+ */
+
+ decode_at_error(&error, g_at_result_final_response(result));
+
+ if (!ok) {
+ cb(&error, NULL, cbd->data);
+ return;
+ }
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+COPS:"))
+ goto error;
- op.name[0] = '\0';
op.mcc[0] = '\0';
op.mnc[0] = '\0';
- op.status = 2;
op.tech = -1;
- CALLBACK_WITH_SUCCESS(cb, &op, data);
+ while (1) {
+ if (!g_at_result_iter_open_list(&iter))
+ break;
+
+ if (!g_at_result_iter_next_number(&iter, &status))
+ goto error;
+
+ op.status = status;
+
+ if (!g_at_result_iter_next_string(&iter, &l))
+ goto error;
+
+ if (strlen(l) > 0) {
+ have_long = TRUE;
+ strncpy(op.name, l, OFONO_MAX_OPERATOR_NAME_LENGTH);
+ }
+
+ if (!g_at_result_iter_next_string(&iter, &s))
+ goto error;
+
+ if (strlen(s) > 0 && !have_long)
+ strncpy(op.name, s, OFONO_MAX_OPERATOR_NAME_LENGTH);
+
+ op.name[OFONO_MAX_OPERATOR_NAME_LENGTH] = '\0';
+
+ if (!g_at_result_iter_next_string(&iter, &n))
+ goto error;
+
+ /* XXX Is n MMC/MNC ? */
+
+ if (!g_at_result_iter_next_number(&iter, &unknown))
+ goto error;
+
+ /* XXX What is this? Nothing in the spec, the phone adds this */
+
+ if (!g_at_result_iter_close_list(&iter))
+ goto error;
+
+ if (op.status == 2)
+ break;
+ }
+
+ if (op.status == 2)
+ cb(&error, &op, cbd->data);
+ else
+ cb(&error, NULL, cbd->data);
+
+ return;
+
+error:
+ CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
+
+}
+
+static void dun_current_operator(struct ofono_netreg *netreg,
+ ofono_netreg_operator_cb_t cb, void *data)
+{
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ struct cb_data *cbd = cb_data_new(cb, data);
+
+ DBG("");
+
+ if (g_at_chat_send(nd->chat, "AT+COPS=?", cops_prefix,
+ current_operator_cb, cbd, g_free) > 0) {
+ return;
+ }
+
+ g_free(cbd);
+
+ CALLBACK_WITH_FAILURE(cb, NULL, data);
}
static void cops_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
struct ofono_netreg *netreg = user_data;
+ DBG("");
+
if (!ok)
return;
@@ -84,6 +185,8 @@ static int dun_netreg_probe(struct ofono_netreg *netreg,
GAtChat *chat = user_data;
struct netreg_data *nd;
+ DBG("");
+
nd = g_try_new0(struct netreg_data, 1);
if (nd == NULL)
return -ENOMEM;
@@ -95,6 +198,22 @@ static int dun_netreg_probe(struct ofono_netreg *netreg,
g_at_chat_send(nd->chat, "AT+COPS=0", cops_prefix,
cops_cb, netreg, NULL);
+ /*
+ g_at_chat_send(nd->chat, "ATE1", NULL, NULL, NULL, NULL);
+ g_at_chat_send(nd->chat, "AT+GMI", NULL, NULL, NULL, NULL);
+ g_at_chat_send(nd->chat, "AT+CGMI", NULL, NULL, NULL, NULL);
+ g_at_chat_send(nd->chat, "AT+GMM", NULL, NULL, NULL, NULL);
+ g_at_chat_send(nd->chat, "AT+CGMM", NULL, NULL, NULL, NULL);
+ g_at_chat_send(nd->chat, "AT+GCAP", NULL, NULL, NULL, NULL);
+ g_at_chat_send(nd->chat, "AT+GIMI", NULL, NULL, NULL, NULL);
+ g_at_chat_send(nd->chat, "AT+WS46=?", NULL, NULL, NULL, NULL);
+ g_at_chat_send(nd->chat, "AT+CGSN", NULL, NULL, NULL, NULL);
+ g_at_chat_send(nd->chat, "AT+COPN=?", NULL, NULL, NULL, NULL);
+ g_at_chat_send(nd->chat, "AT+COPN", NULL, NULL, NULL, NULL);
+ g_at_chat_send(nd->chat, "AT+CSQ", NULL, NULL, NULL, NULL);
+ g_at_chat_send(nd->chat, "AT+COLP?", NULL, NULL, NULL, NULL);
+ */
+
return 0;
}
@@ -102,6 +221,8 @@ static void dun_netreg_remove(struct ofono_netreg *netreg)
{
struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ DBG("");
+
ofono_netreg_set_data(netreg, NULL);
g_free(nd);
diff --git a/plugins/dun_dt.c b/plugins/dun_dt.c
new file mode 100644
index 0000000..2104662
--- /dev/null
+++ b/plugins/dun_dt.c
@@ -0,0 +1,426 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2010 Intel Corporation. All rights reserved.
+ * Copyright (C) 2010 Gustavo Padovan <gustavo(a)padovan.org>
+ * Copyright (C) 2011 BMW Car IT GmbH. 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 <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <glib.h>
+#include <gatchat.h>
+#include <gattty.h>
+#include <ofono.h>
+
+#define OFONO_API_SUBJECT_TO_CHANGE
+#include <ofono/plugin.h>
+#include <ofono/log.h>
+#include <ofono/modem.h>
+#include <ofono/gprs.h>
+
+#include <drivers/dunmodem/dunmodem.h>
+
+#include <ofono/dbus.h>
+
+#include "bluetooth.h"
+
+#define BLUEZ_SERIAL_INTERFACE BLUEZ_SERVICE ".Serial"
+
+#ifndef DBUS_TYPE_UNIX_FD
+#define DBUS_TYPE_UNIX_FD -1
+#endif
+
+static DBusConnection *connection;
+static GHashTable *modem_hash;
+
+struct dun_data {
+ char *dun_path;
+ char *address;
+ char *tty;
+ GAtChat *chat;
+ DBusPendingCall *call;
+};
+
+static void dun_debug(const char *str, void *data)
+{
+ ofono_info("%s: %s", (const char *) data, str);
+}
+
+static int dun_probe(struct ofono_modem *modem)
+{
+ DBG("%p", modem);
+
+ return 0;
+}
+
+static void dun_remove(struct ofono_modem *modem)
+{
+ struct dun_data *data = ofono_modem_get_data(modem);
+
+ if (data->call != NULL)
+ dbus_pending_call_cancel(data->call);
+
+ g_hash_table_remove(modem_hash, data->dun_path);
+
+ g_free(data->dun_path);
+ g_free(data->address);
+ g_free(data->tty);
+ g_free(data->chat);
+ g_free(data);
+
+ ofono_modem_set_data(modem, NULL);
+}
+
+static GAtChat* open_chat(struct dun_data *dd)
+{
+ GIOChannel *io;
+ GAtSyntax *syntax;
+ GAtChat *chat;
+
+ DBG("");
+
+ io = g_at_tty_open(dd->tty, NULL);
+ if (io == NULL) {
+ ofono_error("Connection failed: %s (%d)",
+ strerror(errno), errno);
+ return NULL;
+ }
+
+ syntax = g_at_syntax_new_gsm_permissive();
+ chat = g_at_chat_new(io, syntax);
+
+ g_at_syntax_unref(syntax);
+ g_io_channel_unref(io);
+
+ if (getenv("OFONO_AT_DEBUG"))
+ g_at_chat_set_debug(chat, dun_debug, "DunModem");
+
+ return chat;
+}
+
+static void bt_connect_reply(DBusPendingCall *call, gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct dun_data *data = ofono_modem_get_data(modem);
+ DBusMessage *reply;
+ DBusError derr;
+ char *tty;
+ GAtChat *chat;
+
+ DBG("%p", modem);
+
+ reply = dbus_pending_call_steal_reply(call);
+
+ data->call = NULL;
+
+ dbus_error_init(&derr);
+ if (dbus_set_error_from_message(&derr, reply)) {
+ DBG("Connection to bt serial returned with error: %s, %s",
+ derr.name, derr.message);
+
+ dbus_error_free(&derr);
+ goto done;
+ }
+
+ dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &tty,
+ DBUS_TYPE_INVALID);
+
+ DBG("%p tty %s", modem, tty);
+
+ data->tty = g_strdup(tty);
+
+ chat = open_chat(data);
+ if (chat == NULL)
+ goto done;
+
+ data->chat = chat;
+
+ ofono_modem_set_powered(modem, TRUE);
+
+done:
+ dbus_message_unref(reply);
+}
+
+static int dun_enable(struct ofono_modem *modem)
+{
+ struct dun_data *data = ofono_modem_get_data(modem);
+ DBusPendingCall *call;
+ int status;
+ char *profile = "dun";
+
+ DBG("%p", modem);
+
+ status = bluetooth_send_with_reply(data->dun_path,
+ BLUEZ_SERIAL_INTERFACE, "Connect",
+ &call, bt_connect_reply,
+ modem, NULL, DBUS_TIMEOUT,
+ DBUS_TYPE_STRING, &profile,
+ DBUS_TYPE_INVALID);
+ if (status < 0)
+ return -EINVAL;
+
+ data->call = call;
+
+ return -EINPROGRESS;
+}
+
+static void bt_disconnect_reply(DBusPendingCall *call, gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct dun_data *data = ofono_modem_get_data(modem);
+ DBusMessage *reply;
+
+ reply = dbus_pending_call_steal_reply(call);
+ dbus_message_unref(reply);
+
+ data->call = NULL;
+
+ ofono_modem_set_powered(modem, FALSE);
+
+ g_free(data->tty);
+ data->tty = NULL;
+}
+
+static int dun_disable(struct ofono_modem *modem)
+{
+ struct dun_data *data = ofono_modem_get_data(modem);
+ DBusPendingCall *call;
+ int status;
+
+ DBG("%p", modem);
+
+ if (data->tty == NULL)
+ return 0;
+
+ status = bluetooth_send_with_reply(data->dun_path,
+ BLUEZ_SERIAL_INTERFACE, "Disconnect",
+ &call, bt_disconnect_reply,
+ modem, NULL, DBUS_TIMEOUT,
+ DBUS_TYPE_STRING, &data->tty,
+ DBUS_TYPE_INVALID);
+ if (status < 0)
+ return -EINVAL;
+
+ data->call = call;
+
+ return -EINPROGRESS;
+}
+
+static void dun_set_online(struct ofono_modem *modem, ofono_bool_t online,
+ ofono_modem_online_cb_t cb, void *data) {
+ DBG("%p online: %d", modem, online);
+
+ CALLBACK_WITH_SUCCESS(cb, data);
+}
+
+static void dun_pre_sim(struct ofono_modem *modem)
+{
+ struct dun_data *data = ofono_modem_get_data(modem);
+ struct ofono_gprs *gprs;
+ struct ofono_gprs_context *gc;
+
+ DBG("%p", modem);
+
+ ofono_devinfo_create(modem, 0, "dunmodem", data->address);
+ ofono_netreg_create(modem, 0, "dunmodem", data->chat);
+ gprs = ofono_gprs_create(modem, 0, "dunmodem", data->chat);
+ ofono_gprs_set_cid_range(gprs, 1, 1);
+ gc = ofono_gprs_context_create(modem, 0, "dunmodem", data->chat);
+
+ if (gprs && gc)
+ ofono_gprs_add_context(gprs, gc);
+}
+
+static void dun_post_online(struct ofono_modem *modem)
+{
+ DBG("%p", modem);
+}
+
+static void dun_post_sim(struct ofono_modem *modem)
+{
+ DBG("%p", modem);
+}
+
+static struct ofono_modem_driver dun_driver = {
+ .name = "dun_dt",
+ .probe = dun_probe,
+ .remove = dun_remove,
+ .enable = dun_enable,
+ .disable = dun_disable,
+ .set_online = dun_set_online,
+ .pre_sim = dun_pre_sim,
+ .post_sim = dun_post_sim,
+ .post_online = dun_post_online
+};
+
+static int dun_bt_probe(const char *device, const char *dev_addr,
+ const char *adapter_addr, const char *alias)
+{
+ struct ofono_modem *modem;
+ struct dun_data *data;
+ char buf[256];
+
+ DBG("");
+
+ /* We already have this device in our hash, ignore */
+ if (g_hash_table_lookup(modem_hash, device) != NULL)
+ return -EALREADY;
+
+ ofono_info("Using device: %s, devaddr: %s, adapter: %s",
+ device, dev_addr, adapter_addr);
+
+ strcpy(buf, "dun/");
+ bluetooth_create_path(dev_addr, adapter_addr, buf + 4, sizeof(buf) - 4);
+
+ modem = ofono_modem_create(buf, "dun_dt");
+ if (modem == NULL) {
+ DBG("Failed to create modem");
+ return -ENOMEM;
+ }
+
+ DBG("modem %p", modem);
+
+ data = g_try_new0(struct dun_data, 1);
+ if (data == NULL)
+ goto free;
+
+ data->dun_path = g_strdup(device);
+ if (data->dun_path == NULL)
+ goto free;
+
+ data->address = g_strdup(dev_addr);
+ if (data->address == NULL)
+ goto free;
+
+ ofono_modem_set_data(modem, data);
+ ofono_modem_set_name(modem, alias);
+ ofono_modem_register(modem);
+
+ g_hash_table_insert(modem_hash, g_strdup(device), modem);
+ return 0;
+
+free:
+ g_free(data->dun_path);
+ data->dun_path = NULL;
+ g_free(data);
+ ofono_modem_remove(modem);
+
+ return -ENOMEM;
+}
+
+static gboolean dun_bt_remove_modem(gpointer key, gpointer value,
+ gpointer user_data)
+{
+ struct ofono_modem *modem = value;
+ struct dun_data *data = ofono_modem_get_data(modem);
+ const char *device = key;
+ const char *prefix = user_data;
+
+ DBG("%p", modem);
+
+ if (data->call != NULL)
+ dbus_pending_call_cancel(data->call);
+
+ if (prefix && g_str_has_prefix(device, prefix) == FALSE)
+ return FALSE;
+
+ ofono_modem_remove(modem);
+
+ return TRUE;
+}
+
+static void dun_bt_remove(const char *prefix)
+{
+ DBG("%s", prefix);
+
+ if (modem_hash == NULL)
+ return;
+
+ g_hash_table_foreach_remove(modem_hash, dun_bt_remove_modem,
+ (gpointer) prefix);
+}
+
+static void dun_bt_set_alias(const char *device, const char *alias)
+{
+ struct ofono_modem *modem;
+
+ DBG("");
+
+ if (device == NULL || alias == NULL)
+ return;
+
+ modem = g_hash_table_lookup(modem_hash, device);
+ if (modem == NULL)
+ return;
+
+ ofono_modem_set_name(modem, alias);
+}
+
+static struct bluetooth_profile dun_profile = {
+ .name = "dun_dt",
+ .probe = dun_bt_probe,
+ .remove = dun_bt_remove,
+ .set_alias = dun_bt_set_alias,
+};
+
+static int dun_init(void)
+{
+ int err;
+
+ DBG("");
+
+ if (DBUS_TYPE_UNIX_FD < 0)
+ return -EBADF;
+
+ connection = ofono_dbus_get_connection();
+
+ err = ofono_modem_driver_register(&dun_driver);
+ if (err < 0)
+ return err;
+
+ err = bluetooth_register_uuid(DUN_GW_UUID, &dun_profile);
+ if (err < 0) {
+ ofono_modem_driver_unregister(&dun_driver);
+ return err;
+ }
+
+ modem_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
+
+ return 0;
+}
+
+static void dun_exit(void)
+{
+ DBG("");
+
+ bluetooth_unregister_uuid(DUN_GW_UUID);
+ ofono_modem_driver_unregister(&dun_driver);
+
+ g_hash_table_destroy(modem_hash);
+}
+
+OFONO_PLUGIN_DEFINE(dun_dt, "Dial-up Networking Data Terminal Profile Plugins",
+ VERSION, OFONO_PLUGIN_PRIORITY_DEFAULT,
+ dun_init, dun_exit)
--
1.7.8.rc1.14.g248db
9 years, 3 months
[PATCH 0/7] Get SID and provider name
by Philippe Nunes
Hi,
The goal of these patch is to:
- Merge the huaweicdmamodem driver with cdmamodem driver.
- Add the serving system entry point in cdmamodem driver
- Retrieve the provider name based on the SID provided by the modem.
Philippe Nunes (7):
Huaweicdmamodem: remove this specific driver
huaweicdmamodem: Merge this driver with cdmamodem driver
cdmamodem: Add CDMA network-registration support
cdma-netreg: Add 'serving_system' entry point to cdma-netreg to get
SID
cdmamodem: Add serving system identifier support
cdma-netreg: Make use of the new driver entry point serving_system
cdma-netreg: Add provider name support
Makefile.am | 13 +-
drivers/cdmamodem/cdmamodem.c | 2 +
drivers/cdmamodem/cdmamodem.h | 2 +
drivers/cdmamodem/network-registration.c | 278 ++++++++++++++++++++++++
drivers/huaweicdmamodem/huaweicdmamodem.c | 45 ----
drivers/huaweicdmamodem/huaweicdmamodem.h | 23 --
drivers/huaweicdmamodem/network-registration.c | 199 -----------------
include/cdma-netreg.h | 7 +
plugins/huaweicdma.c | 5 +-
src/cdma-netreg.c | 55 +++++
10 files changed, 353 insertions(+), 276 deletions(-)
create mode 100644 drivers/cdmamodem/network-registration.c
delete mode 100644 drivers/huaweicdmamodem/huaweicdmamodem.c
delete mode 100644 drivers/huaweicdmamodem/huaweicdmamodem.h
delete mode 100644 drivers/huaweicdmamodem/network-registration.c
9 years, 3 months
[PATCH v2 0/6] Add a parser to retrieve the CDMA network name
by Philippe Nunes
- Fix according Denis review (remove unnecessary checking, fix coding style issues).
- Add the serving system query based on the standard CDMA AT command AT+CSS?.
- Merge the huaweicdmamodem driver with cdmamodem driver.
Philippe Nunes (6):
mbpi: Add mbpi_lookup_cdma_provider_name API
tools: Add utility for looking CDMA network name from database
Huaweicdmamodem: remove this specific driver
huaweicdmamodem: Merge this driver with cdmamodem driver
cdmamodem: Add CDMA network-registration support
cdmamodem: Add serving system identifier support
Makefile.am | 19 +-
drivers/cdmamodem/cdmamodem.c | 2 +
drivers/cdmamodem/cdmamodem.h | 2 +
drivers/cdmamodem/network-registration.c | 279 ++++++++++++++++++++++++
drivers/huaweicdmamodem/huaweicdmamodem.c | 45 ----
drivers/huaweicdmamodem/huaweicdmamodem.h | 23 --
drivers/huaweicdmamodem/network-registration.c | 199 -----------------
include/cdma-netreg.h | 7 +
plugins/huaweicdma.c | 5 +-
plugins/mbpi.c | 146 ++++++++++++
plugins/mbpi.h | 2 +
tools/lookup-provider-name.c | 100 +++++++++
12 files changed, 552 insertions(+), 277 deletions(-)
create mode 100644 drivers/cdmamodem/network-registration.c
delete mode 100644 drivers/huaweicdmamodem/huaweicdmamodem.c
delete mode 100644 drivers/huaweicdmamodem/huaweicdmamodem.h
delete mode 100644 drivers/huaweicdmamodem/network-registration.c
create mode 100644 tools/lookup-provider-name.c
9 years, 3 months