#include <sys/fcntl.h>
#include "esp_vfs.h"
#include "esp_vfs_dev.h"
-#include "lwip/opt.h" // just for LWIP_SOCKET_OFFSET
-
-/**
- * BTC_SPP_FDS is the number of file descriptors this VFS driver registers
- */
-#define BTC_SPP_FDS 32
#if (defined BTC_SPP_INCLUDED && BTC_SPP_INCLUDED == TRUE)
spp_slot_t *spp_slots[BTA_JV_MAX_RFC_SR_SESSION + 1];
uint32_t spp_slot_id;
esp_spp_mode_t spp_mode;
- int spp_max_fd;
- int spp_min_fd;
- int spp_fd;
osi_mutex_t spp_slot_mutex;
+ esp_vfs_id_t spp_vfs_id;
} spp_local_param;
static void spp_osi_free(void *p)
osi_free(p);
}
-static int find_free_fd()
-{
- spp_local_param.spp_fd = 1;
- if (spp_local_param.spp_fd < spp_local_param.spp_min_fd || spp_local_param.spp_fd > spp_local_param.spp_max_fd){
- spp_local_param.spp_fd = spp_local_param.spp_min_fd;
- }
- for (size_t i = 1; i <= BTA_JV_MAX_RFC_SR_SESSION; i++) {
- if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->fd == spp_local_param.spp_fd) {
- i = 1;
- spp_local_param.spp_fd++;
- if (spp_local_param.spp_fd < spp_local_param.spp_min_fd || spp_local_param.spp_fd > spp_local_param.spp_max_fd){
- spp_local_param.spp_fd = spp_local_param.spp_min_fd;
- }
- }
- }
- return spp_local_param.spp_fd++;
-}
-
-static spp_slot_t *malloc_spp_slot(void)
+static spp_slot_t *spp_malloc_slot(void)
{
if (++spp_local_param.spp_slot_id == 0) {
spp_local_param.spp_slot_id = 1;
spp_local_param.spp_slots[i]->list = list_new(spp_osi_free);
if (spp_local_param.spp_mode == ESP_SPP_MODE_VFS) {
spp_local_param.spp_slots[i]->incoming_list = list_new(spp_osi_free);
- spp_local_param.spp_slots[i]->fd = find_free_fd();
+ if (esp_vfs_register_fd(spp_local_param.spp_vfs_id, &spp_local_param.spp_slots[i]->fd) != ESP_OK) {
+ osi_free(spp_local_param.spp_slots[i]);
+ return NULL;
+ }
spp_local_param.spp_slots[i]->ringbuf_read = xRingbufferCreate(ESP_SPP_RINGBUF_SIZE, RINGBUF_TYPE_BYTEBUF);
spp_local_param.spp_slots[i]->ringbuf_write = xRingbufferCreate(ESP_SPP_RINGBUF_SIZE, RINGBUF_TYPE_BYTEBUF);
}
return NULL;
}
-static spp_slot_t *find_slot_by_id(uint32_t id)
+static spp_slot_t *spp_find_slot_by_id(uint32_t id)
{
for (size_t i = 1; i <= BTA_JV_MAX_RFC_SR_SESSION; i++) {
if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->id == id) {
return NULL;
}
-static spp_slot_t *find_slot_by_handle(uint32_t handle)
+static spp_slot_t *spp_find_slot_by_handle(uint32_t handle)
{
for (size_t i = 1; i <= BTA_JV_MAX_RFC_SR_SESSION; i++) {
if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->rfc_handle == handle) {
return NULL;
}
-static spp_slot_t *find_slot_by_fd(int fd)
+static spp_slot_t *spp_find_slot_by_fd(int fd)
{
for (size_t i = 1; i <= BTA_JV_MAX_RFC_SR_SESSION; i++) {
if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->fd == fd) {
return NULL;
}
-static void free_spp_slot(spp_slot_t *slot)
+static void spp_free_slot(spp_slot_t *slot)
{
if (!slot) {
return;
spp_local_param.spp_slots[slot->serial] = NULL;
list_free(slot->list);
if (spp_local_param.spp_mode == ESP_SPP_MODE_VFS) {
+ (void) esp_vfs_unregister_fd(spp_local_param.spp_vfs_id, slot->fd);
list_free(slot->incoming_list);
vRingbufferDelete(slot->ringbuf_read);
vRingbufferDelete(slot->ringbuf_write);
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
switch (event) {
case BTA_JV_RFCOMM_SRV_OPEN_EVT:
- slot = find_slot_by_id(id);
+ slot = spp_find_slot_by_id(id);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
break;
}
- slot_new = malloc_spp_slot();
+ slot_new = spp_malloc_slot();
if (!slot_new) {
BTC_TRACE_ERROR("%s unable to malloc RFCOMM slot!", __func__);
break;
slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_data->rfc_srv_open.handle);
break;
case BTA_JV_RFCOMM_OPEN_EVT:
- slot = find_slot_by_id(id);
+ slot = spp_find_slot_by_id(id);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
break;
slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_data->rfc_open.handle);
break;
case BTA_JV_RFCOMM_CLOSE_EVT:
- slot = find_slot_by_id(id);
+ slot = spp_find_slot_by_id(id);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
break;
if (slot->connected) {
BTA_JvRfcommClose(slot->rfc_handle, (void *)slot->id);
}
- free_spp_slot(slot);
+ spp_free_slot(slot);
p_data->rfc_close.status = BTA_JV_SUCCESS;
break;
case BTA_JV_RFCOMM_DATA_IND_EVT:
switch (event) {
case BTA_JV_GET_SCN_EVT:
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
- slot = find_slot_by_id(id);
+ slot = spp_find_slot_by_id(id);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
if (p_data->scn == 0) {
BTC_TRACE_ERROR("%s unable to get scn, start server fail!", __func__);
btc_create_server_fail_cb();
- free_spp_slot(slot);
+ spp_free_slot(slot);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
break;
}
break;
case BTA_JV_CREATE_RECORD_EVT:
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
- slot = find_slot_by_id(id);
+ slot = spp_find_slot_by_id(id);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
BTC_TRACE_ERROR("%s unable to create record, start server fail!", __func__);
btc_create_server_fail_cb();
BTA_JvFreeChannel(slot->scn, BTA_JV_CONN_TYPE_RFCOMM);
- free_spp_slot(slot);
+ spp_free_slot(slot);
}
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
break;
for (size_t i = 1; i <= BTA_JV_MAX_RFC_SR_SESSION; i++) {
if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->connected) {
BTA_JvRfcommClose(spp_local_param.spp_slots[i]->rfc_handle, (void *)spp_local_param.spp_slots[i]->id);
- free_spp_slot(spp_local_param.spp_slots[i]);
+ spp_free_slot(spp_local_param.spp_slots[i]);
spp_local_param.spp_slots[i] = NULL;
}
}
BTA_JvRfcommStopServer(spp_local_param.spp_slots[i]->sdp_handle, (void *)spp_local_param.spp_slots[i]->id);
BTA_JvDeleteRecord(spp_local_param.spp_slots[i]->sdp_handle);
BTA_JvFreeChannel(spp_local_param.spp_slots[i]->scn, BTA_JV_CONN_TYPE_RFCOMM);
- free_spp_slot(spp_local_param.spp_slots[i]);
+ spp_free_slot(spp_local_param.spp_slots[i]);
spp_local_param.spp_slots[i] = NULL;
}
}
static void btc_spp_connect(btc_spp_args_t *arg)
{
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
- spp_slot_t *slot = malloc_spp_slot();
+ spp_slot_t *slot = spp_malloc_slot();
if (!slot) {
BTC_TRACE_ERROR("%s unable to malloc RFCOMM slot!", __func__);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
static void btc_spp_disconnect(btc_spp_args_t *arg)
{
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
- spp_slot_t *slot = find_slot_by_handle(arg->disconnect.handle);
+ spp_slot_t *slot = spp_find_slot_by_handle(arg->disconnect.handle);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot! disconnect fail!", __func__);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
}
BTA_JvRfcommClose(arg->disconnect.handle, (void *)slot->id);
btc_disconnect_cb(slot->rfc_handle);
- free_spp_slot(slot);
+ spp_free_slot(slot);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
}
static void btc_spp_start_srv(btc_spp_args_t *arg)
{
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
- spp_slot_t *slot = malloc_spp_slot();
+ spp_slot_t *slot = spp_malloc_slot();
if (!slot) {
BTC_TRACE_ERROR("%s unable to malloc RFCOMM slot!", __func__);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
static void btc_spp_write(btc_spp_args_t *arg)
{
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
- spp_slot_t *slot = find_slot_by_handle(arg->write.handle);
+ spp_slot_t *slot = spp_find_slot_by_handle(arg->write.handle);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
case BTA_JV_RFCOMM_OPEN_EVT:
if (spp_local_param.spp_mode == ESP_SPP_MODE_VFS) {
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
- slot = find_slot_by_handle(p_data->rfc_open.handle);
+ slot = spp_find_slot_by_handle(p_data->rfc_open.handle);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
case BTA_JV_RFCOMM_SRV_OPEN_EVT:
if (spp_local_param.spp_mode == ESP_SPP_MODE_VFS) {
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
- slot = find_slot_by_handle(p_data->rfc_srv_open.handle);
+ slot = spp_find_slot_by_handle(p_data->rfc_srv_open.handle);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
break;
case BTA_JV_RFCOMM_WRITE_EVT:
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
- slot = find_slot_by_handle(p_data->rfc_write.handle);
+ slot = spp_find_slot_by_handle(p_data->rfc_write.handle);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
btc_spp_cb_to_app(ESP_SPP_CONG_EVT, ¶m);
} else {
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
- slot = find_slot_by_handle(p_data->rfc_cong.handle);
+ slot = spp_find_slot_by_handle(p_data->rfc_cong.handle);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
uint32_t id = (uintptr_t)user_data;
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
- spp_slot_t *slot = find_slot_by_id(id);
+ spp_slot_t *slot = spp_find_slot_by_id(id);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
static ssize_t spp_vfs_write(int fd, const void * data, size_t size)
{
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
- spp_slot_t *slot = find_slot_by_fd(fd);
+ spp_slot_t *slot = spp_find_slot_by_fd(fd);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
static int spp_vfs_close(int fd)
{
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
- spp_slot_t *slot = find_slot_by_fd(fd);
+ spp_slot_t *slot = spp_find_slot_by_fd(fd);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
static ssize_t spp_vfs_read(int fd, void * dst, size_t size)
{
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
- spp_slot_t *slot = find_slot_by_fd(fd);
+ spp_slot_t *slot = spp_find_slot_by_fd(fd);
if (!slot) {
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
return item_size;
}
-void btc_spp_vfs_register()
+esp_err_t btc_spp_vfs_register()
{
esp_vfs_t vfs = {
.flags = ESP_VFS_FLAG_DEFAULT,
.read = spp_vfs_read,
.fcntl = NULL
};
- // File descriptors from LWIP_SOCKET_OFFSET to MAX_FDS-1 are registered
- // for sockets. So here we register from (LWIP_SOCKET_OFFSET - BTC_SPP_FDS)
- // to (LWIP_SOCKET_OFFSET-1) leaving unregistered from 0 to
- // .(LWIP_SOCKET_OFFSET - BTC_SPP_FDS - 1).
- spp_local_param.spp_min_fd = LWIP_SOCKET_OFFSET - BTC_SPP_FDS;
- assert(spp_local_param.spp_min_fd >= 0); //TODO return error instead
- spp_local_param.spp_max_fd = LWIP_SOCKET_OFFSET;
- ESP_ERROR_CHECK(esp_vfs_register_fd_range(&vfs, NULL, spp_local_param.spp_min_fd, spp_local_param.spp_max_fd));//TODO return error if fails
- spp_local_param.spp_fd = spp_local_param.spp_min_fd;
+
+ // No FD range is registered here: spp_vfs_id is used to register/unregister
+ // file descriptors
+ if (esp_vfs_register_with_id(&vfs, NULL, &spp_local_param.spp_vfs_id) != ESP_OK) {
+ return ESP_FAIL;
+ }
+
+ return ESP_OK;
}
#endif ///defined BTC_SPP_INCLUDED && BTC_SPP_INCLUDED == TRUE