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_unpack_index;
|
||||
|
||||
static enum { STOPPED, RUNNING, SHUTTING } inited;
|
||||
|
||||
static int seqno;
|
||||
|
||||
// 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) {
|
||||
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 {
|
||||
lua_getfield(L, -2, "read");
|
||||
if (!lua_isnoneornil (L, -1)) {
|
||||
|
@ -729,6 +745,10 @@ lble_start_advertising() {
|
|||
const char *name = gadget_name;
|
||||
int rc;
|
||||
|
||||
if (inited != RUNNING) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Figure out address to use while advertising (no privacy for now) */
|
||||
rc = ble_hs_id_infer_auto(0, &own_addr_type);
|
||||
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) {
|
||||
if (inited != STOPPED) {
|
||||
return luaL_error(L, "ble is already running");
|
||||
}
|
||||
if (!struct_pack_index) {
|
||||
lua_getglobal(L, "struct");
|
||||
lua_getfield(L, -1, "pack");
|
||||
|
@ -924,10 +947,14 @@ static int lble_init(lua_State *L) {
|
|||
synced = true;
|
||||
}
|
||||
|
||||
inited = RUNNING;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lble_shutdown(lua_State *L) {
|
||||
inited = SHUTTING;
|
||||
|
||||
if (nimble_port_stop()) {
|
||||
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");
|
||||
}
|
||||
|
||||
inited = STOPPED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -383,60 +383,40 @@ static int file_stat( lua_State* L )
|
|||
// g_read()
|
||||
static int file_g_read( lua_State* L, int n, int16_t end_char, int fd )
|
||||
{
|
||||
char *heap_mem = NULL;
|
||||
|
||||
if(n <= 0)
|
||||
n = FILE_READ_CHUNK;
|
||||
|
||||
if(end_char < 0 || end_char >255)
|
||||
end_char = EOF;
|
||||
int i, j;
|
||||
luaL_Buffer b;
|
||||
char p[LUAL_BUFFERSIZE/2];
|
||||
|
||||
if(!fd)
|
||||
return luaL_error(L, "open a file first");
|
||||
|
||||
char *p;
|
||||
int i;
|
||||
size_t bufsize = n;
|
||||
luaL_buffinit(L, &b);
|
||||
|
||||
if (n > LUAL_BUFFERSIZE) {
|
||||
// get buffer from heap
|
||||
p = heap_mem = luaM_malloc(L, bufsize);
|
||||
} else {
|
||||
// small chunks go onto the stack
|
||||
p = alloca(bufsize);
|
||||
}
|
||||
for (j = 0; j < n; j += sizeof(p)) {
|
||||
int nwanted = (n - j >= sizeof(p)) ? sizeof(p) : n - j;
|
||||
int nread = vfs_read(fd, p, nwanted);
|
||||
|
||||
n = vfs_read(fd, p, n);
|
||||
// bypass search if no end character provided
|
||||
if (n > 0 && end_char != EOF) {
|
||||
for (i = 0; i < n; ++i)
|
||||
if (p[i] == end_char)
|
||||
{
|
||||
++i;
|
||||
if (nread == VFS_RES_ERR || nread == 0) {
|
||||
if (j > 0) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
i = n;
|
||||
}
|
||||
|
||||
int err = 0;
|
||||
|
||||
if (i == 0 || n == VFS_RES_ERR) {
|
||||
lua_pushnil(L);
|
||||
} else {
|
||||
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.
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (heap_mem) {
|
||||
luaN_freearray(L, heap_mem, bufsize);
|
||||
for (i = 0; i < nread; ++i) {
|
||||
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){
|
||||
lua_error(L); // luaX_pushlstring failed and the error message is on top of the stack. Throw it.
|
||||
// never returns
|
||||
if (nread < nwanted)
|
||||
break;
|
||||
}
|
||||
|
||||
luaL_pushresult(&b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -476,6 +456,29 @@ static int file_readline( lua_State* L )
|
|||
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")
|
||||
static int file_write( lua_State* L )
|
||||
{
|
||||
|
@ -534,28 +537,6 @@ static int file_fsinfo( lua_State* L )
|
|||
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)
|
||||
static int file_putfile( lua_State* L )
|
||||
{
|
||||
|
@ -622,8 +603,6 @@ LROT_BEGIN(file, NULL, 0)
|
|||
LROT_FUNCENTRY( writeline, file_writeline )
|
||||
LROT_FUNCENTRY( read, file_read )
|
||||
LROT_FUNCENTRY( readline, file_readline )
|
||||
LROT_FUNCENTRY( getcontents, file_getfile )
|
||||
LROT_FUNCENTRY( putcontents, file_putfile )
|
||||
#ifdef CONFIG_NODEMCU_BUILD_SPIFFS
|
||||
LROT_FUNCENTRY( format, file_format )
|
||||
LROT_FUNCENTRY( fscfg, file_fscfg )
|
||||
|
@ -633,6 +612,8 @@ LROT_BEGIN(file, NULL, 0)
|
|||
LROT_FUNCENTRY( flush, file_flush )
|
||||
LROT_FUNCENTRY( rename, file_rename )
|
||||
LROT_FUNCENTRY( exists, file_exists )
|
||||
LROT_FUNCENTRY( getcontents, file_getfile )
|
||||
LROT_FUNCENTRY( putcontents, file_putfile )
|
||||
LROT_FUNCENTRY( fsinfo, file_fsinfo )
|
||||
LROT_FUNCENTRY( on, file_on )
|
||||
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.
|
||||
- `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.
|
||||
- `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)
|
||||
|
||||
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:
|
||||
|
||||
|
|
Loading…
Reference in New Issue