diff options
author | Jeevaka Badrappan <jeevaka.badrappan@elektrobit.com> | 2010-09-14 14:23:14 -0700 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2010-09-14 17:01:49 -0500 |
commit | eb425a281ff76814e5e5a29fb2e087d29cad978d (patch) | |
tree | 8e9fc7bb49d7b00ca78e1902ca7d04c75ecb80f1 /drivers | |
parent | adc0a1bd6cc397efbcf724a7502b0289b7c88088 (diff) | |
download | ofono-eb425a281ff76814e5e5a29fb2e087d29cad978d.tar.bz2 |
ussd: Driver API changes
To support 8bit and UCS2 formatted USSDs as well as Send USSD Proactive
Command.
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/atmodem/ussd.c | 115 | ||||
-rw-r--r-- | drivers/isimodem/ussd.c | 42 |
2 files changed, 77 insertions, 80 deletions
diff --git a/drivers/atmodem/ussd.c b/drivers/atmodem/ussd.c index 30145adc..685bc9bd 100644 --- a/drivers/atmodem/ussd.c +++ b/drivers/atmodem/ussd.c @@ -65,15 +65,17 @@ static void read_charset_cb(gboolean ok, GAtResult *result, static void cusd_parse(GAtResult *result, struct ofono_ussd *ussd) { + struct ussd_data *data = ofono_ussd_get_data(ussd); GAtResultIter iter; int status; int dcs; - const char *content; - char *converted = NULL; - gboolean udhi; + const char *content = NULL; enum sms_charset charset; - gboolean compressed; - gboolean iso639; + unsigned char msg[160]; + const unsigned char *msg_ptr = NULL; + unsigned char *converted = NULL; + long written; + long msg_len = 0; g_at_result_iter_init(&iter, result); @@ -86,34 +88,50 @@ static void cusd_parse(GAtResult *result, struct ofono_ussd *ussd) if (!g_at_result_iter_next_string(&iter, &content)) goto out; - if (g_at_result_iter_next_number(&iter, &dcs)) { - if (!cbs_dcs_decode(dcs, &udhi, NULL, &charset, - &compressed, NULL, &iso639)) - goto out; + if (!g_at_result_iter_next_number(&iter, &dcs)) + dcs = 0; - if (udhi || compressed || iso639) - goto out; - } else - charset = SMS_CHARSET_7BIT; - - if (charset == SMS_CHARSET_7BIT) - converted = convert_gsm_to_utf8((const guint8 *) content, - strlen(content), NULL, NULL, 0); - - else if (charset == SMS_CHARSET_8BIT) { - /* TODO: Figure out what to do with 8 bit data */ - ofono_error("8-bit coded USSD response received"); - status = 4; /* Not supported */ - } else { - /* No other encoding is mentioned in TS27007 7.15 */ + if (!cbs_dcs_decode(dcs, NULL, NULL, &charset, NULL, NULL, NULL)) { ofono_error("Unsupported USSD data coding scheme (%02x)", dcs); status = 4; /* Not supported */ + goto out; } -out: - ofono_ussd_notify(ussd, status, converted); + switch (charset) { + case SMS_CHARSET_7BIT: + if (data->charset == AT_UTIL_CHARSET_GSM) + msg_ptr = pack_7bit_own_buf((const guint8 *) content, + strlen(content), 0, TRUE, &msg_len, 0, msg); + else if (data->charset == AT_UTIL_CHARSET_UTF8) + ussd_encode(content, &msg_len, msg); + else if (data->charset == AT_UTIL_CHARSET_UCS2) { + msg_ptr = decode_hex_own_buf(content, -1, &msg_len, 0, msg); + + converted = convert_ucs2_to_gsm(msg_ptr, msg_len, NULL, + &written, 0); + if (!converted) { + msg_ptr = NULL; + msg_len = 0; + goto out; + } + + msg_ptr = pack_7bit_own_buf(converted, + written, 0, TRUE, + &msg_len, 0, msg); + + g_free(converted); + } + break; + case SMS_CHARSET_8BIT: + msg_ptr = decode_hex_own_buf(content, -1, &msg_len, 0, msg); + break; + case SMS_CHARSET_UCS2: + msg_ptr = decode_hex_own_buf(content, -1, &msg_len, 0, msg); + break; + } - g_free(converted); +out: + ofono_ussd_notify(ussd, status, dcs, msg_ptr, msg_len); } static void cusd_request_cb(gboolean ok, GAtResult *result, gpointer user_data) @@ -130,39 +148,45 @@ static void cusd_request_cb(gboolean ok, GAtResult *result, gpointer user_data) cusd_parse(result, ussd); } -static void at_ussd_request(struct ofono_ussd *ussd, const char *str, +static void at_ussd_request(struct ofono_ussd *ussd, int dcs, + const unsigned char *pdu, int len, ofono_ussd_cb_t cb, void *user_data) { struct ussd_data *data = ofono_ussd_get_data(ussd); struct cb_data *cbd = cb_data_new(cb, user_data); - unsigned char *converted = NULL; - int dcs; - int max_len; - long written; char buf[256]; + unsigned char unpacked_buf[182]; + char coded_buf[160]; + char *converted; + long written; + enum sms_charset charset; if (!cbd) goto error; cbd->user = ussd; - converted = convert_utf8_to_gsm(str, strlen(str), NULL, &written, 0); - - if (!converted) + if (!cbs_dcs_decode(dcs, NULL, NULL, &charset, + NULL, NULL, NULL)) goto error; - else { - dcs = 15; - max_len = 182; - } - if (written > max_len) - goto error; + if (charset == SMS_CHARSET_7BIT) { + unpack_7bit_own_buf(pdu, len, 0, TRUE, sizeof(unpacked_buf), + &written, 0, unpacked_buf); - snprintf(buf, sizeof(buf), "AT+CUSD=1,\"%.*s\",%d", - (int) written, converted, dcs); + if (written < 1) + goto error; - g_free(converted); - converted = NULL; + snprintf(buf, sizeof(buf), "AT+CUSD=1,\"%.*s\",%d", + (int) written, unpacked_buf, dcs); + } else { + converted = encode_hex_own_buf(pdu, len, 0, coded_buf); + if (!converted) + goto error; + + snprintf(buf, sizeof(buf), "AT+CUSD=1,\"%.*s\",%d", + strlen(converted), converted, dcs); + } if (data->vendor == OFONO_VENDOR_QUALCOMM_MSM) { /* Ensure that the modem is using GSM character set. It @@ -179,7 +203,6 @@ static void at_ussd_request(struct ofono_ussd *ussd, const char *str, error: g_free(cbd); - g_free(converted); CALLBACK_WITH_FAILURE(cb, user_data); } diff --git a/drivers/isimodem/ussd.c b/drivers/isimodem/ussd.c index 330a1419..19ba30eb 100644 --- a/drivers/isimodem/ussd.c +++ b/drivers/isimodem/ussd.c @@ -74,24 +74,14 @@ static void ussd_parse(struct ofono_ussd *ussd, const void *restrict data, { const unsigned char *msg = data; int status = OFONO_USSD_STATUS_NOT_SUPPORTED; - char *converted = NULL; if (!msg || len < 4) - goto out; + ofono_ussd_notify(ussd, status, 0, NULL, 0); status = isi_type_to_status(msg[2]); if (msg[3] == 0 || (size_t)(msg[3] + 4) > len) - goto out; - - converted = ussd_decode(msg[1], msg[3], msg + 4); - - if (converted) - status = OFONO_USSD_STATUS_NOTIFY; - -out: - ofono_ussd_notify(ussd, status, converted); - g_free(converted); + ofono_ussd_notify(ussd, status, msg[1], msg + 4, msg[3]); } @@ -129,7 +119,7 @@ error: } static GIsiRequest *ussd_send(GIsiClient *client, - uint8_t *str, size_t len, + int dcs, uint8_t *str, size_t len, void *data, GDestroyNotify notify) { const uint8_t msg[] = { @@ -138,7 +128,7 @@ static GIsiRequest *ussd_send(GIsiClient *client, 0x01, /* subblock count */ SS_GSM_USSD_STRING, 4 + len + 3, /* subblock length */ - 0x0f, /* DCS */ + dcs, /* DCS */ len, /* string length */ /* USSD string goes here */ }; @@ -152,33 +142,17 @@ static GIsiRequest *ussd_send(GIsiClient *client, ussd_send_resp_cb, data, notify); } -static void isi_request(struct ofono_ussd *ussd, const char *str, - ofono_ussd_cb_t cb, void *data) +static void isi_request(struct ofono_ussd *ussd, int dcs, + const unsigned char *pdu, int len, + ofono_ussd_cb_t cb, void *data) { struct ussd_data *ud = ofono_ussd_get_data(ussd); struct isi_cb_data *cbd = isi_cb_data_new(ussd, cb, data); - unsigned char buf[256]; - unsigned char *packed = NULL; - unsigned char *converted = NULL; - long num_packed; - long written; if (!cbd) goto error; - converted = convert_utf8_to_gsm(str, strlen(str), NULL, &written, 0); - if (!converted) - goto error; - - packed = pack_7bit_own_buf(converted, written, 0, TRUE, - &num_packed, 0, buf); - - g_free(converted); - - if (written > SS_MAX_USSD_LENGTH) - goto error; - - if (ussd_send(ud->client, packed, num_packed, cbd, g_free)) + if (ussd_send(ud->client, dcs, (guint8 *) pdu, len, cbd, g_free)) return; error: |