// rfc_slot_t* accept_rs = create_srv_accept_rfc_slot(srv_rs, p_open->rem_bda,p_opne->handle, p_open->new_listen_handle); static inline rfc_slot_t* create_srv_accept_rfc_slot(rfc_slot_t* srv_rs, const bt_bdaddr_t* addr, int open_handle, int new_listen_handle) { rfc_slot_t *accept_rs = alloc_rfc_slot(addr, srv_rs->service_name, srv_rs->service_uuid, srv_rs->scn, 0, FALSE); clear_slot_flag(&accept_rs->f); accept_rs->f.server = FALSE; accept_rs->f.connected = TRUE; accept_rs->security = srv_rs->security; accept_rs->mtu = srv_rs->mtu; accept_rs->role = srv_rs->role; accept_rs->rfc_handle = open_handle; accept_rs->rfc_port_handle = BTA_JvRfcommGetPortHdl(open_handle); //now update listen rfc_handle of server slot srv_rs->rfc_handle = new_listen_handle; srv_rs->rfc_port_handle = BTA_JvRfcommGetPortHdl(new_listen_handle); BTIF_TRACE_DEBUG4("create_srv_accept__rfc_slot(open_handle: 0x%x, new_listen_handle:" "0x%x) accept_rs->rfc_handle:0x%x, srv_rs_listen->rfc_handle:0x%x" ,open_handle, new_listen_handle, accept_rs->rfc_port_handle, srv_rs->rfc_port_handle); asrt(accept_rs->rfc_port_handle != srv_rs->rfc_port_handle); //now swap the slot id uint32_t new_listen_id = accept_rs->id; accept_rs->id = srv_rs->id; srv_rs->id = new_listen_id; return accept_rs; }
static rfc_slot_t *create_srv_accept_rfc_slot(rfc_slot_t *srv_rs, const bt_bdaddr_t *addr, int open_handle, int new_listen_handle) { rfc_slot_t *accept_rs = alloc_rfc_slot(addr, srv_rs->service_name, srv_rs->service_uuid, srv_rs->scn, 0, false); if (!accept_rs) { LOG_ERROR(LOG_TAG, "%s unable to allocate RFCOMM slot.", __func__); return NULL; } accept_rs->f.server = false; accept_rs->f.connected = true; accept_rs->security = srv_rs->security; accept_rs->mtu = srv_rs->mtu; accept_rs->role = srv_rs->role; accept_rs->rfc_handle = open_handle; accept_rs->rfc_port_handle = BTA_JvRfcommGetPortHdl(open_handle); srv_rs->rfc_handle = new_listen_handle; srv_rs->rfc_port_handle = BTA_JvRfcommGetPortHdl(new_listen_handle); assert(accept_rs->rfc_port_handle != srv_rs->rfc_port_handle); // now swap the slot id uint32_t new_listen_id = accept_rs->id; accept_rs->id = srv_rs->id; srv_rs->id = new_listen_id; return accept_rs; }
bt_status_t btsock_rfc_connect(const bt_bdaddr_t *bd_addr, const uint8_t *service_uuid, int channel, int *sock_fd, int flags) { assert(sock_fd != NULL); assert(service_uuid != NULL || (channel >= 1 && channel <= MAX_RFC_CHANNEL)); *sock_fd = INVALID_FD; // TODO(sharvil): not sure that this check makes sense; seems like a logic error to call // functions on RFCOMM sockets before initializing the module. Probably should be an assert. if (!is_init_done()) return BT_STATUS_NOT_READY; int status = BT_STATUS_FAIL; pthread_mutex_lock(&slot_lock); rfc_slot_t *slot = alloc_rfc_slot(bd_addr, NULL, service_uuid, channel, flags, false); if (!slot) { LOG_ERROR(LOG_TAG, "%s unable to allocate RFCOMM slot.", __func__); goto out; } if (is_uuid_empty(service_uuid)) { tBTA_JV_STATUS ret = BTA_JvRfcommConnect(slot->security, slot->role, slot->scn, slot->addr.address, rfcomm_cback, (void *)(uintptr_t)slot->id); if (ret != BTA_JV_SUCCESS) { LOG_ERROR(LOG_TAG, "%s unable to initiate RFCOMM connection: %d", __func__, ret); cleanup_rfc_slot(slot); goto out; } if (!send_app_scn(slot)) { LOG_ERROR(LOG_TAG, "%s unable to send channel number.", __func__); cleanup_rfc_slot(slot); goto out; } } else { tSDP_UUID sdp_uuid; sdp_uuid.len = 16; memcpy(sdp_uuid.uu.uuid128, service_uuid, sizeof(sdp_uuid.uu.uuid128)); if (!is_requesting_sdp()) { BTA_JvStartDiscovery((uint8_t *)bd_addr->address, 1, &sdp_uuid, (void *)(uintptr_t)slot->id); slot->f.pending_sdp_request = false; slot->f.doing_sdp_request = true; } else { slot->f.pending_sdp_request = true; slot->f.doing_sdp_request = false; } } *sock_fd = slot->app_fd; // Transfer ownership of fd to caller. slot->app_fd = INVALID_FD; // Drop our reference to the fd. btsock_thread_add_fd(pth, slot->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_RD, slot->id); status = BT_STATUS_SUCCESS; out:; pthread_mutex_unlock(&slot_lock); return status; }
bt_status_t btsock_rfc_listen(const char *service_name, const uint8_t *service_uuid, int channel, int *sock_fd, int flags) { assert(sock_fd != NULL); assert((service_uuid != NULL) || (channel >= 1 && channel <= MAX_RFC_CHANNEL) || ((flags & BTSOCK_FLAG_NO_SDP) != 0)); *sock_fd = INVALID_FD; // TODO(sharvil): not sure that this check makes sense; seems like a logic error to call // functions on RFCOMM sockets before initializing the module. Probably should be an assert. if (!is_init_done()) return BT_STATUS_NOT_READY; if((flags & BTSOCK_FLAG_NO_SDP) == 0) { if(is_uuid_empty(service_uuid)) { APPL_TRACE_DEBUG("BTA_JvGetChannelId: service_uuid not set AND " "BTSOCK_FLAG_NO_SDP is not set - changing to SPP"); service_uuid = UUID_SPP; // Use serial port profile to listen to specified channel } else { //Check the service_uuid. overwrite the channel # if reserved int reserved_channel = get_reserved_rfc_channel(service_uuid); if (reserved_channel > 0) { channel = reserved_channel; } } } int status = BT_STATUS_FAIL; pthread_mutex_lock(&slot_lock); rfc_slot_t *slot = alloc_rfc_slot(NULL, service_name, service_uuid, channel, flags, true); if (!slot) { LOG_ERROR(LOG_TAG, "%s unable to allocate RFCOMM slot.", __func__); goto out; } APPL_TRACE_DEBUG("BTA_JvGetChannelId: service_name: %s - channel: %d", service_name, channel); BTA_JvGetChannelId(BTA_JV_CONN_TYPE_RFCOMM, UINT_TO_PTR(slot->id), channel); *sock_fd = slot->app_fd; // Transfer ownership of fd to caller. /*TODO: * We are leaking one of the app_fd's - either the listen socket, or the connection socket. * WE need to close this in native, as the FD might belong to another process - This is the server socket FD - For accepted connections, we close the FD after passing it to JAVA. - Try to simply remove the = -1 to free the FD at rs cleanup.*/ // close(rs->app_fd); slot->app_fd = INVALID_FD; // Drop our reference to the fd. btsock_thread_add_fd(pth, slot->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_EXCEPTION, slot->id); status = BT_STATUS_SUCCESS; out:; pthread_mutex_unlock(&slot_lock); return status; }
bt_status_t btsock_rfc_listen(const char* service_name, const uint8_t* service_uuid, int channel, int* sock_fd, int flags) { APPL_TRACE_DEBUG1("btsock_rfc_listen, service_name:%s", service_name); if(sock_fd == NULL || (service_uuid == NULL && (channel < 1 || channel > 30))) { APPL_TRACE_ERROR3("invalid rfc channel:%d or sock_fd:%p, uuid:%p", channel, sock_fd, service_uuid); return BT_STATUS_PARM_INVALID; } *sock_fd = -1; if(!is_init_done()) return BT_STATUS_NOT_READY; if(is_uuid_empty(service_uuid)) service_uuid = UUID_SPP; //use serial port profile to listen to specified channel else { //Check the service_uuid. overwrite the channel # if reserved int reserved_channel = get_reserved_rfc_channel(service_uuid); if(reserved_channel > 0) { channel = reserved_channel; } } int status = BT_STATUS_FAIL; lock_slot(&slot_lock); rfc_slot_t* rs = alloc_rfc_slot(NULL, service_name, service_uuid, channel, flags, TRUE); if(rs) { APPL_TRACE_DEBUG1("BTA_JvCreateRecordByUser:%s", service_name); BTA_JvCreateRecordByUser((void *)rs->id); *sock_fd = rs->app_fd; rs->app_fd = -1; //the fd ownership is transferred to app status = BT_STATUS_SUCCESS; btsock_thread_add_fd(pth, rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_EXCEPTION, rs->id); } unlock_slot(&slot_lock); return status; }
bt_status_t btsock_rfc_connect(const bt_bdaddr_t *bd_addr, const uint8_t* service_uuid, int channel, int* sock_fd, int flags) { if(sock_fd == NULL || (service_uuid == NULL && (channel < 1 || channel > 30))) { APPL_TRACE_ERROR3("invalid rfc channel:%d or sock_fd:%p, uuid:%p", channel, sock_fd, service_uuid); return BT_STATUS_PARM_INVALID; } *sock_fd = -1; if(!is_init_done()) return BT_STATUS_NOT_READY; int status = BT_STATUS_FAIL; lock_slot(&slot_lock); rfc_slot_t* rs = alloc_rfc_slot(bd_addr, NULL, service_uuid, channel, flags, FALSE); if(rs) { if(is_uuid_empty(service_uuid)) { APPL_TRACE_DEBUG1("connecting to rfcomm channel:%d without service discovery", channel); if(BTA_JvRfcommConnect(rs->security, rs->role, rs->scn, rs->addr.address, rfcomm_cback, (void*)rs->id) == BTA_JV_SUCCESS) { if(send_app_scn(rs)) { btsock_thread_add_fd(pth, rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_RD, rs->id); *sock_fd = rs->app_fd; rs->app_fd = -1; //the fd ownership is transferred to app status = BT_STATUS_SUCCESS; } else cleanup_rfc_slot(rs); } else cleanup_rfc_slot(rs); } else { tSDP_UUID sdp_uuid; sdp_uuid.len = 16; memcpy(sdp_uuid.uu.uuid128, service_uuid, sizeof(sdp_uuid.uu.uuid128)); logu("service_uuid", service_uuid); *sock_fd = rs->app_fd; rs->app_fd = -1; //the fd ownership is transferred to app status = BT_STATUS_SUCCESS; rfc_slot_t* rs_doing_sdp = find_rfc_slot_requesting_sdp(); if(rs_doing_sdp == NULL) { BTA_JvStartDiscovery((UINT8*)bd_addr->address, 1, &sdp_uuid, (void*)rs->id); rs->f.pending_sdp_request = FALSE; rs->f.doing_sdp_request = TRUE; } else { rs->f.pending_sdp_request = TRUE; rs->f.doing_sdp_request = FALSE; } btsock_thread_add_fd(pth, rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_RD, rs->id); } } unlock_slot(&slot_lock); return status; }