luat_lib_bluetooth.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. #include "luat_base.h"
  2. #include "luat_mem.h"
  3. #include "luat_rtos.h"
  4. #include "luat_msgbus.h"
  5. #include "luat_bluetooth.h"
  6. #include "luat_log.h"
  7. #define LUAT_LOG_TAG "bluetooth"
  8. #define LUAT_BLUETOOTH_TYPE "BLUETOOTH*"
  9. #define LUAT_BLE_TYPE "BLE*"
  10. static int luatos_ble_callback(lua_State *L, void* ptr){
  11. (void)ptr;
  12. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  13. luat_bluetooth_t* luat_bluetooth =(luat_bluetooth_t *)msg->ptr;
  14. luat_ble_event_t ble_event = (luat_ble_event_t)msg->arg1;
  15. luat_ble_param_t* luat_ble_param = (luat_ble_param_t*)msg->arg2;
  16. // if (luat_bluetooth->luat_ble->lua_cb) {
  17. lua_geti(L, LUA_REGISTRYINDEX, luat_bluetooth->luat_ble->lua_cb);
  18. if (lua_isfunction(L, -1)) {
  19. lua_geti(L, LUA_REGISTRYINDEX, luat_bluetooth->bluetooth_ref);
  20. lua_pushinteger(L, ble_event);
  21. // lua_call(L, 2, 0);
  22. }
  23. // }
  24. switch(ble_event){
  25. case LUAT_BLE_EVENT_WRITE:{
  26. luat_ble_write_req_t* write_req = &(luat_ble_param->write_req);
  27. lua_createtable(L, 0, 3);
  28. lua_pushliteral(L, "conn_idx");
  29. lua_pushinteger(L, write_req->conn_idx);
  30. lua_settable(L, -3);
  31. lua_pushliteral(L, "prf_id");
  32. lua_pushinteger(L, write_req->prf_id);
  33. lua_settable(L, -3);
  34. lua_pushliteral(L, "att_idx");
  35. lua_pushinteger(L, write_req->att_idx);
  36. lua_settable(L, -3);
  37. lua_pushliteral(L, "data");
  38. lua_pushlstring(L, (const char *)write_req->value, write_req->len);
  39. lua_settable(L, -3);
  40. lua_call(L, 3, 0);
  41. if (write_req->value){
  42. luat_heap_free(write_req->value);
  43. }
  44. break;
  45. }
  46. case LUAT_BLE_EVENT_READ: {
  47. luat_ble_read_req_t* read_req = &(luat_ble_param->read_req);
  48. lua_createtable(L, 0, 3);
  49. lua_pushliteral(L, "conn_idx");
  50. lua_pushinteger(L, read_req->conn_idx);
  51. lua_settable(L, -3);
  52. lua_pushliteral(L, "prf_id");
  53. lua_pushinteger(L, read_req->prf_id);
  54. lua_settable(L, -3);
  55. lua_pushliteral(L, "att_idx");
  56. lua_pushinteger(L, read_req->att_idx);
  57. lua_settable(L, -3);
  58. lua_pushliteral(L, "data");
  59. lua_pushlstring(L, (const char *)read_req->value, read_req->len);
  60. lua_settable(L, -3);
  61. lua_call(L, 3, 0);
  62. if (read_req->value){
  63. luat_heap_free(read_req->value);
  64. }
  65. break;
  66. }
  67. default:
  68. lua_call(L, 2, 0);
  69. break;
  70. }
  71. if (luat_ble_param){
  72. luat_heap_free(luat_ble_param);
  73. }
  74. return 0;
  75. }
  76. static void luat_ble_cb(luat_bluetooth_t* luat_bluetooth, luat_ble_event_t ble_event, luat_ble_param_t* ble_param){
  77. // LLOGD("ble event: %d", ble_event);
  78. luat_ble_param_t* luat_ble_param = NULL;
  79. if (ble_param){
  80. luat_ble_param = luat_heap_malloc(sizeof(luat_ble_param_t));
  81. memcpy(luat_ble_param, ble_param, sizeof(luat_ble_param_t));
  82. if ((ble_event == LUAT_BLE_EVENT_WRITE || ble_event == LUAT_BLE_EVENT_READ) && ble_param->write_req.len){
  83. luat_ble_param->write_req.value = luat_heap_malloc(ble_param->write_req.len);
  84. memcpy(luat_ble_param->write_req.value, ble_param->write_req.value, ble_param->write_req.len);
  85. }
  86. }
  87. rtos_msg_t msg = {
  88. .handler = luatos_ble_callback,
  89. .ptr = (void*)luat_bluetooth,
  90. .arg1 = (int)ble_event,
  91. .arg2 = (int)luat_ble_param,
  92. };
  93. luat_msgbus_put(&msg, 0);
  94. }
  95. static int l_bluetooth_create_ble(lua_State* L) {
  96. if (!lua_isuserdata(L, 1)){
  97. return 0;
  98. }
  99. luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t *)luaL_checkudata(L, 1, LUAT_BLUETOOTH_TYPE);
  100. luat_ble_init(luat_bluetooth, luat_ble_cb);
  101. if (lua_isfunction(L, 2)) {
  102. lua_pushvalue(L, 2);
  103. luat_bluetooth->luat_ble->lua_cb = luaL_ref(L, LUA_REGISTRYINDEX);
  104. }
  105. lua_pushboolean(L, 1);
  106. return 1;
  107. }
  108. static int l_ble_gatt_create(lua_State* L) {
  109. if (!lua_isuserdata(L, 1)){
  110. return 0;
  111. }
  112. luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t *)luaL_checkudata(L, 1, LUAT_BLUETOOTH_TYPE);
  113. luat_ble_gatt_cfg_t luat_ble_gatt_cfg = {0};
  114. int argc = lua_gettop(L);
  115. for (size_t m = 2; m <= argc; m++){
  116. if (lua_type(L, m) != LUA_TTABLE){
  117. LLOGE("error param");
  118. return 0;
  119. }
  120. size_t len = 0;
  121. memset(luat_ble_gatt_cfg.uuid, 0x00, sizeof(luat_ble_gatt_cfg.uuid));
  122. lua_pushstring(L, "uuid");
  123. if (LUA_TSTRING == lua_gettable(L, m)){
  124. const char* data = luaL_checklstring(L, -1, &len);
  125. memcpy(luat_ble_gatt_cfg.uuid, data, len);
  126. }
  127. lua_pop(L, 1);
  128. lua_pushstring(L, "att_db");
  129. if (LUA_TTABLE == lua_gettable(L, m)){
  130. luat_ble_gatt_cfg.att_db_num = luaL_len(L, -1);
  131. 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);
  132. memset(luat_ble_gatt_cfg.att_db, 0x00, sizeof(luat_ble_att_db_t));
  133. for (int i = 1; i <= luat_ble_gatt_cfg.att_db_num; i++) {
  134. lua_rawgeti(L, -1, i);
  135. int table_len = luaL_len(L, -1);
  136. for (int j = 1; j <= table_len; j++){
  137. lua_rawgeti(L, -1, j);
  138. if (j == 1 && lua_type(L, -1) == LUA_TSTRING){
  139. const char* data = luaL_checklstring(L, -1, &len);
  140. memcpy(luat_ble_gatt_cfg.att_db[i-1].uuid, data, len);
  141. }else if(j == 2 && lua_type(L, -1) == LUA_TNUMBER){
  142. luat_ble_gatt_cfg.att_db[i-1].perm = (uint16_t)luaL_optnumber(L, -1, 0);
  143. }else if(j == 3 && lua_type(L, -1) == LUA_TNUMBER){
  144. luat_ble_gatt_cfg.att_db[i-1].ext_perm = (uint16_t)luaL_optnumber(L, -1, 0);
  145. }else if(j == 4 && lua_type(L, -1) == LUA_TNUMBER){
  146. luat_ble_gatt_cfg.att_db[i-1].max_size = (uint16_t)luaL_optnumber(L, -1, 0);
  147. }else{
  148. LLOGE("error att_db type");
  149. goto end;
  150. }
  151. lua_pop(L, 1);
  152. }
  153. lua_pop(L, 1);
  154. }
  155. }else{
  156. LLOGE("error att_db");
  157. goto end;
  158. }
  159. lua_pop(L, 1);
  160. luat_ble_create_gatt(luat_bluetooth, &luat_ble_gatt_cfg);
  161. luat_heap_free(luat_ble_gatt_cfg.att_db);
  162. luat_ble_gatt_cfg.prf_id++;
  163. }
  164. lua_pushboolean(L, 1);
  165. return 1;
  166. end:
  167. return 0;
  168. }
  169. static int l_ble_advertising_create(lua_State* L) {
  170. if (!lua_isuserdata(L, 1)){
  171. return 0;
  172. }
  173. if (lua_type(L, 2) != LUA_TTABLE){
  174. LLOGE("error param");
  175. return 0;
  176. }
  177. luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t *)luaL_checkudata(L, 1, LUAT_BLUETOOTH_TYPE);
  178. size_t len = 0;
  179. // const char* complete_local_name = NULL;
  180. // lua_pushstring(L, "name");
  181. // if (LUA_TSTRING == lua_gettable(L, 2)) {
  182. // complete_local_name = luaL_checklstring(L, -1, &len);
  183. // }else{
  184. // complete_local_name = (char* )luat_heap_malloc(32);
  185. // memset(complete_local_name, 0, 32);
  186. // sprintf_(complete_local_name, "LuatOS_%s", luat_os_bsp());
  187. // }
  188. // lua_pop(L, 1);
  189. luat_ble_adv_cfg_t luat_ble_adv_cfg = {
  190. .addr_mode = LUAT_BLE_ADV_ADDR_MODE_PUBLIC,
  191. .channel_map = LUAT_BLE_ADV_CHNLS_ALL,
  192. .intv_min = 120,
  193. .intv_max = 160,
  194. };
  195. lua_pushstring(L, "addr_mode");
  196. if (LUA_TNUMBER == lua_gettable(L, -2)){
  197. luat_ble_adv_cfg.addr_mode = luaL_checknumber(L, -1);
  198. }
  199. lua_pop(L, 1);
  200. lua_pushstring(L, "channel_map");
  201. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  202. luat_ble_adv_cfg.channel_map = luaL_checknumber(L, -1);
  203. }
  204. lua_pop(L, 1);
  205. lua_pushstring(L, "intv_min");
  206. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  207. luat_ble_adv_cfg.intv_min = luaL_checknumber(L, -1);
  208. }
  209. lua_pop(L, 1);
  210. lua_pushstring(L, "intv_max");
  211. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  212. luat_ble_adv_cfg.intv_max = luaL_checknumber(L, -1);
  213. }
  214. lua_pop(L, 1);
  215. luat_ble_create_advertising(luat_bluetooth, &luat_ble_adv_cfg);
  216. // 广播内容 (adv data)
  217. uint8_t adv_data[255] = {0};
  218. uint8_t adv_index = 0;
  219. lua_pushstring(L, "adv_data");
  220. if (LUA_TTABLE == lua_gettable(L, -2)){
  221. int adv_data_count = luaL_len(L, -1);
  222. for (int i = 1; i <= adv_data_count; i++) {
  223. lua_rawgeti(L, -1, i);
  224. if (LUA_TTABLE == lua_type(L, -1)){
  225. lua_rawgeti(L, -1, 2);
  226. if (lua_type(L, -1) == LUA_TSTRING){
  227. const char* data = luaL_checklstring(L, -1, &len);
  228. adv_data[adv_index++] = (uint8_t)(len+1);
  229. lua_rawgeti(L, -2, 1);
  230. if (lua_type(L, -1) == LUA_TNUMBER){
  231. adv_data[adv_index++] = (uint8_t)luaL_checknumber(L, -1);
  232. }else{
  233. LLOGE("error adv_data type");
  234. goto end;
  235. }
  236. memcpy(adv_data + adv_index, data, len);
  237. adv_index += len;
  238. lua_pop(L, 2);
  239. }else{
  240. LLOGE("error adv_data type");
  241. goto end;
  242. }
  243. }else{
  244. LLOGE("error adv_data type");
  245. goto end;
  246. }
  247. lua_pop(L, 1);
  248. }
  249. }
  250. lua_pop(L, 1);
  251. /* set adv paramters */
  252. luat_ble_set_adv_data(luat_bluetooth, adv_data, adv_index);
  253. // luat_ble_set_name(luat_bluetooth, complete_local_name, strlen(complete_local_name));
  254. lua_pushboolean(L, 1);
  255. return 1;
  256. end:
  257. return 0;
  258. }
  259. static int l_ble_advertising_start(lua_State* L) {
  260. luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t*)lua_newuserdata(L, sizeof(luat_bluetooth_t));
  261. lua_pushboolean(L, luat_ble_start_advertising(luat_bluetooth)?0:1);
  262. return 1;
  263. }
  264. static int l_ble_advertising_stop(lua_State* L) {
  265. luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t*)lua_newuserdata(L, sizeof(luat_bluetooth_t));
  266. lua_pushboolean(L, luat_ble_stop_advertising(luat_bluetooth)?0:1);
  267. return 1;
  268. }
  269. static int l_bluetooth_init(lua_State* L) {
  270. luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t*)lua_newuserdata(L, sizeof(luat_bluetooth_t));
  271. if (luat_bluetooth) {
  272. luat_bluetooth_init(luat_bluetooth);
  273. luaL_setmetatable(L, LUAT_BLUETOOTH_TYPE);
  274. lua_pushvalue(L, -1);
  275. luat_bluetooth->bluetooth_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  276. return 1;
  277. }
  278. return 0;
  279. }
  280. static int _bluetooth_struct_newindex(lua_State *L);
  281. void luat_bluetooth_struct_init(lua_State *L) {
  282. luaL_newmetatable(L, LUAT_BLUETOOTH_TYPE);
  283. lua_pushcfunction(L, _bluetooth_struct_newindex);
  284. lua_setfield( L, -2, "__index" );
  285. lua_pop(L, 1);
  286. }
  287. #include "rotable2.h"
  288. static const rotable_Reg_t reg_bluetooth[] = {
  289. {"init", ROREG_FUNC(l_bluetooth_init)},
  290. {"ble", ROREG_FUNC(l_bluetooth_create_ble)},
  291. {"gatt_create", ROREG_FUNC(l_ble_gatt_create)},
  292. {"adv_create", ROREG_FUNC(l_ble_advertising_create)},
  293. {"adv_start", ROREG_FUNC(l_ble_advertising_start)},
  294. {"adv_stop", ROREG_FUNC(l_ble_advertising_stop)},
  295. // BLE_EVENT
  296. {"EVENT_NONE", ROREG_INT(LUAT_BLE_EVENT_NONE)},
  297. {"EVENT_INIT", ROREG_INT(LUAT_BLE_EVENT_INIT)},
  298. {"EVENT_DEINIT", ROREG_INT(LUAT_BLE_EVENT_DEINIT)},
  299. {"EVENT_ADV_INIT", ROREG_INT(LUAT_BLE_EVENT_ADV_INIT)},
  300. {"EVENT_ADV_START", ROREG_INT(LUAT_BLE_EVENT_ADV_START)},
  301. {"EVENT_ADV_STOP", ROREG_INT(LUAT_BLE_EVENT_ADV_STOP)},
  302. {"EVENT_ADV_DEINIT", ROREG_INT(LUAT_BLE_EVENT_ADV_DEINIT)},
  303. {"EVENT_SCAN_INIT", ROREG_INT(LUAT_BLE_EVENT_SCAN_INIT)},
  304. {"EVENT_SCAN_START", ROREG_INT(LUAT_BLE_EVENT_SCAN_START)},
  305. {"EVENT_SCAN_STOP", ROREG_INT(LUAT_BLE_EVENT_SCAN_STOP)},
  306. {"EVENT_SCAN_DEINIT", ROREG_INT(LUAT_BLE_EVENT_SCAN_DEINIT)},
  307. {"EVENT_CONN", ROREG_INT(LUAT_BLE_EVENT_CONN)},
  308. {"EVENT_DISCONN", ROREG_INT(LUAT_BLE_EVENT_DISCONN)},
  309. {"EVENT_WRITE", ROREG_INT(LUAT_BLE_EVENT_WRITE)},
  310. {"EVENT_READ", ROREG_INT(LUAT_BLE_EVENT_READ)},
  311. // ADV_ADDR_MODE
  312. {"PUBLIC", ROREG_INT(LUAT_BLE_ADV_ADDR_MODE_PUBLIC)},
  313. {"RANDOM", ROREG_INT(LUAT_BLE_ADV_ADDR_MODE_RANDOM)},
  314. {"RPA", ROREG_INT(LUAT_BLE_ADV_ADDR_MODE_RPA)},
  315. {"NRPA", ROREG_INT(LUAT_BLE_ADV_ADDR_MODE_NRPA)},
  316. // ADV_CHNL
  317. {"CHNL_37", ROREG_INT(LUAT_BLE_ADV_CHNL_37)},
  318. {"CHNL_38", ROREG_INT(LUAT_BLE_ADV_CHNL_38)},
  319. {"CHNL_39", ROREG_INT(LUAT_BLE_ADV_CHNL_39)},
  320. {"CHNLS_ALL", ROREG_INT(LUAT_BLE_ADV_CHNLS_ALL)},
  321. // Permission
  322. {"READ", ROREG_INT(LUAT_BLE_GATT_PERM_READ)},
  323. {"WRITE", ROREG_INT(LUAT_BLE_GATT_PERM_WRITE)},
  324. {"IND", ROREG_INT(LUAT_BLE_GATT_PERM_IND)},
  325. {"NOTIFY", ROREG_INT(LUAT_BLE_GATT_PERM_NOTIFY)},
  326. // FLAGS
  327. {"FLAGS", ROREG_INT(LUAT_ADV_TYPE_FLAGS)},
  328. {"COMPLETE_LOCAL_NAME", ROREG_INT(LUAT_ADV_TYPE_COMPLETE_LOCAL_NAME)},
  329. {"SERVICE_DATA", ROREG_INT(LUAT_ADV_TYPE_SERVICE_DATA_16BIT)},
  330. {"MANUFACTURER_SPECIFIC_DATA", ROREG_INT(LUAT_ADV_TYPE_MANUFACTURER_SPECIFIC_DATA)},
  331. { NULL, ROREG_INT(0)}
  332. };
  333. static int _bluetooth_struct_newindex(lua_State *L) {
  334. const rotable_Reg_t* reg = reg_bluetooth;
  335. const char* key = luaL_checkstring(L, 2);
  336. while (1) {
  337. if (reg->name == NULL)
  338. return 0;
  339. if (!strcmp(reg->name, key)) {
  340. lua_pushcfunction(L, reg->value.value.func);
  341. return 1;
  342. }
  343. reg ++;
  344. }
  345. }
  346. LUAMOD_API int luaopen_bluetooth( lua_State *L ) {
  347. rotable2_newlib(L, reg_bluetooth);
  348. luat_bluetooth_struct_init(L);
  349. lua_pushvalue(L, -1);
  350. lua_setglobal(L, "ble");
  351. return 1;
  352. }