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