Compare commits

...

23 Commits

Author SHA1 Message Date
Tommi Kenakkala
571d440c14 Merge pull request #220 from jpoutiai/master
[SRC] fix incorrect CF state after CFU erasure
2014-05-05 08:17:19 +03:00
Jarko Poutiainen
25fc82a073 [SRC] fix incorrect CF state after CFU erasure
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-04-30 14:41:45 +03:00
Tommi Kenakkala
e50518effa Merge pull request #219 from tkenakka/conffix
[rilmodem] Fix ratmode bad conf file handling
2014-04-30 09:44:16 +03:00
Tommi Kenakkala
84e1386978 [rilmodem] Fix ratmode bad conf file handling
g_key_file_load_from_file loads also dirs, if a bad file/dir was
picked up first then logic deduced wrong the need for ratmode reconfig.

Signed-off-by: Tommi Kenakkala <tommi.kenakkala@oss.tieto.com>
2014-04-30 09:35:52 +03:00
Slava Monich
0cdd483894 Merge pull request #218 from monich/leaks
[rilmodem] Plugged a few memory leaks
2014-04-29 16:14:44 +03:00
Slava Monich
7dbeba0e83 Merge pull request #217 from monich/simsms
[push-forwarder] Fixed sim/sms watch id mixup
2014-04-29 16:14:01 +03:00
Slava Monich
d7cf952a16 [rilmodem] Plugged a few memory leaks 2014-04-29 15:37:14 +03:00
Slava Monich
e8379285b3 [push-forwarder] Fixed sim/sms watch id mixup 2014-04-29 14:55:01 +03:00
Tommi Kenakkala
f9a91c8453 Merge pull request #216 from jpoutiai/master
Disable stack trace from command line
2014-04-28 15:54:20 +03:00
Jarko Poutiainen
882f75b500 [SRC] Disable stack trace from command line ofono.service.in
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-04-28 15:32:33 +03:00
Jarko Poutiainen
5b6ddee098 [SRC] Disable stack trace from command line ofono.h
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-04-28 12:57:05 +03:00
Jarko Poutiainen
5cbf0de041 [SRC] Disable stack trace from command line main.c
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-04-28 12:56:45 +03:00
Jarko Poutiainen
8ce12b2232 [SRC] Disable stack trace from command line log.c
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-04-28 12:56:21 +03:00
Jarko Poutiainen
62d42e0407 Merge pull request #215 from lpotter/master
[rilmodem] Fix gprs state after offline mode.
2014-04-28 11:09:52 +03:00
Lorn Potter
5053a342e7 [rilmodem] Fix gprs state after offline mode. 2014-04-23 10:54:57 +10:00
Martti Piirainen
5c53260938 Merge pull request #213 from marttipiirainen/mbpi3
Take Service Provider Name into account in MBPI provisioning
2014-04-22 15:11:36 +03:00
Martti Piirainen
e3e691fb48 Merge pull request #214 from marttipiirainen/ringback
[voicecall] Inform client when local ringback tone is needed
2014-04-22 13:54:13 +03:00
Martti Piirainen
8fa99a07e8 [provision] Take SPN into account when finding APNs 2014-04-17 08:14:08 +03:00
Slava Monich
23f92a5b3e [mbpi] Parse gsm provider name 2014-04-17 07:32:36 +03:00
Slava Monich
94494f3a63 [provision] Fixed memory leak 2014-04-16 16:07:40 +03:00
Martti Piirainen
098b3d4a64 [unit] Add provisioning tests 2014-04-16 16:07:29 +03:00
Martti Piirainen
cfeb58f2a8 [provision] Expose provision_get_settings() in header (for testability) 2014-04-16 16:07:21 +03:00
Martti Piirainen
5f821b4a9a [voicecall] Inform client when local ringback tone is needed
In some networks, MO calls do not get the "alerting" tone in-band, so the device needs to play one locally.

This commit adds a "voice call agent" API. It currently contains only the ringback tone notification, but can be extended later.
2014-04-16 15:31:45 +03:00
28 changed files with 687 additions and 73 deletions

View File

