15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Copyright (C) 2009-2012 Broadcom Corporation
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  you may not use this file except in compliance with the License.
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  You may obtain a copy of the License at:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  See the License for the specific language governing permissions and
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  limitations under the License.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/************************************************************************************
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Filename:      btif_sock.c
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Description:   Bluetooth Socket Interface
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ***********************************************************************************/
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <hardware/bluetooth.h>
305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <hardware/bt_sock.h>
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define LOG_TAG "BTIF_SOCK"
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_common.h"
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_util.h"
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bd.h"
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bta_api.h"
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_sock_thread.h"
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_sock_rfc.h"
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic bt_status_t btsock_listen(btsock_type_t type, const char* service_name,
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                const uint8_t* uuid, int channel, int* sock_fd, int flags);
445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic bt_status_t btsock_connect(const bt_bdaddr_t *bd_addr, btsock_type_t type,
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                  const uint8_t* uuid, int channel, int* sock_fd, int flags);
465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void btsock_signaled(int fd, int type, int flags, uint32_t user_id);
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         btsock_ini
525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description     initializes the bt socket interface
545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns         bt_status_t
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic btsock_interface_t sock_if = {
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                sizeof(sock_if),
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                btsock_listen,
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                btsock_connect
625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project       };
635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectbtsock_interface_t *btif_sock_get_interface()
645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return &sock_if;
665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectbt_status_t btif_sock_init()
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    static volatile int binit;
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(!binit)
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        //fix me, the process doesn't exit right now. don't set the init flag for now
735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        //binit = 1;
74689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        BTIF_TRACE_DEBUG0("btsock initializing...");
755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        btsock_thread_init();
765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        int handle = btsock_thread_create(btsock_signaled, NULL);
775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(handle >= 0 && btsock_rfc_init(handle) == BT_STATUS_SUCCESS)
785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
79689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project            BTIF_TRACE_DEBUG0("btsock successfully initialized");
805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return BT_STATUS_SUCCESS;
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
83689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    else BTIF_TRACE_ERROR0("btsock interface already initialized");
845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return BT_STATUS_FAIL;
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid btif_sock_cleanup()
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btsock_rfc_cleanup();
89689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    BTIF_TRACE_DEBUG0("leaving");
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic bt_status_t btsock_listen(btsock_type_t type, const char* service_name,
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        const uint8_t* service_uuid, int channel, int* sock_fd, int flags)
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if((service_uuid == NULL && channel <= 0) || sock_fd == NULL)
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
97689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        BTIF_TRACE_ERROR3("invalid parameters, uuid:%p, channel:%d, sock_fd:%p", service_uuid, channel, sock_fd);
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return BT_STATUS_PARM_INVALID;
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *sock_fd = -1;
1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    bt_status_t status = BT_STATUS_FAIL;
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    switch(type)
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case BTSOCK_RFCOMM:
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            status = btsock_rfc_listen(service_name, service_uuid, channel, sock_fd, flags);
1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case BTSOCK_L2CAP:
108689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project            BTIF_TRACE_ERROR1("bt l2cap socket type not supported, type:%d", type);
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            status = BT_STATUS_UNSUPPORTED;
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case BTSOCK_SCO:
112689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project            BTIF_TRACE_ERROR1("bt sco socket not supported, type:%d", type);
1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            status = BT_STATUS_UNSUPPORTED;
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        default:
116689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project            BTIF_TRACE_ERROR1("unknown bt socket type:%d", type);
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            status = BT_STATUS_UNSUPPORTED;
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic bt_status_t btsock_connect(const bt_bdaddr_t *bd_addr, btsock_type_t type,
1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        const uint8_t* uuid, int channel, int* sock_fd, int flags)
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if((uuid == NULL && channel <= 0) || bd_addr == NULL || sock_fd == NULL)
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
127689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        BTIF_TRACE_ERROR4("invalid parameters, bd_addr:%p, uuid:%p, channel:%d, sock_fd:%p",
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                bd_addr, uuid, channel, sock_fd);
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return BT_STATUS_PARM_INVALID;
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *sock_fd = -1;
1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    bt_status_t status = BT_STATUS_FAIL;
1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    switch(type)
1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case BTSOCK_RFCOMM:
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            status = btsock_rfc_connect(bd_addr, uuid, channel, sock_fd, flags);
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case BTSOCK_L2CAP:
139689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project            BTIF_TRACE_ERROR1("bt l2cap socket type not supported, type:%d", type);
1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            status = BT_STATUS_UNSUPPORTED;
1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case BTSOCK_SCO:
143689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project            BTIF_TRACE_ERROR1("bt sco socket not supported, type:%d", type);
1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            status = BT_STATUS_UNSUPPORTED;
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        default:
147689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project            BTIF_TRACE_ERROR1("unknown bt socket type:%d", type);
1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            status = BT_STATUS_UNSUPPORTED;
1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void btsock_signaled(int fd, int type, int flags, uint32_t user_id)
1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    switch(type)
1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case BTSOCK_RFCOMM:
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            btsock_rfc_signaled(fd, flags, user_id);
1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case BTSOCK_L2CAP:
161689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project            BTIF_TRACE_ERROR2("bt l2cap socket type not supported, fd:%d, flags:%d", fd, flags);
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case BTSOCK_SCO:
164689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project            BTIF_TRACE_ERROR2("bt sco socket type not supported, fd:%d, flags:%d", fd, flags);
1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        default:
167689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project            BTIF_TRACE_ERROR3("unknown socket type:%d, fd:%d, flags:%d", type, fd, flags);
1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
174