summaryrefslogtreecommitdiffstats
path: root/btif
diff options
context:
space:
mode:
authorzzy <zhenye@broadcom.com>2012-10-11 14:48:58 -0700
committerMatthew Xie <mattx@google.com>2012-10-15 22:37:12 -0700
commit8aae7556993cdba8995146be134f8b77a8e15ba4 (patch)
tree9b3a5155adabc5f4613b39ab259be86e5ee706e7 /btif
parentd4cfae4991ee5f1d0f56900e6dc39097f9413202 (diff)
downloadexternal_bluetooth_bluedroid-8aae7556993cdba8995146be134f8b77a8e15ba4.zip
external_bluetooth_bluedroid-8aae7556993cdba8995146be134f8b77a8e15ba4.tar.gz
external_bluetooth_bluedroid-8aae7556993cdba8995146be134f8b77a8e15ba4.tar.bz2
Add serial port profile support and allow to connect to rfcomm channel without sdp discovery
bug 7272974 Change-Id: Idc10edc056b48da2fd96bea84eba3fb73b97bab1
Diffstat (limited to 'btif')
-rw-r--r--btif/include/btif_sock_sdp.h8
-rw-r--r--btif/src/btif_sock_rfc.c80
-rw-r--r--btif/src/btif_sock_sdp.c57
3 files changed, 106 insertions, 39 deletions
diff --git a/btif/include/btif_sock_sdp.h b/btif/include/btif_sock_sdp.h
index 5ca9959..9fe4768 100644
--- a/btif/include/btif_sock_sdp.h
+++ b/btif/include/btif_sock_sdp.h
@@ -18,11 +18,17 @@
#ifndef BTIF_SOCK_SDP_H
#define BTIF_SOCK_SDP_H
+static const UINT8 UUID_OBEX_OBJECT_PUSH[] = {0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
+ 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
+static const UINT8 UUID_PBAP_PSE[] = {0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
+ 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
+static const UINT8 UUID_SPP[] = {0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x10, 0x00,
+ 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
static inline BOOLEAN is_uuid_empty(const uint8_t* uuid)
{
static uint8_t empty_uuid[16];
- return memcmp(uuid, empty_uuid, sizeof(empty_uuid)) == 0;
+ return uuid == NULL || memcmp(uuid, empty_uuid, sizeof(empty_uuid)) == 0;
}
int add_rfc_sdp_rec(const char* name, const uint8_t* uuid, int scn);
diff --git a/btif/src/btif_sock_rfc.c b/btif/src/btif_sock_rfc.c
index b77ce4a..6202ca4 100644
--- a/btif/src/btif_sock_rfc.c
+++ b/btif/src/btif_sock_rfc.c
@@ -110,7 +110,8 @@ static void cleanup_rfc_slot(rfc_slot_t* rs);
static inline void close_rfc_connection(int rfc_handle, int server);
static bt_status_t dm_get_remote_service_record(bt_bdaddr_t *remote_addr,
bt_uuid_t *uuid);
-
+static void *rfcomm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data);
+static inline BOOLEAN send_app_scn(rfc_slot_t* rs);
static pthread_mutex_t slot_lock;
#define is_init_done() (pth != -1)
static inline void clear_slot_flag(flags_t* f)
@@ -271,6 +272,7 @@ static rfc_slot_t* alloc_rfc_slot(const bt_bdaddr_t *addr, const char* name, con
rs->scn = channel;
if(uuid)
memcpy(rs->service_uuid, uuid, sizeof(rs->service_uuid));
+ else memset(rs->service_uuid, 0, sizeof(rs->service_uuid));
if(name && *name)
strncpy(rs->service_name, name, sizeof(rs->service_name) -1);
if(addr)
@@ -310,7 +312,7 @@ static inline rfc_slot_t* create_srv_accept_rfc_slot(rfc_slot_t* srv_rs, const b
bt_status_t btsock_rfc_listen(const char* service_name, const uint8_t* service_uuid, int channel,
int* sock_fd, int flags)
{
- if(sock_fd == NULL || (service_uuid == NULL && !is_reserved_rfc_channel(channel)))
+ if(sock_fd == NULL || (service_uuid == NULL && (channel < 1 || channel > 30)))
{
error("invalid rfc channel:%d or sock_fd:%p, uuid:%p", channel, sock_fd, service_uuid);
return BT_STATUS_PARM_INVALID;
@@ -318,13 +320,17 @@ bt_status_t btsock_rfc_listen(const char* service_name, const uint8_t* service_u
*sock_fd = -1;
if(!is_init_done())
return BT_STATUS_NOT_READY;
- //Check the service_uuid. If it uses a reserved channel number, use it
- int reserved_channel = get_reserved_rfc_channel(service_uuid);
- if(reserved_channel >0)
+ if(is_uuid_empty(service_uuid))
+ service_uuid = UUID_SPP; //use serial port profile to listen to specified channel
+ else
{
- channel = reserved_channel;
+ //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);
@@ -344,7 +350,7 @@ bt_status_t btsock_rfc_listen(const char* service_name, const uint8_t* service_u
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 && !is_reserved_rfc_channel(channel)))
+ if(sock_fd == NULL || (service_uuid == NULL && (channel < 1 || channel > 30)))
{
error("invalid rfc channel:%d or sock_fd:%p, uuid:%p", channel, sock_fd, service_uuid);
return BT_STATUS_PARM_INVALID;
@@ -357,31 +363,49 @@ bt_status_t btsock_rfc_connect(const bt_bdaddr_t *bd_addr, const uint8_t* servic
rfc_slot_t* rs = alloc_rfc_slot(bd_addr, NULL, service_uuid, channel, flags, FALSE);
if(rs)
{
-
- //BTA_API extern tBTA_JV_STATUS BTA_JvStartDiscovery(BD_ADDR bd_addr, UINT16 num_uuid,
- // tSDP_UUID *p_uuid_list, void* user_data);
- tSDP_UUID sdp_uuid;
- sdp_uuid.len = 16;
- memcpy(sdp_uuid.uu.uuid128, service_uuid, sizeof(sdp_uuid.uu.uuid128));
- debug("start service channel discovery, slot id:%d, fd:%d, app_fd:%d, security:0x%x, scn:%d",
- rs->id, rs->fd, rs->app_fd, rs->security, rs->scn);
- 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)
+ if(is_uuid_empty(service_uuid))
{
- BTA_JvStartDiscovery((UINT8*)bd_addr->address, 1, &sdp_uuid, (void*)rs->id);
- rs->f.pending_sdp_request = FALSE;
- rs->f.doing_sdp_request = TRUE;
+ debug("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
{
- rs->f.pending_sdp_request = TRUE;
- rs->f.doing_sdp_request = FALSE;
+ tSDP_UUID sdp_uuid;
+ sdp_uuid.len = 16;
+ memcpy(sdp_uuid.uu.uuid128, service_uuid, sizeof(sdp_uuid.uu.uuid128));
+ debug("start service channel discovery, slot id:%d, fd:%d, app_fd:%d, security:0x%x, scn:%d",
+ rs->id, rs->fd, rs->app_fd, rs->security, rs->scn);
+ 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);
}
- btsock_thread_add_fd(pth, rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_RD, rs->id);
}
unlock_slot(&slot_lock);
return status;
diff --git a/btif/src/btif_sock_sdp.c b/btif/src/btif_sock_sdp.c
index 2dfc526..12adb6b 100644
--- a/btif/src/btif_sock_sdp.c
+++ b/btif/src/btif_sock_sdp.c
@@ -64,12 +64,6 @@
#define RESERVED_SCN_OPS 12
#define UUID_MAX_LENGTH 16
-static const UINT8 UUID_OBEX_OBJECT_PUSH[] = {0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
- 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
-
-static const UINT8 UUID_PBAP_PSE[] = {0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
- 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
-
#define IS_UUID(u1,u2) !memcmp(u1,u2,UUID_MAX_LENGTH)
@@ -317,6 +311,45 @@ static int add_ops_sdp(const char *p_service_name,int scn)
return sdp_handle;
}
+#define SPP_NUM_PROTO_ELEMS 2
+static int add_spp_sdp(const char *service_name, int scn)
+{
+ UINT16 serviceclassid = UUID_SERVCLASS_SERIAL_PORT;
+ tSDP_PROTOCOL_ELEM proto_elem_list[SPP_NUM_PROTO_ELEMS];
+ int sdp_handle;
+
+ info("scn %d, service name %s", scn, service_name);
+
+ /* register the service */
+ if ((sdp_handle = SDP_CreateRecord()) != FALSE)
+ {
+ /*** Fill out the protocol element sequence for SDP ***/
+ proto_elem_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
+ proto_elem_list[0].num_params = 0;
+ proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
+ proto_elem_list[1].num_params = 1;
+
+ proto_elem_list[1].params[0] = scn;
+
+ if (SDP_AddProtocolList(sdp_handle, SPP_NUM_PROTO_ELEMS, proto_elem_list))
+ {
+ if (SDP_AddServiceClassIdList(sdp_handle, 1, &serviceclassid))
+ {
+ if ((SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_NAME,
+ TEXT_STR_DESC_TYPE, (UINT32)(strlen(service_name)+1),
+ (UINT8 *)service_name)))
+ {
+ UINT16 list[1];
+ /* Make the service browseable */
+ list[0] = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
+ SDP_AddUuidSequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST,
+ 1, list);
+ }
+ }
+ }
+ }
+ return sdp_handle;
+}
@@ -351,6 +384,10 @@ static int add_rfc_sdp_by_uuid(const char* name, const uint8_t* uuid, int scn)
{
handle = add_pbap_sdp(name, final_scn); //PBAP Server is always 19
}
+ else if (IS_UUID(UUID_SPP, uuid))
+ {
+ handle = add_spp_sdp(name, final_scn);
+ }
else
{
handle = add_sdp_by_uuid(name, uuid, final_scn);
@@ -391,17 +428,17 @@ int add_rfc_sdp_rec(const char* name, const uint8_t* uuid, int scn)
switch(scn)
{
case RESERVED_SCN_PBS: // PBAP Reserved port
- add_pbap_sdp(name, scn);
+ uuid = UUID_PBAP_PSE;
break;
case RESERVED_SCN_OPS:
- add_ops_sdp(name,scn);
+ uuid = UUID_OBEX_OBJECT_PUSH;
break;
default:
+ uuid = UUID_SPP;
break;
}
}
- else
- sdp_handle = add_rfc_sdp_by_uuid(name, uuid, scn);
+ sdp_handle = add_rfc_sdp_by_uuid(name, uuid, scn);
return sdp_handle;
}