org.bluez.audio.headset.Connect() to handsfree
PATCH 1/1 org.bluez.audio.headset.Connect() to handsfree
Hello,
As of today, when calling org.bluez.audio.headset.Connect(), the hfp profile is searched only if the headset->hfp_handle is initialized. This member variable is initialized upon CreateDevice the first time the device is created (during resolve_services).
The variable is not initialized when the audio service is restarted, so after restarting audio service, it is no longer possible to connect to hfp.
The attached patch fix the problem as follow : first search the hfp profile handle, then search an hsp profile handle, by getting rfcomm channel to connect to.
It is based against latest git tree.
Frederic.
-------------------------------------------------------------------------
SF.Net email is sponsored by: The Future of Linux Business White Paper from Novell. From the desktop to the data center, Linux is going mainstream. Let it simplify your IT future.
http://altfarm.mediaplex.com/ad/ck/8857-50307-18918-4
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel
Here is the patch. :/
Frederic
Quoted 13 lines · Frédéric Dalleau
Hello,
As of today, when calling
org.bluez.audio.headset.Connect(), the hfp profile is searched only if theheadset->hfp_handleis initialized. This member variable is initialized upon CreateDevice the first time the device is created (duringresolve_services).
The variable is not initialized when the audio service is restarted, so after restarting audio service, it is no longer possible to connect to hfp.The attached patch fix the problem as follow : first search the hfp profile handle, then search an hsp profile handle, by getting rfcomm channel to connect to.
It is based against latest git tree.
Frederic.
Quoted 10 lines
-------------------------------------------------------------------------
SF.Net email is sponsored by: The Future of Linux Business White Paper from Novell. From the desktop to the data center, Linux is going mainstream. Let it simplify your IT future.
http://altfarm.mediaplex.com/ad/ck/8857-50307-18918-4
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel
audio/headset.c +27 -5
@@ -111,6 +111,7 @@ struct headset { };static int rfcomm_connect (struct device *device,struct pending_connect *c); +static int get_handles (struct device *device,struct pending_connect *c);static void pending_connect_free (struct pending_connect *c) {
@@ -640,11 +641,21 @@ static void get_record_reply(DBusPendingCall *call, void *data) goto failed_not_supported; } -if ((uuid.type ==SDP_UUID32 && +if (hs->type ==SVC_HEADSET && + ((uuid.type ==SDP_UUID32 && uuid.value.uuid32 !=HEADSET_SVCLASS_ID ) || (uuid.type ==SDP_UUID16 && - uuid.value.uuid16 !=HEADSET_SVCLASS_ID )) { -error ("Service classes did not contain the expected UUID" ); + uuid.value.uuid16 !=HEADSET_SVCLASS_ID ))) { +error ("Service classes did not contain the expected UUID for hsp" ); + goto failed_not_supported; + } + +if (hs->type ==SVC_HANDSFREE && + ((uuid.type ==SDP_UUID32 && + uuid.value.uuid32 !=HANDSFREE_SVCLASS_ID ) || + (uuid.type ==SDP_UUID16 && + uuid.value.uuid16 !=HANDSFREE_SVCLASS_ID ))) { +error ("Service classes did not contain the expected UUID for hfp" ); goto failed_not_supported; }
@@ -750,7 +761,17 @@ static void get_handles_reply(DBusPendingCall *call, void *data) }if (array_len <1 ) { -debug ("No record handles found" ); + +if (hs->type ==SVC_HANDSFREE ) { +debug ("No record handles found for hfp" ); + hs->type =SVC_HEADSET ; +get_handles (device, c); +dbus_message_unref (reply); +return ; + } + +debug ("No record handles found for hsp" ); +if (c->msg)error_not_supported (device->conn, c->msg); goto failed;
@@ -785,6 +806,7 @@ static void get_handles_reply(DBusPendingCall *call, void *data) }dbus_pending_call_set_notify (pending, get_record_reply, device,NULL ); +dbus_pending_call_unref (pending);dbus_message_unref (msg);dbus_message_unref (reply);
@@ -862,7 +884,7 @@ static int rfcomm_connect(struct device *device, struct pending_connect *c)if (!g_slist_find (hs->pending, c)) hs->pending =g_slist_append (hs->pending, c); - hs->type = hs->hfp_handle ?SVC_HANDSFREE :SVC_HEADSET ; + hs->type =SVC_HANDSFREE ;if (hs->state ==HEADSET_STATE_DISCONNECTED )return get_handles (device, c);
-------------------------------------------------------------------------
SF.Net email is sponsored by: The Future of Linux Business White Paper from Novell. From the desktop to the data center, Linux is going mainstream. Let it simplify your IT future.
http://altfarm.mediaplex.com/ad/ck/8857-50307-18918-4
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel
Marcel Holtmann
maintainerHi Frederic,
Quoted 6 lines
As of today, when calling
org.bluez.audio.headset.Connect(), the hfp profile is searched only if theheadset->hfp_handleis initialized. This member variable is initialized upon CreateDevice the first time the device is created (duringresolve_services).
The variable is not initialized when the audio service is restarted, so after restarting audio service, it is no longer possible to connect to hfp.
we had to disable HFP with a config setting since we are not fully supporting it at the moment. So this must depend on the config setting if we search for HFP and if we consider it for the connect. By default we only support HSP.
Regards
Marcel
-------------------------------------------------------------------------
SF.Net email is sponsored by: The Future of Linux Business White Paper from Novell. From the desktop to the data center, Linux is going mainstream. Let it simplify your IT future.
http://altfarm.mediaplex.com/ad/ck/8857-50307-18918-4
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel
Right!
Here is an updated patch. It adds a parameter to headset_init() to know whether hfp is enabled or not.
Let me know what you think,
Regards,
Frederic
Quoted 20 lines · Marcel Holtmann
Hi Frederic,
Quoted 4 lines
As of today, when calling
org.bluez.audio.headset.Connect(), the hfp profile is searched only if theheadset->hfp_handleis initialized. This member variable is initialized upon CreateDevice the first time the device is created (duringresolve_services).
The variable is not initialized when the audio service is restarted, so after restarting audio service, it is no longer possible to connect to hfp.we had to disable HFP with a config setting since we are not fully supporting it at the moment. So this must depend on the config setting if we search for HFP and if we consider it for the connect. By default we only support HSP.
Regards
Marcel
Quoted 10 lines
-------------------------------------------------------------------------
SF.Net email is sponsored by: The Future of Linux Business White Paper from Novell. From the desktop to the data center, Linux is going mainstream. Let it simplify your IT future.
http://altfarm.mediaplex.com/ad/ck/8857-50307-18918-4
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel
audio/headset.c +30 -7
@@ -99,6 +99,7 @@ struct headset {int data_start;int data_length; +int enable_hfp;headset_type_t type;headset_state_t state;
@@ -111,6 +112,7 @@ struct headset { };static int rfcomm_connect (struct device *device,struct pending_connect *c); +static int get_handles (struct device *device,struct pending_connect *c);static void pending_connect_free (struct pending_connect *c) {
@@ -640,11 +642,21 @@ static void get_record_reply(DBusPendingCall *call, void *data) goto failed_not_supported; } -if ((uuid.type ==SDP_UUID32 && +if (hs->type ==SVC_HEADSET && + ((uuid.type ==SDP_UUID32 && uuid.value.uuid32 !=HEADSET_SVCLASS_ID ) || (uuid.type ==SDP_UUID16 && - uuid.value.uuid16 !=HEADSET_SVCLASS_ID )) { -error ("Service classes did not contain the expected UUID" ); + uuid.value.uuid16 !=HEADSET_SVCLASS_ID ))) { +error ("Service classes did not contain the expected UUID hsp" ); + goto failed_not_supported; + } + +if (hs->type ==SVC_HANDSFREE && + ((uuid.type ==SDP_UUID32 && + uuid.value.uuid32 !=HANDSFREE_SVCLASS_ID ) || + (uuid.type ==SDP_UUID16 && + uuid.value.uuid16 !=HANDSFREE_SVCLASS_ID ))) { +error ("Service classes did not contain the expected UUID hfp" ); goto failed_not_supported; }
@@ -750,7 +762,17 @@ static void get_handles_reply(DBusPendingCall *call, void *data) }if (array_len <1 ) { -debug ("No record handles found" ); + +if (hs->type ==SVC_HANDSFREE ) { +debug ("No record handles found for hfp" ); + hs->type =SVC_HEADSET ; +get_handles (device, c); +dbus_message_unref (reply); +return ; + } + +debug ("No record handles found for hsp" ); +if (c->msg)error_not_supported (device->conn, c->msg); goto failed;
@@ -862,7 +884,7 @@ static int rfcomm_connect(struct device *device, struct pending_connect *c)if (!g_slist_find (hs->pending, c)) hs->pending =g_slist_append (hs->pending, c); - hs->type = hs->hfp_handle ?SVC_HANDSFREE :SVC_HEADSET ; + hs->type = hs->enable_hfp ?SVC_HANDSFREE :SVC_HEADSET ;if (hs->state ==HEADSET_STATE_DISCONNECTED )return get_handles (device, c);
@@ -1368,8 +1390,8 @@ void headset_update(struct device *dev, sdp_record_t *record, uint16_t svc)headset_set_channel (headset, record); } -struct headset *headset_init (struct device *dev,sdp_record_t *record, -uint16_t svc) +struct headset *headset_init (struct device *dev,int enable_hfp, +sdp_record_t *record,uint16_t svc) {struct headset *hs;
@@ -1377,6 +1399,7 @@ struct headset *headset_init(struct device *dev, sdp_record_t *record, hs->rfcomm_ch =-1 ; hs->sp_gain =-1 ; hs->mic_gain =-1 ; + hs->enable_hfp = enable_hfp;if (!record) goto register_iface;
audio/headset.h +2 -2
@@ -54,8 +54,8 @@ typedef enum {typedef void (*headset_stream_cb_t ) (struct device *dev,void *user_data); -struct headset *headset_init (struct device *dev,sdp_record_t *record, -uint16_t svc); +struct headset *headset_init (struct device *dev,int enable_hfp, +sdp_record_t *record,uint16_t svc);void headset_free (struct device *dev);
audio/manager.c +8 -3
@@ -108,6 +108,7 @@ static GIOChannel *hs_server = NULL;static GIOChannel *hf_server =NULL ;static const struct enabled_interfaces *enabled; +static gboolean enable_hfp = FALSE;static void get_next_record (struct audio_sdp_data *data); static DBusHandlerResult get_handles(const char *uuid,
@@ -213,7 +214,7 @@ done:return uuid16; } -static gboolean server_is_enabled (uint16_t svc) +gboolean server_is_enabled (uint16_t svc) {gboolean ret;
@@ -254,6 +255,7 @@ static void handle_record(sdp_record_t *record, struct device *device)headset_update (device, record, uuid16); else device->headset = headset_init(device, + enable_hfp, record, uuid16);break ;case HEADSET_AGW_SVCLASS_ID :
@@ -265,6 +267,7 @@ static void handle_record(sdp_record_t *record, struct device *device)headset_update (device, record, uuid16); else device->headset = headset_init(device, + enable_hfp, record, uuid16);break ;case HANDSFREE_AGW_SVCLASS_ID :
@@ -645,7 +648,7 @@ struct device *manager_device_connected(bdaddr_t *bda, const char *uuid)if (device->headset)return device; - device->headset =headset_init (device,NULL ,0 ); + device->headset =headset_init (device, enable_hfp,NULL ,0 );if (!device->headset)return NULL ;
@@ -1070,7 +1073,7 @@ static void parse_stored_devices(char *key, char *value, void *data)bacpy (&device->store, src);if (enabled->headset &&strstr (value,"headset" )) - device->headset =headset_init (device,NULL ,0 ); + device->headset =headset_init (device, enable_hfp,NULL ,0 );if (enabled->sink &&strstr (value,"sink" )) device->sink =sink_init (device);if (enabled->control &&strstr (value,"control" ))
@@ -1561,6 +1564,8 @@ static int headset_server_init(DBusConnection *conn, gboolean no_hfp)if (no_hfp)return 0 ; + enable_hfp = TRUE; + chan =DEFAULT_HF_AG_CHANNEL ; hf_server =server_socket (&chan);
-------------------------------------------------------------------------
SF.Net email is sponsored by: The Future of Linux Business White Paper from Novell. From the desktop to the data center, Linux is going mainstream. Let it simplify your IT future.
http://altfarm.mediaplex.com/ad/ck/8857-50307-18918-4
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel
Quoted 9 lines
Here is an updated patch. It adds a parameter to
headset_init()to know whether hfp is enabled or not.Quoted 5 lines · Marcel Holtmann
Hi Frederic,
Quoted 1 line
As of today, when calling
org.bluez.audio.headset.Connect(), the hfpSo this must depend on the config setting
Updated again, do not remove the static attribute in front of server_is_enabled().
Frederic
audio/headset.c +30 -7
@@ -99,6 +99,7 @@ struct headset {int data_start;int data_length; +int enable_hfp;headset_type_t type;headset_state_t state;
@@ -111,6 +112,7 @@ struct headset { };static int rfcomm_connect (struct device *device,struct pending_connect *c); +static int get_handles (struct device *device,struct pending_connect *c);static void pending_connect_free (struct pending_connect *c) {
@@ -640,11 +642,21 @@ static void get_record_reply(DBusPendingCall *call, void *data) goto failed_not_supported; } -if ((uuid.type ==SDP_UUID32 && +if (hs->type ==SVC_HEADSET && + ((uuid.type ==SDP_UUID32 && uuid.value.uuid32 !=HEADSET_SVCLASS_ID ) || (uuid.type ==SDP_UUID16 && - uuid.value.uuid16 !=HEADSET_SVCLASS_ID )) { -error ("Service classes did not contain the expected UUID" ); + uuid.value.uuid16 !=HEADSET_SVCLASS_ID ))) { +error ("Service classes did not contain the expected UUID hsp" ); + goto failed_not_supported; + } + +if (hs->type ==SVC_HANDSFREE && + ((uuid.type ==SDP_UUID32 && + uuid.value.uuid32 !=HANDSFREE_SVCLASS_ID ) || + (uuid.type ==SDP_UUID16 && + uuid.value.uuid16 !=HANDSFREE_SVCLASS_ID ))) { +error ("Service classes did not contain the expected UUID hfp" ); goto failed_not_supported; }
@@ -750,7 +762,17 @@ static void get_handles_reply(DBusPendingCall *call, void *data) }if (array_len <1 ) { -debug ("No record handles found" ); + +if (hs->type ==SVC_HANDSFREE ) { +debug ("No record handles found for hfp" ); + hs->type =SVC_HEADSET ; +get_handles (device, c); +dbus_message_unref (reply); +return ; + } + +debug ("No record handles found for hsp" ); +if (c->msg)error_not_supported (device->conn, c->msg); goto failed;
@@ -862,7 +884,7 @@ static int rfcomm_connect(struct device *device, struct pending_connect *c)if (!g_slist_find (hs->pending, c)) hs->pending =g_slist_append (hs->pending, c); - hs->type = hs->hfp_handle ?SVC_HANDSFREE :SVC_HEADSET ; + hs->type = hs->enable_hfp ?SVC_HANDSFREE :SVC_HEADSET ;if (hs->state ==HEADSET_STATE_DISCONNECTED )return get_handles (device, c);
@@ -1368,8 +1390,8 @@ void headset_update(struct device *dev, sdp_record_t *record, uint16_t svc)headset_set_channel (headset, record); } -struct headset *headset_init (struct device *dev,sdp_record_t *record, -uint16_t svc) +struct headset *headset_init (struct device *dev,int enable_hfp, +sdp_record_t *record,uint16_t svc) {struct headset *hs;
@@ -1377,6 +1399,7 @@ struct headset *headset_init(struct device *dev, sdp_record_t *record, hs->rfcomm_ch =-1 ; hs->sp_gain =-1 ; hs->mic_gain =-1 ; + hs->enable_hfp = enable_hfp;if (!record) goto register_iface;
audio/headset.h +2 -2
@@ -54,8 +54,8 @@ typedef enum {typedef void (*headset_stream_cb_t ) (struct device *dev,void *user_data); -struct headset *headset_init (struct device *dev,sdp_record_t *record, -uint16_t svc); +struct headset *headset_init (struct device *dev,int enable_hfp, +sdp_record_t *record,uint16_t svc);void headset_free (struct device *dev);
audio/manager.c +7 -2
@@ -108,6 +108,7 @@ static GIOChannel *hs_server = NULL;static GIOChannel *hf_server =NULL ;static const struct enabled_interfaces *enabled; +static gboolean enable_hfp = FALSE;static void get_next_record (struct audio_sdp_data *data); static DBusHandlerResult get_handles(const char *uuid,
@@ -254,6 +255,7 @@ static void handle_record(sdp_record_t *record, struct device *device)headset_update (device, record, uuid16); else device->headset = headset_init(device, + enable_hfp, record, uuid16);break ;case HEADSET_AGW_SVCLASS_ID :
@@ -265,6 +267,7 @@ static void handle_record(sdp_record_t *record, struct device *device)headset_update (device, record, uuid16); else device->headset = headset_init(device, + enable_hfp, record, uuid16);break ;case HANDSFREE_AGW_SVCLASS_ID :
@@ -645,7 +648,7 @@ struct device *manager_device_connected(bdaddr_t *bda, const char *uuid)if (device->headset)return device; - device->headset =headset_init (device,NULL ,0 ); + device->headset =headset_init (device, enable_hfp,NULL ,0 );if (!device->headset)return NULL ;
@@ -1070,7 +1073,7 @@ static void parse_stored_devices(char *key, char *value, void *data)bacpy (&device->store, src);if (enabled->headset &&strstr (value,"headset" )) - device->headset =headset_init (device,NULL ,0 ); + device->headset =headset_init (device, enable_hfp,NULL ,0 );if (enabled->sink &&strstr (value,"sink" )) device->sink =sink_init (device);if (enabled->control &&strstr (value,"control" ))
@@ -1561,6 +1564,8 @@ static int headset_server_init(DBusConnection *conn, gboolean no_hfp)if (no_hfp)return 0 ; + enable_hfp = TRUE; + chan =DEFAULT_HF_AG_CHANNEL ; hf_server =server_socket (&chan);
-------------------------------------------------------------------------
SF.Net email is sponsored by:
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel
PATCH 1/1 Service Level Connection for HFP.
Hello,
I am sending a patch for Service Level Connection(SLC) Establishment for the HandsFree Profile. This patch includes:
1. String table mechanism for headset/handsfree events.
2. Callbacks in form of function pointers for the events.
3. Basic event handling for SLC and complete event handling for Headset.
4. Modification in get_record_reply for HFP.
Currently there are no extra signals/methods, for the sake of simplicity.
This patch requires Fredric's 1st patch(dated:07 Dec 2007) to be applied first.
Please let me know if any changes are required.
Thanks,
Alok.
audio/headset.c +109 -94
@@ -108,9 +108,27 @@ struct headset {int sp_gain;int mic_gain; +unsigned int hfp_features;headset_lock_t lock; }; +struct event { +const char *cmd; +int (*callback) (struct device *device,const char *buf); +}; + +static struct event event_callbacks[] = { + {"ATA" , hf_answer_call}, + {"AT+VG" , hs_signal_gain_setting}, + {"AT+BRSF" , hf_supported_features}, + {"AT+CIND" , hf_report_indicators}, + {"AT+CMER" , hf_event_reporting}, + {"AT+CHLD" , hf_call_hold}, + {"AT+CHUP" , hf_terminate_call}, + {"AT+CKPD" , hf_answer_call}, + {0 } +}; +static int rfcomm_connect (struct device *device,struct pending_connect *c);static int get_handles (struct device *device,struct pending_connect *c);
@@ -130,70 +148,114 @@ static void pending_connect_free(struct pending_connect *c)g_free (c); } -static void hs_signal_gain_setting (struct device *device,const char *buf) +int handle_event (struct device *device,const char *buf) +{ +struct event *pt; +debug ("Received %s" , buf); +for (pt = event_callbacks; pt->cmd; pt++) { +if (!strncmp (buf, pt->cmd,strlen (pt->cmd))) +return pt->callback (device, buf); + } +debug ("Invalid Event" ); +return -1 ; +} + +int hf_supported_features (struct device *device,const char *buf) +{ +struct headset *hs = device->headset; + + hs->hfp_features =strtoul (&buf[8 ],NULL ,10 ); +headset_send (hs,"\r\n+BRSF:0\r\n" ); +headset_send (device->headset,"\r\nOK\r\n" ); +return 0 ; +} + +int hf_report_indicators (struct device *device,const char *buf) +{ +struct headset *hs = device->headset; + +if (buf[7 ] =='=' ) +headset_send (hs,"\r\n+CIND:(\"service\",(0,1)),(\"call\",(0,1)),(\"callsetup\",(0-3))\r\n" ); +else +headset_send (hs,"\r\n+CIND:1, 0, 0\r\n" ); +headset_send (device->headset,"\r\nOK\r\n" ); +return 0 ; +} + +int hf_event_reporting (struct device *device,const char *buf) +{ +struct headset *hs = device->headset; + +headset_send (device->headset,"\r\nOK\r\n" ); +return 0 ; +} + +int hf_call_hold (struct device *device,const char *buf) +{ +struct headset *hs = device->headset; + +headset_send (hs,"\r\n+CHLD:(0,1,1x,2,2x,3,4)\r\n" ); +headset_send (device->headset,"\r\nOK\r\n" ); +return 0 ; +} + +int hf_answer_call (struct device *device,const char *buf) +{ +struct headset *hs = device->headset; + +dbus_connection_emit_signal (device->conn, + device->path,AUDIO_HEADSET_INTERFACE ,"AnswerRequested" ,DBUS_TYPE_INVALID ); +headset_send (device->headset,"\r\nOK\r\n" ); +return 0 ; +} + +int hf_terminate_call (struct device *device,const char *buf) +{ +headset_send (device->headset,"\r\nOK\r\n" ); +return 0 ; +} + + +int hs_signal_gain_setting (struct device *device,const char *buf) {const char *name;dbus_uint16_t gain; -if (strlen (buf) <6 ) { +if (strlen (buf) <8 ) {error ("Too short string for Gain setting" ); -return ; +return -1 ; } - gain = (dbus_uint16_t )strtol (&buf[5 ],NULL ,10 ); + gain = (dbus_uint16_t )strtol (&buf[7 ],NULL ,10 );if (gain >15 ) {error ("Invalid gain value received: %u" , gain); -return ; +return -1 ; } -switch (buf[3 ]) { +switch (buf[5 ]) {case HEADSET_GAIN_SPEAKER :if (device->headset->sp_gain == gain) -return ; +break ; name ="SpeakerGainChanged" ; device->headset->sp_gain = gain;break ;case HEADSET_GAIN_MICROPHONE :if (device->headset->mic_gain == gain) -return ; +break ; name ="MicrophoneGainChanged" ; device->headset->mic_gain = gain;break ;default :error ("Unknown gain setting" ); -return ; - } - -dbus_connection_emit_signal (device->conn, device->path, -AUDIO_HEADSET_INTERFACE , name, -DBUS_TYPE_UINT16 , &gain, -DBUS_TYPE_INVALID ); -} - -static headset_event_t parse_headset_event (const char *buf,char *rsp, -int rsp_len) -{ -printf ("Received: %s\n" , buf); - -/* Return an error if this is not a proper AT command */ -if (strncmp (buf,"AT" ,2 )) { -snprintf (rsp, rsp_len,"\r\nERROR\r\n" ); -return HEADSET_EVENT_INVALID ; +return -1 ; } - buf +=2 ; - -if (!strncmp (buf,"+CKPD" ,5 )) { -snprintf (rsp, rsp_len,"\r\nOK\r\n" ); -return HEADSET_EVENT_KEYPRESS ; - }else if (!strncmp (buf,"+VG" ,3 )) { -snprintf (rsp, rsp_len,"\r\nOK\r\n" ); -return HEADSET_EVENT_GAIN ; - }else { -snprintf (rsp, rsp_len,"\r\nERROR\r\n" ); -return HEADSET_EVENT_UNKNOWN ; - } +dbus_connection_emit_signal (device->conn, + device->path, +AUDIO_HEADSET_INTERFACE , name,DBUS_TYPE_UINT16 , &gain,DBUS_TYPE_INVALID ); +headset_send (device->headset,"\r\nOK\r\n" ); +return 0 ; }static void close_sco (struct device *device)
@@ -214,9 +276,9 @@ static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond, {struct headset *hs;unsigned char buf[BUF_SIZE ]; -char *cr, rsp[BUF_SIZE ]; +char *cr;gsize bytes_read =0 ; -gsize free_space, count, bytes_written, total_bytes_written; +gsize free_space;GIOError err;off_t cmd_len;
@@ -256,46 +318,8 @@ static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond, cmd_len =1 + (off_t ) cr - (off_t) &hs->buf[hs->data_start]; *cr ='\0' ; -memset (rsp,0 ,sizeof (rsp)); - -switch (parse_headset_event (&hs->buf[hs->data_start], rsp, -sizeof (rsp))) { -case HEADSET_EVENT_GAIN : -hs_signal_gain_setting (device, &hs->buf[hs->data_start] +2 ); -break ; - -case HEADSET_EVENT_KEYPRESS : -if (hs->ring_timer) { -g_source_remove (hs->ring_timer); - hs->ring_timer =0 ; - } - -dbus_connection_emit_signal (device->conn, device->path, -AUDIO_HEADSET_INTERFACE , -"AnswerRequested" , -DBUS_TYPE_INVALID ); -break ; - -case HEADSET_EVENT_INVALID : -case HEADSET_EVENT_UNKNOWN : -default : -debug ("Unknown headset event" ); -break ; - } - - count =strlen (rsp); - total_bytes_written = bytes_written =0 ; - err =G_IO_ERROR_NONE ; - -while (err ==G_IO_ERROR_NONE && total_bytes_written < count) { - err =g_io_channel_write (hs->rfcomm, - rsp + total_bytes_written, - count - total_bytes_written, - &bytes_written); -if (err !=G_IO_ERROR_NONE ) -error ("Error while writting to the audio output channel" ); - total_bytes_written += bytes_written; - }; +if (handle_event (device, &hs->buf[hs->data_start]) ==-1 ) +error ("Error in event" ); hs->data_start += cmd_len; hs->data_length -= cmd_len;
@@ -593,6 +617,7 @@ static void get_record_reply(DBusPendingCall *call, void *data)struct device *device = data;struct headset *hs = device->headset;struct pending_connect *c; +unsigned int SVCLASS_ID ; c = hs->pending->data;
@@ -642,21 +667,11 @@ static void get_record_reply(DBusPendingCall *call, void *data) goto failed_not_supported; } -if (hs->type ==SVC_HEADSET && - ((uuid.type ==SDP_UUID32 && - uuid.value.uuid32 !=HEADSET_SVCLASS_ID ) || - (uuid.type ==SDP_UUID16 && - uuid.value.uuid16 !=HEADSET_SVCLASS_ID ))) { -error ("Service classes did not contain the expected UUID hsp" ); - goto failed_not_supported; - } +SVCLASS_ID = hs->enable_hfp ?HANDSFREE_SVCLASS_ID :HEADSET_SVCLASS_ID ; -if (hs->type ==SVC_HANDSFREE && - ((uuid.type ==SDP_UUID32 && - uuid.value.uuid32 !=HANDSFREE_SVCLASS_ID ) || - (uuid.type ==SDP_UUID16 && - uuid.value.uuid16 !=HANDSFREE_SVCLASS_ID ))) { -error ("Service classes did not contain the expected UUID hfp" ); +if ((uuid.type ==SDP_UUID32 && uuid.value.uuid32 !=SVCLASS_ID ) + || (uuid.type ==SDP_UUID16 && uuid.value.uuid16 !=SVCLASS_ID )) { +error ("Service classes did not contain the expected UUID" ); goto failed_not_supported; }
audio/headset.h +9 -7
@@ -28,13 +28,6 @@#define DEFAULT_HF_AG_CHANNEL 13 typedef enum { -HEADSET_EVENT_KEYPRESS , -HEADSET_EVENT_GAIN , -HEADSET_EVENT_UNKNOWN , -HEADSET_EVENT_INVALID -}headset_event_t ; - -typedef enum { HEADSET_STATE_DISCONNECTED, HEADSET_STATE_CONNECT_IN_PROGRESS, HEADSET_STATE_CONNECTED,
@@ -84,3 +77,12 @@ gboolean headset_lock(struct device *dev, headset_lock_t lock);gboolean headset_unlock (struct device *dev,headset_lock_t lock);gboolean headset_suspend (struct device *dev,void *data);gboolean headset_play (struct device *dev,void *data); +static GIOError headset_send (struct headset *hs,const char *str); +int hs_signal_gain_setting (struct device *device,const char *buf); +int hf_supported_features (struct device *device,const char *buf); +int hf_report_indicators (struct device *device,const char *buf); +int hf_event_reporting (struct device *device,const char *buf); +int hf_answer_call (struct device *device,const char *buf); +int hf_call_hold (struct device *device,const char *buf); +int hf_terminate_call (struct device *device,const char *buf); +int hf_answer_call (struct device *device,const char *buf);
-------------------------------------------------------------------------
SF.Net email is sponsored by:
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel