Compare commits

...

3 Commits

Author SHA1 Message Date
Slava Monich
d62f0e6f8a [ril] Respect state restrictions. JB#42752
Do not allow mobile data connections if packet data access is blocked
due to restriction.

Conflicts:
	ofono/drivers/ril/ril_constants.h
2018-09-12 00:54:36 +03:00
Sergey Chupligin
9eea761dcb [ril] Fix incoming call indication on mtk2 vendor. Fixes JB#40790 2018-09-12 00:53:08 +03:00
NeKit
268e2b2139 [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-12 00:53:08 +03:00
3 changed files with 116 additions and 16 deletions

View File

@@ -581,6 +581,14 @@ enum ril_cell_info_type {
/* 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,
RIL_RESTRICTED_STATE_CS_NORMAL = 0x02,
RIL_RESTRICTED_STATE_CS_ALL = 0x04,
RIL_RESTRICTED_STATE_PS_ALL = 0x10
};
/* Suplementary services Service class*/
#define SERVICE_CLASS_NONE 0

View File

@@ -76,6 +76,12 @@ enum ril_data_priv_flags {
typedef GObjectClass RilDataClass;
typedef struct ril_data RilData;
enum ril_data_io_event_id {
IO_EVENT_DATA_CALL_LIST_CHANGED,
IO_EVENT_RESTRICTED_STATE_CHANGED,
IO_EVENT_COUNT
};
enum ril_data_settings_event_id {
SETTINGS_EVENT_IMSI_CHANGED,
SETTINGS_EVENT_PREF_MODE,
@@ -94,9 +100,11 @@ struct ril_data_priv {
struct ril_radio *radio;
struct ril_network *network;
struct ril_data_manager *dm;
enum ril_data_priv_flags flags;
struct ril_vendor_hook *vendor_hook;
enum ril_data_priv_flags flags;
enum ril_restricted_state restricted_state;
struct ril_data_request *req_queue;
struct ril_data_request *pending_req;
@@ -104,7 +112,7 @@ struct ril_data_priv {
guint slot;
char *log_prefix;
guint query_id;
gulong io_event_id;
gulong io_event_id[IO_EVENT_COUNT];
gulong settings_event_id[SETTINGS_EVENT_COUNT];
};
@@ -547,6 +555,37 @@ static void ril_data_set_calls(struct ril_data *self,
}
}
static void ril_data_check_allowed(struct ril_data *self, gboolean was_allowed)
{
if (ril_data_allowed(self) != was_allowed) {
ril_data_signal_emit(self, SIGNAL_ALLOW_CHANGED);
}
}
static void ril_data_restricted_state_changed_cb(GRilIoChannel *io, guint event,
const void *data, guint len, void *user_data)
{
struct ril_data *self = RIL_DATA(user_data);
GRilIoParser rilp;
guint32 count, state;
GASSERT(event == RIL_UNSOL_RESTRICTED_STATE_CHANGED);
grilio_parser_init(&rilp, data, len);
if (grilio_parser_get_uint32(&rilp, &count) && count == 1 &&
grilio_parser_get_uint32(&rilp, &state) &&
grilio_parser_at_end(&rilp)) {
struct ril_data_priv *priv = self->priv;
if (priv->restricted_state != state) {
const gboolean was_allowed = ril_data_allowed(self);
DBG_(self, "restricted state 0x%02x", state);
priv->restricted_state = state;
ril_data_check_allowed(self, was_allowed);
}
}
}
static void ril_data_call_list_changed_cb(GRilIoChannel *io, guint event,
const void *data, guint len, void *user_data)
{
@@ -1070,9 +1109,7 @@ static void ril_data_allow_cb(GRilIoChannel *io, int ril_status,
DBG_(data, "data off");
}
if (ril_data_allowed(data) != was_allowed) {
ril_data_signal_emit(data, SIGNAL_ALLOW_CHANGED);
}
ril_data_check_allowed(data, was_allowed);
}
ril_data_request_finish(req);
@@ -1188,9 +1225,15 @@ struct ril_data *ril_data_new(struct ril_data_manager *dm, const char *name,
priv->radio = ril_radio_ref(radio);
priv->network = ril_network_ref(network);
priv->vendor_hook = ril_vendor_hook_ref(vendor_hook);
priv->io_event_id = grilio_channel_add_unsol_event_handler(io,
priv->io_event_id[IO_EVENT_DATA_CALL_LIST_CHANGED] =
grilio_channel_add_unsol_event_handler(io,
ril_data_call_list_changed_cb,
RIL_UNSOL_DATA_CALL_LIST_CHANGED, self);
priv->io_event_id[IO_EVENT_RESTRICTED_STATE_CHANGED] =
grilio_channel_add_unsol_event_handler(io,
ril_data_restricted_state_changed_cb,
RIL_UNSOL_RESTRICTED_STATE_CHANGED, self);
priv->settings_event_id[SETTINGS_EVENT_IMSI_CHANGED] =
ril_sim_settings_add_imsi_changed_handler(settings,
@@ -1264,6 +1307,8 @@ void ril_data_unref(struct ril_data *self)
gboolean ril_data_allowed(struct ril_data *self)
{
return G_LIKELY(self) &&
(self->priv->restricted_state &
RIL_RESTRICTED_STATE_PS_ALL) == 0 &&
(self->priv->flags &
(RIL_DATA_FLAG_ALLOWED | RIL_DATA_FLAG_ON)) ==
(RIL_DATA_FLAG_ALLOWED | RIL_DATA_FLAG_ON);
@@ -1348,9 +1393,7 @@ static void ril_data_disallow(struct ril_data *self)
ril_data_power_update(self);
}
if (ril_data_allowed(self) != was_allowed) {
ril_data_signal_emit(self, SIGNAL_ALLOW_CHANGED);
}
ril_data_check_allowed(self, was_allowed);
}
static void ril_data_max_speed_cb(gpointer data, gpointer max_speed)
@@ -1468,7 +1511,7 @@ static void ril_data_dispose(GObject *object)
ril_sim_settings_remove_handlers(settings, priv->settings_event_id,
G_N_ELEMENTS(priv->settings_event_id));
grilio_channel_remove_handlers(priv->io, &priv->io_event_id, 1);
grilio_channel_remove_all_handlers(priv->io, priv->io_event_id);
grilio_queue_cancel_all(priv->q, FALSE);
priv->query_id = 0;

View File

@@ -27,6 +27,7 @@
#include <grilio_queue.h>
#include <gutil_macros.h>
#include <gutil_misc.h>
#include "ofono.h"
@@ -83,6 +84,7 @@ struct ril_vendor_hook_mtk_auto {
struct ril_mtk_msg {
gboolean attach_apn_has_roaming_protocol;
guint request_resume_registration;
guint request_set_call_indication;
/* See ril_vendor_mtk_auto_detect_event */
#define unsol_msgs unsol_ps_network_state_changed
@@ -97,6 +99,7 @@ struct ril_mtk_msg {
static const struct ril_mtk_msg msg_mtk1 = {
.attach_apn_has_roaming_protocol = TRUE,
.request_resume_registration = 2050,
.request_set_call_indication = 2065,
.unsol_ps_network_state_changed = 3012,
.unsol_registration_suspended = 3021,
.unsol_incoming_call_indication = 3037,
@@ -106,6 +109,7 @@ static const struct ril_mtk_msg msg_mtk1 = {
static const struct ril_mtk_msg msg_mtk2 = {
.attach_apn_has_roaming_protocol = FALSE,
.request_resume_registration = 2065,
.request_set_call_indication = 2086,
.unsol_ps_network_state_changed = 3015,
.unsol_registration_suspended = 3024,
.unsol_incoming_call_indication = 3042,
@@ -132,6 +136,8 @@ static const char *ril_vendor_mtk_request_to_string
if (request == msg->request_resume_registration) {
return "MTK_RESUME_REGISTRATION";
} else if (request == msg->request_set_call_indication) {
return "MTK_SET_CALL_INDICATION";
} else {
return NULL;
}
@@ -340,12 +346,55 @@ static void ril_vendor_mtk_ps_network_state_changed(GRilIoChannel *io,
ril_network_query_registration_state(self->network);
}
static void ril_vendor_mtk_call_state_changed(GRilIoChannel *io,
guint id, const void *data, guint len, void *user_data)
static void ril_vendor_mtk_incoming_call_indication(GRilIoChannel *io, guint id,
const void *data, guint len, void *user_data)
{
/* Ignore the payload, let ril_voicecall.c do its normal stuff */
grilio_channel_inject_unsol_event(io,
RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0);
struct ril_vendor_hook_mtk *self = user_data;
const struct ril_mtk_msg *msg = self->msg;
GRilIoRequest* req = NULL;
GASSERT(id == msg->unsol_incoming_call_indication);
if (msg->request_set_call_indication) {
int nparams, cid, seq;
gchar *call_id = NULL, *seq_no = NULL;
GRilIoParser rilp;
grilio_parser_init(&rilp, data, len);
if (grilio_parser_get_int32(&rilp, &nparams) && nparams >= 5 &&
(call_id = grilio_parser_get_utf8(&rilp)) != NULL &&
grilio_parser_skip_string(&rilp) /* number */ &&
grilio_parser_skip_string(&rilp) /* type */ &&
grilio_parser_skip_string(&rilp) /* call_mode */ &&
(seq_no = grilio_parser_get_utf8(&rilp)) != NULL &&
gutil_parse_int(call_id, 10, &cid) &&
gutil_parse_int(seq_no, 10, &seq)) {
DBG("slot=%u,cid=%d,seq=%d", self->slot, cid, seq);
req = grilio_request_new();
grilio_request_append_int32(req, 3); /* Param count */
/* mode - IMS_ALLOW_INCOMING_CALL_INDICATION: */
grilio_request_append_int32(req, 0);
grilio_request_append_int32(req, cid);
grilio_request_append_int32(req, seq);
} else {
DBG("failed to parse INCOMING_CALL_INDICATION");
}
g_free(call_id);
g_free(seq_no);
}
if (req) {
grilio_queue_send_request(self->q, req,
msg->request_set_call_indication);
grilio_request_unref(req);
} else {
/* Let ril_voicecall.c know that something happened */
grilio_channel_inject_unsol_event(io,
RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0);
}
}
static GRilIoRequest *ril_vendor_mtk_data_call_req
@@ -443,7 +492,7 @@ static void ril_vendor_mtk_hook_subscribe(struct ril_vendor_hook_mtk *self)
if (msg->unsol_incoming_call_indication) {
self->ril_event_id[MTK_EVENT_INCOMING_CALL_INDICATION] =
grilio_channel_add_unsol_event_handler(self->io,
ril_vendor_mtk_call_state_changed,
ril_vendor_mtk_incoming_call_indication,
msg->unsol_incoming_call_indication, self);
}
}