• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef foobluez5utilhfoo
2 #define foobluez5utilhfoo
3 
4 /***
5   This file is part of PulseAudio.
6 
7   Copyright 2008-2013 João Paulo Rechi Vita
8   Copyrigth 2018-2019 Pali Rohár <pali.rohar@gmail.com>
9 
10   PulseAudio is free software; you can redistribute it and/or modify
11   it under the terms of the GNU Lesser General Public License as
12   published by the Free Software Foundation; either version 2.1 of the
13   License, or (at your option) any later version.
14 
15   PulseAudio is distributed in the hope that it will be useful, but
16   WITHOUT ANY WARRANTY; without even the implied warranty of
17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18   General Public License for more details.
19 
20   You should have received a copy of the GNU Lesser General Public
21   License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
22 ***/
23 
24 #include <pulsecore/core.h>
25 
26 #include "a2dp-codec-util.h"
27 
28 #define PA_BLUETOOTH_UUID_A2DP_SOURCE "0000110a-0000-1000-8000-00805f9b34fb"
29 #define PA_BLUETOOTH_UUID_A2DP_SINK   "0000110b-0000-1000-8000-00805f9b34fb"
30 
31 /* There are two HSP HS UUIDs. The first one (older?) is used both as the HSP
32  * profile identifier and as the HS role identifier, while the second one is
33  * only used to identify the role. As far as PulseAudio is concerned, the two
34  * UUIDs mean exactly the same thing. */
35 #define PA_BLUETOOTH_UUID_HSP_HS      "00001108-0000-1000-8000-00805f9b34fb"
36 #define PA_BLUETOOTH_UUID_HSP_HS_ALT  "00001131-0000-1000-8000-00805f9b34fb"
37 
38 #define PA_BLUETOOTH_UUID_HSP_AG      "00001112-0000-1000-8000-00805f9b34fb"
39 #define PA_BLUETOOTH_UUID_HFP_HF      "0000111e-0000-1000-8000-00805f9b34fb"
40 #define PA_BLUETOOTH_UUID_HFP_AG      "0000111f-0000-1000-8000-00805f9b34fb"
41 
42 typedef struct pa_bluetooth_transport pa_bluetooth_transport;
43 typedef struct pa_bluetooth_device pa_bluetooth_device;
44 typedef struct pa_bluetooth_adapter pa_bluetooth_adapter;
45 typedef struct pa_bluetooth_discovery pa_bluetooth_discovery;
46 typedef struct pa_bluetooth_backend pa_bluetooth_backend;
47 
48 typedef enum pa_bluetooth_hook {
49     PA_BLUETOOTH_HOOK_DEVICE_CONNECTION_CHANGED,          /* Call data: pa_bluetooth_device */
50     PA_BLUETOOTH_HOOK_DEVICE_UNLINK,                      /* Call data: pa_bluetooth_device */
51     PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED,            /* Call data: pa_bluetooth_transport */
52     PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED,  /* Call data: pa_bluetooth_transport */
53     PA_BLUETOOTH_HOOK_TRANSPORT_SPEAKER_GAIN_CHANGED,     /* Call data: pa_bluetooth_transport */
54     PA_BLUETOOTH_HOOK_MAX
55 } pa_bluetooth_hook_t;
56 
57 typedef enum profile {
58     PA_BLUETOOTH_PROFILE_A2DP_SINK,
59     PA_BLUETOOTH_PROFILE_A2DP_SOURCE,
60     PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT,
61     PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY,
62     PA_BLUETOOTH_PROFILE_OFF
63 } pa_bluetooth_profile_t;
64 #define PA_BLUETOOTH_PROFILE_COUNT PA_BLUETOOTH_PROFILE_OFF
65 
66 typedef enum pa_bluetooth_transport_state {
67     PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED,
68     PA_BLUETOOTH_TRANSPORT_STATE_IDLE,
69     PA_BLUETOOTH_TRANSPORT_STATE_PLAYING
70 } pa_bluetooth_transport_state_t;
71 
72 typedef int (*pa_bluetooth_transport_acquire_cb)(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu);
73 typedef void (*pa_bluetooth_transport_release_cb)(pa_bluetooth_transport *t);
74 typedef void (*pa_bluetooth_transport_destroy_cb)(pa_bluetooth_transport *t);
75 typedef void (*pa_bluetooth_transport_set_speaker_gain_cb)(pa_bluetooth_transport *t, uint16_t gain);
76 typedef void (*pa_bluetooth_transport_set_microphone_gain_cb)(pa_bluetooth_transport *t, uint16_t gain);
77 
78 struct pa_bluetooth_transport {
79     pa_bluetooth_device *device;
80 
81     char *owner;
82     char *path;
83     pa_bluetooth_profile_t profile;
84 
85     uint8_t codec;
86     uint8_t *config;
87     size_t config_size;
88 
89     const pa_a2dp_codec *a2dp_codec;
90 
91     uint16_t microphone_gain;
92     uint16_t speaker_gain;
93 
94     pa_bluetooth_transport_state_t state;
95 
96     pa_bluetooth_transport_acquire_cb acquire;
97     pa_bluetooth_transport_release_cb release;
98     pa_bluetooth_transport_destroy_cb destroy;
99     pa_bluetooth_transport_set_speaker_gain_cb set_speaker_gain;
100     pa_bluetooth_transport_set_microphone_gain_cb set_microphone_gain;
101     void *userdata;
102 };
103 
104 struct pa_bluetooth_device {
105     pa_bluetooth_discovery *discovery;
106     pa_bluetooth_adapter *adapter;
107 
108     bool properties_received;
109     bool tried_to_link_with_adapter;
110     bool valid;
111     bool autodetect_mtu;
112 
113     /* Device information */
114     char *path;
115     char *adapter_path;
116     char *alias;
117     char *address;
118     uint32_t class_of_device;
119     pa_hashmap *uuids; /* char* -> char* (hashmap-as-a-set) */
120 
121     pa_bluetooth_transport *transports[PA_BLUETOOTH_PROFILE_COUNT];
122 
123     pa_time_event *wait_for_profiles_timer;
124 };
125 
126 struct pa_bluetooth_adapter {
127     pa_bluetooth_discovery *discovery;
128     char *path;
129     char *address;
130 
131     bool valid;
132 };
133 
134 #ifdef HAVE_BLUEZ_5_OFONO_HEADSET
135 pa_bluetooth_backend *pa_bluetooth_ofono_backend_new(pa_core *c, pa_bluetooth_discovery *y);
136 void pa_bluetooth_ofono_backend_free(pa_bluetooth_backend *b);
137 #else
pa_bluetooth_ofono_backend_new(pa_core * c,pa_bluetooth_discovery * y)138 static inline pa_bluetooth_backend *pa_bluetooth_ofono_backend_new(pa_core *c, pa_bluetooth_discovery *y) {
139     return NULL;
140 }
pa_bluetooth_ofono_backend_free(pa_bluetooth_backend * b)141 static inline void pa_bluetooth_ofono_backend_free(pa_bluetooth_backend *b) {}
142 #endif
143 
144 #ifdef HAVE_BLUEZ_5_NATIVE_HEADSET
145 pa_bluetooth_backend *pa_bluetooth_native_backend_new(pa_core *c, pa_bluetooth_discovery *y, bool enable_hs_role);
146 void pa_bluetooth_native_backend_free(pa_bluetooth_backend *b);
147 void pa_bluetooth_native_backend_enable_hs_role(pa_bluetooth_backend *b, bool enable_hs_role);
148 #else
pa_bluetooth_native_backend_new(pa_core * c,pa_bluetooth_discovery * y,bool enable_hs_role)149 static inline pa_bluetooth_backend *pa_bluetooth_native_backend_new(pa_core *c, pa_bluetooth_discovery *y, bool enable_hs_role) {
150     return NULL;
151 }
pa_bluetooth_native_backend_free(pa_bluetooth_backend * b)152 static inline void pa_bluetooth_native_backend_free(pa_bluetooth_backend *b) {}
pa_bluetooth_native_backend_enable_hs_role(pa_bluetooth_backend * b,bool enable_hs_role)153 static inline void pa_bluetooth_native_backend_enable_hs_role(pa_bluetooth_backend *b, bool enable_hs_role) {}
154 #endif
155 
156 pa_bluetooth_transport *pa_bluetooth_transport_new(pa_bluetooth_device *d, const char *owner, const char *path,
157                                                    pa_bluetooth_profile_t p, const uint8_t *config, size_t size);
158 
159 void pa_bluetooth_transport_set_state(pa_bluetooth_transport *t, pa_bluetooth_transport_state_t state);
160 void pa_bluetooth_transport_put(pa_bluetooth_transport *t);
161 void pa_bluetooth_transport_unlink(pa_bluetooth_transport *t);
162 void pa_bluetooth_transport_free(pa_bluetooth_transport *t);
163 
164 bool pa_bluetooth_device_any_transport_connected(const pa_bluetooth_device *d);
165 
166 pa_bluetooth_device* pa_bluetooth_discovery_get_device_by_path(pa_bluetooth_discovery *y, const char *path);
167 pa_bluetooth_device* pa_bluetooth_discovery_get_device_by_address(pa_bluetooth_discovery *y, const char *remote, const char *local);
168 
169 pa_hook* pa_bluetooth_discovery_hook(pa_bluetooth_discovery *y, pa_bluetooth_hook_t hook);
170 
171 const char *pa_bluetooth_profile_to_string(pa_bluetooth_profile_t profile);
172 
pa_bluetooth_uuid_is_hsp_hs(const char * uuid)173 static inline bool pa_bluetooth_uuid_is_hsp_hs(const char *uuid) {
174     return pa_streq(uuid, PA_BLUETOOTH_UUID_HSP_HS) || pa_streq(uuid, PA_BLUETOOTH_UUID_HSP_HS_ALT);
175 }
176 
177 #define HEADSET_BACKEND_OFONO 0
178 #define HEADSET_BACKEND_NATIVE 1
179 #define HEADSET_BACKEND_AUTO 2
180 
181 pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *core, int headset_backend);
182 pa_bluetooth_discovery* pa_bluetooth_discovery_ref(pa_bluetooth_discovery *y);
183 void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y);
184 void pa_bluetooth_discovery_set_ofono_running(pa_bluetooth_discovery *y, bool is_running);
185 #endif
186