Compare commits

..

36 Commits

Author SHA1 Message Date
Slava Monich
75b07c5c80 Merge branch 'hfp_ag' into 'master'
HFP AG BlueZ5 plugin reconnects to daemon if daemon restarts.

See merge request mer-core/ofono!201
2018-11-30 13:59:21 +00:00
Juho Hämäläinen
4f6f964ca4 [hfp_ag_bluez5] Remove DBUS_TYPE_UNIX_FD check. 2018-11-30 12:46:26 +02:00
Juho Hämäläinen
7af95f6db5 [hfp_ag_bluez5] Follow BlueZ in system bus. JB#42087
Close interface on BlueZ exit and reconnect to BlueZ and re-create
interfaces when the daemon appears again. Now HFP AG is usable with
wanted or crash caused restarts of BlueZ daemon without needing to
restart oFono.
2018-11-30 12:45:43 +02:00
Juho Hämäläinen
99f4667eb7 [handsfree-audio] Set freed agent to NULL on exit. JB#42087 2018-11-29 14:36:27 +02:00
Slava Monich
c1c3ecab31 Merge branch 'context' into 'master'
Added "singleDataContext" configuration option

See merge request mer-core/ofono!200
2018-11-28 17:55:01 +00:00
Slava Monich
83dc99658c [ril] Added "singleDataContext" configuration option. JB#42837
Normally we should be able to have two simultaneously active
data contexts - one for mobile data and one for MMS. However
some devices may require that mobile data is disconnected
before we can send or receive MMS.
2018-11-28 13:54:51 +02:00
Slava Monich
9a7b538087 Merge branch 'jb42297' into 'master'
Handle multi-modem cases better in emulator and plugins.

See merge request mer-core/ofono!199
2018-11-14 23:30:42 +00:00
Juho Hämäläinen
9f7a1ffe3f [bluez5] Use updated emulator. Fixes JB#42297
Instead of using arbitrary modem in multiple modems scenario, pass all
applicaple modems to emulator.
2018-11-13 09:29:46 +02:00
Juho Hämäläinen
1f81ec7d9d [bluez4] Use updated emulator.
Instead of using arbitrary modem in multiple modems scenario, pass all
applicaple modems to emulator.
2018-11-13 09:29:46 +02:00
Juho Hämäläinen
6e833401cc [examples] Use updated emulator. 2018-11-13 09:29:46 +02:00
Juho Hämäläinen
d9c68c4fb9 [ofono] Support multiple modems in emulator. JB#42297
With more than one modem we don't play indicators etc correctly to
headset if the call is coming to a modem we are not watching. As the
modem is picked arbitrarily in hfp plugins, it is better to be able to
follow multiple modems at the same time.

When modems disappear they automatically are removed from the emulator,
with two or more modems it is possible that only one remains for a while
and new modems appear, to handle these cases add functionality to add
modems to the emulator.
2018-11-13 09:29:43 +02:00
Slava Monich
9e6f7721a0 Merge branch 'stray_call' into 'master'
Fix data connection dying after switching radio tech

See merge request mer-core/ofono!198
2018-10-26 15:50:09 +00:00
Slava Monich
9c529dcdcc [ril] Disconnect stray data calls. JB#42752
Sometimes data calls survive change of radio technology and just get
disassociated from ofono context and we may end up trying to activate
another context, thinking that the previous one is gone, even though
it's still alive. This is something that (at least some) operators
don't like, and start start rejecting our data calls.
2018-10-26 13:15:41 +03:00
Slava Monich
41814c6e6a [ril] Don't take LTE caps away from the only SIM 2018-10-25 01:01:05 +03:00
Slava Monich
cf99a5769f Merge branch 'restrict' into 'master'
Respect state restrictions

See merge request mer-core/ofono!197
2018-09-11 21:48:16 +00:00
Slava Monich
076e2f0ef1 [ril] Respect state restrictions. JB#42752
Do not allow mobile data connections if packet data access is blocked
due to restriction.
2018-09-11 17:01:09 +03:00
Slava Monich
fd76cb72ad Merge branch 'mtk2_incoming_call_fix' into 'master'
Fix incoming call indication on mtk2 vendor.

See merge request mer-core/ofono!196
2018-09-10 09:33:12 +00:00
Sergey Chupligin
554e4ab8e5 [ril] Fix incoming call indication on mtk2 vendor. Fixes JB#40790 2018-09-10 12:22:44 +03:00
NeKit
08f3da7577 [ril] Respond to INCOMING_CALL_INDICATION with SET_CALL_INDICATION. Fixes JB#40950
This is needed to make incoming calls to work on Gemini PDA (and noy only)
2018-09-04 12:55:57 +03:00
Slava Monich
2cbd3b6050 Merge branch 'cell_info_dbg' into 'master'
Improved cell info debug log

See merge request mer-core/ofono!194
2018-07-25 15:16:22 +00:00
Slava Monich
78d3d1892d [ril] Improved cell info debug log. JB#42359 2018-07-25 15:22:32 +03:00
Slava Monich
1448bd2320 Merge branch 'transport' into 'master'
Add interface for RIL transport plugins

See merge request mer-core/ofono!193
2018-07-24 08:05:12 +00:00
Slava Monich
ea8dfb48ab plugin: Don't unload external plugins too early
Plugins may reference data structures allocated by each other.
They all need to be deinitialized first, only then it should be
safe to unload the libraries.
2018-07-24 11:00:12 +03:00
Slava Monich
80921e8b7e [ofono] Add interface for RIL transport plugins. JB#42359
Intended to be used for integrating binder support.
2018-07-21 23:39:53 +03:00
Slava Monich
e4cc912719 [ril] Pull phone number type from SUPP_SVC_NOTIFICATION event
It was left uninitialized which wasn't good.
2018-07-21 23:38:41 +03:00
Slava Monich
c5f736d3c3 [ril] Housekeeping 2018-07-21 17:05:12 +03:00
Slava Monich
ddf4cec9b8 [ril] Do not wait for radio power request to complete
... after the power state has changed to the requested one.
There's no guarantee that rild is going to reply at all.
2018-07-21 17:04:02 +03:00
Slava Monich
685d0b34d7 [ril] Do not submit unnecessary radio power requests
Some RILs don't bother to reply to such a request which
blocks the request queue until such request expires.
2018-07-21 17:00:07 +03:00
Slava Monich
896f2f7a71 [ril] Added confirmRadioPowerOn configration entry
Modern RILs don't need and don't like it. The default
remains on for historical reasons.
2018-07-21 16:57:14 +03:00
Slava Monich
e96aacb9e7 [ril] Added radioPowerCycle configration entry.
With modern RILs radio power cycle shouldn't be necessary, it only
slows down the startup.
2018-07-18 23:37:48 +03:00
Slava Monich
91560afeec Merge branch 'fac_lock' into 'master'
Fix broken QUERY_FACILITY_LOCK packets

See merge request mer-core/ofono!192
2018-07-17 20:34:11 +00:00
Slava Monich
09fb8635c9 [ril] Fix broken QUERY_FACILITY_LOCK packets. Fixes JB#42428
I'm surprised that it worked at all - rild was probably ignoring
the broken part.
2018-07-17 16:27:38 +03:00
Slava Monich
1cb80d7d2f Merge branch 'voicecall_filter3' into 'master'
Allow to filter existing calls

See merge request mer-core/ofono!191
2018-07-05 08:54:46 +00:00
Slava Monich
7db5552e79 [ofono] Allow to filter existing calls. JB#41404
Plugins can request it by invoking ofono_voicecall_filter_notify().
Calls that don't pass the filter will be terminated.
2018-07-02 20:16:54 +03:00
Slava Monich
d87e40d0ff modem: Implement ofono_modem_get_voicecall 2018-07-02 20:15:33 +03:00
Slava Monich
35131ff56b include: Add ofono_modem_get_voicecall 2018-07-02 20:15:33 +03:00
47 changed files with 1644 additions and 633 deletions

1
ofono/.gitignore vendored
View File

@@ -48,6 +48,7 @@ unit/test-dbus-queue
unit/test-gprs-filter
unit/test-ril_config
unit/test-ril_util
unit/test-ril-transport
unit/test-rilmodem-cb
unit/test-rilmodem-cs
unit/test-rilmodem-gprs

View File

@@ -25,6 +25,7 @@ pkginclude_HEADERS = include/log.h include/plugin.h include/history.h \
include/handsfree-audio.h include/siri.h \
include/sms-filter.h include/gprs-filter.h \
include/voicecall-filter.h \
include/ril-constants.h include/ril-transport.h \
include/netmon.h include/lte.h \
include/storage.h \
gdbus/gdbus.h
@@ -738,7 +739,7 @@ src_ofonod_SOURCES = $(builtin_sources) $(gatchat_sources) src/ofono.ver \
src/handsfree-audio.c src/bluetooth.h \
src/sim-mnclength.c src/voicecallagent.c \
src/sms-filter.c src/gprs-filter.c src/dbus-queue.c \
src/voicecall-filter.c \
src/voicecall-filter.c src/ril-transport.c \
src/hfp.h src/siri.c \
src/netmon.c src/lte.c \
src/netmonagent.c src/netmonagent.h
@@ -1096,6 +1097,13 @@ unit_test_provision_LDADD = @GLIB_LIBS@ -ldl
unit_objects += $(unit_test_provision_OBJECTS)
unit_tests += unit/test-provision
unit_test_ril_transport_SOURCES = unit/test-ril-transport.c \
src/ril-transport.c src/log.c
unit_test_ril_transport_CFLAGS = $(COVERAGE_OPT) $(AM_CFLAGS)
unit_test_ril_transport_LDADD = @GLIB_LIBS@ -ldl
unit_objects += $(unit_test_ril_transport_OBJECTS)
unit_tests += unit/test-ril-transport
unit_test_sms_filter_SOURCES = unit/test-sms-filter.c \
src/sms-filter.c src/log.c
unit_test_sms_filter_CFLAGS = $(COVERAGE_OPT) $(AM_CFLAGS)

View File

