Making progress on ble
This commit is contained in:
parent
e80361061c
commit
28cb8981b2
|
@ -64,6 +64,8 @@ static QueueHandle_t response_queue;
|
||||||
static int struct_pack_index;
|
static int struct_pack_index;
|
||||||
static int struct_unpack_index;
|
static int struct_unpack_index;
|
||||||
|
|
||||||
|
static enum { STOPPED, RUNNING, SHUTTING } inited;
|
||||||
|
|
||||||
static int seqno;
|
static int seqno;
|
||||||
|
|
||||||
// Note that the buffer should be freed
|
// Note that the buffer should be freed
|
||||||
|
@ -490,7 +492,21 @@ lble_build_gatt_svcs(lua_State *L, struct ble_gatt_svc_def **resultp) {
|
||||||
|
|
||||||
if (lua_getfield(L, -1, "value") != LUA_TNIL) {
|
if (lua_getfield(L, -1, "value") != LUA_TNIL) {
|
||||||
chr->flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE;
|
chr->flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE;
|
||||||
lua_pop(L, 1); // pop off value
|
|
||||||
|
int flags = 0;
|
||||||
|
lua_getfield(L, -2, "read");
|
||||||
|
if (lua_isboolean(L, 1) && lua_toboolean(L, -1)) {
|
||||||
|
flags = BLE_GATT_CHR_F_READ;
|
||||||
|
}
|
||||||
|
lua_getfield(L, -3, "write");
|
||||||
|
if (lua_isboolean(L, 1) && lua_toboolean(L, -1)) {
|
||||||
|
flags |= BLE_GATT_CHR_F_WRITE;
|
||||||
|
}
|
||||||
|
if (flags) {
|
||||||
|
chr->flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pop(L, 3); // pop off value, read, write
|
||||||
} else {
|
} else {
|
||||||
lua_getfield(L, -2, "read");
|
lua_getfield(L, -2, "read");
|
||||||
if (!lua_isnoneornil (L, -1)) {
|
if (!lua_isnoneornil (L, -1)) {
|
||||||
|
@ -729,6 +745,10 @@ lble_start_advertising() {
|
||||||
const char *name = gadget_name;
|
const char *name = gadget_name;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (inited != RUNNING) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Figure out address to use while advertising (no privacy for now) */
|
/* Figure out address to use while advertising (no privacy for now) */
|
||||||
rc = ble_hs_id_infer_auto(0, &own_addr_type);
|
rc = ble_hs_id_infer_auto(0, &own_addr_type);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
|
@ -850,6 +870,9 @@ gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
|
||||||
|
|
||||||
|
|
||||||
static int lble_init(lua_State *L) {
|
static int lble_init(lua_State *L) {
|
||||||
|
if (inited != STOPPED) {
|
||||||
|
return luaL_error(L, "ble is already running");
|
||||||
|
}
|
||||||
if (!struct_pack_index) {
|
if (!struct_pack_index) {
|
||||||
lua_getglobal(L, "struct");
|
lua_getglobal(L, "struct");
|
||||||
lua_getfield(L, -1, "pack");
|
lua_getfield(L, -1, "pack");
|
||||||
|
@ -924,10 +947,14 @@ static int lble_init(lua_State *L) {
|
||||||
synced = true;
|
synced = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inited = RUNNING;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lble_shutdown(lua_State *L) {
|
static int lble_shutdown(lua_State *L) {
|
||||||
|
inited = SHUTTING;
|
||||||
|
|
||||||
if (nimble_port_stop()) {
|
if (nimble_port_stop()) {
|
||||||
return luaL_error(L, "Failed to stop the NIMBLE task");
|
return luaL_error(L, "Failed to stop the NIMBLE task");
|
||||||
}
|
}
|
||||||
|
@ -938,6 +965,8 @@ static int lble_shutdown(lua_State *L) {
|
||||||
return luaL_error(L, "Failed to shutdown the BLE controller");
|
return luaL_error(L, "Failed to shutdown the BLE controller");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inited = STOPPED;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -383,60 +383,40 @@ static int file_stat( lua_State* L )
|
||||||
// g_read()
|
// g_read()
|
||||||
static int file_g_read( lua_State* L, int n, int16_t end_char, int fd )
|
static int file_g_read( lua_State* L, int n, int16_t end_char, int fd )
|
||||||
{
|
{
|
||||||
char *heap_mem = NULL;
|
int i, j;
|
||||||
|
luaL_Buffer b;
|
||||||
if(n <= 0)
|
char p[LUAL_BUFFERSIZE/2];
|
||||||
n = FILE_READ_CHUNK;
|
|
||||||
|
|
||||||
if(end_char < 0 || end_char >255)
|
|
||||||
end_char = EOF;
|
|
||||||
|
|
||||||
if(!fd)
|
if(!fd)
|
||||||
return luaL_error(L, "open a file first");
|
return luaL_error(L, "open a file first");
|
||||||
|
|
||||||
char *p;
|
luaL_buffinit(L, &b);
|
||||||
int i;
|
|
||||||
size_t bufsize = n;
|
|
||||||
|
|
||||||
if (n > LUAL_BUFFERSIZE) {
|
for (j = 0; j < n; j += sizeof(p)) {
|
||||||
// get buffer from heap
|
int nwanted = (n - j >= sizeof(p)) ? sizeof(p) : n - j;
|
||||||
p = heap_mem = luaM_malloc(L, bufsize);
|
int nread = vfs_read(fd, p, nwanted);
|
||||||
} else {
|
|
||||||
// small chunks go onto the stack
|
|
||||||
p = alloca(bufsize);
|
|
||||||
}
|
|
||||||
|
|
||||||
n = vfs_read(fd, p, n);
|
if (nread == VFS_RES_ERR || nread == 0) {
|
||||||
// bypass search if no end character provided
|
if (j > 0) {
|
||||||
if (n > 0 && end_char != EOF) {
|
|
||||||
for (i = 0; i < n; ++i)
|
|
||||||
if (p[i] == end_char)
|
|
||||||
{
|
|
||||||
++i;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
i = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
if (i == 0 || n == VFS_RES_ERR) {
|
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
} else {
|
return 1;
|
||||||
vfs_lseek(fd, -(n - i), VFS_SEEK_CUR);
|
|
||||||
err = luaX_pushlstring(L, p, i); // On error it will return nonzero and leave a message on top of the stack.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (heap_mem) {
|
for (i = 0; i < nread; ++i) {
|
||||||
luaN_freearray(L, heap_mem, bufsize);
|
luaL_addchar(&b, p[i]);
|
||||||
|
if (p[i] == end_char) {
|
||||||
|
vfs_lseek(fd, -nread + i + 1, VFS_SEEK_CUR); //reposition after end char found
|
||||||
|
nread = 0; // force break on outer loop
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err){
|
if (nread < nwanted)
|
||||||
lua_error(L); // luaX_pushlstring failed and the error message is on top of the stack. Throw it.
|
break;
|
||||||
// never returns
|
|
||||||
}
|
}
|
||||||
|
luaL_pushresult(&b);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,6 +456,29 @@ static int file_readline( lua_State* L )
|
||||||
return file_g_read(L, FILE_READ_CHUNK, '\n', fd);
|
return file_g_read(L, FILE_READ_CHUNK, '\n', fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Lua: getfile(filename)
|
||||||
|
static int file_getfile( lua_State* L )
|
||||||
|
{
|
||||||
|
// Warning this code C calls other file_* routines to avoid duplication code. These
|
||||||
|
// use Lua stack addressing of arguments, so this does Lua stack maniplation to
|
||||||
|
// align these
|
||||||
|
int ret_cnt = 0;
|
||||||
|
lua_settop(L ,1);
|
||||||
|
// Stack [1] = FD
|
||||||
|
file_open(L);
|
||||||
|
// Stack [1] = filename; [2] = FD or nil
|
||||||
|
if (!lua_isnil(L, -1)) {
|
||||||
|
lua_remove(L, 1); // dump filename, so [1] = FD
|
||||||
|
file_fd_ud *ud = (file_fd_ud *)luaL_checkudata(L, 1, "file.obj");
|
||||||
|
ret_cnt = file_g_read(L, LUAI_MAXINT32, EOF, ud->fd);
|
||||||
|
// Stack [1] = FD; [2] = contents if ret_cnt = 1;
|
||||||
|
file_close(L); // leaves Stack unchanged if [1] = FD
|
||||||
|
lua_remove(L, 1); // Dump FD leaving contents as [1] / ToS
|
||||||
|
}
|
||||||
|
return ret_cnt;
|
||||||
|
}
|
||||||
|
|
||||||
// Lua: write("string")
|
// Lua: write("string")
|
||||||
static int file_write( lua_State* L )
|
static int file_write( lua_State* L )
|
||||||
{
|
{
|
||||||
|
@ -534,28 +537,6 @@ static int file_fsinfo( lua_State* L )
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lua: getfile(filename)
|
|
||||||
static int file_getfile( lua_State* L )
|
|
||||||
{
|
|
||||||
// Warning this code C calls other file_* routines to avoid duplication code. These
|
|
||||||
// use Lua stack addressing of arguments, so this does Lua stack maniplation to
|
|
||||||
// align these
|
|
||||||
int ret_cnt = 0;
|
|
||||||
lua_settop(L ,1);
|
|
||||||
// Stack [1] = FD
|
|
||||||
file_open(L);
|
|
||||||
// Stack [1] = filename; [2] = FD or nil
|
|
||||||
if (!lua_isnil(L, -1)) {
|
|
||||||
lua_remove(L, 1); // dump filename, so [1] = FD
|
|
||||||
file_fd_ud *ud = (file_fd_ud *)luaL_checkudata(L, 1, "file.obj");
|
|
||||||
ret_cnt = file_g_read(L, LUAI_MAXINT32, EOF, ud->fd);
|
|
||||||
// Stack [1] = FD; [2] = contents if ret_cnt = 1;
|
|
||||||
file_close(L); // leaves Stack unchanged if [1] = FD
|
|
||||||
lua_remove(L, 1); // Dump FD leaving contents as [1] / ToS
|
|
||||||
}
|
|
||||||
return ret_cnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lua: getfile(filename)
|
// Lua: getfile(filename)
|
||||||
static int file_putfile( lua_State* L )
|
static int file_putfile( lua_State* L )
|
||||||
{
|
{
|
||||||
|
@ -622,8 +603,6 @@ LROT_BEGIN(file, NULL, 0)
|
||||||
LROT_FUNCENTRY( writeline, file_writeline )
|
LROT_FUNCENTRY( writeline, file_writeline )
|
||||||
LROT_FUNCENTRY( read, file_read )
|
LROT_FUNCENTRY( read, file_read )
|
||||||
LROT_FUNCENTRY( readline, file_readline )
|
LROT_FUNCENTRY( readline, file_readline )
|
||||||
LROT_FUNCENTRY( getcontents, file_getfile )
|
|
||||||
LROT_FUNCENTRY( putcontents, file_putfile )
|
|
||||||
#ifdef CONFIG_NODEMCU_BUILD_SPIFFS
|
#ifdef CONFIG_NODEMCU_BUILD_SPIFFS
|
||||||
LROT_FUNCENTRY( format, file_format )
|
LROT_FUNCENTRY( format, file_format )
|
||||||
LROT_FUNCENTRY( fscfg, file_fscfg )
|
LROT_FUNCENTRY( fscfg, file_fscfg )
|
||||||
|
@ -633,6 +612,8 @@ LROT_BEGIN(file, NULL, 0)
|
||||||
LROT_FUNCENTRY( flush, file_flush )
|
LROT_FUNCENTRY( flush, file_flush )
|
||||||
LROT_FUNCENTRY( rename, file_rename )
|
LROT_FUNCENTRY( rename, file_rename )
|
||||||
LROT_FUNCENTRY( exists, file_exists )
|
LROT_FUNCENTRY( exists, file_exists )
|
||||||
|
LROT_FUNCENTRY( getcontents, file_getfile )
|
||||||
|
LROT_FUNCENTRY( putcontents, file_putfile )
|
||||||
LROT_FUNCENTRY( fsinfo, file_fsinfo )
|
LROT_FUNCENTRY( fsinfo, file_fsinfo )
|
||||||
LROT_FUNCENTRY( on, file_on )
|
LROT_FUNCENTRY( on, file_on )
|
||||||
LROT_FUNCENTRY( stat, file_stat )
|
LROT_FUNCENTRY( stat, file_stat )
|
||||||
|
|
|
@ -74,10 +74,12 @@ The characteristic table contains the following keys:
|
||||||
- `uuid` The UUID of the characteristics. This can be either a 16 byte string or a 2 byte string that identifies the particular characteristic. Typically, 2 byte strings are used for well-known characteristics.
|
- `uuid` The UUID of the characteristics. This can be either a 16 byte string or a 2 byte string that identifies the particular characteristic. Typically, 2 byte strings are used for well-known characteristics.
|
||||||
- `type` This is the optional type of the value. It has the same value as a unpack code in the `struct` module.
|
- `type` This is the optional type of the value. It has the same value as a unpack code in the `struct` module.
|
||||||
- `value` This is the actual value of the characteristic. This will be a string of bytes unless a `type` value is set.
|
- `value` This is the actual value of the characteristic. This will be a string of bytes unless a `type` value is set.
|
||||||
- `read` This is a function that will be invoked to read the value (and so does not need the `value` entry). It should return a string of bytes (unless `type` is set)
|
- `read` This is a function that will be invoked to read the value (and so does not need the `value` entry). It should return a string of bytes (unless `type` is set).
|
||||||
- `write` This is a function that will be invoked to write the value (and so does not need the `value` entry). It is given a string of bytes (unless `type` is set)
|
- `write` This is a function that will be invoked to write the value (and so does not need the `value` entry). It is given a string of bytes (unless `type` is set)
|
||||||
|
|
||||||
The characteristics are treated as read/write unless only one of the `read` or `write` keys is present and the `value` key is not specificed.
|
If the `value` key is present, then the characteristic is read/write. However, if one or `read` or `write` is set to `true`, then it restricts access to that mode.
|
||||||
|
|
||||||
|
The characteristics are treated as read/write unless only one of the `read` or `write` keys is present and the `value` key is not specified.
|
||||||
|
|
||||||
The calling conventions for these functions are as follows:
|
The calling conventions for these functions are as follows:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue