| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394 |
- #include "luat_base.h"
- #include "luat_mem.h"
- #include "luat_rtos.h"
- #include "luat_msgbus.h"
- #include "luat_bluetooth.h"
- #include "luat_log.h"
- #define LUAT_LOG_TAG "bluetooth"
- #define LUAT_BLUETOOTH_TYPE "BLUETOOTH*"
- #define LUAT_BLE_TYPE "BLE*"
- static int luatos_ble_callback(lua_State *L, void* ptr){
- (void)ptr;
- rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
- luat_bluetooth_t* luat_bluetooth =(luat_bluetooth_t *)msg->ptr;
- luat_ble_event_t ble_event = (luat_ble_event_t)msg->arg1;
- luat_ble_param_t* luat_ble_param = (luat_ble_param_t*)msg->arg2;
- // if (luat_bluetooth->luat_ble->lua_cb) {
- lua_geti(L, LUA_REGISTRYINDEX, luat_bluetooth->luat_ble->lua_cb);
- if (lua_isfunction(L, -1)) {
- lua_geti(L, LUA_REGISTRYINDEX, luat_bluetooth->bluetooth_ref);
- lua_pushinteger(L, ble_event);
- // lua_call(L, 2, 0);
- }
- // }
- switch(ble_event){
- case LUAT_BLE_EVENT_WRITE:{
- luat_ble_write_req_t* write_req = &(luat_ble_param->write_req);
- lua_createtable(L, 0, 3);
- lua_pushliteral(L, "conn_idx");
- lua_pushinteger(L, write_req->conn_idx);
- lua_settable(L, -3);
- lua_pushliteral(L, "prf_id");
- lua_pushinteger(L, write_req->prf_id);
- lua_settable(L, -3);
- lua_pushliteral(L, "att_idx");
- lua_pushinteger(L, write_req->att_idx);
- lua_settable(L, -3);
- lua_pushliteral(L, "data");
- lua_pushlstring(L, (const char *)write_req->value, write_req->len);
- lua_settable(L, -3);
- lua_call(L, 3, 0);
- if (write_req->value){
- luat_heap_free(write_req->value);
- }
- break;
- }
- case LUAT_BLE_EVENT_READ: {
- luat_ble_read_req_t* read_req = &(luat_ble_param->read_req);
- lua_createtable(L, 0, 3);
- lua_pushliteral(L, "conn_idx");
- lua_pushinteger(L, read_req->conn_idx);
- lua_settable(L, -3);
- lua_pushliteral(L, "prf_id");
- lua_pushinteger(L, read_req->prf_id);
- lua_settable(L, -3);
- lua_pushliteral(L, "att_idx");
- lua_pushinteger(L, read_req->att_idx);
- lua_settable(L, -3);
- lua_pushliteral(L, "data");
- lua_pushlstring(L, (const char *)read_req->value, read_req->len);
- lua_settable(L, -3);
- lua_call(L, 3, 0);
- if (read_req->value){
- luat_heap_free(read_req->value);
- }
- break;
- }
- default:
- lua_call(L, 2, 0);
- break;
- }
- if (luat_ble_param){
- luat_heap_free(luat_ble_param);
- }
- return 0;
- }
- static void luat_ble_cb(luat_bluetooth_t* luat_bluetooth, luat_ble_event_t ble_event, luat_ble_param_t* ble_param){
- // LLOGD("ble event: %d", ble_event);
- luat_ble_param_t* luat_ble_param = NULL;
- if (ble_param){
- luat_ble_param = luat_heap_malloc(sizeof(luat_ble_param_t));
- memcpy(luat_ble_param, ble_param, sizeof(luat_ble_param_t));
- if ((ble_event == LUAT_BLE_EVENT_WRITE || ble_event == LUAT_BLE_EVENT_READ) && ble_param->write_req.len){
- luat_ble_param->write_req.value = luat_heap_malloc(ble_param->write_req.len);
- memcpy(luat_ble_param->write_req.value, ble_param->write_req.value, ble_param->write_req.len);
- }
- }
-
- rtos_msg_t msg = {
- .handler = luatos_ble_callback,
- .ptr = (void*)luat_bluetooth,
- .arg1 = (int)ble_event,
- .arg2 = (int)luat_ble_param,
- };
- luat_msgbus_put(&msg, 0);
- }
- static int l_bluetooth_create_ble(lua_State* L) {
- if (!lua_isuserdata(L, 1)){
- return 0;
- }
- luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t *)luaL_checkudata(L, 1, LUAT_BLUETOOTH_TYPE);
- luat_ble_init(luat_bluetooth, luat_ble_cb);
- if (lua_isfunction(L, 2)) {
- lua_pushvalue(L, 2);
- luat_bluetooth->luat_ble->lua_cb = luaL_ref(L, LUA_REGISTRYINDEX);
- }
- lua_pushboolean(L, 1);
- return 1;
- }
- static int l_ble_gatt_create(lua_State* L) {
- if (!lua_isuserdata(L, 1)){
- return 0;
- }
- luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t *)luaL_checkudata(L, 1, LUAT_BLUETOOTH_TYPE);
- luat_ble_gatt_cfg_t luat_ble_gatt_cfg = {0};
- int argc = lua_gettop(L);
- for (size_t m = 2; m <= argc; m++){
- if (lua_type(L, m) != LUA_TTABLE){
- LLOGE("error param");
- return 0;
- }
- size_t len = 0;
-
- memset(luat_ble_gatt_cfg.uuid, 0x00, sizeof(luat_ble_gatt_cfg.uuid));
- lua_pushstring(L, "uuid");
- if (LUA_TSTRING == lua_gettable(L, m)){
- const char* data = luaL_checklstring(L, -1, &len);
- memcpy(luat_ble_gatt_cfg.uuid, data, len);
- }
- lua_pop(L, 1);
-
- lua_pushstring(L, "att_db");
- if (LUA_TTABLE == lua_gettable(L, m)){
- luat_ble_gatt_cfg.att_db_num = luaL_len(L, -1);
- luat_ble_gatt_cfg.att_db = (luat_ble_att_db_t*)luat_heap_malloc(sizeof(luat_ble_att_db_t) * luat_ble_gatt_cfg.att_db_num);
- memset(luat_ble_gatt_cfg.att_db, 0x00, sizeof(luat_ble_att_db_t));
- for (int i = 1; i <= luat_ble_gatt_cfg.att_db_num; i++) {
- lua_rawgeti(L, -1, i);
- int table_len = luaL_len(L, -1);
- for (int j = 1; j <= table_len; j++){
- lua_rawgeti(L, -1, j);
- if (j == 1 && lua_type(L, -1) == LUA_TSTRING){
- const char* data = luaL_checklstring(L, -1, &len);
- memcpy(luat_ble_gatt_cfg.att_db[i-1].uuid, data, len);
- }else if(j == 2 && lua_type(L, -1) == LUA_TNUMBER){
- luat_ble_gatt_cfg.att_db[i-1].perm = (uint16_t)luaL_optnumber(L, -1, 0);
- }else if(j == 3 && lua_type(L, -1) == LUA_TNUMBER){
- luat_ble_gatt_cfg.att_db[i-1].ext_perm = (uint16_t)luaL_optnumber(L, -1, 0);
- }else if(j == 4 && lua_type(L, -1) == LUA_TNUMBER){
- luat_ble_gatt_cfg.att_db[i-1].max_size = (uint16_t)luaL_optnumber(L, -1, 0);
- }else{
- LLOGE("error att_db type");
- goto end;
- }
- lua_pop(L, 1);
- }
- lua_pop(L, 1);
- }
- }else{
- LLOGE("error att_db");
- goto end;
- }
- lua_pop(L, 1);
- luat_ble_create_gatt(luat_bluetooth, &luat_ble_gatt_cfg);
- luat_heap_free(luat_ble_gatt_cfg.att_db);
- luat_ble_gatt_cfg.prf_id++;
- }
- lua_pushboolean(L, 1);
- return 1;
- end:
- return 0;
- }
- static int l_ble_advertising_create(lua_State* L) {
- if (!lua_isuserdata(L, 1)){
- return 0;
- }
- if (lua_type(L, 2) != LUA_TTABLE){
- LLOGE("error param");
- return 0;
- }
- luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t *)luaL_checkudata(L, 1, LUAT_BLUETOOTH_TYPE);
- size_t len = 0;
- // const char* complete_local_name = NULL;
- // lua_pushstring(L, "name");
- // if (LUA_TSTRING == lua_gettable(L, 2)) {
- // complete_local_name = luaL_checklstring(L, -1, &len);
- // }else{
- // complete_local_name = (char* )luat_heap_malloc(32);
- // memset(complete_local_name, 0, 32);
- // sprintf_(complete_local_name, "LuatOS_%s", luat_os_bsp());
- // }
- // lua_pop(L, 1);
- luat_ble_adv_cfg_t luat_ble_adv_cfg = {
- .addr_mode = LUAT_BLE_ADV_ADDR_MODE_PUBLIC,
- .channel_map = LUAT_BLE_ADV_CHNLS_ALL,
- .intv_min = 120,
- .intv_max = 160,
- };
- lua_pushstring(L, "addr_mode");
- if (LUA_TNUMBER == lua_gettable(L, -2)){
- luat_ble_adv_cfg.addr_mode = luaL_checknumber(L, -1);
- }
- lua_pop(L, 1);
- lua_pushstring(L, "channel_map");
- if (LUA_TNUMBER == lua_gettable(L, 2)) {
- luat_ble_adv_cfg.channel_map = luaL_checknumber(L, -1);
- }
- lua_pop(L, 1);
- lua_pushstring(L, "intv_min");
- if (LUA_TNUMBER == lua_gettable(L, 2)) {
- luat_ble_adv_cfg.intv_min = luaL_checknumber(L, -1);
- }
- lua_pop(L, 1);
- lua_pushstring(L, "intv_max");
- if (LUA_TNUMBER == lua_gettable(L, 2)) {
- luat_ble_adv_cfg.intv_max = luaL_checknumber(L, -1);
- }
- lua_pop(L, 1);
- luat_ble_create_advertising(luat_bluetooth, &luat_ble_adv_cfg);
- // 广播内容 (adv data)
- uint8_t adv_data[255] = {0};
- uint8_t adv_index = 0;
- lua_pushstring(L, "adv_data");
- if (LUA_TTABLE == lua_gettable(L, -2)){
- int adv_data_count = luaL_len(L, -1);
- for (int i = 1; i <= adv_data_count; i++) {
- lua_rawgeti(L, -1, i);
- if (LUA_TTABLE == lua_type(L, -1)){
- lua_rawgeti(L, -1, 2);
- if (lua_type(L, -1) == LUA_TSTRING){
- const char* data = luaL_checklstring(L, -1, &len);
- adv_data[adv_index++] = (uint8_t)(len+1);
- lua_rawgeti(L, -2, 1);
- if (lua_type(L, -1) == LUA_TNUMBER){
- adv_data[adv_index++] = (uint8_t)luaL_checknumber(L, -1);
- }else{
- LLOGE("error adv_data type");
- goto end;
- }
- memcpy(adv_data + adv_index, data, len);
- adv_index += len;
- lua_pop(L, 2);
- }else{
- LLOGE("error adv_data type");
- goto end;
- }
- }else{
- LLOGE("error adv_data type");
- goto end;
- }
- lua_pop(L, 1);
- }
- }
- lua_pop(L, 1);
- /* set adv paramters */
- luat_ble_set_adv_data(luat_bluetooth, adv_data, adv_index);
- // luat_ble_set_name(luat_bluetooth, complete_local_name, strlen(complete_local_name));
- lua_pushboolean(L, 1);
- return 1;
- end:
- return 0;
- }
- static int l_ble_advertising_start(lua_State* L) {
- luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t*)lua_newuserdata(L, sizeof(luat_bluetooth_t));
- lua_pushboolean(L, luat_ble_start_advertising(luat_bluetooth)?0:1);
- return 1;
- }
- static int l_ble_advertising_stop(lua_State* L) {
- luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t*)lua_newuserdata(L, sizeof(luat_bluetooth_t));
- lua_pushboolean(L, luat_ble_stop_advertising(luat_bluetooth)?0:1);
- return 1;
- }
- static int l_bluetooth_init(lua_State* L) {
- luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t*)lua_newuserdata(L, sizeof(luat_bluetooth_t));
- if (luat_bluetooth) {
- luat_bluetooth_init(luat_bluetooth);
- luaL_setmetatable(L, LUAT_BLUETOOTH_TYPE);
- lua_pushvalue(L, -1);
- luat_bluetooth->bluetooth_ref = luaL_ref(L, LUA_REGISTRYINDEX);
- return 1;
- }
- return 0;
- }
- static int _bluetooth_struct_newindex(lua_State *L);
- void luat_bluetooth_struct_init(lua_State *L) {
- luaL_newmetatable(L, LUAT_BLUETOOTH_TYPE);
- lua_pushcfunction(L, _bluetooth_struct_newindex);
- lua_setfield( L, -2, "__index" );
- lua_pop(L, 1);
- }
- #include "rotable2.h"
- static const rotable_Reg_t reg_bluetooth[] = {
- {"init", ROREG_FUNC(l_bluetooth_init)},
- {"ble", ROREG_FUNC(l_bluetooth_create_ble)},
- {"gatt_create", ROREG_FUNC(l_ble_gatt_create)},
- {"adv_create", ROREG_FUNC(l_ble_advertising_create)},
- {"adv_start", ROREG_FUNC(l_ble_advertising_start)},
- {"adv_stop", ROREG_FUNC(l_ble_advertising_stop)},
- // BLE_EVENT
- {"EVENT_NONE", ROREG_INT(LUAT_BLE_EVENT_NONE)},
- {"EVENT_INIT", ROREG_INT(LUAT_BLE_EVENT_INIT)},
- {"EVENT_DEINIT", ROREG_INT(LUAT_BLE_EVENT_DEINIT)},
- {"EVENT_ADV_INIT", ROREG_INT(LUAT_BLE_EVENT_ADV_INIT)},
- {"EVENT_ADV_START", ROREG_INT(LUAT_BLE_EVENT_ADV_START)},
- {"EVENT_ADV_STOP", ROREG_INT(LUAT_BLE_EVENT_ADV_STOP)},
- {"EVENT_ADV_DEINIT", ROREG_INT(LUAT_BLE_EVENT_ADV_DEINIT)},
- {"EVENT_SCAN_INIT", ROREG_INT(LUAT_BLE_EVENT_SCAN_INIT)},
- {"EVENT_SCAN_START", ROREG_INT(LUAT_BLE_EVENT_SCAN_START)},
- {"EVENT_SCAN_STOP", ROREG_INT(LUAT_BLE_EVENT_SCAN_STOP)},
- {"EVENT_SCAN_DEINIT", ROREG_INT(LUAT_BLE_EVENT_SCAN_DEINIT)},
- {"EVENT_CONN", ROREG_INT(LUAT_BLE_EVENT_CONN)},
- {"EVENT_DISCONN", ROREG_INT(LUAT_BLE_EVENT_DISCONN)},
- {"EVENT_WRITE", ROREG_INT(LUAT_BLE_EVENT_WRITE)},
- {"EVENT_READ", ROREG_INT(LUAT_BLE_EVENT_READ)},
-
- // ADV_ADDR_MODE
- {"PUBLIC", ROREG_INT(LUAT_BLE_ADV_ADDR_MODE_PUBLIC)},
- {"RANDOM", ROREG_INT(LUAT_BLE_ADV_ADDR_MODE_RANDOM)},
- {"RPA", ROREG_INT(LUAT_BLE_ADV_ADDR_MODE_RPA)},
- {"NRPA", ROREG_INT(LUAT_BLE_ADV_ADDR_MODE_NRPA)},
- // ADV_CHNL
- {"CHNL_37", ROREG_INT(LUAT_BLE_ADV_CHNL_37)},
- {"CHNL_38", ROREG_INT(LUAT_BLE_ADV_CHNL_38)},
- {"CHNL_39", ROREG_INT(LUAT_BLE_ADV_CHNL_39)},
- {"CHNLS_ALL", ROREG_INT(LUAT_BLE_ADV_CHNLS_ALL)},
- // Permission
- {"READ", ROREG_INT(LUAT_BLE_GATT_PERM_READ)},
- {"WRITE", ROREG_INT(LUAT_BLE_GATT_PERM_WRITE)},
- {"IND", ROREG_INT(LUAT_BLE_GATT_PERM_IND)},
- {"NOTIFY", ROREG_INT(LUAT_BLE_GATT_PERM_NOTIFY)},
- // FLAGS
- {"FLAGS", ROREG_INT(LUAT_ADV_TYPE_FLAGS)},
- {"COMPLETE_LOCAL_NAME", ROREG_INT(LUAT_ADV_TYPE_COMPLETE_LOCAL_NAME)},
- {"SERVICE_DATA", ROREG_INT(LUAT_ADV_TYPE_SERVICE_DATA_16BIT)},
- {"MANUFACTURER_SPECIFIC_DATA", ROREG_INT(LUAT_ADV_TYPE_MANUFACTURER_SPECIFIC_DATA)},
- { NULL, ROREG_INT(0)}
- };
- static int _bluetooth_struct_newindex(lua_State *L) {
- const rotable_Reg_t* reg = reg_bluetooth;
- const char* key = luaL_checkstring(L, 2);
- while (1) {
- if (reg->name == NULL)
- return 0;
- if (!strcmp(reg->name, key)) {
- lua_pushcfunction(L, reg->value.value.func);
- return 1;
- }
- reg ++;
- }
- }
- LUAMOD_API int luaopen_bluetooth( lua_State *L ) {
- rotable2_newlib(L, reg_bluetooth);
- luat_bluetooth_struct_init(L);
- lua_pushvalue(L, -1);
- lua_setglobal(L, "ble");
- return 1;
- }
|