1 /******************************************************************************
2 *
3 * Copyright (C) 2014 Google, Inc.
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 implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 #define LOG_TAG "bt_btif_sock"
20
21 #include <assert.h>
22
23 #include <hardware/bluetooth.h>
24 #include <hardware/bt_sock.h>
25
26 #include "bta_api.h"
27 #include "btif_common.h"
28 #include "btif_sock_l2cap.h"
29 #include "btif_sock_rfc.h"
30 #include "btif_sock_sco.h"
31 #include "btif_sock_sdp.h"
32 #include "btif_sock_thread.h"
33 #include "btif_uid.h"
34 #include "btif_util.h"
35 #include "osi/include/thread.h"
36
37 static bt_status_t btsock_listen(btsock_type_t type, const char *service_name, const uint8_t *uuid, int channel, int *sock_fd, int flags, int app_uid);
38 static bt_status_t btsock_connect(const bt_bdaddr_t *bd_addr, btsock_type_t type, const uint8_t *uuid, int channel, int *sock_fd, int flags, int app_uid);
39
40 static void btsock_signaled(int fd, int type, int flags, uint32_t user_id);
41
42 static int thread_handle = -1;
43 static thread_t *thread;
44
btif_sock_get_interface(void)45 btsock_interface_t *btif_sock_get_interface(void) {
46 static btsock_interface_t interface = {
47 sizeof(interface),
48 btsock_listen,
49 btsock_connect
50 };
51
52
53 return &interface;
54 }
55
btif_sock_init(uid_set_t * uid_set)56 bt_status_t btif_sock_init(uid_set_t* uid_set) {
57 assert(thread_handle == -1);
58 assert(thread == NULL);
59
60 btsock_thread_init();
61 thread_handle = btsock_thread_create(btsock_signaled, NULL);
62 if (thread_handle == -1) {
63 LOG_ERROR(LOG_TAG, "%s unable to create btsock_thread.", __func__);
64 goto error;
65 }
66
67 bt_status_t status = btsock_rfc_init(thread_handle, uid_set);
68 if (status != BT_STATUS_SUCCESS) {
69 LOG_ERROR(LOG_TAG, "%s error initializing RFCOMM sockets: %d", __func__, status);
70 goto error;
71 }
72
73 status = btsock_l2cap_init(thread_handle, uid_set);
74 if (status != BT_STATUS_SUCCESS) {
75 LOG_ERROR(LOG_TAG, "%s error initializing L2CAP sockets: %d", __func__, status);
76 goto error;
77 }
78
79 thread = thread_new("btif_sock");
80 if (!thread) {
81 LOG_ERROR(LOG_TAG, "%s error creating new thread.", __func__);
82 btsock_rfc_cleanup();
83 goto error;
84 }
85
86 status = btsock_sco_init(thread);
87 if (status != BT_STATUS_SUCCESS) {
88 LOG_ERROR(LOG_TAG, "%s error initializing SCO sockets: %d", __func__, status);
89 btsock_rfc_cleanup();
90 goto error;
91 }
92
93 return BT_STATUS_SUCCESS;
94
95 error:;
96 thread_free(thread);
97 thread = NULL;
98 if (thread_handle != -1)
99 btsock_thread_exit(thread_handle);
100 thread_handle = -1;
101 uid_set = NULL;
102 return BT_STATUS_FAIL;
103 }
104
btif_sock_cleanup(void)105 void btif_sock_cleanup(void) {
106 if (thread_handle == -1)
107 return;
108
109 thread_stop(thread);
110 thread_join(thread);
111 btsock_thread_exit(thread_handle);
112 btsock_rfc_cleanup();
113 btsock_sco_cleanup();
114 btsock_l2cap_cleanup();
115 thread_free(thread);
116 thread_handle = -1;
117 thread = NULL;
118 }
119
btsock_listen(btsock_type_t type,const char * service_name,const uint8_t * service_uuid,int channel,int * sock_fd,int flags,int app_uid)120 static bt_status_t btsock_listen(btsock_type_t type, const char *service_name, const uint8_t *service_uuid, int channel, int *sock_fd, int flags, int app_uid) {
121 if((flags & BTSOCK_FLAG_NO_SDP) == 0) {
122 assert(service_uuid != NULL || channel > 0);
123 assert(sock_fd != NULL);
124 }
125
126 *sock_fd = INVALID_FD;
127 bt_status_t status = BT_STATUS_FAIL;
128
129 switch (type) {
130 case BTSOCK_RFCOMM:
131 status = btsock_rfc_listen(service_name, service_uuid, channel, sock_fd, flags, app_uid);
132 break;
133 case BTSOCK_L2CAP:
134 status = btsock_l2cap_listen(service_name, channel, sock_fd, flags, app_uid);
135 break;
136
137 case BTSOCK_SCO:
138 status = btsock_sco_listen(sock_fd, flags);
139 break;
140
141 default:
142 LOG_ERROR(LOG_TAG, "%s unknown/unsupported socket type: %d", __func__, type);
143 status = BT_STATUS_UNSUPPORTED;
144 break;
145 }
146 return status;
147 }
148
btsock_connect(const bt_bdaddr_t * bd_addr,btsock_type_t type,const uint8_t * uuid,int channel,int * sock_fd,int flags,int app_uid)149 static bt_status_t btsock_connect(const bt_bdaddr_t *bd_addr, btsock_type_t type, const uint8_t *uuid, int channel, int *sock_fd, int flags, int app_uid) {
150 assert(uuid != NULL || channel > 0);
151 assert(bd_addr != NULL);
152 assert(sock_fd != NULL);
153
154 *sock_fd = INVALID_FD;
155 bt_status_t status = BT_STATUS_FAIL;
156
157 switch (type) {
158 case BTSOCK_RFCOMM:
159 status = btsock_rfc_connect(bd_addr, uuid, channel, sock_fd, flags, app_uid);
160 break;
161
162 case BTSOCK_L2CAP:
163 status = btsock_l2cap_connect(bd_addr, channel, sock_fd, flags, app_uid);
164 break;
165
166 case BTSOCK_SCO:
167 status = btsock_sco_connect(bd_addr, sock_fd, flags);
168 break;
169
170 default:
171 LOG_ERROR(LOG_TAG, "%s unknown/unsupported socket type: %d", __func__, type);
172 status = BT_STATUS_UNSUPPORTED;
173 break;
174 }
175 return status;
176 }
177
btsock_signaled(int fd,int type,int flags,uint32_t user_id)178 static void btsock_signaled(int fd, int type, int flags, uint32_t user_id) {
179 switch (type) {
180 case BTSOCK_RFCOMM:
181 btsock_rfc_signaled(fd, flags, user_id);
182 break;
183 case BTSOCK_L2CAP:
184 btsock_l2cap_signaled(fd, flags, user_id);
185 break;
186 default:
187 assert(false && "Invalid socket type");
188 break;
189 }
190 }
191