@@ -514,7 +514,7 @@ if PROVISION
builtin_sources += plugins/mbpi.h plugins/mbpi.c
builtin_modules += provision
builtin_sources += plugins/provision.c
builtin_sources += plugins/provision.h plugins/provision.c
builtin_modules += cdma_provision
builtin_sources += plugins/cdma-provision.c
@@ -587,7 +587,7 @@ src_ofonod_SOURCES = $(builtin_sources) src/ofono.ver \
src/cdma-provision.c src/handsfree.c \
src/handsfree-audio.c src/bluetooth.h \
src/hfp.h src/sim-mnclength.c src/oemraw.c \
src/siri.c
src/siri.c src/voicecallagent.c
src_ofonod_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
@GLIB_LIBS@ @DBUS_LIBS@ -ldl
@@ -726,7 +726,8 @@ test_scripts = test/backtrace \
test/hangup-multiparty \
test/hangup-call \
test/display-icon \
test/set-msisdn
test/set-msisdn \
test/test-voicecallagent
if TEST
testdir = $(pkglibdir)/test
@@ -747,7 +748,8 @@ unit_tests = unit/test-common unit/test-util unit/test-idmap \
unit/test-grilrequest \
unit/test-grilreply \
unit/test-grilunsol \
unit/test-sms unit/test-cdmasms
unit/test-sms unit/test-cdmasms \
unit/test-provision
noinst_PROGRAMS = $(unit_tests) \
unit/test-sms-root unit/test-mux unit/test-caif
@@ -814,6 +816,13 @@ unit_test_grilunsol_SOURCES = unit/test-grilunsol.c $(gril_sources) \
unit_test_grilunsol_LDADD = @GLIB_LIBS@ -ldl
unit_objects += $(unit_test_grilunsol_OBJECTS)
unit_test_provision_SOURCES = unit/test-provision.c \
plugins/provision.h plugins/provision.c \
plugins/mbpi.c src/gprs-provision.c \
src/log.c
unit_test_provision_LDADD = @GLIB_LIBS@ -ldl
unit_objects += $(unit_test_provision_OBJECTS)
TESTS = $(unit_tests)
if TOOLS

View File

@@ -198,6 +198,25 @@ Methods dict GetProperties()
[service].Error.InvalidFormat
[service].Error.Failed
void RegisterVoicecallAgent(object path)
Registers an agent which will be called whenever a
specific voice call related event requiring a client
action occurs. Currently, the only such action is
playing a ringback tone locally.
Possible Errors: [service].Error.InProgress
[service].Error.InvalidArguments
[service].Error.InvalidFormat
[service].Error.Failed
void UnregisterVoicecallAgent(object path)
Unregisters an agent.
Possible Errors: [service].Error.InvalidArguments
[service].Error.Failed
Signals CallAdded(object path, dict properties)
Signal that is sent when a new call is added. It
@@ -257,3 +276,26 @@ Properties array{string} EmergencyNumbers [readonly]
of numbers provided by the specification and any
extra numbers provisioned by the carrier on the
SIM.
VoiceCallAgent Hierarchy
========================
Service unique name
Interface org.ofono.VoiceCallAgent
Object path freely definable
Methods void RingbackTone(boolean playTone)
Requests the client to generate an alerting tone locally
(3GPP 24.008; 5.2.1.5). This can happen when an outgoing
voice call is made and network is not providing the
alerting tone. Value 0 stands for "stop playing ringback
tone" and 1 for "start playing ringback tone".
void Release() [noreply]
Agent is being released, possibly because of oFono
terminating, voicecall interface is being torn down or
modem is switched off. No UnregisterVoicecallAgent
call is needed.

View File

@@ -98,6 +98,7 @@ static void query_revision_cb(struct ril_msg *message, gpointer user_data)
revision = parcel_r_string(&rilp);
cb(&error, revision, cbd->data);
g_free(revision);
}
static void ril_query_revision(struct ofono_devinfo *info,
@@ -137,10 +138,10 @@ static void query_serial_cb(struct ril_msg *message, gpointer user_data)
}
ril_util_init_parcel(message, &rilp);
imei = parcel_r_string(&rilp);
cb(&error, imei, cbd->data);
g_free(imei);
}
static void ril_query_serial(struct ofono_devinfo *info,

View File

@@ -237,7 +237,7 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
ofono_gprs_detached_notify(gprs);
gd->notified = FALSE;
gd->ofono_attached = FALSE;
} else if (gd->notified && check_if_really_searching()) {
} else if (gd->notified && check_if_ok_to_attach()) {
DBG("hide the searching state");
status = NETWORK_REGISTRATION_STATUS_REGISTERED;
ofono_gprs_status_notify(gprs, status);

View File

@@ -573,11 +573,13 @@ error:
ofono_error("Unable to notify ofono about nitz");
}
gboolean check_if_really_searching()
gboolean check_if_ok_to_attach()
{
int status = NETWORK_REGISTRATION_STATUS_SEARCHING;
status = ofono_netreg_get_status(current_netreg);
if (status == NETWORK_REGISTRATION_STATUS_SEARCHING)
if (status == NETWORK_REGISTRATION_STATUS_SEARCHING
|| status == NETWORK_REGISTRATION_STATUS_ROAMING
|| status == NETWORK_REGISTRATION_STATUS_REGISTERED)
return TRUE;
return FALSE;
}

View File

@@ -75,7 +75,7 @@ static void ril_set_rat_mode(struct ofono_radio_settings *rs,
int pref = rd->ratmode;
int ret = 0;
ofono_info("setting rat mode");
ofono_info("setting rat mode:%d", mode);
parcel_init(&rilp);
@@ -209,7 +209,6 @@ static gboolean ril_get_net_config(struct radio_data *rsd)
rsd->ratmode = PREF_NET_TYPE_GSM_WCDMA_AUTO;
GDir *config_dir;
const gchar *config_file;
char *path;
gsize length;
gchar **codes = NULL;
int i;
@@ -225,11 +224,14 @@ static gboolean ril_get_net_config(struct radio_data *rsd)
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);
char *path = g_strconcat(RIL_CONFIG_DIR "/", config_file, NULL);
DBG("Rilconfig handling %s", path);
gboolean ok = g_key_file_load_from_file(keyfile, path, 0, &err);
if (!g_key_file_load_from_file(keyfile, path, 0, &err)) {
g_free(path);
if (!ok) {
g_error_free(err);
needsconfig = TRUE;
DBG("Rilconfig file skipped");
continue;
}
@@ -258,6 +260,7 @@ static gboolean ril_get_net_config(struct radio_data *rsd)
}
g_key_file_free(keyfile);
g_dir_close(config_dir);
/* Then we need to check if it already set */

View File

@@ -123,7 +123,7 @@ struct ofono_sim *get_sim();
gint check_if_really_roaming(gint status);
gboolean check_if_really_searching();
gboolean check_if_ok_to_attach();
void ril_util_free_sim_apps(struct sim_app **apps, guint num_apps);

View File

@@ -1133,6 +1133,8 @@ static void ril_sim_remove(struct ofono_sim *sim)
if (sd->idle_id > 0)
g_source_remove(sd->idle_id);
g_free(sd->aid_str);
g_free(sd->app_str);
g_ril_unref(sd->ril);
g_free(sd);
}

View File

@@ -275,6 +275,7 @@ void ril_stk_set_lang()
setenv("LANG", pch + strlen(CFG_LANG), 1);
DBG("LANG %s", getenv("LANG"));
}
g_free(contents);
}
}

View File

@@ -4,7 +4,7 @@
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2012 Canonical Ltd.
* Copyright (C) 2013 Jolla Ltd.
* 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
@@ -769,6 +769,23 @@ static gboolean enable_supp_svc(gpointer user_data)
return FALSE;
}
static void ril_ringback_tone_notify(struct ril_msg *message,
gpointer user_data)
{
struct parcel rilp;
struct ofono_voicecall *vc = user_data;
gboolean playTone = FALSE;
ril_util_init_parcel(message, &rilp);
if (message->req == RIL_UNSOL_RINGBACK_TONE) {
if (parcel_r_int32(&rilp) > 0)
playTone = parcel_r_int32(&rilp);
DBG("play ringback tone: %d", playTone);
ofono_voicecall_ringback_tone_notify(vc, playTone);
}
}
static gboolean ril_delayed_register(gpointer user_data)
{
struct ofono_voicecall *vc = user_data;
@@ -789,6 +806,10 @@ static gboolean ril_delayed_register(gpointer user_data)
g_ril_register(vd->ril, RIL_UNSOL_SUPP_SVC_NOTIFICATION,
ril_ss_notify, vc);
/* Register for ringback tone notifications */
g_ril_register(vd->ril, RIL_UNSOL_RINGBACK_TONE,
ril_ringback_tone_notify, vc);
/* request supplementary service notifications*/
enable_supp_svc(vc);
@@ -845,6 +866,7 @@ static void ril_voicecall_remove(struct ofono_voicecall *vc)
if (vd->timer_id > 0)
g_source_remove(vd->timer_id);
g_free(vd->tone_queue);
g_ril_unref(vd->ril);
g_free(vd);
}

View File

