Add basic support for USAT/CAT proactive commands

Only display_text with mandatory fields is currently supported.
This commit is contained in:
Denis Kenzior 2010-02-23 17:10:26 -06:00
parent 19a20e4ccd
commit d90aa1561f
2 changed files with 195 additions and 1 deletions

View File

@ -30,3 +30,172 @@
#include <ofono/types.h>
#include "stkutil.h"
#include "smsutil.h"
#include "simutil.h"
#include "util.h"
static gboolean parse_dataobj_text(struct stk_command *command,
struct comprehension_tlv_iter *iter)
{
unsigned int len;
if (comprehension_tlv_iter_next(iter) != TRUE)
return FALSE;
if (comprehension_tlv_iter_get_tag(iter) !=
STK_DATA_OBJECT_TYPE_TEXT)
return FALSE;
len = comprehension_tlv_iter_get_length(iter);
/* DCS followed by some text, cannot be 1 */
if (len == 1)
return FALSE;
if (len > 0) {
const unsigned char *data =
comprehension_tlv_iter_get_data(iter);
unsigned char dcs = data[0];
char *utf8;
switch (dcs) {
case 0x00:
{
long written;
unsigned long max_to_unpack = (len - 1) * 8 / 7;
unsigned char *unpacked = unpack_7bit(data + 1, len - 1,
0, FALSE,
max_to_unpack,
&written, 0);
if (unpacked == NULL)
return FALSE;
utf8 = convert_gsm_to_utf8(unpacked, written,
NULL, NULL, 0);
g_free(unpacked);
break;
}
case 0x04:
utf8 = convert_gsm_to_utf8(data + 1, len - 1,
NULL, NULL, 0);
break;
case 0x08:
utf8 = g_convert((const gchar *) data + 1, len - 1,
"UTF-8//TRANSLIT", "UCS-2BE",
NULL, NULL, NULL);
break;
default:
return FALSE;;
}
if (utf8 == NULL)
return FALSE;
command->display_text.text = utf8;
} else
command->display_text.text = NULL;
return TRUE;
}
static void destroy_display_text(struct stk_command *command)
{
g_free(command->display_text.text);
}
static gboolean parse_display_text(struct stk_command *command,
struct comprehension_tlv_iter *iter)
{
if (parse_dataobj_text(command, iter) == FALSE)
return FALSE;
command->destructor = destroy_display_text;
return TRUE;
}
struct stk_command *stk_command_new_from_pdu(const unsigned char *pdu,
unsigned int len)
{
struct ber_tlv_iter ber;
struct comprehension_tlv_iter iter;
const unsigned char *data;
struct stk_command *command;
gboolean ok;
ber_tlv_iter_init(&ber, pdu, len);
if (ber_tlv_iter_next(&ber) != TRUE)
return NULL;
/* We should be wrapped in a Proactive UICC Command Tag 0xD0 */
if (ber_tlv_iter_get_short_tag(&ber) != 0xD0)
return NULL;
ber_tlv_iter_recurse_comprehension(&ber, &iter);
/*
* Now parse actual command details, they come in order with
* Command Details TLV first, followed by Device Identities TLV
*/
if (comprehension_tlv_iter_next(&iter) != TRUE)
return NULL;
if (comprehension_tlv_iter_get_tag(&iter) !=
STK_DATA_OBJECT_TYPE_COMMAND_DETAILS)
return NULL;
if (comprehension_tlv_iter_get_length(&iter) != 0x03)
return NULL;
data = comprehension_tlv_iter_get_data(&iter);
command = g_new0(struct stk_command, 1);
command->number = data[0];
command->type = data[1];
command->qualifier = data[2];
if (comprehension_tlv_iter_next(&iter) != TRUE)
goto fail;
if (comprehension_tlv_iter_get_tag(&iter) !=
STK_DATA_OBJECT_TYPE_DEVICE_IDENTITIES)
goto fail;
if (comprehension_tlv_iter_get_length(&iter) != 0x02)
goto fail;
data = comprehension_tlv_iter_get_data(&iter);
command->src = data[0];
command->dst = data[1];
switch (command->type) {
case STK_COMMAND_TYPE_DISPLAY_TEXT:
ok = parse_display_text(command, &iter);
break;
default:
ok = FALSE;
break;
};
if (ok)
return command;
fail:
if (command->destructor)
command->destructor(command);
g_free(command);
return NULL;
}
void stk_command_free(struct stk_command *command)
{
if (command->destructor)
command->destructor(command);
g_free(command);
}

View File

@ -81,7 +81,7 @@ enum stk_command_type {
enum stk_data_object_type {
STK_DATA_OBJECT_TYPE_COMMAND_DETAILS = 0x01,
STK_DATA_OBJECT_TYPE_DEVICE_IDENTITY = 0x02,
STK_DATA_OBJECT_TYPE_DEVICE_IDENTITIES = 0x02,
STK_DATA_OBJECT_TYPE_RESULT = 0x03,
STK_DATA_OBJECT_TYPE_DURATION = 0x04,
STK_DATA_OBJECT_TYPE_ALPHA_IDENTIFIER = 0x05,
@ -184,3 +184,28 @@ enum stk_device_identity_type {
STK_DEVICE_IDENTITY_TYPE_TERMINAL = 0x82,
STK_DEVICE_IDENTITY_TYPE_NETWORK = 0x83,
};
struct stk_command_display_text {
char *text;
unsigned char icon_id;
unsigned char icon_qualifier;
ofono_bool_t immediate_response;
};
struct stk_command {
unsigned char number;
unsigned char type;
unsigned char qualifier;
enum stk_device_identity_type src;
enum stk_device_identity_type dst;
union {
struct stk_command_display_text display_text;
};
void (*destructor)(struct stk_command *command);
};
struct stk_command *stk_command_new_from_pdu(const unsigned char *pdu,
unsigned int len);
void stk_command_free(struct stk_command *command);