• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/bt


Commit MetaInfo

Revision5f824d0aeeb8a54c5af5249bdc08e1bdfb962daa (tree)
Zeit2020-12-30 07:22:36
AutorChih-Wei Huang <cwhuang@linu...>
CommiterMauro Rossi

Log Message

Add back libbt-vendor

Ändern Zusammenfassung

Diff

--- a/vendor_libs/linux/Android.bp
+++ b/vendor_libs/linux/Android.bp
@@ -1,3 +1,33 @@
1+//
2+// Copyright (C) 2019 The Android-x86 Open Source Project
3+//
4+// Licensed under the Apache License, Version 2.0 (the "License");
5+// you may not use this file except in compliance with the License.
6+// You may obtain a copy of the License at:
7+//
8+// http://www.apache.org/licenses/LICENSE-2.0
9+//
10+// Unless required by applicable law or agreed to in writing, software
11+// distributed under the License is distributed on an "AS IS" BASIS,
12+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+// See the License for the specific language governing permissions and
14+// limitations under the License.
15+//
16+
17+// libbt-vendor shared library for target
18+cc_library_shared {
19+ name: "libbt-vendor",
20+ defaults: ["fluoride_defaults"],
21+ srcs: ["bt_vendor_linux.cc"],
22+ include_dirs: ["system/bt"],
23+ shared_libs: [
24+ "liblog",
25+ "libcutils",
26+ ],
27+ static_libs: ["libosi"],
28+ vendor: true,
29+}
30+
131 subdirs = [
232 "interface",
333 ]
--- /dev/null
+++ b/vendor_libs/linux/bt_vendor_linux.cc
@@ -0,0 +1,411 @@
1+/**********************************************************************
2+ *
3+ * Copyright (C) 2015 Intel Corporation
4+ *
5+ * Licensed under the Apache License, Version 2.0 (the "License");
6+ * you may not use this file except in compliance with the License.
7+ * You may obtain a copy of the License at:
8+ *
9+ * http://www.apache.org/licenses/LICENSE-2.0
10+ *
11+ * Unless required by applicable law or agreed to in writing, software
12+ * distributed under the License is distributed on an "AS IS" BASIS,
13+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14+ * implied.
15+ * See the License for the specific language governing permissions and
16+ * limitations under the License.
17+ *
18+ **********************************************************************/
19+
20+#define LOG_TAG "bt_vendor"
21+
22+#include <errno.h>
23+#include <fcntl.h>
24+#include <poll.h>
25+#include <stdbool.h>
26+#include <stdint.h>
27+#include <stdlib.h>
28+#include <string.h>
29+
30+#include <sys/ioctl.h>
31+#include <sys/socket.h>
32+
33+#include "hci/include/bt_vendor_lib.h"
34+#include "osi/include/compat.h"
35+#include "osi/include/log.h"
36+#include "osi/include/osi.h"
37+#include "osi/include/properties.h"
38+
39+#define BTPROTO_HCI 1
40+#define HCI_CHANNEL_USER 1
41+#define HCI_CHANNEL_CONTROL 3
42+#define HCI_DEV_NONE 0xffff
43+
44+#define RFKILL_TYPE_BLUETOOTH 2
45+#define RFKILL_OP_CHANGE_ALL 3
46+
47+#define MGMT_OP_INDEX_LIST 0x0003
48+#define MGMT_EV_INDEX_ADDED 0x0004
49+#define MGMT_EV_COMMAND_COMP 0x0001
50+#define MGMT_EV_SIZE_MAX 1024
51+#define MGMT_EV_POLL_TIMEOUT 3000 /* 3000ms */
52+
53+#define IOCTL_HCIDEVDOWN _IOW('H', 202, int)
54+
55+struct sockaddr_hci {
56+ sa_family_t hci_family;
57+ unsigned short hci_dev;
58+ unsigned short hci_channel;
59+};
60+
61+struct rfkill_event {
62+ uint32_t idx;
63+ uint8_t type;
64+ uint8_t op;
65+ uint8_t soft, hard;
66+} __attribute__((packed));
67+
68+struct mgmt_pkt {
69+ uint16_t opcode;
70+ uint16_t index;
71+ uint16_t len;
72+ uint8_t data[MGMT_EV_SIZE_MAX];
73+} __attribute__((packed));
74+
75+struct mgmt_event_read_index {
76+ uint16_t cc_opcode;
77+ uint8_t status;
78+ uint16_t num_intf;
79+ uint16_t index[0];
80+} __attribute__((packed));
81+
82+static const bt_vendor_callbacks_t* bt_vendor_callbacks;
83+static unsigned char bt_vendor_local_bdaddr[6];
84+static int bt_vendor_fd = -1;
85+static int hci_interface;
86+static int rfkill_en;
87+static int bt_hwcfg_en;
88+
89+static int bt_vendor_init(const bt_vendor_callbacks_t* p_cb,
90+ unsigned char* local_bdaddr) {
91+ char prop_value[PROPERTY_VALUE_MAX];
92+
93+ LOG_INFO(LOG_TAG, "%s", __func__);
94+
95+ if (p_cb == NULL) {
96+ LOG_ERROR(LOG_TAG, "init failed with no user callbacks!");
97+ return -1;
98+ }
99+
100+ bt_vendor_callbacks = p_cb;
101+
102+ memcpy(bt_vendor_local_bdaddr, local_bdaddr, sizeof(bt_vendor_local_bdaddr));
103+
104+ osi_property_get("bluetooth.interface", prop_value, "0");
105+
106+ errno = 0;
107+ if (memcmp(prop_value, "hci", 3))
108+ hci_interface = strtol(prop_value, NULL, 10);
109+ else
110+ hci_interface = strtol(prop_value + 3, NULL, 10);
111+ if (errno) hci_interface = 0;
112+
113+ LOG_INFO(LOG_TAG, "Using interface hci%d", hci_interface);
114+
115+ osi_property_get("bluetooth.rfkill", prop_value, "0");
116+
117+ rfkill_en = atoi(prop_value);
118+ if (rfkill_en) LOG_INFO(LOG_TAG, "RFKILL enabled");
119+
120+ bt_hwcfg_en =
121+ osi_property_get("bluetooth.hwcfg", prop_value, NULL) > 0 ? 1 : 0;
122+ if (bt_hwcfg_en) LOG_INFO(LOG_TAG, "HWCFG enabled");
123+
124+ return 0;
125+}
126+
127+static int bt_vendor_hw_cfg(int stop) {
128+ if (!bt_hwcfg_en) return 0;
129+
130+ if (stop) {
131+ if (osi_property_set("bluetooth.hwcfg", "stop") < 0) {
132+ LOG_ERROR(LOG_TAG, "%s cannot stop btcfg service via prop", __func__);
133+ return 1;
134+ }
135+ } else {
136+ if (osi_property_set("bluetooth.hwcfg", "start") < 0) {
137+ LOG_ERROR(LOG_TAG, "%s cannot start btcfg service via prop", __func__);
138+ return 1;
139+ }
140+ }
141+ return 0;
142+}
143+
144+static int bt_vendor_wait_hcidev(void) {
145+ struct sockaddr_hci addr;
146+ struct pollfd fds[1];
147+ struct mgmt_pkt ev;
148+ int fd;
149+ int ret = 0;
150+
151+ LOG_INFO(LOG_TAG, "%s", __func__);
152+
153+ fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
154+ if (fd < 0) {
155+ LOG_ERROR(LOG_TAG, "Bluetooth socket error: %s", strerror(errno));
156+ return -1;
157+ }
158+
159+ memset(&addr, 0, sizeof(addr));
160+ addr.hci_family = AF_BLUETOOTH;
161+ addr.hci_dev = HCI_DEV_NONE;
162+ addr.hci_channel = HCI_CHANNEL_CONTROL;
163+
164+ if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
165+ LOG_ERROR(LOG_TAG, "HCI Channel Control: %s", strerror(errno));
166+ close(fd);
167+ return -1;
168+ }
169+
170+ fds[0].fd = fd;
171+ fds[0].events = POLLIN;
172+
173+ /* Read Controller Index List Command */
174+ ev.opcode = MGMT_OP_INDEX_LIST;
175+ ev.index = HCI_DEV_NONE;
176+ ev.len = 0;
177+
178+ ssize_t wrote;
179+ OSI_NO_INTR(wrote = write(fd, &ev, 6));
180+ if (wrote != 6) {
181+ LOG_ERROR(LOG_TAG, "Unable to write mgmt command: %s", strerror(errno));
182+ ret = -1;
183+ goto end;
184+ }
185+
186+ while (1) {
187+ int n;
188+ OSI_NO_INTR(n = poll(fds, 1, MGMT_EV_POLL_TIMEOUT));
189+ if (n == -1) {
190+ LOG_ERROR(LOG_TAG, "Poll error: %s", strerror(errno));
191+ ret = -1;
192+ break;
193+ } else if (n == 0) {
194+ LOG_ERROR(LOG_TAG, "Timeout, no HCI device detected");
195+ ret = -1;
196+ break;
197+ }
198+
199+ if (fds[0].revents & POLLIN) {
200+ OSI_NO_INTR(n = read(fd, &ev, sizeof(struct mgmt_pkt)));
201+ if (n < 0) {
202+ LOG_ERROR(LOG_TAG, "Error reading control channel: %s",
203+ strerror(errno));
204+ ret = -1;
205+ break;
206+ }
207+
208+ if (ev.opcode == MGMT_EV_INDEX_ADDED && ev.index == hci_interface) {
209+ goto end;
210+ } else if (ev.opcode == MGMT_EV_COMMAND_COMP) {
211+ struct mgmt_event_read_index* cc;
212+ int i;
213+
214+ cc = (struct mgmt_event_read_index*)ev.data;
215+
216+ if (cc->cc_opcode != MGMT_OP_INDEX_LIST || cc->status != 0) continue;
217+
218+ for (i = 0; i < cc->num_intf; i++) {
219+ if (cc->index[i] == hci_interface) goto end;
220+ }
221+ }
222+ }
223+ }
224+
225+end:
226+ close(fd);
227+ return ret;
228+}
229+
230+static int bt_vendor_open(void* param) {
231+ int(*fd_array)[] = (int(*)[])param;
232+ int fd;
233+
234+ LOG_INFO(LOG_TAG, "%s", __func__);
235+
236+ fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
237+ if (fd < 0) {
238+ LOG_ERROR(LOG_TAG, "socket create error %s", strerror(errno));
239+ return -1;
240+ }
241+
242+ (*fd_array)[CH_CMD] = fd;
243+ (*fd_array)[CH_EVT] = fd;
244+ (*fd_array)[CH_ACL_OUT] = fd;
245+ (*fd_array)[CH_ACL_IN] = fd;
246+
247+ bt_vendor_fd = fd;
248+
249+ LOG_INFO(LOG_TAG, "%s returning %d", __func__, bt_vendor_fd);
250+
251+ return 1;
252+}
253+
254+static int bt_vendor_close(void* param) {
255+ (void)(param);
256+
257+ LOG_INFO(LOG_TAG, "%s", __func__);
258+
259+ if (bt_vendor_fd != -1) {
260+ close(bt_vendor_fd);
261+ bt_vendor_fd = -1;
262+ }
263+
264+ return 0;
265+}
266+
267+static int bt_vendor_rfkill(int block) {
268+ struct rfkill_event event;
269+ int fd;
270+
271+ LOG_INFO(LOG_TAG, "%s", __func__);
272+
273+ fd = open("/dev/rfkill", O_WRONLY);
274+ if (fd < 0) {
275+ LOG_ERROR(LOG_TAG, "Unable to open /dev/rfkill");
276+ return -1;
277+ }
278+
279+ memset(&event, 0, sizeof(struct rfkill_event));
280+ event.op = RFKILL_OP_CHANGE_ALL;
281+ event.type = RFKILL_TYPE_BLUETOOTH;
282+ event.hard = block;
283+ event.soft = block;
284+
285+ ssize_t len;
286+ OSI_NO_INTR(len = write(fd, &event, sizeof(event)));
287+ if (len < 0) {
288+ LOG_ERROR(LOG_TAG, "Failed to change rfkill state");
289+ close(fd);
290+ return 1;
291+ }
292+
293+ close(fd);
294+ return 0;
295+}
296+
297+/* TODO: fw config should thread the device waiting and return immedialty */
298+static void bt_vendor_fw_cfg(void) {
299+ struct sockaddr_hci addr;
300+ int fd = bt_vendor_fd;
301+
302+ LOG_INFO(LOG_TAG, "%s", __func__);
303+
304+ if (fd == -1) {
305+ LOG_ERROR(LOG_TAG, "bt_vendor_fd: %s", strerror(EBADF));
306+ goto failure;
307+ }
308+
309+ memset(&addr, 0, sizeof(addr));
310+ addr.hci_family = AF_BLUETOOTH;
311+ addr.hci_dev = hci_interface;
312+ addr.hci_channel = HCI_CHANNEL_USER;
313+
314+ if (bt_vendor_wait_hcidev()) {
315+ LOG_ERROR(LOG_TAG, "HCI interface (%d) not found", hci_interface);
316+ goto failure;
317+ }
318+
319+ if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
320+ LOG_ERROR(LOG_TAG, "socket bind error %s", strerror(errno));
321+ goto failure;
322+ }
323+
324+ LOG_INFO(LOG_TAG, "HCI device ready");
325+
326+ bt_vendor_callbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
327+
328+ return;
329+
330+failure:
331+ LOG_ERROR(LOG_TAG, "Hardware Config Error");
332+ bt_vendor_callbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
333+}
334+
335+static int bt_vendor_op(bt_vendor_opcode_t opcode, void* param) {
336+ int retval = 0;
337+
338+ LOG_INFO(LOG_TAG, "%s op %d", __func__, opcode);
339+
340+ switch (opcode) {
341+ case BT_VND_OP_POWER_CTRL:
342+ if (!rfkill_en || !param) break;
343+
344+ if (*((int*)param) == BT_VND_PWR_ON) {
345+ retval = bt_vendor_rfkill(0);
346+ if (!retval) retval = bt_vendor_hw_cfg(0);
347+ } else {
348+ retval = bt_vendor_hw_cfg(1);
349+ if (!retval) retval = bt_vendor_rfkill(1);
350+ }
351+
352+ break;
353+
354+ case BT_VND_OP_FW_CFG:
355+ bt_vendor_fw_cfg();
356+ break;
357+
358+ case BT_VND_OP_SCO_CFG:
359+ bt_vendor_callbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS);
360+ break;
361+
362+ case BT_VND_OP_USERIAL_OPEN:
363+ retval = bt_vendor_open(param);
364+ break;
365+
366+ case BT_VND_OP_USERIAL_CLOSE:
367+ retval = bt_vendor_close(param);
368+ break;
369+
370+ case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
371+ *((uint32_t*)param) = 3000;
372+ retval = 0;
373+ break;
374+
375+ case BT_VND_OP_LPM_SET_MODE:
376+ bt_vendor_callbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS);
377+ break;
378+
379+ case BT_VND_OP_LPM_WAKE_SET_STATE:
380+ break;
381+
382+ case BT_VND_OP_SET_AUDIO_STATE:
383+ bt_vendor_callbacks->audio_state_cb(BT_VND_OP_RESULT_SUCCESS);
384+ break;
385+
386+ case BT_VND_OP_EPILOG:
387+ bt_vendor_callbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
388+ break;
389+
390+ case BT_VND_OP_A2DP_OFFLOAD_START:
391+ break;
392+
393+ case BT_VND_OP_A2DP_OFFLOAD_STOP:
394+ break;
395+ }
396+
397+ LOG_INFO(LOG_TAG, "%s op %d retval %d", __func__, opcode, retval);
398+
399+ return retval;
400+}
401+
402+static void bt_vendor_cleanup(void) {
403+ LOG_INFO(LOG_TAG, "%s", __func__);
404+
405+ bt_vendor_callbacks = NULL;
406+}
407+
408+EXPORT_SYMBOL const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
409+ sizeof(bt_vendor_interface_t), bt_vendor_init, bt_vendor_op,
410+ bt_vendor_cleanup,
411+};