blob: 624897db1b92f4b28e408b5c0d739644320fb416 [file] [log] [blame]
The Android Open Source Project5738f832012-12-12 16:00:35 -08001/******************************************************************************
2 *
Sharvil Nanavatife4ec6b2014-08-21 13:17:43 -07003 * Copyright (C) 2014 Google, Inc.
The Android Open Source Project5738f832012-12-12 16:00:35 -08004 *
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
Sharvil Nanavatife4ec6b2014-08-21 13:17:43 -070019#define LOG_TAG "btif_sock"
The Android Open Source Project5738f832012-12-12 16:00:35 -080020
Sharvil Nanavatife4ec6b2014-08-21 13:17:43 -070021#include <assert.h>
The Android Open Source Project5738f832012-12-12 16:00:35 -080022#include <hardware/bluetooth.h>
23#include <hardware/bt_sock.h>
24
The Android Open Source Project5738f832012-12-12 16:00:35 -080025#include "bd.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080026#include "bta_api.h"
Sharvil Nanavatife4ec6b2014-08-21 13:17:43 -070027#include "btif_common.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080028#include "btif_sock_rfc.h"
Ian McKellare93ac122013-11-07 16:30:05 -080029#include "btif_sock_sco.h"
Sharvil Nanavatife4ec6b2014-08-21 13:17:43 -070030#include "btif_sock_thread.h"
31#include "btif_util.h"
32#include "osi.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080033
Sharvil Nanavatife4ec6b2014-08-21 13:17:43 -070034static bt_status_t btsock_listen(btsock_type_t type, const char *service_name, const uint8_t *uuid, int channel, int *sock_fd, int flags);
35static 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);
The Android Open Source Project5738f832012-12-12 16:00:35 -080036
37static void btsock_signaled(int fd, int type, int flags, uint32_t user_id);
38
Sharvil Nanavatife4ec6b2014-08-21 13:17:43 -070039static int thread_handle = -1;
40
41btsock_interface_t *btif_sock_get_interface(void) {
42 static btsock_interface_t interface = {
43 sizeof(interface),
44 btsock_listen,
45 btsock_connect
46 };
47
48 return &interface;
The Android Open Source Project5738f832012-12-12 16:00:35 -080049}
50
Sharvil Nanavatife4ec6b2014-08-21 13:17:43 -070051bt_status_t btif_sock_init(void) {
52 assert(thread_handle == -1);
53
54 btsock_thread_init();
55 thread_handle = btsock_thread_create(btsock_signaled, NULL);
56 if (thread_handle == -1) {
57 ALOGE("%s unable to create btsock_thread.", __func__);
58 return BT_STATUS_FAIL;
59 }
60
61 bt_status_t status = btsock_rfc_init(thread_handle);
62 if (status != BT_STATUS_SUCCESS) {
63 ALOGE("%s error initializing RFCOMM sockets: %d", __func__, status);
64 btsock_thread_exit(thread_handle);
65 thread_handle = -1;
66 return BT_STATUS_FAIL;
67 }
68
69 status = btsock_sco_init(thread_handle);
70 if (status != BT_STATUS_SUCCESS) {
71 btsock_thread_exit(thread_handle);
72 thread_handle = -1;
73 btsock_rfc_cleanup();
74 return BT_STATUS_FAIL;
75 }
76
77 return BT_STATUS_SUCCESS;
The Android Open Source Project5738f832012-12-12 16:00:35 -080078}
Sharvil Nanavatife4ec6b2014-08-21 13:17:43 -070079
80void btif_sock_cleanup(void) {
81 if (thread_handle == -1)
82 return;
83
84 btsock_thread_exit(thread_handle);
85 btsock_rfc_cleanup();
86 btsock_sco_cleanup();
87 thread_handle = -1;
The Android Open Source Project5738f832012-12-12 16:00:35 -080088}
Sharvil Nanavatife4ec6b2014-08-21 13:17:43 -070089
90static 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) {
91 assert(service_uuid != NULL || channel > 0);
92 assert(sock_fd != NULL);
93
94 *sock_fd = INVALID_FD;
95 bt_status_t status = BT_STATUS_FAIL;
96
97 switch (type) {
98 case BTSOCK_RFCOMM:
99 status = btsock_rfc_listen(service_name, service_uuid, channel, sock_fd, flags);
100 break;
101
102 case BTSOCK_SCO:
103 status = btsock_sco_listen(sock_fd, flags);
104 break;
105
106 default:
107 ALOGE("%s unknown/unsupported socket type: %d", __func__, type);
108 status = BT_STATUS_UNSUPPORTED;
109 break;
110 }
111 return status;
112}
113
114static 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) {
115 assert(uuid != NULL || channel > 0);
116 assert(bd_addr != NULL);
117 assert(sock_fd != NULL);
118
119 *sock_fd = INVALID_FD;
120 bt_status_t status = BT_STATUS_FAIL;
121
122 switch (type) {
123 case BTSOCK_RFCOMM:
124 status = btsock_rfc_connect(bd_addr, uuid, channel, sock_fd, flags);
125 break;
126
127 case BTSOCK_SCO:
128 status = btsock_sco_connect(bd_addr, sock_fd, flags);
129 break;
130
131 default:
132 ALOGE("%s unknown/unsupported socket type: %d", __func__, type);
133 status = BT_STATUS_UNSUPPORTED;
134 break;
135 }
136 return status;
137}
138
139static void btsock_signaled(int fd, int type, int flags, uint32_t user_id) {
140 switch (type) {
141 case BTSOCK_RFCOMM:
142 btsock_rfc_signaled(fd, flags, user_id);
143 break;
144
145 case BTSOCK_SCO:
146 btsock_sco_signaled(fd, flags, user_id);
147 break;
148
149 default:
150 assert(false && "Invalid socket type");
151 break;
152 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800153}