Hi Jeevaka,

On 09/09/2010 07:31 AM, Jeevaka Badrappan wrote:
> ---
>  drivers/atmodem/ussd.c  |   81 ++++++++++-----------
>  drivers/isimodem/ussd.c |   44 ++++--------
>  include/types.h         |    1 +
>  include/ussd.h          |    8 ++-
>  src/ofono.h             |   17 +++++
>  src/ussd.c              |  179 
> ++++++++++++++++++++++++++++++++++++++++++-----
>  6 files changed, 236 insertions(+), 94 deletions(-)

Please break this patch up into two.  One with the core driver changes
and one for implementing __ofono_ussd_initiate

> 
> diff --git a/drivers/atmodem/ussd.c b/drivers/atmodem/ussd.c
> index cb1515f..573417a 100644
> --- a/drivers/atmodem/ussd.c
> +++ b/drivers/atmodem/ussd.c
> @@ -67,15 +67,14 @@ 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;
>       enum sms_charset charset;
> -     gboolean compressed;
> -     gboolean iso639;
> +     unsigned char msg[182];

The buffer should be 160 bytes no?

> +     long msg_len = 0;
>  
>       g_at_result_iter_init(&iter, result);
>  
> @@ -89,33 +88,27 @@ static void cusd_parse(GAtResult *result, struct 
> ofono_ussd *ussd)
>               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 (udhi || compressed || iso639)
> +             if (!cbs_dcs_decode(dcs, NULL, NULL, &charset,
> +                                     NULL, NULL, NULL))
>                       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 {
> +     if (charset == SMS_CHARSET_7BIT) {
> +             if (data->charset == AT_UTIL_CHARSET_GSM)
> +                     pack_7bit_own_buf((const guint8 *) content, 
> +                                     strlen(content), 0, TRUE,
> +                                     &msg_len, 0, msg);
> +     } else if (charset == SMS_CHARSET_8BIT)
> +             decode_hex_own_buf(content, -1, &msg_len, 0, msg);
> +     else {
>               /* No other encoding is mentioned in TS27007 7.15 */
>               ofono_error("Unsupported USSD data coding scheme (%02x)", dcs);
>               status = 4; /* Not supported */
>       }
>  
>  out:
> -     ofono_ussd_notify(ussd, status, converted);
> -
> -     g_free(converted);
> +     ofono_ussd_notify(ussd, status, dcs, msg, (int) msg_len);

I don't think you need the cast here

>  }
>  
>  static void cusd_request_cb(gboolean ok, GAtResult *result, gpointer 
> user_data)
> @@ -132,45 +125,50 @@ 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 *binary_data,
> +                             int binary_data_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];
> +     long max_chars = 182;
> +     unsigned char *unpacked_buf = NULL;
> +     long written;
> +     enum sms_charset charset;
>  
>       if (!cbd)
>               goto error;
>  
>       cbd->user = ussd;
> +        
> +     if (!cbs_dcs_decode(dcs, NULL, NULL, &charset,
> +                                     NULL, NULL, NULL))
> +             charset = SMS_CHARSET_7BIT;

Failing is fine here.  As a general rule, it is better to fail early.

>  
> -     converted = convert_utf8_to_gsm(str, strlen(str), NULL, &written, 0);
> -
> -     if (!converted)
> -             goto error;
> -     else {
> -             dcs = 15;
> -             max_len = 182;
> -     }
> +     if (charset == SMS_CHARSET_7BIT) {
> +             unpacked_buf = unpack_7bit(binary_data, binary_data_len, 0,
> +                                             TRUE, max_chars, &written, 0);
>  
> -     if (written > max_len)
> -             goto error;
> +             if ( !unpacked_buf || written <= 0)
> +                     goto error;
>  
> -     snprintf(buf, sizeof(buf), "AT+CUSD=1,\"%.*s\",%d",
> -                     (int) written, converted, dcs);
> +             snprintf(buf, sizeof(buf), "AT+CUSD=1,\"%.*s\",%d",
> +                             (int) written, unpacked_buf, dcs);
>  
> -     g_free(converted);
> -     converted = NULL;
> +             g_free(unpacked_buf);
> +             unpacked_buf = NULL;
> +     } else 
> +             snprintf(buf, sizeof(buf), "AT+CUSD=1,\"%.*s\",%d",
> +                             binary_data_len, binary_data, dcs);

This should be hex encoded

