Compare commits

...

12 Commits

Author SHA1 Message Date
Martti Piirainen
db6d4d1e8e Merge pull request #163 from marttipiirainen/next
Merge Call Barring support, SIM ATK support and SMS ACK bugfix from 'next' to 'master'
2014-02-03 00:46:01 -08:00
Jussi Kangas
5bcbc64e60 [rilmodem] Ack sms receiving also when error
According to ril api also the failed receiving of SMS should be
acked to ril.

Signed-off-by: Jussi Kangas <jussi.kangas@oss.tieto.com>
2014-02-03 10:07:52 +02:00
Petri Takalokastari
48cec5cc58 [rilmodem] Add initial SIM ATK support
Add initial SIM ATK implementation to rilmodem driver, supporting
proactive command, terminal response and envelope.

Signed-off-by: Petri Takalokastari <petri.takalokastari@oss.tieto.com>

[rilmodem] Fix proactive command and terminal response handling

Convert the proactive commands and terminal responses to correct
format

[rilmodem] Fix for envelope sending

Fix typo in envelope sending causing ofono crash

[rilmodem] stk: adjust timings

Adjust the registeration of the rilmodem stk service and usage of timer
when reporting to RIL when ready to receive proactive commands

[rilmodem] Fix for terminal response and envelope construction

Remove usage of strlen, so the terminal responses and envelopes ending
with value 0x00 are sent properly.

[rilmodem] Remove timer usage from start up sequence

Remove usage of timers in startup sequence. Report ofono readiness to
receive proactive commands only when agent has registered.

[rilmodem] Fine tuning of start up sequence

Register to listen STK specific unsolicited messages only if UI STK agent
has registered. This because RILD will send and buffer proactive commands
also if not received RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING
previously. RILD will buffer the proactive command until receiving
RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING or terminal
response to (sent) proactive command.
By this change oFono core/rilmodem will not handle proactive commands
until STK UI agent has been registered to oFono.

[rilmodem] Change envelope sending request

Changed envelope sending request from
RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS to
RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND as it seems that RILD
does not support RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS
properly.
Also cleaned up some excessive tracing.
2014-02-03 10:07:52 +02:00
Miia Leinonen
6e40473ce9 [rilmodem] Fix for Call Barring commit
Signed-off-by: Miia Leinonen <miia.leinonen@oss.tieto.com>
2014-02-03 10:07:52 +02:00
Miia Leinonen
90cae692df [rilmodem] Add Call Barring support
Signed-off-by: Miia Leinonen <miia.leinonen@oss.tieto.com>
2014-02-03 10:07:51 +02:00
Martti Piirainen
d8270409d0 Merge pull request #156 from jpoutiai/master
[rilmodem] add missing brace characters
2014-02-02 23:48:45 -08:00
Jarko Poutiainen
e644196aa3 [rilmodem] add missing brace characters
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-01-17 13:44:32 +02:00
Martti Piirainen
fed4a94862 Merge pull request #150 from jpoutiai/master
[rilmodem] fix CF to support all the service classes
2014-01-15 00:54:21 -08:00
Jarko Poutiainen
ccc8d1afd4 [rilmodem] use SERVICE_CLASS_NONE insteead of hard coded value
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-01-13 12:08:02 +02:00
Jarko Poutiainen
417f20c662 [rilmodem] define SERVICE_CLASS_NONE
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-01-13 12:07:28 +02:00
Jarko Poutiainen
304f7cc197 [rilmodem] remove comments regarding the BEARER_CLASS_DEFAULT
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-01-13 12:07:04 +02:00
Jarko Poutiainen
354285a438 [rilmodem] fix CF to support all the service classes
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-01-13 12:06:22 +02:00
14 changed files with 741 additions and 69 deletions

View File

@@ -142,7 +142,9 @@ builtin_sources += drivers/rilmodem/rilmodem.h \
drivers/rilmodem/call-settings.c \
drivers/rilmodem/call-forwarding.c \
drivers/rilmodem/cbs.c \
drivers/rilmodem/oemraw-messages.c
drivers/rilmodem/oemraw-messages.c \
drivers/rilmodem/call-barring.c \
drivers/rilmodem/stk.c
endif

View File

@@ -0,0 +1,310 @@
/*
*
* oFono - Open Source Telephony
*
* Copyright (C) 2014 Jolla Ltd
* Contact: Miia Leinonen
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <glib.h>
#include <ofono/log.h>
#include <ofono/modem.h>
#include "common.h"
#include "gril.h"
#include "call-barring.h"
#include "rilmodem.h"
#include "ril_constants.h"
/* See 3GPP 27.007 7.4 for possible values */
#define RIL_MAX_SERVICE_LENGTH 3
/*
* ril.h does not state that string count must be given, but that is
* still expected by the modem
*/
#define RIL_QUERY_STRING_COUNT 4
#define RIL_SET_STRING_COUNT 5
#define RIL_SET_PW_STRING_COUNT 3
#define RIL_LENGTH_ZERO 0
struct barring_data {
GRil *ril;
guint timer_id;
};
static void ril_call_barring_query_cb(struct ril_msg *message,
gpointer user_data)
{
struct cb_data *cbd = user_data;
struct parcel rilp;
struct ofono_error error;
ofono_call_barring_query_cb_t cb = cbd->cb;
int bearer_class = 0;
if (message->error != RIL_E_SUCCESS) {
ofono_error("Call Barring query failed, err: %i",
message->error);
decode_ril_error(&error, "FAIL");
goto out;
}
ril_util_init_parcel(message, &rilp);
/*
* Services for which the specified barring facility is active.
* "0" means "disabled for all, -1 if unknown"
*/
parcel_r_int32(&rilp); /* count - we know there is only 1 */
bearer_class = parcel_r_int32(&rilp);
DBG("Active services: %i", bearer_class);
decode_ril_error(&error, "OK");
out:
cb(&error, bearer_class, cbd->data);
}
static void ril_call_barring_query(struct ofono_call_barring *cb,
const char *lock, int cls,
ofono_call_barring_query_cb_t callback,
void *data)
{
struct barring_data *bd = ofono_call_barring_get_data(cb);
struct cb_data *cbd = cb_data_new(callback, data);
struct parcel rilp;
int ret = 0;
char cls_textual[RIL_MAX_SERVICE_LENGTH];
DBG("lock: %s, services to query: %i", lock, cls);
/*
* RIL modems do not support 7 as default bearer class. According to
* the 22.030 Annex C: When service code is not given it corresponds to
* "All tele and bearer services"
*/
if (cls == BEARER_CLASS_DEFAULT)
cls = SERVICE_CLASS_NONE;
sprintf(cls_textual, "%d", cls);
/*
* See 3GPP 27.007 7.4 for parameter descriptions.
* According to ril.h password should be empty string "" when not
* needed, but in reality we only need to give string length as 0
*/
parcel_init(&rilp);
parcel_w_int32(&rilp, RIL_QUERY_STRING_COUNT); /* Nbr of strings */
parcel_w_string(&rilp, (char *) lock); /* Facility code */
parcel_w_int32(&rilp, RIL_LENGTH_ZERO); /* Password length */
parcel_w_string(&rilp, (char *) cls_textual);
parcel_w_string(&rilp, NULL); /* AID (for FDN, not yet supported) */
ret = g_ril_send(bd->ril, RIL_REQUEST_QUERY_FACILITY_LOCK,
rilp.data, rilp.size, ril_call_barring_query_cb,
cbd, g_free);
parcel_free(&rilp);
if (ret <= 0) {
ofono_error("Sending Call Barring query failed, err: %i", ret);
g_free(cbd);
CALLBACK_WITH_FAILURE(callback, -1, data);
}
}
static void ril_call_barring_set_cb(struct ril_msg *message, gpointer user_data)
{
struct cb_data *cbd = user_data;
struct ofono_error error;
ofono_call_barring_set_cb_t cb = cbd->cb;
if (message->error != RIL_E_SUCCESS) {
ofono_error("Call Barring Set request failed, err: %i",
message->error);
decode_ril_error(&error, "FAIL");
goto out;
}
decode_ril_error(&error, "OK");
out:
cb(&error, cbd->data);
}
static void ril_call_barring_set(struct ofono_call_barring *cb,
const char *lock, int enable,
const char *passwd, int cls,
ofono_call_barring_set_cb_t callback,
void *data)
{
struct barring_data *bd = ofono_call_barring_get_data(cb);
struct cb_data *cbd = cb_data_new(callback, data);
struct parcel rilp;
int ret = 0;
char cls_textual[RIL_MAX_SERVICE_LENGTH];
DBG("lock: %s, enable: %i, bearer class: %i", lock, enable, cls);
/*
* RIL modem does not support 7 as default bearer class. According to
* the 22.030 Annex C: When service code is not given it corresponds to
* "All tele and bearer services"
*/
if (cls == BEARER_CLASS_DEFAULT)
cls = SERVICE_CLASS_NONE;
sprintf(cls_textual, "%d", cls);
/* See 3GPP 27.007 7.4 for parameter descriptions */
parcel_init(&rilp);
parcel_w_int32(&rilp, RIL_SET_STRING_COUNT); /* Nbr of strings */
parcel_w_string(&rilp, (char *) lock); /* Facility code */
if (enable)
parcel_w_string(&rilp, RIL_FACILITY_LOCK);
else
parcel_w_string(&rilp, RIL_FACILITY_UNLOCK);
parcel_w_string(&rilp, (char *) passwd);
parcel_w_string(&rilp, (char *) cls_textual);
parcel_w_string(&rilp, NULL); /* AID (for FDN, not yet supported) */
ret = g_ril_send(bd->ril, RIL_REQUEST_SET_FACILITY_LOCK,
rilp.data, rilp.size, ril_call_barring_set_cb,
cbd, g_free);
parcel_free(&rilp);
if (ret <= 0) {
ofono_error("Sending Call Barring Set request failed, err: %i",
ret);
g_free(cbd);
CALLBACK_WITH_FAILURE(callback, data);
}
}
static void ril_call_barring_set_passwd_cb(struct ril_msg *message,
gpointer user_data)
{
struct cb_data *cbd = user_data;
struct ofono_error error;
ofono_call_barring_set_cb_t cb = cbd->cb;
if (message->error != RIL_E_SUCCESS) {
ofono_error("Call Barring Set PW req failed, err: %i",
message->error);
decode_ril_error(&error, "FAIL");
goto out;
}
decode_ril_error(&error, "OK");
out:
cb(&error, cbd->data);
}
static void ril_call_barring_set_passwd(struct ofono_call_barring *barr,
const char *lock,
const char *old_passwd,
const char *new_passwd,
ofono_call_barring_set_cb_t cb,
void *data)
{
struct barring_data *bd = ofono_call_barring_get_data(barr);
struct cb_data *cbd = cb_data_new(cb, data);
struct parcel rilp;
int ret = 0;
DBG("");
parcel_init(&rilp);
parcel_w_int32(&rilp, RIL_SET_PW_STRING_COUNT); /* Nbr of strings */
parcel_w_string(&rilp, (char *) lock); /* Facility code */
parcel_w_string(&rilp, (char *) old_passwd);
parcel_w_string(&rilp, (char *) new_passwd);
ret = g_ril_send(bd->ril, RIL_REQUEST_CHANGE_BARRING_PASSWORD,
rilp.data, rilp.size, ril_call_barring_set_passwd_cb,
cbd, g_free);
parcel_free(&rilp);
if (ret <= 0) {
ofono_error("Sending Call Barring Set PW req failed, err: %i",
ret);
g_free(cbd);
CALLBACK_WITH_FAILURE(cb, data);
}
}
static gboolean ril_delayed_register(gpointer user_data)
{
struct ofono_call_barring *cb = user_data;
struct barring_data *bd = ofono_call_barring_get_data(cb);
bd->timer_id = 0;
ofono_call_barring_register(cb);
return FALSE;
}
static int ril_call_barring_probe(struct ofono_call_barring *cb,
unsigned int vendor, void *user)
{
GRil *ril = user;
struct barring_data *bd = g_try_new0(struct barring_data, 1);
bd->ril = g_ril_clone(ril);
ofono_call_barring_set_data(cb, bd);
g_timeout_add_seconds(2, ril_delayed_register, cb);
return 0;
}
static void ril_call_barring_remove(struct ofono_call_barring *cb)
{
struct barring_data *data = ofono_call_barring_get_data(cb);
ofono_call_barring_set_data(cb, NULL);
if (data->timer_id > 0)
g_source_remove(data->timer_id);
g_ril_unref(data->ril);
g_free(data);
}
static struct ofono_call_barring_driver driver = {
.name = "rilmodem",
.probe = ril_call_barring_probe,
.remove = ril_call_barring_remove,
.query = ril_call_barring_query,
.set = ril_call_barring_set,
.set_passwd = ril_call_barring_set_passwd
};
void ril_call_barring_init(void)
{
ofono_call_barring_driver_register(&driver);
}
void ril_call_barring_exit(void)
{
ofono_call_barring_driver_unregister(&driver);
}

