Return-Path: Message-ID: <4B66474F.4030608@intel.com> Date: Mon, 01 Feb 2010 11:15:27 +0800 From: Zhenhua Zhang MIME-Version: 1.0 To: "ofono@ofono.org" , "Gustavo F. Padovan" CC: "linux-bluetooth@vger.kernel.org" Subject: Re: [PATCH 1/2] clean up audio/gateway.c References: <1264619569-12448-1-git-send-email-padovan@profusion.mobi> <1264619569-12448-2-git-send-email-padovan@profusion.mobi> In-Reply-To: <1264619569-12448-2-git-send-email-padovan@profusion.mobi> Content-Type: text/plain; charset=UTF-8; format=flowed Sender: linux-bluetooth-owner@vger.kernel.org List-ID: Hi Padovan, On 01/28/2010 03:12 AM, Gustavo F. Padovan wrote: > remove all code related to the AT engine > --- > audio/gateway.c | 760 +------------------------------------------------------ > 1 files changed, 1 insertions(+), 759 deletions(-) > > diff --git a/audio/gateway.c b/audio/gateway.c > index a1c1ea2..3dc09ff 100644 > --- a/audio/gateway.c > +++ b/audio/gateway.c > @@ -53,52 +53,6 @@ > #include "dbus-common.h" > > I cannot apply your patch locally. Below is the error: zzhan17@zzhan17-mobl:~/bluez$ git apply clean_up_audio_gateway.c.patch error: patch failed: audio/gateway.c:53 error: audio/gateway.c: patch does not apply Does any one have the same issue? Thanks. > #define RFCOMM_BUF_SIZE 256 > -/* not-more-then-16 defined by GSM + 1 for NULL + padding */ > -#define AG_INDICATOR_DESCR_SIZE 20 > -#define AG_CALLER_NUM_SIZE 64 /* size of number + type */ > - > -/* commands */ > -#define AG_FEATURES "AT+BRSF=26\r" /* = 0x7F = All features supported */ > -#define AG_INDICATORS_SUPP "AT+CIND=?\r" > -#define AG_INDICATORS_VAL "AT+CIND?\r" > -#define AG_INDICATORS_ENABLE "AT+CMER=3,0,0,1\r" > -#define AG_HOLD_MPTY_SUPP "AT+CHLD=?\r" > -#define AG_CALLER_IDENT_ENABLE "AT+CLIP=1\r" > -#define AG_CARRIER_FORMAT "AT+COPS=3,0\r" > -#define AG_EXTENDED_RESULT_CODE "AT+CMEE=1\r" > - > -#define AG_FEATURE_3WAY 0x1 > -#define AG_FEATURE_EXTENDED_RES_CODE 0x100 > -/* Hold and multipary AG features. > - * Comments below are copied from hands-free spec for reference */ > -/* Releases all held calls or sets User Determined User Busy (UDUB) > - * for a waiting call */ > -#define AG_CHLD_0 0x01 > -/* Releases all active calls (if any exist) and accepts the other > - * (held or waiting) call */ > -#define AG_CHLD_1 0x02 > -/* Releases specified active call only */ > -#define AG_CHLD_1x 0x04 > -/* Places all active calls (if any exist) on hold and accepts the other > - * (held or waiting) call */ > -#define AG_CHLD_2 0x08 > -/* Request private consultation mode with specified call (Place all > - * calls on hold EXCEPT the call) */ > -#define AG_CHLD_2x 0x10 > -/* Adds a held call to the conversation */ > -#define AG_CHLD_3 0x20 > -/* Connects the two calls and disconnects the subscriber from both calls > - * (Explicit Call Transfer). Support for this value and its associated > - * functionality is optional for the HF. */ > -#define AG_CHLD_4 0x40 > - > -#define OK_RESPONSE "\r\nOK\r\n" > -#define ERROR_RESPONSE "\r\nERROR\r\n" > - > -struct indicator { > - gchar descr[AG_INDICATOR_DESCR_SIZE]; > - gint value; > -}; > > struct gateway { > gateway_state_t state; > @@ -108,387 +62,10 @@ struct gateway { > gateway_stream_cb_t sco_start_cb; > void *sco_start_cb_data; > DBusMessage *connect_message; > - guint ag_features; > - guint hold_multiparty_features; > - GSList *indies; > - gboolean is_dialing; > - gboolean call_active; > - > - int sp_gain; > - int mic_gain; > }; > > -static gboolean rfcomm_ag_data_cb(GIOChannel *chan, GIOCondition cond, > - struct audio_device *device); > - > int gateway_close(struct audio_device *device); > > -static void rfcomm_start_watch(struct audio_device *dev) > -{ > - struct gateway *gw = dev->gateway; > - > - gw->rfcomm_watch_id = g_io_add_watch(gw->rfcomm, > - G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, > - (GIOFunc) rfcomm_ag_data_cb, dev); > -} > - > -static void rfcomm_stop_watch(struct audio_device *dev) > -{ > - struct gateway *gw = dev->gateway; > - > - g_source_remove(gw->rfcomm_watch_id); > -} > - > -static gboolean io_channel_write_all(GIOChannel *io, gchar *data, > - gsize count) > -{ > - gsize written = 0; > - GIOStatus status; > - > - while (count> 0) { > - status = g_io_channel_write_chars(io, data, count,&written, > - NULL); > - if (status != G_IO_STATUS_NORMAL) > - return FALSE; > - > - data += written; > - count -= written; > - } > - return TRUE; > -} > - > -/* it's worth to mention that data and response could be the same pointers */ > -static gboolean rfcomm_send_and_read(struct gateway *gw, gchar *data, > - gchar *response, gsize count) > -{ > - GIOChannel *rfcomm = gw->rfcomm; > - gsize read = 0; > - gboolean got_ok = FALSE; > - gboolean got_error = FALSE; > - gchar *resp_buf = response; > - gsize toread = RFCOMM_BUF_SIZE - 1; > - GIOStatus status; > - > - if (!io_channel_write_all(rfcomm, data, count)) > - return FALSE; > - > - while (!(got_ok || got_error)) { > - status = g_io_channel_read_chars(rfcomm, resp_buf, toread, > -&read, NULL); > - if (status == G_IO_STATUS_NORMAL) > - resp_buf[read] = '\0'; > - else { > - debug("rfcomm_send_and_read(): %m"); > - return FALSE; > - } > - got_ok = NULL != strstr(resp_buf, OK_RESPONSE); > - got_error = NULL != strstr(resp_buf, ERROR_RESPONSE); > - resp_buf += read; > - toread -= read; > - } > - return TRUE; > -} > - > -/* get from the names: (, ()), (, ()) > - * ... */ > -static GSList *parse_indicator_names(gchar *names, GSList *indies) > -{ > - gchar *current = names - 1; > - GSList *result = indies; > - gchar *next; > - struct indicator *ind; > - > - while (current != NULL) { > - current += 2; > - next = strstr(current, ",("); > - ind = g_slice_new(struct indicator); > - strncpy(ind->descr, current, 20); > - ind->descr[(intptr_t) next - (intptr_t) current] = '\0'; > - result = g_slist_append(result, (gpointer) ind); > - current = strstr(next + 1, ",("); > - } > - return result; > -} > - > -/* get values from,,... */ > -static GSList *parse_indicator_values(gchar *values, GSList *indies) > -{ > - gint val; > - gchar *current = values - 1; > - GSList *runner = indies; > - struct indicator *ind; > - > - while (current != NULL) { > - current += 1; > - sscanf(current, "%d",&val); > - current = strchr(current, ','); > - ind = g_slist_nth_data(runner, 0); > - ind->value = val; > - runner = g_slist_next(runner); > - } > - return indies; > -} > - > -/* get values from,,... */ > -static guint get_hold_mpty_features(gchar *features) > -{ > - guint result = 0; > - > - if (strstr(features, "0")) > - result |= AG_CHLD_0; > - > - if (strstr(features, "1")) > - result |= AG_CHLD_1; > - > - if (strstr(features, "1x")) > - result |= AG_CHLD_1x; > - > - if (strstr(features, "2")) > - result |= AG_CHLD_2; > - > - if (strstr(features, "2x")) > - result |= AG_CHLD_2x; > - > - if (strstr(features, "3")) > - result |= AG_CHLD_3; > - > - if (strstr(features, "4")) > - result |= AG_CHLD_4; > - > - return result; > -} > - > -static gboolean establish_service_level_conn(struct gateway *gw) > -{ > - gchar buf[RFCOMM_BUF_SIZE]; > - gboolean res; > - > - debug("at the begin of establish_service_level_conn()"); > - res = rfcomm_send_and_read(gw, AG_FEATURES, buf, > - sizeof(AG_FEATURES) - 1); > - if (!res || sscanf(buf, "\r\n+BRSF:%d",&gw->ag_features) != 1) > - return FALSE; > - > - debug("features are 0x%X", gw->ag_features); > - res = rfcomm_send_and_read(gw, AG_INDICATORS_SUPP, buf, > - sizeof(AG_INDICATORS_SUPP) - 1); > - if (!res || !strstr(buf, "+CIND:")) > - return FALSE; > - > - gw->indies = parse_indicator_names(strchr(buf, '('), NULL); > - > - res = rfcomm_send_and_read(gw, AG_INDICATORS_VAL, buf, > - sizeof(AG_INDICATORS_VAL) - 1); > - if (!res || !strstr(buf, "+CIND:")) > - return FALSE; > - > - gw->indies = parse_indicator_values(strchr(buf, ':') + 1, gw->indies); > - > - res = rfcomm_send_and_read(gw, AG_INDICATORS_ENABLE, buf, > - sizeof(AG_INDICATORS_ENABLE) - 1); > - if (!res || !strstr(buf, "OK")) > - return FALSE; > - > - if ((gw->ag_features& AG_FEATURE_3WAY) != 0) { > - res = rfcomm_send_and_read(gw, AG_HOLD_MPTY_SUPP, buf, > - sizeof(AG_HOLD_MPTY_SUPP) - 1); > - if (!res || !strstr(buf, "+CHLD:")) { > - g_slice_free1(RFCOMM_BUF_SIZE, buf); > - return FALSE; > - } > - gw->hold_multiparty_features = get_hold_mpty_features( > - strchr(buf, '(')); > - > - } else > - gw->hold_multiparty_features = 0; > - > - debug("Service layer connection successfully established!"); > - rfcomm_send_and_read(gw, AG_CALLER_IDENT_ENABLE, buf, > - sizeof(AG_CALLER_IDENT_ENABLE) - 1); > - rfcomm_send_and_read(gw, AG_CARRIER_FORMAT, buf, > - sizeof(AG_CARRIER_FORMAT) - 1); > - if ((gw->ag_features& AG_FEATURE_EXTENDED_RES_CODE) != 0) > - rfcomm_send_and_read(gw, AG_EXTENDED_RESULT_CODE, buf, > - sizeof(AG_EXTENDED_RESULT_CODE) - 1); > - > - return TRUE; > -} > - > -static void process_ind_change(struct audio_device *dev, guint index, > - gint value) > -{ > - struct gateway *gw = dev->gateway; > - struct indicator *ind = g_slist_nth_data(gw->indies, index - 1); > - gchar *name = ind->descr; > - > - ind->value = value; > - > - debug("at the begin of process_ind_change, name is %s", name); > - if (!strcmp(name, "\"call\"")) { > - if (value> 0) { > - g_dbus_emit_signal(dev->conn, dev->path, > - AUDIO_GATEWAY_INTERFACE, > - "CallStarted", DBUS_TYPE_INVALID); > - gw->is_dialing = FALSE; > - gw->call_active = TRUE; > - } else { > - g_dbus_emit_signal(dev->conn, dev->path, > - AUDIO_GATEWAY_INTERFACE, > - "CallEnded", DBUS_TYPE_INVALID); > - gw->call_active = FALSE; > - } > - > - } else if (!strcmp(name, "\"callsetup\"")) { > - if (value == 0&& gw->is_dialing) { > - g_dbus_emit_signal(dev->conn, dev->path, > - AUDIO_GATEWAY_INTERFACE, > - "CallTerminated", > - DBUS_TYPE_INVALID); > - gw->is_dialing = FALSE; > - } else if (!gw->is_dialing&& value> 0) > - gw->is_dialing = TRUE; > - > - } else if (!strcmp(name, "\"callheld\"")) { > - /* FIXME: The following code is based on assumptions only. > - * Has to be tested for interoperability > - * I assume that callheld=2 would be sent when dial from HF > - * failed in case of 3-way call > - * Unfortunately this path is not covered by the HF spec so > - * the code has to be tested for interop > - */ > - /* '2' means: all calls held, no active calls */ > - if (value == 2) { > - if (gw->is_dialing) { > - g_dbus_emit_signal(dev->conn, dev->path, > - AUDIO_GATEWAY_INTERFACE, > - "CallTerminated", > - DBUS_TYPE_INVALID); > - gw->is_dialing = FALSE; > - } > - } > - } else if (!strcmp(name, "\"service\"")) > - emit_property_changed(dev->conn, dev->path, > - AUDIO_GATEWAY_INTERFACE, "RegistrationStatus", > - DBUS_TYPE_UINT16,&value); > - else if (!strcmp(name, "\"signal\"")) > - emit_property_changed(dev->conn, dev->path, > - AUDIO_GATEWAY_INTERFACE, "SignalStrength", > - DBUS_TYPE_UINT16,&value); > - else if (!strcmp(name, "\"roam\"")) > - emit_property_changed(dev->conn, dev->path, > - AUDIO_GATEWAY_INTERFACE, "RoamingStatus", > - DBUS_TYPE_UINT16,&value); > - else if (!strcmp(name, "\"battchg\"")) > - emit_property_changed(dev->conn, dev->path, > - AUDIO_GATEWAY_INTERFACE, "BatteryCharge", > - DBUS_TYPE_UINT16,&value); > -} > - > -static void process_ring(struct audio_device *device, GIOChannel *chan, > - gchar *buf) > -{ > - gchar number[AG_CALLER_NUM_SIZE]; > - gchar *cli; > - gchar *sep; > - gsize read; > - GIOStatus status; > - > - rfcomm_stop_watch(device); > - status = g_io_channel_read_chars(chan, buf, RFCOMM_BUF_SIZE - 1,&read, NULL); > - if (status != G_IO_STATUS_NORMAL) > - return; > - > - debug("at the begin of process_ring"); > - if (strlen(buf)> AG_CALLER_NUM_SIZE + 10) > - error("process_ring(): buf is too long '%s'", buf); > - else if ((cli = strstr(buf, "\r\n+CLIP"))) { > - if (sscanf(cli, "\r\n+CLIP: \"%s", number) == 1) { > - sep = strchr(number, '"'); > - sep[0] = '\0'; > - > - /* FIXME:signal will be emitted on each RING+CLIP. > - * That's bad */ > - cli = number; > - g_dbus_emit_signal(device->conn, device->path, > - AUDIO_GATEWAY_INTERFACE, "Ring", > - DBUS_TYPE_STRING,&cli, > - DBUS_TYPE_INVALID); > - device->gateway->is_dialing = TRUE; > - } else > - error("process_ring(): '%s' in place of +CLIP after RING", buf); > - > - } > - > - rfcomm_start_watch(device); > -} > - > -static gboolean rfcomm_ag_data_cb(GIOChannel *chan, GIOCondition cond, > - struct audio_device *device) > -{ > - gchar buf[RFCOMM_BUF_SIZE]; > - struct gateway *gw; > - gsize read; > - /* some space for value */ > - gchar indicator[AG_INDICATOR_DESCR_SIZE + 4]; > - gint value; > - guint index; > - gchar *sep; > - > - debug("at the begin of rfcomm_ag_data_cb()"); > - if (cond& G_IO_NVAL) > - return FALSE; > - > - gw = device->gateway; > - > - if (cond& (G_IO_ERR | G_IO_HUP)) { > - debug("connection with remote BT is closed"); > - gateway_close(device); > - return FALSE; > - } > - > - if (g_io_channel_read_chars(chan, buf, sizeof(buf) - 1,&read, NULL) > - != G_IO_STATUS_NORMAL) > - return TRUE; > - buf[read] = '\0'; > - > - if (strlen(buf)> AG_INDICATOR_DESCR_SIZE + 14) > - error("rfcomm_ag_data_cb(): buf is too long '%s'", buf); > - else if (sscanf(buf, "\r\n+CIEV:%s\r\n", indicator) == 1) { > - sep = strchr(indicator, ','); > - sep[0] = '\0'; > - sep += 1; > - index = atoi(indicator); > - value = atoi(sep); > - process_ind_change(device, index, value); > - } else if (strstr(buf, "RING")) > - process_ring(device, chan, buf); > - else if (sscanf(buf, "\r\n+BVRA:%d\r\n",&value) == 1) { > - if (value == 0) > - g_dbus_emit_signal(device->conn, device->path, > - AUDIO_GATEWAY_INTERFACE, > - "VoiceRecognitionActive", > - DBUS_TYPE_INVALID); > - else > - g_dbus_emit_signal(device->conn, device->path, > - AUDIO_GATEWAY_INTERFACE, > - "VoiceRecognitionInactive", > - DBUS_TYPE_INVALID); > - } else if (sscanf(buf, "\r\n+VGS:%d\r\n",&value) == 1) { > - gw->sp_gain = value; > - emit_property_changed(device->conn, device->path, > - AUDIO_GATEWAY_INTERFACE, "SpeakerGain", > - DBUS_TYPE_UINT16,&value); > - } else if (sscanf(buf, "\r\n+VGM:%d\r\n",&value) == 1) { > - gw->mic_gain = value; > - emit_property_changed(device->conn, device->path, > - AUDIO_GATEWAY_INTERFACE, "MicrophoneGain", > - DBUS_TYPE_UINT16,&value); > - } else > - error("rfcomm_ag_data_cb(): read wrong data '%s'", buf); > - > - return TRUE; > -} > - > static gboolean sco_io_cb(GIOChannel *chan, GIOCondition cond, > struct audio_device *dev) > { > @@ -541,7 +118,6 @@ static void rfcomm_connect_cb(GIOChannel *chan, GError *err, > { > struct audio_device *dev = user_data; > struct gateway *gw = dev->gateway; > - DBusMessage *conn_mes = gw->connect_message; > gchar gw_addr[18]; > GIOFlags flags; > > @@ -563,29 +139,6 @@ static void rfcomm_connect_cb(GIOChannel *chan, GError *err, > if (!gw->rfcomm) > gw->rfcomm = g_io_channel_ref(chan); > > - if (establish_service_level_conn(dev->gateway)) { > - gboolean value = TRUE; > - > - debug("%s: Connected to %s", dev->path, gw_addr); > - rfcomm_start_watch(dev); > - if (conn_mes) { > - DBusMessage *reply = > - dbus_message_new_method_return(conn_mes); > - dbus_connection_send(dev->conn, reply, NULL); > - dbus_message_unref(reply); > - dbus_message_unref(conn_mes); > - gw->connect_message = NULL; > - } > - > - gw->state = GATEWAY_STATE_CONNECTED; > - emit_property_changed(dev->conn, dev->path, > - AUDIO_GATEWAY_INTERFACE, > - "Connected", DBUS_TYPE_BOOLEAN,&value); > - return; > - } else > - error("%s: Failed to establish service layer connection to %s", > - dev->path, gw_addr); > - > if (NULL != gw->sco_start_cb) > gw->sco_start_cb(NULL, gw->sco_start_cb_data); > > @@ -732,321 +285,20 @@ static DBusMessage *ag_disconnect(DBusConnection *conn, DBusMessage *msg, > return reply; > } > > -static DBusMessage *process_ag_reponse(DBusMessage *msg, gchar *response) > -{ > - DBusMessage *reply; > - > - > - debug("in process_ag_reponse, response is %s", response); > - if (strstr(response, OK_RESPONSE)) > - reply = dbus_message_new_method_return(msg); > - else { > - /* FIXME: some code should be here to processes errors > - * in better fasion */ > - debug("AG responded with '%s' to %s method call", response, > - dbus_message_get_member(msg)); > - reply = dbus_message_new_error(msg, ERROR_INTERFACE > - ".OperationFailed", > - "Operation failed.See log for details"); > - } > - return reply; > -} > - > -static DBusMessage *process_simple(DBusMessage *msg, struct audio_device *dev, > - gchar *data) > -{ > - struct gateway *gw = dev->gateway; > - gchar buf[RFCOMM_BUF_SIZE]; > - > - rfcomm_stop_watch(dev); > - rfcomm_send_and_read(gw, data, buf, strlen(data)); > - rfcomm_start_watch(dev); > - return process_ag_reponse(msg, buf); > -} > - > -#define AG_ANSWER "ATA\r" > - > -static DBusMessage *ag_answer(DBusConnection *conn, DBusMessage *msg, > - void *data) > -{ > - struct audio_device *dev = data; > - struct gateway *gw = dev->gateway; > - > - if (!gw->rfcomm) > - return g_dbus_create_error(msg, ERROR_INTERFACE > - ".NotConnected", > - "Not Connected"); > - > - if (gw->call_active) > - return g_dbus_create_error(msg, ERROR_INTERFACE > - ".CallAlreadyAnswered", > - "Call AlreadyAnswered"); > - > - return process_simple(msg, dev, AG_ANSWER); > -} > - > -#define AG_HANGUP "AT+CHUP\r" > - > -static DBusMessage *ag_terminate_call(DBusConnection *conn, DBusMessage *msg, > - void *data) > -{ > - struct audio_device *dev = data; > - struct gateway *gw = dev->gateway; > - > - if (!gw->rfcomm) > - return g_dbus_create_error(msg, ERROR_INTERFACE > - ".NotConnected", > - "Not Connected"); > - > - return process_simple(msg, dev, AG_HANGUP); > -} > - > -/* according to GSM spec */ > -#define ALLOWED_NUMBER_SYMBOLS "1234567890*#ABCD" > -#define AG_PLACE_CALL "ATD%s;\r" > -/* dialing from memory is not supported as headset spec doesn't define a way > - * to retreive phone memory entries. > - */ > -static DBusMessage *ag_call(DBusConnection *conn, DBusMessage *msg, > - void *data) > -{ > - struct audio_device *device = data; > - struct gateway *gw = device->gateway; > - gchar buf[RFCOMM_BUF_SIZE]; > - gchar *number; > - gint atd_len; > - DBusMessage *result; > - > - debug("at the begin of ag_call()"); > - if (!gw->rfcomm) > - return g_dbus_create_error(msg, ERROR_INTERFACE > - ".NotConnected", > - "Not Connected"); > - > - dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING,&number, > - DBUS_TYPE_INVALID); > - if (strlen(number) != strspn(number, ALLOWED_NUMBER_SYMBOLS)) > - return dbus_message_new_error(msg, > - ERROR_INTERFACE ".BadNumber", > - "Number contains characters which are not allowed"); > - > - atd_len = sprintf(buf, AG_PLACE_CALL, number); > - rfcomm_stop_watch(device); > - rfcomm_send_and_read(gw, buf, buf, atd_len); > - rfcomm_start_watch(device); > - > - result = process_ag_reponse(msg, buf); > - return result; > -} > - > -#define AG_GET_CARRIER "AT+COPS?\r" > - > -static DBusMessage *ag_get_operator(DBusConnection *conn, DBusMessage *msg, > - void *data) > -{ > - struct audio_device *dev = (struct audio_device *) data; > - struct gateway *gw = dev->gateway; > - gchar buf[RFCOMM_BUF_SIZE]; > - GIOChannel *rfcomm = gw->rfcomm; > - gsize read; > - gchar *result, *sep; > - DBusMessage *reply; > - GIOStatus status; > - > - if (!gw->rfcomm) > - return g_dbus_create_error(msg, ERROR_INTERFACE > - ".NotConnected", > - "Not Connected"); > - > - rfcomm_stop_watch(dev); > - io_channel_write_all(rfcomm, AG_GET_CARRIER, strlen(AG_GET_CARRIER)); > - > - status = g_io_channel_read_chars(rfcomm, buf, RFCOMM_BUF_SIZE - 1, > -&read, NULL); > - rfcomm_start_watch(dev); > - if (G_IO_STATUS_NORMAL == status) { > - buf[read] = '\0'; > - if (strstr(buf, "+COPS")) { > - if (!strrchr(buf, ',')) > - result = "0"; > - else { > - result = strchr(buf, '\"') + 1; > - sep = strchr(result, '\"'); > - sep[0] = '\0'; > - } > - > - reply = dbus_message_new_method_return(msg); > - dbus_message_append_args(reply, DBUS_TYPE_STRING, > -&result, DBUS_TYPE_INVALID); > - } else { > - info("ag_get_operator(): '+COPS' expected but" > - " '%s' received", buf); > - reply = dbus_message_new_error(msg, ERROR_INTERFACE > - ".Failed", > - "Unexpected response from AG"); > - } > - } else { > - error("ag_get_operator(): %m"); > - reply = dbus_message_new_error(msg, ERROR_INTERFACE > - ".ConnectionFailed", > - "Failed to receive response from AG"); > - } > - > - return reply; > -} > - > -#define AG_SEND_DTMF "AT+VTS=%c\r" > -static DBusMessage *ag_send_dtmf(DBusConnection *conn, DBusMessage *msg, > - void *data) > -{ > - struct audio_device *device = data; > - struct gateway *gw = device->gateway; > - gchar buf[RFCOMM_BUF_SIZE]; > - gchar *number; > - gint com_len; > - gboolean got_ok = TRUE; > - gint num_len; > - gint i = 0; > - > - if (!gw->rfcomm) > - return g_dbus_create_error(msg, ERROR_INTERFACE > - ".NotConnected", > - "Not Connected"); > - > - dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING,&number, > - DBUS_TYPE_INVALID); > - if (strlen(number) != strspn(number, ALLOWED_NUMBER_SYMBOLS)) > - return dbus_message_new_error(msg, > - ERROR_INTERFACE ".BadNumber", > - "Number contains characters which are not allowed"); > - > - num_len = strlen(number); > - rfcomm_stop_watch(device); > - while (i< num_len&& got_ok) { > - com_len = sprintf(buf, AG_SEND_DTMF, number[i]); > - rfcomm_send_and_read(gw, buf, buf, com_len); > - got_ok = NULL != strstr(buf, OK_RESPONSE); > - i += 1; > - } > - rfcomm_start_watch(device); > - return process_ag_reponse(msg, buf); > -} > - > -#define AG_GET_SUBSCRIBER_NUMS "AT+CNUM\r" > -#define CNUM_LEN 5 /* length of "+CNUM" string */ > -#define MAX_NUMBER_CNT 16 > -static DBusMessage *ag_get_subscriber_num(DBusConnection *conn, > - DBusMessage *msg, void *data) > -{ > - struct audio_device *device = data; > - struct gateway *gw = device->gateway; > - gchar buf[RFCOMM_BUF_SIZE]; > - gchar *number, *end; > - DBusMessage *reply = dbus_message_new_method_return(msg); > - > - if (!gw->rfcomm) > - return g_dbus_create_error(msg, ERROR_INTERFACE > - ".NotConnected", > - "Not Connected"); > - > - rfcomm_stop_watch(device); > - rfcomm_send_and_read(gw, AG_GET_SUBSCRIBER_NUMS, buf, > - strlen(AG_GET_SUBSCRIBER_NUMS)); > - rfcomm_start_watch(device); > - > - if (strlen(buf)> AG_CALLER_NUM_SIZE + 21) > - error("ag_get_subscriber_num(): buf is too long '%s'", buf); > - else if (strstr(buf, "+CNUM")) { > - number = strchr(buf, ','); > - number++; > - end = strchr(number, ','); > - if (end) { > - *end = '\0'; > - dbus_message_append_args(reply, DBUS_TYPE_STRING, > -&number, DBUS_TYPE_INVALID); > - } > - } else > - error("ag_get_subscriber_num(): read wrong data '%s'", buf); > - > - return reply; > -} > - > static DBusMessage *ag_get_properties(DBusConnection *conn, DBusMessage *msg, > void *data) > { > - struct audio_device *device = data; > - struct gateway *gw = device->gateway; > - DBusMessage *reply; > - DBusMessageIter iter; > - DBusMessageIter dict; > - gboolean value; > - guint index = 0; > - struct indicator *ind; > - > - reply = dbus_message_new_method_return(msg); > - if (!reply) > - return NULL; > - > - dbus_message_iter_init_append(reply,&iter); > - > - dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, > - DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING > - DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING > - DBUS_DICT_ENTRY_END_CHAR_AS_STRING,&dict); > - > - /* Connected */ > - value = gateway_is_connected(device); > - dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN,&value); > - > - if (!value) > - goto done; > - > - while ((ind = g_slist_nth_data(gw->indies, index))) { > - if(!strcmp(ind->descr, "\"service\"")) > - dict_append_entry(&dict, "RegistrationStatus", > - DBUS_TYPE_UINT16,&ind->value); > - else if (!strcmp(ind->descr, "\"signal\"")) > - dict_append_entry(&dict, "SignalStrength", > - DBUS_TYPE_UINT16,&ind->value); > - else if (!strcmp(ind->descr, "\"roam\"")) > - dict_append_entry(&dict, "RoamingStatus", > - DBUS_TYPE_UINT16,&ind->value); > - else if (!strcmp(ind->descr, "\"battchg\"")) > - dict_append_entry(&dict, "BatteryCharge", > - DBUS_TYPE_UINT16,&ind->value); > - index++; > - } > - > - /* SpeakerGain */ > - dict_append_entry(&dict, "SpeakerGain", DBUS_TYPE_UINT16, > -&device->gateway->sp_gain); > - > - /* MicrophoneGain */ > - dict_append_entry(&dict, "MicrophoneGain", DBUS_TYPE_UINT16, > -&device->gateway->mic_gain); > -done: > - dbus_message_iter_close_container(&iter,&dict); > - return reply; > + return NULL; > } > > static GDBusMethodTable gateway_methods[] = { > { "Connect", "", "", ag_connect, G_DBUS_METHOD_FLAG_ASYNC }, > { "Disconnect", "", "", ag_disconnect }, > - { "AnswerCall", "", "", ag_answer }, > - { "TerminateCall", "", "", ag_terminate_call }, > - { "Call", "s", "", ag_call }, > - { "GetOperatorName", "", "s", ag_get_operator }, > - { "SendDTMF", "s", "", ag_send_dtmf }, > - { "GetSubscriberNumber", "", "s", ag_get_subscriber_num }, > { "GetProperties", "", "a{sv}", ag_get_properties }, > { NULL, NULL, NULL, NULL } > }; > > static GDBusSignalTable gateway_signals[] = { > - { "Ring", "s" }, > - { "CallTerminated", "" }, > - { "CallStarted", "" }, > - { "CallEnded", "" }, > { "PropertyChanged", "sv" }, > { NULL, NULL } > }; > @@ -1063,9 +315,6 @@ struct gateway *gateway_init(struct audio_device *dev) > > debug("in gateway_init, dev is %p", dev); > gw = g_new0(struct gateway, 1); > - gw->indies = NULL; > - gw->is_dialing = FALSE; > - gw->call_active = FALSE; > gw->state = GATEWAY_STATE_DISCONNECTED; > return gw; > > @@ -1107,11 +356,6 @@ void gateway_start_service(struct audio_device *device) > rfcomm_connect_cb(device->gateway->rfcomm, NULL, device); > } > > -static void indicator_slice_free(gpointer mem) > -{ > - g_slice_free(struct indicator, mem); > -} > - > int gateway_close(struct audio_device *device) > { > struct gateway *gw = device->gateway; > @@ -1119,8 +363,6 @@ int gateway_close(struct audio_device *device) > GIOChannel *sco = gw->sco; > gboolean value = FALSE; > > - g_slist_foreach(gw->indies, (GFunc) indicator_slice_free, NULL); > - g_slist_free(gw->indies); > if (rfcomm) { > g_io_channel_shutdown(rfcomm, TRUE, NULL); > g_io_channel_unref(rfcomm); > -- > 1.6.4.4 > > _______________________________________________ > ofono mailing list > ofono@ofono.org > http://lists.ofono.org/listinfo/ofono > >