@@ -184,10 +184,10 @@ AC_ARG_ENABLE(sailfish-rilmodem, AC_HELP_STRING([--enable-sailfish-rilmodem],
AM_CONDITIONAL(SAILFISH_RILMODEM, test "${enable_sailfish_rilmodem}" != "no")
if (test "${enable_sailfish_rilmodem}" = "yes"); then
PKG_CHECK_MODULES(GRILIO, libgrilio >= 1.0.21, dummy=yes,
AC_MSG_ERROR(libgrilio >= 1.0.21 is required))
PKG_CHECK_MODULES(GLIBUTIL, libglibutil >= 1.0.23, dummy=yes,
AC_MSG_ERROR(libglibutil >= 1.0.23 is required))
PKG_CHECK_MODULES(GRILIO, libgrilio >= 1.0.25, dummy=yes,
AC_MSG_ERROR(libgrilio >= 1.0.25 is required))
PKG_CHECK_MODULES(GLIBUTIL, libglibutil >= 1.0.30, dummy=yes,
AC_MSG_ERROR(libglibutil >= 1.0.30 is required))
PKG_CHECK_MODULES(LIBMCE, libmce-glib >= 1.0.5, dummy=yes,
AC_MSG_ERROR(libmce-glib >= 1.0.5 is required))
CFLAGS="$CFLAGS $GRILIO_CFLAGS $LIBMCE_CFLAGS"

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2017 Jolla Ltd.
* Copyright (C) 2015-2018 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
@@ -14,6 +14,7 @@
*/
#include "ril_plugin.h"
#include "ril_sim_card.h"
#include "ril_util.h"
#include "ril_log.h"
@@ -26,11 +27,11 @@
* 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
struct ril_call_barring {
struct ril_sim_card *card;
GRilIoQueue *q;
guint timer_id;
};
@@ -106,7 +107,7 @@ static void ril_call_barring_query(struct ofono_call_barring *b,
{
struct ril_call_barring *bd = ofono_call_barring_get_data(b);
char cls_textual[RIL_MAX_SERVICE_LENGTH];
GRilIoRequest *req = grilio_request_new();
GRilIoRequest *req;
DBG("lock: %s, services to query: %d", lock, cls);
@@ -123,15 +124,9 @@ static void ril_call_barring_query(struct ofono_call_barring *b,
/*
* 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
*/
grilio_request_append_int32(req, RIL_QUERY_STRING_COUNT);
grilio_request_append_utf8(req, lock); /* Facility code */
grilio_request_append_int32(req, 0); /* Password length */
grilio_request_append_utf8(req, cls_textual);
grilio_request_append_utf8(req, NULL); /* AID (not yet supported) */
req = grilio_request_array_utf8_new(4, lock, "", cls_textual,
ril_sim_card_app_aid(bd->card));
ril_call_barring_submit_request(bd, req,
RIL_REQUEST_QUERY_FACILITY_LOCK,
ril_call_barring_query_cb, cb, data);
@@ -182,7 +177,7 @@ static void ril_call_barring_set(struct ofono_call_barring *b,
RIL_FACILITY_UNLOCK);
grilio_request_append_utf8(req, passwd);
grilio_request_append_utf8(req, cls_textual);
grilio_request_append_utf8(req, NULL); /* AID (not yet supported) */
grilio_request_append_utf8(req, ril_sim_card_app_aid(bd->card));
ril_call_barring_submit_request(bd, req,
RIL_REQUEST_SET_FACILITY_LOCK,
@@ -243,6 +238,7 @@ static int ril_call_barring_probe(struct ofono_call_barring *b,
struct ril_call_barring *bd = g_new0(struct ril_call_barring, 1);
DBG("");
bd->card = ril_sim_card_ref(modem->sim_card);
bd->q = grilio_queue_new(ril_modem_io(modem));
bd->timer_id = g_idle_add(ril_call_barring_register, b);
ofono_call_barring_set_data(b, bd);
@@ -260,6 +256,7 @@ static void ril_call_barring_remove(struct ofono_call_barring *b)
g_source_remove(bd->timer_id);
}
ril_sim_card_unref(bd->card);
grilio_queue_cancel_all(bd->q, FALSE);
grilio_queue_unref(bd->q);
g_free(bd);

View File

@@ -23,6 +23,7 @@
#include <grilio_request.h>
#include <grilio_parser.h>
#include <gutil_idlepool.h>
#include <gutil_misc.h>
#define DISPLAY_ON_UPDATE_RATE (1000) /* 1 sec */
@@ -75,6 +76,20 @@ static void ril_cell_free1(gpointer cell)
ril_cell_free(cell);
}
static const char *ril_cell_info_int_format(int value, const char *format)
{
if (value == SAILFISH_CELL_INVALID_VALUE) {
return "";
} else {
static GUtilIdlePool *ril_cell_info_pool = NULL;
GUtilIdlePool *pool = gutil_idle_pool_get(&ril_cell_info_pool);
char *str = g_strdup_printf(format, value);
gutil_idle_pool_add(pool, str, g_free);
return str;
}
}
static gboolean ril_cell_info_list_identical(GSList *l1, GSList *l2)
{
while (l1 && l2) {
@@ -123,11 +138,17 @@ static struct sailfish_cell *ril_cell_info_parse_cell_gsm(GRilIoParser *rilp,
grilio_parser_get_int32(rilp, &gsm->bitErrorRate) &&
(version < 12 || /* RIL_GSM_SignalStrength_v12 part */
grilio_parser_get_int32(rilp, &gsm->timingAdvance))) {
DBG("[gsm] reg=%d,mcc=%d,mnc=%d,lac=%d,cid=%d,arfcn=%d,"
"bsic=%d,strength=%d,err=%d,t=%d", registered,
gsm->mcc, gsm->mnc, gsm->lac, gsm->cid, gsm->arfcn,
gsm->bsic, gsm->signalStrength, gsm->bitErrorRate,
gsm->timingAdvance);
DBG("[gsm] reg=%d%s%s%s%s%s%s%s%s%s", registered,
ril_cell_info_int_format(gsm->mcc, ",mcc=%d"),
ril_cell_info_int_format(gsm->mnc, ",mnc=%d"),
ril_cell_info_int_format(gsm->lac, ",lac=%d"),
ril_cell_info_int_format(gsm->cid, ",cid=%d"),
ril_cell_info_int_format(gsm->arfcn, ",arfcn=%d"),
ril_cell_info_int_format(gsm->bsic, ",bsic=%d"),
ril_cell_info_int_format(gsm->signalStrength,
",strength=%d"),
ril_cell_info_int_format(gsm->bitErrorRate, ",err=%d"),
ril_cell_info_int_format(gsm->timingAdvance, ",t=%d"));
cell->type = SAILFISH_CELL_TYPE_GSM;
cell->registered = registered;
return cell;
@@ -155,10 +176,16 @@ static struct sailfish_cell *ril_cell_info_parse_cell_wcdma(GRilIoParser *rilp,
grilio_parser_get_int32(rilp, &wcdma->uarfcn)) &&
grilio_parser_get_int32(rilp, &wcdma->signalStrength) &&
grilio_parser_get_int32(rilp, &wcdma->bitErrorRate)) {
DBG("[wcdma] reg=%d,mcc=%d,mnc=%d,lac=%d,cid=%d,psc=%d,"
"strength=%d,err=%d", registered, wcdma->mcc,
wcdma->mnc, wcdma->lac, wcdma->cid, wcdma->psc,
wcdma->signalStrength, wcdma->bitErrorRate);
DBG("[wcdma] reg=%d%s%s%s%s%s%s%s", registered,
ril_cell_info_int_format(wcdma->mcc, ",mcc=%d"),
ril_cell_info_int_format(wcdma->mnc, ",mnc=%d"),
ril_cell_info_int_format(wcdma->lac, ",lac=%d"),
ril_cell_info_int_format(wcdma->cid, ",cid=%d"),
ril_cell_info_int_format(wcdma->psc, ",psc=%d"),
ril_cell_info_int_format(wcdma->signalStrength,
",strength=%d"),
ril_cell_info_int_format(wcdma->bitErrorRate,
",err=%d"));
cell->type = SAILFISH_CELL_TYPE_WCDMA;
cell->registered = registered;
return cell;
@@ -190,11 +217,19 @@ static struct sailfish_cell *ril_cell_info_parse_cell_lte(GRilIoParser *rilp,
grilio_parser_get_int32(rilp, &lte->rssnr) &&
grilio_parser_get_int32(rilp, &lte->cqi) &&
grilio_parser_get_int32(rilp, &lte->timingAdvance)) {
DBG("[lte] reg=%d,mcc=%d,mnc=%d,ci=%d,pci=%d,tac=%d,"
"strength=%d,rsrp=%d,rsrq=%d,rssnr=%d,cqi=%d,"
"t=0x%x", registered, lte->mcc, lte->mnc, lte->ci,
lte->pci, lte->tac, lte->signalStrength, lte->rsrp,
lte->rsrq, lte->rssnr, lte->cqi, lte->timingAdvance);
DBG("[lte] reg=%d%s%s%s%s%s%s%s%s%s%s%s", registered,
ril_cell_info_int_format(lte->mcc, ",mcc=%d"),
ril_cell_info_int_format(lte->mnc, ",mnc=%d"),
ril_cell_info_int_format(lte->ci, ",ci=%d"),
ril_cell_info_int_format(lte->pci, ",pci=%d"),
ril_cell_info_int_format(lte->tac, ",tac=%d"),
ril_cell_info_int_format(lte->signalStrength,
",strength=%d"),
ril_cell_info_int_format(lte->rsrp, ",rsrp=%d"),
ril_cell_info_int_format(lte->rsrq, ",rsrq=%d"),
ril_cell_info_int_format(lte->rssnr, ",rssnr=%d"),
ril_cell_info_int_format(lte->cqi, ",cqi=%d"),
ril_cell_info_int_format(lte->timingAdvance, ",t=%d"));
cell->type = SAILFISH_CELL_TYPE_LTE;
cell->registered = registered;
return cell;

View File

@@ -19,6 +19,7 @@
#include <gutil_intarray.h>
#include <gutil_ints.h>
#include <gutil_misc.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -206,7 +207,7 @@ GUtilInts *ril_config_get_ints(GKeyFile *file, const char *group,
while (*ptr) {
int val;
if (ril_parse_int(*ptr++, 0, &val)) {
if (gutil_parse_int(*ptr++, 0, &val)) {
gutil_int_array_append(array, val);
}
}

View File

@@ -1,10 +1,6 @@
/*
* RIL constants adopted from AOSP's header:
*
* /hardware/ril/reference_ril/ril.h
*
* Copyright (C) 2013 Canonical Ltd.
* Copyright (C) 2013-2017 Jolla Ltd.
* Copyright (C) 2013-2018 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
@@ -19,81 +15,10 @@
#ifndef __RIL_CONSTANTS_H
#define __RIL_CONSTANTS_H 1
#include <ofono/ril-constants.h>
#define RIL_MAX_UUID_LENGTH 64
/* Error Codes */
enum ril_status {
RIL_E_SUCCESS = 0,
RIL_E_RADIO_NOT_AVAILABLE = 1,
RIL_E_GENERIC_FAILURE = 2,
RIL_E_PASSWORD_INCORRECT = 3,
RIL_E_SIM_PIN2 = 4,
RIL_E_SIM_PUK2 = 5,
RIL_E_REQUEST_NOT_SUPPORTED = 6,
RIL_E_CANCELLED = 7,
RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL = 8,
RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW = 9,
RIL_E_SMS_SEND_FAIL_RETRY = 10,
RIL_E_SIM_ABSENT = 11,
RIL_E_SUBSCRIPTION_NOT_AVAILABLE = 12,
RIL_E_MODE_NOT_SUPPORTED = 13,
RIL_E_FDN_CHECK_FAILURE = 14,
RIL_E_ILLEGAL_SIM_OR_ME = 15,
RIL_E_MISSING_RESOURCE = 16,
RIL_E_NO_SUCH_ELEMENT = 17,
RIL_E_DIAL_MODIFIED_TO_USSD = 18,
RIL_E_DIAL_MODIFIED_TO_SS = 19,
RIL_E_DIAL_MODIFIED_TO_DIAL = 20,
RIL_E_USSD_MODIFIED_TO_DIAL = 21,
RIL_E_USSD_MODIFIED_TO_SS = 22,
RIL_E_USSD_MODIFIED_TO_USSD = 23,
RIL_E_SS_MODIFIED_TO_DIAL = 24,
RIL_E_SS_MODIFIED_TO_USSD = 25,
RIL_E_SUBSCRIPTION_NOT_SUPPORTED = 26,
RIL_E_SS_MODIFIED_TO_SS = 27,
RIL_E_LCE_NOT_SUPPORTED = 36,
RIL_E_NO_MEMORY = 37,
RIL_E_INTERNAL_ERR = 38,
RIL_E_SYSTEM_ERR = 39,
RIL_E_MODEM_ERR = 40,
RIL_E_INVALID_STATE = 41,
RIL_E_NO_RESOURCES = 42,
RIL_E_SIM_ERR = 43,
RIL_E_INVALID_ARGUMENTS = 44,
RIL_E_INVALID_SIM_STATE = 45,
RIL_E_INVALID_MODEM_STATE = 46,
RIL_E_INVALID_CALL_ID = 47,
RIL_E_NO_SMS_TO_ACK = 48,
RIL_E_NETWORK_ERR = 49,
RIL_E_REQUEST_RATE_LIMITED = 50,
RIL_E_SIM_BUSY = 51,
RIL_E_SIM_FULL = 52,
RIL_E_NETWORK_REJECT = 53,
RIL_E_OPERATION_NOT_ALLOWED = 54,
RIL_E_EMPTY_RECORD = 55,
RIL_E_INVALID_SMS_FORMAT = 56,
RIL_E_ENCODING_ERR = 57,
RIL_E_INVALID_SMSC_ADDRESS = 58,
RIL_E_NO_SUCH_ENTRY = 59,
RIL_E_NETWORK_NOT_READY = 60,
RIL_E_NOT_PROVISIONED = 61,
RIL_E_NO_SUBSCRIPTION = 62,
RIL_E_NO_NETWORK_FOUND = 63,
RIL_E_DEVICE_IN_USE = 64,
RIL_E_ABORTED = 65,
RIL_E_INVALID_RESPONSE = 66
};
/* call states */
enum ril_call_state {
RIL_CALL_ACTIVE = 0,
RIL_CALL_HOLDING = 1,
RIL_CALL_DIALING = 2,
RIL_CALL_ALERTING = 3,
RIL_CALL_INCOMING = 4,
RIL_CALL_WAITING = 5
};
/* Radio state */
enum ril_radio_state {
RADIO_STATE_OFF = 0,
@@ -267,30 +192,30 @@ enum ril_call_fail_cause {
};
enum ril_data_call_fail_cause {
PDP_FAIL_NONE = 0,
PDP_FAIL_OPERATOR_BARRED = 0x08,
PDP_FAIL_INSUFFICIENT_RESOURCES = 0x1A,
PDP_FAIL_MISSING_UKNOWN_APN = 0x1B,
PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE = 0x1C,
PDP_FAIL_USER_AUTHENTICATION = 0x1D,
PDP_FAIL_ACTIVATION_REJECT_GGSN = 0x1E,
PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED = 0x1F,
PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED = 0x20,
PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21,
PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22,
PDP_FAIL_NSAPI_IN_USE = 0x23,
PDP_FAIL_REGULAR_DEACTIVATION = 0x24,
PDP_FAIL_ONLY_IPV4_ALLOWED = 0x32,
PDP_FAIL_ONLY_IPV6_ALLOWED = 0x33,
PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED = 0x34,
PDP_FAIL_PROTOCOL_ERRORS = 0x6F,
PDP_FAIL_VOICE_REGISTRATION_FAIL = -1,
PDP_FAIL_DATA_REGISTRATION_FAIL = -2,
PDP_FAIL_SIGNAL_LOST = -3,
PDP_FAIL_PREF_RADIO_TECH_CHANGED = -4,
PDP_FAIL_RADIO_POWER_OFF = -5,
PDP_FAIL_TETHERED_CALL_ACTIVE = -6,
PDP_FAIL_ERROR_UNSPECIFIED = 0xffff
PDP_FAIL_NONE = 0,
PDP_FAIL_OPERATOR_BARRED = 0x08,
PDP_FAIL_INSUFFICIENT_RESOURCES = 0x1A,
PDP_FAIL_MISSING_UKNOWN_APN = 0x1B,
PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE = 0x1C,
PDP_FAIL_USER_AUTHENTICATION = 0x1D,
PDP_FAIL_ACTIVATION_REJECT_GGSN = 0x1E,
PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED = 0x1F,
PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED = 0x20,
PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21,
PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22,
PDP_FAIL_NSAPI_IN_USE = 0x23,
PDP_FAIL_REGULAR_DEACTIVATION = 0x24,
PDP_FAIL_ONLY_IPV4_ALLOWED = 0x32,
PDP_FAIL_ONLY_IPV6_ALLOWED = 0x33,
PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED = 0x34,
PDP_FAIL_PROTOCOL_ERRORS = 0x6F,
PDP_FAIL_VOICE_REGISTRATION_FAIL = -1,
PDP_FAIL_DATA_REGISTRATION_FAIL = -2,
PDP_FAIL_SIGNAL_LOST = -3,
PDP_FAIL_PREF_RADIO_TECH_CHANGED = -4,
PDP_FAIL_RADIO_POWER_OFF = -5,
PDP_FAIL_TETHERED_CALL_ACTIVE = -6,
PDP_FAIL_ERROR_UNSPECIFIED = 0xffff
};
/* RIL_REQUEST_DEACTIVATE_DATA_CALL parameter */
@@ -395,192 +320,6 @@ enum ril_cell_info_type {
RIL_CELL_INFO_TYPE_TD_SCDMA = 5
};
/* RIL Request Messages, ofono -> rild */
#define RIL_REQUEST_GET_SIM_STATUS 1
#define RIL_REQUEST_ENTER_SIM_PIN 2
#define RIL_REQUEST_ENTER_SIM_PUK 3
#define RIL_REQUEST_ENTER_SIM_PIN2 4
#define RIL_REQUEST_ENTER_SIM_PUK2 5
#define RIL_REQUEST_CHANGE_SIM_PIN 6
#define RIL_REQUEST_CHANGE_SIM_PIN2 7
#define RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION 8
#define RIL_REQUEST_GET_CURRENT_CALLS 9
#define RIL_REQUEST_DIAL 10
#define RIL_REQUEST_GET_IMSI 11
#define RIL_REQUEST_HANGUP 12
#define RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND 13
#define RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND 14
#define RIL_REQUEST_SWITCH_HOLDING_AND_ACTIVE 15
#define RIL_REQUEST_CONFERENCE 16
#define RIL_REQUEST_UDUB 17
#define RIL_REQUEST_LAST_CALL_FAIL_CAUSE 18
#define RIL_REQUEST_SIGNAL_STRENGTH 19
#define RIL_REQUEST_VOICE_REGISTRATION_STATE 20
#define RIL_REQUEST_DATA_REGISTRATION_STATE 21
#define RIL_REQUEST_OPERATOR 22
#define RIL_REQUEST_RADIO_POWER 23
#define RIL_REQUEST_DTMF 24
#define RIL_REQUEST_SEND_SMS 25
#define RIL_REQUEST_SEND_SMS_EXPECT_MORE 26
#define RIL_REQUEST_SETUP_DATA_CALL 27
#define RIL_REQUEST_SIM_IO 28
#define RIL_REQUEST_SEND_USSD 29
#define RIL_REQUEST_CANCEL_USSD 30
#define RIL_REQUEST_GET_CLIR 31
#define RIL_REQUEST_SET_CLIR 32
#define RIL_REQUEST_QUERY_CALL_FORWARD_STATUS 33
#define RIL_REQUEST_SET_CALL_FORWARD 34
#define RIL_REQUEST_QUERY_CALL_WAITING 35
#define RIL_REQUEST_SET_CALL_WAITING 36
#define RIL_REQUEST_SMS_ACKNOWLEDGE 37
#define RIL_REQUEST_GET_IMEI 38
#define RIL_REQUEST_GET_IMEISV 39
#define RIL_REQUEST_ANSWER 40
#define RIL_REQUEST_DEACTIVATE_DATA_CALL 41
#define RIL_REQUEST_QUERY_FACILITY_LOCK 42
#define RIL_REQUEST_SET_FACILITY_LOCK 43
#define RIL_REQUEST_CHANGE_BARRING_PASSWORD 44
#define RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE 45
#define RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC 46
#define RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL 47
#define RIL_REQUEST_QUERY_AVAILABLE_NETWORKS 48
#define RIL_REQUEST_DTMF_START 49
#define RIL_REQUEST_DTMF_STOP 50
#define RIL_REQUEST_BASEBAND_VERSION 51
#define RIL_REQUEST_SEPARATE_CONNECTION 52
#define RIL_REQUEST_SET_MUTE 53
#define RIL_REQUEST_GET_MUTE 54
#define RIL_REQUEST_QUERY_CLIP 55
#define RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE 56
#define RIL_REQUEST_DATA_CALL_LIST 57
#define RIL_REQUEST_RESET_RADIO 58
#define RIL_REQUEST_OEM_HOOK_RAW 59
#define RIL_REQUEST_OEM_HOOK_STRINGS 60
#define RIL_REQUEST_SCREEN_STATE 61
#define RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION 62
#define RIL_REQUEST_WRITE_SMS_TO_SIM 63
#define RIL_REQUEST_DELETE_SMS_ON_SIM 64
#define RIL_REQUEST_SET_BAND_MODE 65
#define RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE 66
#define RIL_REQUEST_STK_GET_PROFILE 67
#define RIL_REQUEST_STK_SET_PROFILE 68
#define RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND 69
#define RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE 70
#define RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM 71
#define RIL_REQUEST_EXPLICIT_CALL_TRANSFER 72
#define RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE 73
#define RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE 74
#define RIL_REQUEST_GET_NEIGHBORING_CELL_IDS 75
#define RIL_REQUEST_SET_LOCATION_UPDATES 76
#define RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE 77
#define RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE 78
#define RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE 79
#define RIL_REQUEST_SET_TTY_MODE 80
#define RIL_REQUEST_QUERY_TTY_MODE 81
#define RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE 82
#define RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE 83
#define RIL_REQUEST_CDMA_FLASH 84
#define RIL_REQUEST_CDMA_BURST_DTMF 85
#define RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY 86
#define RIL_REQUEST_CDMA_SEND_SMS 87
#define RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE 88
#define RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG 89
#define RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG 90
#define RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION 91
#define RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG 92
#define RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG 93
#define RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION 94
#define RIL_REQUEST_CDMA_SUBSCRIPTION 95
#define RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM 96
#define RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM 97
#define RIL_REQUEST_DEVICE_IDENTITY 98
#define RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE 99
#define RIL_REQUEST_GET_SMSC_ADDRESS 100
#define RIL_REQUEST_SET_SMSC_ADDRESS 101
#define RIL_REQUEST_REPORT_SMS_MEMORY_STATUS 102
#define RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING 103
#define RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE 104
#define RIL_REQUEST_ISIM_AUTHENTICATION 105
#define RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU 106
#define RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS 107
#define RIL_REQUEST_VOICE_RADIO_TECH 108
#define RIL_REQUEST_GET_CELL_INFO_LIST 109
#define RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE 110
#define RIL_REQUEST_SET_INITIAL_ATTACH_APN 111
#define RIL_REQUEST_IMS_REGISTRATION_STATE 112
#define RIL_REQUEST_IMS_SEND_SMS 113
#define RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC 114
#define RIL_REQUEST_SIM_OPEN_CHANNEL 115
#define RIL_REQUEST_SIM_CLOSE_CHANNEL 116
#define RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL 117
#define RIL_REQUEST_NV_READ_ITEM 118
#define RIL_REQUEST_NV_WRITE_ITEM 119
#define RIL_REQUEST_NV_WRITE_CDMA_PRL 120
#define RIL_REQUEST_NV_RESET_CONFIG 121
/* SET_UICC_SUBSCRIPTION was 115 in v9 and 122 in v10 and later */
#define RIL_REQUEST_V9_SET_UICC_SUBSCRIPTION 115
#define RIL_REQUEST_SET_UICC_SUBSCRIPTION 122
#define RIL_REQUEST_ALLOW_DATA 123
#define RIL_REQUEST_GET_HARDWARE_CONFIG 124
#define RIL_REQUEST_SIM_AUTHENTICATION 125
#define RIL_REQUEST_GET_DC_RT_INFO 126
#define RIL_REQUEST_SET_DC_RT_INFO_RATE 127
#define RIL_REQUEST_SET_DATA_PROFILE 128
#define RIL_REQUEST_SHUTDOWN 129
#define RIL_REQUEST_GET_RADIO_CAPABILITY 130
#define RIL_REQUEST_SET_RADIO_CAPABILITY 131
/* RIL Unsolicited Messages, rild -> ofono */
#define RIL_UNSOL_RESPONSE_BASE 1000
#define RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED 1000
#define RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED 1001
#define RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED 1002
#define RIL_UNSOL_RESPONSE_NEW_SMS 1003
#define RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT 1004
#define RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM 1005
#define RIL_UNSOL_ON_USSD 1006
#define RIL_UNSOL_ON_USSD_REQUEST 1007
#define RIL_UNSOL_NITZ_TIME_RECEIVED 1008
#define RIL_UNSOL_SIGNAL_STRENGTH 1009
#define RIL_UNSOL_DATA_CALL_LIST_CHANGED 1010
#define RIL_UNSOL_SUPP_SVC_NOTIFICATION 1011
#define RIL_UNSOL_STK_SESSION_END 1012
#define RIL_UNSOL_STK_PROACTIVE_COMMAND 1013
#define RIL_UNSOL_STK_EVENT_NOTIFY 1014
#define RIL_UNSOL_STK_CALL_SETUP 1015
#define RIL_UNSOL_SIM_SMS_STORAGE_FULL 1016
#define RIL_UNSOL_SIM_REFRESH 1017
#define RIL_UNSOL_CALL_RING 1018
#define RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED 1019
#define RIL_UNSOL_RESPONSE_CDMA_NEW_SMS 1020
#define RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS 1021
#define RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL 1022
#define RIL_UNSOL_RESTRICTED_STATE_CHANGED 1023
#define RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE 1024
#define RIL_UNSOL_CDMA_CALL_WAITING 1025
#define RIL_UNSOL_CDMA_OTA_PROVISION_STATUS 1026
#define RIL_UNSOL_CDMA_INFO_REC 1027
#define RIL_UNSOL_OEM_HOOK_RAW 1028
#define RIL_UNSOL_RINGBACK_TONE 1029
#define RIL_UNSOL_RESEND_INCALL_MUTE 1030
#define RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED 1031
#define RIL_UNSOL_CDMA_PRL_CHANGED 1032
#define RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE 1033
#define RIL_UNSOL_RIL_CONNECTED 1034
#define RIL_UNSOL_VOICE_RADIO_TECH_CHANGED 1035
#define RIL_UNSOL_CELL_INFO_LIST 1036
#define RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED 1037
#define RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED 1038
#define RIL_UNSOL_SRVCC_STATE_NOTIFY 1039
#define RIL_UNSOL_HARDWARE_CONFIG_CHANGED 1040
#define RIL_UNSOL_DC_RT_INFO_CHANGED 1041
#define RIL_UNSOL_RADIO_CAPABILITY 1042
#define RIL_UNSOL_ON_SS 1043
#define RIL_UNSOL_STK_CC_ALPHA_NOTIFY 1044
/* A special request, ofono -> rild */
#define RIL_RESPONSE_ACKNOWLEDGEMENT 800
enum ril_restricted_state {
RIL_RESTRICTED_STATE_NONE = 0x00,
RIL_RESTRICTED_STATE_CS_EMERGENCY = 0x01,

View File

@@ -114,6 +114,7 @@ struct ril_data_priv {
guint query_id;
gulong io_event_id[IO_EVENT_COUNT];
gulong settings_event_id[SETTINGS_EVENT_COUNT];
GHashTable* grab;
};
enum ril_data_signal {
@@ -185,7 +186,7 @@ struct ril_data_request_allow_data {
static void ril_data_manager_check_data(struct ril_data_manager *dm);
static void ril_data_manager_check_network_mode(struct ril_data_manager *dm);
static void ril_data_call_deact_cid(struct ril_data *data, int cid);
static void ril_data_power_update(struct ril_data *self);
static void ril_data_signal_emit(struct ril_data *self, enum ril_data_signal id)
{
@@ -545,6 +546,10 @@ struct ril_data_call *ril_data_call_find(struct ril_data_call_list *list,
static void ril_data_set_calls(struct ril_data *self,
struct ril_data_call_list *list)
{
struct ril_data_priv *priv = self->priv;
GHashTableIter it;
gpointer key;
if (!ril_data_call_list_equal(self->data_calls, list)) {
DBG("data calls changed");
ril_data_call_list_free(self->data_calls);
@@ -553,6 +558,32 @@ static void ril_data_set_calls(struct ril_data *self,
} else {
ril_data_call_list_free(list);
}
/* Clean up the grab table */
g_hash_table_iter_init(&it, priv->grab);
while (g_hash_table_iter_next(&it, &key, NULL)) {
const int cid = GPOINTER_TO_INT(key);
if (!ril_data_call_find(self->data_calls, cid)) {
g_hash_table_iter_remove(&it);
}
}
if (self->data_calls) {
GSList *l;
/* Disconnect stray calls (one at a time) */
for (l = self->data_calls->calls; l; l = l->next) {
struct ril_data_call *dc = l->data;
key = GINT_TO_POINTER(dc->cid);
if (!g_hash_table_contains(priv->grab, key)) {
DBG_(self, "stray call %u", dc->cid);
ril_data_call_deact_cid(self, dc->cid);
break;
}
}
}
}
static void ril_data_check_allowed(struct ril_data *self, gboolean was_allowed)
@@ -1083,6 +1114,11 @@ static struct ril_data_request *ril_data_call_deact_new(struct ril_data *data,
return req;
}
static void ril_data_call_deact_cid(struct ril_data *data, int cid)
{
ril_data_request_queue(ril_data_call_deact_new(data, cid, NULL, NULL));
}
/*==========================================================================*
* ril_data_allow_request
*==========================================================================*/
@@ -1323,9 +1359,7 @@ static void ril_data_deactivate_all(struct ril_data *self)
struct ril_data_call *call = l->data;
if (call->status == PDP_FAIL_NONE) {
DBG_(self, "deactivating call %u", call->cid);
ril_data_request_queue(
ril_data_call_deact_new(self,
call->cid, NULL, NULL));
ril_data_call_deact_cid(self, call->cid);
}
}
}
@@ -1492,12 +1526,39 @@ struct ril_data_request *ril_data_call_deactivate(struct ril_data *self,
return req;
}
gboolean ril_data_call_grab(struct ril_data *self, int cid, void *cookie)
{
if (self && cookie && ril_data_call_find(self->data_calls, cid)) {
struct ril_data_priv *priv = self->priv;
gpointer key = GINT_TO_POINTER(cid);
void *prev = g_hash_table_lookup(priv->grab, key);
if (!prev) {
g_hash_table_insert(priv->grab, key, cookie);
return TRUE;
} else {
return (prev == cookie);
}
}
return FALSE;
}
void ril_data_call_release(struct ril_data *self, int cid, void *cookie)
{
if (self && cookie) {
struct ril_data_priv *priv = self->priv;
g_hash_table_remove(priv->grab, GUINT_TO_POINTER(cid));
}
}
static void ril_data_init(struct ril_data *self)
{
struct ril_data_priv *priv = G_TYPE_INSTANCE_GET_PRIVATE(self,
RIL_DATA_TYPE, struct ril_data_priv);
self->priv = priv;
priv->grab = g_hash_table_new(g_direct_hash, g_direct_equal);
}
static void ril_data_dispose(GObject *object)
@@ -1525,6 +1586,7 @@ static void ril_data_dispose(GObject *object)
dm->data_list = g_slist_remove(dm->data_list, self);
ril_data_manager_check_data(dm);
g_hash_table_destroy(priv->grab);
G_OBJECT_CLASS(ril_data_parent_class)->dispose(object);
}

View File

@@ -123,6 +123,9 @@ struct ril_data_request *ril_data_call_deactivate(struct ril_data *data,
void ril_data_request_detach(struct ril_data_request *req);
void ril_data_request_cancel(struct ril_data_request *req);
gboolean ril_data_call_grab(struct ril_data *data, int cid, void *cookie);
void ril_data_call_release(struct ril_data *data, int cid, void *cookie);
void ril_data_call_free(struct ril_data_call *call);
struct ril_data_call *ril_data_call_dup(const struct ril_data_call *call);
struct ril_data_call *ril_data_call_find(struct ril_data_call_list *list,

View File

@@ -88,6 +88,7 @@ static int ril_gprs_context_address_family(const char *addr)
static void ril_gprs_context_free_active_call(struct ril_gprs_context *gcd)
{
if (gcd->active_call) {
ril_data_call_release(gcd->data, gcd->active_call->cid, gcd);
ril_data_call_free(gcd->active_call);
gcd->active_call = NULL;
}
@@ -111,6 +112,7 @@ static void ril_gprs_context_set_active_call(struct ril_gprs_context *gcd,
gcd->mtu_watch = mtu_watch_new(MAX_MTU);
}
mtu_watch_set_ifname(gcd->mtu_watch, call->ifname);
ril_data_call_grab(gcd->data, call->cid, gcd);
} else {
ril_gprs_context_free_active_call(gcd);
}

View File

@@ -454,8 +454,10 @@ struct ril_modem *ril_modem_create(GRilIoChannel *io, const char *log_prefix,
ofono_modem_set_data(ofono, md);
err = ofono_modem_register(ofono);
if (!err) {
ril_radio_power_cycle(modem->radio);
GASSERT(io->connected);
if (config->radio_power_cycle) {
ril_radio_power_cycle(modem->radio);
}
/*
* ofono_modem_reset sets Powered to TRUE without

View File

@@ -217,11 +217,11 @@ static gboolean ril_network_parse_response(struct ril_network *self,
reg->max_calls = 2;
}
if (!ril_parse_int(slac, 16, &reg->lac)) {
if (!gutil_parse_int(slac, 16, &reg->lac)) {
reg->lac = -1;
}
if (!ril_parse_int(sci, 16, &reg->ci)) {
if (!gutil_parse_int(sci, 16, &reg->ci)) {
reg->ci = -1;
}

View File

@@ -30,8 +30,11 @@
#include <sailfish_manager.h>
#include <sailfish_watch.h>
#include <grilio_transport.h>
#include <gutil_ints.h>
#include <gutil_macros.h>
#include <gutil_misc.h>
#include <mce_display.h>
#include <mce_log.h>
@@ -48,6 +51,7 @@
#define OFONO_API_SUBJECT_TO_CHANGE
#include <ofono/plugin.h>
#include <ofono/storage.h>
#include <ofono/ril-transport.h>
#define OFONO_RADIO_ACCESS_MODE_ALL (OFONO_RADIO_ACCESS_MODE_GSM |\
OFONO_RADIO_ACCESS_MODE_UMTS |\
@@ -79,6 +83,14 @@
#define RILMODEM_DEFAULT_EMPTY_PIN_QUERY TRUE /* optimistic */
#define RILMODEM_DEFAULT_QUERY_AVAILABLE_BAND_MODE TRUE /* Qualcomm */
#define RILMODEM_DEFAULT_LEGACY_IMEI_QUERY FALSE
#define RILMODEM_DEFAULT_RADIO_POWER_CYCLE TRUE
#define RILMODEM_DEFAULT_CONFIRM_RADIO_POWER_ON TRUE
#define RILMODEM_DEFAULT_SLOT_FLAGS SAILFISH_SLOT_NO_FLAGS
/* RIL socket transport name and parameters */
#define RIL_TRANSPORT_SOCKET "socket"
#define RIL_TRANSPORT_SOCKET_PATH "path"
#define RIL_TRANSPORT_SOCKET_SUB "sub"
/*
* The convention is that the keys which can only appear in the [Settings]
@@ -91,8 +103,9 @@
#define RILCONF_SETTINGS_3GHANDOVER "3GLTEHandover"
#define RILCONF_SETTINGS_SET_RADIO_CAP "SetRadioCapability"
#define RILCONF_DEV_PREFIX "ril_"
#define RILCONF_PATH_PREFIX "/" RILCONF_DEV_PREFIX
#define RILCONF_MODEM_PREFIX "ril_"
#define RILCONF_PATH_PREFIX "/" RILCONF_MODEM_PREFIX
#define RILCONF_TRANSPORT "transport"
#define RILCONF_NAME "name"
#define RILCONF_SOCKET "socket"
#define RILCONF_SLOT "slot"
@@ -115,7 +128,10 @@
#define RILCONF_DATA_CALL_RETRY_DELAY "dataCallRetryDelay"
#define RILCONF_LOCAL_HANGUP_REASONS "localHangupReasons"
#define RILCONF_REMOTE_HANGUP_REASONS "remoteHangupReasons"
#define RILCONF_DEFAULT_LEGACY_IMEI_QUERY "legacyImeiQuery"
#define RILCONF_LEGACY_IMEI_QUERY "legacyImeiQuery"
#define RILCONF_RADIO_POWER_CYCLE "radioPowerCycle"
#define RILCONF_CONFIRM_RADIO_POWER_ON "confirmRadioPowerOn"
#define RILCONF_SINGLE_DATA_CONTEXT "singleDataContext"
/* Modem error ids */
#define RIL_ERROR_ID_RILD_RESTART "rild-restart"
@@ -178,8 +194,8 @@ typedef struct sailfish_slot_impl {
char *imei;
char *imeisv;
char *name;
char *sockpath;
char *sub;
char *transport_name;
GHashTable *transport_params;
char *ecclist_file;
int timeout; /* RIL timeout, in milliseconds */
int index;
@@ -197,6 +213,7 @@ typedef struct sailfish_slot_impl {
struct ril_vendor_hook *vendor_hook;
struct ril_data *data;
gboolean legacy_imei_query;
enum sailfish_slot_flags slot_flags;
guint start_timeout;
guint start_timeout_id;
MceDisplay *display;
@@ -968,10 +985,12 @@ static void ril_plugin_slot_connected(ril_slot *slot)
slot->radio = ril_radio_new(slot->io);
GASSERT(!slot->io_event_id[IO_EVENT_RADIO_STATE_CHANGED]);
slot->io_event_id[IO_EVENT_RADIO_STATE_CHANGED] =
grilio_channel_add_unsol_event_handler(slot->io,
if (slot->config.confirm_radio_power_on) {
slot->io_event_id[IO_EVENT_RADIO_STATE_CHANGED] =
grilio_channel_add_unsol_event_handler(slot->io,
ril_plugin_radio_state_changed,
RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, slot);
}
GASSERT(!slot->sim_card);
slot->sim_card = ril_sim_card_new(slot->io, slot->config.slot,
@@ -1023,9 +1042,10 @@ static void ril_plugin_slot_connected(ril_slot *slot)
slot->start_timeout_id = 0;
/* Register this slot with the sailfish manager plugin */
slot->handle = sailfish_manager_slot_add(plugin->handle, slot,
slot->handle = sailfish_manager_slot_add2(plugin->handle, slot,
slot->path, slot->config.techs, slot->imei,
slot->imeisv, ril_plugin_sim_state(slot));
slot->imeisv, ril_plugin_sim_state(slot),
slot->slot_flags);
sailfish_manager_set_cell_info(slot->handle, slot->cell_info);
/* Check if this was the last slot we were waiting for */
@@ -1048,8 +1068,8 @@ static void ril_plugin_slot_connected_cb(GRilIoChannel *io, void *user_data)
static void ril_plugin_init_io(ril_slot *slot)
{
if (!slot->io) {
DBG("%s %s", slot->sockpath, slot->sub);
slot->io = grilio_channel_new_socket(slot->sockpath, slot->sub);
slot->io = grilio_channel_new(ofono_ril_transport_connect
(slot->transport_name, slot->transport_params));
if (slot->io) {
ril_debug_trace_update(slot);
ril_debug_dump_update(slot);
@@ -1105,7 +1125,7 @@ static void ril_plugin_retry_init_io(ril_slot *slot)
g_source_remove(slot->retry_id);
}
DBG("%s %s", slot->sockpath, slot->sub);
DBG("%s", slot->path);
slot->retry_id = g_timeout_add_seconds(RIL_RETRY_SECS,
ril_plugin_retry_init_io_cb, slot);
}
@@ -1133,7 +1153,7 @@ static void ril_slot_free(ril_slot *slot)
{
ril_plugin* plugin = slot->plugin;
DBG("%s", slot->sockpath);
DBG("%s", slot->path);
ril_plugin_shutdown_slot(slot, TRUE);
plugin->slots = g_slist_remove(plugin->slots, slot);
mce_display_remove_all_handlers(slot->display, slot->display_event_id);
@@ -1147,8 +1167,8 @@ static void ril_slot_free(ril_slot *slot)
g_free(slot->imei);
g_free(slot->imeisv);
g_free(slot->name);
g_free(slot->sockpath);
g_free(slot->sub);
g_free(slot->transport_name);
g_hash_table_destroy(slot->transport_params);
g_free(slot->ecclist_file);
g_free(slot);
}
@@ -1158,7 +1178,7 @@ static gboolean ril_plugin_slot_start_timeout(gpointer user_data)
ril_slot *slot = user_data;
ril_plugin* plugin = slot->plugin;
DBG("%s", slot->sockpath);
DBG("%s", slot->path);
plugin->slots = g_slist_remove(plugin->slots, slot);
slot->start_timeout_id = 0;
ril_slot_free(slot);
@@ -1166,25 +1186,31 @@ static gboolean ril_plugin_slot_start_timeout(gpointer user_data)
return G_SOURCE_REMOVE;
}
static ril_slot *ril_plugin_slot_new_take(char *sockpath, char *path,
char *name, guint slot_index)
static ril_slot *ril_plugin_slot_new_take(char *transport,
GHashTable *transport_params, char *dbus_path,
char *name, guint slot_index)
{
ril_slot *slot = g_new0(ril_slot, 1);
struct ril_slot_config *config = &slot->config;
slot->sockpath = sockpath;
slot->path = path;
slot->transport_name = transport;
slot->transport_params = transport_params;
slot->path = dbus_path;
slot->name = name;
config->slot = slot_index;
config->techs = RILMODEM_DEFAULT_TECHS;
config->lte_network_mode = RILMODEM_DEFAULT_LTE_MODE;
config->empty_pin_query = RILMODEM_DEFAULT_EMPTY_PIN_QUERY;
config->radio_power_cycle = RILMODEM_DEFAULT_RADIO_POWER_CYCLE;
config->confirm_radio_power_on =
RILMODEM_DEFAULT_CONFIRM_RADIO_POWER_ON;
config->enable_voicecall = RILMODEM_DEFAULT_ENABLE_VOICECALL;
config->enable_cbs = RILMODEM_DEFAULT_ENABLE_CBS;
config->query_available_band_mode =
RILMODEM_DEFAULT_QUERY_AVAILABLE_BAND_MODE;
slot->timeout = RILMODEM_DEFAULT_TIMEOUT;
slot->sim_flags = RILMODEM_DEFAULT_SIM_FLAGS;
slot->slot_flags = RILMODEM_DEFAULT_SLOT_FLAGS;
slot->legacy_imei_query = RILMODEM_DEFAULT_LEGACY_IMEI_QUERY;
slot->start_timeout = RILMODEM_DEFAULT_START_TIMEOUT;
slot->data_opt.allow_data = RILMODEM_DEFAULT_DATA_OPT;
@@ -1203,7 +1229,7 @@ static ril_slot *ril_plugin_slot_new_take(char *sockpath, char *path,
mce_display_add_state_changed_handler(slot->display,
ril_plugin_display_cb, slot);
slot->watch = sailfish_watch_new(path);
slot->watch = sailfish_watch_new(dbus_path);
slot->watch_event_id[WATCH_EVENT_MODEM] =
sailfish_watch_add_modem_changed_handler(slot->watch,
ril_plugin_slot_modem_changed, slot);
@@ -1233,11 +1259,23 @@ static void ril_plugin_slot_apply_vendor_defaults(ril_slot *slot)
}
}
static ril_slot *ril_plugin_slot_new(const char *sockpath, const char *path,
static ril_slot *ril_plugin_slot_new_socket(const char *sockpath,
const char *sub, const char *dbus_path,
const char *name, guint slot_index)
{
return ril_plugin_slot_new_take(g_strdup(sockpath), g_strdup(path),
g_strdup(name), slot_index);
/* RIL socket configuration */
GHashTable *params = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, g_free);
g_hash_table_insert(params, g_strdup(RIL_TRANSPORT_SOCKET_PATH),
g_strdup(sockpath));
if (sub) {
g_hash_table_insert(params, g_strdup(RIL_TRANSPORT_SOCKET_SUB),
g_strdup(sub));
}
return ril_plugin_slot_new_take(g_strdup(RIL_TRANSPORT_SOCKET), params,
g_strdup(dbus_path), g_strdup(name), slot_index);
}
static GSList *ril_plugin_create_default_config()
@@ -1246,55 +1284,135 @@ static GSList *ril_plugin_create_default_config()
if (g_file_test(RILMODEM_DEFAULT_SOCK2, G_FILE_TEST_EXISTS)) {
DBG("Falling back to default dual SIM config");
list = g_slist_append(list,
ril_plugin_slot_new(RILMODEM_DEFAULT_SOCK,
list = g_slist_append(list, ril_plugin_slot_new_socket
(RILMODEM_DEFAULT_SOCK, NULL,
RILCONF_PATH_PREFIX "0", "RIL1", 0));
list = g_slist_append(list,
ril_plugin_slot_new(RILMODEM_DEFAULT_SOCK2,
list = g_slist_append(list, ril_plugin_slot_new_socket
(RILMODEM_DEFAULT_SOCK2, NULL,
RILCONF_PATH_PREFIX "1", "RIL2", 1));
} else {
ril_slot *slot = ril_plugin_slot_new(RILMODEM_DEFAULT_SOCK,
RILCONF_PATH_PREFIX "0", "RIL", 0);
DBG("Falling back to default single SIM config");
slot->sub = g_strdup(RILMODEM_DEFAULT_SUB);
list = g_slist_append(list, slot);
list = g_slist_append(list, ril_plugin_slot_new_socket
(RILMODEM_DEFAULT_SOCK, RILMODEM_DEFAULT_SUB,
RILCONF_PATH_PREFIX "0", "RIL", 0));
}
return list;
}
/*
* Parse the spec according to the following grammar:
*
* spec: transport | transport ':' parameters
* params: param | params ';' param
* param: name '=' value
* transport: STRING
* name: STRING
* value: STRING
*
* For example, a RIL socket spec may look like this:
*
* socket:path=/dev/socket/rild;sub=SUB1
*/
static char *ril_plugin_parse_transport_spec(const char *spec,
GHashTable *params)
{
char *transport = NULL;
char *sep = strchr(spec, ':');
if (sep) {
transport = g_strstrip(g_strndup(spec, sep - spec));
if (transport[0]) {
char **list = g_strsplit(sep + 1, ";", 0);
char **ptr;
for (ptr = list; *ptr; ptr++) {
const char *p = *ptr;
sep = strchr(p, '=');
if (sep) {
char *name = g_strndup(p, sep - p);
char* value = g_strdup(sep + 1);
g_hash_table_insert(params,
g_strstrip(name),
g_strstrip(value));
}
}
g_strfreev(list);
return transport;
}
} else {
/* Use default transport attributes */
transport = g_strstrip(g_strdup(spec));
if (transport[0]) {
return transport;
}
}
g_free(transport);
return NULL;
}
static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
const char *group)
{
ril_slot *slot;
struct ril_slot_config *config;
gboolean bval;
int ival;
char *sval;
char **strv;
char *sock = g_key_file_get_string(file, group, RILCONF_SOCKET, NULL);
GHashTable *transport_params = g_hash_table_new_full(g_str_hash,
g_str_equal, g_free, g_free);
char *transport = NULL;
char *transport_spec = g_key_file_get_string(file, group,
RILCONF_TRANSPORT, NULL);
if (!sock) {
ofono_warn("no socket path for %s", group);
if (transport_spec) {
transport = ril_plugin_parse_transport_spec(transport_spec,
transport_params);
if (transport) {
DBG("%s: %s:%s", group, transport,
strchr(transport_spec, ':') + 1);
}
g_free(transport_spec);
} else {
/* Fall back to socket transport */
char *sockpath = g_key_file_get_string(file, group,
RILCONF_SOCKET, NULL);
if (sockpath) {
char *sub = g_key_file_get_string(file, group,
RILCONF_SUB, NULL);
transport = g_strdup(RIL_TRANSPORT_SOCKET);
g_hash_table_insert(transport_params,
g_strdup(RIL_TRANSPORT_SOCKET_PATH),
sockpath);
if (sub && strlen(sub) == RIL_SUB_SIZE) {
DBG("%s: %s:%s", group, sockpath, sub);
g_hash_table_insert(transport_params,
g_strdup(RIL_TRANSPORT_SOCKET_SUB),
sub);
} else {
DBG("%s: %s", group, sockpath);
g_free(sub);
}
}
}
if (!transport) {
ofono_warn("No usable RIL transport defined for %s", group);
g_hash_table_destroy(transport_params);
return NULL;
}
slot = ril_plugin_slot_new_take(sock,
slot = ril_plugin_slot_new_take(transport, transport_params,
g_strconcat("/", group, NULL),
ril_config_get_string(file, group, RILCONF_NAME),
RILMODEM_DEFAULT_SLOT);
config = &slot->config;
/* sub */
sval = ril_config_get_string(file, group, RILCONF_SUB);
if (sval && strlen(sval) == RIL_SUB_SIZE) {
DBG("%s: %s:%s", group, sock, sval);
slot->sub = sval;
} else {
DBG("%s: %s", group, sock);
g_free(sval);
}
/* slot */
if (ril_config_get_integer(file, group, RILCONF_SLOT, &ival) &&
ival >= 0) {
@@ -1414,6 +1532,28 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
config->empty_pin_query ? "on" : "off");
}
/* radioPowerCycle */
if (ril_config_get_boolean(file, group, RILCONF_RADIO_POWER_CYCLE,
&config->radio_power_cycle)) {
DBG("%s: " RILCONF_RADIO_POWER_CYCLE " %s", group,
config->radio_power_cycle ? "on" : "off");
}
/* confirmRadioPowerOn */
if (ril_config_get_boolean(file, group, RILCONF_CONFIRM_RADIO_POWER_ON,
&config->confirm_radio_power_on)) {
DBG("%s: " RILCONF_CONFIRM_RADIO_POWER_ON " %s", group,
config->confirm_radio_power_on ? "on" : "off");
}
/* singleDataContext */
if (ril_config_get_boolean(file, group, RILCONF_SINGLE_DATA_CONTEXT,
&bval) && bval) {
DBG("%s: " RILCONF_SINGLE_DATA_CONTEXT " %s", group,
bval ? "on" : "off");
slot->slot_flags |= SAILFISH_SLOT_SINGLE_CONTEXT;
}
/* uiccWorkaround */
if (ril_config_get_flag(file, group, RILCONF_UICC_WORKAROUND,
RIL_SIM_CARD_V9_UICC_SUBSCRIPTION_WORKAROUND,
@@ -1494,10 +1634,9 @@ static ril_slot *ril_plugin_parse_config_group(GKeyFile *file,
}
/* legacyImeiQuery */
if (ril_config_get_boolean(file, group,
RILCONF_DEFAULT_LEGACY_IMEI_QUERY,
if (ril_config_get_boolean(file, group, RILCONF_LEGACY_IMEI_QUERY,
&slot->legacy_imei_query)) {
DBG("%s: " RILCONF_DEFAULT_LEGACY_IMEI_QUERY " %s", group,
DBG("%s: " RILCONF_LEGACY_IMEI_QUERY " %s", group,
slot->legacy_imei_query ? "on" : "off");
}
@@ -1575,7 +1714,7 @@ static void ril_plugin_parse_identity(struct ril_plugin_identity *identity,
int n;
/* Try numeric */
if (ril_parse_int(group, 0, &n)) {
if (gutil_parse_int(group, 0, &n)) {
gr = getgrgid(n);
}
}
@@ -1587,7 +1726,7 @@ static void ril_plugin_parse_identity(struct ril_plugin_identity *identity,
int n;
/* Try numeric */
if (ril_parse_int(user, 0, &n)) {
if (gutil_parse_int(user, 0, &n)) {
pw = getpwuid(n);
}
}
@@ -1618,7 +1757,7 @@ static GSList *ril_plugin_parse_config_file(GKeyFile *file,
for (i=0; i<n; i++) {
const char *group = groups[i];
if (g_str_has_prefix(group, RILCONF_DEV_PREFIX)) {
if (g_str_has_prefix(group, RILCONF_MODEM_PREFIX)) {
/* Modem configuration */
ril_slot *slot = ril_plugin_parse_config_group(file,
group);
@@ -1942,10 +2081,31 @@ static void ril_slot_enabled_changed(struct sailfish_slot_impl *s)
}
}
/**
* RIL socket transport factory
*/
static struct grilio_transport *ril_socket_transport_connect(GHashTable *args)
{
const char* path = g_hash_table_lookup(args, RIL_TRANSPORT_SOCKET_PATH);
const char* sub = g_hash_table_lookup(args, RIL_TRANSPORT_SOCKET_SUB);
GASSERT(path);
if (path) {
DBG("%s %s", path, sub);
return grilio_transport_socket_new_path(path, sub);
}
return NULL;
}
/* Global part (that requires access to global variables) */
static struct sailfish_slot_driver_reg *ril_driver = NULL;
static guint ril_driver_init_id = 0;
static const struct ofono_ril_transport ril_socket_transport = {
.name = RIL_TRANSPORT_SOCKET,
.api_version = OFONO_RIL_TRANSPORT_API_VERSION,
.connect = ril_socket_transport_connect
};
static void ril_debug_trace_notify(struct ofono_debug_desc *desc)
{
@@ -1991,6 +2151,9 @@ static gboolean ril_plugin_start(gpointer user_data)
DBG("");
ril_driver_init_id = 0;
/* Socket transport can be registered right away */
ofono_ril_transport_register(&ril_socket_transport);
/* Register the driver */
ril_driver = sailfish_slot_driver_register(&ril_slot_driver);
return G_SOURCE_REMOVE;
@@ -2026,6 +2189,7 @@ static void ril_plugin_exit(void)
DBG("");
GASSERT(ril_driver);
ofono_ril_transport_unregister(&ril_socket_transport);
ofono_modem_driver_unregister(&ril_modem_driver);
ofono_sim_driver_unregister(&ril_sim_driver);
ofono_sms_driver_unregister(&ril_sms_driver);

View File

@@ -71,14 +71,16 @@ G_DEFINE_TYPE(RilRadio, ril_radio, G_TYPE_OBJECT)
#define RIL_RADIO_TYPE (ril_radio_get_type())
#define RIL_RADIO(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj,RIL_RADIO_TYPE,RilRadio))
#define DBG_(self,fmt,args...) DBG("%s" fmt, (self)->priv->log_prefix, ##args)
static void ril_radio_submit_power_request(struct ril_radio *self, gboolean on);
static inline gboolean ril_radio_power_should_be_on(struct ril_radio *self)
{
struct ril_radio_priv *priv = self->priv;
return self->online && !priv->power_cycle &&
g_hash_table_size(priv->req_table) > 0;
return (self->online || g_hash_table_size(priv->req_table) > 0) &&
!priv->power_cycle;
}
static inline gboolean ril_radio_state_off(enum ril_radio_state radio_state)
@@ -102,7 +104,7 @@ static gboolean ril_radio_power_request_retry_cb(gpointer user_data)
struct ril_radio *self = RIL_RADIO(user_data);
struct ril_radio_priv *priv = self->priv;
DBG("%s", priv->log_prefix);
DBG_(self, "");
GASSERT(priv->retry_id);
priv->retry_id = 0;
ril_radio_submit_power_request(self,
@@ -116,7 +118,7 @@ static void ril_radio_cancel_retry(struct ril_radio *self)
struct ril_radio_priv *priv = self->priv;
if (priv->retry_id) {
DBG("%sretry cancelled", priv->log_prefix);
DBG_(self, "retry cancelled");
g_source_remove(priv->retry_id);
priv->retry_id = 0;
}
@@ -129,8 +131,8 @@ static void ril_radio_check_state(struct ril_radio *self)
if (!priv->pending_id) {
gboolean should_be_on = ril_radio_power_should_be_on(self);
if (ril_radio_state_on(self->priv->last_known_state) ==
should_be_on) {
if (ril_radio_state_on(priv->last_known_state) ==
should_be_on) {
/* All is good, cancel pending retry if there is one */
ril_radio_cancel_retry(self);
} else if (priv->state_changed_while_request_pending) {
@@ -138,7 +140,7 @@ static void ril_radio_check_state(struct ril_radio *self)
ril_radio_submit_power_request(self, should_be_on);
} else if (!priv->retry_id) {
/* There has been no reaction so far, wait a bit */
DBG("%sretry scheduled", priv->log_prefix);
DBG_(self, "retry scheduled");
priv->retry_id = g_timeout_add_seconds(POWER_RETRY_SECS,
ril_radio_power_request_retry_cb, self);
}
@@ -147,33 +149,38 @@ static void ril_radio_check_state(struct ril_radio *self)
/* Don't update public state while something is pending */
if (!priv->pending_id && !priv->retry_id &&
self->state != priv->last_known_state) {
DBG("%s%s -> %s", priv->log_prefix,
ril_radio_state_to_string(self->state),
DBG_(self, "%s -> %s", ril_radio_state_to_string(self->state),
ril_radio_state_to_string(priv->last_known_state));
self->state = priv->last_known_state;
ril_radio_emit_signal(self, SIGNAL_STATE_CHANGED);
}
}
static void ril_radio_power_request_done(struct ril_radio *self)
{
struct ril_radio_priv *priv = self->priv;
GASSERT(priv->pending_id);
priv->pending_id = 0;
if (priv->next_state_valid) {
ril_radio_submit_power_request(self, priv->next_state);
} else {
ril_radio_check_state(self);
}
}
static void ril_radio_power_request_cb(GRilIoChannel *channel, int ril_status,
const void *data, guint len, void *user_data)
{
struct ril_radio *self = RIL_RADIO(user_data);
struct ril_radio_priv *priv = self->priv;
GASSERT(priv->pending_id);
priv->pending_id = 0;
if (ril_status != RIL_E_SUCCESS) {
ofono_error("Power request failed: %s",
ril_error_to_string(ril_status));
}
if (priv->next_state_valid) {
ril_radio_submit_power_request(self, priv->next_state);
} else {
ril_radio_check_state(self);
}
ril_radio_power_request_done(self);
}
static void ril_radio_submit_power_request(struct ril_radio *self, gboolean on)
@@ -214,13 +221,18 @@ static void ril_radio_power_request(struct ril_radio *self, gboolean on,
/* Wait for the pending request to complete */
priv->next_state_valid = TRUE;
priv->next_state = on;
DBG("%s%s (queued)", priv->log_prefix, on_off);
DBG_(self, "%s (queued)", on_off);
} else {
DBG("%s%s (ignored)", priv->log_prefix, on_off);
DBG_(self, "%s (ignored)", on_off);
}
} else {
DBG("%s%s", priv->log_prefix, on_off);
ril_radio_submit_power_request(self, on);
if (ril_radio_state_on(priv->last_known_state) == on) {
DBG_(self, "%s (already)", on_off);
ril_radio_check_state(self);
} else {
DBG_(self, "%s", on_off);
ril_radio_submit_power_request(self, on);
}
}
}
@@ -237,12 +249,12 @@ void ril_radio_power_cycle(struct ril_radio *self)
struct ril_radio_priv *priv = self->priv;
if (ril_radio_state_off(priv->last_known_state)) {
DBG("%spower is already off", priv->log_prefix);
DBG_(self, "power is already off");
GASSERT(!priv->power_cycle);
} else if (priv->power_cycle) {
DBG("%salready in progress", priv->log_prefix);
DBG_(self, "already in progress");
} else {
DBG("%sinitiated", priv->log_prefix);
DBG_(self, "initiated");
priv->power_cycle = TRUE;
if (!priv->pending_id) {
ril_radio_submit_power_request(self, FALSE);
@@ -259,7 +271,7 @@ void ril_radio_power_on(struct ril_radio *self, gpointer tag)
if (!g_hash_table_contains(priv->req_table, tag)) {
gboolean was_on = ril_radio_power_should_be_on(self);
DBG("%s%p", priv->log_prefix, tag);
DBG_(self, "%p", tag);
g_hash_table_insert(priv->req_table, tag, tag);
if (!was_on && ril_radio_power_should_be_on(self)) {
ril_radio_power_request(self, TRUE, FALSE);
@@ -274,7 +286,7 @@ void ril_radio_power_off(struct ril_radio *self, gpointer tag)
struct ril_radio_priv *priv = self->priv;
if (g_hash_table_remove(priv->req_table, tag)) {
DBG("%s%p", priv->log_prefix, tag);
DBG_(self, "%p", tag);
if (!ril_radio_power_should_be_on(self)) {
/* The last one turns the lights off */
ril_radio_power_request(self, FALSE, FALSE);
@@ -346,20 +358,41 @@ static void ril_radio_state_changed(GRilIoChannel *io, guint code,
if (radio_state != RADIO_STATE_UNAVAILABLE) {
struct ril_radio_priv *priv = self->priv;
DBG("%s%s", priv->log_prefix,
ril_radio_state_to_string(radio_state));
DBG_(self, "%s", ril_radio_state_to_string(radio_state));
GASSERT(!priv->pending_id || !priv->retry_id);
if (priv->power_cycle && ril_radio_state_off(radio_state)) {
DBG("%sswitched off for power cycle", priv->log_prefix);
DBG_(self, "switched off for power cycle");
priv->power_cycle = FALSE;
}
priv->last_known_state = radio_state;
if (priv->pending_id) {
priv->state_changed_while_request_pending++;
if (ril_radio_state_on(radio_state) ==
ril_radio_power_should_be_on(self)) {
DBG_(self, "dropping pending request");
/*
* All right, the modem has switched to the
* desired state, drop the request.
*/
grilio_queue_cancel_request(priv->q,
priv->pending_id, FALSE);
/*
* This will zero pending_id and call
* ril_radio_check_state() if necesary:
*/
ril_radio_power_request_done(self);
/* We are done */
return;
} else {
/* Something weird is going on */
priv->state_changed_while_request_pending++;
}
}
priv->last_known_state = radio_state;
ril_radio_check_state(self);
}
}
@@ -374,7 +407,7 @@ struct ril_radio *ril_radio_new(GRilIoChannel *io)
priv->log_prefix =
(io && io->name && io->name[0] && strcmp(io->name, "RIL")) ?
g_strconcat(io->name, " ", NULL) : g_strdup("");
DBG("%s", priv->log_prefix);
DBG_(self, "");
priv->state_event_id = grilio_channel_add_unsol_event_handler(priv->io,
ril_radio_state_changed,
RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, self);
@@ -431,7 +464,7 @@ static void ril_radio_finalize(GObject *object)
struct ril_radio *self = RIL_RADIO(object);
struct ril_radio_priv *priv = self->priv;
DBG("%s", priv->log_prefix);
DBG_(self, "");
g_free(priv->log_prefix);
grilio_channel_unref(priv->io);
grilio_queue_unref(priv->q);

View File

@@ -1284,6 +1284,24 @@ static GSList *ril_radio_caps_manager_empty_slots
return found;
}
static guint ril_radio_caps_manager_sim_count
(struct ril_radio_caps_manager *self)
{
const GPtrArray *list = self->caps_list;
guint i, count = 0;
for (i = 0; i < list->len; i++) {
const struct ril_radio_caps *caps = list->pdata[i];
if (caps->simcard->status->card_state ==
RIL_CARDSTATE_PRESENT) {
count++;
}
}
return count;
}
/**
* There could be no capability mismatch but LTE could be enabled for
* the slot that has no SIM card in it. That's a waste, fix it.
@@ -1327,7 +1345,7 @@ static void ril_radio_caps_manager_check(struct ril_radio_caps_manager *self)
if (ril_radio_caps_manager_can_check(self)) {
const int first = ril_radio_caps_manager_first_mismatch(self);
if (first >= 0) {
if (first >= 0 && ril_radio_caps_manager_sim_count(self) > 1) {
if (ril_radio_caps_manager_update_caps(self, first)) {
ril_radio_caps_manager_start_transaction(self);
}

View File

@@ -275,11 +275,6 @@ static void ril_sim_pin_req_done(gpointer ptr)
}
}
static const char *ril_sim_app_id(struct ril_sim *sd)
{
return sd->card->app ? sd->card->app->aid : NULL;
}
int ril_sim_app_type(struct ofono_sim *sim)
{
struct ril_sim *sd = ril_sim_get_data(sim);
@@ -504,7 +499,8 @@ static void ril_sim_request_io(struct ril_sim *sd, guint cmd, int fileid,
GRilIoRequest *req = grilio_request_new();
DBG_(sd, "cmd=0x%.2X,efid=0x%.4X,%d,%d,%d,%s,pin2=(null),aid=%s",
cmd, fileid, p1, p2, p3, hex_data, ril_sim_app_id(sd));
cmd, fileid, p1, p2, p3, hex_data,
ril_sim_card_app_aid(sd->card));
grilio_request_append_int32(req, cmd);
grilio_request_append_int32(req, fileid);
@@ -514,7 +510,7 @@ static void ril_sim_request_io(struct ril_sim *sd, guint cmd, int fileid,
grilio_request_append_int32(req, p3); /* P3 */
grilio_request_append_utf8(req, hex_data); /* data; only for writes */
grilio_request_append_utf8(req, NULL); /* pin2; only for writes */
grilio_request_append_utf8(req, ril_sim_app_id(sd));
grilio_request_append_utf8(req, ril_sim_card_app_aid(sd->card));
grilio_request_set_blocking(req, TRUE);
grilio_request_set_timeout(req, SIM_IO_TIMEOUT_SECS * 1000);
@@ -680,7 +676,7 @@ static void ril_sim_read_imsi(struct ofono_sim *sim, ofono_sim_imsi_cb_t cb,
void *data)
{
struct ril_sim *sd = ril_sim_get_data(sim);
const char *app_id = ril_sim_app_id(sd);
const char *app_id = ril_sim_card_app_aid(sd->card);
struct ril_sim_cbd_io *cbd = ril_sim_cbd_io_new(sd, cb, data);
GRilIoRequest *req = grilio_request_array_utf8_new(1, app_id);
@@ -902,25 +898,22 @@ static int ril_sim_parse_retry_count(const void *data, guint len)
static GRilIoRequest *ril_sim_enter_sim_pin_req(struct ril_sim *sd,
const char *pin)
{
if (sd->card->app) {
/*
* If there's no AID then so be it... Some
* adaptations (namely, MTK) don't provide it
* but don't seem to require it either.
*/
GRilIoRequest *req = grilio_request_array_utf8_new(2,
pin, sd->card->app->aid);
/*
* If there's no AID then so be it... Some
* adaptations (namely, MTK) don't provide it
* but don't seem to require it either.
*/
GRilIoRequest *req = grilio_request_array_utf8_new(2, pin,
ril_sim_card_app_aid(sd->card));
grilio_request_set_blocking(req, TRUE);
return req;
}
return NULL;
grilio_request_set_blocking(req, TRUE);
return req;
}
static GRilIoRequest *ril_sim_enter_sim_puk_req(struct ril_sim *sd,
const char *puk, const char *pin)
{
const char *app_id = ril_sim_app_id(sd);
const char *app_id = ril_sim_card_app_aid(sd->card);
if (app_id) {
GRilIoRequest *req = grilio_request_array_utf8_new(3,
puk, pin, app_id);
@@ -1222,7 +1215,7 @@ static void ril_sim_pin_send(struct ofono_sim *sim, const char *passwd,
GRilIoRequest *req = ril_sim_enter_sim_pin_req(sd, passwd);
if (req) {
DBG_(sd, "%s,aid=%s", passwd, ril_sim_app_id(sd));
DBG_(sd, "%s,aid=%s", passwd, ril_sim_card_app_aid(sd->card));
grilio_queue_send_request_full(sd->q, req,
RIL_REQUEST_ENTER_SIM_PIN, ril_sim_pin_change_state_cb,
ril_sim_pin_req_done, ril_sim_pin_cbd_new(sd,
@@ -1249,10 +1242,7 @@ static guint ril_perso_change_state(struct ofono_sim *sim,
case OFONO_SIM_PASSWORD_PHNET_PIN:
if (!enable) {
code = RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION;
req = grilio_request_sized_new(12);
grilio_request_append_int32(req,
RIL_PERSOSUBSTATE_SIM_NETWORK);
grilio_request_append_utf8(req, passwd);
req = grilio_request_array_utf8_new(1, passwd);
} else {
DBG_(sd, "Not supported, enable=%d", enable);
}
@@ -1301,7 +1291,7 @@ static void ril_sim_pin_change_state(struct ofono_sim *sim,
const char *passwd, ofono_sim_lock_unlock_cb_t cb, void *data)
{
struct ril_sim *sd = ril_sim_get_data(sim);
const char *app_id = ril_sim_app_id(sd);
const char *app_id = ril_sim_card_app_aid(sd->card);
const char *type_str = ril_sim_facility_code(passwd_type);
struct ofono_error error;
guint id = 0;
@@ -1339,7 +1329,7 @@ static void ril_sim_pin_send_puk(struct ofono_sim *sim,
if (req) {
DBG_(sd, "puk=%s,pin=%s,aid=%s", puk, passwd,
ril_sim_app_id(sd));
ril_sim_card_app_aid(sd->card));
grilio_queue_send_request_full(sd->q, req,
RIL_REQUEST_ENTER_SIM_PUK, ril_sim_pin_change_state_cb,
ril_sim_pin_req_done, ril_sim_pin_cbd_new(sd,
@@ -1359,7 +1349,7 @@ static void ril_sim_change_passwd(struct ofono_sim *sim,
ofono_sim_lock_unlock_cb_t cb, void *data)
{
struct ril_sim *sd = ril_sim_get_data(sim);
const char *app_id = ril_sim_app_id(sd);
const char *app_id = ril_sim_card_app_aid(sd->card);
GRilIoRequest *req = grilio_request_array_utf8_new(3,
old_passwd, new_passwd, app_id);
@@ -1411,7 +1401,7 @@ static void ril_sim_query_facility_lock(struct ofono_sim *sim,
const char *type_str = ril_sim_facility_code(type);
struct ril_sim_cbd_io *cbd = ril_sim_cbd_io_new(sd, cb, data);
GRilIoRequest *req = grilio_request_array_utf8_new(4,
type_str, "", "0" /* class */, ril_sim_app_id(sd));
type_str, "", "0" /* class */, ril_sim_card_app_aid(sd->card));
/* Make sure that this request gets completed sooner or later */
grilio_request_set_timeout(req, FAC_LOCK_QUERY_TIMEOUT_SECS * 1000);

View File

@@ -77,9 +77,10 @@ void ril_sim_card_remove_handler(struct ril_sim_card *sc, gulong id);
void ril_sim_card_remove_handlers(struct ril_sim_card *sc, gulong *ids, int n);
/* Inline wrappers */
static inline enum ril_app_type
ril_sim_card_app_type(struct ril_sim_card *sc)
static inline enum ril_app_type ril_sim_card_app_type(struct ril_sim_card *sc)
{ return (sc && sc->app) ? sc->app->app_type : RIL_APPTYPE_UNKNOWN; }
static inline const char *ril_sim_card_app_aid(struct ril_sim_card *sc)
{ return (sc && sc->app) ? sc->app->aid : NULL; }
#define ril_sim_card_remove_all_handlers(net, ids) \
ril_sim_card_remove_handlers(net, ids, G_N_ELEMENTS(ids))

View File

@@ -222,3 +222,30 @@ socket=/dev/socket/rild
# The default is 20000 (20 seconds)
#
#networkModeTimeout=20000
# Cycle radio power at startup.
#
# The default is true (cycle the power)
#
#radioPowerCycle=true
# With some RILs it seems to be necessary to kick (RIL_REQUEST_RADIO_POWER)
# the modems with power on after one of the modems has been powered off.
# Otherwise bad things may happen (like the modem never registering
# on the network).
#
# On the other hand, with some RILs it's causing some trouble (like this
# extra RIL_REQUEST_RADIO_POWER getting stuck indefinitely).
#
# The default is true for historical reasons
#
#confirmRadioPowerOn=true
# Normally we should be able to have two simultaneously active data
# contexts - one for mobile data and one for MMS. Some devices however
# require that mobile data is disconnected before we can send or receive
# MMS. In other words, activation of the second data context fails.
#
# The default is false (more than one context is supported)
#
#singleDataContext=false

View File

@@ -55,6 +55,8 @@ struct ril_slot_config {
int network_mode_timeout;
gboolean query_available_band_mode;
gboolean empty_pin_query;
gboolean radio_power_cycle;
gboolean confirm_radio_power_on;
gboolean enable_voicecall;
gboolean enable_cbs;
GUtilInts *local_hangup_reasons;

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2017 Jolla Ltd.
* Copyright (C) 2015-2018 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
@@ -18,10 +18,10 @@
#include <grilio_channel.h>
#include <gutil_misc.h>
#include <sys/socket.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include "common.h"
#include "netreg.h"
@@ -326,7 +326,7 @@ int ril_parse_tech(const char *stech, int *ril_tech)
{
int access_tech = -1;
int tech = -1;
if (ril_parse_int(stech, 0, &tech)) {
if (gutil_parse_int(stech, 0, &tech)) {
switch (tech) {
case RADIO_TECH_GPRS:
case RADIO_TECH_GSM:
@@ -411,26 +411,6 @@ gboolean ril_parse_mcc_mnc(const char *str, struct ofono_network_operator *op)
return FALSE;
}
gboolean ril_parse_int(const char *str, int base, int *value)
{
gboolean ok = FALSE;
if (str && str[0]) {
char *str2 = g_strstrip(g_strdup(str));
char *end = str2;
long l;
errno = 0;
l = strtol(str2, &end, base);
ok = !*end && errno != ERANGE && l >= INT_MIN && l <= INT_MAX;
if (ok && value) {
*value = (int)l;
}
g_free(str2);
}
return ok;
}
/*
* Local Variables:
* mode: C

View File

@@ -1,7 +1,7 @@
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2017 Jolla Ltd.
* Copyright (C) 2015-2018 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
@@ -26,7 +26,6 @@ const char *ril_unsol_event_to_string(guint event);
const char *ril_radio_state_to_string(int radio_state);
int ril_parse_tech(const char *stech, int *ril_tech);
gboolean ril_parse_mcc_mnc(const char *str, struct ofono_network_operator *op);
gboolean ril_parse_int(const char *str, int base, int *value);
#define ril_error_init_ok(err) \
((err)->error = 0, (err)->type = OFONO_ERROR_TYPE_NO_ERROR)

View File

@@ -693,7 +693,7 @@ static void ril_voicecall_supp_svc_notification_event(GRilIoChannel *io,
grilio_parser_get_int32(&rilp, &type);
grilio_parser_get_int32(&rilp, &code);
grilio_parser_get_int32(&rilp, &index);
grilio_parser_get_int32(&rilp, NULL);
grilio_parser_get_int32(&rilp, &phone.type);
tmp = grilio_parser_get_utf8(&rilp);
if (tmp) {

View File

@@ -54,7 +54,7 @@ static gboolean on_socket_connected(GIOChannel *chan, GIOCondition cond,
unsigned int len = sizeof(saddr);
int fd;
struct ofono_emulator *em;
struct ofono_modem *modem;
GList *i;
if (cond != G_IO_IN)
return FALSE;
@@ -63,15 +63,16 @@ static gboolean on_socket_connected(GIOChannel *chan, GIOCondition cond,
if (fd == -1)
return FALSE;
/* Pick the first powered modem */
modem = modems->data;
DBG("Picked modem %p for emulator", modem);
DBG("Using all modems for emulator.");
em = ofono_emulator_create(modem, GPOINTER_TO_INT(user));
if (em == NULL)
close(fd);
else
em = ofono_emulator_create(GPOINTER_TO_INT(user));
if (em) {
for (i = modems; i; i = i->next)
ofono_emulator_add_modem(em, i->data);
ofono_emulator_register(em, fd);
} else
close(fd);
return TRUE;
}

View File

@@ -68,8 +68,9 @@ typedef void (*ofono_emulator_request_cb_t)(struct ofono_emulator *em,
struct ofono_emulator_request *req,
void *data);
struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
enum ofono_emulator_type type);
struct ofono_emulator *ofono_emulator_create(enum ofono_emulator_type type);
void ofono_emulator_add_modem(struct ofono_emulator *em,
struct ofono_modem *modem);
void ofono_emulator_register(struct ofono_emulator *em, int fd);

View File

@@ -31,6 +31,7 @@ extern "C" {
struct ofono_modem;
struct ofono_gprs;
struct ofono_sim;
struct ofono_voicecall;
enum ofono_modem_type {
OFONO_MODEM_TYPE_HARDWARE = 0,
@@ -84,6 +85,7 @@ void ofono_modem_remove_interface(struct ofono_modem *modem,
const char *ofono_modem_get_path(struct ofono_modem *modem);
struct ofono_sim *ofono_modem_get_sim(struct ofono_modem *modem);
struct ofono_gprs *ofono_modem_get_gprs(struct ofono_modem *modem);
struct ofono_voicecall *ofono_modem_get_voicecall(struct ofono_modem *modem);
void ofono_modem_set_data(struct ofono_modem *modem, void *data);
void *ofono_modem_get_data(struct ofono_modem *modem);

View File

@@ -0,0 +1,284 @@
/*
* oFono - Open Source Telephony
*
* Copyright (C) 2018 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.
*/
#ifndef __OFONO_RIL_CONSTANTS_H
#define __OFONO_RIL_CONSTANTS_H
#ifdef __cplusplus
extern "C" {
#endif
/* Error Codes */
enum ril_status {
RIL_E_SUCCESS = 0,
RIL_E_RADIO_NOT_AVAILABLE = 1,
RIL_E_GENERIC_FAILURE = 2,
RIL_E_PASSWORD_INCORRECT = 3,
RIL_E_SIM_PIN2 = 4,
RIL_E_SIM_PUK2 = 5,
RIL_E_REQUEST_NOT_SUPPORTED = 6,
RIL_E_CANCELLED = 7,
RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL = 8,
RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW = 9,
RIL_E_SMS_SEND_FAIL_RETRY = 10,
RIL_E_SIM_ABSENT = 11,
RIL_E_SUBSCRIPTION_NOT_AVAILABLE = 12,
RIL_E_MODE_NOT_SUPPORTED = 13,
RIL_E_FDN_CHECK_FAILURE = 14,
RIL_E_ILLEGAL_SIM_OR_ME = 15,
RIL_E_MISSING_RESOURCE = 16,
RIL_E_NO_SUCH_ELEMENT = 17,
RIL_E_DIAL_MODIFIED_TO_USSD = 18,
RIL_E_DIAL_MODIFIED_TO_SS = 19,
RIL_E_DIAL_MODIFIED_TO_DIAL = 20,
RIL_E_USSD_MODIFIED_TO_DIAL = 21,
RIL_E_USSD_MODIFIED_TO_SS = 22,
RIL_E_USSD_MODIFIED_TO_USSD = 23,
RIL_E_SS_MODIFIED_TO_DIAL = 24,
RIL_E_SS_MODIFIED_TO_USSD = 25,
RIL_E_SUBSCRIPTION_NOT_SUPPORTED = 26,
RIL_E_SS_MODIFIED_TO_SS = 27,
RIL_E_LCE_NOT_SUPPORTED = 36,
RIL_E_NO_MEMORY = 37,
RIL_E_INTERNAL_ERR = 38,
RIL_E_SYSTEM_ERR = 39,
RIL_E_MODEM_ERR = 40,
RIL_E_INVALID_STATE = 41,
RIL_E_NO_RESOURCES = 42,
RIL_E_SIM_ERR = 43,
RIL_E_INVALID_ARGUMENTS = 44,
RIL_E_INVALID_SIM_STATE = 45,
RIL_E_INVALID_MODEM_STATE = 46,
RIL_E_INVALID_CALL_ID = 47,
RIL_E_NO_SMS_TO_ACK = 48,
RIL_E_NETWORK_ERR = 49,
RIL_E_REQUEST_RATE_LIMITED = 50,
RIL_E_SIM_BUSY = 51,
RIL_E_SIM_FULL = 52,
RIL_E_NETWORK_REJECT = 53,
RIL_E_OPERATION_NOT_ALLOWED = 54,
RIL_E_EMPTY_RECORD = 55,
RIL_E_INVALID_SMS_FORMAT = 56,
RIL_E_ENCODING_ERR = 57,
RIL_E_INVALID_SMSC_ADDRESS = 58,
RIL_E_NO_SUCH_ENTRY = 59,
RIL_E_NETWORK_NOT_READY = 60,
RIL_E_NOT_PROVISIONED = 61,
RIL_E_NO_SUBSCRIPTION = 62,
RIL_E_NO_NETWORK_FOUND = 63,
RIL_E_DEVICE_IN_USE = 64,
RIL_E_ABORTED = 65,
RIL_E_INVALID_RESPONSE = 66
};
/* RIL Request Messages, ofono -> rild */
#define RIL_REQUEST_GET_SIM_STATUS 1
#define RIL_REQUEST_ENTER_SIM_PIN 2
#define RIL_REQUEST_ENTER_SIM_PUK 3
#define RIL_REQUEST_ENTER_SIM_PIN2 4
#define RIL_REQUEST_ENTER_SIM_PUK2 5
#define RIL_REQUEST_CHANGE_SIM_PIN 6
#define RIL_REQUEST_CHANGE_SIM_PIN2 7
#define RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION 8
#define RIL_REQUEST_GET_CURRENT_CALLS 9
#define RIL_REQUEST_DIAL 10
#define RIL_REQUEST_GET_IMSI 11
#define RIL_REQUEST_HANGUP 12
#define RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND 13
#define RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND 14
#define RIL_REQUEST_SWITCH_HOLDING_AND_ACTIVE 15
#define RIL_REQUEST_CONFERENCE 16
#define RIL_REQUEST_UDUB 17
#define RIL_REQUEST_LAST_CALL_FAIL_CAUSE 18
#define RIL_REQUEST_SIGNAL_STRENGTH 19
#define RIL_REQUEST_VOICE_REGISTRATION_STATE 20
#define RIL_REQUEST_DATA_REGISTRATION_STATE 21
#define RIL_REQUEST_OPERATOR 22
#define RIL_REQUEST_RADIO_POWER 23
#define RIL_REQUEST_DTMF 24
#define RIL_REQUEST_SEND_SMS 25
#define RIL_REQUEST_SEND_SMS_EXPECT_MORE 26
#define RIL_REQUEST_SETUP_DATA_CALL 27
#define RIL_REQUEST_SIM_IO 28
#define RIL_REQUEST_SEND_USSD 29
#define RIL_REQUEST_CANCEL_USSD 30
#define RIL_REQUEST_GET_CLIR 31
#define RIL_REQUEST_SET_CLIR 32
#define RIL_REQUEST_QUERY_CALL_FORWARD_STATUS 33
#define RIL_REQUEST_SET_CALL_FORWARD 34
#define RIL_REQUEST_QUERY_CALL_WAITING 35
#define RIL_REQUEST_SET_CALL_WAITING 36
#define RIL_REQUEST_SMS_ACKNOWLEDGE 37
#define RIL_REQUEST_GET_IMEI 38
#define RIL_REQUEST_GET_IMEISV 39
#define RIL_REQUEST_ANSWER 40
#define RIL_REQUEST_DEACTIVATE_DATA_CALL 41
#define RIL_REQUEST_QUERY_FACILITY_LOCK 42
#define RIL_REQUEST_SET_FACILITY_LOCK 43
#define RIL_REQUEST_CHANGE_BARRING_PASSWORD 44
#define RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE 45
#define RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC 46
#define RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL 47
#define RIL_REQUEST_QUERY_AVAILABLE_NETWORKS 48
#define RIL_REQUEST_DTMF_START 49
#define RIL_REQUEST_DTMF_STOP 50
#define RIL_REQUEST_BASEBAND_VERSION 51
#define RIL_REQUEST_SEPARATE_CONNECTION 52
#define RIL_REQUEST_SET_MUTE 53
#define RIL_REQUEST_GET_MUTE 54
#define RIL_REQUEST_QUERY_CLIP 55
#define RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE 56
#define RIL_REQUEST_DATA_CALL_LIST 57
#define RIL_REQUEST_RESET_RADIO 58
#define RIL_REQUEST_OEM_HOOK_RAW 59
#define RIL_REQUEST_OEM_HOOK_STRINGS 60
#define RIL_REQUEST_SCREEN_STATE 61
#define RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION 62
#define RIL_REQUEST_WRITE_SMS_TO_SIM 63
#define RIL_REQUEST_DELETE_SMS_ON_SIM 64
#define RIL_REQUEST_SET_BAND_MODE 65
#define RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE 66
#define RIL_REQUEST_STK_GET_PROFILE 67
#define RIL_REQUEST_STK_SET_PROFILE 68
#define RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND 69
#define RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE 70
#define RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM 71
#define RIL_REQUEST_EXPLICIT_CALL_TRANSFER 72
#define RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE 73
#define RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE 74
#define RIL_REQUEST_GET_NEIGHBORING_CELL_IDS 75
#define RIL_REQUEST_SET_LOCATION_UPDATES 76
#define RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE 77
#define RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE 78
#define RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE 79
#define RIL_REQUEST_SET_TTY_MODE 80
#define RIL_REQUEST_QUERY_TTY_MODE 81
#define RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE 82
#define RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE 83
#define RIL_REQUEST_CDMA_FLASH 84
#define RIL_REQUEST_CDMA_BURST_DTMF 85
#define RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY 86
#define RIL_REQUEST_CDMA_SEND_SMS 87
#define RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE 88
#define RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG 89
#define RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG 90
#define RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION 91
#define RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG 92
#define RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG 93
#define RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION 94
#define RIL_REQUEST_CDMA_SUBSCRIPTION 95
#define RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM 96
#define RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM 97
#define RIL_REQUEST_DEVICE_IDENTITY 98
#define RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE 99
#define RIL_REQUEST_GET_SMSC_ADDRESS 100
#define RIL_REQUEST_SET_SMSC_ADDRESS 101
#define RIL_REQUEST_REPORT_SMS_MEMORY_STATUS 102
#define RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING 103
#define RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE 104
#define RIL_REQUEST_ISIM_AUTHENTICATION 105
#define RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU 106
#define RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS 107
#define RIL_REQUEST_VOICE_RADIO_TECH 108
#define RIL_REQUEST_GET_CELL_INFO_LIST 109
#define RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE 110
#define RIL_REQUEST_SET_INITIAL_ATTACH_APN 111
#define RIL_REQUEST_IMS_REGISTRATION_STATE 112
#define RIL_REQUEST_IMS_SEND_SMS 113
#define RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC 114
#define RIL_REQUEST_SIM_OPEN_CHANNEL 115
#define RIL_REQUEST_SIM_CLOSE_CHANNEL 116
#define RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL 117
#define RIL_REQUEST_NV_READ_ITEM 118
#define RIL_REQUEST_NV_WRITE_ITEM 119
#define RIL_REQUEST_NV_WRITE_CDMA_PRL 120
#define RIL_REQUEST_NV_RESET_CONFIG 121
/* SET_UICC_SUBSCRIPTION was 115 in v9 and 122 in v10 and later */
#define RIL_REQUEST_V9_SET_UICC_SUBSCRIPTION 115
#define RIL_REQUEST_SET_UICC_SUBSCRIPTION 122
#define RIL_REQUEST_ALLOW_DATA 123
#define RIL_REQUEST_GET_HARDWARE_CONFIG 124
#define RIL_REQUEST_SIM_AUTHENTICATION 125
#define RIL_REQUEST_GET_DC_RT_INFO 126
#define RIL_REQUEST_SET_DC_RT_INFO_RATE 127
#define RIL_REQUEST_SET_DATA_PROFILE 128
#define RIL_REQUEST_SHUTDOWN 129
#define RIL_REQUEST_GET_RADIO_CAPABILITY 130
#define RIL_REQUEST_SET_RADIO_CAPABILITY 131
/* RIL Unsolicited Messages, rild -> ofono */
#define RIL_UNSOL_RESPONSE_BASE 1000
#define RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED 1000
#define RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED 1001
#define RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED 1002
#define RIL_UNSOL_RESPONSE_NEW_SMS 1003
#define RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT 1004
#define RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM 1005
#define RIL_UNSOL_ON_USSD 1006
#define RIL_UNSOL_ON_USSD_REQUEST 1007
#define RIL_UNSOL_NITZ_TIME_RECEIVED 1008
#define RIL_UNSOL_SIGNAL_STRENGTH 1009
#define RIL_UNSOL_DATA_CALL_LIST_CHANGED 1010
#define RIL_UNSOL_SUPP_SVC_NOTIFICATION 1011
#define RIL_UNSOL_STK_SESSION_END 1012
#define RIL_UNSOL_STK_PROACTIVE_COMMAND 1013
#define RIL_UNSOL_STK_EVENT_NOTIFY 1014
#define RIL_UNSOL_STK_CALL_SETUP 1015
#define RIL_UNSOL_SIM_SMS_STORAGE_FULL 1016
#define RIL_UNSOL_SIM_REFRESH 1017
#define RIL_UNSOL_CALL_RING 1018
#define RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED 1019
#define RIL_UNSOL_RESPONSE_CDMA_NEW_SMS 1020
#define RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS 1021
#define RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL 1022
#define RIL_UNSOL_RESTRICTED_STATE_CHANGED 1023
#define RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE 1024
#define RIL_UNSOL_CDMA_CALL_WAITING 1025
#define RIL_UNSOL_CDMA_OTA_PROVISION_STATUS 1026
#define RIL_UNSOL_CDMA_INFO_REC 1027
#define RIL_UNSOL_OEM_HOOK_RAW 1028
#define RIL_UNSOL_RINGBACK_TONE 1029
#define RIL_UNSOL_RESEND_INCALL_MUTE 1030
#define RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED 1031
#define RIL_UNSOL_CDMA_PRL_CHANGED 1032
#define RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE 1033
#define RIL_UNSOL_RIL_CONNECTED 1034
#define RIL_UNSOL_VOICE_RADIO_TECH_CHANGED 1035
#define RIL_UNSOL_CELL_INFO_LIST 1036
#define RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED 1037
#define RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED 1038
#define RIL_UNSOL_SRVCC_STATE_NOTIFY 1039
#define RIL_UNSOL_HARDWARE_CONFIG_CHANGED 1040
#define RIL_UNSOL_DC_RT_INFO_CHANGED 1041
#define RIL_UNSOL_RADIO_CAPABILITY 1042
#define RIL_UNSOL_ON_SS 1043
#define RIL_UNSOL_STK_CC_ALPHA_NOTIFY 1044
/* A special request, ofono -> rild */
#define RIL_RESPONSE_ACKNOWLEDGEMENT 800
#ifdef __cplusplus
}
#endif
#endif /* __OFONO_RIL_CONSTANTS_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 8
* indent-tabs-mode: t
* End:
*/

View File

@@ -0,0 +1,64 @@
/*
* oFono - Open Source Telephony
*
* Copyright (C) 2018 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.
*/
#ifndef __OFONO_RIL_TRANSPORT_H
#define __OFONO_RIL_TRANSPORT_H
#include <ofono/types.h>
#include <glib.h>
#ifdef __cplusplus
extern "C" {
#endif
struct grilio_transport;
/*
* The api_version field makes it possible to keep using old plugins
* even if struct ofono_ril_transport gets extended with new callbacks.
*/
#define OFONO_RIL_TRANSPORT_API_VERSION (0)
/*
* The connect callback takes a (char*) -> (char*) hashtable containing
* transport-specific connection parameters. The caller receives a reference
* i.e. it has to unref the returned object.
*/
struct ofono_ril_transport {
const char *name;
int api_version; /* OFONO_RIL_TRANSPORT_API_VERSION */
struct grilio_transport *(*connect)(GHashTable *params);
};
int ofono_ril_transport_register(const struct ofono_ril_transport *t);
void ofono_ril_transport_unregister(const struct ofono_ril_transport *t);
struct grilio_transport *ofono_ril_transport_connect(const char *name,
GHashTable *params);
#ifdef __cplusplus
}
#endif
#endif /* __OFONO_RIL_TRANSPORT_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 8
* indent-tabs-mode: t
* End:
*/

View File

@@ -35,6 +35,18 @@ struct sailfish_cell_info;
typedef void (*sailfish_slot_manager_impl_cb_t)
(struct sailfish_slot_manager_impl *impl, void *user_data);
enum sailfish_slot_flags {
SAILFISH_SLOT_NO_FLAGS = 0,
/* Normally we should be able to have two simultaneously active
* data contexts - one for mobile data and one for MMS. The flag
* below says that for whatever reason it's impossible and mobile
* data has to be disconnected before we can send or receive MMS.
* On such devices it may not be a good idea to automatically
* download MMS because that would kill active mobile data
* connections. */
SAILFISH_SLOT_SINGLE_CONTEXT = 0x01
};
typedef struct sailfish_slot {
const char *path;
const char *imei;
@@ -81,6 +93,12 @@ struct sailfish_slot *sailfish_manager_slot_add
const char *path, enum ofono_radio_access_mode techs,
const char *imei, const char *imeisv,
enum sailfish_sim_state sim_state);
struct sailfish_slot *sailfish_manager_slot_add2
(struct sailfish_slot_manager *m, struct sailfish_slot_impl *i,
const char *path, enum ofono_radio_access_mode techs,
const char *imei, const char *imeisv,
enum sailfish_sim_state sim_state,
enum sailfish_slot_flags flags);
void sailfish_manager_imei_obtained(struct sailfish_slot *s, const char *imei);
void sailfish_manager_imeisv_obtained(struct sailfish_slot *s,
const char *imeisv);

View File

@@ -109,6 +109,7 @@ struct ofono_voicecall_filter {
void *data);
};
void ofono_voicecall_filter_notify(struct ofono_voicecall *vc);
int ofono_voicecall_filter_register(const struct ofono_voicecall_filter *f);
void ofono_voicecall_filter_unregister(const struct ofono_voicecall_filter *f);

View File

@@ -79,7 +79,7 @@ static const gchar *dun_record =
static void dun_gw_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
{
struct ofono_emulator *em = user_data;
struct ofono_modem *modem;
GList *i;
int fd;
DBG("");
@@ -90,16 +90,17 @@ static void dun_gw_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
return;
}
/* Pick the first powered modem */
modem = modems->data;
DBG("Picked modem %p for emulator", modem);
DBG("Using all modems for emulator");
em = ofono_emulator_create(modem, OFONO_EMULATOR_TYPE_DUN);
em = ofono_emulator_create(OFONO_EMULATOR_TYPE_DUN);
if (em == NULL) {
g_io_channel_shutdown(io, TRUE, NULL);
return;
}
for (i = modems; i; i = i->next)
ofono_emulator_add_modem(em, i->data);
fd = g_io_channel_unix_get_fd(io);
g_io_channel_set_close_on_unref(io, FALSE);

View File

@@ -56,7 +56,7 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
const char *device;
int fd;
struct ofono_emulator *em;
struct ofono_modem *modem;
GList *i;
DBG("Profile handler NewConnection");
@@ -80,7 +80,6 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
DBG("%s", device);
/* Pick the first powered modem */
if (modems == NULL) {
close(fd);
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
@@ -88,10 +87,9 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
"No GPRS capable modem");
}
modem = modems->data;
DBG("Picked modem %p for emulator", modem);
DBG("Using all modems for emulator.");
em = ofono_emulator_create(modem, OFONO_EMULATOR_TYPE_DUN);
em = ofono_emulator_create(OFONO_EMULATOR_TYPE_DUN);
if (em == NULL) {
close(fd);
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
@@ -99,6 +97,9 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
"Not enough resources");
}
for (i = modems; i; i = i->next)
ofono_emulator_add_modem(em, i->data);
ofono_emulator_register(em, fd);
return dbus_message_new_method_return(msg);

View File

@@ -91,6 +91,7 @@ static void hfp_ag_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
struct ofono_modem *modem;
struct ofono_emulator *em;
int fd;
GList *i;
DBG("");
@@ -99,17 +100,18 @@ static void hfp_ag_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
return;
}
/* Pick the first voicecall capable modem */
modem = modems->data;
if (modem == NULL)
if (modems == NULL)
return;
DBG("Picked modem %p for emulator", modem);
DBG("Using all modems for emulator");
em = ofono_emulator_create(modem, OFONO_EMULATOR_TYPE_HFP);
em = ofono_emulator_create(OFONO_EMULATOR_TYPE_HFP);
if (em == NULL)
return;
for (i = modems; i; i = i->next)
ofono_emulator_add_modem(em, i->data);
fd = g_io_channel_unix_get_fd(io);
g_io_channel_set_close_on_unref(io, FALSE);

View File

@@ -47,19 +47,18 @@ typedef struct GAtResult GAtResult;
#include "bluez5.h"
#include "bluetooth.h"
#ifndef DBUS_TYPE_UNIX_FD
#define DBUS_TYPE_UNIX_FD -1
#endif
#define HFP_AG_EXT_PROFILE_PATH "/bluetooth/profile/hfp_ag"
#define BT_ADDR_SIZE 18
#define HFP_AG_DRIVER "hfp-ag-driver"
static gboolean hfp_ag_enabled;
static guint service_watch_id;
static guint modemwatch_id;
static GList *modems;
static GHashTable *sim_hash = NULL;
static GHashTable *connection_hash;
static struct ofono_emulator *emulator = NULL;
static int hfp_card_probe(struct ofono_handsfree_card *card,
unsigned int vendor, void *data)
@@ -72,6 +71,8 @@ static int hfp_card_probe(struct ofono_handsfree_card *card,
static void hfp_card_remove(struct ofono_handsfree_card *card)
{
DBG("");
emulator = NULL;
}
static void codec_negotiation_done_cb(int err, void *data)
@@ -172,9 +173,9 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
struct sockaddr_rc saddr;
socklen_t optlen;
struct ofono_emulator *em;
struct ofono_modem *modem;
char local[BT_ADDR_SIZE], remote[BT_ADDR_SIZE];
struct ofono_handsfree_card *card;
GList *i;
int err;
DBG("Profile handler NewConnection");
@@ -202,7 +203,6 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
goto invalid;
}
/* Pick the first voicecall capable modem */
if (modems == NULL) {
close(fd);
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
@@ -210,9 +210,7 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
"No voice call capable modem");
}
modem = modems->data;
DBG("Picked modem %p for emulator", modem);
DBG("Using all modems for emulator.");
memset(&saddr, 0, sizeof(saddr));
optlen = sizeof(saddr);
@@ -240,7 +238,7 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
bt_ba2str(&saddr.rc_bdaddr, remote);
em = ofono_emulator_create(modem, OFONO_EMULATOR_TYPE_HFP);
em = ofono_emulator_create(OFONO_EMULATOR_TYPE_HFP);
if (em == NULL) {
close(fd);
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
@@ -248,6 +246,10 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
"Not enough resources");
}
for (i = modems; i; i = i->next)
ofono_emulator_add_modem(em, i->data);
emulator = em;
ofono_emulator_register(em, fd);
fd_dup = dup(fd);
@@ -367,6 +369,9 @@ static void sim_state_watch(enum ofono_sim_state new_state, void *data)
modems = g_list_append(modems, modem);
if (emulator)
ofono_emulator_add_modem(emulator, modem);
if (modems->next != NULL)
return;
@@ -459,29 +464,27 @@ static void call_modemwatch(struct ofono_modem *modem, void *user)
modem_watch(modem, TRUE, user);
}
static int hfp_ag_init(void)
static void hfp_ag_enable(DBusConnection *conn)
{
DBusConnection *conn = ofono_dbus_get_connection();
int err;
if (DBUS_TYPE_UNIX_FD < 0)
return -EBADF;
/* Registers External Profile handler */
if (!g_dbus_register_interface(conn, HFP_AG_EXT_PROFILE_PATH,
BLUEZ_PROFILE_INTERFACE,
profile_methods, NULL,
NULL, NULL, NULL)) {
if (!g_dbus_register_interface(conn,
HFP_AG_EXT_PROFILE_PATH,
BLUEZ_PROFILE_INTERFACE,
profile_methods,
NULL, NULL, NULL, NULL)) {
ofono_error("Register Profile interface failed: %s",
HFP_AG_EXT_PROFILE_PATH);
return -EIO;
HFP_AG_EXT_PROFILE_PATH);
return;
}
err = ofono_handsfree_card_driver_register(&hfp_ag_driver);
if (err < 0) {
g_dbus_unregister_interface(conn, HFP_AG_EXT_PROFILE_PATH,
BLUEZ_PROFILE_INTERFACE);
return err;
BLUEZ_PROFILE_INTERFACE);
ofono_error("Failed to register driver: %d", err);
return;
}
sim_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
@@ -490,10 +493,65 @@ static int hfp_ag_init(void)
__ofono_modem_foreach(call_modemwatch, NULL);
connection_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, connection_destroy);
g_free, connection_destroy);
ofono_handsfree_audio_ref();
hfp_ag_enabled = TRUE;
}
static void hfp_ag_disable(DBusConnection *conn)
{
if (modemwatch_id) {
__ofono_modemwatch_remove(modemwatch_id);
modemwatch_id = 0;
}
if (connection_hash) {
g_hash_table_destroy(connection_hash);
connection_hash = NULL;
}
g_list_free(modems);
modems = NULL;
if (sim_hash) {
g_hash_table_foreach_remove(sim_hash, sim_watch_remove, NULL);
g_hash_table_destroy(sim_hash);
sim_hash = NULL;
}
if (hfp_ag_enabled) {
g_dbus_unregister_interface(conn, HFP_AG_EXT_PROFILE_PATH,
BLUEZ_PROFILE_INTERFACE);
ofono_handsfree_card_driver_unregister(&hfp_ag_driver);
ofono_handsfree_audio_unref();
}
hfp_ag_enabled = FALSE;
}
static void bluez_connect_cb(DBusConnection *connection, void *user_data)
{
hfp_ag_enable(connection);
}
static void bluez_disconnect_cb(DBusConnection *connection, void *user_data)
{
hfp_ag_disable(connection);
}
static int hfp_ag_init(void)
{
DBusConnection *conn = ofono_dbus_get_connection();
hfp_ag_enable(conn);
service_watch_id = g_dbus_add_service_watch(conn, "org.bluez",
bluez_connect_cb,
bluez_disconnect_cb,
NULL, NULL);
return 0;
}
@@ -501,19 +559,12 @@ static void hfp_ag_exit(void)
{
DBusConnection *conn = ofono_dbus_get_connection();
__ofono_modemwatch_remove(modemwatch_id);
g_dbus_unregister_interface(conn, HFP_AG_EXT_PROFILE_PATH,
BLUEZ_PROFILE_INTERFACE);
if (service_watch_id) {
g_dbus_remove_watch(conn, service_watch_id);
service_watch_id = 0;
}
ofono_handsfree_card_driver_unregister(&hfp_ag_driver);
g_hash_table_destroy(connection_hash);
g_list_free(modems);
g_hash_table_foreach_remove(sim_hash, sim_watch_remove, NULL);
g_hash_table_destroy(sim_hash);
ofono_handsfree_audio_unref();
hfp_ag_disable(conn);
}
OFONO_PLUGIN_DEFINE(hfp_ag_bluez5, "Hands-Free Audio Gateway Profile Plugins",

View File

@@ -89,6 +89,7 @@ struct sailfish_slot_priv {
struct sailfish_cell_info *cellinfo;
struct sailfish_cell_info_dbus *cellinfo_dbus;
enum sailfish_sim_state sim_state;
enum sailfish_slot_flags flags;
gulong watch_event_id[WATCH_EVENT_COUNT];
char *imei;
char *imeisv;
@@ -320,6 +321,17 @@ struct sailfish_slot *sailfish_manager_slot_add
const char *path, enum ofono_radio_access_mode techs,
const char *imei, const char *imeisv,
enum sailfish_sim_state sim_state)
{
return sailfish_manager_slot_add2(m, impl, path, techs, imei, imeisv,
sim_state, SAILFISH_SLOT_NO_FLAGS);
}
struct sailfish_slot *sailfish_manager_slot_add2
(struct sailfish_slot_manager *m, struct sailfish_slot_impl *impl,
const char *path, enum ofono_radio_access_mode techs,
const char *imei, const char *imeisv,
enum sailfish_sim_state sim_state,
enum sailfish_slot_flags flags)
{
/* Only accept these calls when we are starting! We have been
* assuming all along that the number of slots is known right
@@ -339,6 +351,7 @@ struct sailfish_slot *sailfish_manager_slot_add
s->impl = impl;
s->manager = m;
s->sim_state = sim_state;
s->flags = flags;
s->watch = sailfish_watch_new(path);
s->siminfo = sailfish_sim_info_new(path);
s->siminfo_dbus = sailfish_sim_info_dbus_new(s->siminfo);
@@ -649,10 +662,12 @@ static int sailfish_manager_update_modem_paths(struct sailfish_manager_priv *p)
mms_slot = sailfish_manager_find_slot_imsi(p, p->mms_imsi);
}
if (mms_slot && mms_slot != slot) {
if (mms_slot && (mms_slot != slot ||
(slot->flags & SAILFISH_SLOT_SINGLE_CONTEXT))) {
/*
* Reset default data SIM if another SIM is
* temporarily selected for MMS.
* Reset default data SIM if
* a) another SIM is temporarily selected for MMS; or
* b) this slot can't have more than one context active.
*/
slot = NULL;
}

View File

@@ -51,7 +51,9 @@ struct hfp_codec_info {
};
struct ofono_emulator {
struct ofono_atom *atom;
GList *atoms;
GList *registered_atoms;
gboolean emulator_registered;
enum ofono_emulator_type type;
GAtServer *server;
GAtPPP *ppp;
@@ -355,10 +357,17 @@ static struct indicator *find_indicator(struct ofono_emulator *em,
static struct ofono_call *find_call_with_status(struct ofono_emulator *em,
int status)
{
struct ofono_modem *modem = __ofono_atom_get_modem(em->atom);
struct ofono_voicecall *vc;
struct ofono_modem *modem;
struct ofono_voicecall *vc = NULL;
GList *i;
for (i = em->atoms; i; i = i->next) {
modem = __ofono_atom_get_modem(i->data);
if ((vc = __ofono_atom_find(OFONO_ATOM_TYPE_VOICECALL, modem)))
break;
}
vc = __ofono_atom_find(OFONO_ATOM_TYPE_VOICECALL, modem);
if (vc == NULL)
return NULL;
@@ -1153,7 +1162,20 @@ static void emulator_unregister(struct ofono_atom *atom)
struct ofono_emulator *em = __ofono_atom_get_data(atom);
GSList *l;
DBG("%p", em);
DBG("%p (atom %p)", em, atom);
em->registered_atoms = g_list_remove(em->registered_atoms, atom);
if (em->registered_atoms)
return;
if (!em->emulator_registered) {
DBG("emulator already unregistered");
return;
}
em->emulator_registered = FALSE;
DBG("%p no more atoms registered", em);
if (em->callsetup_source) {
g_source_remove(em->callsetup_source);
@@ -1185,12 +1207,27 @@ static void emulator_unregister(struct ofono_atom *atom)
em->card = NULL;
}
static void emulator_register_atom(struct ofono_emulator *em, struct ofono_atom *atom)
{
if (!g_list_find(em->registered_atoms, atom)) {
em->registered_atoms = g_list_append(em->registered_atoms, atom);
DBG("%p", atom);
__ofono_atom_register(atom, emulator_unregister);
}
}
void ofono_emulator_register(struct ofono_emulator *em, int fd)
{
GIOChannel *io;
GList *i;
DBG("%p, %d", em, fd);
if (em->emulator_registered) {
DBG("emulator already registered");
return;
}
if (fd < 0)
return;
@@ -1240,7 +1277,8 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)
g_at_server_register(em->server, "+BCS", bcs_cb, em, NULL);
}
__ofono_atom_register(em->atom, emulator_unregister);
for (i = em->atoms; i; i = i->next)
emulator_register_atom(em, i->data);
switch (em->type) {
case OFONO_EMULATOR_TYPE_DUN:
@@ -1254,31 +1292,41 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)
default:
break;
}
em->emulator_registered = TRUE;
}
static void emulator_free(struct ofono_emulator *em)
{
g_assert(!em->atoms);
DBG("free emulator %p", em);
if (em->registered_atoms)
g_list_free(em->registered_atoms);
g_free(em);
}
static void emulator_remove(struct ofono_atom *atom)
{
struct ofono_emulator *em = __ofono_atom_get_data(atom);
DBG("atom: %p", atom);
DBG("remove atom %p", atom);
em->atoms = g_list_remove(em->atoms, atom);
g_free(em);
if (!em->atoms)
emulator_free(em);
}
struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
enum ofono_emulator_type type)
struct ofono_emulator *ofono_emulator_create(enum ofono_emulator_type type)
{
struct ofono_emulator *em;
enum ofono_atom_type atom_t;
DBG("modem: %p, type: %d", modem, type);
if (type == OFONO_EMULATOR_TYPE_DUN)
atom_t = OFONO_ATOM_TYPE_EMULATOR_DUN;
else if (type == OFONO_EMULATOR_TYPE_HFP)
atom_t = OFONO_ATOM_TYPE_EMULATOR_HFP;
else
if (type != OFONO_EMULATOR_TYPE_DUN && type != OFONO_EMULATOR_TYPE_HFP) {
DBG("unsupported emulator type %d", type);
return NULL;
}
DBG("create emulator of type %d", type);
em = g_try_new0(struct ofono_emulator, 1);
@@ -1296,15 +1344,59 @@ struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
em->events_mode = 3; /* default mode is forwarding events */
em->cmee_mode = 0; /* CME ERROR disabled by default */
em->atom = __ofono_modem_add_atom_offline(modem, atom_t,
emulator_remove, em);
return em;
}
void ofono_emulator_add_modem(struct ofono_emulator *em,
struct ofono_modem *modem)
{
struct ofono_atom *atom;
enum ofono_atom_type atom_t;
if (em->type == OFONO_EMULATOR_TYPE_DUN)
atom_t = OFONO_ATOM_TYPE_EMULATOR_DUN;
else
atom_t = OFONO_ATOM_TYPE_EMULATOR_HFP;
if ((atom = __ofono_modem_find_atom(modem, atom_t))) {
if (g_list_find(em->atoms, atom)) {
DBG("modem %p already added", modem);
goto register_atom;
}
}
DBG("%p", modem);
atom = __ofono_modem_add_atom_offline(modem, atom_t,
emulator_remove, em);
em->atoms = g_list_append(em->atoms, atom);
register_atom:
if (em->emulator_registered)
emulator_register_atom(em, atom);
}
void ofono_emulator_remove(struct ofono_emulator *em)
{
__ofono_atom_free(em->atom);
GList *remove_list;
GList *i;
DBG("");
/* If emulator has atoms we make a copy of the atom list here,
* as the list is modified when the atoms are being destroyed.
* When last atom is gone struct ofono_emulator is freed as
* well (in emulator_remove()). */
if (em->atoms) {
remove_list = g_list_copy(em->atoms);
for (i = remove_list; i; i = i->next) {
DBG("free atom %p", i->data);
__ofono_atom_free(i->data);
}
g_list_free(remove_list);
} else {
emulator_free(em);
}
}
void ofono_emulator_send_final(struct ofono_emulator *em,

View File

@@ -912,6 +912,7 @@ void ofono_handsfree_audio_unref(void)
if (agent) {
agent_release(agent);
agent_free(agent);
agent = NULL;
}
__ofono_handsfree_audio_manager_cleanup();

View File

@@ -195,6 +195,11 @@ struct ofono_gprs *ofono_modem_get_gprs(struct ofono_modem *modem)
return __ofono_atom_find(OFONO_ATOM_TYPE_GPRS, modem);
}
struct ofono_voicecall *ofono_modem_get_voicecall(struct ofono_modem *modem)
{
return __ofono_atom_find(OFONO_ATOM_TYPE_VOICECALL, modem);
}
struct ofono_atom *__ofono_modem_add_atom(struct ofono_modem *modem,
enum ofono_atom_type type,
void (*destruct)(struct ofono_atom *),

View File

@@ -626,6 +626,10 @@ void __ofono_voicecall_filter_chain_dial(struct voicecall_filter_chain *c,
enum ofono_clir_option clir,
ofono_voicecall_filter_dial_cb_t cb,
ofono_destroy_func destroy, void *user_data);
void __ofono_voicecall_filter_chain_dial_check(struct voicecall_filter_chain *c,
const struct ofono_call *call,
ofono_voicecall_filter_dial_cb_t cb,
ofono_destroy_func destroy, void *user_data);
void __ofono_voicecall_filter_chain_incoming(struct voicecall_filter_chain *c,
const struct ofono_call *call,
ofono_voicecall_filter_incoming_cb_t cb,

View File

@@ -211,17 +211,26 @@ void __ofono_plugin_cleanup(void)
DBG("");
/*
* Terminate the plugins but don't unload the libraries yet.
* Plugins may reference data structures allocated by each other.
*/
for (list = plugins; list; list = list->next) {
struct ofono_plugin *plugin = list->data;
if (plugin->active == TRUE && plugin->desc->exit)
plugin->desc->exit();
}
/* Second pass - unload the libraries */
for (list = plugins; list; list = list->next) {
struct ofono_plugin *plugin = list->data;
if (plugin->handle)
dlclose(plugin->handle);
g_free(plugin);
}
g_slist_free(plugins);
/* Finally, free the memory */
g_slist_free_full(plugins, g_free);
plugins = NULL;
}

78
ofono/src/ril-transport.c Normal file
View File

@@ -0,0 +1,78 @@
/*
* oFono - Open Source Telephony
*
* Copyright (C) 2018 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.
*/
#include <ofono/ril-transport.h>
#include <ofono/log.h>
#include <string.h>
#include <errno.h>
static GSList *ril_transports = NULL;
struct grilio_transport *ofono_ril_transport_connect(const char *name,
GHashTable *params)
{
if (name) {
GSList *l;
for (l = ril_transports; l; l = l->next) {
const struct ofono_ril_transport *t = l->data;
if (!strcmp(name, t->name)) {
return t->connect ? t->connect(params) : NULL;
}
}
ofono_error("Unknown RIL transport: %s", name);
}
return NULL;
}
int ofono_ril_transport_register(const struct ofono_ril_transport *t)
{
if (!t || !t->name) {
return -EINVAL;
} else {
GSList *l;
for (l = ril_transports; l; l = l->next) {
const struct ofono_ril_transport *t1 = l->data;
if (!strcmp(t->name, t1->name)) {
DBG("%s already registered", t->name);
return -EALREADY;
}
}
DBG("%s", t->name);
ril_transports = g_slist_append(ril_transports, (void*)t);
return 0;
}
}
void ofono_ril_transport_unregister(const struct ofono_ril_transport *t)
{
if (t && t->name) {
DBG("%s", t->name);
ril_transports = g_slist_remove(ril_transports, t);
}
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 8
* indent-tabs-mode: t
* End:
*/

View File

@@ -565,6 +565,29 @@ void __ofono_voicecall_filter_chain_dial(struct voicecall_filter_chain *chain,
}
}
void __ofono_voicecall_filter_chain_dial_check(struct voicecall_filter_chain *c,
const struct ofono_call *call,
ofono_voicecall_filter_dial_cb_t cb,
ofono_destroy_func destroy, void *user_data)
{
if (c && voicecall_filters && call && cb) {
struct voicecall_filter_request *req =
voicecall_filter_request_dial_new(c,
&call->phone_number, OFONO_CLIR_OPTION_DEFAULT,
cb, destroy, user_data);
req->call = call;
voicecall_filter_request_process(req);
} else {
if (cb) {
cb(OFONO_VOICECALL_FILTER_DIAL_CONTINUE, user_data);
}
if (destroy) {
destroy(user_data);
}
}
}
void __ofono_voicecall_filter_chain_incoming(struct voicecall_filter_chain *fc,
const struct ofono_call *call,
ofono_voicecall_filter_incoming_cb_t cb,

View File

@@ -704,6 +704,9 @@ static void voicecall_destroy(gpointer userdata)
{
struct voicecall *voicecall = (struct voicecall *)userdata;
__ofono_voicecall_filter_chain_cancel(voicecall->vc->filters,
voicecall->call);
g_free(voicecall->call);
g_free(voicecall->message);
@@ -1515,6 +1518,133 @@ static void manager_dial_callback(const struct ofono_error *error, void *data)
voicecalls_emit_call_added(vc, v);
}
static void dummy_callback(const struct ofono_error *error, void *data)
{
if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
DBG("command failed with error: %s",
telephony_error_to_str(error));
}
static void filter_hangup(struct voicecall *v)
{
struct ofono_voicecall *vc = v->vc;
const struct ofono_call *call = v->call;
const struct ofono_voicecall_driver *driver = vc->driver;
switch (call->status) {
case OFONO_CALL_STATUS_WAITING:
if (driver->set_udub) {
driver->set_udub(vc, dummy_callback, vc);
return;
} else if (driver->release_specific) {
driver->release_specific(vc, call->id,
dummy_callback, vc);
return;
}
break;
case OFONO_CALL_STATUS_ACTIVE:
case OFONO_CALL_STATUS_DIALING:
case OFONO_CALL_STATUS_ALERTING:
if (driver->hangup_active) {
driver->hangup_active(vc, dummy_callback, vc);
return;
}
/* no break */
default:
if (driver->release_specific) {
driver->release_specific(vc, call->id,
dummy_callback, vc);
return;
}
break;
}
ofono_warn("Couldn't disconnect %s call %d",
call_status_to_string(call->status), call->id);
}
static void filter_dial_check_cb(enum ofono_voicecall_filter_dial_result result,
void *data)
{
struct voicecall *v = data;
if (result == OFONO_VOICECALL_FILTER_DIAL_CONTINUE) {
DBG("No need to release %s call %d",
call_status_to_string(v->call->status), v->call->id);
} else {
DBG("Need to release %s call %d",
call_status_to_string(v->call->status), v->call->id);
filter_hangup(v);
}
}
static void filter_incoming_check_cb
(enum ofono_voicecall_filter_incoming_result result, void *data)
{
struct voicecall *v = data;
if (result == OFONO_VOICECALL_FILTER_INCOMING_CONTINUE) {
DBG("No need to release %s call %d",
call_status_to_string(v->call->status), v->call->id);
} else {
DBG("Need to release %s call %d",
call_status_to_string(v->call->status), v->call->id);
filter_hangup(v);
}
}
static void filter_incoming_cb(enum ofono_voicecall_filter_incoming_result res,
void *data)
{
struct voicecall *v = data;
struct ofono_voicecall *vc = v->vc;
vc->incoming_filter_list = g_slist_remove(vc->incoming_filter_list, v);
if (res == OFONO_VOICECALL_FILTER_INCOMING_HANGUP) {
if (vc->driver->release_specific) {
vc->driver->release_specific(vc, v->call->id,
dummy_callback, vc);
}
voicecall_destroy(v);
} else if (res == OFONO_VOICECALL_FILTER_INCOMING_IGNORE) {
voicecall_destroy(v);
} else if (voicecall_dbus_register(v)) {
struct ofono_voicecall *vc = v->vc;
vc->call_list = g_slist_insert_sorted(vc->call_list, v,
call_compare);
voicecalls_emit_call_added(vc, v);
}
}
void ofono_voicecall_filter_notify(struct ofono_voicecall *vc)
{
GSList *l;
struct voicecall *v;
/* Cancel all active filtering requests */
__ofono_voicecall_filter_chain_cancel(vc->filters, NULL);
/* Re-check incoming_filter_list */
for (l = vc->incoming_filter_list; l; l = l->next) {
v = l->data;
__ofono_voicecall_filter_chain_incoming(vc->filters, v->call,
filter_incoming_cb, NULL, v);
}
/* Re-check the calls that have already passed the filter */
for (l = vc->call_list; l; l = l->next) {
v = l->data;
if (v->call->direction == CALL_DIRECTION_MOBILE_ORIGINATED) {
__ofono_voicecall_filter_chain_dial_check(vc->filters,
v->call, filter_dial_check_cb, NULL, v);
} else {
__ofono_voicecall_filter_chain_incoming(vc->filters,
v->call, filter_incoming_check_cb, NULL, v);
}
}
}
static void dial_filter_cb(enum ofono_voicecall_filter_dial_result result,
void *req_data)
{
@@ -2326,12 +2456,10 @@ void ofono_voicecall_disconnected(struct ofono_voicecall *vc, int id,
if (l) {
/* Incoming call was disconnected in the process of being
* filtered. Cancel the filtering. */
call = l->data;
__ofono_voicecall_filter_chain_cancel(vc->filters, call->call);
* filtered. voicecall_destroy cancels it. */
vc->incoming_filter_list = g_slist_delete_link
(vc->incoming_filter_list, l);
voicecall_destroy(call);
voicecall_destroy(l->data);
return;
}
@@ -2405,37 +2533,6 @@ void ofono_voicecall_disconnected(struct ofono_voicecall *vc, int id,
vc->call_list = g_slist_remove(vc->call_list, call);
}
static void dummy_callback(const struct ofono_error *error, void *data)
{
if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
DBG("command failed with error: %s",
telephony_error_to_str(error));
}
static void filter_incoming_cb(enum ofono_voicecall_filter_incoming_result res,
void *data)
{
struct voicecall *v = data;
struct ofono_voicecall *vc = v->vc;
vc->incoming_filter_list = g_slist_remove(vc->incoming_filter_list, v);
if (res == OFONO_VOICECALL_FILTER_INCOMING_HANGUP) {
if (vc->driver->release_specific) {
vc->driver->release_specific(vc, v->call->id,
dummy_callback, vc);
}
voicecall_destroy(v);
} else if (res == OFONO_VOICECALL_FILTER_INCOMING_IGNORE) {
voicecall_destroy(v);
} else if (voicecall_dbus_register(v)) {
struct ofono_voicecall *vc = v->vc;
vc->call_list = g_slist_insert_sorted(vc->call_list, v,
call_compare);
voicecalls_emit_call_added(vc, v);
}
}
void ofono_voicecall_notify(struct ofono_voicecall *vc,
const struct ofono_call *call)
{
@@ -3010,8 +3107,7 @@ static void voicecall_unregister(struct ofono_atom *atom)
g_slist_free(vc->call_list);
vc->call_list = NULL;
/* Cancel the filtering */
__ofono_voicecall_filter_chain_cancel(vc->filters, NULL);
/* voicecall_destroy cancels the filtering */
g_slist_free_full(vc->incoming_filter_list, voicecall_destroy);
vc->incoming_filter_list = NULL;

View File

@@ -21,6 +21,7 @@ TESTS="\
test-provision \
test-ril_util \
test-ril_config \
test-ril-transport \
test-sms-filter \
test-voicecall-filter \
test-sailfish_cell_info \

View File

@@ -0,0 +1,97 @@
/*
* oFono - Open Source Telephony
*
* Copyright (C) 2018 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.
*/
#include "ofono.h"
#include <ofono/ril-transport.h>
#include <string.h>
#include <errno.h>
static void test_null(void)
{
struct ofono_ril_transport noname;
memset(&noname, 0, sizeof(noname));
g_assert(ofono_ril_transport_register(NULL) == -EINVAL);
g_assert(ofono_ril_transport_register(&noname) == -EINVAL);
ofono_ril_transport_unregister(NULL);
ofono_ril_transport_unregister(&noname);
g_assert(!ofono_ril_transport_connect(NULL, NULL));
}
static void test_register(void)
{
struct ofono_ril_transport foo;
struct ofono_ril_transport bar;
memset(&foo, 0, sizeof(foo));
memset(&bar, 0, sizeof(bar));
foo.name = "foo";
bar.name = "bar";
g_assert(ofono_ril_transport_register(&foo) == 0);
g_assert(ofono_ril_transport_register(&bar) == 0);
g_assert(ofono_ril_transport_register(&bar) == (-EALREADY));
g_assert(!ofono_ril_transport_connect(foo.name, NULL));
g_assert(!ofono_ril_transport_connect("test", NULL));
ofono_ril_transport_unregister(&foo);
ofono_ril_transport_unregister(&bar);
}
static struct grilio_transport *test_connect_cb(GHashTable *params)
{
static int dummy;
return (void*)&dummy;
}
static void test_connect(void)
{
static const struct ofono_ril_transport test = {
.name = "test",
.api_version = OFONO_RIL_TRANSPORT_API_VERSION,
.connect = test_connect_cb
};
g_assert(ofono_ril_transport_register(&test) == 0);
/* The returned pointer points to a static variable, no need to free */
g_assert(ofono_ril_transport_connect(test.name, NULL));
ofono_ril_transport_unregister(&test);
}
#define TEST_(name) "/ril-transport/" name
int main(int argc, char *argv[])
{
g_test_init(&argc, &argv, NULL);
__ofono_log_init("test-ril_util",
g_test_verbose() ? "*" : NULL,
FALSE, FALSE);
g_test_add_func(TEST_("null"), test_null);
g_test_add_func(TEST_("register"), test_register);
g_test_add_func(TEST_("connect"), test_connect);
return g_test_run();
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 8
* indent-tabs-mode: t
* End:
*/

View File

@@ -81,27 +81,6 @@ void test_parse_mcc_mnc(void)
g_assert(!op.tech);
}
void test_parse_int(void)
{
int value;
g_assert(!ril_parse_int(NULL, 0, NULL));
g_assert(!ril_parse_int("", 0, NULL));
g_assert(!ril_parse_int("garbage", 0, NULL));
g_assert(!ril_parse_int("0 trailing garbage", 0, NULL));
g_assert(ril_parse_int("0", 0, NULL));
g_assert(ril_parse_int("0", 0, &value));
g_assert(value == 0);
g_assert(!ril_parse_int("0x10000000000000000", 0, &value));
g_assert(!ril_parse_int("-2147483649", 0, &value));
g_assert(!ril_parse_int("4294967295", 0, &value));
g_assert(ril_parse_int(" 0x7fffffff ", 0, &value));
g_assert(value == 0x7fffffff);
g_assert(ril_parse_int(" 7fffffff ", 16, &value));
g_assert(value == 0x7fffffff);
g_assert(!ril_parse_int("0xffffffff", 0, &value));
}
void test_strings(void)
{
g_assert(!g_strcmp0(ril_error_to_string(RIL_E_SUCCESS), "OK"));
@@ -128,7 +107,6 @@ int main(int argc, char *argv[])
g_test_add_func(TEST_("parse_tech"), test_parse_tech);
g_test_add_func(TEST_("parse_mcc_mnc"), test_parse_mcc_mnc);
g_test_add_func(TEST_("parse_int"), test_parse_int);
g_test_add_func(TEST_("strings"), test_strings);
return g_test_run();

View File

@@ -84,6 +84,12 @@ static void test_dial_expect_block_and_quit
g_main_loop_quit(test_loop);
}
static void test_dial_unexpected
(enum ofono_voicecall_filter_dial_result result, void *data)
{
g_assert(FALSE);
}
static void test_incoming_expect_continue_inc
(enum ofono_voicecall_filter_incoming_result result, void *data)
{
@@ -336,6 +342,21 @@ static void test_misc(void)
g_assert(count == 2);
count = 0;
__ofono_voicecall_filter_chain_dial_check(NULL, NULL, NULL,
test_inc, &count);
g_assert(count == 1);
count = 0;
__ofono_voicecall_filter_chain_dial_check(NULL, NULL,
test_dial_expect_continue_inc, NULL, &count);
g_assert(count == 1);
count = 0;
__ofono_voicecall_filter_chain_dial_check(NULL, NULL,
test_dial_expect_continue_inc, test_inc, &count);
g_assert(count == 2);
count = 0;
__ofono_voicecall_filter_chain_incoming(NULL, NULL,
test_incoming_expect_continue_inc,
test_inc, &count);
@@ -589,6 +610,69 @@ static void test_dial_block_async(void)
test_common_deinit();
}
/* ==== dial_check ==== */
static void test_dial_check(void)
{
static struct ofono_voicecall_filter filter = {
.name = "dial_check",
.api_version = OFONO_VOICECALL_FILTER_API_VERSION,
.priority = OFONO_VOICECALL_FILTER_PRIORITY_DEFAULT,
.filter_dial = filter_dial_continue
};
struct ofono_voicecall vc;
struct ofono_phone_number number;
struct ofono_call call;
int count = 0;
test_common_init();
test_voicecall_init(&vc);
string_to_phone_number("112", &number);
memset(&call, 0, sizeof(call));
g_assert((vc.chain = __ofono_voicecall_filter_chain_new(&vc)) != NULL);
/* This one gets ok'ed immediately because there're no filters */
__ofono_voicecall_filter_chain_dial_check(vc.chain, &call,
test_dial_expect_continue_inc,
test_inc, &count);
g_assert(count == 2);
count = 0;
/* Register the filter */
g_assert(ofono_voicecall_filter_register(&filter) == 0);
/* This one gets ok'ed immediately because there's no call (hmmm?) */
__ofono_voicecall_filter_chain_dial_check(vc.chain, NULL,
test_dial_expect_continue_inc,
test_inc, &count);
g_assert(count == 2);
count = 0;
/* This one does nothing because there's no callback */
__ofono_voicecall_filter_chain_dial_check(vc.chain, &call,
NULL, test_inc, &count);
g_assert(count == 1);
count = 0;
/* Completion callback will terminate the loop */
__ofono_voicecall_filter_chain_dial_check(vc.chain, &call,
test_dial_expect_continue_and_quit,
test_inc, &count);
g_main_loop_run(test_loop);
g_assert(test_filter_dial_count == 1);
/* Count is incremented by the request destructor */
g_assert(count == 1);
count = 0;
__ofono_voicecall_filter_chain_free(vc.chain);
ofono_voicecall_filter_unregister(&filter);
test_common_deinit();
}
/* ==== incoming_allow ==== */
static void test_incoming_allow(void)
@@ -814,8 +898,7 @@ static void test_cancel1(void)
/* Submit the request */
__ofono_voicecall_filter_chain_dial(vc.chain, &number,
OFONO_CLIR_OPTION_DEFAULT,
test_dial_expect_continue_and_quit,
test_inc, &count);
test_dial_unexpected, test_inc, &count);
/* And immediately cancel it */
__ofono_voicecall_filter_chain_cancel(vc.chain, NULL);
@@ -862,7 +945,7 @@ static void test_cancel2(void)
/* Submit the request */
__ofono_voicecall_filter_chain_dial(vc.chain, &number,
OFONO_CLIR_OPTION_DEFAULT,
test_dial_expect_continue_and_quit,
test_dial_unexpected,
test_inc, &count);
/* It will be cancelled before it's completed */
@@ -911,8 +994,7 @@ static void test_cancel3(void)
/* Submit the request */
__ofono_voicecall_filter_chain_dial(vc.chain, &number,
OFONO_CLIR_OPTION_DEFAULT,
test_dial_expect_continue_and_quit,
test_inc, &count);
test_dial_unexpected, test_inc, &count);
/* It will be cancelled before it's completed */
g_main_loop_run(test_loop);
@@ -928,6 +1010,44 @@ static void test_cancel3(void)
/* ==== cancel4 ==== */
static void test_cancel4(void)
{
static struct ofono_voicecall_filter filter = {
.name = "dial_allow_async",
.api_version = OFONO_VOICECALL_FILTER_API_VERSION,
.filter_dial = filter_dial_cancel3, /* Reuse */
.filter_cancel = filter_cancel
};
struct ofono_voicecall vc;
struct ofono_call call;
int count = 0;
test_common_init();
test_voicecall_init(&vc);
ofono_call_init(&call);
string_to_phone_number("+1234", &call.phone_number);
g_assert(ofono_voicecall_filter_register(&filter) == 0);
g_assert((vc.chain = __ofono_voicecall_filter_chain_new(&vc)) != NULL);
/* Submit the request */
__ofono_voicecall_filter_chain_dial_check(vc.chain, &call,
test_dial_unexpected, test_inc, &count);
/* It will be cancelled before it's completed */
g_main_loop_run(test_loop);
g_assert(!test_filter_dial_count);
g_assert(count == 1);
count = 0;
__ofono_voicecall_filter_chain_free(vc.chain);
ofono_voicecall_filter_unregister(&filter);
test_common_deinit();
}
/* ==== cancel5 ==== */
static void test_cancel5(void)
{
static struct ofono_voicecall_filter filter1 = {
.name = "incoming_allow",
@@ -984,9 +1104,9 @@ static void test_cancel4(void)
test_common_deinit();
}
/* ==== cancel5 ==== */
/* ==== cancel6 ==== */
static void test_cancel5(void)
static void test_cancel6(void)
{
static struct ofono_voicecall_filter filter1 = {
.name = "incoming_allow",
@@ -1066,6 +1186,7 @@ int main(int argc, char *argv[])
g_test_add_func(TEST_("dial_allow_async"), test_dial_allow_async);
g_test_add_func(TEST_("dial_block"), test_dial_block);
g_test_add_func(TEST_("dial_block_async"), test_dial_block_async);
g_test_add_func(TEST_("dial_check"), test_dial_check);
g_test_add_func(TEST_("incoming_allow"), test_incoming_allow);
g_test_add_func(TEST_("incoming_hangup"), test_incoming_hangup);
g_test_add_func(TEST_("incoming_ignore"), test_incoming_ignore);
@@ -1075,6 +1196,7 @@ int main(int argc, char *argv[])
g_test_add_func(TEST_("cancel3"), test_cancel3);
g_test_add_func(TEST_("cancel4"), test_cancel4);
g_test_add_func(TEST_("cancel5"), test_cancel5);
g_test_add_func(TEST_("cancel6"), test_cancel6);
return g_test_run();
}

View File

@@ -10,8 +10,8 @@ Source: %{name}-%{version}.tar.bz2
Requires: dbus
Requires: systemd
Requires: ofono-configs
Requires: libgrilio >= 1.0.21
Requires: libglibutil >= 1.0.23
Requires: libgrilio >= 1.0.25
Requires: libglibutil >= 1.0.30
Requires: mobile-broadband-provider-info
Requires(preun): systemd
Requires(post): systemd
@@ -21,8 +21,8 @@ BuildRequires: pkgconfig(dbus-glib-1)
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(libudev) >= 145
BuildRequires: pkgconfig(libwspcodec) >= 2.0
BuildRequires: pkgconfig(libgrilio) >= 1.0.21
BuildRequires: pkgconfig(libglibutil) >= 1.0.23
BuildRequires: pkgconfig(libgrilio) >= 1.0.25
BuildRequires: pkgconfig(libglibutil) >= 1.0.30
BuildRequires: pkgconfig(libdbuslogserver-dbus)
BuildRequires: pkgconfig(libmce-glib) >= 1.0.5
BuildRequires: pkgconfig(mobile-broadband-provider-info)