16ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach/******************************************************************************
26ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *
36ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  Copyright (C) 2009-2012 Broadcom Corporation
46ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *
56ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  Licensed under the Apache License, Version 2.0 (the "License");
66ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  you may not use this file except in compliance with the License.
76ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  You may obtain a copy of the License at:
86ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *
96ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  http://www.apache.org/licenses/LICENSE-2.0
106ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *
116ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  Unless required by applicable law or agreed to in writing, software
126ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  distributed under the License is distributed on an "AS IS" BASIS,
136ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
146ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  See the License for the specific language governing permissions and
156ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  limitations under the License.
1666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani *
176ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach ******************************************************************************/
1866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani
1966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani
2066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani/************************************************************************************
2166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani *
2266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani *  Filename:      btif_sock.c
2366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani *
2466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani *  Description:   Bluetooth Socket Interface
2566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani *
2666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani *
2766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ***********************************************************************************/
2866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani
2966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <hardware/bluetooth.h>
3066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <hardware/bt_sock.h>
3166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani
3266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#define LOG_TAG "BTIF_SOCK"
3366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include "btif_common.h"
3466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include "btif_util.h"
3566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani
3666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include "bd.h"
3766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani
3866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include "bta_api.h"
3966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include "btif_sock_thread.h"
4066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include "btif_sock_rfc.h"
4166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <cutils/log.h>
42595bced8e7c280e37a75b9bf9c1f36263434041cMatthew Xie#define info(fmt, ...)  ALOGI ("btif_sock: %s: " fmt,__FUNCTION__,  ## __VA_ARGS__)
43595bced8e7c280e37a75b9bf9c1f36263434041cMatthew Xie#define debug(fmt, ...) ALOGD ("btif_sock: %s: " fmt,__FUNCTION__,  ## __VA_ARGS__)
44595bced8e7c280e37a75b9bf9c1f36263434041cMatthew Xie#define error(fmt, ...) ALOGE ("btif_sock: ## ERROR : %s: " fmt "##",__FUNCTION__,  ## __VA_ARGS__)
45595bced8e7c280e37a75b9bf9c1f36263434041cMatthew Xie#define asrt(s) if(!(s)) ALOGE ("btif_sock: ## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__)
4666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani
4766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic bt_status_t btsock_listen(btsock_type_t type, const char* service_name,
4866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani                                const uint8_t* uuid, int channel, int* sock_fd, int flags);
4966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic bt_status_t btsock_connect(const bt_bdaddr_t *bd_addr, btsock_type_t type,
5066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani                                  const uint8_t* uuid, int channel, int* sock_fd, int flags);
5166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani
5266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic void btsock_signaled(int fd, int type, int flags, uint32_t user_id);
5366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani
5466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani/*******************************************************************************
5566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani**
5666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Function         btsock_ini
5766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani**
5866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Description     initializes the bt socket interface
5966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani**
6066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Returns         bt_status_t
6166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani**
6266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani*******************************************************************************/
6366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic btsock_interface_t sock_if = {
6466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani                sizeof(sock_if),
6566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani                btsock_listen,
6666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani                btsock_connect
6766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani       };
6866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanibtsock_interface_t *btif_sock_get_interface()
6966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{
7066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    return &sock_if;
7166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani}
7266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanibt_status_t btif_sock_init()
7366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{
747105408a110e1fa7bfa7b82637cd704a2c428f68fredc    debug("");
757105408a110e1fa7bfa7b82637cd704a2c428f68fredc
767105408a110e1fa7bfa7b82637cd704a2c428f68fredc
7766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    static volatile int binit;
7866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    if(!binit)
7966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    {
80e8070c41e25c6f0d368d7a53c0641524ea4630d2zzy        //fix me, the process doesn't exit right now. don't set the init flag for now
81e8070c41e25c6f0d368d7a53c0641524ea4630d2zzy        //binit = 1;
8266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        debug("btsock initializing...");
8366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        btsock_thread_init();
8454cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy        int handle = btsock_thread_create(btsock_signaled, NULL);
8566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        if(handle >= 0 && btsock_rfc_init(handle) == BT_STATUS_SUCCESS)
8666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        {
8766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            debug("btsock successfully initialized");
8866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            return BT_STATUS_SUCCESS;
8966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        }
9066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    }
9166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    else error("btsock interface already initialized");
9266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    return BT_STATUS_FAIL;
9366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani}
9466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanivoid btif_sock_cleanup()
9566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{
967105408a110e1fa7bfa7b82637cd704a2c428f68fredc    debug("");
97e8070c41e25c6f0d368d7a53c0641524ea4630d2zzy    btsock_rfc_cleanup();
987105408a110e1fa7bfa7b82637cd704a2c428f68fredc    debug("leaving");
9966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani}
1007105408a110e1fa7bfa7b82637cd704a2c428f68fredc
10166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic bt_status_t btsock_listen(btsock_type_t type, const char* service_name,
10266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        const uint8_t* service_uuid, int channel, int* sock_fd, int flags)
10366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{
10466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    if((service_uuid == NULL && channel <= 0) || sock_fd == NULL)
10566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    {
10666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        error("invalid parameters, uuid:%p, channel:%d, sock_fd:%p", service_uuid, channel, sock_fd);
10766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        return BT_STATUS_PARM_INVALID;
10866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    }
10966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    *sock_fd = -1;
11066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    bt_status_t status = BT_STATUS_FAIL;
11166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    switch(type)
11266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    {
11366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        case BTSOCK_RFCOMM:
11466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            status = btsock_rfc_listen(service_name, service_uuid, channel, sock_fd, flags);
11566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            break;
11666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        case BTSOCK_L2CAP:
11766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            error("bt l2cap socket type not supported, type:%d", type);
11866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            status = BT_STATUS_UNSUPPORTED;
11966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            break;
12066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        case BTSOCK_SCO:
12166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            error("bt sco socket not supported, type:%d", type);
12266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            status = BT_STATUS_UNSUPPORTED;
12366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            break;
12466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        default:
12566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            error("unknown bt socket type:%d", type);
12666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            status = BT_STATUS_UNSUPPORTED;
12766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            break;
12866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    }
12966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    return status;
13066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani}
13166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic bt_status_t btsock_connect(const bt_bdaddr_t *bd_addr, btsock_type_t type,
13266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        const uint8_t* uuid, int channel, int* sock_fd, int flags)
13366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{
13466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    if((uuid == NULL && channel <= 0) || bd_addr == NULL || sock_fd == NULL)
13566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    {
13666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        error("invalid parameters, bd_addr:%p, uuid:%p, channel:%d, sock_fd:%p",
13766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani                bd_addr, uuid, channel, sock_fd);
13866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        return BT_STATUS_PARM_INVALID;
13966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    }
14066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    *sock_fd = -1;
14166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    bt_status_t status = BT_STATUS_FAIL;
14266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    switch(type)
14366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    {
14466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        case BTSOCK_RFCOMM:
14566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            status = btsock_rfc_connect(bd_addr, uuid, channel, sock_fd, flags);
14666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            break;
14766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        case BTSOCK_L2CAP:
14866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            error("bt l2cap socket type not supported, type:%d", type);
14966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            status = BT_STATUS_UNSUPPORTED;
15066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            break;
15166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        case BTSOCK_SCO:
15266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            error("bt sco socket not supported, type:%d", type);
15366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            status = BT_STATUS_UNSUPPORTED;
15466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            break;
15566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        default:
15666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            error("unknown bt socket type:%d", type);
15766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            status = BT_STATUS_UNSUPPORTED;
15866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            break;
15966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    }
16066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    return status;
16166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani}
16266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic void btsock_signaled(int fd, int type, int flags, uint32_t user_id)
16366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{
16466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    switch(type)
16566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    {
16666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        case BTSOCK_RFCOMM:
16766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            btsock_rfc_signaled(fd, flags, user_id);
16866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            break;
16966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        case BTSOCK_L2CAP:
17066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            error("bt l2cap socket type not supported, fd:%d, flags:%d", fd, flags);
17166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            break;
17266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        case BTSOCK_SCO:
17366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            error("bt sco socket type not supported, fd:%d, flags:%d", fd, flags);
17466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            break;
17566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani        default:
17666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            error("unknown socket type:%d, fd:%d, flags:%d", type, fd, flags);
17766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani            break;
17866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani    }
17966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani}
18066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani
18166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani
18266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani
183