View File

@@ -89,18 +89,16 @@ static void ril_registration(struct ofono_call_forwarding *cf, int type,
parcel_w_int32(&rilp, type);
/* Modem seems to respond with error to all queries
/*
* Modem seems to respond with error to all queries
* or settings made with bearer class
* BEARER_CLASS_DEFAULT. Design decision: If given
* class is BEARER_CLASS_DEFAULT let's map it to
* SERVICE_CLASS_VOICE effectively making it the
* default bearer. This in line with API which is
* contains only voice anyways. TODO: Checkout
* the behaviour with final modem
* SERVICE_CLASS_NONE as with it e.g. ./send-ussd '*21*<phone_number>#'
* returns cls:53 i.e. 1+4+16+32 as service class.
*/
if (cls == BEARER_CLASS_DEFAULT)
cls = BEARER_CLASS_VOICE;
cls = SERVICE_CLASS_NONE;
parcel_w_int32(&rilp, cls);
@@ -137,18 +135,16 @@ static void ril_send_forward_cmd(struct ofono_call_forwarding *cf,
parcel_w_int32(&rilp, type);
/* Modem seems to respond with error to all queries
/*
* Modem seems to respond with error to all queries
* or settings made with bearer class
* BEARER_CLASS_DEFAULT. Design decision: If given
* class is BEARER_CLASS_DEFAULT let's map it to
* SERVICE_CLASS_VOICE effectively making it the
* default bearer. This in line with API which is
* contains only voice anyways. TODO: Checkout
* the behaviour with final modem
* SERVICE_CLASS_NONE as with it e.g. ./send-ussd '*21*<phone_number>#'
* returns cls:53 i.e. 1+4+16+32 as service class.
*/
if (cls == BEARER_CLASS_DEFAULT)
cls = BEARER_CLASS_VOICE;
cls = SERVICE_CLASS_NONE;
parcel_w_int32(&rilp, cls); /* Service class */
@@ -246,7 +242,7 @@ static void ril_query_cb(struct ril_msg *message, gpointer user_data)
}
CALLBACK_WITH_SUCCESS(cb, 1, list, cbd->data);
CALLBACK_WITH_SUCCESS(cb, nmbr_of_resps, list, cbd->data);
g_free(list);
} else {
@@ -272,18 +268,16 @@ static void ril_query(struct ofono_call_forwarding *cf, int type, int cls,
parcel_w_int32(&rilp, type);
/* Modem seems to respond with error to all queries
/*
* Modem seems to respond with error to all queries
* or settings made with bearer class
* BEARER_CLASS_DEFAULT. Design decision: If given
* class is BEARER_CLASS_DEFAULT let's map it to
* SERVICE_CLASS_VOICE effectively making it the
* default bearer. This in line with API which is
* contains only voice anyways. TODO: Checkout
* the behaviour with final modem
* SERVICE_CLASS_NONE as with it e.g. ./send-ussd '*21*<phone_number>#'
* returns cls:53 i.e. 1+4+16+32 as service class.
*/
if (cls == BEARER_CLASS_DEFAULT)
cls = BEARER_CLASS_VOICE;
cls = SERVICE_CLASS_NONE;
parcel_w_int32(&rilp, cls);
@@ -351,10 +345,10 @@ static struct ofono_call_forwarding_driver driver = {
.probe = ril_call_forwarding_probe,
.remove = ril_call_forwarding_remove,
.erasure = ril_erasure,
.deactivation = ril_deactivate,
.deactivation = ril_deactivate,
.query = ril_query,
.registration = ril_registration,
.activation = ril_activate
.registration = ril_registration,
.activation = ril_activate
};
void ril_call_forwarding_init(void)

View File

@@ -53,8 +53,10 @@ static int rilmodem_init(void)
ril_ussd_init();
ril_call_settings_init();
ril_call_forwarding_init();
ril_call_barring_init();
ril_cbs_init();
ril_oemraw_init();
ril_stk_init();
return 0;
}
@@ -76,8 +78,10 @@ static void rilmodem_exit(void)
ril_ussd_exit();
ril_call_settings_exit();
ril_call_forwarding_exit();
ril_call_barring_exit();
ril_cbs_exit();
ril_oemraw_exit();
ril_stk_exit();
}
OFONO_PLUGIN_DEFINE(rilmodem, "RIL modem driver", VERSION,

View File

@@ -68,6 +68,9 @@ extern void ril_call_settings_exit(void);
extern void ril_call_forwarding_init(void);
extern void ril_call_forwarding_exit(void);
extern void ril_call_barring_init(void);
extern void ril_call_barring_exit(void);
extern void ril_cbs_init(void);
extern void ril_cbs_exit(void);
@@ -76,3 +79,7 @@ extern void ril_phonebook_exit(void);
extern void ril_oemraw_init(void);
extern void ril_oemraw_exit(void);
extern void ril_stk_init(void);
extern void ril_stk_exit(void);

View File

@@ -74,10 +74,6 @@
#define ENTER_SIM_PUK_PARAMS 3
#define CHANGE_SIM_PIN_PARAMS 3
/* RIL_FACILITY_LOCK parameters */
#define RIL_FACILITY_UNLOCK "0"
#define RIL_FACILITY_LOCK "1"
/* Current SIM */
static struct ofono_sim *current_sim;
/* Current active app */
@@ -217,11 +213,13 @@ static void ril_file_info_cb(struct ril_msg *message, gpointer user_data)
if (response_len) {
if (response[0] == 0x62) {
ok = sim_parse_3g_get_response(response, response_len,
&flen, &rlen, &str, access, NULL);
ok = sim_parse_3g_get_response(
response, response_len,
&flen, &rlen, &str, access, NULL);
} else
ok = sim_parse_2g_get_response(response, response_len,
&flen, &rlen, &str, access, &file_status);
ok = sim_parse_2g_get_response(
response, response_len,
&flen, &rlen, &str, access, &file_status);
}
if (!ok) {
@@ -240,7 +238,8 @@ error:
}
static void ril_sim_read_info(struct ofono_sim *sim, int fileid,
const unsigned char *path, unsigned int path_len,
const unsigned char *path,
unsigned int path_len,
ofono_sim_file_info_cb_t cb,
void *data)
{
@@ -340,7 +339,8 @@ error:
static void ril_sim_read_binary(struct ofono_sim *sim, int fileid,
int start, int length,
const unsigned char *path, unsigned int path_len,
const unsigned char *path,
unsigned int path_len,
ofono_sim_read_cb_t cb, void *data)
{
struct sim_data *sd = ofono_sim_get_data(sim);
@@ -393,7 +393,8 @@ static void ril_sim_read_binary(struct ofono_sim *sim, int fileid,
static void ril_sim_read_record(struct ofono_sim *sim, int fileid,
int record, int length,
const unsigned char *path, unsigned int path_len,
const unsigned char *path,
unsigned int path_len,
ofono_sim_read_cb_t cb, void *data)
{
struct sim_data *sd = ofono_sim_get_data(sim);
@@ -506,10 +507,10 @@ static void ril_read_imsi(struct ofono_sim *sim, ofono_sim_imsi_cb_t cb,
}
}
void set_pin_lock_state(struct ofono_sim *sim,struct sim_app *app)
void set_pin_lock_state(struct ofono_sim *sim, struct sim_app *app)
{
DBG("pin1:%u,pin2:%u",app->pin1_state,app->pin2_state);
/*
DBG("pin1:%u,pin2:%u", app->pin1_state, app->pin2_state);
/*
* Updates only pin and pin2 state. Other locks are not dealt here. For
* that a RIL_REQUEST_QUERY_FACILITY_LOCK request should be used.
*/
@@ -518,10 +519,11 @@ void set_pin_lock_state(struct ofono_sim *sim,struct sim_app *app)
case RIL_PINSTATE_ENABLED_VERIFIED:
case RIL_PINSTATE_ENABLED_BLOCKED:
case RIL_PINSTATE_ENABLED_PERM_BLOCKED:
ofono_set_pin_lock_state(sim,OFONO_SIM_PASSWORD_SIM_PIN,TRUE);
ofono_set_pin_lock_state(sim, OFONO_SIM_PASSWORD_SIM_PIN, TRUE);
break;
case RIL_PINSTATE_DISABLED:
ofono_set_pin_lock_state(sim,OFONO_SIM_PASSWORD_SIM_PIN,FALSE);
ofono_set_pin_lock_state(
sim, OFONO_SIM_PASSWORD_SIM_PIN, FALSE);
break;
default:
break;
@@ -531,10 +533,12 @@ void set_pin_lock_state(struct ofono_sim *sim,struct sim_app *app)
case RIL_PINSTATE_ENABLED_VERIFIED:
case RIL_PINSTATE_ENABLED_BLOCKED:
case RIL_PINSTATE_ENABLED_PERM_BLOCKED:
ofono_set_pin_lock_state(sim,OFONO_SIM_PASSWORD_SIM_PIN2,TRUE);
ofono_set_pin_lock_state(
sim, OFONO_SIM_PASSWORD_SIM_PIN2, TRUE);
break;
case RIL_PINSTATE_DISABLED:
ofono_set_pin_lock_state(sim,OFONO_SIM_PASSWORD_SIM_PIN2,FALSE);
ofono_set_pin_lock_state(
sim, OFONO_SIM_PASSWORD_SIM_PIN2, FALSE);
break;
default:
break;
@@ -642,7 +646,7 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
if (sd->sim_registered == FALSE) {
ofono_sim_register(sim);
sd->sim_registered = TRUE;
} else
} else {
/* TODO: There doesn't seem to be any other
* way to force the core SIM code to
* recheck the PIN.
@@ -650,15 +654,16 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
* more appropriate call here??
* __ofono_sim_refresh(sim, NULL, TRUE, TRUE);
*/
DBG("sd->card_state:%u",sd->card_state);
DBG("sd->card_state:%u", sd->card_state);
if (sd->card_state != RIL_CARDSTATE_PRESENT) {
ofono_sim_inserted_notify(sim, TRUE);
sd->card_state = RIL_CARDSTATE_PRESENT;
}
}
if (current_passwd) {
if (!strcmp(current_passwd, defaultpasswd)) {
__ofono_sim_recheck_pin(sim);
__ofono_sim_recheck_pin(sim);
} else if (sd->passwd_state !=
OFONO_SIM_PASSWORD_SIM_PIN) {
__ofono_sim_recheck_pin(sim);
@@ -787,7 +792,9 @@ static void ril_pin_change_state_cb(struct ril_msg *message, gpointer user_data)
retries[passwd_type] = retry_count;
sd->retries[passwd_type] = retries[passwd_type];
/* TODO: re-bfactor to not use macro for FAILURE; doesn't return error! */
/*
* TODO: re-bfactor to not use macro for FAILURE; doesn't return error!
*/
if (message->error == RIL_E_SUCCESS) {
CALLBACK_WITH_SUCCESS(cb, cbd->data);
@@ -838,9 +845,9 @@ static void ril_pin_send(struct ofono_sim *sim, const char *passwd,
}
static void ril_pin_change_state(struct ofono_sim *sim,
enum ofono_sim_password_type passwd_type,
int enable, const char *passwd,
ofono_sim_lock_unlock_cb_t cb, void *data)
enum ofono_sim_password_type passwd_type,
int enable, const char *passwd,
ofono_sim_lock_unlock_cb_t cb, void *data)
{
struct sim_data *sd = ofono_sim_get_data(sim);
struct cb_data *cbd = cb_data_new(cb, data);

View File

@@ -248,19 +248,21 @@ static void ril_ack_delivery_cb(struct ril_msg *message, gpointer user_data)
"SMS acknowledgement failed: Further SMS reception is not guaranteed");
}
static void ril_ack_delivery(struct ofono_sms *sms)
static void ril_ack_delivery(struct ofono_sms *sms, int error)
{
struct sms_data *sd = ofono_sms_get_data(sms);
struct parcel rilp;
int ret;
int request = RIL_REQUEST_SMS_ACKNOWLEDGE;
int code = 0;
if (!error)
code = 0xFF;
parcel_init(&rilp);
parcel_w_int32(&rilp, 2); /* Number of int32 values in array */
parcel_w_int32(&rilp, 1); /* Successful receipt */
parcel_w_int32(&rilp, 0); /* error code */
/* TODO: should ACK be sent for either of the error cases? */
parcel_w_int32(&rilp, error); /* Successful (1)/Failed (0) receipt */
parcel_w_int32(&rilp, code); /* error code */
/* ACK the incoming NEW_SMS */
ret = g_ril_send(sd->ril, request,
@@ -329,11 +331,13 @@ static void ril_sms_notify(struct ril_msg *message, gpointer user_data)
ril_buf_len - smsc_len);
}
ril_ack_delivery(sms);
ril_ack_delivery(sms, TRUE);
return;
error:
ril_ack_delivery(sms, FALSE);
ofono_error("Unable to parse NEW_SMS notification");
}

View File

@@ -0,0 +1,306 @@
/*
*
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2014 Jolla Ltd
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#define _GNU_SOURCE
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <glib.h>
#include <ofono/log.h>
#include <ofono/modem.h>
#include <ofono/stk.h>
#include "gril.h"
#include "util.h"
#include "rilmodem.h"
#include "ril_constants.h"
struct stk_data {
GRil *ril;
};
static void ril_envelope_cb(struct ril_msg *message, gpointer user_data)
{
struct cb_data *cbd = user_data;
ofono_stk_envelope_cb_t cb = cbd->cb;
struct ofono_error error;
DBG("");
if (message->error == RIL_E_SUCCESS) {
decode_ril_error(&error, "OK");
} else {
DBG("Envelope reply failure: %s",
ril_error_to_string(message->error));
decode_ril_error(&error, "FAIL");
}
cb(&error, NULL, 0, cbd->data);
}
static void ril_stk_envelope(struct ofono_stk *stk, int length,
const unsigned char *command,
ofono_stk_envelope_cb_t cb, void *data)
{
struct stk_data *sd = ofono_stk_get_data(stk);
struct cb_data *cbd = cb_data_new(cb, data);
struct parcel rilp;
char *hex_envelope = NULL;
int request = RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND;
guint ret;
DBG("");
hex_envelope = encode_hex(command, length, 0);
DBG("rilmodem envelope: %s", hex_envelope);
parcel_init(&rilp);
parcel_w_string(&rilp, hex_envelope);
ret = g_ril_send(sd->ril, request,
rilp.data, rilp.size, ril_envelope_cb,
cbd, g_free);
parcel_free(&rilp);
if (ret <= 0) {
g_free(cbd);
CALLBACK_WITH_FAILURE(cb, NULL, -1, data);
}
}
static void ril_tr_cb(struct ril_msg *message, gpointer user_data)
{
struct cb_data *cbd = user_data;
ofono_stk_generic_cb_t cb = cbd->cb;
struct ofono_error error;
DBG("");
if (message->error == RIL_E_SUCCESS) {
decode_ril_error(&error, "OK");
} else {
DBG("Error in sending terminal response");
ofono_error("Error in sending terminal response");
decode_ril_error(&error, "FAIL");
}
cb(&error, cbd->data);
}
static void ril_stk_terminal_response(struct ofono_stk *stk, int length,
const unsigned char *resp,
ofono_stk_generic_cb_t cb, void *data)
{
struct stk_data *sd = ofono_stk_get_data(stk);
struct cb_data *cbd = cb_data_new(cb, data);
struct parcel rilp;
char *hex_tr = NULL;
int request = RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE;
guint ret;
DBG("");
hex_tr = encode_hex(resp, length, 0);
DBG("rilmodem terminal response: %s", hex_tr);
parcel_init(&rilp);
parcel_w_string(&rilp, hex_tr);
ret = g_ril_send(sd->ril, request,
rilp.data, rilp.size, ril_tr_cb,
cbd, g_free);
parcel_free(&rilp);
if (ret <= 0) {
g_free(cbd);
CALLBACK_WITH_FAILURE(cb, data);
}
}
static void ril_stk_user_confirmation(struct ofono_stk *stk,
ofono_bool_t confirm)
{
struct stk_data *sd = ofono_stk_get_data(stk);
struct parcel rilp;
int request = RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM;
int ret;
DBG("");
/* Only pcmd needing user confirmation is call set up
* RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM
*/
parcel_init(&rilp);
parcel_w_int32(&rilp, 1); /* size of array */
parcel_w_int32(&rilp, confirm); /* yes/no */
/* fire and forget i.e. not waiting for the callback*/
ret = g_ril_send(sd->ril, request, rilp.data,
rilp.size, NULL, NULL, NULL);
g_ril_print_request_no_args(sd->ril, ret, request);
parcel_free(&rilp);
}
static void ril_stk_pcmd_notify(struct ril_msg *message, gpointer user_data)
{
struct ofono_stk *stk = user_data;
struct parcel rilp;
char *pcmd = NULL;
guchar *pdu = NULL;
long len;
DBG("");
ril_util_init_parcel(message, &rilp);
pcmd = parcel_r_string(&rilp);
DBG("pcmd: %s", pcmd);
pdu = decode_hex((const char *) pcmd,
strlen(pcmd),
&len, -1);
ofono_stk_proactive_command_notify(stk, len, (const guchar *)pdu);
}
static void ril_stk_event_notify(struct ril_msg *message, gpointer user_data)
{
struct ofono_stk *stk = user_data;
struct parcel rilp;
char *pcmd = NULL;
guchar *pdu = NULL;
long len;
DBG("");
/* Proactive command has been handled by the modem. */
ril_util_init_parcel(message, &rilp);
pcmd = parcel_r_string(&rilp);
DBG("pcmd: %s", pcmd);
pdu = decode_hex((const char *) pcmd,
strlen(pcmd),
&len, -1);
ofono_stk_proactive_command_handled_notify(stk, len,
(const guchar *)pdu);
}
static void ril_stk_session_end_notify(struct ril_msg *message,
gpointer user_data)
{
struct ofono_stk *stk = user_data;
DBG("");
ofono_stk_proactive_session_end_notify(stk);
}
static void ril_stk_agent_ready(struct ofono_stk *stk)
{
struct stk_data *sd = ofono_stk_get_data(stk);
int request = RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING;
int ret;
DBG("");
/* register for unsol's only if agent has registered */
g_ril_register(sd->ril, RIL_UNSOL_STK_PROACTIVE_COMMAND,
ril_stk_pcmd_notify, stk);
g_ril_register(sd->ril, RIL_UNSOL_STK_SESSION_END,
ril_stk_session_end_notify, stk);
g_ril_register(sd->ril, RIL_UNSOL_STK_EVENT_NOTIFY,
ril_stk_event_notify, stk);
/* fire and forget i.e. not waiting for the callback*/
ret = g_ril_send(sd->ril, request, NULL, 0,
NULL, NULL, NULL);
g_ril_print_request_no_args(sd->ril, ret, request);
}
static int ril_stk_probe(struct ofono_stk *stk, unsigned int vendor, void *data)
{
GRil *ril = data;
struct stk_data *sd;
DBG("");
sd = g_try_new0(struct stk_data, 1);
if (sd == NULL)
return -ENOMEM;
sd->ril = g_ril_clone(ril);
ofono_stk_set_data(stk, sd);
/* Register interface in this phase for stk agent */
ofono_stk_register(stk);
return 0;
}
static void ril_stk_remove(struct ofono_stk *stk)
{
struct stk_data *sd = ofono_stk_get_data(stk);
DBG("");
ofono_stk_set_data(stk, NULL);
g_ril_unref(sd->ril);
g_free(sd);
}
static struct ofono_stk_driver driver = {
.name = "rilmodem",
.probe = ril_stk_probe,
.remove = ril_stk_remove,
.envelope = ril_stk_envelope,
.terminal_response = ril_stk_terminal_response,
.user_confirmation = ril_stk_user_confirmation,
.ready = ril_stk_agent_ready
};
void ril_stk_init(void)
{
ofono_stk_driver_register(&driver);
}
void ril_stk_exit(void)
{
ofono_stk_driver_unregister(&driver);
}

View File

@@ -384,4 +384,11 @@
#define RIL_UNSOL_STK_CC_ALPHA_NOTIFY 1040
#define RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED 1041
/* Suplementary services Service class*/
#define SERVICE_CLASS_NONE 0
/* RIL_FACILITY_LOCK parameters */
#define RIL_FACILITY_UNLOCK "0"
#define RIL_FACILITY_LOCK "1"
#endif /*__RIL_CONSTANTS_H*/

View File

@@ -48,6 +48,7 @@ struct ofono_stk_driver {
int length, const unsigned char *resp,
ofono_stk_generic_cb_t cb, void *data);
void (*user_confirmation)(struct ofono_stk *stk, ofono_bool_t confirm);
void (*ready)(struct ofono_stk *stk);
};
int ofono_stk_driver_register(const struct ofono_stk_driver *d);

View File

@@ -63,6 +63,7 @@
#include <ofono/types.h>
#include <ofono/message-waiting.h>
#include <ofono/oemraw.h>
#include <ofono/stk.h>
#include "drivers/rilmodem/rilmodem.h"
@@ -154,9 +155,12 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
} else {
ofono_warn("No SIM card present.");
}
// We cannot power on modem, but we need to get
// certain interfaces up to be able to make emergency calls
// in offline mode and without SIM
/*
* We cannot power on modem, but we need to get
* certain interfaces up to be able to make emergency calls
* in offline mode and without SIM
*/
ofono_modem_set_powered(modem, TRUE);
}
}
@@ -258,7 +262,7 @@ static void ril_post_sim(struct ofono_modem *modem)
ril->modem);
if (gc == NULL)
break;
ofono_gprs_add_context(gprs, gc);
}
}
@@ -266,6 +270,8 @@ static void ril_post_sim(struct ofono_modem *modem)
ofono_radio_settings_create(modem, 0, "rilmodem", ril->modem);
ofono_phonebook_create(modem, 0, "rilmodem", ril->modem);
ofono_call_forwarding_create(modem, 0, "rilmodem", ril->modem);
ofono_call_barring_create(modem, 0, "rilmodem", ril->modem);
ofono_stk_create(modem, 0, "rilmodem", ril->modem);
mw = ofono_message_waiting_create(modem);
if (mw)
@@ -292,9 +298,8 @@ static void ril_set_online_cb(struct ril_msg *message, gpointer user_data)
struct cb_data *cbd = user_data;
ofono_modem_online_cb_t cb = cbd->cb;
if (message->error == RIL_E_SUCCESS) {
if (message->error == RIL_E_SUCCESS)
CALLBACK_WITH_SUCCESS(cb, cbd->data);
}
else
CALLBACK_WITH_FAILURE(cb, cbd->data);
}
@@ -406,7 +411,7 @@ static void ril_connected(struct ril_msg *message, gpointer user_data)
connection = ofono_dbus_get_connection();
mce_daemon_watch = g_dbus_add_service_watch(connection, MCE_SERVICE,
mce_connect, mce_disconnect, modem, NULL);
mce_connect, mce_disconnect, modem, NULL);
}
static gboolean ril_re_init(gpointer user_data)
@@ -434,10 +439,10 @@ void ril_switchUser()
ofono_error("prctl(PR_SET_KEEPCAPS) failed:%s,%d",
strerror(errno), errno);
if (setgid(RADIO_ID) < 0 )
if (setgid(RADIO_ID) < 0)
ofono_error("setgid(%d) failed:%s,%d",
RADIO_ID, strerror(errno), errno);
if (setuid(RADIO_ID) < 0 )
if (setuid(RADIO_ID) < 0)
ofono_error("setuid(%d) failed:%s,%d",
RADIO_ID, strerror(errno), errno);

