forked from sailfishos/ofono
Compare commits
72 Commits
mer/1.14+g
...
mer/1.14+g
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c156bbf14b | ||
|
|
a724d6bc9d | ||
|
|
21b7c9bc97 | ||
|
|
fc04b4cef2 | ||
|
|
6d35002f11 | ||
|
|
803dda81ea | ||
|
|
31f8abf851 | ||
|
|
8f4aefa945 | ||
|
|
58e133cbf5 | ||
|
|
6c3992aa86 | ||
|
|
c3352608c6 | ||
|
|
5da34324ca | ||
|
|
b64a5c2655 | ||
|
|
e11c1afdd3 | ||
|
|
9834debe92 | ||
|
|
2d75463ae2 | ||
|
|
95b95f9af9 | ||
|
|
d43ec9e0ed | ||
|
|
8bc1e0a300 | ||
|
|
b489dc995b | ||
|
|
d25fd17f09 | ||
|
|
73a794e9f6 | ||
|
|
df0e72c780 | ||
|
|
7cdaa7cd13 | ||
|
|
558a6639d6 | ||
|
|
5f2e8e24f0 | ||
|
|
31f85495dc | ||
|
|
689d7358ba | ||
|
|
b3ca644f1d | ||
|
|
1e811dd49a | ||
|
|
9a520a7825 | ||
|
|
2f51bc9e62 | ||
|
|
d8dd65b579 | ||
|
|
1e139cb4c6 | ||
|
|
68c0a9f164 | ||
|
|
dfe0f280de | ||
|
|
5a54a71fd8 | ||
|
|
0f39bdc9c3 | ||
|
|
24e8514c55 | ||
|
|
f1b689ed3c | ||
|
|
e5df37be4b | ||
|
|
a61a8cc183 | ||
|
|
e25b5b13f9 | ||
|
|
3f3375442d | ||
|
|
782669b412 | ||
|
|
5a401c8b50 | ||
|
|
3ac41bc759 | ||
|
|
5af079bd03 | ||
|
|
cf6278f5cc | ||
|
|
dd3b0c5aca | ||
|
|
988a759e4c | ||
|
|
555585c17f | ||
|
|
4b99034c3f | ||
|
|
03e35b6757 | ||
|
|
b36fdce803 | ||
|
|
34251bdba7 | ||
|
|
530c66393a | ||
|
|
10c823d732 | ||
|
|
db6d4d1e8e | ||
|
|
5bcbc64e60 | ||
|
|
48cec5cc58 | ||
|
|
6e40473ce9 | ||
|
|
90cae692df | ||
|
|
d8270409d0 | ||
|
|
e644196aa3 | ||
|
|
fed4a94862 | ||
|
|
99497f79cb | ||
|
|
2c6c7a9f23 | ||
|
|
ccc8d1afd4 | ||
|
|
417f20c662 | ||
|
|
304f7cc197 | ||
|
|
354285a438 |
@@ -142,7 +142,9 @@ builtin_sources += drivers/rilmodem/rilmodem.h \
|
||||
drivers/rilmodem/call-settings.c \
|
||||
drivers/rilmodem/call-forwarding.c \
|
||||
drivers/rilmodem/cbs.c \
|
||||
drivers/rilmodem/oemraw-messages.c
|
||||
drivers/rilmodem/oemraw-messages.c \
|
||||
drivers/rilmodem/call-barring.c \
|
||||
drivers/rilmodem/stk.c
|
||||
|
||||
endif
|
||||
|
||||
@@ -547,6 +549,13 @@ builtin_sources += plugins/smart-messaging.c
|
||||
builtin_modules += push_notification
|
||||
builtin_sources += plugins/push-notification.c
|
||||
|
||||
if PUSHFORWARDER
|
||||
builtin_modules += push_forwarder
|
||||
builtin_sources += plugins/push-forwarder.c
|
||||
builtin_cflags += @WSPCODEC_CFLAGS@
|
||||
builtin_libadd += @WSPCODEC_LIBS@
|
||||
endif
|
||||
|
||||
builtin_modules += sms_history
|
||||
builtin_sources += plugins/smshistory.c
|
||||
|
||||
|
||||
@@ -192,7 +192,10 @@ AM_CONDITIONAL(BLUETOOTH, test "${enable_bluetooth}" != "no")
|
||||
AC_ARG_ENABLE(nettime, AC_HELP_STRING([--disable-nettime],
|
||||
[disable Nettime plugin]),
|
||||
[enable_nettime=${enableval}])
|
||||
AM_CONDITIONAL(NETTIME, test "${enable_netttime}" != "no")
|
||||
if (test "${enable_nettime}" != "no"); then
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||
fi
|
||||
AM_CONDITIONAL(NETTIME, test "${enable_nettime}" != "no")
|
||||
|
||||
AC_ARG_WITH([provisiondb], AC_HELP_STRING([--with-provisiondb=FILE],
|
||||
[location of provision database]), [path_provisiondb=${withval}])
|
||||
@@ -223,6 +226,17 @@ AC_ARG_ENABLE(datafiles, AC_HELP_STRING([--disable-datafiles],
|
||||
[enable_datafiles=${enableval}])
|
||||
AM_CONDITIONAL(DATAFILES, test "${enable_datafiles}" != "no")
|
||||
|
||||
AC_ARG_ENABLE(pushforwarder, AC_HELP_STRING([--disable-pushforwarder],
|
||||
[disable Push Forwarder plugin]),
|
||||
[enable_pushforwarder=${enableval}])
|
||||
AM_CONDITIONAL(PUSHFORWARDER, test "${enable_pushforwarder}" != "no")
|
||||
if (test "${enable_pushforwarder}" != "no"); then
|
||||
PKG_CHECK_MODULES(WSPCODEC, libwspcodec >= 2.0, dummy=yes,
|
||||
AC_MSG_ERROR(WSP decoder is required))
|
||||
AC_SUBST(WSPCODEC_CFLAGS)
|
||||
AC_SUBST(WSPCODEC_LIBS)
|
||||
fi
|
||||
|
||||
if (test "${prefix}" = "NONE"); then
|
||||
dnl no prefix and no localstatedir, so default to /var
|
||||
if (test "$localstatedir" = '${prefix}/var'); then
|
||||
|
||||
310
ofono/drivers/rilmodem/call-barring.c
Normal file
310
ofono/drivers/rilmodem/call-barring.c
Normal file
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2014 Jolla Ltd
|
||||
* Contact: Miia Leinonen
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <ofono/log.h>
|
||||
#include <ofono/modem.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "gril.h"
|
||||
#include "call-barring.h"
|
||||
#include "rilmodem.h"
|
||||
#include "ril_constants.h"
|
||||
|
||||
/* See 3GPP 27.007 7.4 for possible values */
|
||||
#define RIL_MAX_SERVICE_LENGTH 3
|
||||
|
||||
/*
|
||||
* ril.h does not state that string count must be given, but that is
|
||||
* still expected by the modem
|
||||
*/
|
||||
#define RIL_QUERY_STRING_COUNT 4
|
||||
#define RIL_SET_STRING_COUNT 5
|
||||
#define RIL_SET_PW_STRING_COUNT 3
|
||||
|
||||
#define RIL_LENGTH_ZERO 0
|
||||
|
||||
struct barring_data {
|
||||
GRil *ril;
|
||||
guint timer_id;
|
||||
};
|
||||
|
||||
static void ril_call_barring_query_cb(struct ril_msg *message,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
struct parcel rilp;
|
||||
struct ofono_error error;
|
||||
ofono_call_barring_query_cb_t cb = cbd->cb;
|
||||
int bearer_class = 0;
|
||||
|
||||
if (message->error != RIL_E_SUCCESS) {
|
||||
ofono_error("Call Barring query failed, err: %i",
|
||||
message->error);
|
||||
decode_ril_error(&error, "FAIL");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ril_util_init_parcel(message, &rilp);
|
||||
|
||||
/*
|
||||
* Services for which the specified barring facility is active.
|
||||
* "0" means "disabled for all, -1 if unknown"
|
||||
*/
|
||||
parcel_r_int32(&rilp); /* count - we know there is only 1 */
|
||||
bearer_class = parcel_r_int32(&rilp);
|
||||
DBG("Active services: %i", bearer_class);
|
||||
|
||||
decode_ril_error(&error, "OK");
|
||||
|
||||
out:
|
||||
cb(&error, bearer_class, cbd->data);
|
||||
}
|
||||
|
||||
static void ril_call_barring_query(struct ofono_call_barring *cb,
|
||||
const char *lock, int cls,
|
||||
ofono_call_barring_query_cb_t callback,
|
||||
void *data)
|
||||
{
|
||||
struct barring_data *bd = ofono_call_barring_get_data(cb);
|
||||
struct cb_data *cbd = cb_data_new(callback, data);
|
||||
struct parcel rilp;
|
||||
int ret = 0;
|
||||
char cls_textual[RIL_MAX_SERVICE_LENGTH];
|
||||
|
||||
DBG("lock: %s, services to query: %i", lock, cls);
|
||||
|
||||
/*
|
||||
* RIL modems do not support 7 as default bearer class. According to
|
||||
* the 22.030 Annex C: When service code is not given it corresponds to
|
||||
* "All tele and bearer services"
|
||||
*/
|
||||
if (cls == BEARER_CLASS_DEFAULT)
|
||||
cls = SERVICE_CLASS_NONE;
|
||||
|
||||
sprintf(cls_textual, "%d", cls);
|
||||
|
||||
/*
|
||||
* See 3GPP 27.007 7.4 for parameter descriptions.
|
||||
* According to ril.h password should be empty string "" when not
|
||||
* needed, but in reality we only need to give string length as 0
|
||||
*/
|
||||
parcel_init(&rilp);
|
||||
parcel_w_int32(&rilp, RIL_QUERY_STRING_COUNT); /* Nbr of strings */
|
||||
parcel_w_string(&rilp, (char *) lock); /* Facility code */
|
||||
parcel_w_int32(&rilp, RIL_LENGTH_ZERO); /* Password length */
|
||||
parcel_w_string(&rilp, (char *) cls_textual);
|
||||
parcel_w_string(&rilp, NULL); /* AID (for FDN, not yet supported) */
|
||||
|
||||
ret = g_ril_send(bd->ril, RIL_REQUEST_QUERY_FACILITY_LOCK,
|
||||
rilp.data, rilp.size, ril_call_barring_query_cb,
|
||||
cbd, g_free);
|
||||
|
||||
parcel_free(&rilp);
|
||||
|
||||
if (ret <= 0) {
|
||||
ofono_error("Sending Call Barring query failed, err: %i", ret);
|
||||
g_free(cbd);
|
||||
CALLBACK_WITH_FAILURE(callback, -1, data);
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_call_barring_set_cb(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
struct ofono_error error;
|
||||
ofono_call_barring_set_cb_t cb = cbd->cb;
|
||||
|
||||
if (message->error != RIL_E_SUCCESS) {
|
||||
ofono_error("Call Barring Set request failed, err: %i",
|
||||
message->error);
|
||||
decode_ril_error(&error, "FAIL");
|
||||
goto out;
|
||||
}
|
||||
|
||||
decode_ril_error(&error, "OK");
|
||||
|
||||
out:
|
||||
cb(&error, cbd->data);
|
||||
}
|
||||
|
||||
static void ril_call_barring_set(struct ofono_call_barring *cb,
|
||||
const char *lock, int enable,
|
||||
const char *passwd, int cls,
|
||||
ofono_call_barring_set_cb_t callback,
|
||||
void *data)
|
||||
{
|
||||
struct barring_data *bd = ofono_call_barring_get_data(cb);
|
||||
struct cb_data *cbd = cb_data_new(callback, data);
|
||||
struct parcel rilp;
|
||||
int ret = 0;
|
||||
char cls_textual[RIL_MAX_SERVICE_LENGTH];
|
||||
|
||||
DBG("lock: %s, enable: %i, bearer class: %i", lock, enable, cls);
|
||||
|
||||
/*
|
||||
* RIL modem does not support 7 as default bearer class. According to
|
||||
* the 22.030 Annex C: When service code is not given it corresponds to
|
||||
* "All tele and bearer services"
|
||||
*/
|
||||
if (cls == BEARER_CLASS_DEFAULT)
|
||||
cls = SERVICE_CLASS_NONE;
|
||||
|
||||
sprintf(cls_textual, "%d", cls);
|
||||
|
||||
/* See 3GPP 27.007 7.4 for parameter descriptions */
|
||||
parcel_init(&rilp);
|
||||
parcel_w_int32(&rilp, RIL_SET_STRING_COUNT); /* Nbr of strings */
|
||||
parcel_w_string(&rilp, (char *) lock); /* Facility code */
|
||||
|
||||
if (enable)
|
||||
parcel_w_string(&rilp, RIL_FACILITY_LOCK);
|
||||
else
|
||||
parcel_w_string(&rilp, RIL_FACILITY_UNLOCK);
|
||||
|
||||
parcel_w_string(&rilp, (char *) passwd);
|
||||
parcel_w_string(&rilp, (char *) cls_textual);
|
||||
parcel_w_string(&rilp, NULL); /* AID (for FDN, not yet supported) */
|
||||
|
||||
ret = g_ril_send(bd->ril, RIL_REQUEST_SET_FACILITY_LOCK,
|
||||
rilp.data, rilp.size, ril_call_barring_set_cb,
|
||||
cbd, g_free);
|
||||
|
||||
parcel_free(&rilp);
|
||||
|
||||
if (ret <= 0) {
|
||||
ofono_error("Sending Call Barring Set request failed, err: %i",
|
||||
ret);
|
||||
g_free(cbd);
|
||||
CALLBACK_WITH_FAILURE(callback, data);
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_call_barring_set_passwd_cb(struct ril_msg *message,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
struct ofono_error error;
|
||||
ofono_call_barring_set_cb_t cb = cbd->cb;
|
||||
|
||||
if (message->error != RIL_E_SUCCESS) {
|
||||
ofono_error("Call Barring Set PW req failed, err: %i",
|
||||
message->error);
|
||||
decode_ril_error(&error, "FAIL");
|
||||
goto out;
|
||||
}
|
||||
|
||||
decode_ril_error(&error, "OK");
|
||||
|
||||
out:
|
||||
cb(&error, cbd->data);
|
||||
}
|
||||
|
||||
static void ril_call_barring_set_passwd(struct ofono_call_barring *barr,
|
||||
const char *lock,
|
||||
const char *old_passwd,
|
||||
const char *new_passwd,
|
||||
ofono_call_barring_set_cb_t cb,
|
||||
void *data)
|
||||
{
|
||||
struct barring_data *bd = ofono_call_barring_get_data(barr);
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
struct parcel rilp;
|
||||
int ret = 0;
|
||||
|
||||
DBG("");
|
||||
|
||||
parcel_init(&rilp);
|
||||
parcel_w_int32(&rilp, RIL_SET_PW_STRING_COUNT); /* Nbr of strings */
|
||||
parcel_w_string(&rilp, (char *) lock); /* Facility code */
|
||||
parcel_w_string(&rilp, (char *) old_passwd);
|
||||
parcel_w_string(&rilp, (char *) new_passwd);
|
||||
|
||||
ret = g_ril_send(bd->ril, RIL_REQUEST_CHANGE_BARRING_PASSWORD,
|
||||
rilp.data, rilp.size, ril_call_barring_set_passwd_cb,
|
||||
cbd, g_free);
|
||||
|
||||
parcel_free(&rilp);
|
||||
|
||||
if (ret <= 0) {
|
||||
ofono_error("Sending Call Barring Set PW req failed, err: %i",
|
||||
ret);
|
||||
g_free(cbd);
|
||||
CALLBACK_WITH_FAILURE(cb, data);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean ril_delayed_register(gpointer user_data)
|
||||
{
|
||||
struct ofono_call_barring *cb = user_data;
|
||||
struct barring_data *bd = ofono_call_barring_get_data(cb);
|
||||
|
||||
bd->timer_id = 0;
|
||||
|
||||
ofono_call_barring_register(cb);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int ril_call_barring_probe(struct ofono_call_barring *cb,
|
||||
unsigned int vendor, void *user)
|
||||
{
|
||||
GRil *ril = user;
|
||||
struct barring_data *bd = g_try_new0(struct barring_data, 1);
|
||||
|
||||
bd->ril = g_ril_clone(ril);
|
||||
ofono_call_barring_set_data(cb, bd);
|
||||
g_timeout_add_seconds(2, ril_delayed_register, cb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ril_call_barring_remove(struct ofono_call_barring *cb)
|
||||
{
|
||||
struct barring_data *data = ofono_call_barring_get_data(cb);
|
||||
ofono_call_barring_set_data(cb, NULL);
|
||||
|
||||
if (data->timer_id > 0)
|
||||
g_source_remove(data->timer_id);
|
||||
|
||||
g_ril_unref(data->ril);
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
static struct ofono_call_barring_driver driver = {
|
||||
.name = "rilmodem",
|
||||
.probe = ril_call_barring_probe,
|
||||
.remove = ril_call_barring_remove,
|
||||
.query = ril_call_barring_query,
|
||||
.set = ril_call_barring_set,
|
||||
.set_passwd = ril_call_barring_set_passwd
|
||||
};
|
||||
|
||||
void ril_call_barring_init(void)
|
||||
{
|
||||
ofono_call_barring_driver_register(&driver);
|
||||
}
|
||||
|
||||
void ril_call_barring_exit(void)
|
||||
{
|
||||
ofono_call_barring_driver_unregister(&driver);
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2013 Jolla Ltd
|
||||
* Copyright (C) 2013-2014 Jolla Ltd
|
||||
* Contact: Jussi Kangas <jussi.kangas@tieto.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -89,16 +89,13 @@ static void ril_registration(struct ofono_call_forwarding *cf, int type,
|
||||
|
||||
parcel_w_int32(&rilp, type);
|
||||
|
||||
/* Modem seems to respond with error to all queries
|
||||
/*
|
||||
* Modem seems to respond with error to all queries
|
||||
* or settings made with bearer class
|
||||
* BEARER_CLASS_DEFAULT. Design decision: If given
|
||||
* class is BEARER_CLASS_DEFAULT let's map it to
|
||||
* SERVICE_CLASS_VOICE effectively making it the
|
||||
* default bearer. This in line with API which is
|
||||
* contains only voice anyways. TODO: Checkout
|
||||
* the behaviour with final modem
|
||||
* BEARER_CLASS_VOICE as per RIL design.
|
||||
*/
|
||||
|
||||
if (cls == BEARER_CLASS_DEFAULT)
|
||||
cls = BEARER_CLASS_VOICE;
|
||||
|
||||
@@ -137,16 +134,13 @@ static void ril_send_forward_cmd(struct ofono_call_forwarding *cf,
|
||||
|
||||
parcel_w_int32(&rilp, type);
|
||||
|
||||
/* Modem seems to respond with error to all queries
|
||||
/*
|
||||
* Modem seems to respond with error to all queries
|
||||
* or settings made with bearer class
|
||||
* BEARER_CLASS_DEFAULT. Design decision: If given
|
||||
* class is BEARER_CLASS_DEFAULT let's map it to
|
||||
* SERVICE_CLASS_VOICE effectively making it the
|
||||
* default bearer. This in line with API which is
|
||||
* contains only voice anyways. TODO: Checkout
|
||||
* the behaviour with final modem
|
||||
* BEARER_CLASS_VOICE as per RIL design.
|
||||
*/
|
||||
|
||||
if (cls == BEARER_CLASS_DEFAULT)
|
||||
cls = BEARER_CLASS_VOICE;
|
||||
|
||||
@@ -246,7 +240,7 @@ static void ril_query_cb(struct ril_msg *message, gpointer user_data)
|
||||
|
||||
}
|
||||
|
||||
CALLBACK_WITH_SUCCESS(cb, 1, list, cbd->data);
|
||||
CALLBACK_WITH_SUCCESS(cb, nmbr_of_resps, list, cbd->data);
|
||||
|
||||
g_free(list);
|
||||
} else {
|
||||
@@ -272,18 +266,15 @@ static void ril_query(struct ofono_call_forwarding *cf, int type, int cls,
|
||||
|
||||
parcel_w_int32(&rilp, type);
|
||||
|
||||
/* Modem seems to respond with error to all queries
|
||||
/*
|
||||
* Modem seems to respond with error to all queries
|
||||
* or settings made with bearer class
|
||||
* BEARER_CLASS_DEFAULT. Design decision: If given
|
||||
* class is BEARER_CLASS_DEFAULT let's map it to
|
||||
* SERVICE_CLASS_VOICE effectively making it the
|
||||
* default bearer. This in line with API which is
|
||||
* contains only voice anyways. TODO: Checkout
|
||||
* the behaviour with final modem
|
||||
* SERVICE_CLASS_NONE as per RIL design.
|
||||
*/
|
||||
|
||||
if (cls == BEARER_CLASS_DEFAULT)
|
||||
cls = BEARER_CLASS_VOICE;
|
||||
cls = SERVICE_CLASS_NONE;
|
||||
|
||||
parcel_w_int32(&rilp, cls);
|
||||
|
||||
@@ -351,10 +342,10 @@ static struct ofono_call_forwarding_driver driver = {
|
||||
.probe = ril_call_forwarding_probe,
|
||||
.remove = ril_call_forwarding_remove,
|
||||
.erasure = ril_erasure,
|
||||
.deactivation = ril_deactivate,
|
||||
.deactivation = ril_deactivate,
|
||||
.query = ril_query,
|
||||
.registration = ril_registration,
|
||||
.activation = ril_activate
|
||||
.registration = ril_registration,
|
||||
.activation = ril_activate
|
||||
};
|
||||
|
||||
void ril_call_forwarding_init(void)
|
||||
|
||||
@@ -1107,15 +1107,27 @@ static void pb_reference_data_cb(const struct ofono_error *error,
|
||||
pbd->pb_reference_file_info.record_length)) {
|
||||
pbd->pb_reference_file_info.record++;
|
||||
DBG("Next EFpbr record %d", pbd->pb_reference_file_info.record);
|
||||
pbd->sim_driver->read_file_linear(get_sim(),
|
||||
pbd->pb_reference_file_info.
|
||||
file_id,
|
||||
pbd->pb_reference_file_info.
|
||||
record,
|
||||
pbd->pb_reference_file_info.
|
||||
record_length,
|
||||
NULL, 0,
|
||||
pb_reference_data_cb, cbd);
|
||||
if (RIL_APPTYPE_SIM == ril_get_app_type()) {
|
||||
pbd->sim_driver->read_file_linear(get_sim(),
|
||||
pbd->pb_reference_file_info.
|
||||
file_id,
|
||||
pbd->pb_reference_file_info.
|
||||
record,
|
||||
pbd->pb_reference_file_info.
|
||||
record_length,
|
||||
sim_path, sizeof(sim_path),
|
||||
pb_reference_data_cb, cbd);
|
||||
} else {
|
||||
pbd->sim_driver->read_file_linear(get_sim(),
|
||||
pbd->pb_reference_file_info.
|
||||
file_id,
|
||||
pbd->pb_reference_file_info.
|
||||
record,
|
||||
pbd->pb_reference_file_info.
|
||||
record_length,
|
||||
usim_path, sizeof(usim_path),
|
||||
pb_reference_data_cb, cbd);
|
||||
}
|
||||
} else {
|
||||
struct pb_file_info *file_info;
|
||||
DBG("All EFpbr records read");
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <ofono/log.h>
|
||||
#include <ofono/modem.h>
|
||||
#include <ofono/radio-settings.h>
|
||||
#include <ofono/sim.h>
|
||||
|
||||
#include "gril.h"
|
||||
#include "grilutil.h"
|
||||
@@ -200,11 +201,18 @@ static gboolean ril_get_net_config(struct radio_data *rsd)
|
||||
{
|
||||
GKeyFile *keyfile;
|
||||
GError *err = NULL;
|
||||
char *path = RIL_CONFIG;
|
||||
char *config_path = RIL_CONFIG_DIR;
|
||||
char **alreadyset = NULL;
|
||||
gboolean needsconfig = FALSE;
|
||||
gboolean value = FALSE;
|
||||
gboolean found = FALSE;
|
||||
rsd->ratmode = PREF_NET_TYPE_GSM_WCDMA_AUTO;
|
||||
GDir *config_dir;
|
||||
const gchar *config_file;
|
||||
char *path;
|
||||
gsize length;
|
||||
gchar **codes = NULL;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* First we need to check should the LTE be on
|
||||
@@ -215,12 +223,38 @@ static gboolean ril_get_net_config(struct radio_data *rsd)
|
||||
|
||||
g_key_file_set_list_separator(keyfile, ',');
|
||||
|
||||
if (!g_key_file_load_from_file(keyfile, path, 0, &err)) {
|
||||
g_error_free(err);
|
||||
return needsconfig;
|
||||
} else {
|
||||
config_dir = g_dir_open(config_path, 0, NULL);
|
||||
while ((config_file = g_dir_read_name(config_dir)) != NULL) {
|
||||
path = g_strconcat(RIL_CONFIG_DIR "/", config_file, NULL);
|
||||
|
||||
if (!g_key_file_load_from_file(keyfile, path, 0, &err)) {
|
||||
g_error_free(err);
|
||||
needsconfig = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_key_file_has_group(keyfile, LTE_FLAG))
|
||||
found = TRUE;
|
||||
else if (g_key_file_has_group(keyfile, MCC_LIST)) {
|
||||
codes = g_key_file_get_string_list(keyfile, MCC_LIST,
|
||||
MCC_KEY, &length, NULL);
|
||||
if (codes) {
|
||||
for (i = 0; codes[i]; i++) {
|
||||
if (g_str_equal(codes[i],
|
||||
ofono_sim_get_mcc(get_sim()))
|
||||
== TRUE) {
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_strfreev(codes);
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
rsd->ratmode = PREF_NET_TYPE_LTE_GSM_WCDMA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_key_file_free(keyfile);
|
||||
@@ -233,6 +267,8 @@ static gboolean ril_get_net_config(struct radio_data *rsd)
|
||||
if (alreadyset[0])
|
||||
value = g_key_file_get_boolean(
|
||||
keyfile, alreadyset[0], LTE_FLAG, NULL);
|
||||
else if (rsd->ratmode == PREF_NET_TYPE_GSM_WCDMA_AUTO)
|
||||
value = TRUE;
|
||||
|
||||
if (!value && rsd->ratmode == PREF_NET_TYPE_LTE_GSM_WCDMA) {
|
||||
g_key_file_set_boolean(keyfile,
|
||||
|
||||
@@ -53,8 +53,10 @@ static int rilmodem_init(void)
|
||||
ril_ussd_init();
|
||||
ril_call_settings_init();
|
||||
ril_call_forwarding_init();
|
||||
ril_call_barring_init();
|
||||
ril_cbs_init();
|
||||
ril_oemraw_init();
|
||||
ril_stk_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -76,8 +78,10 @@ static void rilmodem_exit(void)
|
||||
ril_ussd_exit();
|
||||
ril_call_settings_exit();
|
||||
ril_call_forwarding_exit();
|
||||
ril_call_barring_exit();
|
||||
ril_cbs_exit();
|
||||
ril_oemraw_exit();
|
||||
ril_stk_exit();
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(rilmodem, "RIL modem driver", VERSION,
|
||||
|
||||
@@ -28,9 +28,14 @@
|
||||
/* Shared constants */
|
||||
#define EF_STATUS_INVALIDATED 0
|
||||
#define EF_STATUS_VALID 1
|
||||
#define RIL_CONFIG "/etc/ofono/ril_subscription.conf"
|
||||
#define RIL_HW_CONFIG "/etc/ofono/ril_subscription.conf"
|
||||
#define RIL_CONFIG_DIR "/etc/ofono/"
|
||||
#define RIL_STORE "rilmodem"
|
||||
#define LTE_FLAG "4gOn"
|
||||
#define MCC_LIST "MCC-whitelist"
|
||||
#define MCC_KEY "Countries"
|
||||
#define UI_LANG "/var/lib/environment/nemo/locale.conf"
|
||||
#define CFG_LANG "LANG="
|
||||
|
||||
extern void ril_devinfo_init(void);
|
||||
extern void ril_devinfo_exit(void);
|
||||
@@ -68,6 +73,9 @@ extern void ril_call_settings_exit(void);
|
||||
extern void ril_call_forwarding_init(void);
|
||||
extern void ril_call_forwarding_exit(void);
|
||||
|
||||
extern void ril_call_barring_init(void);
|
||||
extern void ril_call_barring_exit(void);
|
||||
|
||||
extern void ril_cbs_init(void);
|
||||
extern void ril_cbs_exit(void);
|
||||
|
||||
@@ -76,3 +84,7 @@ extern void ril_phonebook_exit(void);
|
||||
|
||||
extern void ril_oemraw_init(void);
|
||||
extern void ril_oemraw_exit(void);
|
||||
|
||||
extern void ril_stk_init(void);
|
||||
extern void ril_stk_exit(void);
|
||||
|
||||
|
||||
@@ -402,13 +402,25 @@ gboolean ril_util_parse_sim_status(GRil *gril,
|
||||
|
||||
apps[i]->app_type = parcel_r_int32(&rilp);
|
||||
apps[i]->app_state = parcel_r_int32(&rilp);
|
||||
|
||||
/*
|
||||
* Consider RIL_APPSTATE_ILLEGAL also READY. Even if app state
|
||||
* is RIL_APPSTATE_ILLEGAL (-1), ICC operations must be
|
||||
* permitted. Network access requests will anyway be rejected
|
||||
* and ME will be in limited service.
|
||||
*/
|
||||
if (apps[i]->app_state == RIL_APPSTATE_ILLEGAL) {
|
||||
DBG("RIL_APPSTATE_ILLEGAL => RIL_APPSTATE_READY");
|
||||
apps[i]->app_state = RIL_APPSTATE_READY;
|
||||
}
|
||||
|
||||
apps[i]->perso_substate = parcel_r_int32(&rilp);
|
||||
|
||||
/* TODO: we need a way to instruct parcel to skip
|
||||
* a string, without allocating memory...
|
||||
*/
|
||||
apps[i]->aid_str = parcel_r_string(&rilp); /* application ID (AID) */
|
||||
apps[i]->app_str = parcel_r_string(&rilp); /* application label */
|
||||
apps[i]->aid_str = parcel_r_string(&rilp); /* app ID (AID) */
|
||||
apps[i]->app_str = parcel_r_string(&rilp); /* app label */
|
||||
|
||||
apps[i]->pin_replaced = parcel_r_int32(&rilp);
|
||||
apps[i]->pin1_state = parcel_r_int32(&rilp);
|
||||
@@ -459,7 +471,8 @@ gboolean ril_util_parse_reg(GRil *gril,
|
||||
* >= 4 for VOICE_REG reply
|
||||
* >= 5 for DATA_REG reply
|
||||
*/
|
||||
if ((tmp = parcel_r_int32(&rilp)) < 4) {
|
||||
tmp = parcel_r_int32(&rilp);
|
||||
if (tmp < 4) {
|
||||
DBG("Size of response array is too small: %d", tmp);
|
||||
goto error;
|
||||
}
|
||||
@@ -482,10 +495,12 @@ gboolean ril_util_parse_reg(GRil *gril,
|
||||
* voice & data response.
|
||||
*/
|
||||
if (tmp--) {
|
||||
sreason = parcel_r_string(&rilp); /* TODO: different use for CDMA */
|
||||
/* TODO: different use for CDMA */
|
||||
sreason = parcel_r_string(&rilp);
|
||||
|
||||
if (tmp--) {
|
||||
smax = parcel_r_string(&rilp); /* TODO: different use for CDMA */
|
||||
/* TODO: different use for CDMA */
|
||||
smax = parcel_r_string(&rilp);
|
||||
|
||||
if (smax && max_calls)
|
||||
*max_calls = atoi(smax);
|
||||
@@ -518,7 +533,7 @@ gboolean ril_util_parse_reg(GRil *gril,
|
||||
|
||||
if (tech) {
|
||||
if (stech) {
|
||||
switch(atoi(stech)) {
|
||||
switch (atoi(stech)) {
|
||||
case RADIO_TECH_UNKNOWN:
|
||||
*tech = -1;
|
||||
break;
|
||||
@@ -659,7 +674,8 @@ gint ril_util_get_signal(GRil *gril, struct ril_msg *message)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ril_util_free_sim_apps(struct sim_app **apps, guint num_apps) {
|
||||
void ril_util_free_sim_apps(struct sim_app **apps, guint num_apps)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < num_apps; i++) {
|
||||
|
||||
@@ -62,29 +62,6 @@ enum at_util_charset {
|
||||
RIL_UTIL_CHARSET_8859_H = 0x10000,
|
||||
};
|
||||
|
||||
/* TODO: consider moving these to ril_constants.h */
|
||||
enum app_state {
|
||||
APPSTATE_UNKNOWN,
|
||||
APPSTATE_DETECTED,
|
||||
APPSTATE_PIN,
|
||||
APPSTATE_PUK,
|
||||
APPSTATE_SUBSCRIPTION_PERSO,
|
||||
APPSTATE_READY,
|
||||
};
|
||||
|
||||
enum perso_state {
|
||||
PERSOSUBSTATE_SIM_NETWORK = 3,
|
||||
PERSOSUBSTATE_SIM_NETWORK_SUBSET,
|
||||
PERSOSUBSTATE_SIM_CORPORATE,
|
||||
PERSOSUBSTATE_SIM_SERVICE_PROVIDER,
|
||||
PERSOSUBSTATE_SIM_SIM,
|
||||
PERSOSUBSTATE_SIM_NETWORK_PUK,
|
||||
PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK,
|
||||
PERSOSUBSTATE_SIM_CORPORATE_PUK,
|
||||
PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK,
|
||||
PERSOSUBSTATE_SIM_SIM_PUK,
|
||||
};
|
||||
|
||||
#define MAX_UICC_APPS 16
|
||||
|
||||
struct sim_status {
|
||||
@@ -193,7 +170,7 @@ static inline int ril_util_convert_signal_strength(int strength)
|
||||
return result;
|
||||
}
|
||||
|
||||
#define DECLARE_FAILURE(e) \
|
||||
#define DECLARE_FAILURE(e) \
|
||||
struct ofono_error e; \
|
||||
e.type = OFONO_ERROR_TYPE_FAILURE; \
|
||||
e.error = 0 \
|
||||
|
||||
@@ -74,10 +74,6 @@
|
||||
#define ENTER_SIM_PUK_PARAMS 3
|
||||
#define CHANGE_SIM_PIN_PARAMS 3
|
||||
|
||||
/* RIL_FACILITY_LOCK parameters */
|
||||
#define RIL_FACILITY_UNLOCK "0"
|
||||
#define RIL_FACILITY_LOCK "1"
|
||||
|
||||
/* Current SIM */
|
||||
static struct ofono_sim *current_sim;
|
||||
/* Current active app */
|
||||
@@ -217,11 +213,13 @@ static void ril_file_info_cb(struct ril_msg *message, gpointer user_data)
|
||||
|
||||
if (response_len) {
|
||||
if (response[0] == 0x62) {
|
||||
ok = sim_parse_3g_get_response(response, response_len,
|
||||
&flen, &rlen, &str, access, NULL);
|
||||
ok = sim_parse_3g_get_response(
|
||||
response, response_len,
|
||||
&flen, &rlen, &str, access, NULL);
|
||||
} else
|
||||
ok = sim_parse_2g_get_response(response, response_len,
|
||||
&flen, &rlen, &str, access, &file_status);
|
||||
ok = sim_parse_2g_get_response(
|
||||
response, response_len,
|
||||
&flen, &rlen, &str, access, &file_status);
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
@@ -240,7 +238,8 @@ error:
|
||||
}
|
||||
|
||||
static void ril_sim_read_info(struct ofono_sim *sim, int fileid,
|
||||
const unsigned char *path, unsigned int path_len,
|
||||
const unsigned char *path,
|
||||
unsigned int path_len,
|
||||
ofono_sim_file_info_cb_t cb,
|
||||
void *data)
|
||||
{
|
||||
@@ -340,7 +339,8 @@ error:
|
||||
|
||||
static void ril_sim_read_binary(struct ofono_sim *sim, int fileid,
|
||||
int start, int length,
|
||||
const unsigned char *path, unsigned int path_len,
|
||||
const unsigned char *path,
|
||||
unsigned int path_len,
|
||||
ofono_sim_read_cb_t cb, void *data)
|
||||
{
|
||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
||||
@@ -393,7 +393,8 @@ static void ril_sim_read_binary(struct ofono_sim *sim, int fileid,
|
||||
|
||||
static void ril_sim_read_record(struct ofono_sim *sim, int fileid,
|
||||
int record, int length,
|
||||
const unsigned char *path, unsigned int path_len,
|
||||
const unsigned char *path,
|
||||
unsigned int path_len,
|
||||
ofono_sim_read_cb_t cb, void *data)
|
||||
{
|
||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
||||
@@ -506,10 +507,10 @@ static void ril_read_imsi(struct ofono_sim *sim, ofono_sim_imsi_cb_t cb,
|
||||
}
|
||||
}
|
||||
|
||||
void set_pin_lock_state(struct ofono_sim *sim,struct sim_app *app)
|
||||
void set_pin_lock_state(struct ofono_sim *sim, struct sim_app *app)
|
||||
{
|
||||
DBG("pin1:%u,pin2:%u",app->pin1_state,app->pin2_state);
|
||||
/*
|
||||
DBG("pin1:%u,pin2:%u", app->pin1_state, app->pin2_state);
|
||||
/*
|
||||
* Updates only pin and pin2 state. Other locks are not dealt here. For
|
||||
* that a RIL_REQUEST_QUERY_FACILITY_LOCK request should be used.
|
||||
*/
|
||||
@@ -518,10 +519,11 @@ void set_pin_lock_state(struct ofono_sim *sim,struct sim_app *app)
|
||||
case RIL_PINSTATE_ENABLED_VERIFIED:
|
||||
case RIL_PINSTATE_ENABLED_BLOCKED:
|
||||
case RIL_PINSTATE_ENABLED_PERM_BLOCKED:
|
||||
ofono_set_pin_lock_state(sim,OFONO_SIM_PASSWORD_SIM_PIN,TRUE);
|
||||
ofono_set_pin_lock_state(sim, OFONO_SIM_PASSWORD_SIM_PIN, TRUE);
|
||||
break;
|
||||
case RIL_PINSTATE_DISABLED:
|
||||
ofono_set_pin_lock_state(sim,OFONO_SIM_PASSWORD_SIM_PIN,FALSE);
|
||||
ofono_set_pin_lock_state(
|
||||
sim, OFONO_SIM_PASSWORD_SIM_PIN, FALSE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -531,10 +533,12 @@ void set_pin_lock_state(struct ofono_sim *sim,struct sim_app *app)
|
||||
case RIL_PINSTATE_ENABLED_VERIFIED:
|
||||
case RIL_PINSTATE_ENABLED_BLOCKED:
|
||||
case RIL_PINSTATE_ENABLED_PERM_BLOCKED:
|
||||
ofono_set_pin_lock_state(sim,OFONO_SIM_PASSWORD_SIM_PIN2,TRUE);
|
||||
ofono_set_pin_lock_state(
|
||||
sim, OFONO_SIM_PASSWORD_SIM_PIN2, TRUE);
|
||||
break;
|
||||
case RIL_PINSTATE_DISABLED:
|
||||
ofono_set_pin_lock_state(sim,OFONO_SIM_PASSWORD_SIM_PIN2,FALSE);
|
||||
ofono_set_pin_lock_state(
|
||||
sim, OFONO_SIM_PASSWORD_SIM_PIN2, FALSE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -552,42 +556,42 @@ static void configure_active_app(struct sim_data *sd,
|
||||
|
||||
DBG("setting aid_str (AID) to: %s", sd->aid_str);
|
||||
switch (app->app_state) {
|
||||
case APPSTATE_PIN:
|
||||
case RIL_APPSTATE_PIN:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PIN;
|
||||
break;
|
||||
case APPSTATE_PUK:
|
||||
case RIL_APPSTATE_PUK:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PUK;
|
||||
break;
|
||||
case APPSTATE_SUBSCRIPTION_PERSO:
|
||||
case RIL_APPSTATE_SUBSCRIPTION_PERSO:
|
||||
switch (app->perso_substate) {
|
||||
case PERSOSUBSTATE_SIM_NETWORK:
|
||||
case RIL_PERSOSUBSTATE_SIM_NETWORK:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHNET_PIN;
|
||||
break;
|
||||
case PERSOSUBSTATE_SIM_NETWORK_SUBSET:
|
||||
case RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHNETSUB_PIN;
|
||||
break;
|
||||
case PERSOSUBSTATE_SIM_CORPORATE:
|
||||
case RIL_PERSOSUBSTATE_SIM_CORPORATE:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHCORP_PIN;
|
||||
break;
|
||||
case PERSOSUBSTATE_SIM_SERVICE_PROVIDER:
|
||||
case RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHSP_PIN;
|
||||
break;
|
||||
case PERSOSUBSTATE_SIM_SIM:
|
||||
case RIL_PERSOSUBSTATE_SIM_SIM:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHSIM_PIN;
|
||||
break;
|
||||
case PERSOSUBSTATE_SIM_NETWORK_PUK:
|
||||
case RIL_PERSOSUBSTATE_SIM_NETWORK_PUK:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHNET_PUK;
|
||||
break;
|
||||
case PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK:
|
||||
case RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHNETSUB_PUK;
|
||||
break;
|
||||
case PERSOSUBSTATE_SIM_CORPORATE_PUK:
|
||||
case RIL_PERSOSUBSTATE_SIM_CORPORATE_PUK:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHCORP_PUK;
|
||||
break;
|
||||
case PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK:
|
||||
case RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHSP_PUK;
|
||||
break;
|
||||
case PERSOSUBSTATE_SIM_SIM_PUK:
|
||||
case RIL_PERSOSUBSTATE_SIM_SIM_PUK:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_PHFSIM_PUK;
|
||||
break;
|
||||
default:
|
||||
@@ -595,11 +599,11 @@ static void configure_active_app(struct sim_data *sd,
|
||||
break;
|
||||
};
|
||||
break;
|
||||
case APPSTATE_READY:
|
||||
case RIL_APPSTATE_READY:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_NONE;
|
||||
break;
|
||||
case APPSTATE_UNKNOWN:
|
||||
case APPSTATE_DETECTED:
|
||||
case RIL_APPSTATE_UNKNOWN:
|
||||
case RIL_APPSTATE_DETECTED:
|
||||
default:
|
||||
sd->passwd_state = OFONO_SIM_PASSWORD_INVALID;
|
||||
break;
|
||||
@@ -642,7 +646,7 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
|
||||
if (sd->sim_registered == FALSE) {
|
||||
ofono_sim_register(sim);
|
||||
sd->sim_registered = TRUE;
|
||||
} else
|
||||
} else {
|
||||
/* TODO: There doesn't seem to be any other
|
||||
* way to force the core SIM code to
|
||||
* recheck the PIN.
|
||||
@@ -650,15 +654,16 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
|
||||
* more appropriate call here??
|
||||
* __ofono_sim_refresh(sim, NULL, TRUE, TRUE);
|
||||
*/
|
||||
DBG("sd->card_state:%u",sd->card_state);
|
||||
DBG("sd->card_state:%u", sd->card_state);
|
||||
if (sd->card_state != RIL_CARDSTATE_PRESENT) {
|
||||
ofono_sim_inserted_notify(sim, TRUE);
|
||||
sd->card_state = RIL_CARDSTATE_PRESENT;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_passwd) {
|
||||
if (!strcmp(current_passwd, defaultpasswd)) {
|
||||
__ofono_sim_recheck_pin(sim);
|
||||
__ofono_sim_recheck_pin(sim);
|
||||
} else if (sd->passwd_state !=
|
||||
OFONO_SIM_PASSWORD_SIM_PIN) {
|
||||
__ofono_sim_recheck_pin(sim);
|
||||
@@ -787,7 +792,9 @@ static void ril_pin_change_state_cb(struct ril_msg *message, gpointer user_data)
|
||||
retries[passwd_type] = retry_count;
|
||||
sd->retries[passwd_type] = retries[passwd_type];
|
||||
|
||||
/* TODO: re-bfactor to not use macro for FAILURE; doesn't return error! */
|
||||
/*
|
||||
* TODO: re-bfactor to not use macro for FAILURE; doesn't return error!
|
||||
*/
|
||||
|
||||
if (message->error == RIL_E_SUCCESS) {
|
||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
||||
@@ -838,9 +845,9 @@ static void ril_pin_send(struct ofono_sim *sim, const char *passwd,
|
||||
}
|
||||
|
||||
static void ril_pin_change_state(struct ofono_sim *sim,
|
||||
enum ofono_sim_password_type passwd_type,
|
||||
int enable, const char *passwd,
|
||||
ofono_sim_lock_unlock_cb_t cb, void *data)
|
||||
enum ofono_sim_password_type passwd_type,
|
||||
int enable, const char *passwd,
|
||||
ofono_sim_lock_unlock_cb_t cb, void *data)
|
||||
{
|
||||
struct sim_data *sd = ofono_sim_get_data(sim);
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
|
||||
@@ -168,10 +168,14 @@ static void submit_sms_cb(struct ril_msg *message, gpointer user_data)
|
||||
int mr;
|
||||
|
||||
if (message->error == RIL_E_SUCCESS) {
|
||||
ofono_info("sms sending succesful");
|
||||
ofono_info("sms sending successful");
|
||||
decode_ril_error(&error, "OK");
|
||||
} else if (message->error == RIL_E_GENERIC_FAILURE) {
|
||||
ofono_info("not allowed by MO SMS control, do not retry");
|
||||
error.type = OFONO_ERROR_TYPE_CMS;
|
||||
error.error = 500;
|
||||
} else {
|
||||
ofono_error("sms sending failed");
|
||||
ofono_error("sms sending failed, retry");
|
||||
decode_ril_error(&error, "FAIL");
|
||||
}
|
||||
|
||||
@@ -248,19 +252,21 @@ static void ril_ack_delivery_cb(struct ril_msg *message, gpointer user_data)
|
||||
"SMS acknowledgement failed: Further SMS reception is not guaranteed");
|
||||
}
|
||||
|
||||
static void ril_ack_delivery(struct ofono_sms *sms)
|
||||
static void ril_ack_delivery(struct ofono_sms *sms, int error)
|
||||
{
|
||||
struct sms_data *sd = ofono_sms_get_data(sms);
|
||||
struct parcel rilp;
|
||||
int ret;
|
||||
int request = RIL_REQUEST_SMS_ACKNOWLEDGE;
|
||||
int code = 0;
|
||||
|
||||
if (!error)
|
||||
code = 0xFF;
|
||||
|
||||
parcel_init(&rilp);
|
||||
parcel_w_int32(&rilp, 2); /* Number of int32 values in array */
|
||||
parcel_w_int32(&rilp, 1); /* Successful receipt */
|
||||
parcel_w_int32(&rilp, 0); /* error code */
|
||||
|
||||
/* TODO: should ACK be sent for either of the error cases? */
|
||||
parcel_w_int32(&rilp, error); /* Successful (1)/Failed (0) receipt */
|
||||
parcel_w_int32(&rilp, code); /* error code */
|
||||
|
||||
/* ACK the incoming NEW_SMS */
|
||||
ret = g_ril_send(sd->ril, request,
|
||||
@@ -329,11 +335,13 @@ static void ril_sms_notify(struct ril_msg *message, gpointer user_data)
|
||||
ril_buf_len - smsc_len);
|
||||
}
|
||||
|
||||
ril_ack_delivery(sms);
|
||||
ril_ack_delivery(sms, TRUE);
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
ril_ack_delivery(sms, FALSE);
|
||||
|
||||
ofono_error("Unable to parse NEW_SMS notification");
|
||||
}
|
||||
|
||||
|
||||
336
ofono/drivers/rilmodem/stk.c
Normal file
336
ofono/drivers/rilmodem/stk.c
Normal file
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2014 Jolla Ltd
|
||||
*
|
||||
* 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 <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <ofono/log.h>
|
||||
#include <ofono/modem.h>
|
||||
#include <ofono/stk.h>
|
||||
|
||||
#include "gril.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "rilmodem.h"
|
||||
#include "ril_constants.h"
|
||||
|
||||
struct stk_data {
|
||||
GRil *ril;
|
||||
};
|
||||
|
||||
gboolean subscribed;
|
||||
|
||||
static void ril_envelope_cb(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_stk_envelope_cb_t cb = cbd->cb;
|
||||
struct ofono_error error;
|
||||
|
||||
DBG("");
|
||||
|
||||
if (message->error == RIL_E_SUCCESS) {
|
||||
decode_ril_error(&error, "OK");
|
||||
} else {
|
||||
DBG("Envelope reply failure: %s",
|
||||
ril_error_to_string(message->error));
|
||||
decode_ril_error(&error, "FAIL");
|
||||
}
|
||||
|
||||
cb(&error, NULL, 0, cbd->data);
|
||||
}
|
||||
|
||||
static void ril_stk_envelope(struct ofono_stk *stk, int length,
|
||||
const unsigned char *command,
|
||||
ofono_stk_envelope_cb_t cb, void *data)
|
||||
{
|
||||
struct stk_data *sd = ofono_stk_get_data(stk);
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
struct parcel rilp;
|
||||
char *hex_envelope = NULL;
|
||||
int request = RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND;
|
||||
guint ret;
|
||||
|
||||
DBG("");
|
||||
|
||||
hex_envelope = encode_hex(command, length, 0);
|
||||
|
||||
DBG("rilmodem envelope: %s", hex_envelope);
|
||||
|
||||
parcel_init(&rilp);
|
||||
parcel_w_string(&rilp, hex_envelope);
|
||||
|
||||
ret = g_ril_send(sd->ril, request,
|
||||
rilp.data, rilp.size, ril_envelope_cb,
|
||||
cbd, g_free);
|
||||
|
||||
parcel_free(&rilp);
|
||||
|
||||
if (ret <= 0) {
|
||||
g_free(cbd);
|
||||
CALLBACK_WITH_FAILURE(cb, NULL, -1, data);
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_tr_cb(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_stk_generic_cb_t cb = cbd->cb;
|
||||
struct ofono_error error;
|
||||
|
||||
DBG("");
|
||||
|
||||
if (message->error == RIL_E_SUCCESS) {
|
||||
decode_ril_error(&error, "OK");
|
||||
} else {
|
||||
DBG("Error in sending terminal response");
|
||||
ofono_error("Error in sending terminal response");
|
||||
decode_ril_error(&error, "FAIL");
|
||||
}
|
||||
|
||||
cb(&error, cbd->data);
|
||||
}
|
||||
|
||||
static void ril_stk_terminal_response(struct ofono_stk *stk, int length,
|
||||
const unsigned char *resp,
|
||||
ofono_stk_generic_cb_t cb, void *data)
|
||||
{
|
||||
struct stk_data *sd = ofono_stk_get_data(stk);
|
||||
struct cb_data *cbd = cb_data_new(cb, data);
|
||||
struct parcel rilp;
|
||||
char *hex_tr = NULL;
|
||||
int request = RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE;
|
||||
guint ret;
|
||||
|
||||
DBG("");
|
||||
|
||||
hex_tr = encode_hex(resp, length, 0);
|
||||
|
||||
DBG("rilmodem terminal response: %s", hex_tr);
|
||||
|
||||
parcel_init(&rilp);
|
||||
parcel_w_string(&rilp, hex_tr);
|
||||
|
||||
ret = g_ril_send(sd->ril, request,
|
||||
rilp.data, rilp.size, ril_tr_cb,
|
||||
cbd, g_free);
|
||||
|
||||
parcel_free(&rilp);
|
||||
|
||||
if (ret <= 0) {
|
||||
g_free(cbd);
|
||||
CALLBACK_WITH_FAILURE(cb, data);
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_stk_user_confirmation(struct ofono_stk *stk,
|
||||
ofono_bool_t confirm)
|
||||
{
|
||||
struct stk_data *sd = ofono_stk_get_data(stk);
|
||||
struct parcel rilp;
|
||||
int request = RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM;
|
||||
int ret;
|
||||
|
||||
DBG("");
|
||||
|
||||
/* Only pcmd needing user confirmation is call set up
|
||||
* RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM
|
||||
*/
|
||||
parcel_init(&rilp);
|
||||
parcel_w_int32(&rilp, 1); /* size of array */
|
||||
parcel_w_int32(&rilp, confirm); /* yes/no */
|
||||
|
||||
/* fire and forget i.e. not waiting for the callback*/
|
||||
ret = g_ril_send(sd->ril, request, rilp.data,
|
||||
rilp.size, NULL, NULL, NULL);
|
||||
|
||||
g_ril_print_request_no_args(sd->ril, ret, request);
|
||||
|
||||
parcel_free(&rilp);
|
||||
}
|
||||
|
||||
static void ril_stk_pcmd_notify(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct ofono_stk *stk = user_data;
|
||||
struct parcel rilp;
|
||||
char *pcmd = NULL;
|
||||
guchar *pdu = NULL;
|
||||
long len;
|
||||
|
||||
DBG("");
|
||||
|
||||
ril_util_init_parcel(message, &rilp);
|
||||
pcmd = parcel_r_string(&rilp);
|
||||
DBG("pcmd: %s", pcmd);
|
||||
|
||||
pdu = decode_hex((const char *) pcmd,
|
||||
strlen(pcmd),
|
||||
&len, -1);
|
||||
|
||||
ofono_stk_proactive_command_notify(stk, len, (const guchar *)pdu);
|
||||
}
|
||||
|
||||
static void ril_stk_event_notify(struct ril_msg *message, gpointer user_data)
|
||||
{
|
||||
struct ofono_stk *stk = user_data;
|
||||
struct parcel rilp;
|
||||
char *pcmd = NULL;
|
||||
guchar *pdu = NULL;
|
||||
long len;
|
||||
|
||||
DBG("");
|
||||
|
||||
/* Proactive command has been handled by the modem. */
|
||||
ril_util_init_parcel(message, &rilp);
|
||||
pcmd = parcel_r_string(&rilp);
|
||||
DBG("pcmd: %s", pcmd);
|
||||
|
||||
pdu = decode_hex((const char *) pcmd,
|
||||
strlen(pcmd),
|
||||
&len, -1);
|
||||
|
||||
ofono_stk_proactive_command_handled_notify(stk, len,
|
||||
(const guchar *)pdu);
|
||||
}
|
||||
|
||||
static void ril_stk_session_end_notify(struct ril_msg *message,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct ofono_stk *stk = user_data;
|
||||
|
||||
DBG("");
|
||||
|
||||
ofono_stk_proactive_session_end_notify(stk);
|
||||
}
|
||||
|
||||
static void ril_stk_agent_ready(struct ofono_stk *stk)
|
||||
{
|
||||
struct stk_data *sd = ofono_stk_get_data(stk);
|
||||
int request = RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING;
|
||||
int ret;
|
||||
|
||||
DBG("");
|
||||
|
||||
if (!subscribed) {
|
||||
DBG("Subscribing notifications");
|
||||
g_ril_register(sd->ril, RIL_UNSOL_STK_PROACTIVE_COMMAND,
|
||||
ril_stk_pcmd_notify, stk);
|
||||
|
||||
g_ril_register(sd->ril, RIL_UNSOL_STK_SESSION_END,
|
||||
ril_stk_session_end_notify, stk);
|
||||
|
||||
g_ril_register(sd->ril, RIL_UNSOL_STK_EVENT_NOTIFY,
|
||||
ril_stk_event_notify, stk);
|
||||
subscribed = TRUE;
|
||||
}
|
||||
|
||||
/* fire and forget i.e. not waiting for the callback*/
|
||||
ret = g_ril_send(sd->ril, request, NULL, 0,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
g_ril_print_request_no_args(sd->ril, ret, request);
|
||||
}
|
||||
|
||||
void ril_stk_set_lang()
|
||||
{
|
||||
gchar *contents;
|
||||
GError *err = NULL;
|
||||
|
||||
if (!g_file_get_contents(UI_LANG, &contents, NULL, &err)) {
|
||||
if (err)
|
||||
ofono_error("cannot open %s error: %d: message: %s",
|
||||
UI_LANG, err->code, err->message);
|
||||
g_error_free(err);
|
||||
} else {
|
||||
gchar *pch = g_strrstr(contents, CFG_LANG);
|
||||
/* Set System UI lang to env LANG */
|
||||
if (pch) {
|
||||
setenv("LANG", pch + strlen(CFG_LANG), 1);
|
||||
DBG("LANG %s", getenv("LANG"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int ril_stk_probe(struct ofono_stk *stk, unsigned int vendor, void *data)
|
||||
{
|
||||
GRil *ril = data;
|
||||
struct stk_data *sd;
|
||||
|
||||
DBG("");
|
||||
|
||||
sd = g_try_new0(struct stk_data, 1);
|
||||
if (sd == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
sd->ril = g_ril_clone(ril);
|
||||
ofono_stk_set_data(stk, sd);
|
||||
|
||||
/* Register interface in this phase for stk agent */
|
||||
ofono_stk_register(stk);
|
||||
|
||||
subscribed = FALSE;
|
||||
|
||||
/* UI language for local info */
|
||||
ril_stk_set_lang();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ril_stk_remove(struct ofono_stk *stk)
|
||||
{
|
||||
struct stk_data *sd = ofono_stk_get_data(stk);
|
||||
|
||||
DBG("");
|
||||
|
||||
ofono_stk_set_data(stk, NULL);
|
||||
|
||||
g_ril_unref(sd->ril);
|
||||
g_free(sd);
|
||||
}
|
||||
|
||||
static struct ofono_stk_driver driver = {
|
||||
.name = "rilmodem",
|
||||
.probe = ril_stk_probe,
|
||||
.remove = ril_stk_remove,
|
||||
.envelope = ril_stk_envelope,
|
||||
.terminal_response = ril_stk_terminal_response,
|
||||
.user_confirmation = ril_stk_user_confirmation,
|
||||
.ready = ril_stk_agent_ready
|
||||
};
|
||||
|
||||
void ril_stk_init(void)
|
||||
{
|
||||
ofono_stk_driver_register(&driver);
|
||||
}
|
||||
|
||||
void ril_stk_exit(void)
|
||||
{
|
||||
ofono_stk_driver_unregister(&driver);
|
||||
}
|
||||
@@ -835,6 +835,9 @@ static gboolean can_write_data(gpointer data)
|
||||
gsize len;
|
||||
char *cr;
|
||||
gboolean wakeup_first = FALSE;
|
||||
#ifdef WRITE_SCHEDULER_DEBUG
|
||||
int limiter;
|
||||
#endif
|
||||
|
||||
/* Grab the first command off the queue and write as
|
||||
* much of it as we can
|
||||
@@ -886,13 +889,20 @@ static gboolean can_write_data(gpointer data)
|
||||
towrite = cr - (cmd->cmd + chat->cmd_bytes_written) + 1;
|
||||
|
||||
#ifdef WRITE_SCHEDULER_DEBUG
|
||||
if (towrite > 5)
|
||||
towrite = 5;
|
||||
limiter = towrite;
|
||||
|
||||
if (limiter > 5)
|
||||
limiter = 5;
|
||||
#endif
|
||||
|
||||
bytes_written = g_at_io_write(chat->io,
|
||||
cmd->cmd + chat->cmd_bytes_written,
|
||||
towrite);
|
||||
#ifdef WRITE_SCHEDULER_DEBUG
|
||||
limiter
|
||||
#else
|
||||
towrite
|
||||
#endif
|
||||
);
|
||||
|
||||
if (bytes_written == 0)
|
||||
return FALSE;
|
||||
|
||||
@@ -355,7 +355,8 @@ static void handle_response(struct ril_s *p, struct ril_msg *message)
|
||||
int i;
|
||||
guint len, id;
|
||||
|
||||
g_assert(count > 0);
|
||||
if (!count)
|
||||
return;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
req = g_queue_peek_nth(p->command_queue, i);
|
||||
@@ -373,13 +374,13 @@ static void handle_response(struct ril_s *p, struct ril_msg *message)
|
||||
message->error));
|
||||
|
||||
req = g_queue_pop_nth(p->command_queue, i);
|
||||
if (req->callback) {
|
||||
if (req->callback)
|
||||
req->callback(message, req->user_data);
|
||||
}
|
||||
|
||||
len = g_queue_get_length(p->out_queue);
|
||||
for (i = 0; i < len; i++) {
|
||||
id = *(guint *) g_queue_peek_nth(p->out_queue, i);
|
||||
id = *(guint *) g_queue_peek_nth(
|
||||
p->out_queue, i);
|
||||
if (id == req->id) {
|
||||
g_queue_pop_nth(p->out_queue, i);
|
||||
break;
|
||||
@@ -403,14 +404,21 @@ static void handle_response(struct ril_s *p, struct ril_msg *message)
|
||||
|
||||
}
|
||||
|
||||
static void notify_call_callback(gpointer data, gpointer user_data)
|
||||
{
|
||||
struct ril_notify_node *node = data;
|
||||
struct ril_msg *message = user_data;
|
||||
|
||||
node->callback(message, node->user_data);
|
||||
}
|
||||
|
||||
static void handle_unsol_req(struct ril_s *p, struct ril_msg *message)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
struct ril_notify *notify;
|
||||
int req_key;
|
||||
gpointer key, value;
|
||||
GList *list_item;
|
||||
struct ril_notify_node *node;
|
||||
GSList *list_item;
|
||||
gboolean found = FALSE;
|
||||
|
||||
if (p->notify_list == NULL)
|
||||
@@ -430,15 +438,12 @@ static void handle_unsol_req(struct ril_s *p, struct ril_msg *message)
|
||||
if (req_key != message->req)
|
||||
continue;
|
||||
|
||||
list_item = (GList *) notify->nodes;
|
||||
list_item = notify->nodes;
|
||||
|
||||
while (list_item != NULL) {
|
||||
node = list_item->data;
|
||||
|
||||
node->callback(message, node->user_data);
|
||||
if (list_item)
|
||||
found = TRUE;
|
||||
list_item = (GList *) g_slist_next(list_item);
|
||||
}
|
||||
|
||||
g_slist_foreach(notify->nodes, notify_call_callback, message);
|
||||
}
|
||||
|
||||
/* Only log events not being listended for... */
|
||||
@@ -582,9 +587,8 @@ static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
|
||||
while (p->suspended == FALSE && (p->read_so_far < len)) {
|
||||
gsize rbytes = MIN(len - p->read_so_far, wrap - p->read_so_far);
|
||||
|
||||
if (rbytes < 4) {
|
||||
if (rbytes < 4)
|
||||
return;
|
||||
}
|
||||
|
||||
/* this function attempts to read the next full length
|
||||
* fixed message from the stream. if not all bytes are
|
||||
@@ -595,9 +599,8 @@ static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
|
||||
message = read_fixed_record(p, buf, &rbytes);
|
||||
|
||||
/* wait for the rest of the record... */
|
||||
if (message == NULL) {
|
||||
if (message == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
buf += rbytes;
|
||||
p->read_so_far += rbytes;
|
||||
@@ -642,7 +645,8 @@ static gboolean can_write_data(gpointer data)
|
||||
for (i = 0; i < qlen; i++) {
|
||||
req = g_queue_peek_nth(ril->command_queue, i);
|
||||
if (req) {
|
||||
id = *(guint *) g_queue_peek_head(ril->out_queue);
|
||||
id = *(guint *) g_queue_peek_head(
|
||||
ril->out_queue);
|
||||
if (req->id == id)
|
||||
goto out;
|
||||
} else {
|
||||
|
||||
@@ -191,6 +191,7 @@
|
||||
#define RIL_PERSOSUBSTATE_RUIM_RUIM_PUK 24
|
||||
|
||||
/* SIM - App states */
|
||||
#define RIL_APPSTATE_ILLEGAL -1
|
||||
#define RIL_APPSTATE_UNKNOWN 0
|
||||
#define RIL_APPSTATE_DETECTED 1
|
||||
#define RIL_APPSTATE_PIN 2
|
||||
@@ -384,4 +385,11 @@
|
||||
#define RIL_UNSOL_STK_CC_ALPHA_NOTIFY 1040
|
||||
#define RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED 1041
|
||||
|
||||
/* Suplementary services Service class*/
|
||||
#define SERVICE_CLASS_NONE 0
|
||||
|
||||
/* RIL_FACILITY_LOCK parameters */
|
||||
#define RIL_FACILITY_UNLOCK "0"
|
||||
#define RIL_FACILITY_LOCK "1"
|
||||
|
||||
#endif /*__RIL_CONSTANTS_H*/
|
||||
|
||||
@@ -80,29 +80,29 @@ extern "C" {
|
||||
DBusConnection *ofono_dbus_get_connection(void);
|
||||
|
||||
void ofono_dbus_dict_append(DBusMessageIter *dict, const char *key, int type,
|
||||
void *value);
|
||||
const void *value);
|
||||
|
||||
void ofono_dbus_dict_append_array(DBusMessageIter *dict, const char *key,
|
||||
int type, void *val);
|
||||
int type, const void *val);
|
||||
|
||||
void ofono_dbus_dict_append_dict(DBusMessageIter *dict, const char *key,
|
||||
int type, void *val);
|
||||
int type, const void *val);
|
||||
|
||||
int ofono_dbus_signal_property_changed(DBusConnection *conn, const char *path,
|
||||
const char *interface, const char *name,
|
||||
int type, void *value);
|
||||
int type, const void *value);
|
||||
|
||||
int ofono_dbus_signal_array_property_changed(DBusConnection *conn,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *name, int type,
|
||||
void *value);
|
||||
const void *value);
|
||||
|
||||
int ofono_dbus_signal_dict_property_changed(DBusConnection *conn,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *name, int type,
|
||||
void *value);
|
||||
const void *value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ struct ofono_stk_driver {
|
||||
int length, const unsigned char *resp,
|
||||
ofono_stk_generic_cb_t cb, void *data);
|
||||
void (*user_confirmation)(struct ofono_stk *stk, ofono_bool_t confirm);
|
||||
void (*ready)(struct ofono_stk *stk);
|
||||
};
|
||||
|
||||
int ofono_stk_driver_register(const struct ofono_stk_driver *d);
|
||||
|
||||
@@ -190,7 +190,9 @@ static void apn_end(GMarkupParseContext *context, const gchar *element_name,
|
||||
{
|
||||
if (g_str_equal(element_name, "name") ||
|
||||
g_str_equal(element_name, "username") ||
|
||||
g_str_equal(element_name, "password"))
|
||||
g_str_equal(element_name, "password") ||
|
||||
g_str_equal(element_name, "mmsc") ||
|
||||
g_str_equal(element_name, "mmsproxy"))
|
||||
g_markup_parse_context_pop(context);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,54 @@
|
||||
|
||||
#include "mbpi.h"
|
||||
|
||||
/* Returns the list containing exactly one INTERNET and one MMS access point */
|
||||
static GSList *provision_normalize_apn_list(GSList *apns)
|
||||
{
|
||||
struct ofono_gprs_provision_data *internet = NULL;
|
||||
struct ofono_gprs_provision_data *mms = NULL;
|
||||
GSList *l = apns;
|
||||
|
||||
while (l != NULL) {
|
||||
GSList *next = l->next;
|
||||
struct ofono_gprs_provision_data *ap = l->data;
|
||||
|
||||
if (ap->type == OFONO_GPRS_CONTEXT_TYPE_INTERNET && !internet) {
|
||||
internet = ap;
|
||||
} else if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS && !mms) {
|
||||
mms = ap;
|
||||
} else {
|
||||
/* Remove duplicate and unnecessary access points */
|
||||
DBG("Discarding APN: '%s' Name: '%s' Type: %s",
|
||||
ap->apn, ap->name, mbpi_ap_type(ap->type));
|
||||
mbpi_ap_free(ap);
|
||||
apns = g_slist_remove_link(apns, l);
|
||||
}
|
||||
l = next;
|
||||
}
|
||||
|
||||
if (!internet) {
|
||||
internet = g_try_new0(struct ofono_gprs_provision_data, 1);
|
||||
if (internet) {
|
||||
internet->type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
|
||||
internet->name = g_strdup("Internet");
|
||||
internet->apn = g_strdup("internet");
|
||||
apns = g_slist_append(apns, internet);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mms) {
|
||||
mms = g_try_new0(struct ofono_gprs_provision_data, 1);
|
||||
if (mms) {
|
||||
mms->type = OFONO_GPRS_CONTEXT_TYPE_MMS;
|
||||
mms->name = g_strdup("MMS");
|
||||
mms->apn = g_strdup("mms");
|
||||
apns = g_slist_append(apns, mms);
|
||||
}
|
||||
}
|
||||
|
||||
return apns;
|
||||
}
|
||||
|
||||
static int provision_get_settings(const char *mcc, const char *mnc,
|
||||
const char *spn,
|
||||
struct ofono_gprs_provision_data **settings,
|
||||
@@ -52,33 +100,22 @@ static int provision_get_settings(const char *mcc, const char *mnc,
|
||||
DBG("Provisioning for MCC %s, MNC %s, SPN '%s'", mcc, mnc, spn);
|
||||
|
||||
/*
|
||||
* TODO: review with upstream. Default behavior was to
|
||||
* disallow duplicate APN entries, which unfortunately exist
|
||||
* in the mobile-broadband-provider-info db.
|
||||
* Passing FALSE to mbpi_lookup_apn() would return
|
||||
* an empty list if duplicates are found.
|
||||
*/
|
||||
apns = mbpi_lookup_apn(mcc, mnc, TRUE, &error);
|
||||
if (apns == NULL) {
|
||||
if (error != NULL) {
|
||||
ofono_error("%s", error->message);
|
||||
g_error_free(error);
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
if (error != NULL) {
|
||||
ofono_error("%s", error->message);
|
||||
g_error_free(error);
|
||||
}
|
||||
|
||||
apns = provision_normalize_apn_list(apns);
|
||||
if (apns == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
ap_count = g_slist_length(apns);
|
||||
|
||||
ofono_info("GPRS Provisioning found %d matching APNs for SPN: %s MCC: %s MNC: %s",
|
||||
ap_count, spn, mcc, mnc);
|
||||
/*
|
||||
* Only keep the first APN found.
|
||||
*
|
||||
* This allows auto-provisioning to work most of the time vs.
|
||||
* passing FALSE to mbpi_lookup_apn() which would return an
|
||||
* an empty list if duplicates are found.
|
||||
*/
|
||||
if (ap_count > 1)
|
||||
ap_count = 1;
|
||||
DBG("Found %d APs", ap_count);
|
||||
|
||||
*settings = g_try_new0(struct ofono_gprs_provision_data, ap_count);
|
||||
if (*settings == NULL) {
|
||||
@@ -97,25 +134,16 @@ static int provision_get_settings(const char *mcc, const char *mnc,
|
||||
for (l = apns, i = 0; l; l = l->next, i++) {
|
||||
struct ofono_gprs_provision_data *ap = l->data;
|
||||
|
||||
/*
|
||||
* Only create a data context for the first matching APN.
|
||||
* See comment above that restricts restricts apn_count.
|
||||
*/
|
||||
if (i == 0) {
|
||||
ofono_info("Name: '%s'", ap->name);
|
||||
ofono_info("APN: '%s'", ap->apn);
|
||||
ofono_info("Type: %s", mbpi_ap_type(ap->type));
|
||||
ofono_info("Username: '%s'", ap->username);
|
||||
ofono_info("Password: '%s'", ap->password);
|
||||
DBG("Name: '%s'", ap->name);
|
||||
DBG("APN: '%s'", ap->apn);
|
||||
DBG("Type: %s", mbpi_ap_type(ap->type));
|
||||
DBG("Username: '%s'", ap->username);
|
||||
DBG("Password: '%s'", ap->password);
|
||||
|
||||
memcpy(*settings + i, ap,
|
||||
sizeof(struct ofono_gprs_provision_data));
|
||||
|
||||
g_free(ap);
|
||||
} else {
|
||||
mbpi_ap_free(ap);
|
||||
}
|
||||
memcpy(*settings + i, ap,
|
||||
sizeof(struct ofono_gprs_provision_data));
|
||||
|
||||
g_free(ap);
|
||||
}
|
||||
|
||||
g_slist_free(apns);
|
||||
|
||||
541
ofono/plugins/push-forwarder.c
Normal file
541
ofono/plugins/push-forwarder.c
Normal file
@@ -0,0 +1,541 @@
|
||||
/*
|
||||
* Copyright (C) 2013-2014 Jolla Ltd.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <wspcodec.h>
|
||||
|
||||
#define OFONO_API_SUBJECT_TO_CHANGE
|
||||
#include <ofono.h>
|
||||
#include <plugin.h>
|
||||
|
||||
/*
|
||||
* Push forwarder plugin is looking for configuration files in
|
||||
* /etc/ofono/push_forwarder.d directory. Confiration files are
|
||||
* glib key files that look like this:
|
||||
*
|
||||
* [Jolla MMS Handler]
|
||||
* ContentType = application/vnd.wap.mms-message
|
||||
* Interface = com.jolla.MmsEngine.
|
||||
* Service = com.jolla.MmsEngine
|
||||
* Method = HandlePush
|
||||
* Path = /
|
||||
*
|
||||
* Only files with .conf suffix are loaded. In addition to the keys
|
||||
* from the above example, SourcePort and DestinationPort port keys
|
||||
* are supported. All other keys are ignored. One file may describe
|
||||
* several push handlers. See pf_parse_config() function for details.
|
||||
*
|
||||
* When push fowarder receives a WAP push, it goes through the list
|
||||
* of registered handlers and invokes all of them that match content
|
||||
* type and/or port numbers. The rest is up to the D-Bus service
|
||||
* handling the call.
|
||||
*/
|
||||
|
||||
#define PF_CONFIG_DIR CONFIGDIR "/push_forwarder.d"
|
||||
|
||||
struct pf_modem {
|
||||
struct ofono_modem *modem;
|
||||
struct ofono_sms *sms;
|
||||
struct ofono_sim *sim;
|
||||
unsigned int sim_watch_id;
|
||||
unsigned int sms_watch_id;
|
||||
unsigned int push_watch_id;
|
||||
};
|
||||
|
||||
struct push_datagram_handler {
|
||||
char *name;
|
||||
char *content_type;
|
||||
char *interface;
|
||||
char *service;
|
||||
char *method;
|
||||
char *path;
|
||||
int dst_port;
|
||||
int src_port;
|
||||
};
|
||||
|
||||
static GSList *handlers;
|
||||
static GSList *modems;
|
||||
static unsigned int modem_watch_id;
|
||||
static int inotify_fd = -1;
|
||||
static int inotify_watch_id = -1;
|
||||
static guint inotify_watch_source_id;
|
||||
static GIOChannel *inotify_watch_channel;
|
||||
|
||||
static void pf_notify_handler(struct push_datagram_handler *h,
|
||||
const char *imsi, const char *from, const struct tm *remote,
|
||||
const struct tm *local, int dst, int src,
|
||||
const char *ct, const void *data, unsigned int len)
|
||||
{
|
||||
struct tm remote_tm = *remote;
|
||||
struct tm local_tm = *local;
|
||||
dbus_uint32_t remote_time_arg = mktime(&remote_tm);
|
||||
dbus_uint32_t local_time_arg = mktime(&local_tm);
|
||||
dbus_int32_t dst_arg = dst;
|
||||
dbus_int32_t src_arg = src;
|
||||
DBusMessageIter iter, array;
|
||||
DBusMessage *msg = dbus_message_new_method_call(h->service,
|
||||
h->path, h->interface, h->method);
|
||||
|
||||
dbus_message_append_args(msg,
|
||||
DBUS_TYPE_STRING, &imsi,
|
||||
DBUS_TYPE_STRING, &from,
|
||||
DBUS_TYPE_UINT32, &remote_time_arg,
|
||||
DBUS_TYPE_UINT32, &local_time_arg,
|
||||
DBUS_TYPE_INT32, &dst_arg,
|
||||
DBUS_TYPE_INT32, &src_arg,
|
||||
DBUS_TYPE_STRING, &ct,
|
||||
DBUS_TYPE_INVALID);
|
||||
dbus_message_iter_init_append(msg, &iter);
|
||||
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
|
||||
DBUS_TYPE_BYTE_AS_STRING, &array);
|
||||
dbus_message_iter_append_fixed_array(&array,
|
||||
DBUS_TYPE_BYTE, &data, len);
|
||||
dbus_message_iter_close_container(&iter, &array);
|
||||
dbus_message_set_no_reply(msg, TRUE);
|
||||
dbus_connection_send(ofono_dbus_get_connection(), msg, NULL);
|
||||
dbus_message_unref(msg);
|
||||
}
|
||||
|
||||
static gboolean pf_match_port(int port, int expected_port)
|
||||
{
|
||||
if (expected_port < 0)
|
||||
return TRUE;
|
||||
|
||||
if (expected_port == port)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean pf_match_handler(struct push_datagram_handler *h,
|
||||
const char *ct, int dst, int src)
|
||||
{
|
||||
if (pf_match_port(dst, h->dst_port) == FALSE)
|
||||
return FALSE;
|
||||
|
||||
if (pf_match_port(src, h->src_port) == FALSE)
|
||||
return FALSE;
|
||||
|
||||
if (h->content_type == NULL)
|
||||
return TRUE;
|
||||
|
||||
if (strcmp(h->content_type, ct) == 0)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void pf_handle_datagram(const char *from,
|
||||
const struct tm *remote, const struct tm *local, int dst,
|
||||
int src, const unsigned char *buffer, unsigned int len,
|
||||
void *userdata)
|
||||
{
|
||||
struct pf_modem *pm = userdata;
|
||||
guint remain;
|
||||
const guint8 *data;
|
||||
unsigned int hdrlen;
|
||||
unsigned int off;
|
||||
const void *ct;
|
||||
const char *imsi;
|
||||
GSList *link;
|
||||
|
||||
DBG("received push of size: %u", len);
|
||||
|
||||
if (pm->sim == NULL)
|
||||
return;
|
||||
|
||||
imsi = ofono_sim_get_imsi(pm->sim);
|
||||
if (len < 3)
|
||||
return;
|
||||
|
||||
if (buffer[1] != 6)
|
||||
return;
|
||||
|
||||
remain = len - 2;
|
||||
data = buffer + 2;
|
||||
|
||||
if (wsp_decode_uintvar(data, remain, &hdrlen, &off) == FALSE)
|
||||
return;
|
||||
|
||||
if ((off + hdrlen) > remain)
|
||||
return;
|
||||
|
||||
data += off;
|
||||
remain -= off;
|
||||
|
||||
DBG(" WAP header %u bytes", hdrlen);
|
||||
|
||||
if (wsp_decode_content_type(data, hdrlen, &ct, &off, NULL) == FALSE)
|
||||
return;
|
||||
|
||||
data += hdrlen;
|
||||
remain -= hdrlen;
|
||||
|
||||
DBG(" content type %s", (char *)ct);
|
||||
DBG(" imsi %s", imsi);
|
||||
DBG(" data size %u", remain);
|
||||
|
||||
link = handlers;
|
||||
|
||||
while (link) {
|
||||
struct push_datagram_handler *h = link->data;
|
||||
|
||||
if (pf_match_handler(h, ct, dst, src) != FALSE) {
|
||||
DBG("notifying %s", h->name);
|
||||
pf_notify_handler(h, imsi, from, remote, local, dst,
|
||||
src, ct, data, remain);
|
||||
}
|
||||
link = link->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void pf_sms_watch(struct ofono_atom *atom,
|
||||
enum ofono_atom_watch_condition cond, void *userdata)
|
||||
{
|
||||
struct pf_modem *pm = userdata;
|
||||
|
||||
if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED) {
|
||||
DBG("registered");
|
||||
pm->sms = __ofono_atom_get_data(atom);
|
||||
pm->push_watch_id = __ofono_sms_datagram_watch_add(pm->sms,
|
||||
pf_handle_datagram, -1, -1, pm, NULL);
|
||||
} else if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
|
||||
DBG("unregistered");
|
||||
pm->sms = NULL;
|
||||
pm->push_watch_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void pf_sms_watch_done(void *userdata)
|
||||
{
|
||||
struct pf_modem *pm = userdata;
|
||||
|
||||
pm->sms_watch_id = 0;
|
||||
}
|
||||
|
||||
static void pf_sim_watch(struct ofono_atom *atom,
|
||||
enum ofono_atom_watch_condition cond, void *userdata)
|
||||
{
|
||||
struct pf_modem *pm = userdata;
|
||||
|
||||
if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED) {
|
||||
DBG("registered");
|
||||
pm->sim = __ofono_atom_get_data(atom);
|
||||
} else if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
|
||||
DBG("unregistered");
|
||||
pm->sim = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void pf_sim_watch_done(void *userdata)
|
||||
{
|
||||
struct pf_modem *pm = userdata;
|
||||
|
||||
pm->sim_watch_id = 0;
|
||||
}
|
||||
|
||||
static void pf_free_modem(struct pf_modem *pm)
|
||||
{
|
||||
if (pm == NULL)
|
||||
return;
|
||||
|
||||
if (pm->push_watch_id != 0)
|
||||
__ofono_sms_datagram_watch_remove(pm->sms, pm->push_watch_id);
|
||||
|
||||
if (pm->sim_watch_id != 0)
|
||||
__ofono_modem_remove_atom_watch(pm->modem, pm->sim_watch_id);
|
||||
|
||||
if (pm->sms_watch_id != 0)
|
||||
__ofono_modem_remove_atom_watch(pm->modem, pm->sms_watch_id);
|
||||
|
||||
g_free(pm);
|
||||
}
|
||||
|
||||
static void pf_modem_watch(struct ofono_modem *modem,
|
||||
gboolean added, void *userdata)
|
||||
{
|
||||
DBG("modem: %p, added: %d", modem, added);
|
||||
if (added != FALSE) {
|
||||
struct pf_modem *pm;
|
||||
|
||||
pm = g_try_new0(struct pf_modem, 1);
|
||||
if (pm == NULL)
|
||||
return;
|
||||
|
||||
pm->modem = modem;
|
||||
pm->sim_watch_id = __ofono_modem_add_atom_watch(modem,
|
||||
OFONO_ATOM_TYPE_SMS, pf_sms_watch, pm,
|
||||
pf_sms_watch_done);
|
||||
pm->sms_watch_id = __ofono_modem_add_atom_watch(modem,
|
||||
OFONO_ATOM_TYPE_SIM, pf_sim_watch, pm,
|
||||
pf_sim_watch_done);
|
||||
modems = g_slist_append(modems, pm);
|
||||
} else {
|
||||
GSList *link = modems;
|
||||
|
||||
while (link) {
|
||||
struct pf_modem *pm = link->data;
|
||||
|
||||
if (pm->modem == modem) {
|
||||
modems = g_slist_delete_link(modems, link);
|
||||
pf_free_modem(pm);
|
||||
break;
|
||||
}
|
||||
link = link->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pf_modem_init(struct ofono_modem *modem,
|
||||
void *userdata)
|
||||
{
|
||||
pf_modem_watch(modem, TRUE, NULL);
|
||||
}
|
||||
|
||||
static void pf_free_handler(void *data)
|
||||
{
|
||||
struct push_datagram_handler *h = data;
|
||||
|
||||
g_free(h->content_type);
|
||||
g_free(h->interface);
|
||||
g_free(h->service);
|
||||
g_free(h->method);
|
||||
g_free(h->path);
|
||||
g_free(h->name);
|
||||
g_free(h);
|
||||
}
|
||||
|
||||
static void pf_parse_handler(GKeyFile *conf, const char *g)
|
||||
{
|
||||
GError *err = NULL;
|
||||
struct push_datagram_handler *h;
|
||||
char *interface;
|
||||
char *service;
|
||||
char *method;
|
||||
char *path;
|
||||
|
||||
interface = g_key_file_get_string(conf, g, "Interface", NULL);
|
||||
if (interface == NULL)
|
||||
goto no_interface;
|
||||
|
||||
service = g_key_file_get_string(conf, g, "Service", NULL);
|
||||
if (service == NULL)
|
||||
goto no_service;
|
||||
|
||||
method = g_key_file_get_string(conf, g, "Method", NULL);
|
||||
if (method == NULL)
|
||||
goto no_method;
|
||||
|
||||
path = g_key_file_get_string(conf, g, "Path", NULL);
|
||||
if (path == NULL)
|
||||
goto no_path;
|
||||
|
||||
h = g_try_new0(struct push_datagram_handler, 1);
|
||||
if (h == NULL)
|
||||
goto no_memory;
|
||||
|
||||
h->name = g_strdup(g);
|
||||
h->interface = interface;
|
||||
h->service = service;
|
||||
h->method = method;
|
||||
h->path = path;
|
||||
h->content_type = g_key_file_get_string(conf, g, "ContentType", NULL);
|
||||
h->dst_port = g_key_file_get_integer(conf, g, "DestinationPort", &err);
|
||||
if (h->dst_port == 0 && err != NULL) {
|
||||
h->dst_port = -1;
|
||||
g_error_free(err);
|
||||
err = NULL;
|
||||
}
|
||||
h->src_port = g_key_file_get_integer(conf, g, "SourcePort", &err);
|
||||
if (h->src_port == 0 && err != NULL) {
|
||||
h->src_port = -1;
|
||||
g_error_free(err);
|
||||
err = NULL;
|
||||
}
|
||||
DBG("registered %s", h->name);
|
||||
if (h->content_type != NULL)
|
||||
DBG(" ContentType: %s", h->content_type);
|
||||
if (h->dst_port >= 0)
|
||||
DBG(" DestinationPort: %d", h->dst_port);
|
||||
if (h->src_port >= 0)
|
||||
DBG(" SourcePort: %d", h->src_port);
|
||||
DBG(" Interface: %s", interface);
|
||||
DBG(" Service: %s", service);
|
||||
DBG(" Method: %s", method);
|
||||
DBG(" Path: %s", path);
|
||||
handlers = g_slist_append(handlers, h);
|
||||
return;
|
||||
|
||||
no_memory:
|
||||
g_free(path);
|
||||
|
||||
no_path:
|
||||
g_free(method);
|
||||
|
||||
no_method:
|
||||
g_free(service);
|
||||
|
||||
no_service:
|
||||
g_free(interface);
|
||||
|
||||
no_interface:
|
||||
return;
|
||||
}
|
||||
|
||||
static void pf_parse_config(void)
|
||||
{
|
||||
GDir *dir;
|
||||
const gchar *file;
|
||||
|
||||
g_slist_free_full(handlers, pf_free_handler);
|
||||
handlers = NULL;
|
||||
|
||||
dir = g_dir_open(PF_CONFIG_DIR, 0, NULL);
|
||||
if (dir == NULL) {
|
||||
DBG(PF_CONFIG_DIR " not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
DBG("loading configuration from " PF_CONFIG_DIR);
|
||||
while ((file = g_dir_read_name(dir)) != NULL) {
|
||||
GError *err;
|
||||
GKeyFile *conf;
|
||||
char *path;
|
||||
|
||||
if (g_str_has_suffix(file, ".conf") == FALSE)
|
||||
continue;
|
||||
|
||||
err = NULL;
|
||||
conf = g_key_file_new();
|
||||
path = g_strconcat(PF_CONFIG_DIR "/", file, NULL);
|
||||
DBG("reading %s", file);
|
||||
|
||||
if (g_key_file_load_from_file(conf, path, 0, &err) != FALSE) {
|
||||
gsize i, n;
|
||||
char **names = g_key_file_get_groups(conf, &n);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
pf_parse_handler(conf, names[i]);
|
||||
g_strfreev(names);
|
||||
} else {
|
||||
ofono_warn("%s", err->message);
|
||||
g_error_free(err);
|
||||
}
|
||||
|
||||
g_key_file_free(conf);
|
||||
g_free(path);
|
||||
}
|
||||
|
||||
g_dir_close(dir);
|
||||
}
|
||||
|
||||
static gboolean pf_inotify(GIOChannel *gio, GIOCondition c, gpointer data)
|
||||
{
|
||||
int avail;
|
||||
gsize len;
|
||||
void *buf;
|
||||
GError *error;
|
||||
|
||||
if (ioctl(inotify_fd, FIONREAD, &avail) < 0)
|
||||
return FALSE;
|
||||
|
||||
buf = g_try_malloc(avail);
|
||||
if (buf == NULL)
|
||||
return FALSE;
|
||||
|
||||
error = NULL;
|
||||
if (g_io_channel_read_chars(gio, buf, avail, &len, &error) !=
|
||||
G_IO_STATUS_NORMAL) {
|
||||
g_free(buf);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pf_parse_config();
|
||||
g_free(buf);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int pf_plugin_init(void)
|
||||
{
|
||||
DBG("");
|
||||
pf_parse_config();
|
||||
modem_watch_id = __ofono_modemwatch_add(pf_modem_watch, NULL, NULL);
|
||||
__ofono_modem_foreach(pf_modem_init, NULL);
|
||||
inotify_fd = inotify_init();
|
||||
if (inotify_fd < 0)
|
||||
return 0;
|
||||
|
||||
inotify_watch_id = inotify_add_watch(inotify_fd,
|
||||
PF_CONFIG_DIR,
|
||||
IN_CLOSE_WRITE | IN_DELETE | IN_MOVE);
|
||||
if (inotify_watch_id < 0)
|
||||
goto no_inotify_watch_id;
|
||||
|
||||
inotify_watch_channel = g_io_channel_unix_new(inotify_fd);
|
||||
if (inotify_watch_channel == NULL)
|
||||
goto no_inotify_watch_channel;
|
||||
|
||||
g_io_channel_set_encoding(inotify_watch_channel, NULL, NULL);
|
||||
g_io_channel_set_buffered(inotify_watch_channel, FALSE);
|
||||
inotify_watch_source_id = g_io_add_watch(inotify_watch_channel,
|
||||
G_IO_IN, pf_inotify, NULL);
|
||||
if (inotify_watch_source_id != 0)
|
||||
return 0;
|
||||
|
||||
g_io_channel_unref(inotify_watch_channel);
|
||||
inotify_watch_channel = NULL;
|
||||
|
||||
no_inotify_watch_channel:
|
||||
inotify_rm_watch(inotify_fd, inotify_watch_id);
|
||||
inotify_watch_id = -1;
|
||||
|
||||
no_inotify_watch_id:
|
||||
close(inotify_fd);
|
||||
inotify_fd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pf_plugin_exit(void)
|
||||
{
|
||||
DBG("");
|
||||
__ofono_modemwatch_remove(modem_watch_id);
|
||||
modem_watch_id = 0;
|
||||
g_slist_free_full(modems, (GDestroyNotify)pf_free_modem);
|
||||
modems = NULL;
|
||||
g_slist_free_full(handlers, pf_free_handler);
|
||||
handlers = NULL;
|
||||
if (inotify_watch_source_id == 0)
|
||||
return;
|
||||
|
||||
g_source_remove(inotify_watch_source_id);
|
||||
inotify_watch_source_id = 0;
|
||||
g_io_channel_unref(inotify_watch_channel);
|
||||
inotify_watch_channel = NULL;
|
||||
inotify_rm_watch(inotify_fd, inotify_watch_id);
|
||||
inotify_watch_id = -1;
|
||||
close(inotify_fd);
|
||||
inotify_fd = -1;
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(push_forwarder, "Push Forwarder Plugin", VERSION,
|
||||
OFONO_PLUGIN_PRIORITY_DEFAULT, pf_plugin_init,
|
||||
pf_plugin_exit)
|
||||
@@ -63,6 +63,7 @@
|
||||
#include <ofono/types.h>
|
||||
#include <ofono/message-waiting.h>
|
||||
#include <ofono/oemraw.h>
|
||||
#include <ofono/stk.h>
|
||||
|
||||
#include "drivers/rilmodem/rilmodem.h"
|
||||
|
||||
@@ -97,10 +98,10 @@ struct ril_data {
|
||||
static guint mce_daemon_watch;
|
||||
static guint signal_watch;
|
||||
static DBusConnection *connection;
|
||||
gboolean reconnecting = FALSE;
|
||||
|
||||
static int ril_init(void);
|
||||
guint reconnect_timer;
|
||||
|
||||
static void ril_exit(void);
|
||||
static int send_get_sim_status(struct ofono_modem *modem);
|
||||
|
||||
static void ril_debug(const char *str, void *user_data)
|
||||
@@ -154,9 +155,12 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
|
||||
} else {
|
||||
ofono_warn("No SIM card present.");
|
||||
}
|
||||
// We cannot power on modem, but we need to get
|
||||
// certain interfaces up to be able to make emergency calls
|
||||
// in offline mode and without SIM
|
||||
|
||||
/*
|
||||
* We cannot power on modem, but we need to get
|
||||
* certain interfaces up to be able to make emergency calls
|
||||
* in offline mode and without SIM
|
||||
*/
|
||||
ofono_modem_set_powered(modem, TRUE);
|
||||
}
|
||||
}
|
||||
@@ -218,9 +222,6 @@ static void ril_remove(struct ofono_modem *modem)
|
||||
if (ril->timer_id > 0)
|
||||
g_source_remove(ril->timer_id);
|
||||
|
||||
if (reconnect_timer > 0)
|
||||
g_source_remove(ril->timer_id);
|
||||
|
||||
g_ril_unref(ril->modem);
|
||||
|
||||
g_free(ril);
|
||||
@@ -258,7 +259,7 @@ static void ril_post_sim(struct ofono_modem *modem)
|
||||
ril->modem);
|
||||
if (gc == NULL)
|
||||
break;
|
||||
|
||||
|
||||
ofono_gprs_add_context(gprs, gc);
|
||||
}
|
||||
}
|
||||
@@ -266,6 +267,8 @@ static void ril_post_sim(struct ofono_modem *modem)
|
||||
ofono_radio_settings_create(modem, 0, "rilmodem", ril->modem);
|
||||
ofono_phonebook_create(modem, 0, "rilmodem", ril->modem);
|
||||
ofono_call_forwarding_create(modem, 0, "rilmodem", ril->modem);
|
||||
ofono_call_barring_create(modem, 0, "rilmodem", ril->modem);
|
||||
ofono_stk_create(modem, 0, "rilmodem", ril->modem);
|
||||
|
||||
mw = ofono_message_waiting_create(modem);
|
||||
if (mw)
|
||||
@@ -282,7 +285,6 @@ static void ril_post_online(struct ofono_modem *modem)
|
||||
ofono_netreg_create(modem, 0, "rilmodem", ril->modem);
|
||||
ofono_ussd_create(modem, 0, "rilmodem", ril->modem);
|
||||
ofono_call_settings_create(modem, 0, "rilmodem", ril->modem);
|
||||
ofono_cbs_create(modem, 0, "rilmodem", ril->modem);
|
||||
ofono_oem_raw_create(modem, 0, "rilmodem", ril->modem);
|
||||
}
|
||||
|
||||
@@ -292,9 +294,8 @@ static void ril_set_online_cb(struct ril_msg *message, gpointer user_data)
|
||||
struct cb_data *cbd = user_data;
|
||||
ofono_modem_online_cb_t cb = cbd->cb;
|
||||
|
||||
if (message->error == RIL_E_SUCCESS) {
|
||||
if (message->error == RIL_E_SUCCESS)
|
||||
CALLBACK_WITH_SUCCESS(cb, cbd->data);
|
||||
}
|
||||
else
|
||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
||||
}
|
||||
@@ -406,25 +407,34 @@ static void ril_connected(struct ril_msg *message, gpointer user_data)
|
||||
|
||||
connection = ofono_dbus_get_connection();
|
||||
mce_daemon_watch = g_dbus_add_service_watch(connection, MCE_SERVICE,
|
||||
mce_connect, mce_disconnect, modem, NULL);
|
||||
mce_connect, mce_disconnect, modem, NULL);
|
||||
}
|
||||
|
||||
static gboolean ril_re_init(gpointer user_data)
|
||||
{
|
||||
ril_init();
|
||||
return FALSE;
|
||||
if (reconnecting) {
|
||||
ril_init();
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void gril_disconnected(gpointer user_data)
|
||||
{
|
||||
/* Signal clients modem going down */
|
||||
/* Signal clients modem going down
|
||||
*/
|
||||
struct ofono_modem *modem = user_data;
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
|
||||
if (modem) {
|
||||
if (ofono_modem_is_registered(modem)) {
|
||||
ofono_modem_remove(modem);
|
||||
mce_disconnect(conn, user_data);
|
||||
reconnect_timer = g_timeout_add_seconds(2, ril_re_init, NULL);
|
||||
}
|
||||
|
||||
if (!reconnecting) {
|
||||
reconnecting = TRUE;
|
||||
g_timeout_add_seconds(2, ril_re_init, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,10 +444,10 @@ void ril_switchUser()
|
||||
ofono_error("prctl(PR_SET_KEEPCAPS) failed:%s,%d",
|
||||
strerror(errno), errno);
|
||||
|
||||
if (setgid(RADIO_ID) < 0 )
|
||||
if (setgid(RADIO_ID) < 0)
|
||||
ofono_error("setgid(%d) failed:%s,%d",
|
||||
RADIO_ID, strerror(errno), errno);
|
||||
if (setuid(RADIO_ID) < 0 )
|
||||
if (setuid(RADIO_ID) < 0)
|
||||
ofono_error("setuid(%d) failed:%s,%d",
|
||||
RADIO_ID, strerror(errno), errno);
|
||||
|
||||
@@ -482,6 +492,8 @@ static int ril_enable(struct ofono_modem *modem)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
reconnecting = FALSE;
|
||||
|
||||
if (getenv("OFONO_RIL_TRACE"))
|
||||
g_ril_set_trace(ril->modem, TRUE);
|
||||
|
||||
@@ -577,23 +589,6 @@ static int ril_init(void)
|
||||
retval = ofono_modem_register(modem);
|
||||
DBG("ofono_modem_register returned: %d", retval);
|
||||
|
||||
/* kickstart the modem:
|
||||
* causes core modem code to call
|
||||
* - set_powered(TRUE) - which in turn
|
||||
* calls driver->enable()
|
||||
*
|
||||
* - driver->pre_sim()
|
||||
*
|
||||
* Could also be done via:
|
||||
*
|
||||
* - a DBus call to SetProperties w/"Powered=TRUE" *1
|
||||
* - sim_state_watch ( handles SIM removal? LOCKED states? **2
|
||||
* - ofono_modem_set_powered()
|
||||
*/
|
||||
ofono_modem_reset(modem);
|
||||
|
||||
reconnect_timer = 0;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ struct error_mapping_entry cme_errors_mapping[] = {
|
||||
};
|
||||
|
||||
static void append_variant(DBusMessageIter *iter,
|
||||
int type, void *value)
|
||||
int type, const void *value)
|
||||
{
|
||||
char sig[2];
|
||||
DBusMessageIter valueiter;
|
||||
@@ -65,7 +65,7 @@ static void append_variant(DBusMessageIter *iter,
|
||||
}
|
||||
|
||||
void ofono_dbus_dict_append(DBusMessageIter *dict,
|
||||
const char *key, int type, void *value)
|
||||
const char *key, int type, const void *value)
|
||||
{
|
||||
DBusMessageIter keyiter;
|
||||
|
||||
@@ -85,7 +85,8 @@ void ofono_dbus_dict_append(DBusMessageIter *dict,
|
||||
dbus_message_iter_close_container(dict, &keyiter);
|
||||
}
|
||||
|
||||
static void append_array_variant(DBusMessageIter *iter, int type, void *val)
|
||||
static void append_array_variant(DBusMessageIter *iter, int type,
|
||||
const void *val)
|
||||
{
|
||||
DBusMessageIter variant, array;
|
||||
char typesig[2];
|
||||
@@ -113,7 +114,7 @@ static void append_array_variant(DBusMessageIter *iter, int type, void *val)
|
||||
}
|
||||
|
||||
void ofono_dbus_dict_append_array(DBusMessageIter *dict, const char *key,
|
||||
int type, void *val)
|
||||
int type, const void *val)
|
||||
{
|
||||
DBusMessageIter entry;
|
||||
|
||||
@@ -127,7 +128,8 @@ void ofono_dbus_dict_append_array(DBusMessageIter *dict, const char *key,
|
||||
dbus_message_iter_close_container(dict, &entry);
|
||||
}
|
||||
|
||||
static void append_dict_variant(DBusMessageIter *iter, int type, void *val)
|
||||
static void append_dict_variant(DBusMessageIter *iter, int type,
|
||||
const void *val)
|
||||
{
|
||||
DBusMessageIter variant, array, entry;
|
||||
char typesig[5];
|
||||
@@ -182,7 +184,7 @@ static void append_dict_variant(DBusMessageIter *iter, int type, void *val)
|
||||
}
|
||||
|
||||
void ofono_dbus_dict_append_dict(DBusMessageIter *dict, const char *key,
|
||||
int type, void *val)
|
||||
int type, const void *val)
|
||||
{
|
||||
DBusMessageIter entry;
|
||||
|
||||
@@ -200,7 +202,7 @@ int ofono_dbus_signal_property_changed(DBusConnection *conn,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *name,
|
||||
int type, void *value)
|
||||
int type, const void *value)
|
||||
{
|
||||
DBusMessage *signal;
|
||||
DBusMessageIter iter;
|
||||
@@ -225,7 +227,7 @@ int ofono_dbus_signal_array_property_changed(DBusConnection *conn,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *name,
|
||||
int type, void *value)
|
||||
int type, const void *value)
|
||||
|
||||
{
|
||||
DBusMessage *signal;
|
||||
@@ -251,7 +253,7 @@ int ofono_dbus_signal_dict_property_changed(DBusConnection *conn,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *name,
|
||||
int type, void *value)
|
||||
int type, const void *value)
|
||||
|
||||
{
|
||||
DBusMessage *signal;
|
||||
|
||||
@@ -3016,14 +3016,56 @@ static void ofono_gprs_finish_register(struct ofono_gprs *gprs)
|
||||
__ofono_atom_register(gprs->atom, gprs_unregister);
|
||||
}
|
||||
|
||||
static gboolean mms_context_configured(struct ofono_gprs *gprs)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
for (l = gprs->contexts; l; l = l->next) {
|
||||
struct pri_context *ctx = l->data;
|
||||
|
||||
if (ctx->type == OFONO_GPRS_CONTEXT_TYPE_MMS)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void provision_mms_context(struct ofono_gprs *gprs, const char *mcc,
|
||||
const char *mnc, const char *spn)
|
||||
{
|
||||
struct ofono_gprs_provision_data *settings;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
if (__ofono_gprs_provision_get_settings(mcc, mnc, spn,
|
||||
&settings, &count) == FALSE) {
|
||||
ofono_warn("Provisioning failed");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (settings[i].type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
|
||||
provision_context(&settings[i], gprs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__ofono_gprs_provision_free_settings(settings, count);
|
||||
}
|
||||
|
||||
static void spn_read_cb(const char *spn, const char *dc, void *data)
|
||||
{
|
||||
struct ofono_gprs *gprs = data;
|
||||
struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
|
||||
struct ofono_sim *sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM, modem);
|
||||
|
||||
provision_contexts(gprs, ofono_sim_get_mcc(sim),
|
||||
if (gprs->contexts == NULL) {
|
||||
provision_contexts(gprs, ofono_sim_get_mcc(sim),
|
||||
ofono_sim_get_mnc(sim), spn);
|
||||
} else if (!mms_context_configured(gprs)) {
|
||||
provision_mms_context(gprs, ofono_sim_get_mcc(sim),
|
||||
ofono_sim_get_mnc(sim), spn);
|
||||
}
|
||||
|
||||
ofono_sim_remove_spn_watch(sim, &gprs->spn_watch);
|
||||
|
||||
@@ -3040,7 +3082,7 @@ void ofono_gprs_register(struct ofono_gprs *gprs)
|
||||
|
||||
gprs_load_settings(gprs, ofono_sim_get_imsi(sim));
|
||||
|
||||
if (gprs->contexts)
|
||||
if (mms_context_configured(gprs))
|
||||
goto finish;
|
||||
|
||||
ofono_sim_add_spn_watch(sim, &gprs->spn_watch, spn_read_cb, gprs, NULL);
|
||||
|
||||
@@ -2106,18 +2106,14 @@ void ofono_netreg_register(struct ofono_netreg *netreg)
|
||||
ofono_sim_add_spn_watch(netreg->sim, &netreg->spn_watch,
|
||||
spn_read_cb, netreg, NULL);
|
||||
|
||||
if (__ofono_sim_service_available(netreg->sim,
|
||||
SIM_UST_SERVICE_PROVIDER_DISPLAY_INFO,
|
||||
SIM_SST_SERVICE_PROVIDER_DISPLAY_INFO)) {
|
||||
ofono_sim_read(netreg->sim_context, SIM_EFSPDI_FILEID,
|
||||
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
|
||||
sim_spdi_read_cb, netreg);
|
||||
ofono_sim_read(netreg->sim_context, SIM_EFSPDI_FILEID,
|
||||
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
|
||||
sim_spdi_read_cb, netreg);
|
||||
|
||||
ofono_sim_add_file_watch(netreg->sim_context,
|
||||
SIM_EFSPDI_FILEID,
|
||||
sim_spdi_changed,
|
||||
netreg, NULL);
|
||||
}
|
||||
ofono_sim_add_file_watch(netreg->sim_context,
|
||||
SIM_EFSPDI_FILEID,
|
||||
sim_spdi_changed,
|
||||
netreg, NULL);
|
||||
}
|
||||
|
||||
__ofono_atom_register(netreg->atom, netreg_unregister);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
[Unit]
|
||||
Description=Telephony service
|
||||
After=syslog.target
|
||||
Requires=dbus.service
|
||||
After=dbus.service
|
||||
|
||||
[Service]
|
||||
Type=dbus
|
||||
|
||||
@@ -767,12 +767,14 @@ static char *sim_network_name_parse(const unsigned char *buffer, int length,
|
||||
gboolean *add_ci)
|
||||
{
|
||||
char *ret = NULL;
|
||||
unsigned char *endp;
|
||||
unsigned char dcs;
|
||||
int i;
|
||||
gboolean ci = FALSE;
|
||||
unsigned char *unpacked_buf;
|
||||
long num_char, written;
|
||||
int spare_bits;
|
||||
|
||||
if (length < 1)
|
||||
if (length < 2)
|
||||
return NULL;
|
||||
|
||||
dcs = *buffer++;
|
||||
@@ -787,11 +789,18 @@ static char *sim_network_name_parse(const unsigned char *buffer, int length,
|
||||
|
||||
switch (dcs & (7 << 4)) {
|
||||
case 0x00:
|
||||
endp = memchr(buffer, 0xff, length);
|
||||
if (endp)
|
||||
length = endp - buffer;
|
||||
ret = convert_gsm_to_utf8(buffer, length,
|
||||
NULL, NULL, 0xff);
|
||||
spare_bits = dcs & 0x07;
|
||||
num_char = (length * 8 - spare_bits) / 7;
|
||||
|
||||
unpacked_buf = unpack_7bit(buffer, length, 0, FALSE,
|
||||
num_char, &written, 0);
|
||||
if (unpacked_buf == NULL)
|
||||
break;
|
||||
|
||||
ret = convert_gsm_to_utf8(unpacked_buf, written, NULL, NULL, 0);
|
||||
|
||||
g_free(unpacked_buf);
|
||||
|
||||
break;
|
||||
case 0x10:
|
||||
if ((length % 2) == 1) {
|
||||
|
||||
@@ -737,6 +737,11 @@ static DBusMessage *stk_register_agent(DBusConnection *conn,
|
||||
if (stk->session_agent == NULL)
|
||||
stk->current_agent = stk->default_agent;
|
||||
|
||||
if (stk->driver && stk->driver->ready) {
|
||||
DBG("Report driver agent is ready");
|
||||
stk->driver->ready(stk);
|
||||
}
|
||||
|
||||
return dbus_message_new_method_return(msg);
|
||||
}
|
||||
|
||||
|
||||
@@ -2859,19 +2859,24 @@ static void read_sim_ecc_numbers(int id, void *userdata)
|
||||
ecc_g3_read_cb, vc);
|
||||
}
|
||||
|
||||
static void get_ecc_numbers(struct ofono_voicecall *vc)
|
||||
{
|
||||
if (vc->sim_context == NULL) {
|
||||
vc->sim_context = ofono_sim_context_create(vc->sim);
|
||||
ofono_sim_add_file_watch(vc->sim_context, SIM_EFECC_FILEID,
|
||||
read_sim_ecc_numbers, vc, NULL);
|
||||
}
|
||||
|
||||
read_sim_ecc_numbers(SIM_EFECC_FILEID, vc);
|
||||
}
|
||||
|
||||
static void sim_state_watch(enum ofono_sim_state new_state, void *user)
|
||||
{
|
||||
struct ofono_voicecall *vc = user;
|
||||
|
||||
switch (new_state) {
|
||||
case OFONO_SIM_STATE_INSERTED:
|
||||
if (vc->sim_context == NULL)
|
||||
vc->sim_context = ofono_sim_context_create(vc->sim);
|
||||
|
||||
read_sim_ecc_numbers(SIM_EFECC_FILEID, vc);
|
||||
|
||||
ofono_sim_add_file_watch(vc->sim_context, SIM_EFECC_FILEID,
|
||||
read_sim_ecc_numbers, vc, NULL);
|
||||
get_ecc_numbers(vc);
|
||||
break;
|
||||
case OFONO_SIM_STATE_NOT_PRESENT:
|
||||
case OFONO_SIM_STATE_RESETTING:
|
||||
@@ -2888,6 +2893,8 @@ static void sim_state_watch(enum ofono_sim_state new_state, void *user)
|
||||
voicecall_close_settings(vc);
|
||||
break;
|
||||
case OFONO_SIM_STATE_READY:
|
||||
get_ecc_numbers(vc);
|
||||
|
||||
voicecall_load_settings(vc);
|
||||
break;
|
||||
case OFONO_SIM_STATE_LOCKED_OUT:
|
||||
|
||||
@@ -63,6 +63,8 @@ if __name__ == "__main__":
|
||||
except dbus.DBusException, e:
|
||||
print "Unable to Disable All barrings: ", e
|
||||
sys.exit(1)
|
||||
print "Disabled all call barrings"
|
||||
sys.exit(0)
|
||||
elif (sys.argv[1] == 'passwd'):
|
||||
try:
|
||||
cb.ChangePassword(old_password, new_password)
|
||||
@@ -77,6 +79,8 @@ if __name__ == "__main__":
|
||||
except dbus.DBusException, e:
|
||||
print "Unable to set property: ", e
|
||||
sys.exit(1)
|
||||
print "Property set completed", property
|
||||
sys.exit(0)
|
||||
|
||||
canexit = True
|
||||
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import gobject
|
||||
import sys
|
||||
|
||||
import dbus
|
||||
import dbus.mainloop.glib
|
||||
|
||||
def print_usage():
|
||||
print "Usage: test-ss-control-cb <password>"
|
||||
sys.exit(1);
|
||||
|
||||
def property_changed(property, value):
|
||||
print "CallBarring property %s changed to %s" % (property, value)
|
||||
|
||||
@@ -15,6 +20,11 @@ def print_properties(cb):
|
||||
print "property %s, value: %s" % (p, properties[p])
|
||||
|
||||
if __name__ == "__main__":
|
||||
if (len(sys.argv) != 2):
|
||||
print_usage()
|
||||
|
||||
password = sys.argv[1]
|
||||
|
||||
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
||||
|
||||
bus = dbus.SystemBus()
|
||||
@@ -29,7 +39,7 @@ if __name__ == "__main__":
|
||||
|
||||
cb.connect_to_signal("PropertyChanged", property_changed)
|
||||
|
||||
ss = dbus.Interface(bus.get_object('org.ofono', modems[0]),
|
||||
ss = dbus.Interface(bus.get_object('org.ofono', modems[0][0]),
|
||||
'org.ofono.SupplementaryServices')
|
||||
|
||||
print_properties(cb)
|
||||
@@ -82,13 +92,19 @@ if __name__ == "__main__":
|
||||
print "Query All"
|
||||
print ss.Initiate("*#330#")
|
||||
|
||||
ss_string = "*33*" + password + "*11#"
|
||||
|
||||
print "Enable Barring for Outgoing International calls for Voice"
|
||||
print ss.Initiate("*33*3579*11#")
|
||||
print ss.Initiate(ss_string)
|
||||
|
||||
print_properties(cb)
|
||||
|
||||
ss_string = "#330*" + password + "#"
|
||||
|
||||
print "Disable All Barrings"
|
||||
print ss.Initiate("#330*3579#")
|
||||
print ss.Initiate(ss_string)
|
||||
|
||||
sys.exit(1);
|
||||
|
||||
mainloop = gobject.MainLoop()
|
||||
mainloop.run()
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
#
|
||||
# Do NOT Edit the Auto-generated Part!
|
||||
# Generated by: spectacle version 0.26
|
||||
#
|
||||
|
||||
Name: ofono
|
||||
|
||||
# >> macros
|
||||
# << macros
|
||||
|
||||
Summary: Open Source Telephony
|
||||
Version: 1.14
|
||||
Release: 1
|
||||
@@ -15,7 +7,6 @@ Group: Communications/Connectivity Adaptation
|
||||
License: GPLv2
|
||||
URL: http://ofono.org
|
||||
Source0: http://www.kernel.org/pub/linux/network/ofono/ofono-%{version}.tar.xz
|
||||
Source100: ofono.yaml
|
||||
Requires: dbus
|
||||
Requires: systemd
|
||||
Requires: ofono-configs
|
||||
@@ -27,6 +18,7 @@ BuildRequires: pkgconfig(dbus-1)
|
||||
BuildRequires: pkgconfig(libudev) >= 145
|
||||
BuildRequires: pkgconfig(bluez) >= 4.85
|
||||
BuildRequires: pkgconfig(mobile-broadband-provider-info)
|
||||
BuildRequires: pkgconfig(libwspcodec) >= 2.0
|
||||
BuildRequires: libtool
|
||||
BuildRequires: automake
|
||||
BuildRequires: autoconf
|
||||
@@ -66,14 +58,10 @@ This package provides default configs for ofono
|
||||
%prep
|
||||
%setup -q -n %{name}-%{version}/%{name}
|
||||
|
||||
# >> setup
|
||||
./bootstrap
|
||||
# << setup
|
||||
|
||||
%build
|
||||
# >> build pre
|
||||
autoreconf --force --install
|
||||
# << build pre
|
||||
|
||||
%configure --disable-static \
|
||||
--enable-dundee \
|
||||
@@ -82,35 +70,32 @@ autoreconf --force --install
|
||||
|
||||
make %{?jobs:-j%jobs}
|
||||
|
||||
# >> build post
|
||||
# << build post
|
||||
|
||||
%install
|
||||
rm -rf %{buildroot}
|
||||
# >> install pre
|
||||
# << install pre
|
||||
%make_install
|
||||
|
||||
# >> install post
|
||||
mkdir -p %{buildroot}/%{_sysconfdir}/ofono/push_forwarder.d
|
||||
mkdir -p %{buildroot}/%{_lib}/systemd/system/network.target.wants
|
||||
ln -s ../ofono.service %{buildroot}/%{_lib}/systemd/system/network.target.wants/ofono.service
|
||||
# << install post
|
||||
|
||||
%preun
|
||||
if [ "$1" -eq 0 ]; then
|
||||
systemctl stop ofono.service
|
||||
systemctl stop ofono.service ||:
|
||||
fi
|
||||
|
||||
%post
|
||||
systemctl daemon-reload
|
||||
systemctl reload-or-try-restart ofono.service
|
||||
systemctl daemon-reload ||:
|
||||
# Do not restart during update
|
||||
# We don't want to break anything during update
|
||||
# New daemon is taken in use after reboot
|
||||
# systemctl reload-or-try-restart ofono.service ||:
|
||||
|
||||
%postun
|
||||
systemctl daemon-reload
|
||||
systemctl daemon-reload ||:
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
# >> files
|
||||
%doc COPYING ChangeLog AUTHORS README
|
||||
%config(noreplace) %{_sysconfdir}/dbus-1/system.d/*.conf
|
||||
%{_sbindir}/*
|
||||
@@ -118,27 +103,21 @@ systemctl daemon-reload
|
||||
/%{_lib}/systemd/system/ofono.service
|
||||
/%{_lib}/systemd/system/dundee.service
|
||||
%dir %{_sysconfdir}/ofono/
|
||||
%dir %{_sysconfdir}/ofono/push_forwarder.d
|
||||
# This file is part of phonesim and not needed with ofono.
|
||||
%exclude %{_sysconfdir}/ofono/phonesim.conf
|
||||
%doc /usr/share/man/man8/ofonod.8.gz
|
||||
%dir %attr(775,radio,radio) /var/lib/ofono
|
||||
# << files
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root,-)
|
||||
%{_includedir}/ofono/
|
||||
%{_libdir}/pkgconfig/ofono.pc
|
||||
# >> files devel
|
||||
# << files devel
|
||||
|
||||
%files tests
|
||||
%defattr(-,root,root,-)
|
||||
%{_libdir}/%{name}/test/*
|
||||
# >> files tests
|
||||
# << files tests
|
||||
|
||||
%files configs-mer
|
||||
%defattr(-,root,root,-)
|
||||
%config /etc/ofono/ril_subscription.conf
|
||||
# >> files ofono-configs-mer
|
||||
# << files ofono-configs-mer
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
Name: ofono
|
||||
Summary: Open Source Telephony
|
||||
Description: Telephony stack
|
||||
Version: 1.14
|
||||
Release: 1
|
||||
Group: Communications/Connectivity Adaptation
|
||||
License: GPLv2
|
||||
URL: http://ofono.org
|
||||
Sources:
|
||||
- http://www.kernel.org/pub/linux/network/ofono/ofono-%{version}.tar.xz
|
||||
Requires:
|
||||
- dbus
|
||||
PkgBR:
|
||||
- libtool
|
||||
- automake
|
||||
- autoconf
|
||||
PkgConfigBR:
|
||||
- glib-2.0
|
||||
- dbus-1
|
||||
- libudev >= 145
|
||||
- bluez >= 4.85
|
||||
- mobile-broadband-provider-info
|
||||
SetupOptions: -q -n %{name}-%{version}/%{name}
|
||||
ConfigOptions:
|
||||
- --enable-dundee
|
||||
- --enable-test
|
||||
- --with-systemdunitdir="/%{_lib}/systemd/system"
|
||||
SubPackages:
|
||||
- Name: devel
|
||||
Summary: Headers for oFono
|
||||
Group: Development/Libraries
|
||||
Description: Development headers and libraries for oFono
|
||||
Files:
|
||||
- "%{_includedir}/ofono/"
|
||||
- "%{_libdir}/pkgconfig/ofono.pc"
|
||||
|
||||
- Name: tests
|
||||
Summary: Test Scripts for oFono
|
||||
Group: Development/Libraries
|
||||
Description: Scripts for testing oFono and its functionality
|
||||
Obsoletes:
|
||||
- "ofono-test < 1.0"
|
||||
Provides:
|
||||
- "ofono-test >= 1.0"
|
||||
Requires:
|
||||
- dbus-python
|
||||
- pygobject2
|
||||
Files:
|
||||
- "%{_libdir}/%{name}/test/*"
|
||||
|
||||
Reference in New Issue
Block a user