Skip to content

Commit fecaa79

Browse files
committed
bluebinder: add support for AIDL Bluetooth HAL
1 parent 9c15cd8 commit fecaa79

File tree

1 file changed

+189
-35
lines changed

1 file changed

+189
-35
lines changed

bluebinder.c

Lines changed: 189 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@
6868
#define BINDER_BLUETOOTH_SERVICE_IFACE_CALLBACKS "android.hardware.bluetooth@1.0::IBluetoothHciCallbacks"
6969
#define BINDER_BLUETOOTH_SERVICE_SLOT "default"
7070

71+
#define BINDER_BLUETOOTH_AIDL_SERVICE_IFACE "android.hardware.bluetooth.IBluetoothHci"
72+
#define BINDER_BLUETOOTH_AIDL_SERVICE_IFACE_CALLBACKS "android.hardware.bluetooth.IBluetoothHciCallbacks"
73+
7174
// Priority for wait packet processed must be higher than the gio channel (PRIORITY_HOST_READ_PACKETS)
7275
// otherwise we might process a second command
7376
// before the first one was accepted.
@@ -91,21 +94,102 @@
9194
// are completely handled.
9295
#define PRIORITY_RFKILL_CHANNEL (G_PRIORITY_DEFAULT + 6)
9396

94-
enum bluetooth_codes {
97+
enum bluetooth_hidl_codes {
9598
INITIALIZE = GBINDER_FIRST_CALL_TRANSACTION,
9699
SEND_HCI_COMMAND,
97100
SEND_ACL_DATA,
98101
SEND_SCO_DATA,
99102
CLOSE,
100103
};
101104

102-
enum bluetooth_callback_codes {
105+
enum bluetooth_aidl_codes {
106+
AIDL_CLOSE = GBINDER_FIRST_CALL_TRANSACTION,
107+
AIDL_INITIALIZE,
108+
AIDL_SEND_ACL_DATA,
109+
AIDL_SEND_HCI_COMMAND,
110+
AIDL_SEND_ISO_DATA,
111+
AIDL_SEND_SCO_DATA,
112+
};
113+
114+
enum bluetooth_hidl_callback_codes {
103115
INITIALIZATION_COMPLETE = GBINDER_FIRST_CALL_TRANSACTION,
104116
HCI_EVENT_RECEIVED,
105117
ACL_DATA_RECEIVED,
106118
SCO_DATA_RECEIVED,
107119
};
108120

121+
enum bluetooth_aidl_callback_codes {
122+
AIDL_ACL_DATA_RECEIVED = GBINDER_FIRST_CALL_TRANSACTION,
123+
AIDL_HCI_EVENT_RECEIVED,
124+
AIDL_INITIALIZATION_COMPLETE,
125+
AIDL_ISO_DATA_RECEIVED,
126+
AIDL_SCO_DATA_RECEIVED,
127+
};
128+
129+
enum binder_rpc_protocol {
130+
BINDER_RPC_PROTOCOL_HIDL = 0,
131+
BINDER_RPC_PROTOCOL_AIDL
132+
};
133+
134+
struct bluetooth_hal_protocol {
135+
const char *service_name;
136+
const char *service_iface;
137+
const char *callback_iface;
138+
const char *service_slot;
139+
enum binder_rpc_protocol rpc_protocol;
140+
141+
int tx_initialize;
142+
int tx_close;
143+
int tx_send_cmd;
144+
int tx_send_acl;
145+
int tx_send_sco;
146+
int tx_send_iso;
147+
148+
int rx_init_complete;
149+
int rx_hci_event;
150+
int rx_acl_data;
151+
int rx_sco_data;
152+
int rx_iso_data;
153+
};
154+
155+
static const struct bluetooth_hal_protocol protocol_hidl = {
156+
.service_name = BINDER_BLUETOOTH_SERVICE_IFACE,
157+
.service_iface = BINDER_BLUETOOTH_SERVICE_IFACE,
158+
.callback_iface = BINDER_BLUETOOTH_SERVICE_IFACE_CALLBACKS,
159+
.service_slot = BINDER_BLUETOOTH_SERVICE_SLOT,
160+
.rpc_protocol = BINDER_RPC_PROTOCOL_HIDL,
161+
.tx_initialize = INITIALIZE,
162+
.tx_close = CLOSE,
163+
.tx_send_cmd = SEND_HCI_COMMAND,
164+
.tx_send_acl = SEND_ACL_DATA,
165+
.tx_send_sco = SEND_SCO_DATA,
166+
.tx_send_iso = -1,
167+
.rx_init_complete = INITIALIZATION_COMPLETE,
168+
.rx_hci_event = HCI_EVENT_RECEIVED,
169+
.rx_acl_data = ACL_DATA_RECEIVED,
170+
.rx_sco_data = SCO_DATA_RECEIVED,
171+
.rx_iso_data = -1,
172+
};
173+
174+
static const struct bluetooth_hal_protocol protocol_aidl = {
175+
.service_name = BINDER_BLUETOOTH_AIDL_SERVICE_IFACE,
176+
.service_iface = BINDER_BLUETOOTH_AIDL_SERVICE_IFACE,
177+
.callback_iface = BINDER_BLUETOOTH_AIDL_SERVICE_IFACE_CALLBACKS,
178+
.service_slot = BINDER_BLUETOOTH_SERVICE_SLOT,
179+
.rpc_protocol = BINDER_RPC_PROTOCOL_AIDL,
180+
.tx_initialize = AIDL_INITIALIZE,
181+
.tx_close = AIDL_CLOSE,
182+
.tx_send_cmd = AIDL_SEND_HCI_COMMAND,
183+
.tx_send_acl = AIDL_SEND_ACL_DATA,
184+
.tx_send_sco = AIDL_SEND_SCO_DATA,
185+
.tx_send_iso = AIDL_SEND_ISO_DATA,
186+
.rx_init_complete = AIDL_INITIALIZATION_COMPLETE,
187+
.rx_hci_event = AIDL_HCI_EVENT_RECEIVED,
188+
.rx_acl_data = AIDL_ACL_DATA_RECEIVED,
189+
.rx_sco_data = AIDL_SCO_DATA_RECEIVED,
190+
.rx_iso_data = AIDL_ISO_DATA_RECEIVED,
191+
};
192+
109193
struct pending_packet {
110194
uint8_t *packet;
111195
unsigned int size;
@@ -132,6 +216,7 @@ struct proxy {
132216
GBinderLocalObject *local_callbacks_object;
133217
GBinderRemoteObject *remote;
134218
GBinderServiceManager *sm;
219+
const struct bluetooth_hal_protocol *protocol;
135220

136221
bool bluetooth_hal_initialized;
137222

@@ -186,6 +271,8 @@ host_write_packet(
186271
{
187272
GBinderLocalRequest *local_request = NULL;
188273
GBinderWriter writer;
274+
uint8_t packet_type = ((uint8_t*)buf)[0];
275+
int tx_code = -1;
189276

190277
local_request = gbinder_client_new_request(proxy->binder_client);
191278
if (!local_request) {
@@ -195,23 +282,34 @@ host_write_packet(
195282
}
196283

197284
gbinder_local_request_init_writer(local_request, &writer);
285+
198286
// data, without the package type.
199-
gbinder_writer_append_hidl_vec(&writer, (void*)((char*)buf + 1), len - 1, sizeof(uint8_t));
287+
if (proxy->protocol->rpc_protocol == BINDER_RPC_PROTOCOL_AIDL) {
288+
gbinder_writer_append_byte_array(&writer, (void*)((char*)buf + 1), len - 1);
289+
} else {
290+
gbinder_writer_append_hidl_vec(&writer, (void*)((char*)buf + 1), len - 1, sizeof(uint8_t));
291+
}
200292

201293
proxy->binder_replies_pending++;
202294
g_idle_add_full(PRIORITY_WAIT_PACKET_PROCESSED, waiting_for_binder_reply, proxy, NULL);
203295

204-
if (((uint8_t*)buf)[0] == HCI_COMMAND_PKT) {
205-
gbinder_client_transact(proxy->binder_client, SEND_HCI_COMMAND, 0, local_request, handle_binder_reply, NULL, proxy);
206-
} else if (((uint8_t*)buf)[0] == HCI_ACLDATA_PKT) {
207-
gbinder_client_transact(proxy->binder_client, SEND_ACL_DATA, 0, local_request, handle_binder_reply, NULL, proxy);
208-
} else if (((uint8_t*)buf)[0] == HCI_SCODATA_PKT) {
209-
gbinder_client_transact(proxy->binder_client, SEND_SCO_DATA, 0, local_request, handle_binder_reply, NULL, proxy);
296+
if (packet_type == HCI_COMMAND_PKT) {
297+
tx_code = proxy->protocol->tx_send_cmd;
298+
} else if (packet_type == HCI_ACLDATA_PKT) {
299+
tx_code = proxy->protocol->tx_send_acl;
300+
} else if (packet_type == HCI_SCODATA_PKT) {
301+
tx_code = proxy->protocol->tx_send_sco;
302+
} else if (packet_type == HCI_ISODATA_PKT) {
303+
tx_code = proxy->protocol->tx_send_iso;
210304
} else {
211305
fprintf(stderr, "Received incorrect packet type from HCI client.\n");
212306
g_main_loop_quit(proxy->loop);
213307
}
214308

309+
if (tx_code != -1) {
310+
gbinder_client_transact(proxy->binder_client, tx_code, 0, local_request, handle_binder_reply, NULL, proxy);
311+
}
312+
215313
gbinder_local_request_unref(local_request);
216314
}
217315

@@ -265,8 +363,8 @@ configure_bt(
265363
gbinder_local_request_append_local_object
266364
(initialize_request, proxy->local_callbacks_object);
267365

268-
reply = gbinder_client_transact_sync_reply
269-
(proxy->binder_client, INITIALIZE, initialize_request, &status);
366+
reply = gbinder_client_transact_sync_reply(proxy->binder_client,
367+
proxy->protocol->tx_initialize, initialize_request, &status);
270368

271369
if (status != GBINDER_STATUS_OK) {
272370
fprintf(stderr, "ERROR: init reply: %p, %d\n", reply, status);
@@ -281,8 +379,8 @@ configure_bt(
281379
fprintf(stderr, "Turning bluetooth off\n");
282380
proxy->bluetooth_hal_initialized = FALSE;
283381

284-
reply = gbinder_client_transact_sync_reply
285-
(proxy->binder_client, CLOSE, NULL, &status);
382+
reply = gbinder_client_transact_sync_reply(proxy->binder_client,
383+
proxy->protocol->tx_close, NULL, &status);
286384

287385
if (status != GBINDER_STATUS_OK) {
288386
fprintf(stderr, "ERROR: close reply: %p, %d\n", reply, status);
@@ -483,8 +581,7 @@ binder_remote_died(
483581
void* user_data)
484582
{
485583
struct proxy *proxy = user_data;
486-
char *fqname =
487-
(BINDER_BLUETOOTH_SERVICE_IFACE "/" BINDER_BLUETOOTH_SERVICE_SLOT);
584+
char *fqname = NULL;
488585
int status;
489586

490587
fprintf(stderr, "Remote has died, trying to reconnect...\n");
@@ -493,9 +590,10 @@ binder_remote_died(
493590
proxy->binder_client = NULL;
494591

495592
gbinder_remote_object_remove_handler(proxy->remote, proxy->death_id);
496-
497593
gbinder_remote_object_unref(proxy->remote);
498594

595+
asprintf(&fqname, "%s/%s", proxy->protocol->service_name, proxy->protocol->service_slot);
596+
499597
int retries = 0;
500598
while (retries < 10) {
501599
proxy->remote = gbinder_remote_object_ref
@@ -510,9 +608,12 @@ binder_remote_died(
510608
sleep(1);
511609
retries++;
512610
}
611+
612+
free(fqname);
613+
513614
if (!proxy->remote) goto failed;
514615

515-
proxy->binder_client = gbinder_client_new(proxy->remote, BINDER_BLUETOOTH_SERVICE_IFACE);
616+
proxy->binder_client = gbinder_client_new(proxy->remote, proxy->protocol->service_iface);
516617

517618
configure_bt(proxy, FALSE);
518619

@@ -733,8 +834,15 @@ bluebinder_callbacks_transact(
733834
return NULL;
734835
}
735836

736-
if (!g_strcmp0(iface, BINDER_BLUETOOTH_SERVICE_IFACE_CALLBACKS)) {
737-
if (code == INITIALIZATION_COMPLETE) {
837+
if (!g_strcmp0(iface, proxy->protocol->callback_iface)) {
838+
839+
gboolean is_init_complete = (code == proxy->protocol->rx_init_complete);
840+
gboolean is_data_received = (code == proxy->protocol->rx_hci_event ||
841+
code == proxy->protocol->rx_acl_data ||
842+
code == proxy->protocol->rx_sco_data ||
843+
(proxy->protocol->rx_iso_data != -1 && code == proxy->protocol->rx_iso_data));
844+
845+
if (is_init_complete) {
738846
int result = 0;
739847

740848
gbinder_remote_request_read_int32(req, &result);
@@ -750,29 +858,48 @@ bluebinder_callbacks_transact(
750858

751859
*status = GBINDER_STATUS_OK;
752860
return gbinder_local_reply_append_int32(gbinder_local_object_new_reply(obj), 0);
753-
} else if (code == HCI_EVENT_RECEIVED || code == ACL_DATA_RECEIVED || code == SCO_DATA_RECEIVED) {
861+
} else if (is_data_received) {
754862
gsize count, elemsize;
755863
GBinderReader reader;
756864
const uint8_t *vec;
757865
uint8_t *packet;
758866

759867
gbinder_remote_request_init_reader(req, &reader);
760868

761-
vec = gbinder_reader_read_hidl_vec(&reader, &count, &elemsize);
762-
if (elemsize != 1) {
763-
fprintf(stderr, "Received unexpected array element size, expected sizeof(uint8_t)\n");
764-
g_main_loop_quit(proxy->loop);
765-
*status = GBINDER_STATUS_FAILED;
766-
return NULL;
869+
if (proxy->protocol->rpc_protocol == BINDER_RPC_PROTOCOL_AIDL) {
870+
vec = gbinder_reader_read_byte_array(&reader, &count);
871+
if (!vec) {
872+
fprintf(stderr, "Failed to read byte array from AIDL transaction\n");
873+
g_main_loop_quit(proxy->loop);
874+
*status = GBINDER_STATUS_FAILED;
875+
return NULL;
876+
}
877+
} else {
878+
vec = gbinder_reader_read_hidl_vec(&reader, &count, &elemsize);
879+
if (elemsize != 1) {
880+
fprintf(stderr, "Received unexpected array element size, expected sizeof(uint8_t)\n");
881+
g_main_loop_quit(proxy->loop);
882+
*status = GBINDER_STATUS_FAILED;
883+
return NULL;
884+
}
767885
}
768886

769887
// first byte will be the type
770888
packet = malloc(count + 1);
771889
memcpy(packet + 1, vec, count);
772890

773-
packet[0] = (code == HCI_EVENT_RECEIVED) ? HCI_EVENT_PKT :
774-
(code == ACL_DATA_RECEIVED) ? HCI_ACLDATA_PKT :
775-
(code == SCO_DATA_RECEIVED) ? HCI_SCODATA_PKT : /* unreachable */ 0xFF;
891+
if (code == proxy->protocol->rx_hci_event) {
892+
packet[0] = HCI_EVENT_PKT;
893+
} else if (code == proxy->protocol->rx_acl_data) {
894+
packet[0] = HCI_ACLDATA_PKT;
895+
} else if (code == proxy->protocol->rx_sco_data) {
896+
packet[0] = HCI_SCODATA_PKT;
897+
} else if (code == proxy->protocol->rx_iso_data) {
898+
packet[0] = HCI_ISODATA_PKT;
899+
} else {
900+
/* unknown? */
901+
packet[0] = 0xFF;
902+
}
776903

777904
if (local_features_mask) {
778905
// Command complete
@@ -873,8 +1000,7 @@ void stop_watch(struct proxy *proxy) {
8731000

8741001
int main(int argc, char *argv[])
8751002
{
876-
char *fqname =
877-
(BINDER_BLUETOOTH_SERVICE_IFACE "/" BINDER_BLUETOOTH_SERVICE_SLOT);
1003+
char *fqname = NULL;
8781004
struct proxy proxy;
8791005
int status = 0;
8801006
int err = 0;
@@ -886,12 +1012,36 @@ int main(int argc, char *argv[])
8861012

8871013
memset(&proxy, 0, sizeof(struct proxy));
8881014

889-
proxy.sm = gbinder_servicemanager_new(BINDER_BLUETOOTH_SERVICE_DEVICE);
1015+
proxy.sm = gbinder_servicemanager_new(GBINDER_DEFAULT_BINDER);
1016+
if (!proxy.sm) {
1017+
fprintf(stderr, "Failed to connect to %s servicemanager\n", GBINDER_DEFAULT_BINDER);
1018+
return 1;
1019+
}
8901020

1021+
fqname = g_strdup_printf("%s/%s", protocol_aidl.service_name, protocol_aidl.service_slot);
8911022
proxy.remote = gbinder_remote_object_ref
8921023
(gbinder_servicemanager_get_service_sync(proxy.sm, fqname, &status));
1024+
g_free(fqname);
8931025

894-
proxy.binder_client = gbinder_client_new(proxy.remote, BINDER_BLUETOOTH_SERVICE_IFACE);
1026+
if (proxy.remote) {
1027+
printf("Connected to AIDL bluetooth service\n");
1028+
proxy.protocol = &protocol_aidl;
1029+
proxy.binder_client = gbinder_client_new(proxy.remote, protocol_aidl.service_iface);
1030+
} else {
1031+
gbinder_servicemanager_unref(proxy.sm);
1032+
proxy.sm = gbinder_servicemanager_new(BINDER_BLUETOOTH_SERVICE_DEVICE);
1033+
1034+
fqname = g_strdup_printf("%s/%s", protocol_hidl.service_name, protocol_hidl.service_slot);
1035+
proxy.remote = gbinder_remote_object_ref
1036+
(gbinder_servicemanager_get_service_sync(proxy.sm, fqname, &status));
1037+
g_free(fqname);
1038+
1039+
if (proxy.remote) {
1040+
printf("Connected to HIDL bluetooth service\n");
1041+
proxy.protocol = &protocol_hidl;
1042+
proxy.binder_client = gbinder_client_new(proxy.remote, protocol_hidl.service_iface);
1043+
}
1044+
}
8951045

8961046
if (!proxy.binder_client) {
8971047
fprintf(stderr, "Failed to connect to bluetooth binder service\n");
@@ -901,10 +1051,14 @@ int main(int argc, char *argv[])
9011051

9021052
proxy.local_callbacks_object = gbinder_servicemanager_new_local_object(
9031053
proxy.sm,
904-
BINDER_BLUETOOTH_SERVICE_IFACE_CALLBACKS,
1054+
proxy.protocol->callback_iface,
9051055
bluebinder_callbacks_transact,
9061056
&proxy);
9071057

1058+
if (proxy.protocol->rpc_protocol == BINDER_RPC_PROTOCOL_AIDL) {
1059+
gbinder_local_object_set_stability(proxy.local_callbacks_object, GBINDER_STABILITY_VINTF);
1060+
}
1061+
9081062
sigtrm = g_unix_signal_add(SIGTERM, signal_callback, &proxy);
9091063
sigint = g_unix_signal_add(SIGINT, signal_callback, &proxy);
9101064

@@ -962,7 +1116,7 @@ int main(int argc, char *argv[])
9621116
if (proxy.bluetooth_hal_initialized) {
9631117
fprintf(stderr, "Turning bluetooth off on stop.\n");
9641118
reply = gbinder_client_transact_sync_reply
965-
(proxy.binder_client, CLOSE, NULL, &status);
1119+
(proxy.binder_client, proxy.protocol->tx_close, NULL, &status);
9661120

9671121
if (status != GBINDER_STATUS_OK) {
9681122
fprintf(stderr, "ERROR: close reply: %p, %d\n", reply, status);

0 commit comments

Comments
 (0)