View File

@@ -737,6 +737,11 @@ static DBusMessage *stk_register_agent(DBusConnection *conn,
if (stk->session_agent == NULL)
stk->current_agent = stk->default_agent;
if (stk->driver && stk->driver->ready) {
DBG("Report driver agent is ready");
stk->driver->ready(stk);
}
return dbus_message_new_method_return(msg);
}

View File

@@ -63,6 +63,8 @@ if __name__ == "__main__":
except dbus.DBusException, e:
print "Unable to Disable All barrings: ", e
sys.exit(1)
print "Disabled all call barrings"
sys.exit(0)
elif (sys.argv[1] == 'passwd'):
try:
cb.ChangePassword(old_password, new_password)
@@ -77,6 +79,8 @@ if __name__ == "__main__":
except dbus.DBusException, e:
print "Unable to set property: ", e
sys.exit(1)
print "Property set completed", property
sys.exit(0)
canexit = True

View File

@@ -1,10 +1,15 @@
#!/usr/bin/python
import gobject
import sys
import dbus
import dbus.mainloop.glib
def print_usage():
print "Usage: test-ss-control-cb <password>"
sys.exit(1);
def property_changed(property, value):
print "CallBarring property %s changed to %s" % (property, value)
@@ -15,6 +20,11 @@ def print_properties(cb):
print "property %s, value: %s" % (p, properties[p])
if __name__ == "__main__":
if (len(sys.argv) != 2):
print_usage()
password = sys.argv[1]
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
@@ -29,7 +39,7 @@ if __name__ == "__main__":
cb.connect_to_signal("PropertyChanged", property_changed)
ss = dbus.Interface(bus.get_object('org.ofono', modems[0]),
ss = dbus.Interface(bus.get_object('org.ofono', modems[0][0]),
'org.ofono.SupplementaryServices')
print_properties(cb)
@@ -82,13 +92,19 @@ if __name__ == "__main__":
print "Query All"
print ss.Initiate("*#330#")
ss_string = "*33*" + password + "*11#"
print "Enable Barring for Outgoing International calls for Voice"
print ss.Initiate("*33*3579*11#")
print ss.Initiate(ss_string)
print_properties(cb)
ss_string = "#330*" + password + "#"
print "Disable All Barrings"
print ss.Initiate("#330*3579#")
print ss.Initiate(ss_string)
sys.exit(1);
mainloop = gobject.MainLoop()
mainloop.run()