1/******************************************************************************
2 *
3 *  Copyright (C) 2009-2012 Broadcom 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 implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19
20/************************************************************************************
21 *
22 *  Filename:      btif_sock.c
23 *
24 *  Description:   Bluetooth Socket Interface
25 *
26 *
27 ***********************************************************************************/
28
29#include <hardware/bluetooth.h>
30#include <hardware/bt_sock.h>
31
32#define LOG_TAG "BTIF_SOCK"
33#include "btif_common.h"
34#include "btif_util.h"
35
36#include "bd.h"
37
38#include "bta_api.h"
39#include "btif_sock_thread.h"
40#include "btif_sock_rfc.h"
41
42static bt_status_t btsock_listen(btsock_type_t type, const char* service_name,
43                                const uint8_t* uuid, int channel, int* sock_fd, int flags);
44static bt_status_t btsock_connect(const bt_bdaddr_t *bd_addr, btsock_type_t type,
45                                  const uint8_t* uuid, int channel, int* sock_fd, int flags);
46
47static void btsock_signaled(int fd, int type, int flags, uint32_t user_id);
48
49/*******************************************************************************
50**
51** Function         btsock_ini
52**
53** Description     initializes the bt socket interface
54**
55** Returns         bt_status_t
56**
57*******************************************************************************/
58static btsock_interface_t sock_if = {
59                sizeof(sock_if),
60                btsock_listen,
61                btsock_connect
62       };
63btsock_interface_t *btif_sock_get_interface()
64{
65    return &sock_if;
66}
67bt_status_t btif_sock_init()
68{
69    static volatile int binit;
70    if(!binit)
71    {
72        //fix me, the process doesn't exit right now. don't set the init flag for now
73        //binit = 1;
74        BTIF_TRACE_DEBUG("btsock initializing...");
75        btsock_thread_init();
76        int handle = btsock_thread_create(btsock_signaled, NULL);
77        if(handle >= 0 && btsock_rfc_init(handle) == BT_STATUS_SUCCESS)
78        {
79            BTIF_TRACE_DEBUG("btsock successfully initialized");
80            return BT_STATUS_SUCCESS;
81        }
82    }
83    else BTIF_TRACE_ERROR("btsock interface already initialized");
84    return BT_STATUS_FAIL;
85}
86void btif_sock_cleanup()
87{
88    btsock_rfc_cleanup();
89    BTIF_TRACE_DEBUG("leaving");
90}
91
92static bt_status_t btsock_listen(btsock_type_t type, const char* service_name,
93        const uint8_t* service_uuid, int channel, int* sock_fd, int flags)
94{
95    if((service_uuid == NULL && channel <= 0) || sock_fd == NULL)
96    {
97        BTIF_TRACE_ERROR("invalid parameters, uuid:%p, channel:%d, sock_fd:%p", service_uuid, channel, sock_fd);
98        return BT_STATUS_PARM_INVALID;
99    }
100    *sock_fd = -1;
101    bt_status_t status = BT_STATUS_FAIL;
102    switch(type)
103    {
104        case BTSOCK_RFCOMM:
105            status = btsock_rfc_listen(service_name, service_uuid, channel, sock_fd, flags);
106            break;
107        case BTSOCK_L2CAP:
108            BTIF_TRACE_ERROR("bt l2cap socket type not supported, type:%d", type);
109            status = BT_STATUS_UNSUPPORTED;
110            break;
111        case BTSOCK_SCO:
112            BTIF_TRACE_ERROR("bt sco socket not supported, type:%d", type);
113            status = BT_STATUS_UNSUPPORTED;
114            break;
115        default:
116            BTIF_TRACE_ERROR("unknown bt socket type:%d", type);
117            status = BT_STATUS_UNSUPPORTED;
118            break;
119    }
120    return status;
121}
122static bt_status_t btsock_connect(const bt_bdaddr_t *bd_addr, btsock_type_t type,
123        const uint8_t* uuid, int channel, int* sock_fd, int flags)
124{
125    if((uuid == NULL && channel <= 0) || bd_addr == NULL || sock_fd == NULL)
126    {
127        BTIF_TRACE_ERROR("invalid parameters, bd_addr:%p, uuid:%p, channel:%d, sock_fd:%p",
128                bd_addr, uuid, channel, sock_fd);
129        return BT_STATUS_PARM_INVALID;
130    }
131    *sock_fd = -1;
132    bt_status_t status = BT_STATUS_FAIL;
133    switch(type)
134    {
135        case BTSOCK_RFCOMM:
136            status = btsock_rfc_connect(bd_addr, uuid, channel, sock_fd, flags);
137            break;
138        case BTSOCK_L2CAP:
139            BTIF_TRACE_ERROR("bt l2cap socket type not supported, type:%d", type);
140            status = BT_STATUS_UNSUPPORTED;
141            break;
142        case BTSOCK_SCO:
143            BTIF_TRACE_ERROR("bt sco socket not supported, type:%d", type);
144            status = BT_STATUS_UNSUPPORTED;
145            break;
146        default:
147            BTIF_TRACE_ERROR("unknown bt socket type:%d", type);
148            status = BT_STATUS_UNSUPPORTED;
149            break;
150    }
151    return status;
152}
153static void btsock_signaled(int fd, int type, int flags, uint32_t user_id)
154{
155    switch(type)
156    {
157        case BTSOCK_RFCOMM:
158            btsock_rfc_signaled(fd, flags, user_id);
159            break;
160        case BTSOCK_L2CAP:
161            BTIF_TRACE_ERROR("bt l2cap socket type not supported, fd:%d, flags:%d", fd, flags);
162            break;
163        case BTSOCK_SCO:
164            BTIF_TRACE_ERROR("bt sco socket type not supported, fd:%d, flags:%d", fd, flags);
165            break;
166        default:
167            BTIF_TRACE_ERROR("unknown socket type:%d, fd:%d, flags:%d", type, fd, flags);
168            break;
169    }
170}
171
172
173
174