@@ -31,6 +31,7 @@ extern "C" {
struct ofono_gprs_provision_data {
enum ofono_gprs_context_type type;
enum ofono_gprs_proto proto;
char *provider_name;
char *name;
char *apn;
char *username;

View File

@@ -3,6 +3,7 @@
* 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
@@ -171,6 +172,9 @@ void ofono_voicecall_ssn_mt_notify(struct ofono_voicecall *vc, unsigned int id,
int code, int index,
const struct ofono_phone_number *ph);
void ofono_voicecall_ringback_tone_notify(struct ofono_voicecall *vc,
const ofono_bool_t playTone);
#ifdef __cplusplus
}
#endif

View File

@@ -53,6 +53,7 @@ enum MBPI_ERROR {
struct gsm_data {
const char *match_mcc;
const char *match_mnc;
char *provider_name;
GSList *apns;
gboolean match_found;
gboolean allow_duplicates;
@@ -84,6 +85,7 @@ static GQuark mbpi_error_quark(void)
void mbpi_ap_free(struct ofono_gprs_provision_data *ap)
{
g_free(ap->provider_name);
g_free(ap->name);
g_free(ap->apn);
g_free(ap->username);
@@ -117,6 +119,7 @@ static void text_handler(GMarkupParseContext *context,
{
char **string = userdata;
g_free(*string);
*string = g_strndup(text, text_len);
}
@@ -288,6 +291,7 @@ static void apn_handler(GMarkupParseContext *context, struct gsm_data *gsm,
}
ap = g_new0(struct ofono_gprs_provision_data, 1);
ap->provider_name = g_strdup(gsm->provider_name);
ap->apn = g_strdup(apn);
ap->type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
ap->proto = OFONO_GPRS_PROTO_IP;
@@ -454,6 +458,44 @@ static const GMarkupParser provider_parser = {
NULL,
};
static void gsm_provider_start(GMarkupParseContext *context,
const gchar *element_name,
const gchar **atribute_names,
const gchar **attribute_values,
gpointer userdata, GError **error)
{
struct gsm_data *gsm = userdata;
if (g_str_equal(element_name, "name")) {
g_free(gsm->provider_name);
gsm->provider_name = NULL;
g_markup_parse_context_push(context, &text_parser,
&gsm->provider_name);
} else if (g_str_equal(element_name, "gsm")) {
gsm->match_found = FALSE;
g_markup_parse_context_push(context, &gsm_parser, gsm);
} else if (g_str_equal(element_name, "cdma"))
g_markup_parse_context_push(context, &skip_parser, NULL);
}
static void gsm_provider_end(GMarkupParseContext *context,
const gchar *element_name,
gpointer userdata, GError **error)
{
if (g_str_equal(element_name, "name") ||
g_str_equal(element_name, "gsm") ||
g_str_equal(element_name, "cdma"))
g_markup_parse_context_pop(context);
}
static const GMarkupParser gsm_provider_parser = {
gsm_provider_start,
gsm_provider_end,
NULL,
NULL,
NULL,
};
static void toplevel_gsm_start(GMarkupParseContext *context,
const gchar *element_name,
const gchar **atribute_names,
@@ -462,19 +504,15 @@ static void toplevel_gsm_start(GMarkupParseContext *context,
{
struct gsm_data *gsm = userdata;
if (g_str_equal(element_name, "gsm")) {
gsm->match_found = FALSE;
g_markup_parse_context_push(context, &gsm_parser, gsm);
} else if (g_str_equal(element_name, "cdma"))
g_markup_parse_context_push(context, &skip_parser, NULL);
if (g_str_equal(element_name, "provider"))
g_markup_parse_context_push(context, &gsm_provider_parser, gsm);
}
static void toplevel_gsm_end(GMarkupParseContext *context,
const gchar *element_name,
gpointer userdata, GError **error)
{
if (g_str_equal(element_name, "gsm") ||
g_str_equal(element_name, "cdma"))
if (g_str_equal(element_name, "provider"))
g_markup_parse_context_pop(context);
}
@@ -591,6 +629,7 @@ GSList *mbpi_lookup_apn(const char *mcc, const char *mnc,
gsm.apns = NULL;
}
g_free(gsm.provider_name);
return gsm.apns;
}

View File

@@ -24,6 +24,7 @@
#include <config.h>
#endif
#define _GNU_SOURCE
#include <errno.h>
#include <string.h>
@@ -36,57 +37,102 @@
#include <ofono/modem.h>
#include <ofono/gprs-provision.h>
#include "provision.h"
#include "mbpi.h"
/* Returns the list containing exactly one INTERNET and one MMS access point */
static GSList *provision_normalize_apn_list(GSList *apns)
static GSList *provision_normalize_apn_list(GSList *apns, const char* spn)
{
struct ofono_gprs_provision_data *internet = NULL;
struct ofono_gprs_provision_data *mms = NULL;
GSList *l = apns;
struct ofono_gprs_provision_data *best_internet = NULL;
struct ofono_gprs_provision_data *best_mms = NULL;
struct ofono_gprs_provision_data *second_best_internet = NULL;
struct ofono_gprs_provision_data *second_best_mms = NULL;
GSList *best_apns = NULL;
GSList *l;
/* 1. save the first found internet APN and the first MMS APN */
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);
if (ap->type == OFONO_GPRS_CONTEXT_TYPE_INTERNET
&& !best_internet) {
best_internet = ap;
} else if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS
&& !best_mms) {
best_mms = ap;
}
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);
/*
* 2. if there is an SPN given, save the first internet APN and the
* first MMS APN matching the SPN (partially, case-insensitively)
* */
if (spn) {
second_best_internet = best_internet;
best_internet = NULL;
second_best_mms = best_mms;
best_mms = NULL;
l = apns;
while (l != NULL) {
GSList *next = l->next;
struct ofono_gprs_provision_data *ap = l->data;
if ((ap->provider_name && strcasestr(ap->provider_name, spn))
|| (ap->name && strcasestr(ap->name, spn))
|| (ap->apn && strcasestr(ap->apn, spn))) {
if (ap->type == OFONO_GPRS_CONTEXT_TYPE_INTERNET
&& !best_internet) {
best_internet = ap;
} else if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS
&& !best_mms) {
best_mms = ap;
}
}
l = next;
}
/* no better match found */
if (!best_internet)
best_internet = second_best_internet;
if (!best_mms)
best_mms = second_best_mms;
}
/* 3. if none found yet, create APNs with default values */
if (!best_internet) {
best_internet = g_try_new0(struct ofono_gprs_provision_data, 1);
if (best_internet) {
best_internet->type =
OFONO_GPRS_CONTEXT_TYPE_INTERNET;
best_internet->name =
g_strdup("Internet");
best_internet->apn =
g_strdup("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);
if (!best_mms) {
best_mms = g_try_new0(struct ofono_gprs_provision_data, 1);
if (best_mms) {
best_mms->type =
OFONO_GPRS_CONTEXT_TYPE_MMS;
best_mms->name =
g_strdup("MMS");
best_mms->apn =
g_strdup("mms");
}
}
return apns;
best_apns = g_slist_append(best_apns, best_internet);
best_apns = g_slist_append(best_apns, best_mms);
return best_apns;
}
static int provision_get_settings(const char *mcc, const char *mnc,
int provision_get_settings(const char *mcc, const char *mnc,
const char *spn,
struct ofono_gprs_provision_data **settings,
int *count)
@@ -97,7 +143,7 @@ static int provision_get_settings(const char *mcc, const char *mnc,
int ap_count;
int i;
DBG("Provisioning for MCC %s, MNC %s, SPN '%s'", mcc, mnc, spn);
ofono_info("Provisioning for MCC %s, MNC %s, SPN '%s'", mcc, mnc, spn);
/*
* Passing FALSE to mbpi_lookup_apn() would return
@@ -109,13 +155,14 @@ static int provision_get_settings(const char *mcc, const char *mnc,
g_error_free(error);
}
apns = provision_normalize_apn_list(apns);
ofono_info("Found %d APs in MBPI", g_slist_length(apns));
apns = provision_normalize_apn_list(apns, spn);
if (apns == NULL)
return -ENOENT;
ap_count = g_slist_length(apns);
DBG("Found %d APs", ap_count);
ofono_info("Provisioning %d APs", ap_count);
*settings = g_try_new0(struct ofono_gprs_provision_data, ap_count);
if (*settings == NULL) {
@@ -134,11 +181,11 @@ 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;
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);
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);
memcpy(*settings + i, ap,
sizeof(struct ofono_gprs_provision_data));

28
ofono/plugins/provision.h Normal file
View File

@@ -0,0 +1,28 @@
/*
*
* oFono - Open Source Telephony
*
* Copyright (C) 2014 Jolla. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
struct ofono_gprs_provision_data;
int provision_get_settings(const char *mcc, const char *mnc,
const char *spn,
struct ofono_gprs_provision_data **settings,
int *count);

View File

@@ -282,10 +282,10 @@ static void pf_modem_watch(struct ofono_modem *modem,
return;
pm->modem = modem;
pm->sim_watch_id = __ofono_modem_add_atom_watch(modem,
pm->sms_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,
pm->sim_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);

View File

@@ -713,8 +713,12 @@ static DBusMessage *set_property_request(struct ofono_call_forwarding *cf,
if (ph->number[0] != '\0')
cf->driver->registration(cf, type, cls, ph, timeout,
set_property_callback, cf);
else
else {
if (cf->query_next == CALL_FORWARDING_TYPE_UNCONDITIONAL)
cf->query_end = CALL_FORWARDING_TYPE_NOT_REACHABLE;
cf->driver->erasure(cf, type, cls, set_property_callback, cf);
}
return NULL;
}

View File

@@ -289,7 +289,8 @@ void __ofono_log_enable(struct ofono_debug_desc *start,
}
int __ofono_log_init(const char *program, const char *debug,
ofono_bool_t detach)
ofono_bool_t detach,
ofono_bool_t backtrace)
{
static char path[PATH_MAX];
int option = LOG_NDELAY | LOG_PID;
@@ -305,7 +306,8 @@ int __ofono_log_init(const char *program, const char *debug,
if (detach == FALSE)
option |= LOG_PERROR;
signal_setup(signal_handler);
if (backtrace == TRUE)
signal_setup(signal_handler);
openlog(basename(program), option, LOG_DAEMON);
@@ -314,13 +316,14 @@ int __ofono_log_init(const char *program, const char *debug,
return 0;
}
void __ofono_log_cleanup(void)
void __ofono_log_cleanup(ofono_bool_t backtrace)
{
syslog(LOG_INFO, "Exit");
closelog();
signal_setup(SIG_DFL);
if (backtrace == TRUE)
signal_setup(SIG_DFL);
g_strfreev(enabled);
}

View File

@@ -133,6 +133,7 @@ static gchar *option_plugin = NULL;
static gchar *option_noplugin = NULL;
static gboolean option_detach = TRUE;
static gboolean option_version = FALSE;
static gboolean option_backtrace = TRUE;
static gboolean parse_debug(const char *key, const char *value,
gpointer user_data, GError **error)
@@ -158,6 +159,9 @@ static GOptionEntry options[] = {
"Don't run as daemon in background" },
{ "version", 'v', 0, G_OPTION_ARG_NONE, &option_version,
"Show version information and exit" },
{ "nobacktrace", 0, G_OPTION_FLAG_REVERSE,
G_OPTION_ARG_NONE, &option_backtrace,
"Don't print out backtrace information" },
{ NULL },
};
@@ -213,7 +217,8 @@ int main(int argc, char **argv)
signal = setup_signalfd();
__ofono_log_init(argv[0], option_debug, option_detach);
__ofono_log_init(argv[0], option_debug, option_detach,
option_backtrace);
dbus_error_init(&error);
@@ -264,7 +269,7 @@ cleanup:
g_main_loop_unref(event_loop);
__ofono_log_cleanup();
__ofono_log_cleanup(option_backtrace);
return 0;
}

View File

@@ -15,6 +15,7 @@
<allow send_interface="org.ofono.SmartMessagingAgent"/>
<allow send_interface="org.ofono.PositioningRequestAgent"/>
<allow send_interface="org.ofono.HandsfreeAudioAgent"/>
<allow send_interface="org.ofono.VoiceCallAgent"/>
</policy>
<policy user="radio">
@@ -25,6 +26,7 @@
<allow send_interface="org.ofono.SmartMessagingAgent"/>
<allow send_interface="org.ofono.PositioningRequestAgent"/>
<allow send_interface="org.ofono.HandsfreeAudioAgent"/>
<allow send_interface="org.ofono.VoiceCallAgent"/>
</policy>
<policy at_console="true">

View File

@@ -38,8 +38,9 @@ void __ofono_modem_shutdown(void);
#include <ofono/log.h>
int __ofono_log_init(const char *program, const char *debug,
ofono_bool_t detach);
void __ofono_log_cleanup(void);
ofono_bool_t detach,
ofono_bool_t backtrace);
void __ofono_log_cleanup(ofono_bool_t backtrace);
void __ofono_log_enable(struct ofono_debug_desc *start,
struct ofono_debug_desc *stop);

View File

@@ -8,7 +8,7 @@ Type=dbus
BusName=org.ofono
User=root
EnvironmentFile=-/var/lib/environment/ofono/*.conf
ExecStart=@prefix@/sbin/ofonod -n $OFONO_ARGS
ExecStart=@prefix@/sbin/ofonod -n --nobacktrace $OFONO_ARGS
StandardError=null
Restart=always
RestartSec=3

View File

@@ -3,6 +3,7 @@
* 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
@@ -38,6 +39,7 @@
#include "simutil.h"
#include "smsutil.h"
#include "storage.h"
#include "voicecallagent.h"
#define MAX_VOICE_CALLS 16
@@ -75,6 +77,7 @@ struct ofono_voicecall {
ofono_voicecall_cb_t release_queue_done_cb;
struct ofono_emulator *pending_em;
unsigned int pending_id;
struct voicecall_agent *vc_agent;
};
struct voicecall {
@@ -2140,6 +2143,72 @@ static DBusMessage *manager_get_calls(DBusConnection *conn,
return reply;
}
static void voicecall_agent_notify(gpointer user_data)
{
struct ofono_voicecall *vc = user_data;
vc->vc_agent = NULL;
}
static DBusMessage *voicecall_register_agent(DBusConnection *conn,
DBusMessage *msg, void *data)
{
struct ofono_voicecall *vc = data;
const char *agent_path;
if (vc->vc_agent)
return __ofono_error_busy(msg);
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH,
&agent_path, DBUS_TYPE_INVALID) == FALSE)
return __ofono_error_invalid_args(msg);
if (!__ofono_dbus_valid_object_path(agent_path))
return __ofono_error_invalid_format(msg);
vc->vc_agent = voicecall_agent_new(agent_path,
dbus_message_get_sender(msg));
if (vc->vc_agent == NULL)
return __ofono_error_failed(msg);
voicecall_agent_set_removed_notify(vc->vc_agent,
voicecall_agent_notify, vc);
return dbus_message_new_method_return(msg);
}
static DBusMessage *voicecall_unregister_agent(DBusConnection *conn,
DBusMessage *msg, void *data)
{
struct ofono_voicecall *vc = data;
const char *agent_path;
const char *agent_bus = dbus_message_get_sender(msg);
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &agent_path,
DBUS_TYPE_INVALID) == FALSE)
return __ofono_error_invalid_args(msg);
if (vc->vc_agent == NULL)
return __ofono_error_failed(msg);
if (!voicecall_agent_matches(vc->vc_agent, agent_path, agent_bus))
return __ofono_error_access_denied(msg);
if (vc->vc_agent) {
voicecall_agent_free(vc->vc_agent);
vc->vc_agent = NULL;
}
return dbus_message_new_method_return(msg);
}
void ofono_voicecall_ringback_tone_notify(struct ofono_voicecall *vc,
const ofono_bool_t playTone)
{
if (vc->vc_agent)
voicecall_agent_ringback_tone(vc->vc_agent, playTone);
}
static const GDBusMethodTable manager_methods[] = {
{ GDBUS_METHOD("GetProperties",
NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
@@ -2172,6 +2241,12 @@ static const GDBusMethodTable manager_methods[] = {
{ GDBUS_METHOD("GetCalls",
NULL, GDBUS_ARGS({ "calls_with_properties", "a(oa{sv})" }),
manager_get_calls) },
{ GDBUS_ASYNC_METHOD("RegisterVoicecallAgent",
GDBUS_ARGS({ "path", "o" }), NULL,
voicecall_register_agent) },
{ GDBUS_ASYNC_METHOD("UnregisterVoicecallAgent",
GDBUS_ARGS({ "path", "o" }), NULL,
voicecall_unregister_agent) },
{ }
};
@@ -2744,6 +2819,11 @@ static void voicecall_unregister(struct ofono_atom *atom)
voicecall_close_settings(vc);
if (vc->vc_agent) {
voicecall_agent_free(vc->vc_agent);
vc->vc_agent = 0;
}
if (vc->sim_state_watch) {
ofono_sim_remove_state_watch(vc->sim, vc->sim_state_watch);
vc->sim_state_watch = 0;

131
ofono/src/voicecallagent.c Normal file
View File

@@ -0,0 +1,131 @@
/*
*
* oFono - Open Source Telephony
*
* 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
*
*/
#include <glib.h>
#include <gdbus.h>
#include "ofono.h"
#include "voicecallagent.h"
#define OFONO_VOICECALL_AGENT_INTERFACE "org.ofono.VoiceCallAgent"
struct voicecall_agent {
char *path; /* Agent Path */
char *bus; /* Agent bus */
guint disconnect_watch; /* DBus disconnect watch */
ofono_destroy_func removed_cb;
void *removed_data;
};
void voicecall_agent_ringback_tone(struct voicecall_agent *agent,
const ofono_bool_t playTone)
{
DBusConnection *conn = ofono_dbus_get_connection();
DBusMessage *message = dbus_message_new_method_call(
agent->bus, agent->path,
OFONO_VOICECALL_AGENT_INTERFACE,
"RingbackTone");
if (message == NULL)
return;
if (!dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &playTone,
DBUS_TYPE_INVALID))
return;
dbus_message_set_no_reply(message, TRUE);
g_dbus_send_message(conn, message);
}
void voicecall_agent_send_release(struct voicecall_agent *agent)
{
DBusConnection *conn = ofono_dbus_get_connection();
DBusMessage *message = dbus_message_new_method_call(
agent->bus, agent->path,
OFONO_VOICECALL_AGENT_INTERFACE,
"Release");
if (message == NULL)
return;
dbus_message_set_no_reply(message, TRUE);
g_dbus_send_message(conn, message);
}
void voicecall_agent_set_removed_notify(struct voicecall_agent *agent,
ofono_destroy_func destroy,
void *user_data)
{
agent->removed_cb = destroy;
agent->removed_data = user_data; /* voicecall atom (not owned) */
}
void voicecall_agent_free(struct voicecall_agent *agent)
{
DBusConnection *conn = ofono_dbus_get_connection();
if (agent->disconnect_watch) {
voicecall_agent_send_release(agent);
g_dbus_remove_watch(conn, agent->disconnect_watch);
agent->disconnect_watch = 0;
}
if (agent->removed_cb)
agent->removed_cb(agent->removed_data);
g_free(agent->path);
g_free(agent->bus);
g_free(agent);
}
ofono_bool_t voicecall_agent_matches(struct voicecall_agent *agent,
const char *path, const char *sender)
{
return g_str_equal(agent->path, path) &&
g_str_equal(agent->bus, sender);
}
void voicecall_agent_disconnect_cb(DBusConnection *conn, void *user_data)
{
struct voicecall_agent *agent = user_data;
agent->disconnect_watch = 0;
voicecall_agent_free(agent);
}
struct voicecall_agent *voicecall_agent_new(const char *path,
const char *sender)
{
struct voicecall_agent *agent = g_try_new0(struct voicecall_agent, 1);
DBusConnection *conn = ofono_dbus_get_connection();
if (agent == NULL)
return NULL;
agent->path = g_strdup(path);
agent->bus = g_strdup(sender);
agent->disconnect_watch = g_dbus_add_disconnect_watch(conn, sender,
voicecall_agent_disconnect_cb,
agent, NULL);
return agent;
}

View File

@@ -0,0 +1,40 @@
/*
*
* oFono - Open Source Telephony
*
* 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
*
*/
struct voicecall_agent;
void voicecall_agent_ringback_tone(struct voicecall_agent *agent,
const ofono_bool_t playTone);
void voicecall_agent_set_removed_notify(struct voicecall_agent *agent,
ofono_destroy_func removed_cb,
void *user_data);
void voicecall_agent_free(struct voicecall_agent *agent);
ofono_bool_t voicecall_agent_matches(struct voicecall_agent *agent,
const char *path, const char *sender);
struct voicecall_agent *voicecall_agent_new(const char *path,
const char *sender);
void voicecall_agent_disconnect_cb(DBusConnection *conn,
void *user_data);

48
ofono/test/test-voicecallagent Executable file
View File

@@ -0,0 +1,48 @@
#!/usr/bin/python
import gobject
import sys
import dbus
import dbus.service
import dbus.mainloop.glib
class VoiceCallAgent(dbus.service.Object):
@dbus.service.method("org.ofono.VoiceCallAgent",
in_signature="", out_signature="")
def Release(self):
print "Agent got Release"
mainloop.quit()
@dbus.service.method("org.ofono.VoiceCallAgent",
in_signature="b", out_signature="")
def RingbackTone(self, playTone):
print "Agent got playTone notification: %d" % playTone
if __name__ == '__main__':
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
manager = dbus.Interface(bus.get_object("org.ofono", "/"),
"org.ofono.Manager")
modems = manager.GetModems()
for path, properties in modems:
if "org.ofono.VoiceCallManager" not in properties["Interfaces"]:
continue
vcm = dbus.Interface(bus.get_object('org.ofono', path),
'org.ofono.VoiceCallManager')
path = "/test/agent"
agent = VoiceCallAgent(bus, path)
vcm.RegisterVoicecallAgent(agent)
print "Agent registered"
mainloop = gobject.MainLoop()
try:
mainloop.run()
except KeyboardInterrupt:
vcm.UnregisterVoicecallAgent(path)
print "Agent unregistered (interrupt)"

View File

@@ -0,0 +1,99 @@
/*
*
* oFono - Open Source Telephony
*
* Copyright (C) 2014 Jolla. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <glib.h>
struct ofono_modem;
#include <gprs-provision.h>
#include "plugins/mbpi.h"
#include "plugins/provision.h"
void get_and_print_settings(const char *mcc, const char *mnc,
const char *spn)
{
struct ofono_gprs_provision_data *settings;
int count;
int i;
provision_get_settings(mcc, mnc, spn, &settings, &count);
g_print("Found %d contexts for (%s/%s/%s):\n", count, mcc, mnc, spn);
for (i = 0; i < count; i++){
struct ofono_gprs_provision_data ap = settings[i];
g_print(" Name: %s\n", ap.name);
g_print(" APN: %s\n", ap.apn);
g_print(" Type: %s\n", mbpi_ap_type(ap.type));
if (ap.username)
g_print(" Username: %s\n", ap.username);
if (ap.password)
g_print(" Password: %s\n", ap.password);
if (ap.message_proxy)
g_print(" MMS proxy: %s\n", ap.message_proxy);
if (ap.message_center)
g_print(" MMS center: %s\n", ap.message_center);
g_print("----------\n");
}
}
static void test_get_settings(void)
{
/* not in database */
get_and_print_settings("999", "999", NULL);
/* partial and case-insensitive matching */
get_and_print_settings("244", "91", "sonera");
get_and_print_settings("244", "91", "sONErA");
get_and_print_settings("244", "91", "sone");
get_and_print_settings("244", "91", "nera");
/* related to Sonera/Finland network */
get_and_print_settings("244", "91", NULL);
get_and_print_settings("244", "91", "sonera");
get_and_print_settings("244", "91", "aina");
/* related to DNA/Finland network */
get_and_print_settings("244", "03", NULL);
get_and_print_settings("244", "03", "dna");
get_and_print_settings("244", "03", "aina");
get_and_print_settings("244", "04", NULL);
get_and_print_settings("244", "04", "dna");
get_and_print_settings("244", "04", "aina");
/* related to O2/UK network */
get_and_print_settings("234", "10", NULL);
get_and_print_settings("234", "10", "o2");
get_and_print_settings("234", "10", "tesco");
get_and_print_settings("234", "10", "giffgaff");
/* related to E-Plus/Germany network */
get_and_print_settings("262", "03", NULL);
get_and_print_settings("262", "03", "E-Plus");
get_and_print_settings("262", "03", "simyo");
}
int main(int argc, char **argv)
{
g_test_init(&argc, &argv, NULL);
g_test_add_func("/testprovision/get_settings", test_get_settings);
return g_test_run();
}

View File

@@ -101,7 +101,7 @@ systemctl daemon-reload ||:
%files
%defattr(-,root,root,-)
%doc COPYING ChangeLog AUTHORS README
%config(noreplace) %{_sysconfdir}/dbus-1/system.d/*.conf
%config %{_sysconfdir}/dbus-1/system.d/*.conf
%{_sbindir}/*
/%{_lib}/systemd/system/network.target.wants/ofono.service
/%{_lib}/systemd/system/ofono.service