luat_lib_bluetooth.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  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. default:
  26. break;
  27. }
  28. return 0;
  29. }
  30. static void luat_ble_cb(luat_bluetooth_t* luat_bluetooth, luat_ble_event_t ble_event, luat_ble_param_t* ble_param){
  31. luat_ble_wlan_config_info_t* config_info = (luat_ble_wlan_config_info_t*)luat_bluetooth->luat_ble->userdata;
  32. luat_ble_wlan_config_cb_t luat_ble_wlan_config_cb = luat_bluetooth->luat_ble->wlan_config_cb;
  33. // LLOGD("ble event: %d", ble_event);
  34. rtos_msg_t msg = {
  35. .handler = luatos_ble_callback,
  36. .ptr = (void*)luat_bluetooth,
  37. .arg1 = (int)ble_event,
  38. .arg2 = (int)ble_param,
  39. };
  40. luat_msgbus_put(&msg, 0);
  41. }
  42. static int l_bluetooth_create(lua_State* L) {
  43. if (!lua_isuserdata(L, 1)){
  44. return 0;
  45. }
  46. size_t len = 0;
  47. luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t *)luaL_checkudata(L, 1, LUAT_BLUETOOTH_TYPE);
  48. const char* type = luaL_checklstring(L, 2, &len);
  49. if(memcmp("ble", type, len) == 0 || memcmp("BLE", type, len) == 0){
  50. luat_ble_init(luat_bluetooth, luat_ble_cb);
  51. int ble_param = lua_gettable(L, 2);
  52. if (lua_gettable(L, 2) == LUA_TTABLE){
  53. /* code */
  54. }
  55. }else{
  56. LLOGE("error type: %s", type);
  57. return 0;
  58. }
  59. return 0;
  60. }
  61. static int l_bluetooth_create_ble(lua_State* L) {
  62. if (!lua_isuserdata(L, 1)){
  63. return 0;
  64. }
  65. luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t *)luaL_checkudata(L, 1, LUAT_BLUETOOTH_TYPE);
  66. luat_ble_init(luat_bluetooth, luat_ble_cb);
  67. if (lua_isfunction(L, 2)) {
  68. lua_pushvalue(L, 2);
  69. luat_bluetooth->luat_ble->lua_cb = luaL_ref(L, LUA_REGISTRYINDEX);
  70. }
  71. lua_pushboolean(L, 1);
  72. return 1;
  73. }
  74. static int l_ble_gatt_create(lua_State* L) {
  75. if (!lua_isuserdata(L, 1)){
  76. return 0;
  77. }
  78. if (lua_type(L, 2) != LUA_TTABLE){
  79. LLOGE("error param");
  80. return 0;
  81. }
  82. size_t len = 0;
  83. luat_ble_gatt_cfg_t luat_ble_gatt_cfg = {0};
  84. luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t *)luaL_checkudata(L, 1, LUAT_BLUETOOTH_TYPE);
  85. lua_pushstring(L, "uuid");
  86. if (LUA_TSTRING == lua_gettable(L, -2)){
  87. const char* data = luaL_checklstring(L, -1, &len);
  88. memcpy(luat_ble_gatt_cfg.uuid, data, len);
  89. }
  90. lua_pop(L, 1);
  91. lua_pushstring(L, "att_db");
  92. if (LUA_TTABLE == lua_gettable(L, -2)){
  93. luat_ble_gatt_cfg.att_db_num = luaL_len(L, -1);
  94. 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);
  95. for (int i = 1; i <= luat_ble_gatt_cfg.att_db_num; i++) {
  96. lua_rawgeti(L, -1, i);
  97. int table_len = luaL_len(L, -1);
  98. for (int j = 1; j <= table_len; j++){
  99. lua_rawgeti(L, -1, j);
  100. if (j == 1 && lua_type(L, -1) == LUA_TSTRING){
  101. const char* data = luaL_checklstring(L, -1, &len);
  102. memcpy(luat_ble_gatt_cfg.att_db[i-1].uuid, data, len);
  103. }else if(j == 2 && lua_type(L, -1) == LUA_TNUMBER){
  104. luat_ble_gatt_cfg.att_db[i-1].perm = (uint16_t)luaL_optnumber(L, -1, 0);
  105. }else if(j == 3 && lua_type(L, -1) == LUA_TNUMBER){
  106. luat_ble_gatt_cfg.att_db[i-1].ext_perm = (uint16_t)luaL_optnumber(L, -1, 0);
  107. }else if(j == 4 && lua_type(L, -1) == LUA_TNUMBER){
  108. luat_ble_gatt_cfg.att_db[i-1].max_size = (uint16_t)luaL_optnumber(L, -1, 0);
  109. }else{
  110. LLOGE("error att_db type");
  111. goto end;
  112. }
  113. lua_pop(L, 1);
  114. }
  115. lua_pop(L, 1);
  116. }
  117. }
  118. lua_pop(L, 1);
  119. luat_ble_create_gatt(luat_bluetooth, &luat_ble_gatt_cfg);
  120. luat_heap_free(luat_ble_gatt_cfg.att_db);
  121. // if (lua_isfunction(L, 3)) {
  122. // lua_pushvalue(L, 3);
  123. // luat_bluetooth->luat_ble->lua_cb = luaL_ref(L, LUA_REGISTRYINDEX);
  124. // }
  125. lua_pushboolean(L, 1);
  126. return 1;
  127. end:
  128. return 0;
  129. }
  130. static int l_ble_advertising_create(lua_State* L) {
  131. if (!lua_isuserdata(L, 1)){
  132. return 0;
  133. }
  134. if (lua_type(L, 2) != LUA_TTABLE){
  135. LLOGE("error param");
  136. return 0;
  137. }
  138. luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t *)luaL_checkudata(L, 1, LUAT_BLUETOOTH_TYPE);
  139. size_t len = 0;
  140. // const char* complete_local_name = NULL;
  141. // lua_pushstring(L, "name");
  142. // if (LUA_TSTRING == lua_gettable(L, 2)) {
  143. // complete_local_name = luaL_checklstring(L, -1, &len);
  144. // }else{
  145. // complete_local_name = (char* )luat_heap_malloc(32);
  146. // memset(complete_local_name, 0, 32);
  147. // sprintf_(complete_local_name, "LuatOS_%s", luat_os_bsp());
  148. // }
  149. // lua_pop(L, 1);
  150. luat_ble_adv_cfg_t luat_ble_adv_cfg = {
  151. .addr_mode = LUAT_BLE_ADV_ADDR_MODE_PUBLIC,
  152. .channel_map = LUAT_BLE_ADV_CHNLS_ALL,
  153. .intv_min = 120,
  154. .intv_max = 160,
  155. };
  156. lua_pushstring(L, "addr_mode");
  157. if (LUA_TNUMBER == lua_gettable(L, -2)){
  158. luat_ble_adv_cfg.addr_mode = luaL_checknumber(L, -1);
  159. }
  160. lua_pop(L, 1);
  161. lua_pushstring(L, "channel_map");
  162. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  163. luat_ble_adv_cfg.channel_map = luaL_checknumber(L, -1);
  164. }
  165. lua_pop(L, 1);
  166. lua_pushstring(L, "intv_min");
  167. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  168. luat_ble_adv_cfg.intv_min = luaL_checknumber(L, -1);
  169. }
  170. lua_pop(L, 1);
  171. lua_pushstring(L, "intv_max");
  172. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  173. luat_ble_adv_cfg.intv_max = luaL_checknumber(L, -1);
  174. }
  175. lua_pop(L, 1);
  176. luat_ble_create_advertising(luat_bluetooth, &luat_ble_adv_cfg);
  177. // 广播内容 (adv data)
  178. uint8_t adv_data[255] = {0};
  179. uint8_t adv_index = 0;
  180. lua_pushstring(L, "adv_data");
  181. if (LUA_TTABLE == lua_gettable(L, -2)){
  182. int adv_data_count = luaL_len(L, -1);
  183. for (int i = 1; i <= adv_data_count; i++) {
  184. lua_rawgeti(L, -1, i);
  185. if (LUA_TTABLE == lua_type(L, -1)){
  186. lua_rawgeti(L, -1, 2);
  187. if (lua_type(L, -1) == LUA_TSTRING){
  188. const char* data = luaL_checklstring(L, -1, &len);
  189. adv_data[adv_index++] = (uint8_t)(len+1);
  190. lua_rawgeti(L, -2, 1);
  191. if (lua_type(L, -1) == LUA_TNUMBER){
  192. adv_data[adv_index++] = (uint8_t)luaL_checknumber(L, -1);
  193. }else{
  194. LLOGE("error adv_data type");
  195. goto end;
  196. }
  197. memcpy(adv_data + adv_index, data, len);
  198. adv_index += len;
  199. lua_pop(L, 2);
  200. }else{
  201. LLOGE("error adv_data type");
  202. goto end;
  203. }
  204. }else{
  205. LLOGE("error adv_data type");
  206. goto end;
  207. }
  208. lua_pop(L, 1);
  209. }
  210. }
  211. lua_pop(L, 1);
  212. /* set adv paramters */
  213. luat_ble_set_adv_data(luat_bluetooth, adv_data, adv_index);
  214. // luat_ble_set_name(luat_bluetooth, complete_local_name, strlen(complete_local_name));
  215. lua_pushboolean(L, 1);
  216. return 1;
  217. end:
  218. return 0;
  219. }
  220. static int l_ble_advertising_start(lua_State* L) {
  221. luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t*)lua_newuserdata(L, sizeof(luat_bluetooth_t));
  222. lua_pushboolean(L, luat_ble_start_advertising(luat_bluetooth)?0:1);
  223. return 1;
  224. }
  225. static int l_ble_advertising_stop(lua_State* L) {
  226. luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t*)lua_newuserdata(L, sizeof(luat_bluetooth_t));
  227. lua_pushboolean(L, luat_ble_stop_advertising(luat_bluetooth)?0:1);
  228. return 1;
  229. }
  230. static int l_bluetooth_init(lua_State* L) {
  231. luat_bluetooth_t* luat_bluetooth = (luat_bluetooth_t*)lua_newuserdata(L, sizeof(luat_bluetooth_t));
  232. if (luat_bluetooth) {
  233. luat_bluetooth_init(luat_bluetooth);
  234. luaL_setmetatable(L, LUAT_BLUETOOTH_TYPE);
  235. lua_pushvalue(L, -1);
  236. luat_bluetooth->bluetooth_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  237. return 1;
  238. }
  239. return 0;
  240. }
  241. static int _bluetooth_struct_newindex(lua_State *L);
  242. void luat_bluetooth_struct_init(lua_State *L) {
  243. luaL_newmetatable(L, LUAT_BLUETOOTH_TYPE);
  244. lua_pushcfunction(L, _bluetooth_struct_newindex);
  245. lua_setfield( L, -2, "__index" );
  246. lua_pop(L, 1);
  247. }
  248. #include "rotable2.h"
  249. static const rotable_Reg_t reg_bluetooth[] =
  250. {
  251. {"init", ROREG_FUNC(l_bluetooth_init)},
  252. {"create", ROREG_FUNC(l_bluetooth_create)},
  253. {"ble", ROREG_FUNC(l_bluetooth_create_ble)},
  254. {"gatt_create", ROREG_FUNC(l_ble_gatt_create)},
  255. {"adv_create", ROREG_FUNC(l_ble_advertising_create)},
  256. {"adv_start", ROREG_FUNC(l_ble_advertising_start)},
  257. {"adv_stop", ROREG_FUNC(l_ble_advertising_stop)},
  258. // ADV_ADDR_MODE
  259. {"PUBLIC", ROREG_INT(LUAT_BLE_ADV_ADDR_MODE_PUBLIC)},
  260. {"RANDOM", ROREG_INT(LUAT_BLE_ADV_ADDR_MODE_RANDOM)},
  261. {"RPA", ROREG_INT(LUAT_BLE_ADV_ADDR_MODE_RPA)},
  262. {"NRPA", ROREG_INT(LUAT_BLE_ADV_ADDR_MODE_NRPA)},
  263. // ADV_CHNL
  264. {"CHNL_37", ROREG_INT(LUAT_BLE_ADV_CHNL_37)},
  265. {"CHNL_38", ROREG_INT(LUAT_BLE_ADV_CHNL_38)},
  266. {"CHNL_39", ROREG_INT(LUAT_BLE_ADV_CHNL_39)},
  267. {"CHNLS_ALL", ROREG_INT(LUAT_BLE_ADV_CHNLS_ALL)},
  268. // Permission
  269. {"READ", ROREG_INT(LUAT_BLE_GATT_PERM_READ)},
  270. {"WRITE", ROREG_INT(LUAT_BLE_GATT_PERM_WRITE)},
  271. {"IND", ROREG_INT(LUAT_BLE_GATT_PERM_IND)},
  272. {"NOTIFY", ROREG_INT(LUAT_BLE_GATT_PERM_NOTIFY)},
  273. // FLAGS
  274. {"FLAGS", ROREG_INT(LUAT_ADV_TYPE_FLAGS)},
  275. {"COMPLETE_LOCAL_NAME", ROREG_INT(LUAT_ADV_TYPE_COMPLETE_LOCAL_NAME)},
  276. {"SERVICE_DATA", ROREG_INT(LUAT_ADV_TYPE_SERVICE_DATA_16BIT)},
  277. {"MANUFACTURER_SPECIFIC_DATA", ROREG_INT(LUAT_ADV_TYPE_MANUFACTURER_SPECIFIC_DATA)},
  278. { NULL, ROREG_INT(0)}
  279. };
  280. static int _bluetooth_struct_newindex(lua_State *L) {
  281. const rotable_Reg_t* reg = reg_bluetooth;
  282. const char* key = luaL_checkstring(L, 2);
  283. while (1) {
  284. if (reg->name == NULL)
  285. return 0;
  286. if (!strcmp(reg->name, key)) {
  287. lua_pushcfunction(L, reg->value.value.func);
  288. return 1;
  289. }
  290. reg ++;
  291. }
  292. }
  293. LUAMOD_API int luaopen_bluetooth( lua_State *L ) {
  294. rotable2_newlib(L, reg_bluetooth);
  295. luat_bluetooth_struct_init(L);
  296. lua_pushvalue(L, -1);
  297. lua_setglobal(L, "ble");
  298. return 1;
  299. }