From: Jessica Nilsson <jessica.j.nilsson(a)stericsson.com>
---
drivers/isimodem/call-settings.c | 697 +++++++++++++++++++++++++++++++++++++-
drivers/isimodem/call.h | 9 +
drivers/isimodem/debug.c | 4 +
drivers/isimodem/ss.h | 22 ++
4 files changed, 714 insertions(+), 18 deletions(-)
diff --git a/drivers/isimodem/call-settings.c b/drivers/isimodem/call-settings.c
index 89270e9..7a6bedf 100644
--- a/drivers/isimodem/call-settings.c
+++ b/drivers/isimodem/call-settings.c
@@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) ST-Ericsson SA 2011.
*
* 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
@@ -43,10 +44,15 @@
#include "ss.h"
#include "debug.h"
+#define CLIP_ETC
+
struct settings_data {
GIsiClient *client;
};
+#define content_size 40
+static char content[content_size] = {0};
+
static void update_status_mask(unsigned int *mask, int bsc)
{
switch (bsc) {
@@ -88,7 +94,6 @@ static void update_status_mask(unsigned int *mask, int bsc)
break;
}
}
-
static gboolean check_response_status(const GIsiMessage *msg, uint8_t msgid)
{
if (g_isi_msg_error(msg) < 0) {
@@ -104,6 +109,59 @@ static gboolean check_response_status(const GIsiMessage *msg, uint8_t
msgid)
return TRUE;
}
+static void clip_query_cb(const GIsiMessage *msg, void *data)
+{
+ GIsiSubBlockIter iter;
+ struct isi_cb_data *cbd = data;
+
+ ofono_call_settings_status_cb_t cb = cbd->cb;
+ uint8_t service;
+ guint32 mask = 0;
+
+ if (!check_response_status(msg, SS_SERVICE_COMPLETED_RESP))
+ goto error;
+
+ if (!g_isi_msg_data_get_byte(msg, 0, &service) ||
+ service != SS_INTERROGATION)
+ goto error;
+
+ for (g_isi_sb_iter_init(&iter, msg, 6);
+ g_isi_sb_iter_is_valid(&iter);
+ g_isi_sb_iter_next(&iter)) {
+ DBG("Sub-block %s",
+ ss_subblock_name(g_isi_sb_iter_get_id(&iter)));
+
+ switch (g_isi_sb_iter_get_id(&iter)) {
+ case SS_STATUS_RESULT: {
+ guint8 ss_status;
+
+ if (!g_isi_sb_iter_get_byte(&iter, &ss_status, 2))
+ goto error;
+
+ DBG("SS_STATUS_RESULT=%d", ss_status);
+
+ if (ss_status & SS_GSM_PROVISIONED)
+ mask = 1;
+ }
+ break;
+ case SS_GSM_ADDITIONAL_INFO:
+ break;
+ default:
+ DBG("Skipping sub-block: %s (%zd bytes)",
+ ss_subblock_name(g_isi_sb_iter_get_id(&iter)),
+ g_isi_sb_iter_get_len(&iter));
+ break;
+ }
+ }
+
+ DBG("status_mask %d\n", mask);
+ CALLBACK_WITH_SUCCESS(cb, mask, cbd->data);
+ return;
+error:
+ CALLBACK_WITH_FAILURE(cb, 0, cbd->data);
+}
+
+
static gboolean decode_gsm_bsc_info(GIsiSubBlockIter *iter, uint32_t *mask)
{
uint8_t num;
@@ -136,23 +194,611 @@ static void query_resp_cb(const GIsiMessage *msg, void *data)
goto error;
for (g_isi_sb_iter_init(&iter, msg, 6);
+ g_isi_sb_iter_is_valid(&iter);
+ g_isi_sb_iter_next(&iter)) {
+
+ if (g_isi_sb_iter_get_id(&iter) == SS_GSM_BSC_INFO) {
+ if (!decode_gsm_bsc_info(&iter, &mask))
+ goto error;
+
+ CALLBACK_WITH_SUCCESS(cb, mask, cbd->data);
+ return;
+ } else if (g_isi_sb_iter_get_id(&iter) == SS_STATUS_RESULT) {
+ guint8 ss_status;
+
+ if (!g_isi_sb_iter_get_byte(&iter, &ss_status, 2))
+ goto error;
+
+ if (ss_status & SS_GSM_PROVISIONED)
+ mask = 1;
+ CALLBACK_WITH_SUCCESS(cb, mask, cbd->data);
+ return;
+ }
+ }
+
+error:
+ CALLBACK_WITH_FAILURE(cb, 0, cbd->data);
+}
+
+static void isi_clip_query(struct ofono_call_settings *cs,
+ ofono_call_settings_status_cb_t cb, void *data)
+{
+ struct settings_data *sd = ofono_call_settings_get_data(cs);
+ struct isi_cb_data *cbd = isi_cb_data_new(cs, cb, data);
+ unsigned char msg[] = {
+ SS_SERVICE_REQ,
+ SS_INTERROGATION,
+ SS_ALL_TELE_AND_BEARER,
+ SS_GSM_CLIP >> 8, /* Supplementary services */
+ SS_GSM_CLIP & 0xFF, /* code */
+ SS_SEND_ADDITIONAL_INFO,
+ 0 /* Subblock count */
+ };
+ DBG("");
+
+ if (cbd == NULL)
+ goto error;
+
+ if (g_isi_client_send(sd->client, msg, sizeof(msg),
+ clip_query_cb, cbd, g_free))
+ return;
+
+error:
+ CALLBACK_WITH_FAILURE(cb, 0, data);
+ g_free(cbd);
+}
+
+static int set_clir_status(const char *value)
+{
+ DBG("Setting CLIR status to %s", value);
+ strncpy(content, value, content_size);
+ content[content_size-1] = 0;
+ return EXIT_SUCCESS;
+}
+
+static int get_clir_status(void)
+{
+ DBG("Getting CLIR status %s", content);
+
+ if (!strcmp(content, "OFONO_CLIR_OPTION_INVOCATION"))
+ return OFONO_CLIR_OPTION_INVOCATION;
+
+ if (!strcmp(content, "OFONO_CLIR_OPTION_SUPPRESSION"))
+ return OFONO_CLIR_OPTION_SUPPRESSION;
+
+ return OFONO_CLIR_OPTION_DEFAULT;
+}
+
+static void clir_set_cb(const GIsiMessage *msg, void *data)
+{
+ GIsiSubBlockIter iter, iter_info;
+ struct isi_cb_data *cbd = data;
+ ofono_call_settings_set_cb_t cb = cbd->cb;
+ gint override = OFONO_CLIR_OPTION_DEFAULT;
+ gint network = CLIR_STATUS_UNKNOWN;
+ uint8_t service;
+
+ if (!check_response_status(msg, SS_SERVICE_COMPLETED_RESP))
+ goto error;
+
+ if (!g_isi_msg_data_get_byte(msg, 0, &service) ||
+ service != SS_INTERROGATION)
+ goto error;
+
+ for (g_isi_sb_iter_init(&iter, msg, 6);
g_isi_sb_iter_is_valid(&iter);
g_isi_sb_iter_next(&iter)) {
+ DBG("Sub-block %s",
+ ss_subblock_name(g_isi_sb_iter_get_id(&iter)));
- if (g_isi_sb_iter_get_id(&iter) != SS_GSM_BSC_INFO)
- continue;
+ switch (g_isi_sb_iter_get_id(&iter)) {
+ case SS_STATUS_RESULT: {
+ guint8 ss_status;
+
+ if (!g_isi_sb_iter_get_byte(&iter, &ss_status, 2))
+ goto error;
+
+ DBG("SS_STATUS_RESULT=%d", ss_status);
+
+ if (!(ss_status & SS_GSM_PROVISIONED))
+ network = CLIR_STATUS_NOT_PROVISIONED;
+ }
+ break;
+ case SS_GSM_ADDITIONAL_INFO:
+ break;
+ case SS_GSM_GENERIC_SERVICE_INFO: {
+ guint8 ss_status = 0;
+ guint8 clir_option = 0;
+ void *info = NULL;
+ GIsiMessage info_msg;
+
+ if (!g_isi_sb_iter_get_byte(&iter, &ss_status, 2))
+ goto error;
+
+ if (!(ss_status & SS_GSM_PROVISIONED))
+ network = CLIR_STATUS_NOT_PROVISIONED;
+
+ if (!g_isi_sb_iter_get_data(&iter, &info, 4))
+ goto error;
+
+ info_msg.addr = NULL;
+ info_msg.error = 0;
+ /*
+ * GIsiMessage function adds 2 to data pointer and
+ * removes 2 from len
+ */
+ info_msg.data = info - 2;
+ info_msg.len = msg->len - 6 + 2;
+
+ for (g_isi_sb_iter_init(&iter_info, &info_msg, 0);
+ g_isi_sb_iter_is_valid(&iter_info);
+ g_isi_sb_iter_next(&iter_info)) {
+ DBG("Sub-block %s",
+ ss_subblock_name(
+ g_isi_sb_iter_get_id(&iter_info)));
+
+ switch (g_isi_sb_iter_get_id(&iter_info)) {
+ case SS_GSM_CLIR_INFO: {
+ if (!g_isi_sb_iter_get_byte(&iter_info,
+ &clir_option, 2))
+ goto error;
+ }
+ break;
+ }
+
+ DBG("SS_STATUS_RESULT=%d, CLIR_OPTION=%d",
+ ss_status, clir_option);
+ }
+
+ if (network != CLIR_STATUS_NOT_PROVISIONED) {
+ int result;
+ DBG("CLIR set successfully.");
+ result = set_clir_status(
+ "OFONO_CLIR_OPTION_INVOCATION");
+
+ if (result == EXIT_FAILURE)
+ goto error;
+ } else {
+ DBG("CLIR option not supported by network "
+ "provider.");
+ }
+ }
+ break;
+ default:
+ DBG("Skipping sub-block: %s (%zd bytes)",
+ ss_subblock_name(g_isi_sb_iter_get_id(&iter)),
+ g_isi_sb_iter_get_len(&iter));
+ break;
+ }
+ }
- if (!decode_gsm_bsc_info(&iter, &mask))
+ DBG("override=%d, network=%d\n", override, network);
+ CALLBACK_WITH_SUCCESS(cb, cbd->data);
+ return;
+error:
+ CALLBACK_WITH_FAILURE(cb, cbd->data);
+}
+
+static void isi_clir_set(struct ofono_call_settings *cs,
+ int mode,
+ ofono_call_settings_set_cb_t cb,
+ void *data)
+{
+ struct settings_data *sd = ofono_call_settings_get_data(cs);
+ struct isi_cb_data *cbd = isi_cb_data_new(cs, cb, data);
+ int result = 0;
+ /*
+ * CLIR cannot be activated in Network, but we can override it
+ * using local settings - 3GPP TS 24.081 Chapter 2.5
+ */
+
+ switch (mode) {
+ case(OFONO_CLIR_OPTION_DEFAULT):
+ result = set_clir_status("OFONO_CLIR_OPTION_DEFAULT");
+ break;
+ /* CLIR enabled (number not shown) */
+ case(OFONO_CLIR_OPTION_INVOCATION): {
+ /*
+ * We send interrogation request to check if Network
+ * has CLIR option provisioned.
+ */
+ unsigned char msg[] = {
+ SS_SERVICE_REQ,
+ SS_INTERROGATION,
+ SS_ALL_TELE_AND_BEARER,
+ SS_GSM_CLIR >> 8, /* Supplementary services */
+ SS_GSM_CLIR & 0xFF, /* code */
+ SS_SEND_ADDITIONAL_INFO,
+ 0 /* Subblock count */
+ };
+
+ DBG("Attempting to set the CLIR - checking Network Settings");
+
+ if (cbd == NULL)
+ goto error;
+
+ if (g_isi_client_send(sd->client, msg, sizeof(msg),
+ clir_set_cb, cbd, g_free))
+
+ return;
+ else
goto error;
+ }
+ break;
+ case(OFONO_CLIR_OPTION_SUPPRESSION): /* CLIR disabled (number shown) */
+ result = set_clir_status("OFONO_CLIR_OPTION_SUPPRESSION");
+ break;
+ default:
+ DBG("CLIR mode not supported %d", mode);
+ break;
+ }
+
+ if (result == EXIT_FAILURE)
+ goto error;
+
+ DBG("CLIR set to mode: %d", mode);
+ CALLBACK_WITH_SUCCESS(cb, data);
+ goto out;
+error:
+ CALLBACK_WITH_FAILURE(cb, data);
+out:
+ g_free(cbd);
+ return;
+}
+
+static void clir_query_cb(const GIsiMessage *msg, void *data)
+{
+ GIsiSubBlockIter iter, iter_info;
+ struct isi_cb_data *cbd = data;
+ ofono_call_settings_clir_cb_t cb = cbd->cb;
+ uint8_t service;
+ gint override = OFONO_CLIR_OPTION_DEFAULT;
+ gint network = CLIR_STATUS_UNKNOWN;
+
+
+ if (!check_response_status(msg, SS_SERVICE_COMPLETED_RESP))
+ goto error;
+
+ if (!g_isi_msg_data_get_byte(msg, 0, &service) ||
+ service != SS_INTERROGATION)
+ goto error;
+
+ for (g_isi_sb_iter_init(&iter, msg, 6);
+ g_isi_sb_iter_is_valid(&iter);
+ g_isi_sb_iter_next(&iter)) {
+ DBG("Sub-block %s",
+ ss_subblock_name(g_isi_sb_iter_get_id(&iter)));
+ switch (g_isi_sb_iter_get_id(&iter)) {
+ case SS_STATUS_RESULT: {
+ guint8 ss_status;
+
+ if (!g_isi_sb_iter_get_byte(&iter, &ss_status, 2))
+ goto error;
+
+ DBG("SS_STATUS_RESULT=%d", ss_status);
+
+ if (!(ss_status & SS_GSM_PROVISIONED))
+ network = CLIR_STATUS_NOT_PROVISIONED;
+ }
+ break;
+ case SS_GSM_ADDITIONAL_INFO:
+ break;
+ case SS_GSM_GENERIC_SERVICE_INFO: {
+ guint8 ss_status = 0;
+ guint8 clir_option = 0;
+ void *info = NULL;
+ GIsiMessage info_msg;
+
+ if (!g_isi_sb_iter_get_byte(&iter, &ss_status, 2))
+ goto error;
+
+ if (!(ss_status & SS_GSM_PROVISIONED))
+ network = CLIR_STATUS_NOT_PROVISIONED;
+
+ if (!g_isi_sb_iter_get_data(&iter, &info, 4))
+ goto error;
+
+ info_msg.addr = NULL;
+ info_msg.error = 0;
+ /* GIsiMessage function adds 2 to data pointer and
+ * removes 2 from len */
+ info_msg.data = info - 2;
+ info_msg.len = msg->len - 6 + 2;
+
+ for (g_isi_sb_iter_init(&iter_info, &info_msg, 0);
+ g_isi_sb_iter_is_valid(&iter_info);
+ g_isi_sb_iter_next(&iter_info)) {
+ uint8_t id = g_isi_sb_iter_get_id(&iter_info);
+ DBG("Sub-sub-block %d", id);
+
+ switch (id) {
+ case SS_GSM_CLIR_INFO: {
+ if (!g_isi_sb_iter_get_byte(&iter_info,
+ &clir_option, 2))
+ goto error;
+ break;
+ }
+ default:
+ break;
+ }
+
+ DBG("SS_STATUS_RESULT=%d, CLIR_OPTION=%d",
+ ss_status, clir_option);
+ }
+
+ if (network != CLIR_STATUS_NOT_PROVISIONED) {
+ switch (clir_option) {
+ case SS_GSM_CLI_PERMANENT:
+ network =
+ CLIR_STATUS_PROVISIONED_PERMANENT;
+ break;
+ case SS_GSM_DEFAULT_RESTRICTED:
+ break;
+ case SS_GSM_CLI_DEFAULT_ALLOWED:
+ network =
+ CLIR_STATUS_TEMPORARY_ALLOWED;
+ break;
+ case SS_GSM_OVERRIDE_ENABLED:
+ override =
+ OFONO_CLIR_OPTION_SUPPRESSION;
+ break;
+ case SS_GSM_OVERRIDE_DISABLED:
+ override =
+ OFONO_CLIR_OPTION_INVOCATION;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ DBG("Skipping sub-block: %s (%zd bytes)",
+ ss_subblock_name(g_isi_sb_iter_get_id(&iter)),
+ g_isi_sb_iter_get_len(&iter));
+ break;
+ }
+ }
+ /*
+ * CLIR cannot be activated,registrated in Network, but we can override
+ * it using local settings - 33GPP TS 24.081 Chapter 2.5
+ * we have to read status and pass override parameter to Ofono
+ */
+
+ if (network != CLIR_STATUS_NOT_PROVISIONED) {
+ override = get_clir_status();
+ DBG("CLIR mode queried %d\n", override);
+ }
+
+ DBG("override=%d, network=%d\n", override, network);
+ CALLBACK_WITH_SUCCESS(cb, override, network, cbd->data);
+ return;
+error:
+ CALLBACK_WITH_FAILURE(cb, override, network, cbd->data);
+}
+
+static void isi_clir_query(struct ofono_call_settings *cs,
+ ofono_call_settings_clir_cb_t cb, void *data)
+{
+ struct settings_data *sd = ofono_call_settings_get_data(cs);
+ struct isi_cb_data *cbd = isi_cb_data_new(cs, cb, data);
+ int override = 0, network = 2;
+ unsigned char msg[] = {
+ SS_SERVICE_REQ,
+ SS_INTERROGATION,
+ SS_ALL_TELE_AND_BEARER,
+ SS_GSM_CLIR >> 8, /* Supplementary services */
+ SS_GSM_CLIR & 0xFF, /* code */
+ SS_SEND_ADDITIONAL_INFO,
+ 0 /* Subblock count */
+ };
+ DBG("");
+
+ if (cbd == NULL)
+ goto error;
+
+ if (g_isi_client_send(sd->client, msg, sizeof(msg),
+ clir_query_cb, cbd, g_free))
+ return;
+
+error:
+ CALLBACK_WITH_FAILURE(cb, override, network, data);
+ g_free(cbd);
+}
+
+static void colp_query_cb(const GIsiMessage *msg, void *data)
+{
+ GIsiSubBlockIter iter;
+ struct isi_cb_data *cbd = data;
+ ofono_call_settings_status_cb_t cb = cbd->cb;
+ uint8_t service;
+ guint32 mask = 0;
+
+ if (!check_response_status(msg, SS_SERVICE_COMPLETED_RESP))
+ goto error;
+
+ if (!g_isi_msg_data_get_byte(msg, 0, &service) ||
+ service != SS_INTERROGATION)
+ goto error;
+
+ for (g_isi_sb_iter_init(&iter, msg, 6);
+ g_isi_sb_iter_is_valid(&iter);
+ g_isi_sb_iter_next(&iter)) {
+ DBG("Sub-block %s",
+ ss_subblock_name(g_isi_sb_iter_get_id(&iter)));
+
+ switch (g_isi_sb_iter_get_id(&iter)) {
+ case SS_STATUS_RESULT: {
+ guint8 ss_status;
+
+ if (!g_isi_sb_iter_get_byte(&iter, &ss_status, 2))
+ goto error;
+
+ DBG("SS_STATUS_RESULT=%d", ss_status);
+
+ if (ss_status & SS_GSM_PROVISIONED)
+ mask = 1;
+ }
+ break;
+ case SS_GSM_ADDITIONAL_INFO:
+ break;
+ case SS_GSM_BSC_INFO: {
+ guint8 bsc;
+ guint8 count;
+ guint8 i;
+
+ if (!g_isi_sb_iter_get_byte(&iter, &count, 2))
+ goto error;
+
+ for (i = 0; i < count; i++) {
+ if (!g_isi_sb_iter_get_byte(&iter, &bsc, 3 + i))
+ goto error;
+
+ update_status_mask(&mask, bsc);
+ }
+
+ break;
+ }
+ default:
+ DBG("Skipping sub-block: %s (%zd bytes)",
+ ss_subblock_name(g_isi_sb_iter_get_id(&iter)),
+ g_isi_sb_iter_get_len(&iter));
+ break;
+ }
+ }
+
+ DBG("status_mask %d\n", mask);
+ CALLBACK_WITH_SUCCESS(cb, mask, cbd->data);
+ return;
+error:
+ CALLBACK_WITH_FAILURE(cb, 0, cbd->data);
+}
+
+static void isi_colp_query(struct ofono_call_settings *cs,
+ ofono_call_settings_status_cb_t cb, void *data)
+{
+ struct settings_data *sd = ofono_call_settings_get_data(cs);
+ struct isi_cb_data *cbd = isi_cb_data_new(cs, cb, data);
+ unsigned char msg[] = {
+ SS_SERVICE_REQ,
+ SS_INTERROGATION,
+ SS_ALL_TELE_AND_BEARER,
+ SS_GSM_COLP >> 8, /* Supplementary services */
+ SS_GSM_COLP & 0xFF, /* code */
+ SS_SEND_ADDITIONAL_INFO,
+ 0 /* Subblock count */
+ };
+ DBG("");
+
+ if (cbd == NULL)
+ goto error;
- CALLBACK_WITH_SUCCESS(cb, mask, cbd->data);
+ if (g_isi_client_send(sd->client, msg, sizeof(msg),
+ colp_query_cb, cbd, g_free))
return;
+
+error:
+ CALLBACK_WITH_FAILURE(cb, 0, data);
+ g_free(cbd);
+}
+
+static void colr_query_cb(const GIsiMessage *msg, void *data)
+{
+ GIsiSubBlockIter iter;
+ struct isi_cb_data *cbd = data;
+ ofono_call_settings_status_cb_t cb = cbd->cb;
+ uint8_t service;
+ guint32 mask = 0;
+
+ if (!check_response_status(msg, SS_SERVICE_COMPLETED_RESP))
+ goto error;
+
+ if (!g_isi_msg_data_get_byte(msg, 0, &service) ||
+ service != SS_INTERROGATION)
+ goto error;
+
+ for (g_isi_sb_iter_init(&iter, msg, 6);
+ g_isi_sb_iter_is_valid(&iter);
+ g_isi_sb_iter_next(&iter)) {
+ DBG("Sub-block %s",
+ ss_subblock_name(g_isi_sb_iter_get_id(&iter)));
+
+ switch (g_isi_sb_iter_get_id(&iter)) {
+ case SS_STATUS_RESULT: {
+ guint8 ss_status;
+
+ if (!g_isi_sb_iter_get_byte(&iter, &ss_status, 2))
+ goto error;
+
+ DBG("SS_STATUS_RESULT=%d", ss_status);
+
+ if (ss_status & SS_GSM_PROVISIONED)
+ mask = 1;
+ }
+ break;
+ case SS_GSM_ADDITIONAL_INFO:
+ break;
+ case SS_GSM_BSC_INFO: {
+ guint8 bsc;
+ guint8 count;
+ guint8 i;
+
+ if (!g_isi_sb_iter_get_byte(&iter, &count, 2))
+ goto error;
+ for (i = 0; i < count; i++) {
+ if (!g_isi_sb_iter_get_byte(&iter, &bsc,
+ 3 + i))
+ goto error;
+
+ update_status_mask(&mask, bsc);
+ }
+
+ break;
+ }
+ default:
+ DBG("Skipping sub-block: %s (%zd bytes)",
+ ss_subblock_name(g_isi_sb_iter_get_id(&iter)),
+ g_isi_sb_iter_get_len(&iter));
+ break;
+ }
}
+ DBG("status_mask %d\n", mask);
+ CALLBACK_WITH_SUCCESS(cb, mask, cbd->data);
+ return;
error:
CALLBACK_WITH_FAILURE(cb, 0, cbd->data);
}
+static void isi_colr_query(struct ofono_call_settings *cs,
+ ofono_call_settings_status_cb_t cb, void *data)
+{
+ struct settings_data *sd = ofono_call_settings_get_data(cs);
+ struct isi_cb_data *cbd = isi_cb_data_new(cs, cb, data);
+ unsigned char msg[] = {
+ SS_SERVICE_REQ,
+ SS_INTERROGATION,
+ SS_ALL_TELE_AND_BEARER,
+ SS_GSM_COLR >> 8, /* Supplementary services */
+ SS_GSM_COLR & 0xFF, /* code */
+ SS_SEND_ADDITIONAL_INFO,
+ 0 /* Subblock count */
+ };
+ DBG("");
+
+ if (cbd == NULL)
+ goto error;
+
+ if (g_isi_client_send(sd->client, msg, sizeof(msg),
+ colr_query_cb, cbd, g_free))
+
+ return;
+
+error:
+ CALLBACK_WITH_FAILURE(cb, 0, data);
+ g_free(cbd);
+}
+
static void isi_cw_query(struct ofono_call_settings *cs, int cls,
ofono_call_settings_status_cb_t cb, void *data)
{
@@ -205,17 +851,31 @@ static void set_resp_cb(const GIsiMessage *msg, void *data)
if (g_isi_sb_iter_get_id(&iter) != SS_GSM_DATA)
continue;
- if (!g_isi_sb_iter_get_byte(&iter, &status, 2))
- goto error;
+ if (g_isi_sb_iter_get_id(&iter) == SS_GSM_DATA) {
+ if (!g_isi_sb_iter_get_byte(&iter, &status, 2))
+ goto error;
- if ((status & SS_GSM_ACTIVE) && (service == SS_DEACTIVATION))
- goto error;
+ if ((status & SS_GSM_ACTIVE) &&
+ (service == SS_DEACTIVATION))
+ goto error;
- if (!(status & SS_GSM_ACTIVE) && (service == SS_ACTIVATION))
- goto error;
+ if (!(status & SS_GSM_ACTIVE) &&
+ (service == SS_ACTIVATION))
+ goto error;
- CALLBACK_WITH_SUCCESS(cb, cbd->data);
- return;
+ CALLBACK_WITH_SUCCESS(cb, cbd->data);
+ return;
+ } else if (g_isi_sb_iter_get_id(&iter) == SS_GSM_DATA) {
+ guint8 ss_status;
+
+ if (!g_isi_sb_iter_get_byte(&iter, &ss_status, 2))
+ goto error;
+
+
+ CALLBACK_WITH_SUCCESS(cb, cbd->data);
+ return;
+
+ }
}
error:
@@ -273,6 +933,7 @@ static int isi_call_settings_probe(struct ofono_call_settings *cs,
return -ENOMEM;
sd->client = g_isi_client_create(modem, PN_SS);
+
if (sd->client == NULL) {
g_free(sd);
return -ENOMEM;
@@ -302,11 +963,11 @@ static struct ofono_call_settings_driver driver = {
.name = "isimodem",
.probe = isi_call_settings_probe,
.remove = isi_call_settings_remove,
- .clip_query = NULL,
- .colp_query = NULL,
- .clir_query = NULL,
- .colr_query = NULL,
- .clir_set = NULL,
+ .clip_query = isi_clip_query,
+ .colp_query = isi_colp_query,
+ .clir_query = isi_clir_query,
+ .colr_query = isi_colr_query,
+ .clir_set = isi_clir_set,
.cw_query = isi_cw_query,
.cw_set = isi_cw_set
};
diff --git a/drivers/isimodem/call.h b/drivers/isimodem/call.h
index 05f05a5..84f4e04 100644
--- a/drivers/isimodem/call.h
+++ b/drivers/isimodem/call.h
@@ -402,6 +402,15 @@ enum {
CALL_DTMF_DISABLE_TONE_IND_SEND = 0x02,
};
+/* 27.007 Section 7.7 */
+enum clir_status {
+ CLIR_STATUS_NOT_PROVISIONED = 0,
+ CLIR_STATUS_PROVISIONED_PERMANENT,
+ CLIR_STATUS_UNKNOWN,
+ CLIR_STATUS_TEMPORARY_RESTRICTED,
+ CLIR_STATUS_TEMPORARY_ALLOWED
+};
+
#ifdef __cplusplus
};
#endif
diff --git a/drivers/isimodem/debug.c b/drivers/isimodem/debug.c
index 89e4573..33e4dcb 100644
--- a/drivers/isimodem/debug.c
+++ b/drivers/isimodem/debug.c
@@ -95,10 +95,14 @@ const char *ss_subblock_name(enum ss_subblock value)
_(SS_GSM_FORWARDING_FEATURE);
_(SS_GSM_DATA);
_(SS_GSM_BSC_INFO);
+ _(SS_GSM_GENERIC_SERVICE_INFO);
+ _(SS_GSM_CLIR_INFO);
_(SS_GSM_PASSWORD_INFO);
_(SS_GSM_INDICATE_PASSWORD_ERROR);
_(SS_GSM_INDICATE_ERROR);
_(SS_GSM_ADDITIONAL_INFO);
+ _(SS_GSM_BARRING_INFO);
+ _(SS_GSM_BARRING_FEATURE);
_(SS_GSM_USSD_STRING);
}
return "SS_<UNKNOWN>";
diff --git a/drivers/isimodem/ss.h b/drivers/isimodem/ss.h
index 5cd86e9..8a2942e 100644
--- a/drivers/isimodem/ss.h
+++ b/drivers/isimodem/ss.h
@@ -94,6 +94,12 @@ enum ss_codes {
SS_GSM_BARR_OUT_INTER = 331,
SS_GSM_BARR_OUT_INTER_EXC_HOME = 332,
SS_GSM_BARR_ALL_IN_ROAM = 351,
+ SS_GSM_CLIP = 0x001E,
+ SS_GSM_CLIR = 0x001F,
+ SS_GSM_COLP = 0x004C,
+ SS_GSM_COLR = 0x004D,
+ SS_GSM_CNAP = 0x012C,
+ SS_GSM_ECT = 0x0060
};
enum ss_response_data {
@@ -106,9 +112,13 @@ enum ss_subblock {
SS_GSM_PASSWORD = 0x03,
SS_GSM_FORWARDING_INFO = 0x04,
SS_GSM_FORWARDING_FEATURE = 0x05,
+ SS_GSM_BARRING_INFO = 0x06,
+ SS_GSM_BARRING_FEATURE = 0x07,
SS_GSM_DATA = 0x08,
SS_GSM_BSC_INFO = 0x09,
+ SS_GSM_GENERIC_SERVICE_INFO = 0x0A,
SS_GSM_PASSWORD_INFO = 0x0B,
+ SS_GSM_CLIR_INFO = 0x0C,
SS_GSM_INDICATE_PASSWORD_ERROR = 0x0D,
SS_GSM_INDICATE_ERROR = 0x0E,
SS_GSM_ADDITIONAL_INFO = 0x2F,
@@ -122,4 +132,16 @@ enum ss_isi_cause {
SS_GSM_QUIESCENT = 0x08,
};
+enum ss_gsm_cli_restriction_option {
+ SS_GSM_CLI_PERMANENT = 0x00,
+ SS_GSM_DEFAULT_RESTRICTED = 0x01,
+ SS_GSM_CLI_DEFAULT_ALLOWED = 0x02,
+ SS_GSM_OVERRIDE_ENABLED = 0x03,
+ SS_GSM_OVERRIDE_DISABLED = 0x04
+};
+
+enum ss_constants {
+ SS_UNDEFINED_TIME = 0x00,
+};
+
#endif /* __ISIMODEM_SS_H */
--
1.7.3.5