>  
>       if (data->vendor == OFONO_VENDOR_QUALCOMM_MSM) {
>               /* Ensure that the modem is using GSM character set. It
>                * seems it defaults to IRA and then umlauts are not
>                * properly encoded. The modem returns some weird from
> -              * of Latin-1, but it is not really Latin-1 either. */
> +              * of Latin-1, but it is not really Latin-1 either.
> +              */

Please send this as a separate cleanup patch

>               g_at_chat_send(data->chat, "AT+CSCS=\"GSM\"", none_prefix,
>                                                       NULL, NULL, NULL);
>       }
> @@ -181,7 +179,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 330a141..6ac945b 100644
> --- a/drivers/isimodem/ussd.c
> +++ b/drivers/isimodem/ussd.c
> @@ -74,7 +74,9 @@ 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;
> +     int msg_len = 0;
> +     int dcs = -1;
> +     unsigned char *coded_msg = NULL;
>  
>       if (!msg || len < 4)
>               goto out;
> @@ -84,14 +86,11 @@ static void ussd_parse(struct ofono_ussd *ussd, const 
> void *restrict data,
>       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;
> -
> +     dcs = msg[1];
> +     msg_len = msg[3];
> +     coded_msg = (guint8 *) msg+4;
>  out:
> -     ofono_ussd_notify(ussd, status, converted);
> -     g_free(converted);
> +     ofono_ussd_notify(ussd, status, dcs, coded_msg, msg_len);
>  }
>  
>  
> @@ -129,7 +128,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 +137,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 +151,18 @@ 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 *binary_data, int binary_data_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 *) binary_data,
> +                     binary_data_len, cbd, g_free))
>               return;
>  

This looks fine to me

>  error:
> diff --git a/include/types.h b/include/types.h
> index 6098cba..fbd3c6a 100644
> --- a/include/types.h
> +++ b/include/types.h
> @@ -77,6 +77,7 @@ struct ofono_error {
>  };
>  
>  #define OFONO_MAX_PHONE_NUMBER_LENGTH 20
> +#define OFONO_MAX_USSD_LENGTH 160

This define is only being used by ussd.c.  If so, please move it out to
ussd.c and don't give it the OFONO_ prefix.

