@@ -50,17 +50,15 @@
return cbd;
}
-static void ril_ussd_cb(GRilIoChannel *io, int status,
+static void ril_ussd_cancel_cb(GRilIoChannel *io, int status,
const void *data, guint len, void *user_data)
{
struct ofono_error error;
struct ril_ussd_cbd *cbd = user_data;
- if (status == RIL_E_SUCCESS) {
- cbd->cb(ril_error_ok(&error), cbd->data);
- } else {
- cbd->cb(ril_error_failure(&error), cbd->data);
- }
+ /* Always report sucessful completion, otherwise ofono may get
+ * stuck in the USSD_STATE_ACTIVE state */
+ cbd->cb(ril_error_ok(&error), cbd->data);
}
static void ril_ussd_request(struct ofono_ussd *ussd, int dcs,
@@ -120,7 +118,8 @@
ofono_info("send ussd cancel");
grilio_queue_send_request_full(ud->q, NULL, RIL_REQUEST_CANCEL_USSD,
- ril_ussd_cb, ril_ussd_cbd_free, ril_ussd_cbd_new(cb, data));
+ ril_ussd_cancel_cb, ril_ussd_cbd_free,
+ ril_ussd_cbd_new(cb, data));
}
static void ril_ussd_notify(GRilIoChannel *io, guint code,
@@ -128,32 +127,32 @@
{
struct ril_ussd *ud = user_data;
GRilIoParser rilp;
- char *ussd_from_network = NULL;
- char *type = NULL;
- int ussdtype = 0;
+ char *type;
+ guint32 n = 0;
- ofono_info("ussd_received");
+ ofono_info("ussd received");
GASSERT(code == RIL_UNSOL_ON_USSD);
grilio_parser_init(&rilp, data, len);
- grilio_parser_get_uint32(&rilp, NULL);
+ grilio_parser_get_uint32(&rilp, &n);
type = grilio_parser_get_utf8(&rilp);
- ussd_from_network = grilio_parser_get_utf8(&rilp);
- ussdtype = g_ascii_xdigit_value(*type);
+ if (type) {
+ int ussdtype = g_ascii_xdigit_value(*type);
+ char *msg = (n > 1) ? grilio_parser_get_utf8(&rilp) : NULL;
+
+ if (msg) {
+ const int msglen = strlen(msg);
+ DBG("ussd length %d", msglen);
+ ofono_ussd_notify(ud->ussd, ussdtype, 0xFF,
+ (const unsigned char *)msg, msglen);
+ /* msg is freed by core if dcs is 0xFF */
+ } else {
+ ofono_ussd_notify(ud->ussd, ussdtype, 0, NULL, 0);
+ }
- if (ussd_from_network) {
- const int data_len = strlen(ussd_from_network);
- DBG("ussd_received, length %d", data_len);
- ofono_ussd_notify(ud->ussd, ussdtype, 0xFF,
- (const unsigned char *) ussd_from_network, data_len);
- } else {
- ofono_ussd_notify(ud->ussd, ussdtype, 0, NULL, 0);
+ g_free(type);
}
-
- /* ussd_from_network not freed because core does that if dcs is 0xFF */
- g_free(type);
- return;
}
static gboolean ril_ussd_register(gpointer user_data)
@@ -170,7 +169,7 @@
ril_ussd_notify, RIL_UNSOL_ON_USSD, ud);
/* Single-shot */
- return FALSE;
+ return G_SOURCE_REMOVE;
}
static int ril_ussd_probe(struct ofono_ussd *ussd, unsigned int vendor,
|