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 *  Filename:      btif_sock_rfc.c
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Description:   Handsfree Profile Bluetooth Interface
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ***********************************************************************************/
26847ea13e09f3fc1d2a46a8b75109ef89243ace31Sharvil Nanavati#include <assert.h>
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <hardware/bluetooth.h>
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <hardware/bt_sock.h>
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/types.h>
305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/socket.h>
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <errno.h>
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/ioctl.h>
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define LOG_TAG "BTIF_SOCK"
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_common.h"
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_util.h"
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bd.h"
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bta_api.h"
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_sock_thread.h"
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_sock_sdp.h"
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_sock_util.h"
445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_target.h"
465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "gki.h"
475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "hcimsgs.h"
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "sdp_api.h"
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btu.h"
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btm_api.h"
515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btm_int.h"
525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bta_jv_api.h"
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bta_jv_co.h"
545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "port_api.h"
55847ea13e09f3fc1d2a46a8b75109ef89243ace31Sharvil Nanavati#include "list.h"
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <cutils/log.h>
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <hardware/bluetooth.h>
59e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati#define asrt(s) if(!(s)) APPL_TRACE_ERROR("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__)
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectextern void uuid_to_string(bt_uuid_t *p_uuid, char *str);
625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void logu(const char* title, const uint8_t * p_uuid)
635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    char uuids[128];
655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    uuid_to_string((bt_uuid_t*)p_uuid, uuids);
665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    ALOGD("%s: %s", title, uuids);
675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define MAX_RFC_CHANNEL 30
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define MAX_RFC_SESSION BTA_JV_MAX_RFC_SR_SESSION //3 by default
735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef struct {
745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int outgoing_congest : 1;
755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int pending_sdp_request : 1;
765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int doing_sdp_request : 1;
775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int server : 1;
785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int connected : 1;
795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int closing : 1;
805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} flags_t;
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef struct {
835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  flags_t f;
845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  uint32_t id;
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  int security;
865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  int scn;
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  bt_bdaddr_t addr;
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  uint8_t service_uuid[16];
895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  char service_name[256];
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  int fd, app_fd;
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  int mtu;
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  uint8_t* packet;
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  int sdp_handle;
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  int rfc_handle;
955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  int rfc_port_handle;
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  int role;
97847ea13e09f3fc1d2a46a8b75109ef89243ace31Sharvil Nanavati  list_t *incoming_queue;
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} rfc_slot_t;
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic rfc_slot_t rfc_slots[MAX_RFC_CHANNEL];
1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic uint32_t rfc_slot_id;
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic volatile int pth = -1; //poll thread handle
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data);
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void cleanup_rfc_slot(rfc_slot_t* rs);
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void *rfcomm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data);
1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline BOOLEAN send_app_scn(rfc_slot_t* rs);
1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic pthread_mutex_t slot_lock;
1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define is_init_done() (pth != -1)
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void clear_slot_flag(flags_t* f)
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset(f, 0, sizeof(*f));
1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void bd_copy(UINT8* dest, UINT8* src, BOOLEAN swap)
1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (swap)
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        int i;
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for (i =0; i < 6 ;i++)
1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            dest[i]= src[5-i];
1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else memcpy(dest, src, 6);
1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void init_rfc_slots()
1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int i;
1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset(rfc_slots, 0, sizeof(rfc_slot_t)*MAX_RFC_CHANNEL);
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for(i = 0; i < MAX_RFC_CHANNEL; i++)
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rfc_slots[i].scn = -1;
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rfc_slots[i].sdp_handle = 0;
1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rfc_slots[i].fd = rfc_slots[i].app_fd = -1;
133847ea13e09f3fc1d2a46a8b75109ef89243ace31Sharvil Nanavati        rfc_slots[i].incoming_queue = list_new(GKI_freebuf);
134847ea13e09f3fc1d2a46a8b75109ef89243ace31Sharvil Nanavati        assert(rfc_slots[i].incoming_queue != NULL);
1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BTA_JvEnable(jv_dm_cback);
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    init_slot_lock(&slot_lock);
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectbt_status_t btsock_rfc_init(int poll_thread_handle)
1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    pth = poll_thread_handle;
1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    init_rfc_slots();
1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return BT_STATUS_SUCCESS;
1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid btsock_rfc_cleanup()
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int curr_pth = pth;
1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    pth = -1;
1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btsock_thread_exit(curr_pth);
1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    lock_slot(&slot_lock);
1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int i;
1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for(i = 0; i < MAX_RFC_CHANNEL; i++)
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
154847ea13e09f3fc1d2a46a8b75109ef89243ace31Sharvil Nanavati        if(rfc_slots[i].id) {
1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            cleanup_rfc_slot(&rfc_slots[i]);
156847ea13e09f3fc1d2a46a8b75109ef89243ace31Sharvil Nanavati            list_free(rfc_slots[i].incoming_queue);
157847ea13e09f3fc1d2a46a8b75109ef89243ace31Sharvil Nanavati        }
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline rfc_slot_t* find_free_slot()
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int i;
1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for(i = 0; i < MAX_RFC_CHANNEL; i++)
1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(rfc_slots[i].fd == -1)
1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project             return &rfc_slots[i];
1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return NULL;
1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline rfc_slot_t* find_rfc_slot_by_id(uint32_t id)
1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int i;
1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(id)
1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for(i = 0; i < MAX_RFC_CHANNEL; i++)
1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if(rfc_slots[i].id == id)
1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return &rfc_slots[i];
1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
186e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati    APPL_TRACE_WARNING("invalid rfc slot id: %d", id);
1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return NULL;
1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline rfc_slot_t* find_rfc_slot_by_pending_sdp()
1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    uint32_t min_id = (uint32_t)-1;
1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int slot = -1;
1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int i;
1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for(i = 0; i < MAX_RFC_CHANNEL; i++)
1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(rfc_slots[i].id && rfc_slots[i].f.pending_sdp_request)
1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if(rfc_slots[i].id < min_id)
1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                min_id = rfc_slots[i].id;
2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                slot = i;
2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(0<= slot && slot < MAX_RFC_CHANNEL)
2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return &rfc_slots[slot];
2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return NULL;
2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline rfc_slot_t* find_rfc_slot_requesting_sdp()
2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int i;
2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for(i = 0; i < MAX_RFC_CHANNEL; i++)
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(rfc_slots[i].id && rfc_slots[i].f.doing_sdp_request)
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return &rfc_slots[i];
2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
217e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati    APPL_TRACE_DEBUG("can not find any slot is requesting sdp");
2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return NULL;
2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline rfc_slot_t* find_rfc_slot_by_fd(int fd)
2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int i;
2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(fd >= 0)
2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for(i = 0; i < MAX_RFC_CHANNEL; i++)
2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if(rfc_slots[i].fd == fd)
2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if(rfc_slots[i].id)
2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    return &rfc_slots[i];
2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else
2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
234e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati                    APPL_TRACE_ERROR("invalid rfc slot id, cannot be 0");
2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    break;
2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return NULL;
2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic rfc_slot_t* alloc_rfc_slot(const bt_bdaddr_t *addr, const char* name, const uint8_t* uuid, int channel, int flags, BOOLEAN server)
2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int security = 0;
2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(flags & BTSOCK_FLAG_ENCRYPT)
2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        security |= server ? BTM_SEC_IN_ENCRYPT : BTM_SEC_OUT_ENCRYPT;
2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(flags & BTSOCK_FLAG_AUTH)
2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        security |= server ? BTM_SEC_IN_AUTHENTICATE : BTM_SEC_OUT_AUTHENTICATE;
2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_slot_t* rs = find_free_slot();
2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs)
2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        int fds[2] = {-1, -1};
2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(socketpair(AF_LOCAL, SOCK_STREAM, 0, fds))
2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
256e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati            APPL_TRACE_ERROR("socketpair failed, errno:%d", errno);
2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return NULL;
2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rs->fd = fds[0];
2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rs->app_fd = fds[1];
2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rs->security = security;
2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rs->scn = channel;
2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(uuid)
2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memcpy(rs->service_uuid, uuid, sizeof(rs->service_uuid));
2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else memset(rs->service_uuid, 0, sizeof(rs->service_uuid));
2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(name && *name)
2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            strncpy(rs->service_name, name, sizeof(rs->service_name) -1);
2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(addr)
2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            rs->addr = *addr;
2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ++rfc_slot_id;
2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(rfc_slot_id == 0)
2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            rfc_slot_id = 1; //skip 0 when wrapped
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rs->id = rfc_slot_id;
2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rs->f.server = server;
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return rs;
2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// rfc_slot_t* accept_rs = create_srv_accept_rfc_slot(srv_rs, p_open->rem_bda,p_opne->handle,  p_open->new_listen_handle);
2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline rfc_slot_t* create_srv_accept_rfc_slot(rfc_slot_t* srv_rs, const bt_bdaddr_t* addr,
2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                        int open_handle, int new_listen_handle)
2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_slot_t *accept_rs = alloc_rfc_slot(addr, srv_rs->service_name, srv_rs->service_uuid, srv_rs->scn, 0, FALSE);
283a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella    if( accept_rs)
284a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella    {
285a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella        clear_slot_flag(&accept_rs->f);
286a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella        accept_rs->f.server = FALSE;
287a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella        accept_rs->f.connected = TRUE;
288a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella        accept_rs->security = srv_rs->security;
289a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella        accept_rs->mtu = srv_rs->mtu;
290a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella        accept_rs->role = srv_rs->role;
291a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella        accept_rs->rfc_handle = open_handle;
292a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella        accept_rs->rfc_port_handle = BTA_JvRfcommGetPortHdl(open_handle);
293a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella        //now update listen rfc_handle of server slot
294a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella        srv_rs->rfc_handle = new_listen_handle;
295a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella        srv_rs->rfc_port_handle = BTA_JvRfcommGetPortHdl(new_listen_handle);
296afa6e1abbedaad8fe854b0f43999b8aeb801af91Matthew Xie        BTIF_TRACE_DEBUG("create_srv_accept__rfc_slot(open_handle: 0x%x, new_listen_handle:"
297a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella                "0x%x) accept_rs->rfc_handle:0x%x, srv_rs_listen->rfc_handle:0x%x"
298a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella                ,open_handle, new_listen_handle, accept_rs->rfc_port_handle, srv_rs->rfc_port_handle);
299a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella        asrt(accept_rs->rfc_port_handle != srv_rs->rfc_port_handle);
300a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella        //now swap the slot id
301a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella        uint32_t new_listen_id = accept_rs->id;
302a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella        accept_rs->id = srv_rs->id;
303a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella        srv_rs->id = new_listen_id;
304a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella
305a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella        return accept_rs;
306a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella    }
307a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella    else
308a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella    {
309afa6e1abbedaad8fe854b0f43999b8aeb801af91Matthew Xie        APPL_TRACE_ERROR(" accept_rs is NULL %s", __FUNCTION__);
310a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella        return NULL;
311a7bd2a1084569fb7170ebc62b1a2030a6865b797Srinu Jella    }
3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectbt_status_t btsock_rfc_listen(const char* service_name, const uint8_t* service_uuid, int channel,
3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            int* sock_fd, int flags)
3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
316689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project
317e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati    APPL_TRACE_DEBUG("btsock_rfc_listen, service_name:%s", service_name);
3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(sock_fd == NULL || (service_uuid == NULL && (channel < 1 || channel > 30)))
3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
320e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        APPL_TRACE_ERROR("invalid rfc channel:%d or sock_fd:%p, uuid:%p", channel, sock_fd, service_uuid);
3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return BT_STATUS_PARM_INVALID;
3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *sock_fd = -1;
3245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(!is_init_done())
3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return BT_STATUS_NOT_READY;
3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(is_uuid_empty(service_uuid))
3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        service_uuid = UUID_SPP; //use serial port profile to listen to specified channel
3285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        //Check the service_uuid. overwrite the channel # if reserved
3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        int reserved_channel = get_reserved_rfc_channel(service_uuid);
3325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(reserved_channel > 0)
3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            channel = reserved_channel;
3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int status = BT_STATUS_FAIL;
3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    lock_slot(&slot_lock);
3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_slot_t* rs = alloc_rfc_slot(NULL, service_name, service_uuid, channel, flags, TRUE);
3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs)
3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
342e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        APPL_TRACE_DEBUG("BTA_JvCreateRecordByUser:%s", service_name);
34322c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT        BTA_JvCreateRecordByUser((void *)(intptr_t)rs->id);
3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *sock_fd = rs->app_fd;
3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rs->app_fd = -1; //the fd ownership is transferred to app
346ec2777e6a3e8516deff362e5cc732811d0afb1c8Matthew Xie        if (btsock_thread_add_fd(pth, rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_EXCEPTION, rs->id)) {
347ec2777e6a3e8516deff362e5cc732811d0afb1c8Matthew Xie            status = BT_STATUS_SUCCESS;
348ec2777e6a3e8516deff362e5cc732811d0afb1c8Matthew Xie        }
349ec2777e6a3e8516deff362e5cc732811d0afb1c8Matthew Xie        else
350ec2777e6a3e8516deff362e5cc732811d0afb1c8Matthew Xie        {
351ec2777e6a3e8516deff362e5cc732811d0afb1c8Matthew Xie            cleanup_rfc_slot(rs);
352ec2777e6a3e8516deff362e5cc732811d0afb1c8Matthew Xie        }
3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectbt_status_t btsock_rfc_connect(const bt_bdaddr_t *bd_addr, const uint8_t* service_uuid,
3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        int channel, int* sock_fd, int flags)
3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(sock_fd == NULL || (service_uuid == NULL && (channel < 1 || channel > 30)))
3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
362e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        APPL_TRACE_ERROR("invalid rfc channel:%d or sock_fd:%p, uuid:%p", channel, sock_fd,
3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                          service_uuid);
3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return BT_STATUS_PARM_INVALID;
3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *sock_fd = -1;
3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(!is_init_done())
3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return BT_STATUS_NOT_READY;
3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int status = BT_STATUS_FAIL;
3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    lock_slot(&slot_lock);
3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_slot_t* rs = alloc_rfc_slot(bd_addr, NULL, service_uuid, channel, flags, FALSE);
3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs)
3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(is_uuid_empty(service_uuid))
3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
376e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati            APPL_TRACE_DEBUG("connecting to rfcomm channel:%d without service discovery", channel);
3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if(BTA_JvRfcommConnect(rs->security, rs->role, rs->scn, rs->addr.address,
37822c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT                        rfcomm_cback, (void*)(intptr_t)rs->id) == BTA_JV_SUCCESS)
3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if(send_app_scn(rs))
3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    btsock_thread_add_fd(pth, rs->fd, BTSOCK_RFCOMM,
3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                        SOCK_THREAD_FD_RD, rs->id);
3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    *sock_fd = rs->app_fd;
3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    rs->app_fd = -1; //the fd ownership is transferred to app
3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = BT_STATUS_SUCCESS;
3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else cleanup_rfc_slot(rs);
3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else cleanup_rfc_slot(rs);
3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            tSDP_UUID sdp_uuid;
3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            sdp_uuid.len = 16;
3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memcpy(sdp_uuid.uu.uuid128, service_uuid, sizeof(sdp_uuid.uu.uuid128));
3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            logu("service_uuid", service_uuid);
3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *sock_fd = rs->app_fd;
3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            rs->app_fd = -1; //the fd ownership is transferred to app
4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            status = BT_STATUS_SUCCESS;
4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            rfc_slot_t* rs_doing_sdp = find_rfc_slot_requesting_sdp();
4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if(rs_doing_sdp == NULL)
4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
40422c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT                BTA_JvStartDiscovery((UINT8*)bd_addr->address, 1, &sdp_uuid, (void*)(intptr_t)rs->id);
4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                rs->f.pending_sdp_request = FALSE;
4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                rs->f.doing_sdp_request = TRUE;
4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                rs->f.pending_sdp_request = TRUE;
4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                rs->f.doing_sdp_request = FALSE;
4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            btsock_thread_add_fd(pth, rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_RD, rs->id);
4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int create_server_sdp_record(rfc_slot_t* rs)
4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int scn = rs->scn;
4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs->scn > 0)
4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(BTM_TryAllocateSCN(rs->scn) == FALSE)
4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
427e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati            APPL_TRACE_ERROR("rfc channel:%d already in use", scn);
4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return FALSE;
4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if((rs->scn = BTM_AllocateSCN()) == 0)
4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
433e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        APPL_TRACE_ERROR("run out of rfc channels");
4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return FALSE;
4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if((rs->sdp_handle = add_rfc_sdp_rec(rs->service_name, rs->service_uuid, rs->scn)) <= 0)
4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return FALSE;
4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return TRUE;
4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectconst char * jv_evt[] = {
4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_ENABLE_EVT",
4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_SET_DISCOVER_EVT",
4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_LOCAL_ADDR_EVT",
4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_LOCAL_NAME_EVT",
4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_REMOTE_NAME_EVT",
4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_SET_ENCRYPTION_EVT",
4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_GET_SCN_EVT",
4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_GET_PSM_EVT",
4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_DISCOVERY_COMP_EVT",
4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_SERVICES_LEN_EVT",
4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_SERVICE_SEL_EVT",
4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_CREATE_RECORD_EVT",
4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_UPDATE_RECORD_EVT",
4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_ADD_ATTR_EVT",
4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_DELETE_ATTR_EVT",
4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_CANCEL_DISCVRY_EVT",
4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_L2CAP_OPEN_EVT",
4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_L2CAP_CLOSE_EVT",
4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_L2CAP_START_EVT",
4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_L2CAP_CL_INIT_EVT",
4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_L2CAP_DATA_IND_EVT",
4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_L2CAP_CONG_EVT",
4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_L2CAP_READ_EVT",
4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_L2CAP_RECEIVE_EVT",
4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_L2CAP_WRITE_EVT",
4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_RFCOMM_OPEN_EVT",
4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_RFCOMM_CLOSE_EVT",
4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_RFCOMM_START_EVT",
4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_RFCOMM_CL_INIT_EVT",
4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_RFCOMM_DATA_IND_EVT",
4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_RFCOMM_CONG_EVT",
4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_RFCOMM_READ_EVT",
4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_RFCOMM_WRITE_EVT",
4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_RFCOMM_SRV_OPEN_EVT", //  33 /* open status of Server RFCOMM connection */
4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "BTA_JV_MAX_EVT"
4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project};
4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void free_rfc_slot_scn(rfc_slot_t* rs)
4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs->scn > 0)
4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
485689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        if(rs->f.server && !rs->f.closing && rs->rfc_handle)
4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
48722c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT            BTA_JvRfcommStopServer(rs->rfc_handle, (void*)(uintptr_t)rs->id);
4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            rs->rfc_handle = 0;
4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
490689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        if(rs->f.server)
491689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project            BTM_FreeSCN(rs->scn);
4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rs->scn = 0;
4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void cleanup_rfc_slot(rfc_slot_t* rs)
4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
497e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati    APPL_TRACE_DEBUG("cleanup slot:%d, fd:%d, scn:%d, sdp_handle:0x%x", rs->id, rs->fd, rs->scn, rs->sdp_handle);
4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs->fd != -1)
4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        shutdown(rs->fd, 2);
5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        close(rs->fd);
5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rs->fd = -1;
5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs->app_fd != -1)
5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        close(rs->app_fd);
5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rs->app_fd = -1;
5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs->sdp_handle > 0)
5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        del_rfc_sdp_rec(rs->sdp_handle);
5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rs->sdp_handle = 0;
5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs->rfc_handle && !rs->f.closing && !rs->f.server)
5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
516e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        APPL_TRACE_DEBUG("closing rfcomm connection, rfc_handle:0x%x", rs->rfc_handle);
51722c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT        BTA_JvRfcommClose(rs->rfc_handle, (void*)(uintptr_t)rs->id);
5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rs->rfc_handle = 0;
5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    free_rfc_slot_scn(rs);
521847ea13e09f3fc1d2a46a8b75109ef89243ace31Sharvil Nanavati    list_clear(rs->incoming_queue);
5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rs->rfc_port_handle = 0;
5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    //cleanup the flag
5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset(&rs->f, 0, sizeof(rs->f));
5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rs->id = 0;
5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline BOOLEAN send_app_scn(rfc_slot_t* rs)
5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(sock_send_all(rs->fd, (const uint8_t*)&rs->scn, sizeof(rs->scn)) == sizeof(rs->scn))
5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return TRUE;
5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return FALSE;
5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN send_app_connect_signal(int fd, const bt_bdaddr_t* addr, int channel, int status, int send_fd)
5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*
5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    typedef struct {
5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    short size;
5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    bt_bdaddr_t bd_addr;
5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int channel;
5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int status;
5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} __attribute__((packed)) sock_connect_signal_t;
5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*/
5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    sock_connect_signal_t cs;
5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    cs.size = sizeof(cs);
5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    cs.bd_addr = *addr;
5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    cs.channel = channel;
5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    cs.status = status;
5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(send_fd != -1)
5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(sock_send_fd(fd, (const uint8_t*)&cs, sizeof(cs), send_fd) == sizeof(cs))
5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return TRUE;
556e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        else APPL_TRACE_ERROR("sock_send_fd failed, fd:%d, send_fd:%d", fd, send_fd);
5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if(sock_send_all(fd, (const uint8_t*)&cs, sizeof(cs)) == sizeof(cs))
5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return TRUE;
5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return FALSE;
5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void on_cl_rfc_init(tBTA_JV_RFCOMM_CL_INIT *p_init, uint32_t id)
5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   lock_slot(&slot_lock);
5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_slot_t* rs = find_rfc_slot_by_id(id);
5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs)
5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_init->status != BTA_JV_SUCCESS)
5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            cleanup_rfc_slot(rs);
5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            rs->rfc_handle = p_init->handle;
5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void  on_srv_rfc_listen_started(tBTA_JV_RFCOMM_START *p_start, uint32_t id)
5805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    lock_slot(&slot_lock);
5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_slot_t* rs = find_rfc_slot_by_id(id);
5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs)
5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_start->status != BTA_JV_SUCCESS)
5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            cleanup_rfc_slot(rs);
5875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            rs->rfc_handle = p_start->handle;
5905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if(!send_app_scn(rs))
5925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
5935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                //closed
594e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati                APPL_TRACE_DEBUG("send_app_scn() failed, close rs->id:%d", rs->id);
5955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                cleanup_rfc_slot(rs);
5965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
5975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
5985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
6005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic uint32_t on_srv_rfc_connect(tBTA_JV_RFCOMM_SRV_OPEN *p_open, uint32_t id)
6025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    uint32_t new_listen_slot_id = 0;
6045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    lock_slot(&slot_lock);
6055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_slot_t* srv_rs = find_rfc_slot_by_id(id);
6065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(srv_rs)
6075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rfc_slot_t* accept_rs = create_srv_accept_rfc_slot(srv_rs, (const bt_bdaddr_t*)p_open->rem_bda,
6095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                                           p_open->handle, p_open->new_listen_handle);
6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(accept_rs)
6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            //start monitor the socket
6135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            btsock_thread_add_fd(pth, srv_rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_EXCEPTION, srv_rs->id);
6145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            btsock_thread_add_fd(pth, accept_rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_RD, accept_rs->id);
615e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati            APPL_TRACE_DEBUG("sending connect signal & app fd:%dto app server to accept() the connection",
6165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                             accept_rs->app_fd);
617e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati            APPL_TRACE_DEBUG("server fd:%d, scn:%d", srv_rs->fd, srv_rs->scn);
6185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            send_app_connect_signal(srv_rs->fd, &accept_rs->addr, srv_rs->scn, 0, accept_rs->app_fd);
6195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            accept_rs->app_fd = -1; //the fd is closed after sent to app
6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            new_listen_slot_id = srv_rs->id;
6215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
6245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return new_listen_slot_id;
6255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void on_cli_rfc_connect(tBTA_JV_RFCOMM_OPEN *p_open, uint32_t id)
6275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    lock_slot(&slot_lock);
6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_slot_t* rs = find_rfc_slot_by_id(id);
6305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs && p_open->status == BTA_JV_SUCCESS)
6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rs->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_open->handle);
6335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        bd_copy(rs->addr.address, p_open->rem_bda, 0);
6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        //notify app rfc is connected
635e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        APPL_TRACE_DEBUG("call send_app_connect_signal, slot id:%d, fd:%d, rfc scn:%d, server:%d",
6365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                         rs->id, rs->fd, rs->scn, rs->f.server);
6375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(send_app_connect_signal(rs->fd, &rs->addr, rs->scn, 0, -1))
6385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
6395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            //start monitoring the socketpair to get call back when app writing data
640e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati            APPL_TRACE_DEBUG("on_rfc_connect_ind, connect signal sent, slot id:%d, rfc scn:%d, server:%d",
6415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                             rs->id, rs->scn, rs->f.server);
6425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            rs->f.connected = TRUE;
6435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
644e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        else APPL_TRACE_ERROR("send_app_connect_signal failed");
6455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if(rs)
6475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cleanup_rfc_slot(rs);
6485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
6495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void on_rfc_close(tBTA_JV_RFCOMM_CLOSE * p_close, uint32_t id)
6515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6525cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(p_close);
6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    lock_slot(&slot_lock);
6545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_slot_t* rs = find_rfc_slot_by_id(id);
6555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs)
6565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
657e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        APPL_TRACE_DEBUG("on_rfc_close, slot id:%d, fd:%d, rfc scn:%d, server:%d",
6585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                         rs->id, rs->fd, rs->scn, rs->f.server);
6595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        free_rfc_slot_scn(rs);
6602f338f25530d2aaab7acf45701c271d10b81d96dGanesh Ganapathi Batta        // rfc_handle already closed when receiving rfcomm close event from stack.
6615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rs->f.connected = FALSE;
6625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cleanup_rfc_slot(rs);
6635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
6655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void on_rfc_write_done(tBTA_JV_RFCOMM_WRITE *p, uint32_t id)
6675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6685cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(p);
6695cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
6705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    lock_slot(&slot_lock);
6715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_slot_t* rs = find_rfc_slot_by_id(id);
6725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs && !rs->f.outgoing_congest)
6735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        //mointer the fd for any outgoing data
6755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        btsock_thread_add_fd(pth, rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_RD, rs->id);
6765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
6785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void on_rfc_outgoing_congest(tBTA_JV_RFCOMM_CONG *p, uint32_t id)
6805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    lock_slot(&slot_lock);
6825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_slot_t* rs = find_rfc_slot_by_id(id);
6835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs)
6845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rs->f.outgoing_congest = p->cong ? 1 : 0;
6865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        //mointer the fd for any outgoing data
6875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(!rs->f.outgoing_congest)
6885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            btsock_thread_add_fd(pth, rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_RD, rs->id);
6895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
6915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void *rfcomm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data)
6945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int rc;
6965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    void* new_user_data = NULL;
697e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati    APPL_TRACE_DEBUG("event=%s", jv_evt[event]);
6985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    switch (event)
7005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BTA_JV_RFCOMM_START_EVT:
70222c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT        on_srv_rfc_listen_started(&p_data->rfc_start, (uintptr_t)user_data);
7035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
7045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BTA_JV_RFCOMM_CL_INIT_EVT:
70622c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT        on_cl_rfc_init(&p_data->rfc_cl_init, (uintptr_t)user_data);
7075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
7085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BTA_JV_RFCOMM_OPEN_EVT:
7102f338f25530d2aaab7acf45701c271d10b81d96dGanesh Ganapathi Batta        BTA_JvSetPmProfile(p_data->rfc_open.handle,BTA_JV_PM_ID_1,BTA_JV_CONN_OPEN);
71122c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT        on_cli_rfc_connect(&p_data->rfc_open, (uintptr_t)user_data);
7125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
7135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BTA_JV_RFCOMM_SRV_OPEN_EVT:
7142f338f25530d2aaab7acf45701c271d10b81d96dGanesh Ganapathi Batta        BTA_JvSetPmProfile(p_data->rfc_srv_open.handle,BTA_JV_PM_ALL,BTA_JV_CONN_OPEN);
71522c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT        new_user_data = (void*)(intptr_t)on_srv_rfc_connect(&p_data->rfc_srv_open, (uintptr_t)user_data);
7165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
7175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BTA_JV_RFCOMM_CLOSE_EVT:
719afa6e1abbedaad8fe854b0f43999b8aeb801af91Matthew Xie        APPL_TRACE_DEBUG("BTA_JV_RFCOMM_CLOSE_EVT: user_data:%d", (uintptr_t)user_data);
72022c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT        on_rfc_close(&p_data->rfc_close, (uintptr_t)user_data);
7215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
7225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BTA_JV_RFCOMM_READ_EVT:
724e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        APPL_TRACE_DEBUG("BTA_JV_RFCOMM_READ_EVT not used");
7255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
7265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BTA_JV_RFCOMM_WRITE_EVT:
72822c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT        on_rfc_write_done(&p_data->rfc_write, (uintptr_t)user_data);
7295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
7305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BTA_JV_RFCOMM_DATA_IND_EVT:
732e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        APPL_TRACE_DEBUG("BTA_JV_RFCOMM_DATA_IND_EVT not used");
7335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
7345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case BTA_JV_RFCOMM_CONG_EVT:
7365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        //on_rfc_cong(&p_data->rfc_cong);
73722c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT        on_rfc_outgoing_congest(&p_data->rfc_cong, (uintptr_t)user_data);
7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
7395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    default:
740afa6e1abbedaad8fe854b0f43999b8aeb801af91Matthew Xie        APPL_TRACE_ERROR("unhandled event %d, slot id:%d", event, (uintptr_t)user_data);
7415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
7425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return new_user_data;
7445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data)
7475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
74822c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT    uint32_t id = (uintptr_t)user_data;
749e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati    APPL_TRACE_DEBUG("jv_dm_cback: event:%d, slot id:%d", event, id);
7505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    switch(event)
7515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case BTA_JV_CREATE_RECORD_EVT:
7535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
7545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                lock_slot(&slot_lock);
7555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                rfc_slot_t* rs = find_rfc_slot_by_id(id);
7565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if(rs && create_server_sdp_record(rs))
7575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
7585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    //now start the rfcomm server after sdp & channel # assigned
7595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    BTA_JvRfcommStartServer(rs->security, rs->role, rs->scn, MAX_RFC_SESSION, rfcomm_cback,
76022c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT                                            (void*)(uintptr_t)rs->id);
7615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
762689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project                else if(rs)
763689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project                {
764e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati                    APPL_TRACE_ERROR("jv_dm_cback: cannot start server, slot found:%p", rs);
765689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project                    cleanup_rfc_slot(rs);
766689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project                }
7675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                unlock_slot(&slot_lock);
7685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
7695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
7705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case BTA_JV_DISCOVERY_COMP_EVT:
7715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
7725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                rfc_slot_t* rs = NULL;
7735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                lock_slot(&slot_lock);
7745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if(p_data->disc_comp.status == BTA_JV_SUCCESS && p_data->disc_comp.scn)
7755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
776e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati                    APPL_TRACE_DEBUG("BTA_JV_DISCOVERY_COMP_EVT, slot id:%d, status:%d, scn:%d",
7775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                      id, p_data->disc_comp.status, p_data->disc_comp.scn);
7785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    rs = find_rfc_slot_by_id(id);
7805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if(rs && rs->f.doing_sdp_request)
7815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
7825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        if(BTA_JvRfcommConnect(rs->security, rs->role, p_data->disc_comp.scn, rs->addr.address,
78322c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT                                    rfcomm_cback, (void*)(uintptr_t)rs->id) == BTA_JV_SUCCESS)
7845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        {
7855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            rs->scn = p_data->disc_comp.scn;
7865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            rs->f.doing_sdp_request = FALSE;
7875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            if(!send_app_scn(rs))
7885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                cleanup_rfc_slot(rs);
7895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        }
7905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        else cleanup_rfc_slot(rs);
7915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
7925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    else if(rs)
7935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
794e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati                        APPL_TRACE_ERROR("DISCOVERY_COMP_EVT no pending sdp request, slot id:%d, \
7955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                flag sdp pending:%d, flag sdp doing:%d",
7965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                id, rs->f.pending_sdp_request, rs->f.doing_sdp_request);
7975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
7985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
7995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else
8005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
801e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati                    APPL_TRACE_ERROR("DISCOVERY_COMP_EVT slot id:%d, failed to find channle, \
8025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                      status:%d, scn:%d", id, p_data->disc_comp.status,
8035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                      p_data->disc_comp.scn);
8045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    rs = find_rfc_slot_by_id(id);
8055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if(rs)
8065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        cleanup_rfc_slot(rs);
8075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
8085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                rs = find_rfc_slot_by_pending_sdp();
8095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if(rs)
8105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
811e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati                    APPL_TRACE_DEBUG("BTA_JV_DISCOVERY_COMP_EVT, start another pending scn sdp request");
8125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    tSDP_UUID sdp_uuid;
8135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    sdp_uuid.len = 16;
8145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    memcpy(sdp_uuid.uu.uuid128, rs->service_uuid, sizeof(sdp_uuid.uu.uuid128));
81522c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT                    BTA_JvStartDiscovery((UINT8*)rs->addr.address, 1, &sdp_uuid, (void*)(uintptr_t)rs->id);
8165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    rs->f.pending_sdp_request = FALSE;
8175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    rs->f.doing_sdp_request = TRUE;
8185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
8195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                unlock_slot(&slot_lock);
8205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
8215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
8225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        default:
823e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati            APPL_TRACE_DEBUG("unhandled event:%d, slot id:%d", event, id);
8245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
8255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define SENT_ALL 2
8295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define SENT_PARTIAL 1
8305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define SENT_NONE 0
8315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define SENT_FAILED (-1)
8325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int send_data_to_app(int fd, BT_HDR *p_buf)
8335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
8345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(p_buf->len == 0)
8355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return SENT_ALL;
8365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int sent = send(fd, (UINT8 *)(p_buf + 1) + p_buf->offset,  p_buf->len, MSG_DONTWAIT);
8375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(sent == p_buf->len)
8385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return SENT_ALL;
8395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(sent > 0 && sent < p_buf->len)
8415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        //sent partial
843e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        APPL_TRACE_ERROR("send partial, sent:%d, p_buf->len:%d", sent, p_buf->len);
8445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->offset += sent;
8455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->len -= sent;
8465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return SENT_PARTIAL;
8475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(sent < 0 &&
8505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR))
8515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
852e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        APPL_TRACE_ERROR("send none, EAGAIN or EWOULDBLOCK, errno:%d", errno);
8535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return SENT_NONE;
8545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
855e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati    APPL_TRACE_ERROR("unknown send() error, sent:%d, p_buf->len:%d,  errno:%d", sent, p_buf->len, errno);
8565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return SENT_FAILED;
8575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN flush_incoming_que_on_wr_signal(rfc_slot_t* rs)
8595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
860847ea13e09f3fc1d2a46a8b75109ef89243ace31Sharvil Nanavati    while(!list_is_empty(rs->incoming_queue))
8615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
862847ea13e09f3fc1d2a46a8b75109ef89243ace31Sharvil Nanavati        BT_HDR *p_buf = list_front(rs->incoming_queue);
8635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        int sent = send_data_to_app(rs->fd, p_buf);
8645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        switch(sent)
8655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
8665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case SENT_NONE:
8675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case SENT_PARTIAL:
8685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                //monitor the fd to get callback when app is ready to receive data
8695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                btsock_thread_add_fd(pth, rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_WR, rs->id);
8705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return TRUE;
8715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case SENT_ALL:
872694988f6aadc9ff9611c595a9863661c85da2e0fZhenye Zhu                list_remove(rs->incoming_queue, p_buf);
873694988f6aadc9ff9611c595a9863661c85da2e0fZhenye Zhu                break;
8745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case SENT_FAILED:
875847ea13e09f3fc1d2a46a8b75109ef89243ace31Sharvil Nanavati                list_remove(rs->incoming_queue, p_buf);
8765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return FALSE;
8775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
8785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    //app is ready to receive data, tell stack to start the data flow
8815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    //fix me: need a jv flow control api to serialize the call in stack
882e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati    APPL_TRACE_DEBUG("enable data flow, rfc_handle:0x%x, rfc_port_handle:0x%x, user_id:%d",
883181adbef76c194e257639daecb486bfc9a0ad037zzy                        rs->rfc_handle, rs->rfc_port_handle, rs->id);
884181adbef76c194e257639daecb486bfc9a0ad037zzy    extern int PORT_FlowControl_MaxCredit(UINT16 handle, BOOLEAN enable);
885181adbef76c194e257639daecb486bfc9a0ad037zzy    PORT_FlowControl_MaxCredit(rs->rfc_port_handle, TRUE);
8865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return TRUE;
8875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid btsock_rfc_signaled(int fd, int flags, uint32_t user_id)
8895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
8905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    lock_slot(&slot_lock);
8915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_slot_t* rs = find_rfc_slot_by_id(user_id);
8925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs)
8935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
894e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati        APPL_TRACE_DEBUG("rfc slot id:%d, fd:%d, flags:%x", rs->id, fd, flags);
8955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        BOOLEAN need_close = FALSE;
8965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(flags & SOCK_THREAD_FD_RD)
8975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
8985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            //data available from app, tell stack we have outgoing data
8995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if(!rs->f.server)
9005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
9015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if(rs->f.connected)
9029ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie                {
9039ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie                    int size = 0;
9049ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie                    //make sure there's data pending in case the peer closed the socket
9059ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie                    if(!(flags & SOCK_THREAD_FD_EXCEPTION) ||
9069ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie                                (ioctl(rs->fd, FIONREAD, &size) == 0 && size))
907359895efb36a7e4f65fbcc9a28221b6ede44aaddgit-zhenye.broadcom.com                    {
908359895efb36a7e4f65fbcc9a28221b6ede44aaddgit-zhenye.broadcom.com                        int rfc_handle = rs->rfc_handle;
909359895efb36a7e4f65fbcc9a28221b6ede44aaddgit-zhenye.broadcom.com                        UINT32 rs_id = rs->id;
910359895efb36a7e4f65fbcc9a28221b6ede44aaddgit-zhenye.broadcom.com                        //unlock before BTA_JvRfcommWrite to avoid deadlock on concurrnet multi rfcomm connectoins
911359895efb36a7e4f65fbcc9a28221b6ede44aaddgit-zhenye.broadcom.com                        unlock_slot(&slot_lock);
912359895efb36a7e4f65fbcc9a28221b6ede44aaddgit-zhenye.broadcom.com                        BTA_JvRfcommWrite(rfc_handle, rs_id);
913359895efb36a7e4f65fbcc9a28221b6ede44aaddgit-zhenye.broadcom.com                        return;
914359895efb36a7e4f65fbcc9a28221b6ede44aaddgit-zhenye.broadcom.com                    }
9159ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie                }
9165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else
9175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
918e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati                    APPL_TRACE_ERROR("SOCK_THREAD_FD_RD signaled when rfc is not connected, \
9195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                      slot id:%d, channel:%d", rs->id, rs->scn);
9205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    need_close = TRUE;
9215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
9225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
9235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
9245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(flags & SOCK_THREAD_FD_WR)
9255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
9265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            //app is ready to receive more data, tell stack to enable the data flow
9275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if(!rs->f.connected || !flush_incoming_que_on_wr_signal(rs))
9285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
9295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                need_close = TRUE;
930e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati                APPL_TRACE_ERROR("SOCK_THREAD_FD_WR signaled when rfc is not connected \
9315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                  or app closed fd, slot id:%d, channel:%d", rs->id, rs->scn);
9325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
9335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
9355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(need_close || (flags & SOCK_THREAD_FD_EXCEPTION))
9365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
9379ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie            int size = 0;
9389ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie            if(need_close || ioctl(rs->fd, FIONREAD, &size) != 0 || size == 0 )
9399ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie            {
9409ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie                //cleanup when no data pending
941e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati                APPL_TRACE_DEBUG("SOCK_THREAD_FD_EXCEPTION, cleanup, flags:%x, need_close:%d, pending size:%d",
9429ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie                                flags, need_close, size);
9439ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie                cleanup_rfc_slot(rs);
9449ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie            }
9455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
946e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati                APPL_TRACE_DEBUG("SOCK_THREAD_FD_EXCEPTION, cleanup pending, flags:%x, need_close:%d, pending size:%d",
9479ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie                                flags, need_close, size);
9485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
9495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
9515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9522f338f25530d2aaab7acf45701c271d10b81d96dGanesh Ganapathi Batta
9535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint bta_co_rfc_data_incoming(void *user_data, BT_HDR *p_buf)
9545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
95522c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT    uint32_t id = (uintptr_t)user_data;
9565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int ret = 0;
9575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    lock_slot(&slot_lock);
9585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_slot_t* rs = find_rfc_slot_by_id(id);
9595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs)
9605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
961847ea13e09f3fc1d2a46a8b75109ef89243ace31Sharvil Nanavati        if(!list_is_empty(rs->incoming_queue))
962847ea13e09f3fc1d2a46a8b75109ef89243ace31Sharvil Nanavati            list_append(rs->incoming_queue, p_buf);
963031d239b408618294a5980cb3933e03e185f96cfzzy        else
9645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
965031d239b408618294a5980cb3933e03e185f96cfzzy            int sent = send_data_to_app(rs->fd, p_buf);
966031d239b408618294a5980cb3933e03e185f96cfzzy            switch(sent)
967031d239b408618294a5980cb3933e03e185f96cfzzy            {
968031d239b408618294a5980cb3933e03e185f96cfzzy                case SENT_NONE:
969031d239b408618294a5980cb3933e03e185f96cfzzy                case SENT_PARTIAL:
970031d239b408618294a5980cb3933e03e185f96cfzzy                    //add it to the end of the queue
971847ea13e09f3fc1d2a46a8b75109ef89243ace31Sharvil Nanavati                    list_append(rs->incoming_queue, p_buf);
972031d239b408618294a5980cb3933e03e185f96cfzzy                    //monitor the fd to get callback when app is ready to receive data
973031d239b408618294a5980cb3933e03e185f96cfzzy                    btsock_thread_add_fd(pth, rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_WR, rs->id);
974031d239b408618294a5980cb3933e03e185f96cfzzy                    break;
975031d239b408618294a5980cb3933e03e185f96cfzzy                case SENT_ALL:
976031d239b408618294a5980cb3933e03e185f96cfzzy                    GKI_freebuf(p_buf);
977031d239b408618294a5980cb3933e03e185f96cfzzy                    ret = 1;//enable the data flow
978031d239b408618294a5980cb3933e03e185f96cfzzy                    break;
979031d239b408618294a5980cb3933e03e185f96cfzzy                case SENT_FAILED:
980031d239b408618294a5980cb3933e03e185f96cfzzy                    GKI_freebuf(p_buf);
981031d239b408618294a5980cb3933e03e185f96cfzzy                    cleanup_rfc_slot(rs);
982031d239b408618294a5980cb3933e03e185f96cfzzy                    break;
983031d239b408618294a5980cb3933e03e185f96cfzzy            }
9845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
9855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     }
9865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
9875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return ret;//return 0 to disable data flow
9885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint bta_co_rfc_data_outgoing_size(void *user_data, int *size)
9905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
99122c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT    uint32_t id = (uintptr_t)user_data;
9925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int ret = FALSE;
9935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *size = 0;
9945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    lock_slot(&slot_lock);
9955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_slot_t* rs = find_rfc_slot_by_id(id);
9965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs)
9975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(ioctl(rs->fd, FIONREAD, size) == 0)
9995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1000e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati            APPL_TRACE_DEBUG("ioctl read avaiable size:%d, fd:%d", *size, rs->fd);
10015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ret = TRUE;
10025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
10035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
10045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1005e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati            APPL_TRACE_ERROR("ioctl FIONREAD error, errno:%d, fd:%d", errno, rs->fd);
10065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            cleanup_rfc_slot(rs);
10075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
10085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1009e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati    else APPL_TRACE_ERROR("bta_co_rfc_data_outgoing_size, invalid slot id:%d", id);
10105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
10115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return ret;
10125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint bta_co_rfc_data_outgoing(void *user_data, UINT8* buf, UINT16 size)
10145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
101522c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT    uint32_t id = (uintptr_t)user_data;
10165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int ret = FALSE;
10175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    lock_slot(&slot_lock);
10185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_slot_t* rs = find_rfc_slot_by_id(id);
10195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(rs)
10205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        int received = recv(rs->fd, buf, size, 0);
10225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(received == size)
10235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ret = TRUE;
10245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
10255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1026e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati            APPL_TRACE_ERROR("recv error, errno:%d, fd:%d, size:%d, received:%d",
10275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                             errno, rs->fd, size, received);
10285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            cleanup_rfc_slot(rs);
10295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
10305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1031e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati    else APPL_TRACE_ERROR("bta_co_rfc_data_outgoing, invalid slot id:%d", id);
10325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
10335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return ret;
10345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1036