>  
>  struct ofono_phone_number {
>       char number[OFONO_MAX_PHONE_NUMBER_LENGTH + 1];
> diff --git a/include/ussd.h b/include/ussd.h
> index 96e04cb..08dfc40 100644
> --- a/include/ussd.h
> +++ b/include/ussd.h
> @@ -45,13 +45,15 @@ struct ofono_ussd_driver {
>       const char *name;
>       int (*probe)(struct ofono_ussd *ussd, unsigned int vendor, void *data);
>       void (*remove)(struct ofono_ussd *ussd);
> -     void (*request)(struct ofono_ussd *ussd, const char *str,
> -                             ofono_ussd_cb_t, void *data);
> +     void (*request)(struct ofono_ussd *ussd, int dcs,
> +                     const unsigned char *binary_data, int binary_data_len,
> +                     ofono_ussd_cb_t, void *data);
>       void (*cancel)(struct ofono_ussd *ussd,
>                               ofono_ussd_cb_t cb, void *data);
>  };
>  
> -void ofono_ussd_notify(struct ofono_ussd *ussd, int status, const char *str);
> +void ofono_ussd_notify(struct ofono_ussd *ussd, int status, int dcs,
> +                     const unsigned char *data, int data_len);
>  
>  int ofono_ussd_driver_register(const struct ofono_ussd_driver *d);
>  void ofono_ussd_driver_unregister(const struct ofono_ussd_driver *d);
> diff --git a/src/ofono.h b/src/ofono.h
> index 9b8d938..bc67c73 100644
> --- a/src/ofono.h
> +++ b/src/ofono.h
> @@ -244,6 +244,13 @@ gboolean __ofono_ssn_mt_watch_remove(struct ofono_ssn 
> *ssn, int id);
>  
>  #include <ofono/ussd.h>
>  
> +enum ofono_ussd_failure {
> +     OFONO_USSD_FAILURE_NONE,
> +     OFONO_USSD_FAILURE_USER_TERMINATED,
> +     OFONO_USSD_FAILURE_RETURN_ERROR,
> +     OFONO_USSD_FAILURE_TIMED_OUT,
> +};
> +
>  typedef gboolean (*ofono_ussd_ssc_cb_t)(int type,
>                                       const char *sc,
>                                       const char *sia, const char *sib,
> @@ -254,6 +261,10 @@ typedef gboolean (*ofono_ussd_passwd_cb_t)(const char 
> *sc,
>                                       const char *old, const char *new,
>                                       DBusMessage *msg, void *data);
>  
> +typedef void (*ofono_ussd_request_cb_t)(int error, int dcs,
> +                                     const unsigned char *str,
> +                                     int str_len, void *data);
> +
>  gboolean __ofono_ussd_ssc_register(struct ofono_ussd *ussd, const char *sc,
>                                       ofono_ussd_ssc_cb_t cb, void *data,
>                                       ofono_destroy_func destroy);
> @@ -264,6 +275,12 @@ gboolean __ofono_ussd_passwd_register(struct ofono_ussd 
> *ussd, const char *sc,
>                                       ofono_destroy_func destroy);
>  void __ofono_ussd_passwd_unregister(struct ofono_ussd *ussd, const char *sc);
>  
> +gboolean __ofono_ussd_is_busy(struct ofono_ussd *ussd);
> +
> +int __ofono_ussd_initiate(struct ofono_ussd *ussd, int dcs,
> +                     const unsigned char *binary_data, int binary_data_len,

naming these data or pdu and len is good enough

> +                     ofono_ussd_request_cb_t cb, void *user_data);
> +
>  #include <ofono/netreg.h>
>  
>  typedef void (*ofono_netreg_status_notify_cb_t)(int status, int lac, int ci,
> diff --git a/src/ussd.c b/src/ussd.c
> index 825d560..c58bd7c 100644
> --- a/src/ussd.c
> +++ b/src/ussd.c
> @@ -34,6 +34,8 @@
>  #include "ofono.h"
>  
>  #include "common.h"
> +#include "smsutil.h"
> +#include "util.h"
>  
>  #define SUPPLEMENTARY_SERVICES_INTERFACE "org.ofono.SupplementaryServices"
>  
> @@ -46,6 +48,15 @@ enum ussd_state {
>       USSD_STATE_RESPONSE_SENT,
>  };
>  
> +struct ussd_request {
> +     struct ofono_ussd *ussd;
> +     int dcs;
> +     unsigned char *str;
> +     int str_len;
> +     ofono_ussd_request_cb_t cb;
> +     void *user_data;
> +};
> +
>  struct ofono_ussd {
>       int state;
>       DBusMessage *pending;
> @@ -56,6 +67,7 @@ struct ofono_ussd {
>       const struct ofono_ussd_driver *driver;
>       void *driver_data;
>       struct ofono_atom *atom;
> +     struct ussd_request *req;
>  };
>  
>  struct ssc_entry {
> @@ -306,15 +318,56 @@ static void ussd_change_state(struct ofono_ussd *ussd, 
> int state)
>                       "State", DBUS_TYPE_STRING, &value);
>  }
>  
> -void ofono_ussd_notify(struct ofono_ussd *ussd, int status, const char *str)
> +static void ussd_request_finish(struct ofono_ussd *ussd, int error, int dcs,
> +                             const unsigned char *str, int str_len)
> +{
> +     struct ussd_request *req = ussd->req;
> +
> +     if (req && req->cb) {
> +             req->cb(error, dcs, str, str_len, req->user_data);
> +             g_free(req->str);
> +             g_free(req);
> +             ussd->req = NULL;
> +     }
> +}
> +
> +static int ussd_status_to_failure_code(int status)
> +{
> +     switch (status) {
> +     case OFONO_USSD_STATUS_TIMED_OUT:
> +             return OFONO_USSD_FAILURE_TIMED_OUT;
> +     case OFONO_USSD_STATUS_NOT_SUPPORTED:
> +             return OFONO_USSD_FAILURE_RETURN_ERROR;
> +     }
> +
> +     return OFONO_USSD_FAILURE_NONE;
> +}
> +
> +void ofono_ussd_notify(struct ofono_ussd *ussd, int status, int dcs,
> +                     const unsigned char *data, int data_len)
>  {
>       DBusConnection *conn = ofono_dbus_get_connection();
>       const char *ussdstr = "USSD";
> +     char *utf8_str = NULL;
> +     gboolean utf8_str_valid = FALSE;
>       const char sig[] = { DBUS_TYPE_STRING, 0 };
>       DBusMessage *reply;
>       DBusMessageIter iter;
>       DBusMessageIter variant;
>  
> +     if (ussd->req &&
> +             (status == OFONO_USSD_STATUS_NOTIFY ||
> +             status == OFONO_USSD_STATUS_TERMINATED ||
> +             status == OFONO_USSD_STATUS_TIMED_OUT ||
> +             status == OFONO_USSD_STATUS_NOT_SUPPORTED)) {
> +
> +             ussd_request_finish(ussd, ussd_status_to_failure_code(status),
> +                                     dcs, data, data_len);
> +
> +             ussd_change_state(ussd, USSD_STATE_IDLE);
> +             return;
> +     }
> +
>       if (status == OFONO_USSD_STATUS_NOT_SUPPORTED) {
>               ussd_change_state(ussd, USSD_STATE_IDLE);
>  
> @@ -334,15 +387,21 @@ void ofono_ussd_notify(struct ofono_ussd *ussd, int 
> status, const char *str)
>               reply = __ofono_error_timed_out(ussd->pending);
>               goto out;
>       }
> +     
> +     if (data && data_len > 0)
> +             utf8_str = ussd_decode(dcs, data_len, data);
> +
> +     if (!utf8_str) {
> +             utf8_str = "";
> +             status = OFONO_USSD_STATUS_NOTIFY;
> +     } else
> +             utf8_str_valid = TRUE;
>  
>       /* TODO: Rework this in the Agent framework */
>       if (ussd->state == USSD_STATE_ACTIVE) {
>  
>               reply = dbus_message_new_method_return(ussd->pending);
>  
> -             if (!str)
> -                     str = "";
> -
>               dbus_message_iter_init_append(reply, &iter);
>  
>               dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
> @@ -352,7 +411,7 @@ void ofono_ussd_notify(struct ofono_ussd *ussd, int 
> status, const char *str)
>                                                       &variant);
>  
>               dbus_message_iter_append_basic(&variant, DBUS_TYPE_STRING,
> -                                             &str);
> +                                             &utf8_str);
>  
>               dbus_message_iter_close_container(&iter, &variant);
>  
> @@ -364,10 +423,7 @@ void ofono_ussd_notify(struct ofono_ussd *ussd, int 
> status, const char *str)
>       } else if (ussd->state == USSD_STATE_RESPONSE_SENT) {
>               reply = dbus_message_new_method_return(ussd->pending);
>  
> -             if (!str)
> -                     str = "";
> -
> -             dbus_message_append_args(reply, DBUS_TYPE_STRING, &str,
> +             dbus_message_append_args(reply, DBUS_TYPE_STRING, &utf8_str,
>                                               DBUS_TYPE_INVALID);
>  
>               if (status == OFONO_USSD_STATUS_ACTION_REQUIRED)
> @@ -387,20 +443,17 @@ void ofono_ussd_notify(struct ofono_ussd *ussd, int 
> status, const char *str)
>                       signal_name = "NotificationReceived";
>               }
>  
> -             if (!str)
> -                     str = "";
> -
>               g_dbus_emit_signal(conn, path,
>                               SUPPLEMENTARY_SERVICES_INTERFACE, signal_name,
> -                             DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID);
> +                             DBUS_TYPE_STRING, &utf8_str, DBUS_TYPE_INVALID);
>  
>               ussd_change_state(ussd, new_state);
> -             return;
> +             goto free;
>       } else {
>               ofono_error("Received an unsolicited USSD but can't handle.");
> -             DBG("USSD is: status: %d, %s", status, str);
> +             DBG("USSD is: status: %d, %s", status, utf8_str);
>  
> -             return;
> +             goto free;
>       }
>  
>  out:
> @@ -408,6 +461,10 @@ out:
>  
>       dbus_message_unref(ussd->pending);
>       ussd->pending = NULL;
> +
> +free:
> +     if (utf8_str_valid)
> +             g_free(utf8_str);
>  }
>  
>  static void ussd_callback(const struct ofono_error *error, void *data)
> @@ -436,6 +493,12 @@ static DBusMessage *ussd_initiate(DBusConnection *conn, 
> DBusMessage *msg,
>  {
>       struct ofono_ussd *ussd = data;
>       const char *str;
> +     int dcs = 0x0f;
> +     unsigned char buf[256];
> +     unsigned char *converted;
> +     unsigned char *packed = NULL;
> +     long num_packed;
> +     long written;
>  
>       if (ussd->pending)
>               return __ofono_error_busy(msg);
> @@ -458,14 +521,27 @@ static DBusMessage *ussd_initiate(DBusConnection *conn, 
> DBusMessage *msg,
>       if (!valid_ussd_string(str))
>               return __ofono_error_invalid_format(msg);
>  
> -     DBG("OK, running USSD request");
> +     converted = convert_utf8_to_gsm(str, strlen(str), NULL, &written, 0);
> +     if (!converted)
> +             return __ofono_error_invalid_format(msg);
> +
> +     packed = pack_7bit_own_buf(converted, written, 0, TRUE,
> +                                     &num_packed, 0, buf);
> +
> +     g_free(converted);
> +
> +     if (num_packed > OFONO_MAX_USSD_LENGTH)
> +             return __ofono_error_invalid_format(msg);
>  
>       if (!ussd->driver->request)
>               return __ofono_error_not_implemented(msg);
>  
> +     DBG("OK, running USSD request");
> +
>       ussd->pending = dbus_message_ref(msg);
>  
> -     ussd->driver->request(ussd, str, ussd_callback, ussd);
> +     ussd->driver->request(ussd, dcs, packed, (int) num_packed,
> +                             ussd_callback, ussd);
>  
>       return NULL;
>  }
> @@ -496,6 +572,12 @@ static DBusMessage *ussd_respond(DBusConnection *conn, 
> DBusMessage *msg,
>  {
>       struct ofono_ussd *ussd = data;
>       const char *str;
> +     int dcs = 0x0f;
> +     unsigned char buf[256];
> +     unsigned char *converted;
> +     unsigned char *packed = NULL;
> +     long num_packed;
> +     long written;
>  
>       if (ussd->pending)
>               return __ofono_error_busy(msg);
> @@ -510,12 +592,25 @@ static DBusMessage *ussd_respond(DBusConnection *conn, 
> DBusMessage *msg,
>       if (strlen(str) == 0)
>               return __ofono_error_invalid_format(msg);
>  
> +     converted = convert_utf8_to_gsm(str, strlen(str), NULL, &written, 0);
> +     if (!converted)
> +             return __ofono_error_invalid_format(msg);
> +
> +     packed = pack_7bit_own_buf(converted, written, 0, TRUE,
> +                                     &num_packed, 0, buf);
> +
> +     g_free(converted);
> +
> +     if (num_packed > OFONO_MAX_USSD_LENGTH)
> +             return __ofono_error_invalid_args(msg);
> +
>       if (!ussd->driver->request)
>               return __ofono_error_not_implemented(msg);
>  
>       ussd->pending = dbus_message_ref(msg);
>  
> -     ussd->driver->request(ussd, str, ussd_response_callback, ussd);
> +     ussd->driver->request(ussd, dcs, packed, (int) num_packed,
> +                             ussd_response_callback, ussd);
>  
>       return NULL;
>  }
> @@ -543,6 +638,9 @@ static void ussd_cancel_callback(const struct ofono_error 
> *error, void *data)
>       reply = dbus_message_new_method_return(ussd->cancel);
>       __ofono_dbus_pending_reply(&ussd->cancel, reply);
>  
> +     if (ussd->req)
> +             ussd_request_finish(ussd, -1, USSD_STATE_USER_ACTION, NULL, -1);
> +
>       ussd_change_state(ussd, USSD_STATE_IDLE);
>  }
>  
> @@ -741,3 +839,46 @@ void *ofono_ussd_get_data(struct ofono_ussd *ussd)
>  {
>       return ussd->driver_data;
>  }
> +
> +static void ussd_request_callback(const struct ofono_error *error, void 
> *data)
> +{
> +     struct ofono_ussd *ussd = data;
> +
> +     if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
> +             ussd_request_finish(ussd, OFONO_USSD_FAILURE_RETURN_ERROR, -1, 
> NULL, -1);
> +     else
> +             ussd_change_state(ussd,USSD_STATE_ACTIVE);
> +}
> +
> +gboolean __ofono_ussd_is_busy(struct ofono_ussd *ussd)
> +{
> +     if (ussd->pending || ussd->state != USSD_STATE_IDLE || ussd->req)
> +             return TRUE;
> +
> +     return FALSE;
> +}
> +
> +int __ofono_ussd_initiate(struct ofono_ussd *ussd, int dcs,
> +                             const unsigned char *binary_data,
> +                             int binary_data_len,
> +                             ofono_ussd_request_cb_t cb, void *user_data)
> +{
> +     struct ussd_request *req;
> +
> +     if (!ussd->driver->request)
> +             return -ENOSYS;
> +
> +     req = g_try_new0(struct ussd_request, 1);
> +     req->dcs = dcs;
> +     req->str = g_memdup(binary_data, binary_data_len);
> +     req->str_len = binary_data_len;
> +     req->cb = cb;
> +     req->user_data = user_data;
> +
> +     ussd->req = req;
> +
> +     ussd->driver->request(ussd, dcs, binary_data, binary_data_len,
> +                             ussd_request_callback, ussd);
> +
> +     return 0;
> +}

Otherwise it looks fine, but I'll have to perform another round of
reviews once you separate out the driver changes from
ofono_ussd_initiate changes.

Regards,
-Denis
_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono

Reply via email to