diff --git a/android/socket.c b/android/socket.c
index c39e3a3..c1801ca 100644
--- a/android/socket.c
+++ b/android/socket.c
#include "utils.h"
#include "socket.h"
+#define RFCOMM_CHANNEL_MAX 30
+
#define SPP_DEFAULT_CHANNEL 3
#define OPP_DEFAULT_CHANNEL 9
#define PBAP_DEFAULT_CHANNEL 15
static const uint8_t zero_uuid[16] = { 0 };
-/* Simple list of RFCOMM server sockets */
-GList *servers = NULL;
-
/* Simple list of RFCOMM connected sockets */
GList *connections = NULL;
const struct profile_info *profile;
};
+struct rfcomm_channel {
+ bool reserved;
+ struct rfcomm_sock *rfsock;
+};
+
+static struct rfcomm_channel servers[RFCOMM_CHANNEL_MAX + 1];
+
static int rfsock_set_buffer(struct rfcomm_sock *rfsock)
{
socklen_t len = sizeof(int);
return FALSE;
if (cond & (G_IO_ERR | G_IO_HUP )) {
- servers = g_list_remove(servers, rfsock);
+ servers[rfsock->channel].rfsock = NULL;
cleanup_rfsock(rfsock);
}
DBG("chan %d flags 0x%02x uuid %s name %s", chan, flags, uuid_str,
name);
- if (!memcmp(uuid, zero_uuid, sizeof(zero_uuid)) && chan <= 0) {
+ if ((!memcmp(uuid, zero_uuid, sizeof(zero_uuid)) && chan <= 0) ||
+ (chan > RFCOMM_CHANNEL_MAX)) {
error("Invalid rfcomm listen params");
return HAL_STATUS_INVALID;
}
sec_level = profile->sec_level;
}
+ if (servers[chan].rfsock != NULL) {
+ error("Channel already registered (%d)", chan);
+ return HAL_STATUS_BUSY;
+ }
+
DBG("chan %d sec_level %d", chan, sec_level);
rfsock = create_rfsock(-1, hal_sock);
if (!rfsock)
return HAL_STATUS_FAILED;
+ rfsock->channel = chan;
+
io = bt_io_listen(accept_cb, NULL, rfsock, NULL, &err,
BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
BT_IO_OPT_CHANNEL, chan,
rfsock->service_handle = sdp_service_register(profile, name);
- servers = g_list_append(servers, rfsock);
+ servers[chan].rfsock = rfsock;
return HAL_STATUS_SUCCESS;
void bt_socket_register(const bdaddr_t *addr)
{
+ size_t i;
+
DBG("");
+ /* make sure channels assigned for profiles are reserved and not used
+ * for app services
+ */
+ for (i = 0; i < G_N_ELEMENTS(profiles); i++)
+ if (profiles[i].channel)
+ servers[profiles[i].channel].reserved = true;
+
bacpy(&adapter_addr, addr);
ipc_register(HAL_SERVICE_ID_SOCK, cmd_handlers,
G_N_ELEMENTS(cmd_handlers));
void bt_socket_unregister(void)
{
+ int ch;
+
DBG("");
g_list_free_full(connections, cleanup_rfsock);
- g_list_free_full(servers, cleanup_rfsock);
+
+ for (ch = 0; ch <= RFCOMM_CHANNEL_MAX; ch++)
+ if (servers[ch].rfsock)
+ cleanup_rfsock(&servers[ch]);
+
+ memset(servers, 0, sizeof(servers));
ipc_unregister(HAL_SERVICE_ID_SOCK);
}