@@ -1,6 +1,7 @@
/*
- * Copyright (C) 2018-2020 Jolla Ltd.
- * Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
+ * Copyright (C) 2018-2021 Jolla Ltd.
+ * Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
+ * Copyright (C) 2021 Open Mobile Platform LLC.
*
* You may use this file under the terms of BSD license as follows:
*
@@ -58,10 +59,34 @@
#define RIL_BINDER_KEY_MODEM "modem"
#define RIL_BINDER_KEY_DEV "dev"
#define RIL_BINDER_KEY_NAME "name"
+#define RIL_BINDER_KEY_INTERFACE "interface"
-#define RIL_BINDER_DEFAULT_MODEM "/ril_0"
-#define RIL_BINDER_DEFAULT_DEV "/dev/hwbinder"
-#define RIL_BINDER_DEFAULT_NAME "slot1"
+#define RIL_BINDER_DEFAULT_MODEM "/ril_0"
+#define RIL_BINDER_DEFAULT_DEV "/dev/hwbinder"
+#define RIL_BINDER_DEFAULT_NAME "slot1"
+
+#define DEFAULT_INTERFACE RADIO_INTERFACE_1_2
+
+#define RIL_PROTO_IP_STR "IP"
+#define RIL_PROTO_IPV6_STR "IPV6"
+#define RIL_PROTO_IPV4V6_STR "IPV4V6"
+
+/* Preferred network types as defined in ril.h */
+enum ril_pref_net_type {
+ PREF_NET_TYPE_GSM_WCDMA = 0,
+ PREF_NET_TYPE_GSM_ONLY = 1,
+ PREF_NET_TYPE_WCDMA = 2,
+ PREF_NET_TYPE_GSM_WCDMA_AUTO = 3,
+ PREF_NET_TYPE_CDMA_EVDO_AUTO = 4,
+ PREF_NET_TYPE_CDMA_ONLY = 5,
+ PREF_NET_TYPE_EVDO_ONLY = 6,
+ PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO = 7,
+ PREF_NET_TYPE_LTE_CDMA_EVDO = 8,
+ PREF_NET_TYPE_LTE_GSM_WCDMA = 9,
+ PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA = 10,
+ PREF_NET_TYPE_LTE_ONLY = 11,
+ PREF_NET_TYPE_LTE_WCDMA = 12
+};
enum {
RADIO_EVENT_INDICATION,
@@ -96,17 +121,21 @@
RilBinderOemHook* oemhook;
gulong oemhook_raw_response_id;
GUtilIdleQueue* idle;
- GHashTable* req_map; /* code -> RilBinderRadioCall */
- GHashTable* resp_map; /* resp_tx -> RilBinderRadioCall */
- GHashTable* unsol_map; /* unsol_tx -> RilBinderRadioEvent */
GByteArray* buf;
gulong radio_event_id[RADIO_EVENT_COUNT];
+ /* code -> RilBinderRadioCall */
+ GHashTable* req_map[RADIO_INTERFACE_COUNT];
+ /* resp_tx -> RilBinderRadioCall */
+ GHashTable* resp_map[RADIO_INTERFACE_COUNT];
+ /* unsol_tx -> RilBinderRadioEvent */
+ GHashTable* unsol_map[RADIO_INTERFACE_COUNT];
};
G_DEFINE_TYPE(RilBinderRadio, ril_binder_radio, GRILIO_TYPE_TRANSPORT)
#define PARENT_CLASS ril_binder_radio_parent_class
+#define ARRAY_AND_COUNT(a) a, G_N_ELEMENTS(a)
#define DBG_(self,fmt,args...) \
GDEBUG("%s" fmt, (self)->parent.log_prefix, ##args)
@@ -211,6 +240,125 @@
return (val && val[0]) ? val : def;
}
+static
+void
+ril_binder_radio_init_call_maps(
+ GHashTable* req_map,
+ GHashTable* resp_map,
+ const RilBinderRadioCall* calls,
+ guint count)
+{
+ guint i;
+
+ for (i = 0; i < count; i++) {
+ const RilBinderRadioCall* call = calls + i;
+
+ if (call->req_tx) {
+ g_hash_table_insert(req_map, GINT_TO_POINTER(call->code),
+ (gpointer) call);
+ }
+ if (call->resp_tx) {
+ g_hash_table_insert(resp_map, GINT_TO_POINTER(call->resp_tx),
+ (gpointer) call);
+ }
+ }
+}
+
+static
+void
+ril_binder_radio_init_unsol_map(
+ GHashTable* unsol_map,
+ const RilBinderRadioEvent* events,
+ guint count)
+{
+ guint i;
+
+ for (i = 0; i < count; i++) {
+ const RilBinderRadioEvent* event = events + i;
+
+ g_hash_table_insert(unsol_map, GINT_TO_POINTER(event->unsol_tx),
+ (gpointer) event);
+ }
+}
+
+static
+void
+ril_binder_radio_init_version(
+ RilBinderRadioPriv* priv,
+ RADIO_INTERFACE v,
+ const RilBinderRadioCall* calls,
+ guint num_calls,
+ const RilBinderRadioEvent* events,
+ guint num_events)
+{
+ priv->req_map[v] = g_hash_table_new(g_direct_hash, g_direct_equal);
+ priv->resp_map[v] = g_hash_table_new(g_direct_hash, g_direct_equal);
+ priv->unsol_map[v] = g_hash_table_new(g_direct_hash, g_direct_equal);
+ ril_binder_radio_init_unsol_map(priv->unsol_map[v], events, num_events);
+ ril_binder_radio_init_call_maps(priv->req_map[v], priv->resp_map[v],
+ calls, num_calls);
+}
+
+static
+RADIO_APN_TYPES
+ril_binder_radio_apn_types_for_profile(
+ RADIO_DATA_PROFILE_ID profile_id)
+{
+ switch (profile_id) {
+ case RADIO_DATA_PROFILE_INVALID:
+ return RADIO_APN_TYPE_NONE;
+ case RADIO_DATA_PROFILE_IMS:
+ return RADIO_APN_TYPE_IMS;
+ case RADIO_DATA_PROFILE_CBS:
+ return RADIO_APN_TYPE_CBS;
+ case RADIO_DATA_PROFILE_FOTA:
+ return RADIO_APN_TYPE_FOTA;
+ case RADIO_DATA_PROFILE_DEFAULT:
+ return (RADIO_APN_TYPE_DEFAULT |
+ RADIO_APN_TYPE_SUPL |
+ RADIO_APN_TYPE_IA);
+ default:
+ /*
+ * There's no standard profile id for MMS, OEM-specific profile ids
+ * are used for that.
+ */
+ return RADIO_APN_TYPE_MMS;
+ }
+}
+
+static
+const char *
+radio_pdp_protocol_type_to_str(enum radio_pdp_protocol_type type)
+{
+ switch (type) {
+ case RADIO_PDP_PROTOCOL_IP:
+ return RIL_PROTO_IP_STR;
+ case RADIO_PDP_PROTOCOL_IPV6:
+ return RIL_PROTO_IPV6_STR;
+ case RADIO_PDP_PROTOCOL_IPV4V6:
+ return RIL_PROTO_IPV4V6_STR;
+ default:
+ return "";
+ }
+}
+
+static
+const char*
+ril_binder_radio_interface_name(
+ RADIO_INTERFACE interface)
+{
+ switch (interface) {
+ case RADIO_INTERFACE_1_0: return "radio@1.0";
+ case RADIO_INTERFACE_1_1: return "radio@1.1";
+ case RADIO_INTERFACE_1_2: return "radio@1.2";
+ case RADIO_INTERFACE_1_3: return "radio@1.3";
+ case RADIO_INTERFACE_1_4: return "radio@1.4";
+ case RADIO_INTERFACE_COUNT:
+ break;
+ }
+ return NULL;
+}
+
/*==========================================================================*
* Encoders (plugin -> binder)
*==========================================================================*/
@@ -411,6 +559,45 @@
return ok;
}
+static
+gboolean
+ril_binder_radio_encode_deactivate_data_call_1_2(
+ GRilIoRequest* in,
+ GBinderLocalRequest* out)
+{
+ gboolean ok = FALSE;
+ GRilIoParser parser;
+ gint32 count, cid, reason;
+ char* cid_str = NULL;
+ char* reason_str = NULL;
+
+ ril_binder_radio_init_parser(&parser, in);
+ if (grilio_parser_get_int32(&parser, &count) && count == 2 &&
+ (cid_str = grilio_parser_get_utf8(&parser)) != NULL &&
+ (reason_str = grilio_parser_get_utf8(&parser)) != NULL &&
+ gutil_parse_int(cid_str, 10, &cid) &&
+ gutil_parse_int(reason_str, 10, &reason)) {
+ GBinderWriter writer;
+
+ if (reason == 0) {
+ reason = RADIO_DATA_REQUEST_REASON_NORMAL;
+ } else if (reason == 1) {
+ reason = RADIO_DATA_REQUEST_REASON_SHUTDOWN;
+ } else {
+ reason = RADIO_DATA_REQUEST_REASON_HANDOVER;
+ }
+
+ gbinder_local_request_init_writer(out, &writer);
+ gbinder_writer_append_int32(&writer, grilio_request_serial(in));
+ gbinder_writer_append_int32(&writer, cid);
+ gbinder_writer_append_int32(&writer, reason);
+ ok = TRUE;
+ }
+ g_free(cid_str);
+ g_free(reason_str);
+ return ok;
+}
+
/**
* @param int32_t Serial number of request.
* @param dialInfo Dial struct
@@ -572,8 +759,7 @@
profile->authType = auth;
profile->enabled = TRUE;
profile->supportedApnTypesBitmap =
- (profile_id == RADIO_DATA_PROFILE_DEFAULT) ?
- RADIO_APN_TYPE_DEFAULT : RADIO_APN_TYPE_MMS;
+ ril_binder_radio_apn_types_for_profile(profile_id);
/* Write the parcel */
gbinder_writer_append_int32(&writer, grilio_request_serial(in));
@@ -599,6 +785,135 @@
/**
* @param int32_t Serial number of request.
+ * @param RadioTechnology Radio technology to use.
+ * @param DataProfileInfo Data profile info.
+ * @param bool modemCognitive Indicating this profile was sent to the modem
+ * through setDataProfile earlier.
+ * @param bool roamingAllowed Indicating data roaming is allowed or not.
+ * @param bool isRoaming Indicating the device is roaming or not.
+ */
+static
+gboolean
+ril_binder_radio_encode_setup_data_call_1_2(
+ GRilIoRequest* in,
+ GBinderLocalRequest* out)
+{
+ gboolean ok = FALSE;
+ GRilIoParser parser;
+ gint32 count, tech, auth, profile_id;
+ char* profile_str = NULL;
+ char* tech_str = NULL;
+ char* auth_str = NULL;
+ char* apn = NULL;
+ char* user = NULL;
+ char* password = NULL;
+ char* proto = NULL;
+
+ ril_binder_radio_init_parser(&parser, in);
+ if (grilio_parser_get_int32(&parser, &count) && count == 7 &&
+ (tech_str = grilio_parser_get_utf8(&parser)) != NULL &&
+ gutil_parse_int(tech_str, 10, &tech) &&
+ (profile_str = grilio_parser_get_utf8(&parser)) != NULL &&
+ gutil_parse_int(profile_str, 10, &profile_id) &&
+ (apn = grilio_parser_get_utf8(&parser)) != NULL &&
+ (user = grilio_parser_get_utf8(&parser)) != NULL &&
+ (password = grilio_parser_get_utf8(&parser)) != NULL &&
+ (auth_str = grilio_parser_get_utf8(&parser)) != NULL &&
+ gutil_parse_int(auth_str, 10, &auth) &&
+ (proto = grilio_parser_get_utf8(&parser)) != NULL) {
+ GBinderWriter writer;
+ RadioDataProfile* profile;
+ RADIO_ACCESS_NETWORK ran;
+
+ /* ril.h has this to say about the radio tech parameter:
+ *
+ * ((const char **)data)[0] Radio technology to use: 0-CDMA,
+ * 1-GSM/UMTS, 2... for values above 2
+ * this is RIL_RadioTechnology + 2.
+ *
+ * Makes little sense but it is what it is.
+ */
+ if (tech > 4) {
+ tech -= 2;
+ }
+
+ ran = RADIO_ACCESS_NETWORK_UNKNOWN;
+ switch ((RADIO_TECH)tech) {
+ case RADIO_TECH_GPRS:
+ case RADIO_TECH_EDGE:
+ case RADIO_TECH_GSM:
+ ran = RADIO_ACCESS_NETWORK_GERAN;
+ break;
+ case RADIO_TECH_UMTS:
+ case RADIO_TECH_HSDPA:
+ case RADIO_TECH_HSPAP:
+ case RADIO_TECH_HSUPA:
+ case RADIO_TECH_HSPA:
+ case RADIO_TECH_TD_SCDMA:
+ ran = RADIO_ACCESS_NETWORK_UTRAN;
+ break;
+ case RADIO_TECH_IS95A:
+ case RADIO_TECH_IS95B:
+ case RADIO_TECH_ONE_X_RTT:
+ case RADIO_TECH_EVDO_0:
+ case RADIO_TECH_EVDO_A:
+ case RADIO_TECH_EVDO_B:
+ case RADIO_TECH_EHRPD:
+ ran = RADIO_ACCESS_NETWORK_CDMA2000;
+ break;
+ case RADIO_TECH_LTE:
+ case RADIO_TECH_LTE_CA:
+ ran = RADIO_ACCESS_NETWORK_EUTRAN;
+ break;
+ case RADIO_TECH_IWLAN:
+ ran = RADIO_ACCESS_NETWORK_IWLAN;
+ break;
+ case RADIO_TECH_UNKNOWN:
+ break;
+ }
+
+ /* Initialize the writer and the data to be written */
+ gbinder_local_request_init_writer(out, &writer);
+ profile = gbinder_writer_new0(&writer, RadioDataProfile);
+ ril_binder_radio_take_string(out, &profile->apn, apn);
+ ril_binder_radio_take_string(out, &profile->protocol, proto);
+ ril_binder_radio_take_string(out, &profile->user, user);
+ ril_binder_radio_take_string(out, &profile->password, password);
+ ril_binder_radio_take_string(out, &profile->mvnoMatchData, NULL);
+ profile->roamingProtocol = profile->protocol;
+ profile->profileId = profile_id;
+ profile->authType = auth;
+ profile->enabled = TRUE;
+ profile->supportedApnTypesBitmap =
+ ril_binder_radio_apn_types_for_profile(profile_id);
+
+ /* Write the parcel */
+ gbinder_writer_append_int32(&writer, grilio_request_serial(in));
+ gbinder_writer_append_int32(&writer, ran); /* accessNetwork */
+ ril_binder_radio_write_single_data_profile(&writer, profile);
+ gbinder_writer_append_bool(&writer, FALSE); /* modemCognitive */
+ /* TODO: provide the actual roaming status? */
+ gbinder_writer_append_bool(&writer, TRUE); /* roamingAllowed */
+ gbinder_writer_append_bool(&writer, FALSE); /* isRoaming */
+ gbinder_writer_append_int32(&writer, RADIO_DATA_REQUEST_REASON_NORMAL);
+ gbinder_writer_append_hidl_string_vec(&writer, NULL, 0); /* addresses */
+ gbinder_writer_append_hidl_string_vec(&writer, NULL, 0); /* dnses */
+ ok = TRUE;
+ } else {
+ g_free(apn);
+ g_free(user);
+ g_free(password);
+ g_free(proto);
+ }
+
+ g_free(profile_str);
+ g_free(tech_str);
+ g_free(auth_str);
+ return ok;
+}
+
+/**
+ * @param int32_t Serial number of request.
* @param smsWriteArgs SmsWriteArgs defined in types.hal
*/
static
@@ -1139,7 +1454,7 @@
for (i = 0; i < n; i++) {
RadioDataProfile* dp = profiles + i;
- gint32 profile_id, auth_type, enabled;
+ gint32 profile_id, type, auth_type, enabled;
char* apn = NULL;
char* proto = NULL;
char* username = NULL;
@@ -1151,7 +1466,7 @@
grilio_parser_get_int32(&parser, &auth_type) &&
grilio_parser_get_nullable_utf8(&parser, &username) &&
grilio_parser_get_nullable_utf8(&parser, &password) &&
- grilio_parser_get_int32(&parser, &dp->type) &&
+ grilio_parser_get_int32(&parser, &type) &&
grilio_parser_get_int32(&parser, &dp->maxConnsTime) &&
grilio_parser_get_int32(&parser, &dp->maxConns) &&
grilio_parser_get_int32(&parser, &dp->waitTime) &&
@@ -1162,14 +1477,13 @@
ril_binder_radio_take_string(out, &dp->user, username);
ril_binder_radio_take_string(out, &dp->password, password);
ril_binder_radio_take_string(out, &dp->mvnoMatchData, NULL);
+ dp->type = type;
dp->roamingProtocol = dp->protocol;
dp->profileId = profile_id;
dp->authType = auth_type;
dp->enabled = enabled;
dp->supportedApnTypesBitmap =
- (profile_id == RADIO_DATA_PROFILE_DEFAULT) ?
- (RADIO_APN_TYPE_DEFAULT | RADIO_APN_TYPE_SUPL |
- RADIO_APN_TYPE_IA) : RADIO_APN_TYPE_MMS;
+ ril_binder_radio_apn_types_for_profile(profile_id);
} else {
g_free(apn);
g_free(proto);
@@ -1254,6 +1568,74 @@
return FALSE;
}
+static
+gboolean
+ril_binder_radio_encode_icc_open_logical_channel(
+ GRilIoRequest* in,
+ GBinderLocalRequest* out)
+{
+ GRilIoParser parser;
+ char* aid;
+
+ ril_binder_radio_init_parser(&parser, in);
+ aid = grilio_parser_get_utf8(&parser);
+ if (aid) {
+ GBinderWriter writer;
+ gint32 p2 = 0;
+
+ grilio_parser_get_int32(&parser, &p2); /* Optional? */
+ gbinder_local_request_cleanup(out, g_free, aid);
+ gbinder_local_request_init_writer(out, &writer);
+ gbinder_writer_append_int32(&writer, grilio_request_serial(in));
+ gbinder_writer_append_hidl_string(&writer, aid);
+ gbinder_writer_append_int32(&writer, p2);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * @param int32_t Serial number of request.
+ * @param SimApdu
+ */
+static
+gboolean
+ril_binder_radio_encode_icc_transmit_apdu_logical_channel(
+ GRilIoRequest* in,
+ GBinderLocalRequest* out)
+{
+ GRilIoParser parser;
+ RadioSimApdu* apdu = g_new0(RadioSimApdu, 1);
+ char* data = NULL;
+
+ ril_binder_radio_init_parser(&parser, in);
+ if (grilio_parser_get_int32(&parser, &apdu->sessionId) &&
+ grilio_parser_get_int32(&parser, &apdu->cla) &&
+ grilio_parser_get_int32(&parser, &apdu->instruction) &&
+ grilio_parser_get_int32(&parser, &apdu->p1) &&
+ grilio_parser_get_int32(&parser, &apdu->p2) &&
+ grilio_parser_get_int32(&parser, &apdu->p3) &&
+ grilio_parser_get_nullable_utf8(&parser, &data)) {
+ GBinderWriter writer;
+ guint parent;
+
+ /* Initialize the writer and the data to be written */
+ gbinder_local_request_init_writer(out, &writer);
+ gbinder_local_request_cleanup(out, g_free, apdu);
+ ril_binder_radio_take_string(out, &apdu->data, data);
+
+ /* Write the arguments */
+ gbinder_writer_append_int32(&writer, grilio_request_serial(in));
+ parent = gbinder_writer_append_buffer_object(&writer, apdu,
+ sizeof(*apdu));
+ ril_binder_radio_write_hidl_string_data(&writer, apdu, data, parent);
+ return TRUE;
+ }
+
+ g_free(apdu);
+ return FALSE;
+}
+
/*==========================================================================*
* Decoders (binder -> plugin)
*==========================================================================*/
@@ -1436,12 +1818,84 @@
return FALSE;
}
+static
+void
+ril_binder_decode_vec_utf8_as_string(
+ GByteArray* out,
+ const GBinderHidlVec *vec,
+ const char *separator)
+{
+ const GBinderHidlString* elem = vec->data.ptr;
+ char str[256];
+ gchar *p = str;
+ int i;
+
+ bzero(str, sizeof(str));
+ for (i = 0; i < vec->count; i++) {
+ if (i) {
+ p += g_strlcat(p, separator, sizeof(str) - (p - str));
+ }
+ p += g_strlcat(p, elem->data.str, sizeof(str) - (p - str));
+ elem++;
+ }
+ grilio_encode_utf8(out, str);
+}
+
+static
+void
+ril_binder_radio_decode_data_call_1_4(
+ GByteArray* out,
+ const RadioDataCall_1_4* call)
+{
+ grilio_encode_int32(out, call->cause);
+ grilio_encode_int32(out, call->suggestedRetryTime);
+ grilio_encode_int32(out, call->cid);
+ grilio_encode_int32(out, call->active);
+ grilio_encode_utf8(out, radio_pdp_protocol_type_to_str(call->type));
+ grilio_encode_utf8(out, call->ifname.data.str);
+ ril_binder_decode_vec_utf8_as_string(out, &call->addresses, " ");
+ ril_binder_decode_vec_utf8_as_string(out, &call->dnses, " ");
+ ril_binder_decode_vec_utf8_as_string(out, &call->gateways, " ");
+ ril_binder_decode_vec_utf8_as_string(out, &call->pcscf, " ");
+ grilio_encode_int32(out, call->mtu);
+}
+
/**
* @param cardStatus ICC card status as defined by CardStatus in types.hal
*/
static
-gboolean
+void
ril_binder_radio_decode_icc_card_status(
+ const RadioCardStatus* sim,
+ GByteArray* out)
+{
+ const RadioAppStatus* apps = sim->apps.data.ptr;
+ guint i;
+
+ grilio_encode_int32(out, sim->cardState);
+ grilio_encode_int32(out, sim->universalPinState);
+ grilio_encode_int32(out, sim->gsmUmtsSubscriptionAppIndex);
+ grilio_encode_int32(out, sim->cdmaSubscriptionAppIndex);
+ grilio_encode_int32(out, sim->imsSubscriptionAppIndex);
+ grilio_encode_int32(out, sim->apps.count);
+
+ for (i = 0; i < sim->apps.count; i++) {
+ const RadioAppStatus* app = apps + i;
+
+ grilio_encode_int32(out, app->appType);
+ grilio_encode_int32(out, app->appState);
+ grilio_encode_int32(out, app->persoSubstate);
+ grilio_encode_utf8(out, app->aid.data.str);
+ grilio_encode_utf8(out, app->label.data.str);
+ grilio_encode_int32(out, app->pinReplaced);
+ grilio_encode_int32(out, app->pin1);
+ grilio_encode_int32(out, app->pin2);
+ }
+}
+
+static
+gboolean
+ril_binder_radio_decode_icc_card_status_1_0(
GBinderReader* in,
GByteArray* out)
{
@@ -1450,29 +1904,47 @@
(in, RadioCardStatus);
if (sim) {
- const RadioAppStatus* apps = sim->apps.data.ptr;
- guint i;
+ ril_binder_radio_decode_icc_card_status(sim, out);
+ ok = TRUE;
+ }
+ return ok;
+}
- grilio_encode_int32(out, sim->cardState);
- grilio_encode_int32(out, sim->universalPinState);
- grilio_encode_int32(out, sim->gsmUmtsSubscriptionAppIndex);
- grilio_encode_int32(out, sim->cdmaSubscriptionAppIndex);
- grilio_encode_int32(out, sim->imsSubscriptionAppIndex);
- grilio_encode_int32(out, sim->apps.count);
-
- for (i = 0; i < sim->apps.count; i++) {
- const RadioAppStatus* app = apps + i;
-
- grilio_encode_int32(out, app->appType);
- grilio_encode_int32(out, app->appState);
- grilio_encode_int32(out, app->persoSubstate);
- grilio_encode_utf8(out, app->aid.data.str);
- grilio_encode_utf8(out, app->label.data.str);
- grilio_encode_int32(out, app->pinReplaced);
- grilio_encode_int32(out, app->pin1);
- grilio_encode_int32(out, app->pin2);
- }
+/**
+ * @param cardStatus ICC card status as defined by CardStatus in types.hal
+ */
+static
+gboolean
+ril_binder_radio_decode_icc_card_status_1_2(
+ GBinderReader* in,
+ GByteArray* out)
+{
+ gboolean ok = FALSE;
+ const RadioCardStatus_1_2* sim = gbinder_reader_read_hidl_struct
+ (in, RadioCardStatus_1_2);
+ if (sim) {
+ ril_binder_radio_decode_icc_card_status(&sim->base, out);
+ ok = TRUE;
+ }
+ return ok;
+}
+
+/**
+ * @param cardStatus ICC card status as defined by CardStatus in types.hal
+ */
+static
+gboolean
+ril_binder_radio_decode_icc_card_status_1_4(
+ GBinderReader* in,
+ GByteArray* out)
+{
+ gboolean ok = FALSE;
+ const RadioCardStatus_1_4* sim = gbinder_reader_read_hidl_struct
+ (in, RadioCardStatus_1_4);
+
+ if (sim) {
+ ril_binder_radio_decode_icc_card_status(&sim->base, out);
ok = TRUE;
}
return ok;
@@ -1528,6 +2000,31 @@
}
/**
+ * @param dataRegResponse DataRegStateResult defined in types.hal
+ */
+static
+gboolean
+ril_binder_radio_decode_data_reg_state_1_4(
+ GBinderReader* in,
+ GByteArray* out)
+{
+ const RadioDataRegStateResult_1_4* reg = gbinder_reader_read_hidl_struct
+ (in, RadioDataRegStateResult_1_4);
+
+ if (reg) {
+ grilio_encode_int32(out, 6);
+ grilio_encode_format(out, "%d", reg->regState);
+ grilio_encode_utf8(out, ""); /* slac */
+ grilio_encode_utf8(out, ""); /* sci */
+ grilio_encode_format(out, "%d", reg->rat);
+ grilio_encode_format(out, "%d", reg->reasonDataDenied);
+ grilio_encode_format(out, "%d", reg->maxDataCalls);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
* @param sms Response to sms sent as defined by SendSmsResult in types.hal
*/
static
@@ -1553,7 +2050,7 @@
*/
static
gboolean
-ril_binder_radio_decode_icc_result(
+ril_binder_radio_decode_icc_io_result(
GBinderReader* in,
GByteArray* out)
{
@@ -1607,6 +2104,27 @@
* @param calls Current call list
*/
static
+void
+ril_binder_radio_decode_call(
+ const RadioCall* call,
+ GByteArray* out)
+{
+ grilio_encode_int32(out, call->state);
+ grilio_encode_int32(out, call->index);
+ grilio_encode_int32(out, call->toa);
+ grilio_encode_int32(out, call->isMpty);
+ grilio_encode_int32(out, call->isMT);
+ grilio_encode_int32(out, call->als);
+ grilio_encode_int32(out, call->isVoice);
+ grilio_encode_int32(out, call->isVoicePrivacy);
+ grilio_encode_utf8(out, call->number.data.str);
+ grilio_encode_int32(out, call->numberPresentation);
+ grilio_encode_utf8(out, call->name.data.str);
+ grilio_encode_int32(out, call->namePresentation);
+ grilio_encode_int32(out, 0); /* uusInfo */
+}
+
+static
gboolean
ril_binder_radio_decode_call_list(
GBinderReader* in,
@@ -1622,21 +2140,33 @@
grilio_encode_int32(out, count);
for (i = 0; i < count; i++) {
- const RadioCall* call = calls + i;
+ ril_binder_radio_decode_call(calls + i, out);
+ }
+ ok = TRUE;
+ }
+ return ok;
+}
- grilio_encode_int32(out, call->state);
- grilio_encode_int32(out, call->index);
- grilio_encode_int32(out, call->toa);
- grilio_encode_int32(out, call->isMpty);
- grilio_encode_int32(out, call->isMT);
- grilio_encode_int32(out, call->als);
- grilio_encode_int32(out, call->isVoice);
- grilio_encode_int32(out, call->isVoicePrivacy);
- grilio_encode_utf8(out, call->number.data.str);
- grilio_encode_int32(out, call->numberPresentation);
- grilio_encode_utf8(out, call->name.data.str);
- grilio_encode_int32(out, call->namePresentation);
- grilio_encode_int32(out, 0); /* uusInfo */
+/**
+ * @param calls Current call list
+ */
+static
+gboolean
+ril_binder_radio_decode_call_list_1_2(
+ GBinderReader* in,
+ GByteArray* out)
+{
+ gboolean ok = FALSE;
+ gsize count = 0;
+ const RadioCall_1_2* calls = gbinder_reader_read_hidl_type_vec
+ (in, RadioCall_1_2, &count);
+
+ if (calls) {
+ guint i;
+
+ grilio_encode_int32(out, count);
+ for (i = 0; i < count; i++) {
+ ril_binder_radio_decode_call(&calls[i].base, out);
}
ok = TRUE;
}
@@ -1752,6 +2282,33 @@
}
/**
+ * @param dcResponse List of SetupDataCallResult as defined in types.hal
+ */
+static
+gboolean
+ril_binder_radio_decode_data_call_list_1_4(
+ GBinderReader* in,
+ GByteArray* out)
+{
+ gboolean ok = FALSE;
+ gsize count = 0;
+ const RadioDataCall_1_4* calls = gbinder_reader_read_hidl_type_vec
+ (in, RadioDataCall_1_4, &count);
+
+ if (calls) {
+ guint i;
+
+ grilio_encode_int32(out, DATA_CALL_VERSION);
+ grilio_encode_int32(out, count);
+ for (i = 0; i < count; i++) {
+ ril_binder_radio_decode_data_call_1_4(out, calls + i);
+ }
+ ok = TRUE;
+ }
+ return ok;
+}
+
+/**
* @param dcResponse SetupDataCallResult defined in types.hal
*/
static
@@ -1773,6 +2330,27 @@
}
/**
+ * @param dcResponse SetupDataCallResult defined in types.hal
+ */
+static
+gboolean
+ril_binder_radio_decode_setup_data_call_result_1_4(
+ GBinderReader* in,
+ GByteArray* out)
+{
+ const RadioDataCall_1_4* call = gbinder_reader_read_hidl_struct
+ (in, RadioDataCall_1_4);
+
+ if (call) {
+ grilio_encode_int32(out, DATA_CALL_VERSION);
+ grilio_encode_int32(out, 1);
+ ril_binder_radio_decode_data_call_1_4(out, call);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
* @param nwType RadioPreferredNetworkType defined in types.hal
*/
static
@@ -1791,6 +2369,61 @@
return FALSE;
}
+static
+gint32
+ril_binder_radio_raf_to_pref_mode(
+ gint32 raf)
+{
+ gint32 gen = 0;
+
+#define RADIO_GEN_2G (RAF_GSM | RAF_GPRS | RAF_EDGE)
+#define RADIO_GEN_3G (RAF_UMTS | RAF_HSDPA | RAF_HSUPA | RAF_HSPA | RAF_HSPAP)
+#define RADIO_GEN_4G (RAF_LTE | RAF_LTE_CA)
+
+ gen |= (raf & RADIO_GEN_2G) ? RADIO_GEN_2G : 0;
+ gen |= (raf & RADIO_GEN_3G) ? RADIO_GEN_3G : 0;
+ gen |= (raf & RADIO_GEN_4G) ? RADIO_GEN_4G : 0;
+
+ switch (gen) {
+ case RADIO_GEN_2G:
+ return PREF_NET_TYPE_GSM_ONLY;
+ case RADIO_GEN_2G | RADIO_GEN_3G:
+ return PREF_NET_TYPE_GSM_WCDMA;
+ case RADIO_GEN_2G | RADIO_GEN_3G | RADIO_GEN_4G:
+ return PREF_NET_TYPE_LTE_GSM_WCDMA;
+ case RADIO_GEN_3G | RADIO_GEN_4G:
+ return PREF_NET_TYPE_LTE_WCDMA;
+ case RADIO_GEN_4G:
+ return PREF_NET_TYPE_LTE_ONLY;
+ default:
+ /* Other combinations are not yet supported */
+ return PREF_NET_TYPE_GSM_ONLY;
+ }
+#undef RADIO_GEN_2G
+#undef RADIO_GEN_3G
+#undef RADIO_GEN_4G
+}
+
+/**
+ * @param networkTypeBitmap a 32-bit bitmap of RadioAccessFamily
+ */
+static
+gboolean
+ril_binder_radio_decode_pref_network_type_bitmap(
+ GBinderReader* in,
+ GByteArray* out)
+{
+ gint32 raf, pref;
+
+ if (gbinder_reader_read_int32(in, &raf)) {
+ pref = ril_binder_radio_raf_to_pref_mode(raf);
+ grilio_encode_int32(out, 1);
+ grilio_encode_int32(out, pref);
+ return TRUE;
+ }
+ return FALSE;
+}
+
/**
* @param configs Vector of GSM/WCDMA Cell broadcast configs
*/
@@ -1874,6 +2507,55 @@
return FALSE;
}
+static
+void
+ril_binder_radio_decode_signal_strength_common(
+ const RadioSignalStrengthGsm* gsm,
+ const RadioSignalStrengthCdma* cdma,
+ const RadioSignalStrengthEvdo* evdo,
+ const RadioSignalStrengthLte* lte,
+ const RadioSignalStrengthTdScdma* tdScdma,
+ const RadioSignalStrengthWcdma* wcdma,
+ GByteArray* out)
+{
+ /* GW_SignalStrength */
+ if (wcdma && wcdma->signalStrength <= 31 && gsm->signalStrength > 31) {
+ /*
+ * Presumably, 3G signal. The wcdma field did't exist in RIL
+ * socket times.
+ *
+ * Valid signal strength values for both 2G and 3G are (0-31, 99)
+ * as defined in TS 27.007 8.5
+ */
+ grilio_encode_int32(out, wcdma->signalStrength);
+ grilio_encode_int32(out, wcdma->bitErrorRate);
+ } else {
+ grilio_encode_int32(out, gsm->signalStrength);
+ grilio_encode_int32(out, gsm->bitErrorRate);
+ }
+
+ /* CDMA_SignalStrength */
+ grilio_encode_int32(out, cdma->dbm);
+ grilio_encode_int32(out, cdma->ecio);
+
+ /* EVDO_SignalStrength */
+ grilio_encode_int32(out, evdo->dbm);
+ grilio_encode_int32(out, evdo->ecio);
+ grilio_encode_int32(out, evdo->signalNoiseRatio);
+
+ /* LTE_SignalStrength_v8 */
+ grilio_encode_int32(out, lte->signalStrength);
+ grilio_encode_int32(out, lte->rsrp);
+ grilio_encode_int32(out, lte->rsrq);
+ grilio_encode_int32(out, lte->rssnr);
+ grilio_encode_int32(out, lte->cqi);
+ grilio_encode_int32(out, lte->timingAdvance);
+
+ /* TD_SCDMA_SignalStrength */
+ grilio_encode_int32(out, tdScdma->rscp);
+}
+
+
/**
* @param signalStrength SignalStrength information as defined in types.hal
*/
@@ -1887,29 +2569,60 @@
(in, RadioSignalStrength);
if (strength) {
- /* GW_SignalStrength */
- grilio_encode_int32(out, strength->gw.signalStrength);
- grilio_encode_int32(out, strength->gw.bitErrorRate);
-
- /* CDMA_SignalStrength */
- grilio_encode_int32(out, strength->cdma.dbm);
- grilio_encode_int32(out, strength->cdma.ecio);
-
- /* EVDO_SignalStrength */
- grilio_encode_int32(out, strength->evdo.dbm);
- grilio_encode_int32(out, strength->evdo.ecio);
- grilio_encode_int32(out, strength->evdo.signalNoiseRatio);
+ RadioSignalStrengthTdScdma tdscdma;
- /* LTE_SignalStrength_v8 */
- grilio_encode_int32(out, strength->lte.signalStrength);
- grilio_encode_int32(out, strength->lte.rsrp);
- grilio_encode_int32(out, strength->lte.rsrq);
- grilio_encode_int32(out, strength->lte.rssnr);
- grilio_encode_int32(out, strength->lte.cqi);
- grilio_encode_int32(out, strength->lte.timingAdvance);
+ tdscdma.rscp = strength->tdScdma.rscp;
+ ril_binder_radio_decode_signal_strength_common(&strength->gw,
+ &strength->cdma, &strength->evdo, &strength->lte,
+ &tdscdma, NULL, out);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * @param signalStrength SignalStrength information as defined in types.hal
+ */
+static
+gboolean
+ril_binder_radio_decode_signal_strength_1_2(
+ GBinderReader* in,
+ GByteArray* out)
+{
+ const RadioSignalStrength_1_2* strength = gbinder_reader_read_hidl_struct
+ (in, RadioSignalStrength_1_2);
+
+ if (strength) {
+ RadioSignalStrengthTdScdma tdscdma;
- /* TD_SCDMA_SignalStrength */
- grilio_encode_int32(out, strength->tdScdma.rscp);
+ tdscdma.rscp = strength->tdScdma.rscp;
+ ril_binder_radio_decode_signal_strength_common(&strength->gw,
+ &strength->cdma, &strength->evdo, &strength->lte,
+ &tdscdma, &strength->wcdma.base, out);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * @param signalStrength SignalStrength information as defined in types.hal
+ */
+static
+gboolean
+ril_binder_radio_decode_signal_strength_1_4(
+ GBinderReader* in,
+ GByteArray* out)
+{
+ const RadioSignalStrength_1_4* strength = gbinder_reader_read_hidl_struct
+ (in, RadioSignalStrength_1_4);
+
+ if (strength) {
+ RadioSignalStrengthTdScdma tdscdma;
+
+ tdscdma.rscp = strength->tdscdma.rscp;
+ ril_binder_radio_decode_signal_strength_common(&strength->gsm,
+ &strength->cdma, &strength->evdo, &strength->lte,
+ &tdscdma, &strength->wcdma.base, out);
return TRUE;
}
return FALSE;
@@ -1978,32 +2691,42 @@
void
ril_binder_radio_decode_cell_info_gsm(
GByteArray* out,
+ const RadioCellIdentityGsm* id,
+ const RadioSignalStrengthGsm* ss)
+{
+ int mcc, mnc;
+
+ if (!gutil_parse_int(id->mcc.data.str, 10, &mcc)) {
+ mcc = RADIO_CELL_INVALID_VALUE;
+ }
+ if (!gutil_parse_int(id->mnc.data.str, 10, &mnc)) {
+ mnc = RADIO_CELL_INVALID_VALUE;
+ }
+ grilio_encode_int32(out, mcc);
+ grilio_encode_int32(out, mnc);
+ grilio_encode_int32(out, id->lac);
+ grilio_encode_int32(out, id->cid);
+ grilio_encode_int32(out, id->arfcn);
+ grilio_encode_int32(out, id->bsic);
+ grilio_encode_int32(out, ss->signalStrength);
+ grilio_encode_int32(out, ss->bitErrorRate);
+ grilio_encode_int32(out, ss->timingAdvance);
+}
+
+static
+void
+ril_binder_radio_decode_cell_info_gsm_1_0(
+ GByteArray* out,
const RadioCellInfo* cell)
{
const RadioCellInfoGsm* info = cell->gsm.data.ptr;
guint i, count = cell->gsm.count;
for (i = 0; i < count; i++) {
- const RadioCellIdentityGsm* id = &info[i].cellIdentityGsm;
- const RadioSignalStrengthGsm* ss = &info[i].signalStrengthGsm;
- int mcc, mnc;
-
ril_binder_radio_decode_cell_info_header(out, cell);
- if (!gutil_parse_int(id->mcc.data.str, 10, &mcc)) {
- mcc = RADIO_CELL_INVALID_VALUE;
- }
- if (!gutil_parse_int(id->mnc.data.str, 10, &mnc)) {
- mnc = RADIO_CELL_INVALID_VALUE;
- }
- grilio_encode_int32(out, mcc);
- grilio_encode_int32(out, mnc);
- grilio_encode_int32(out, id->lac);
- grilio_encode_int32(out, id->cid);
- grilio_encode_int32(out, id->arfcn);
- grilio_encode_int32(out, id->bsic);
- grilio_encode_int32(out, ss->signalStrength);
- grilio_encode_int32(out, ss->bitErrorRate);
- grilio_encode_int32(out, ss->timingAdvance);
+ ril_binder_radio_decode_cell_info_gsm(out,
+ &info[i].cellIdentityGsm,
+ &info[i].signalStrengthGsm);
}
}
@@ -2011,27 +2734,37 @@
void
ril_binder_radio_decode_cell_info_cdma(
GByteArray* out,
+ const RadioCellIdentityCdma* id,
+ const RadioSignalStrengthCdma* ss,
+ const RadioSignalStrengthEvdo* evdo)
+{
+ grilio_encode_int32(out, id->networkId);
+ grilio_encode_int32(out, id->systemId);
+ grilio_encode_int32(out, id->baseStationId);
+ grilio_encode_int32(out, id->longitude);
+ grilio_encode_int32(out, id->latitude);
+ grilio_encode_int32(out, ss->dbm);
+ grilio_encode_int32(out, ss->ecio);
+ grilio_encode_int32(out, evdo->dbm);
+ grilio_encode_int32(out, evdo->ecio);
+ grilio_encode_int32(out, evdo->signalNoiseRatio);
+}
+
+static
+void
+ril_binder_radio_decode_cell_info_cdma_1_0(
+ GByteArray* out,
const RadioCellInfo* cell)
{
const RadioCellInfoCdma* info = cell->cdma.data.ptr;
guint i, count = cell->cdma.count;
for (i = 0; i < count; i++) {
- const RadioCellIdentityCdma* id = &info[i].cellIdentityCdma;
- const RadioSignalStrengthCdma* ss = &info[i].signalStrengthCdma;
- const RadioSignalStrengthEvdo* evdo = &info[i].signalStrengthEvdo;
-
ril_binder_radio_decode_cell_info_header(out, cell);
- grilio_encode_int32(out, id->networkId);
- grilio_encode_int32(out, id->systemId);
- grilio_encode_int32(out, id->baseStationId);
- grilio_encode_int32(out, id->longitude);
- grilio_encode_int32(out, id->latitude);
- grilio_encode_int32(out, ss->dbm);
- grilio_encode_int32(out, ss->ecio);
- grilio_encode_int32(out, evdo->dbm);
- grilio_encode_int32(out, evdo->ecio);
- grilio_encode_int32(out, evdo->signalNoiseRatio);
+ ril_binder_radio_decode_cell_info_cdma(out,
+ &info[i].cellIdentityCdma,
+ &info[i].signalStrengthCdma,
+ &info[i].signalStrengthEvdo);
}
}
@@ -2039,35 +2772,45 @@
void
ril_binder_radio_decode_cell_info_lte(
GByteArray* out,
+ const RadioCellIdentityLte* id,
+ const RadioSignalStrengthLte* ss)
+{
+ int mcc, mnc;
+
+ if (!gutil_parse_int(id->mcc.data.str, 10, &mcc)) {
+ mcc = RADIO_CELL_INVALID_VALUE;
+ }
+ if (!gutil_parse_int(id->mnc.data.str, 10, &mnc)) {
+ mnc = RADIO_CELL_INVALID_VALUE;
+ }
+ grilio_encode_int32(out, mcc);
+ grilio_encode_int32(out, mnc);
+ grilio_encode_int32(out, id->ci);
+ grilio_encode_int32(out, id->pci);
+ grilio_encode_int32(out, id->tac);
+ grilio_encode_int32(out, id->earfcn);
+ grilio_encode_int32(out, ss->signalStrength);
+ grilio_encode_int32(out, ss->rsrp);
+ grilio_encode_int32(out, ss->rsrq);
+ grilio_encode_int32(out, ss->rssnr);
+ grilio_encode_int32(out, ss->cqi);
+ grilio_encode_int32(out, ss->timingAdvance);
+}
+
+static
+void
+ril_binder_radio_decode_cell_info_lte_1_0(
+ GByteArray* out,
const RadioCellInfo* cell)
{
const RadioCellInfoLte* info = cell->lte.data.ptr;
guint i, count = cell->lte.count;
for (i = 0; i < count; i++) {
- const RadioCellIdentityLte* id = &info[i].cellIdentityLte;
- const RadioSignalStrengthLte* ss = &info[i].signalStrengthLte;
- int mcc, mnc;
-
ril_binder_radio_decode_cell_info_header(out, cell);
- if (!gutil_parse_int(id->mcc.data.str, 10, &mcc)) {
- mcc = RADIO_CELL_INVALID_VALUE;
- }
- if (!gutil_parse_int(id->mnc.data.str, 10, &mnc)) {
- mnc = RADIO_CELL_INVALID_VALUE;
- }
- grilio_encode_int32(out, mcc);
- grilio_encode_int32(out, mnc);
- grilio_encode_int32(out, id->ci);
- grilio_encode_int32(out, id->pci);
- grilio_encode_int32(out, id->tac);
- grilio_encode_int32(out, id->earfcn);
- grilio_encode_int32(out, ss->signalStrength);
- grilio_encode_int32(out, ss->rsrp);
- grilio_encode_int32(out, ss->rsrq);
- grilio_encode_int32(out, ss->rssnr);
- grilio_encode_int32(out, ss->cqi);
- grilio_encode_int32(out, ss->timingAdvance);
+ ril_binder_radio_decode_cell_info_lte(out,
+ &info[i].cellIdentityLte,
+ &info[i].signalStrengthLte);
}
}
@@ -2075,31 +2818,41 @@
void
ril_binder_radio_decode_cell_info_wcdma(
GByteArray* out,
+ const RadioCellIdentityWcdma* id,
+ const RadioSignalStrengthWcdma* ss)
+{
+ int mcc, mnc;
+
+ if (!gutil_parse_int(id->mcc.data.str, 10, &mcc)) {
+ mcc = RADIO_CELL_INVALID_VALUE;
+ }
+ if (!gutil_parse_int(id->mnc.data.str, 10, &mnc)) {
+ mnc = RADIO_CELL_INVALID_VALUE;
+ }
+ grilio_encode_int32(out, mcc);
+ grilio_encode_int32(out, mnc);
+ grilio_encode_int32(out, id->lac);
+ grilio_encode_int32(out, id->cid);
+ grilio_encode_int32(out, id->psc);
+ grilio_encode_int32(out, id->uarfcn);
+ grilio_encode_int32(out, ss->signalStrength);
+ grilio_encode_int32(out, ss->bitErrorRate);
+}
+
+static
+void
+ril_binder_radio_decode_cell_info_wcdma_1_0(
+ GByteArray* out,
const RadioCellInfo* cell)
{
const RadioCellInfoWcdma* info = cell->wcdma.data.ptr;
guint i, count = cell->wcdma.count;
for (i = 0; i < count; i++) {
- const RadioCellIdentityWcdma* id = &info[i].cellIdentityWcdma;
- const RadioSignalStrengthWcdma* ss = &info[i].signalStrengthWcdma;
- int mcc, mnc;
-
ril_binder_radio_decode_cell_info_header(out, cell);
- if (!gutil_parse_int(id->mcc.data.str, 10, &mcc)) {
- mcc = RADIO_CELL_INVALID_VALUE;
- }
- if (!gutil_parse_int(id->mnc.data.str, 10, &mnc)) {
- mnc = RADIO_CELL_INVALID_VALUE;
- }
- grilio_encode_int32(out, mcc);
- grilio_encode_int32(out, mnc);
- grilio_encode_int32(out, id->lac);
- grilio_encode_int32(out, id->cid);
- grilio_encode_int32(out, id->psc);
- grilio_encode_int32(out, id->uarfcn);
- grilio_encode_int32(out, ss->signalStrength);
- grilio_encode_int32(out, ss->bitErrorRate);
+ ril_binder_radio_decode_cell_info_wcdma(out,
+ &info[i].cellIdentityWcdma,
+ &info[i].signalStrengthWcdma);
}
}
@@ -2107,29 +2860,151 @@
void
ril_binder_radio_decode_cell_info_tdscdma(
GByteArray* out,
+ const RadioCellIdentityTdscdma* id,
+ guint32 rscp)
+{
+ int mcc = RADIO_CELL_INVALID_VALUE;
+ int mnc = RADIO_CELL_INVALID_VALUE;
+
+ gutil_parse_int(id->mcc.data.str, 10, &mcc);
+ gutil_parse_int(id->mnc.data.str, 10, &mnc);
+ grilio_encode_int32(out, mcc);
+ grilio_encode_int32(out, mnc);
+ grilio_encode_int32(out, id->lac);
+ grilio_encode_int32(out, id->cid);
+ grilio_encode_int32(out, id->cpid);
+ grilio_encode_int32(out, rscp);
+}
+
+static
+void
+ril_binder_radio_decode_cell_info_tdscdma_1_0(
+ GByteArray* out,
const RadioCellInfo* cell)
{
const RadioCellInfoTdscdma* info = cell->tdscdma.data.ptr;
guint i, count = cell->tdscdma.count;
for (i = 0; i < count; i++) {
- const RadioCellIdentityTdscdma* id = &info[i].cellIdentityTdscdma;
- const RadioSignalStrengthTdScdma* ss = &info[i].signalStrengthTdscdma;
- int mcc, mnc;
-
ril_binder_radio_decode_cell_info_header(out, cell);
- if (!gutil_parse_int(id->mcc.data.str, 10, &mcc)) {
- mcc = RADIO_CELL_INVALID_VALUE;
- }
- if (!gutil_parse_int(id->mnc.data.str, 10, &mnc)) {
- mnc = RADIO_CELL_INVALID_VALUE;
- }
- grilio_encode_int32(out, mcc);
- grilio_encode_int32(out, mnc);
- grilio_encode_int32(out, id->lac);
- grilio_encode_int32(out, id->cid);
- grilio_encode_int32(out, id->cpid);
- grilio_encode_int32(out, ss->rscp);
+ ril_binder_radio_decode_cell_info_tdscdma(out,
+ &info[i].cellIdentityTdscdma,
+ info[i].signalStrengthTdscdma.rscp);
+ }
+}
+
+static
+void
+ril_binder_radio_decode_cell_info_header_1_2(
+ GByteArray* out,
+ const RadioCellInfo_1_2* cell)
+{
+ grilio_encode_int32(out, cell->cellInfoType);
+ grilio_encode_int32(out, cell->registered);
+ grilio_encode_int32(out, cell->timeStampType);
+ /* There should be grilio_encode_int64() call below (there's no
+ * such function in libgrilio) but the timestamp value is ignored
+ * anyway, so who cares... */
+ grilio_encode_bytes(out, &cell->timeStamp, sizeof(cell->timeStamp));
+}
+
+static
+void
+ril_binder_radio_decode_cell_info_header_1_4(
+ GByteArray* out,
+ const RadioCellInfo_1_4* cell,
+ const RADIO_CELL_INFO_TYPE cellInfoType)
+{
+ grilio_encode_int32(out, cellInfoType);
+ grilio_encode_int32(out, cell->registered);
+ grilio_encode_int32(out, 0); /* timeStampType */
+ grilio_encode_int32(out, 0); /* timeStamp */
+ grilio_encode_int32(out, 0); /* timeStamp */
+}
+
+static
+void
+ril_binder_radio_decode_cell_info_gsm_1_2(
+ GByteArray* out,
+ const RadioCellInfo_1_2* cell)
+{
+ const RadioCellInfoGsm_1_2* info = cell->gsm.data.ptr;
+ guint i, count = cell->gsm.count;
+
+ for (i = 0; i < count; i++) {
+ ril_binder_radio_decode_cell_info_header_1_2(out, cell);
+ ril_binder_radio_decode_cell_info_gsm(out,
+ &info[i].cellIdentityGsm.base,
+ &info[i].signalStrengthGsm);
+ }
+}
+
+static
+void
+ril_binder_radio_decode_cell_info_cdma_1_2(
+ GByteArray* out,
+ const RadioCellInfo_1_2* cell)
+{
+ const RadioCellInfoCdma_1_2* info = cell->cdma.data.ptr;
+ guint i, count = cell->cdma.count;
+
+ for (i = 0; i < count; i++) {
+ ril_binder_radio_decode_cell_info_header_1_2(out, cell);
+ ril_binder_radio_decode_cell_info_cdma(out,
+ &info[i].cellIdentityCdma.base,
+ &info[i].signalStrengthCdma,
+ &info[i].signalStrengthEvdo);
+ }
+}
+
+static
+void
+ril_binder_radio_decode_cell_info_lte_1_2(
+ GByteArray* out,
+ const RadioCellInfo_1_2* cell)
+{
+ const RadioCellInfoLte_1_2* info = cell->lte.data.ptr;
+ guint i, count = cell->lte.count;
+
+ for (i = 0; i < count; i++) {
+ ril_binder_radio_decode_cell_info_header_1_2(out, cell);
+ ril_binder_radio_decode_cell_info_lte(out,
+ &info[i].cellIdentityLte.base,
+ &info[i].signalStrengthLte);
+ }
+}
+
+static
+void
+ril_binder_radio_decode_cell_info_wcdma_1_2(
+ GByteArray* out,
+ const RadioCellInfo_1_2* cell)
+{
+ const RadioCellInfoWcdma_1_2* info = cell->wcdma.data.ptr;
+ guint i, count = cell->wcdma.count;
+
+ for (i = 0; i < count; i++) {
+ ril_binder_radio_decode_cell_info_header_1_2(out, cell);
+ ril_binder_radio_decode_cell_info_wcdma(out,
+ &info[i].cellIdentityWcdma.base,
+ &info[i].signalStrengthWcdma.base);
+ }
+}
+
+static
+void
+ril_binder_radio_decode_cell_info_tdscdma_1_2(
+ GByteArray* out,
+ const RadioCellInfo_1_2* cell)
+{
+ const RadioCellInfoTdscdma_1_2* info = cell->tdscdma.data.ptr;
+ guint i, count = cell->tdscdma.count;
+
+ for (i = 0; i < count; i++) {
+ ril_binder_radio_decode_cell_info_header_1_2(out, cell);
+ ril_binder_radio_decode_cell_info_tdscdma(out,
+ &info[i].cellIdentityTdscdma.base,
+ info[i].signalStrengthTdscdma.rscp);
}
}
@@ -2180,19 +3055,171 @@
switch (cell->cellInfoType) {
case RADIO_CELL_INFO_GSM:
- ril_binder_radio_decode_cell_info_gsm(out, cell);
+ ril_binder_radio_decode_cell_info_gsm_1_0(out, cell);
+ break;
+ case RADIO_CELL_INFO_CDMA:
+ ril_binder_radio_decode_cell_info_cdma_1_0(out, cell);
+ break;
+ case RADIO_CELL_INFO_LTE:
+ ril_binder_radio_decode_cell_info_lte_1_0(out, cell);
+ break;
+ case RADIO_CELL_INFO_WCDMA:
+ ril_binder_radio_decode_cell_info_wcdma_1_0(out, cell);
+ break;
+ case RADIO_CELL_INFO_TD_SCDMA:
+ ril_binder_radio_decode_cell_info_tdscdma_1_0(out, cell);
+ break;
+ }
+ }
+ ok = TRUE;
+ }
+ return ok;
+}
+
+/**
+ * @param cellInfo List of current cell information known to radio
+ */
+static
+gboolean
+ril_binder_radio_decode_cell_info_list_1_2(
+ GBinderReader* in,
+ GByteArray* out)
+{
+ gboolean ok = FALSE;
+ gsize count = 0;
+ const RadioCellInfo_1_2* cells = gbinder_reader_read_hidl_type_vec
+ (in, RadioCellInfo_1_2, &count);
+
+ if (cells) {
+ guint i, n = 0;
+
+ /* Count supported types */
+ for (i = 0; i < count; i++) {
+ const RadioCellInfo_1_2* cell = cells + i;
+
+ switch (cells[i].cellInfoType) {
+ case RADIO_CELL_INFO_GSM:
+ n += cell->gsm.count;
+ break;
+ case RADIO_CELL_INFO_CDMA:
+ n += cell->cdma.count;
+ break;
+ case RADIO_CELL_INFO_LTE:
+ n += cell->lte.count;
+ break;
+ case RADIO_CELL_INFO_WCDMA:
+ n += cell->wcdma.count;
+ break;
+ case RADIO_CELL_INFO_TD_SCDMA:
+ n += cell->tdscdma.count;
+ break;
+ }
+ }
+
+ grilio_encode_int32(out, n);
+
+ for (i = 0; i < count; i++) {
+ const RadioCellInfo_1_2* cell = cells + i;
+
+ switch (cell->cellInfoType) {
+ case RADIO_CELL_INFO_GSM:
+ ril_binder_radio_decode_cell_info_gsm_1_2(out, cell);
break;
case RADIO_CELL_INFO_CDMA:
- ril_binder_radio_decode_cell_info_cdma(out, cell);
+ ril_binder_radio_decode_cell_info_cdma_1_2(out, cell);
break;
case RADIO_CELL_INFO_LTE:
- ril_binder_radio_decode_cell_info_lte(out, cell);
+ ril_binder_radio_decode_cell_info_lte_1_2(out, cell);
break;
case RADIO_CELL_INFO_WCDMA:
- ril_binder_radio_decode_cell_info_wcdma(out, cell);
+ ril_binder_radio_decode_cell_info_wcdma_1_2(out, cell);
break;
case RADIO_CELL_INFO_TD_SCDMA:
- ril_binder_radio_decode_cell_info_tdscdma(out, cell);
+ ril_binder_radio_decode_cell_info_tdscdma_1_2(out, cell);
+ break;
+ }
+ }
+ ok = TRUE;
+ }
+ return ok;
+}
+
+/**
+ * @param cellInfo List of current cell information known to radio
+ */
+static
+gboolean
+ril_binder_radio_decode_cell_info_list_1_4(
+ GBinderReader* in,
+ GByteArray* out)
+{
+ gboolean ok = FALSE;
+ gsize count = 0;
+ const RadioCellInfo_1_4* cells = gbinder_reader_read_hidl_type_vec
+ (in, RadioCellInfo_1_4, &count);
+
+ if (cells) {
+ guint i, n = 0;
+
+ /* Count supported types */
+ for (i = 0; i < count; i++) {
+ switch (cells[i].cellInfoType) {
+ case RADIO_CELL_INFO_1_4_GSM:
+ case RADIO_CELL_INFO_1_4_CDMA:
+ case RADIO_CELL_INFO_1_4_WCDMA:
+ case RADIO_CELL_INFO_1_4_LTE:
+ case RADIO_CELL_INFO_1_4_TD_SCDMA:
+ n++;
+ break;
+ /* Do not count 5G cells for now */
+ case RADIO_CELL_INFO_1_4_NR:
+ break;
+ }
+ }
+
+ grilio_encode_int32(out, n);
+
+ for (i = 0; i < count; i++) {
+ const RadioCellInfo_1_4* cell = cells + i;
+
+ switch (cell->cellInfoType) {
+ case RADIO_CELL_INFO_1_4_GSM:
+ ril_binder_radio_decode_cell_info_header_1_4(out,
+ cell, RADIO_CELL_INFO_GSM);
+ ril_binder_radio_decode_cell_info_gsm(out,
+ &cell->info.gsm.cellIdentityGsm.base,
+ &cell->info.gsm.signalStrengthGsm);
+ break;
+ case RADIO_CELL_INFO_1_4_CDMA:
+ ril_binder_radio_decode_cell_info_header_1_4(out,
+ cell, RADIO_CELL_INFO_CDMA);
+ ril_binder_radio_decode_cell_info_cdma(out,
+ &cell->info.cdma.cellIdentityCdma.base,
+ &cell->info.cdma.signalStrengthCdma,
+ &cell->info.cdma.signalStrengthEvdo);
+ break;
+ case RADIO_CELL_INFO_1_4_LTE:
+ ril_binder_radio_decode_cell_info_header_1_4(out,
+ cell, RADIO_CELL_INFO_LTE);
+ ril_binder_radio_decode_cell_info_lte(out,
+ &cell->info.lte.base.cellIdentityLte.base,
+ &cell->info.lte.base.signalStrengthLte);
+ break;
+ case RADIO_CELL_INFO_1_4_WCDMA:
+ ril_binder_radio_decode_cell_info_header_1_4(out,
+ cell, RADIO_CELL_INFO_WCDMA);
+ ril_binder_radio_decode_cell_info_wcdma(out,
+ &cell->info.wcdma.cellIdentityWcdma.base,
+ &cell->info.wcdma.signalStrengthWcdma.base);
+ break;
+ case RADIO_CELL_INFO_1_4_TD_SCDMA:
+ ril_binder_radio_decode_cell_info_header_1_4(out,
+ cell, RADIO_CELL_INFO_TD_SCDMA);
+ ril_binder_radio_decode_cell_info_tdscdma(out,
+ &cell->info.tdscdma.cellIdentityTdscdma.base,
+ cell->info.tdscdma.signalStrengthTdscdma.rscp);
+ break;
+ case RADIO_CELL_INFO_1_4_NR:
break;
}
}
@@ -2224,6 +3251,23 @@
return FALSE;
}
+static
+gboolean
+ril_binder_radio_decode_icc_open_logical_channel(
+ GBinderReader* in,
+ GByteArray* out)
+{
+ guint32 channel;
+
+ if (gbinder_reader_read_uint32(in, &channel)) {
+ grilio_encode_int32(out, 1); /* Number of ints to follow */
+ grilio_encode_int32(out, channel);
+ /* Ignore the select response, ofono doesn't need it */
+ return TRUE;
+ }
+ return FALSE;
+}
+
/**
* @param rc Radio capability as defined by RadioCapability
*/
@@ -2252,13 +3296,13 @@
* Calls
*==========================================================================*/
-static const RilBinderRadioCall ril_binder_radio_calls[] = {
+static const RilBinderRadioCall ril_binder_radio_calls_1_0[] = {
{
RIL_REQUEST_GET_SIM_STATUS,
RADIO_REQ_GET_ICC_CARD_STATUS,
RADIO_RESP_GET_ICC_CARD_STATUS,
ril_binder_radio_encode_serial,
- ril_binder_radio_decode_icc_card_status,
+ ril_binder_radio_decode_icc_card_status_1_0,
"getIccCardStatus"
},{
RIL_REQUEST_ENTER_SIM_PIN,
@@ -2447,7 +3491,7 @@
RADIO_REQ_ICC_IO_FOR_APP,
RADIO_RESP_ICC_IO_FOR_APP,
ril_binder_radio_encode_icc_io,
- ril_binder_radio_decode_icc_result,
+ ril_binder_radio_decode_icc_io_result,
"iccIOForApp"
},{
RIL_REQUEST_SEND_USSD,
@@ -2778,6 +3822,27 @@
ril_binder_radio_decode_ims_registration_state,
"getImsRegistrationState"
},{
+ RIL_REQUEST_SIM_OPEN_CHANNEL,
+ RADIO_REQ_ICC_OPEN_LOGICAL_CHANNEL,
+ RADIO_RESP_ICC_OPEN_LOGICAL_CHANNEL,
+ ril_binder_radio_encode_icc_open_logical_channel,
+ ril_binder_radio_decode_icc_open_logical_channel,
+ "iccOpenLogicalChannel"
+ },{
+ RIL_REQUEST_SIM_CLOSE_CHANNEL,
+ RADIO_REQ_ICC_CLOSE_LOGICAL_CHANNEL,
+ RADIO_RESP_ICC_CLOSE_LOGICAL_CHANNEL,
+ ril_binder_radio_encode_ints,
+ NULL,
+ "iccCloseLogicalChannel"
+ },{
+ RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL,
+ RADIO_REQ_ICC_TRANSMIT_APDU_LOGICAL_CHANNEL,
+ RADIO_RESP_ICC_TRANSMIT_APDU_LOGICAL_CHANNEL,
+ ril_binder_radio_encode_icc_transmit_apdu_logical_channel,
+ ril_binder_radio_decode_icc_io_result,
+ "iccTransmitApduLogicalChannel"
+ },{
RIL_REQUEST_SET_UICC_SUBSCRIPTION,
RADIO_REQ_SET_UICC_SUBSCRIPTION,
RADIO_RESP_SET_UICC_SUBSCRIPTION,
@@ -2836,11 +3901,131 @@
}
};
+static const RilBinderRadioCall ril_binder_radio_calls_1_2[] = {
+ {
+ 0,
+ 0,
+ RADIO_RESP_GET_ICC_CARD_STATUS_1_2,
+ NULL,
+ ril_binder_radio_decode_icc_card_status_1_2,
+ "getIccCardStatus_1_2"
+ },{
+ RIL_REQUEST_SETUP_DATA_CALL,
+ RADIO_REQ_SETUP_DATA_CALL_1_2,
+ 0,
+ ril_binder_radio_encode_setup_data_call_1_2,
+ ril_binder_radio_decode_setup_data_call_result,
+ "setupDataCall_1_2"
+ },{
+ RIL_REQUEST_DEACTIVATE_DATA_CALL,
+ RADIO_REQ_DEACTIVATE_DATA_CALL_1_2,
+ 0,
+ ril_binder_radio_encode_deactivate_data_call_1_2,
+ NULL,
+ "deactivateDataCall_1_2"
+ },{
+ 0,
+ 0,
+ RADIO_RESP_GET_VOICE_REGISTRATION_STATE_1_2,
+ NULL,
+ ril_binder_radio_decode_voice_reg_state,
+ "getVoiceRegistrationState_1_2"
+ },{
+ 0,
+ 0,
+ RADIO_RESP_GET_DATA_REGISTRATION_STATE_1_2,
+ NULL,
+ ril_binder_radio_decode_data_reg_state,
+ "getDataRegistrationState_1_2"
+ },{
+ 0,
+ 0,
+ RADIO_RESP_GET_CURRENT_CALLS_1_2,
+ NULL,
+ ril_binder_radio_decode_call_list_1_2,
+ "getCurrentCalls_1_2"
+ },{
+ 0,
+ 0,
+ RADIO_RESP_GET_CELL_INFO_LIST_1_2,
+ NULL,
+ ril_binder_radio_decode_cell_info_list_1_2,
+ "getCellInfoList_1_2"
+ },{
+ 0,
+ 0,
+ RADIO_RESP_GET_SIGNAL_STRENGTH_1_2,
+ NULL,
+ ril_binder_radio_decode_signal_strength_1_2,
+ "getSignalStrength_1_2"
+ }
+};
+
+static const RilBinderRadioCall ril_binder_radio_calls_1_4[] = {
+ {
+ 0,
+ 0,
+ RADIO_RESP_GET_ICC_CARD_STATUS_RESPONSE_1_4,
+ NULL,
+ ril_binder_radio_decode_icc_card_status_1_4,
+ "getIccCardStatus_1_4"
+ },{
+ RIL_REQUEST_SETUP_DATA_CALL,
+ RADIO_REQ_SETUP_DATA_CALL_1_2, /* Using setupDataCall_1_2 */
+ RADIO_RESP_SETUP_DATA_CALL_RESPONSE_1_4,
+ ril_binder_radio_encode_setup_data_call_1_2,
+ ril_binder_radio_decode_setup_data_call_result_1_4,
+ "setupDataCall_1_4"
+ },{
+ 0,
+ 0,
+ RADIO_RESP_GET_DATA_REGISTRATION_STATE_RESPONSE_1_4,
+ NULL,
+ ril_binder_radio_decode_data_reg_state_1_4,
+ "getDataRegistrationState_1_4"
+ },{
+ 0,
+ 0,
+ RADIO_RESP_GET_DATA_CALL_LIST_RESPONSE_1_4,
+ NULL,
+ ril_binder_radio_decode_call_list_1_2,
+ "getDataCallList_1_4"
+ },{
+ 0,
+ 0,
+ RADIO_RESP_GET_CELL_INFO_LIST_RESPONSE_1_4,
+ NULL,
+ ril_binder_radio_decode_cell_info_list_1_4,
+ "getCellInfoList_1_4"
+ },{
+ 0,
+ 0,
+ RADIO_RESP_GET_SIGNAL_STRENGTH_1_4,
+ NULL,
+ ril_binder_radio_decode_signal_strength_1_4,
+ "getSignalStrength_1_4"
+ },{
+ RADIO_REQ_SET_PREFERRED_NETWORK_TYPE,
+ 0,
+ RADIO_RESP_SET_PREFERRED_NETWORK_TYPE_BITMAP,
+ ril_binder_radio_encode_ints,
+ NULL,
+ "setPreferredNetworkTypeBitmap_1_4"
+ },{
+ 0,
+ 0,
+ RADIO_RESP_GET_PREFERRED_NETWORK_TYPE_BITMAP,
+ NULL,
+ ril_binder_radio_decode_pref_network_type_bitmap,
+ "getPreferredNetworkTypeBitmap_1_4"
+ }
+};
+
/*==========================================================================*
* Events
*==========================================================================*/
-static const RilBinderRadioEvent ril_binder_radio_events[] = {
+static const RilBinderRadioEvent ril_binder_radio_events_1_0[] = {
{
RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
RADIO_IND_RADIO_STATE_CHANGED,
@@ -2954,6 +4139,39 @@
}
};
+static const RilBinderRadioEvent ril_binder_radio_events_1_2[] = {
+ {
+ RIL_UNSOL_CELL_INFO_LIST,
+ RADIO_IND_CELL_INFO_LIST_1_2,
+ ril_binder_radio_decode_cell_info_list_1_2,
+ "cellInfoList_1_2"
+ },{
+ RIL_UNSOL_SIGNAL_STRENGTH,
+ RADIO_IND_CURRENT_SIGNAL_STRENGTH_1_2,
+ ril_binder_radio_decode_signal_strength_1_2,
+ "currentSignalStrength_1_2"
+ }
+};
+
+static const RilBinderRadioEvent ril_binder_radio_events_1_4[] = {
+ {
+ RIL_UNSOL_CELL_INFO_LIST,
+ RADIO_IND_CELL_INFO_LIST_1_4,
+ ril_binder_radio_decode_cell_info_list_1_4,
+ "cellInfoList_1_4"
+ },{
+ RIL_UNSOL_DATA_CALL_LIST_CHANGED,
+ RADIO_IND_DATA_CALL_LIST_CHANGED_1_4,
+ ril_binder_radio_decode_data_call_list_1_4,
+ "dataCallListChanged_1_4"
+ },{
+ RIL_UNSOL_SIGNAL_STRENGTH,
+ RADIO_IND_CURRENT_SIGNAL_STRENGTH_1_4,
+ ril_binder_radio_decode_signal_strength_1_4,
+ "currentSignalStrength_1_4"
+ }
+};
+
/*==========================================================================*
* Generic failure
*==========================================================================*/
@@ -3068,6 +4286,7 @@
DBG_(self, "connected");
GASSERT(!transport->connected);
+ transport->ril_version = self->radio->version;
transport->connected = TRUE;
grilio_transport_signal_connected(transport);
}
@@ -3188,8 +4407,16 @@
const GBinderReader* args)
{
RilBinderRadioPriv* priv = self->priv;
- const RilBinderRadioCall* call = g_hash_table_lookup(priv->resp_map,
- GINT_TO_POINTER(code));
+ int i = MIN(self->radio->version, RADIO_INTERFACE_COUNT - 1);
+ const RilBinderRadioCall* call = NULL;
+
+ while (i >= 0 && !call) {
+ GHashTable* map = priv->resp_map[i--];
+
+ if (map) {
+ call = g_hash_table_lookup(map, GINT_TO_POINTER(code));
+ }
+ }
if (call) {
GBinderReader copy;
@@ -3213,16 +4440,23 @@
RADIO_IND_TYPE type,
const GBinderReader* args)
{
- RilBinderRadioPriv* priv = self->priv;
-
/* CONNECTED indication is slightly special */
if (code == RADIO_IND_RIL_CONNECTED) {
DBG_(self, "IRadioIndication %u rilConnected", code);
ril_binder_radio_connected(self);
return TRUE;
} else {
- const RilBinderRadioEvent* event = g_hash_table_lookup(priv->unsol_map,
- GINT_TO_POINTER(code));
+ RilBinderRadioPriv* priv = self->priv;
+ int i = MIN(self->radio->version, RADIO_INTERFACE_COUNT - 1);
+ const RilBinderRadioEvent* event = NULL;
+
+ while (i >= 0 && !event) {
+ GHashTable* map = priv->unsol_map[i--];
+
+ if (map) {
+ event = g_hash_table_lookup(map, GINT_TO_POINTER(code));
+ }
+ }
if (event) {
GBinderReader reader;
@@ -3254,8 +4488,16 @@
{
RilBinderRadio* self = RIL_BINDER_RADIO(transport);
RilBinderRadioPriv* priv = self->priv;
- const RilBinderRadioCall* call = g_hash_table_lookup(priv->req_map,
- GINT_TO_POINTER(code));
+ int i = MIN(self->radio->version, RADIO_INTERFACE_COUNT - 1);
+ const RilBinderRadioCall* call = NULL;
+
+ while (i >= 0 && !call) {
+ GHashTable* map = priv->req_map[i--];
+
+ if (map) {
+ call = g_hash_table_lookup(map, GINT_TO_POINTER(code));
+ }
+ }
if (call) {
/* This is a known request */
@@ -3474,21 +4716,62 @@
RIL_BINDER_DEFAULT_NAME);
}
+static
+RADIO_INTERFACE
+ril_binder_radio_arg_interface(
+ GHashTable* args)
+{
+ const char *name = ril_binder_radio_arg_value(args,
+ RIL_BINDER_KEY_INTERFACE, NULL);
+
+ if (name) {
+ RADIO_INTERFACE i;
+
+ for (i = RADIO_INTERFACE_1_0; i < RADIO_INTERFACE_COUNT; i++ ) {
+ if (!g_strcmp0(name, ril_binder_radio_interface_name(i))) {
+ return i;
+ }
+ }
+ }
+ return DEFAULT_INTERFACE;
+}
+
gboolean
ril_binder_radio_init_base(
RilBinderRadio* self,
GHashTable* args)
{
- RilBinderRadioPriv* priv = self->priv;
const char* dev = ril_binder_radio_arg_dev(args);
const char* name = ril_binder_radio_arg_name(args);
+ const RADIO_INTERFACE interface = ril_binder_radio_arg_interface(args);
- GDEBUG("%s %s %s %s", self->parent.log_prefix,
- ril_binder_radio_arg_modem(args), dev, name);
- self->radio = radio_instance_new(dev, name);
+ GDEBUG("%s %s %s %s %s", self->parent.log_prefix,
+ ril_binder_radio_arg_modem(args), dev, name,
+ ril_binder_radio_interface_name(interface));
+ self->radio = radio_instance_new_with_version(dev, name, interface);
if (self->radio) {
+ RilBinderRadioPriv* priv = self->priv;
GBinderServiceManager* sm = gbinder_servicemanager_new(dev);
+ /* android.hardware.radio@1.0 */
+ ril_binder_radio_init_version(priv, RADIO_INTERFACE_1_0,
+ ARRAY_AND_COUNT(ril_binder_radio_calls_1_0),
+ ARRAY_AND_COUNT(ril_binder_radio_events_1_0));
+
+ if (self->radio->version >= RADIO_INTERFACE_1_2) {
+ /* android.hardware.radio@1.2 */
+ ril_binder_radio_init_version(priv, RADIO_INTERFACE_1_2,
+ ARRAY_AND_COUNT(ril_binder_radio_calls_1_2),
+ ARRAY_AND_COUNT(ril_binder_radio_events_1_2));
+ }
+
+ if (self->radio->version >= RADIO_INTERFACE_1_4) {
+ /* android.hardware.radio@1.4 */
+ ril_binder_radio_init_version(priv, RADIO_INTERFACE_1_4,
+ ARRAY_AND_COUNT(ril_binder_radio_calls_1_4),
+ ARRAY_AND_COUNT(ril_binder_radio_events_1_4));
+ }
+
priv->oemhook = ril_binder_oemhook_new(sm, self->radio);
if (priv->oemhook) {
priv->oemhook_raw_response_id =
@@ -3523,33 +4806,12 @@
ril_binder_radio_init(
RilBinderRadio* self)
{
- guint i;
RilBinderRadioPriv* priv = G_TYPE_INSTANCE_GET_PRIVATE
(self, RIL_TYPE_BINDER_RADIO, RilBinderRadioPriv);
self->priv = priv;
priv->idle = gutil_idle_queue_new();
- priv->req_map = g_hash_table_new(g_direct_hash, g_direct_equal);
- priv->resp_map = g_hash_table_new(g_direct_hash, g_direct_equal);
- priv->unsol_map = g_hash_table_new(g_direct_hash, g_direct_equal);
-
- for (i = 0; i < G_N_ELEMENTS(ril_binder_radio_calls); i++) {
- const RilBinderRadioCall* call = ril_binder_radio_calls + i;
-
- g_hash_table_insert(priv->req_map, GINT_TO_POINTER(call->code),
- (gpointer)call);
- if (call->resp_tx) {
- g_hash_table_insert(priv->resp_map, GINT_TO_POINTER(call->resp_tx),
- (gpointer)call);
- }
- }
-
- for (i = 0; i < G_N_ELEMENTS(ril_binder_radio_events); i++) {
- const RilBinderRadioEvent* event = ril_binder_radio_events + i;
-
- g_hash_table_insert(priv->unsol_map, GINT_TO_POINTER(event->unsol_tx),
- (gpointer)event);
- }
+ priv->buf = g_byte_array_new();
}
static
@@ -3559,16 +4821,23 @@
{
RilBinderRadio* self = RIL_BINDER_RADIO(object);
RilBinderRadioPriv* priv = self->priv;
+ int i;
ril_binder_radio_drop_radio(self);
gutil_idle_queue_cancel_all(priv->idle);
gutil_idle_queue_unref(priv->idle);
- g_hash_table_destroy(priv->req_map);
- g_hash_table_destroy(priv->resp_map);
- g_hash_table_destroy(priv->unsol_map);
- if (priv->buf) {
- g_byte_array_unref(priv->buf);
+ for (i = 0; i < RADIO_INTERFACE_COUNT; i++) {
+ if (priv->req_map[i]) {
+ g_hash_table_destroy(priv->req_map[i]);
+ }
+ if (priv->resp_map[i]) {
+ g_hash_table_destroy(priv->resp_map[i]);
+ }
+ if (priv->unsol_map[i]) {
+ g_hash_table_destroy(priv->unsol_map[i]);
+ }
}
+ g_byte_array_unref(priv->buf);
G_OBJECT_CLASS(PARENT_CLASS)->finalize(object);
}
|