| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256 |
- /*
- @module ble
- @summary 低功耗蓝牙
- @version 1.0
- @date 2025.6.21
- @usage
- -- 本库用于操作BLE对象, 需要搭配bluetooth.init()使用
- -- 详细用法请查阅demo
- -- 模式解释
- -- 从机模式(peripheral), 设备会被扫描到, 并且可以被连接
- -- 主机模式(central), 设备会扫描其他设备, 并且可以连接其他设备
- -- 广播者模式(ibeacon), 设备会周期性的广播beacon信息, 但不会被扫描到, 也不会连接其他设备
- -- 观察者模式(scan), 设备会扫描其他设备, 但不会连接其他设备
- -- 从机模式(peripheral)的基本流程(概要描述)
- -- 1. 初始化蓝牙框架
- -- 2. 创建BLE对象
- -- local ble_device = bluetooth_device:ble(ble_event_cb)
- -- 3. 创建GATT描述
- -- local att_db = {xxx}
- -- 4. 创建广播信息
- -- ble_device:adv_create(adv_data)
- -- 5. 开始广播
- -- ble_device:adv_start()
- -- 6. 等待连接
- -- 7. 在回调函数中处理连接事件, 如接收数据, 发送数据等
- -- 主机模式(central)的基本流程(概要描述)
- -- TODO
- -- 广播者模式(ibeacon)的基本流程(概要描述)
- -- TODO
- -- 观察者模式(scan)的基本流程(概要描述)
- -- 1. 初始化蓝牙框架
- -- 2. 创建BLE对象
- -- local ble_device = bluetooth_device:ble(ble_event_cb)
- -- 3. 开始扫描
- -- ble_device:scan_start()
- -- 4. 在回调函数中处理扫描事件, 如接收设备信息等
- -- 5. 按需停止扫描
- -- ble_device:scan_stop()
- */
- #include "luat_base.h"
- #include "luat_mem.h"
- #include "luat_rtos.h"
- #include "luat_msgbus.h"
- #include "luat_ble.h"
- #include "luat_bluetooth.h"
- #include "luat_log.h"
- #define LUAT_LOG_TAG "bt.ble"
- #define LUAT_BLE_TYPE "BLE*"
- extern int g_bt_ble_ref;
- extern int g_ble_lua_cb_ref;
- int l_ble_callback(lua_State *L, void *ptr)
- {
- (void)ptr;
- rtos_msg_t *msg = (rtos_msg_t *)lua_topointer(L, -1);
- luat_ble_event_t evt = (luat_ble_event_t)msg->arg1;
- luat_ble_param_t *param = (luat_ble_param_t *)msg->arg2;
- uint8_t tmpbuff[16] = {0};
- lua_geti(L, LUA_REGISTRYINDEX, g_ble_lua_cb_ref);
- if (lua_isfunction(L, -1)){
- lua_geti(L, LUA_REGISTRYINDEX, g_bt_ble_ref);
- lua_pushinteger(L, evt);
- }else{
- LLOGE("用户回调函数不存在");
- goto exit;
- }
- switch (evt){
- case LUAT_BLE_EVENT_WRITE:{
- luat_ble_write_req_t *write_req = &(param->write_req);
- lua_createtable(L, 0, 5);
- lua_pushliteral(L, "handle");
- lua_pushinteger(L, write_req->handle);
- lua_settable(L, -3);
- lua_pushliteral(L, "uuid_service");
- lua_pushlstring(L, (const char *)write_req->uuid_service.uuid, write_req->uuid_service.uuid_type);
- lua_settable(L, -3);
- lua_pushliteral(L, "uuid_characteristic");
- lua_pushlstring(L, (const char *)write_req->uuid_characteristic.uuid, write_req->uuid_characteristic.uuid_type);
- lua_settable(L, -3);
- if (write_req->uuid_descriptor.uuid[0] != 0 || write_req->uuid_descriptor.uuid[1] != 0){
- lua_pushliteral(L, "uuid_descriptor");
- lua_pushlstring(L, (const char *)write_req->uuid_descriptor.uuid, write_req->uuid_descriptor.uuid_type);
- lua_settable(L, -3);
- }
- lua_pushliteral(L, "data");
- lua_pushlstring(L, (const char *)write_req->value, write_req->value_len);
- lua_settable(L, -3);
- lua_call(L, 3, 0);
- break;
- }
- case LUAT_BLE_EVENT_READ:
- case LUAT_BLE_EVENT_READ_VALUE:{
- luat_ble_read_req_t *read_req = &(param->read_req);
- lua_createtable(L, 0, 5);
- lua_pushliteral(L, "handle");
- lua_pushinteger(L, read_req->handle);
- lua_settable(L, -3);
- lua_pushliteral(L, "uuid_service");
- lua_pushlstring(L, (const char *)read_req->uuid_service.uuid, read_req->uuid_service.uuid_type);
- lua_settable(L, -3);
- lua_pushliteral(L, "uuid_characteristic");
- lua_pushlstring(L, (const char *)read_req->uuid_characteristic.uuid, read_req->uuid_characteristic.uuid_type);
- lua_settable(L, -3);
- if (read_req->uuid_descriptor.uuid[0] != 0 || read_req->uuid_descriptor.uuid[1] != 0){
- lua_pushliteral(L, "uuid_descriptor");
- lua_pushlstring(L, (const char *)read_req->uuid_descriptor.uuid, read_req->uuid_descriptor.uuid_type);
- lua_settable(L, -3);
- }
- if (evt == LUAT_BLE_EVENT_READ_VALUE){
- lua_pushliteral(L, "data");
- lua_pushlstring(L, (const char *)read_req->value, read_req->value_len);
- lua_settable(L, -3);
- }
- lua_call(L, 3, 0);
- break;
- }case LUAT_BLE_EVENT_SCAN_REPORT:{
- luat_ble_adv_req_t *adv_req = &(param->adv_req);
- lua_createtable(L, 0, 4);
- lua_pushliteral(L, "rssi");
- lua_pushinteger(L, adv_req->rssi);
- lua_settable(L, -3);
- lua_pushliteral(L, "addr_type");
- lua_pushinteger(L, adv_req->adv_addr_type);
- lua_settable(L, -3);
- lua_pushliteral(L, "adv_addr");
- lua_pushlstring(L, (const char *)adv_req->adv_addr, 6);
- lua_settable(L, -3);
- lua_pushliteral(L, "data");
- lua_pushlstring(L, (const char *)adv_req->data, adv_req->data_len);
- lua_settable(L, -3);
- // uint8_t actv_idx; /**< The index of the activity */
- // uint8_t evt_type; /**< Event type (see enum \ref adv_report_info and see enum \ref adv_report_type)*/
- lua_call(L, 3, 0);
- break;
- }case LUAT_BLE_EVENT_GATT_ITEM:{
- luat_ble_gatt_service_t *gatt_service = param->gatt_item_ind.gatt_service;
- lua_newtable(L);
- // servise uuid
- lua_pushlstring(L, (const char *)gatt_service->uuid, gatt_service->uuid_type);
- lua_rawseti(L, -2, 1);
- // characteristics
- uint8_t characteristics_num = gatt_service->characteristics_num;
- for (size_t m = 0; m < characteristics_num; m++){
- luat_ble_gatt_chara_t *gatt_chara = &gatt_service->characteristics[m];
- lua_newtable(L);
- lua_pushlstring(L, (const char *)gatt_chara->uuid, gatt_chara->uuid_type);
- lua_seti(L, -2, 1);
- // Properties
- lua_pushnumber(L, gatt_chara->perm);
- lua_seti(L, -2, 2);
- lua_seti(L, -2, m + 2);
- }
- lua_call(L, 3, 0);
- break;
- }case LUAT_BLE_EVENT_GATT_DONE:{
- uint8_t gatt_service_num = param->gatt_done_ind.gatt_service_num;
- lua_newtable(L);
- lua_pushinteger(L, gatt_service_num);
- lua_setfield(L, -2, "service_num");
- lua_call(L, 3, 0);
- break;
- }case LUAT_BLE_EVENT_CONN:{
- luat_ble_conn_ind_t *conn = &(param->conn_ind);
- lua_newtable(L);
- memcpy(tmpbuff, conn->peer_addr, 6);
- luat_bluetooth_mac_swap(tmpbuff);
- lua_pushlstring(L, (const char *)tmpbuff, 6);
- lua_setfield(L, -2, "addr");
- lua_pushinteger(L, conn->peer_addr_type);
- lua_setfield(L, -2, "addr_type");
- lua_call(L, 3, 0);
- break;
- }case LUAT_BLE_EVENT_DISCONN:{
- luat_ble_disconn_ind_t *disconn = &(param->disconn_ind);
- lua_newtable(L);
- lua_pushinteger(L, disconn->reason);
- lua_setfield(L, -2, "reason");
- lua_call(L, 3, 0);
- break;
- }
- default:
- lua_call(L, 2, 0);
- break;
- }
- exit:
- if (param)
- {
- if (LUAT_BLE_EVENT_WRITE == evt && param->write_req.value_len)
- {
- // LLOGD("free write_req.value %p", param->write_req.value);
- luat_heap_free(param->write_req.value);
- param->write_req.value = NULL;
- }
- else if (LUAT_BLE_EVENT_SCAN_REPORT == evt && param->adv_req.data)
- {
- // LLOGD("free adv_req.data %p", param->adv_req.data);
- luat_heap_free(param->adv_req.data);
- param->adv_req.data = NULL;
- }
- else if (LUAT_BLE_EVENT_READ_VALUE == evt && param->read_req.value_len){
- // LLOGD("free read_req.value %p", param->read_req.value);
- luat_heap_free(param->read_req.value);
- param->read_req.value = NULL;
- }
- luat_heap_free(param);
- param = NULL;
- }
- return 0;
- }
- void luat_ble_cb(luat_ble_t *args, luat_ble_event_t ble_event, luat_ble_param_t *ble_param){
- // LLOGD("ble event: %d param: %p", ble_event, ble_param);
- luat_ble_param_t *luat_ble_param = NULL;
- if (ble_param){
- // LLOGD("ble param: %p", ble_param);
- luat_ble_param = luat_heap_malloc(sizeof(luat_ble_param_t));
- memset(luat_ble_param,0,sizeof(luat_ble_param_t));
- memcpy(luat_ble_param, ble_param, sizeof(luat_ble_param_t));
- if (ble_event == LUAT_BLE_EVENT_WRITE && ble_param->write_req.value_len){
- luat_ble_param->write_req.value = luat_heap_malloc(ble_param->write_req.value_len);
- memcpy(luat_ble_param->write_req.value, ble_param->write_req.value, ble_param->write_req.value_len);
- }else if (ble_event == LUAT_BLE_EVENT_READ_VALUE && ble_param->read_req.value_len){
- luat_ble_param->read_req.value = luat_heap_malloc(ble_param->read_req.value_len);
- memcpy(luat_ble_param->read_req.value, ble_param->read_req.value, ble_param->read_req.value_len);
- }else if (ble_event == LUAT_BLE_EVENT_SCAN_REPORT && ble_param->adv_req.data_len){
- luat_ble_param->adv_req.data = luat_heap_malloc(ble_param->adv_req.data_len);
- memcpy(luat_ble_param->adv_req.data, ble_param->adv_req.data, ble_param->adv_req.data_len);
- }
- }
- rtos_msg_t msg = {
- .handler = l_ble_callback,
- .ptr = (void *)NULL,
- .arg1 = (int)ble_event,
- .arg2 = (int)luat_ble_param,
- };
- luat_msgbus_put(&msg, 0);
- }
- /*
- 创建一个BLE GATT服务
- @api ble.gatt_create(opts)
- @table GATT服务的描述信息
- @return boolean 是否创建成功
- @usage
- local att_db = { -- Service
- string.fromHex("FA00"), -- Service UUID, 服务的UUID, 可以是16位、32位或128位
- -- Characteristic
- { -- Characteristic 1
- string.fromHex("EA01"), -- Characteristic UUID Value, 特征的UUID值, 可以是16位、32位或128位
- ble.NOTIFY | ble.READ | ble.WRITE -- Properties, 对应蓝牙特征的属性, 参考权限常量
- string.fromHex("1234"), -- 默认value
- }
- }
- ble_device:gatt_create(att_db)
- */
- static int l_ble_gatt_create(lua_State *L){
- if (!lua_isuserdata(L, 1)){
- return 0;
- }
- uint8_t characteristics_num = 0;
- size_t len = 0;
- luat_ble_gatt_service_t *luat_ble_gatt_service = luat_heap_malloc(sizeof(luat_ble_gatt_service_t));
- memset(luat_ble_gatt_service, 0, sizeof(luat_ble_gatt_service_t));
- if (lua_type(L, 2) != LUA_TTABLE){
- LLOGE("error param");
- return 0;
- }
- int gatt_table_len = luaL_len(L, 2) - 1;
- if (lua_rawgeti(L, -1, 1) == LUA_TSTRING){
- const char *service_uuid = luaL_checklstring(L, -1, &len);
- if (len == 2){
- luat_ble_gatt_service->uuid_type = LUAT_BLE_UUID_TYPE_16;
- }else if (len == 4){
- luat_ble_gatt_service->uuid_type = LUAT_BLE_UUID_TYPE_32;
- }else if (len == 16){
- luat_ble_gatt_service->uuid_type = LUAT_BLE_UUID_TYPE_128;
- }
- memcpy(luat_ble_gatt_service->uuid, service_uuid, len);
- }else if (lua_rawgeti(L, -1, 1) == LUA_TNUMBER){
- uint16_t service_uuid = (uint16_t)luaL_checknumber(L, -1);
- luat_ble_gatt_service->uuid_type = LUAT_BLE_UUID_TYPE_16;
- luat_ble_gatt_service->uuid[0] = service_uuid & 0xff;
- luat_ble_gatt_service->uuid[1] = service_uuid >> 8;
- }else{
- LLOGE("error uuid type");
- return 0;
- }
- lua_pop(L, 1);
- // Characteristics
- luat_ble_gatt_service->characteristics = (luat_ble_gatt_chara_t *)luat_heap_malloc(sizeof(luat_ble_gatt_chara_t) * gatt_table_len);
- memset(luat_ble_gatt_service->characteristics, 0, sizeof(luat_ble_gatt_chara_t) * gatt_table_len);
- luat_ble_gatt_chara_t *characteristics = luat_ble_gatt_service->characteristics;
- for (size_t j = 2; j <= gatt_table_len + 1; j++){
- if (lua_rawgeti(L, -1, j) == LUA_TTABLE){
- lua_rawgeti(L, -1, 1);
- // lua_pushstring(L, "descriptor");
- // if (LUA_TSTRING == lua_gettable(L, -2)){
- // const char* value = luaL_checklstring(L, -1, &len);
- // characteristics[j-2].value = luat_heap_malloc(len);
- // characteristics[j-2].value_len = len;
- // }
- // lua_pop(L, 1);
- // UUID
- uint16_t uuid_type = 0;
- uint8_t uuid[LUAT_BLE_UUID_LEN_MAX] = {0};
- if (LUA_TSTRING == lua_type(L, -1)){
- const char *characteristics_uuid = luaL_checklstring(L, -1, &len);
- uuid_type = len;
- memcpy(uuid, characteristics_uuid, len);
- }else if (LUA_TNUMBER == lua_type(L, -1)){
- uint16_t characteristics_uuid = (uint16_t)luaL_checknumber(L, -1);
- uuid_type = LUAT_BLE_UUID_TYPE_16;
- uuid[0] = characteristics_uuid >> 8;
- uuid[1] = characteristics_uuid & 0xFF;
- }else{
- LLOGE("error characteristics uuid type");
- goto error_exit;
- }
- lua_pop(L, 1);
- if (characteristics[characteristics_num].uuid_type == LUAT_BLE_UUID_TYPE_16 &&
- characteristics[characteristics_num].uuid[0] == (LUAT_BLE_GATT_DESC_MAX >> 8) &&
- characteristics[characteristics_num].uuid[1] <= (LUAT_BLE_GATT_DESC_MAX & 0xFF)){
- // Descriptors
- characteristics[characteristics_num].perm |= LUAT_BLE_GATT_PERM_READ;
- characteristics[characteristics_num].perm |= LUAT_BLE_GATT_PERM_WRITE;
- characteristics[characteristics_num].max_size = 0;
- luat_ble_gatt_descriptor_t *descriptor = characteristics[characteristics_num].descriptor;
- if (descriptor){
- descriptor = luat_heap_realloc(descriptor,sizeof(luat_ble_gatt_descriptor_t)*(characteristics[characteristics_num].descriptors_num+1));
- descriptor[characteristics[characteristics_num].descriptors_num].uuid_type = uuid_type;
- memcpy(descriptor[characteristics[characteristics_num].descriptors_num].uuid, uuid, len);
- }else{
- descriptor = luat_heap_malloc(sizeof(luat_ble_gatt_descriptor_t));
- descriptor->uuid_type = uuid_type;
- memcpy(descriptor->uuid, uuid, len);
- }
- characteristics[characteristics_num].descriptors_num++;
- }else{
- // Characteristics uuid
- characteristics[characteristics_num].uuid_type = uuid_type;
- memcpy(characteristics[characteristics_num].uuid, uuid, len);
- // Characteristics properties
- lua_rawgeti(L, -1, 2);
- if (LUA_TNUMBER == lua_type(L, -1)){
- characteristics[characteristics_num].perm = (uint16_t)luaL_optnumber(L, -1, 0);
- }
- lua_pop(L, 1);
- // Descriptors
- if (characteristics[characteristics_num].perm & LUAT_BLE_GATT_PERM_NOTIFY){
- luat_ble_gatt_chara_t *characteristic = &characteristics[characteristics_num];
- if (characteristic->descriptor){
- uint8_t descriptor_ind = characteristics[characteristics_num].descriptors_num;
- characteristic->descriptor = luat_heap_realloc(characteristic->descriptor,sizeof(luat_ble_gatt_descriptor_t)*(descriptor_ind+1));
- memset(&characteristic->descriptor[descriptor_ind],0,sizeof(luat_ble_gatt_descriptor_t));
- characteristic->descriptor[descriptor_ind].uuid_type = LUAT_BLE_UUID_TYPE_16;
- characteristic->descriptor[descriptor_ind].uuid[0] = 0x2902 >> 8;
- characteristic->descriptor[descriptor_ind].uuid[1] = 0x2902 & 0xFF;
- }else{
- characteristic->descriptor = luat_heap_malloc(sizeof(luat_ble_gatt_descriptor_t));
- memset(characteristic->descriptor,0,sizeof(luat_ble_gatt_descriptor_t));
- characteristic->descriptor->uuid_type = LUAT_BLE_UUID_TYPE_16;
- characteristic->descriptor->uuid[0] = 0x2902 >> 8;
- characteristic->descriptor->uuid[1] = 0x2902 & 0xFF;
- }
- characteristics[characteristics_num].descriptors_num++;
- }
- // Characteristics value
- lua_rawgeti(L, -1, 3);
- if (LUA_TSTRING == lua_type(L, -1)){
- const char *value = luaL_checklstring(L, -1, &len);
- characteristics[characteristics_num].value = luat_heap_malloc(len);
- memcpy(characteristics[characteristics_num].value, value, len);
- characteristics[characteristics_num].value_len = len;
- }
- lua_pop(L, 1);
- // Characteristics max_size
- lua_pushstring(L, "max_size");
- if (LUA_TNUMBER == lua_gettable(L, -2)){
- characteristics[characteristics_num].max_size = (uint16_t)luaL_optnumber(L, -1, 0);
- }else{
- characteristics[characteristics_num].max_size = 256;
- }
- lua_pop(L, 1);
- characteristics_num++;
- }
- }
- lua_pop(L, 1);
- }
- luat_ble_gatt_service->characteristics_num = characteristics_num;
- lua_pushboolean(L, luat_ble_create_gatt(NULL, luat_ble_gatt_service) == 0 ? 1 : 0);
- return 1;
- error_exit:
- return 0;
- }
- /*
- 创建一个BLE广播
- @api ble.adv_create(opts)
- @table 广播的描述信息
- @return boolean 是否创建成功
- @usage
- -- 创建广播信息
- ble_device:adv_create({
- addr_mode = ble.PUBLIC, -- 广播地址模式, 可选值: ble.PUBLIC, ble.RANDOM, ble.RPA, ble.NRPA
- channel_map = ble.CHNLS_ALL, -- 广播的通道, 可选值: ble.CHNLS_37, ble.CHNLS_38, ble.CHNLS_39, ble.CHNLS_ALL
- intv_min = 120, -- 广播间隔最小值, 单位为0.625ms, 最小值为20, 最大值为10240
- intv_max = 120, -- 广播间隔最大值, 单位为0.625ms, 最小值为20, 最大值为10240
- adv_data = { -- 支持表格形式, 也支持字符串形式(255字节以内)
- {ble.FLAGS, string.char(0x06)},
- {ble.COMPLETE_LOCAL_NAME, "LuatOS123"}, -- 广播的设备名
- {ble.SERVICE_DATA, string.fromHex("FE01")}, -- 广播的服务数据
- {ble.MANUFACTURER_SPECIFIC_DATA, string.fromHex("05F0")}
- }
- })
- */
- 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;
- }
- size_t len = 0;
- uint8_t local_name_set_flag = 0;
- const char complete_local_name[32] = {0};
- luat_ble_adv_cfg_t luat_ble_adv_cfg = {
- .addr_mode = LUAT_BLE_ADDR_MODE_PUBLIC,
- .channel_map = LUAT_BLE_ADV_CHNLS_ALL,
- .intv_min = 120,
- .intv_max = 160,
- .adv_type = LUAT_BLE_ADV_TYPE_LEGACY,
- .adv_prop = LUAT_BLE_ADV_PROP_CONNECTABLE | LUAT_BLE_ADV_PROP_SCANNABLE,
- };
- 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);
- lua_pushstring(L, "adv_type");
- if (LUA_TNUMBER == lua_gettable(L, 2)){
- luat_ble_adv_cfg.adv_type = luaL_checknumber(L, -1);
- }
- lua_pop(L, 1);
- lua_pushstring(L, "adv_prop");
- if (LUA_TNUMBER == lua_gettable(L, 2)){
- luat_ble_adv_cfg.adv_prop = luaL_checknumber(L, -1);
- }
- lua_pop(L, 1);
- luat_ble_create_advertising(NULL, &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){
- uint8_t adv_type = (uint8_t)luaL_checknumber(L, -1);
- adv_data[adv_index++] = adv_type;
- if (adv_type == LUAT_ADV_TYPE_COMPLETE_LOCAL_NAME){
- luat_ble_set_name(NULL, data, len);
- local_name_set_flag = 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);
- }
- }
- else if (lua_isstring(L, -1)){
- // 字符串形式
- const char *data = luaL_checklstring(L, -1, &len);
- if (len > 255) {
- LLOGE("adv_data too long, max length is 255");
- goto end;
- }
- memcpy(adv_data, data, len);
- adv_index = len;
- }
- else {
- LLOGE("error adv_data type");
- goto end;
- }
- lua_pop(L, 1);
- if (!local_name_set_flag){
- sprintf_(complete_local_name, "LuatOS_%s", luat_os_bsp());
- luat_ble_set_name(NULL, complete_local_name, strlen(complete_local_name));
- }
- /* set adv paramters */
- luat_ble_set_adv_data(NULL, adv_data, adv_index);
- lua_pushstring(L, "rsp_data");
- if (LUA_TSTRING == lua_gettable(L, 2)){
- uint8_t *rsp_data = luaL_checklstring(L, -1, &len);
- if (len){
- luat_ble_set_scan_rsp_data(NULL, rsp_data, len);
- }
- }
- lua_pop(L, 1);
- lua_pushboolean(L, 1);
- return 1;
- end:
- return 0;
- }
- /*
- 开始广播
- @api ble.adv_start()
- @return boolean 是否成功
- @usage
- -- 开始广播
- ble_device:adv_start()
- -- 提醒, 对于从机模式, 如果被断开了连接, 则需要重新开始广播, 才能被重新搜索到
- */
- static int l_ble_advertising_start(lua_State *L){
- lua_pushboolean(L, luat_ble_start_advertising(NULL) ? 0 : 1);
- return 1;
- }
- /*
- 主动停止广播
- @api ble.adv_stop()
- @return boolean 是否成功
- @usage
- -- 停止广播
- ble_device:adv_stop()
- */
- static int l_ble_advertising_stop(lua_State *L){
- lua_pushboolean(L, luat_ble_stop_advertising(NULL) ? 0 : 1);
- return 1;
- }
- /*
- 写入带通知的特征值
- @api ble.write_notify(opts, value)
- @table 特征值的描述信息
- @string value 要写入的值
- @return boolean 是否成功
- @usage
- -- 写入带通知的特征值
- ble_device:write_notify({
- uuid_service = "FA00", -- 服务的UUID, 可以是16位、32位或128位
- uuid_characteristic = "EA01", -- 特征的UUID值, 可以是16位、32位或128位
- }, "Hello BLE") -- 要写入的值
- */
- static int l_ble_write_notify(lua_State *L){
- uint16_t ret = 0;
- const char *service_uuid = NULL;
- const char *characteristic_uuid = NULL;
- const char *descriptor_uuid = NULL;
- luat_ble_uuid_t service = {0};
- luat_ble_uuid_t characteristic = {0};
- luat_ble_uuid_t descriptor = {0};
- size_t tmp = 0;
- if (1){
- size_t len = 0;
- const char *value = luaL_checklstring(L, 3, &len);
- lua_pushstring(L, "uuid_service");
- if (LUA_TSTRING == lua_gettable(L, 2)){
- service_uuid = luaL_checklstring(L, -1, &tmp);
- service.uuid_type = tmp;
- memcpy(service.uuid, service_uuid, service.uuid_type);
- // LLOGD("uuid_service: %02X %02X", service.uuid[0], service.uuid[1]);
- }
- else{
- LLOGW("缺失 uuid_service 参数");
- goto end_error;
- }
- lua_pop(L, 1);
- lua_pushstring(L, "uuid_characteristic");
- if (LUA_TSTRING == lua_gettable(L, 2)){
- characteristic_uuid = luaL_checklstring(L, -1, &tmp);
- characteristic.uuid_type = tmp;
- memcpy(characteristic.uuid, characteristic_uuid, characteristic.uuid_type);
- // LLOGD("uuid_characteristic: %02X %02X", characteristic.uuid[0], characteristic.uuid[1]);
- }
- else{
- LLOGW("缺失 uuid_characteristic 参数");
- goto end_error;
- }
- lua_pop(L, 1);
- lua_pushstring(L, "uuid_descriptor");
- if (LUA_TSTRING == lua_gettable(L, 2)){
- descriptor_uuid = luaL_checklstring(L, -1, &tmp);
- descriptor.uuid_type = tmp;
- memcpy(descriptor.uuid, descriptor_uuid, descriptor.uuid_type);
- // LLOGD("uuid_descriptor: %02X %02X", descriptor.uuid[0], descriptor.uuid[1]);
- ret = luat_ble_write_notify_value(&service, &characteristic, &descriptor, (uint8_t *)value, len);
- }else{
- ret = luat_ble_write_notify_value(&service, &characteristic, NULL, (uint8_t *)value, len);
- }
- lua_pop(L, 1);
-
- // LLOGD("luat_ble_write_notify_value ret %d", ret);
- lua_pushboolean(L, ret == 0 ? 1 : 0);
- return 1;
- }
- end_error:
- LLOGE("error param");
- return 0;
- }
- /*
- 写入带指示的特征值
- @api ble.write_indicate(opts, value)
- @table 特征值的描述信息
- @string value 要写入的值
- @return boolean 是否成功
- @usage
- -- 写入带指示的特征值
- ble_device:write_indicate({
- uuid_service = "FA00", -- 服务的UUID, 可以是16位、32位或128位
- uuid_characteristic = "EA01", -- 特征的UUID值, 可以是16位、32位或128位
- }, "Hello BLE") -- 要写入的值
- */
- static int l_ble_write_indicate(lua_State *L){
- uint16_t ret = 0;
- const char *service_uuid = NULL;
- const char *characteristic_uuid = NULL;
- const char *descriptor_uuid = NULL;
- luat_ble_uuid_t service = {0};
- luat_ble_uuid_t characteristic = {0};
- luat_ble_uuid_t descriptor = {0};
- size_t tmp = 0;
- if (1){
- size_t len = 0;
- const char *value = luaL_checklstring(L, 3, &len);
- lua_pushstring(L, "uuid_service");
- if (LUA_TSTRING == lua_gettable(L, 2)){
- service_uuid = luaL_checklstring(L, -1, &tmp);
- service.uuid_type = tmp;
- memcpy(service.uuid, service_uuid, service.uuid_type);
- // LLOGD("uuid_service: %02X %02X", service.uuid[0], service.uuid[1]);
- }
- else{
- LLOGW("缺失 uuid_service 参数");
- goto end_error;
- }
- lua_pop(L, 1);
- lua_pushstring(L, "uuid_characteristic");
- if (LUA_TSTRING == lua_gettable(L, 2)){
- characteristic_uuid = luaL_checklstring(L, -1, &tmp);
- characteristic.uuid_type = tmp;
- memcpy(characteristic.uuid, characteristic_uuid, characteristic.uuid_type);
- // LLOGD("uuid_characteristic: %02X %02X", characteristic.uuid[0], characteristic.uuid[1]);
- }
- else{
- LLOGW("缺失 uuid_characteristic 参数");
- goto end_error;
- }
- lua_pop(L, 1);
- lua_pushstring(L, "uuid_descriptor");
- if (LUA_TSTRING == lua_gettable(L, 2)){
- descriptor_uuid = luaL_checklstring(L, -1, &tmp);
- descriptor.uuid_type = tmp;
- memcpy(descriptor.uuid, descriptor_uuid, descriptor.uuid_type);
- // LLOGD("uuid_descriptor: %02X %02X", descriptor.uuid[0], descriptor.uuid[1]);
- ret = luat_ble_write_indicate_value(&service, &characteristic, &descriptor, (uint8_t *)value, len);
- }else{
- ret = luat_ble_write_indicate_value(&service, &characteristic, NULL, (uint8_t *)value, len);
- }
- lua_pop(L, 1);
-
- // LLOGD("luat_ble_write_indicate_value ret %d", ret);
- lua_pushboolean(L, ret == 0 ? 1 : 0);
- return 1;
- }
- end_error:
- LLOGE("error param");
- return 0;
- }
- /*
- 写入特征值
- @api ble.write_value(opts, value)
- @table 特征值的描述信息
- @string value 要写入的值
- @return boolean 是否成功
- @usage
- -- 写入特征值,填充预设值,被动读取
- ble_device:write_value({
- uuid_service = "FA00", -- 服务的UUID, 可以是16位、32位或128位
- uuid_characteristic = "EA01", -- 特征的UUID值, 可以是16位、32位或128位
- }, "Hello BLE") -- 要写入的值
- */
- static int l_ble_write_value(lua_State *L){
- uint16_t ret = 0;
- const char *service_uuid = NULL;
- const char *characteristic_uuid = NULL;
- const char *descriptor_uuid = NULL;
- luat_ble_uuid_t service = {0};
- luat_ble_uuid_t characteristic = {0};
- luat_ble_uuid_t descriptor = {0};
- size_t tmp = 0;
- if (1){
- size_t len = 0;
- const char *value = luaL_checklstring(L, 3, &len);
- lua_pushstring(L, "uuid_service");
- if (LUA_TSTRING == lua_gettable(L, 2)){
- service_uuid = luaL_checklstring(L, -1, &tmp);
- service.uuid_type = tmp;
- memcpy(service.uuid, service_uuid, service.uuid_type);
- // LLOGD("uuid_service: %02X %02X", service.uuid[0], service.uuid[1]);
- }
- else{
- LLOGW("缺失 uuid_service 参数");
- goto end_error;
- }
- lua_pop(L, 1);
- lua_pushstring(L, "uuid_characteristic");
- if (LUA_TSTRING == lua_gettable(L, 2)){
- characteristic_uuid = luaL_checklstring(L, -1, &tmp);
- characteristic.uuid_type = tmp;
- memcpy(characteristic.uuid, characteristic_uuid, characteristic.uuid_type);
- // LLOGD("uuid_characteristic: %02X %02X", characteristic.uuid[0], characteristic.uuid[1]);
- }
- else{
- LLOGW("缺失 uuid_characteristic 参数");
- goto end_error;
- }
- lua_pop(L, 1);
- lua_pushstring(L, "uuid_descriptor");
- if (LUA_TSTRING == lua_gettable(L, 2)){
- descriptor_uuid = luaL_checklstring(L, -1, &tmp);
- descriptor.uuid_type = tmp;
- memcpy(descriptor.uuid, descriptor_uuid, descriptor.uuid_type);
- // LLOGD("uuid_descriptor: %02X %02X", descriptor.uuid[0], descriptor.uuid[1]);
- ret = luat_ble_write_value(&service, &characteristic, &descriptor, (uint8_t *)value, len);
- }else{
- ret = luat_ble_write_value(&service, &characteristic, NULL, (uint8_t *)value, len);
- }
- lua_pop(L, 1);
-
- // LLOGD("luat_ble_write_value ret %d", ret);
- lua_pushboolean(L, ret == 0 ? 1 : 0);
- return 1;
- }
- end_error:
- LLOGE("error param");
- return 0;
- }
- /*
- 读取特征值
- @api ble.read_value(opts)
- @table 特征值的描述信息
- @return boolean 是否成功
- @usage
- -- 读取特征值,通过回调中的 EVENT_READ_VALUE 事件返回读取的value值
- ble_device:read_value({
- uuid_service = "FA00", -- 服务的UUID, 可以是16位、32位或128位
- uuid_characteristic = "EA01", -- 特征的UUID值, 可以是16位、32位或128位
- })
- */
- static int l_ble_read_value(lua_State *L){
- uint16_t ret = 0;
- const char *service_uuid = NULL;
- const char *characteristic_uuid = NULL;
- const char *descriptor_uuid = NULL;
- luat_ble_uuid_t service = {0};
- luat_ble_uuid_t characteristic = {0};
- luat_ble_uuid_t descriptor = {0};
- size_t tmp = 0;
- if (1){
- size_t len = 0;
- uint8_t* value = NULL;
- lua_pushstring(L, "uuid_service");
- if (LUA_TSTRING == lua_gettable(L, 2)){
- service_uuid = luaL_checklstring(L, -1, &tmp);
- service.uuid_type = tmp;
- memcpy(service.uuid, service_uuid, service.uuid_type);
- // LLOGD("uuid_service: %02X %02X", service.uuid[0], service.uuid[1]);
- }
- else{
- LLOGW("缺失 uuid_service 参数");
- goto end_error;
- }
- lua_pop(L, 1);
- lua_pushstring(L, "uuid_characteristic");
- if (LUA_TSTRING == lua_gettable(L, 2)){
- characteristic_uuid = luaL_checklstring(L, -1, &tmp);
- characteristic.uuid_type = tmp;
- memcpy(characteristic.uuid, characteristic_uuid, characteristic.uuid_type);
- // LLOGD("uuid_characteristic: %02X %02X", characteristic.uuid[0], characteristic.uuid[1]);
- }
- else{
- LLOGW("缺失 uuid_characteristic 参数");
- goto end_error;
- }
- lua_pop(L, 1);
- lua_pushstring(L, "uuid_descriptor");
- if (LUA_TSTRING == lua_gettable(L, 2)){
- descriptor_uuid = luaL_checklstring(L, -1, &tmp);
- descriptor.uuid_type = tmp;
- memcpy(descriptor.uuid, descriptor_uuid, descriptor.uuid_type);
- // LLOGD("uuid_descriptor: %02X %02X", descriptor.uuid[0], descriptor.uuid[1]);
- ret = luat_ble_read_value(&service, &characteristic, &descriptor, &value, &len);
- }else{
- ret = luat_ble_read_value(&service, &characteristic, NULL, &value, &len);
- }
- lua_pop(L, 1);
- if (ret == 0){
- lua_pushlstring(L, (const char *)value, len);
- return 1;
- }else{
- LLOGE("ble read value error");
- return 0;
- }
- }
- end_error:
- LLOGE("error param");
- return 0;
- }
- /*
- 开关监听
- @api ble.notify_enable(opts, value)
- @table 特征值的描述信息
- @boolean enable 开/关 可选,默认开
- @return boolean 是否成功
- @usage
- -- 写入特征值,填充预设值,被动读取
- ble_device:notify_enable({
- uuid_service = "FA00", -- 服务的UUID, 可以是16位、32位或128位
- uuid_characteristic = "EA01", -- 特征的UUID值, 可以是16位、32位或128位
- }, true) -- 开/关
- */
- static int l_ble_notify_enable(lua_State *L){
- uint16_t ret = 0;
- const char *service_uuid = NULL;
- const char *characteristic_uuid = NULL;
- luat_ble_uuid_t service = {0};
- luat_ble_uuid_t characteristic = {0};
- size_t tmp = 0;
- if (1){
- uint8_t enable = 1;
- if (lua_isboolean(L, 3)) {
- enable = lua_toboolean(L, 3);
- }
- lua_pushstring(L, "uuid_service");
- if (LUA_TSTRING == lua_gettable(L, 2)){
- service_uuid = luaL_checklstring(L, -1, &tmp);
- service.uuid_type = tmp;
- memcpy(service.uuid, service_uuid, service.uuid_type);
- // LLOGD("uuid_service: %02X %02X", service.uuid[0], service.uuid[1]);
- }
- else{
- LLOGW("缺失 uuid_service 参数");
- goto end_error;
- }
- lua_pop(L, 1);
- lua_pushstring(L, "uuid_characteristic");
- if (LUA_TSTRING == lua_gettable(L, 2)){
- characteristic_uuid = luaL_checklstring(L, -1, &tmp);
- characteristic.uuid_type = tmp;
- memcpy(characteristic.uuid, characteristic_uuid, characteristic.uuid_type);
- // LLOGD("uuid_characteristic: %02X %02X", characteristic.uuid[0], characteristic.uuid[1]);
- }
- else{
- LLOGW("缺失 uuid_characteristic 参数");
- goto end_error;
- }
- lua_pop(L, 1);
- ret = luat_ble_notify_enable(&service, &characteristic, enable);
-
- // LLOGD("luat_ble_write_value ret %d", ret);
- lua_pushboolean(L, ret == 0 ? 1 : 0);
- return 1;
- }
- end_error:
- LLOGE("error param");
- return 0;
- }
- /*
- 创建一个BLE扫描
- @api ble.scan_create(addr_mode, scan_interval, scan_window)
- @number addr_mode 广播地址模式, 可选值: ble.PUBLIC, ble.RANDOM, ble.RPA, ble.NRPA
- @number scan_interval 扫描间隔, 单位为0.625ms, 最小值为20, 最大值为10240
- @number scan_window 扫描窗口, 单位为0.625ms, 最小值为20, 最大值为10240
- @return boolean 是否创建成功
- @usage
- -- 创建BLE扫描
- ble_device:scan_create(ble.PUBLIC, 100, 100)
- */
- static int l_ble_scanning_create(lua_State *L){
- if (!lua_isuserdata(L, 1)){
- return 0;
- }
- if (1){
- luat_ble_scan_cfg_t cfg = {
- .addr_mode = LUAT_BLE_ADDR_MODE_PUBLIC,
- .scan_interval = 100,
- .scan_window = 100,
- };
- if (lua_isinteger(L, 2))
- {
- cfg.addr_mode = luaL_checkinteger(L, 2);
- }
- if (lua_isinteger(L, 3))
- {
- cfg.scan_interval = luaL_checkinteger(L, 3);
- }
- if (lua_isinteger(L, 4))
- {
- cfg.scan_window = luaL_checkinteger(L, 4);
- }
- lua_pushboolean(L, luat_ble_create_scanning(NULL, &cfg) ? 0 : 1);
- return 1;
- }
- return 0;
- }
- /*
- 开始BLE扫描
- @api ble.scan_start()
- @return boolean 是否成功
- @usage
- -- 开始BLE扫描
- ble_device:scan_start()
- -- 提醒, 扫描会一直进行, 直到调用ble.scan_stop()停止扫描
- -- 扫描结果会立即执行回调, 同一个设备不会去重, 扫描到数据就会执行回调
- */
- static int l_ble_scanning_start(lua_State *L){
- lua_pushboolean(L, luat_ble_start_scanning(NULL) ? 0 : 1);
- return 1;
- }
- /*
- 停止BLE扫描
- @api ble.scan_stop()
- @return boolean 是否成功
- @usage
- -- 停止BLE扫描
- ble_device:scan_stop()
- -- 提醒, 扫描会一直进行, 直到调用ble.scan_stop()停止扫描
- */
- static int l_ble_scanning_stop(lua_State *L){
- lua_pushboolean(L, luat_ble_stop_scanning(NULL) ? 0 : 1);
- return 1;
- }
- /*
- BLE连接
- @api ble.connect()
- @string mac 地址
- @int 地址类型 ble.PUBLIC ble.RANDOM
- @return boolean 是否成功
- @usage
- -- BLE连接
- ble_device:connect(string.fromHex("C8478C4E027D"),0)
- */
- static int l_ble_connect(lua_State *L){
- size_t len = 0;
- luat_ble_connect_req_t conn = {0};
- uint8_t *adv_addr = luaL_checklstring(L, 2, &len);
- uint8_t adv_addr_type = luaL_checknumber(L, 3);
- if (len != 6){
- LLOGE("error adv_addr len %d", len);
- return 0;
- }
- memcpy(conn.adv_addr, adv_addr, len);
- conn.adv_addr_type = adv_addr_type;
- // LLOGD(" adv_addr_type:%d, adv_addr:%02x:%02x:%02x:%02x:%02x:%02x",
- // adv_addr_type, adv_addr[0], adv_addr[1], adv_addr[2],
- // adv_addr[3], adv_addr[4], adv_addr[5]);
- lua_pushboolean(L, luat_ble_connect(NULL, &conn) ? 0 : 1);
- return 1;
- }
- /*
- BLE断开连接
- @api ble.disconnect()
- @return boolean 是否成功
- @usage
- -- BLE断开连接
- ble_device:disconnect()
- */
- static int l_ble_disconnect(lua_State *L){
- lua_pushboolean(L, luat_ble_disconnect(NULL) ? 0 : 1);
- return 1;
- }
- /*
- 解码广播数据
- @api ble.adv_decode(data)
- @string data 广播数据
- @return table 广播数据的解码结果
- @usage
- -- 解码广播数据
- local data = string.fromHex("1EFF060001092002BE0F0AAD8A6D2E251ED6DFBB3D15249929E10BE138DF7B")
- -- 解析广播数据
- local adv_data = ble_device:adv_decode(data)
- if adv_data then
- for k, v in pairs(adv_data) do
- log.info("ble", "adv data", v.len, v.tp, v.data:toHex())
- end
- end
- */
- static int l_ble_adv_decode(lua_State *L) {
- size_t len = 0;
- const char *data = luaL_checklstring(L, 2, &len);
- if (len == 0) {
- lua_pushnil(L);
- return 1;
- }
- lua_newtable(L);
- uint8_t *p = (uint8_t *)data;
- size_t offset = 0;
- int index = 1;
- while (offset < len) {
- uint8_t length = p[offset++];
- if (length == 0 || offset + length > len) {
- LLOGE("Invalid BLE advertisement data");
- lua_pushnil(L);
- return 1;
- }
- uint8_t type = p[offset++];
- lua_newtable(L);
- lua_pushinteger(L, length - 1); // Length does not include the length byte itself
- lua_setfield(L, -2, "len");
- lua_pushinteger(L, type);
- lua_setfield(L, -2, "tp");
- lua_pushlstring(L, (const char *)&p[offset], length - 1); // Data does not include the length byte
- lua_setfield(L, -2, "data");
- lua_seti(L, -2, index);
- offset += length - 1;
- index ++;
- }
- return 1;
- }
- static int _ble_struct_newindex(lua_State *L);
- void luat_ble_struct_init(lua_State *L){
- luaL_newmetatable(L, LUAT_BLE_TYPE);
- lua_pushcfunction(L, _ble_struct_newindex);
- lua_setfield(L, -2, "__index");
- lua_pop(L, 1);
- }
- #include "rotable2.h"
- static const rotable_Reg_t reg_ble[] = {
- // advertise
- {"adv_create", ROREG_FUNC(l_ble_advertising_create)},
- {"adv_start", ROREG_FUNC(l_ble_advertising_start)},
- {"adv_stop", ROREG_FUNC(l_ble_advertising_stop)},
- {"adv_decode", ROREG_FUNC(l_ble_adv_decode)},
- // gatt
- // slaver
- {"gatt_create", ROREG_FUNC(l_ble_gatt_create)},
- {"write_notify", ROREG_FUNC(l_ble_write_notify)},
- {"write_indicate", ROREG_FUNC(l_ble_write_indicate)},
- {"write_value", ROREG_FUNC(l_ble_write_value)},
- {"read_value", ROREG_FUNC(l_ble_read_value)},
- {"notify_enable", ROREG_FUNC(l_ble_notify_enable)},
- // scanning
- {"scan_create", ROREG_FUNC(l_ble_scanning_create)},
- {"scan_start", ROREG_FUNC(l_ble_scanning_start)},
- {"scan_stop", ROREG_FUNC(l_ble_scanning_stop)},
- {"connect", ROREG_FUNC(l_ble_connect)},
- {"disconnect", ROREG_FUNC(l_ble_disconnect)},
- // 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_SCAN_REPORT", ROREG_INT(LUAT_BLE_EVENT_SCAN_REPORT)},
- {"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)},
- {"EVENT_READ_VALUE", ROREG_INT(LUAT_BLE_EVENT_READ_VALUE)},
- {"EVENT_GATT_DONE", ROREG_INT(LUAT_BLE_EVENT_GATT_DONE)},
- {"EVENT_GATT_ITEM", ROREG_INT(LUAT_BLE_EVENT_GATT_ITEM)},
-
- // ADV_ADDR_MODE
- //@const PUBLIC 控制器的公共地址
- {"PUBLIC", ROREG_INT(LUAT_BLE_ADDR_MODE_PUBLIC)},
- //@const RANDOM 生成的静态地址
- {"RANDOM", ROREG_INT(LUAT_BLE_ADDR_MODE_RANDOM)},
- {"RPA", ROREG_INT(LUAT_BLE_ADDR_MODE_RPA)},
- {"NRPA", ROREG_INT(LUAT_BLE_ADDR_MODE_NRPA)},
- // ADV_CHNL
- //@const CHNL_37 37通道
- {"CHNL_37", ROREG_INT(LUAT_BLE_ADV_CHNL_37)},
- //@const CHNL_38 38通道
- {"CHNL_38", ROREG_INT(LUAT_BLE_ADV_CHNL_38)},
- //@const CHNL_39 39通道
- {"CHNL_39", ROREG_INT(LUAT_BLE_ADV_CHNL_39)},
- //@const CHNLS_ALL 所有通道(37 38 39)
- {"CHNLS_ALL", ROREG_INT(LUAT_BLE_ADV_CHNLS_ALL)},
- // Permission
- //@const READ 读权限
- {"READ", ROREG_INT(LUAT_BLE_GATT_PERM_READ)},
- //@const WRITE 写权限
- {"WRITE", ROREG_INT(LUAT_BLE_GATT_PERM_WRITE)},
- //@const IND 指示权限
- {"IND", ROREG_INT(LUAT_BLE_GATT_PERM_IND)},
- //@const NOTIFY 通知权限
- {"NOTIFY", ROREG_INT(LUAT_BLE_GATT_PERM_NOTIFY)},
- //@const WRITE_CMD 写权限(无需确认)
- {"WRITE_CMD", ROREG_INT(LUAT_BLE_GATT_PERM_WRITE_CMD)},
- // 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)},
- // adv type
- {"ADV_TYPE_LEGACY", ROREG_INT(LUAT_BLE_ADV_TYPE_LEGACY)},
- {"ADV_TYPE_EXTENDED", ROREG_INT(LUAT_BLE_ADV_TYPE_EXTENDED)},
- {"ADV_TYPE_SCAN_RESPONSE", ROREG_INT(LUAT_BLE_ADV_PERIODIC)},
- // adv prop
- {"ADV_PROP_CONNECTABLE", ROREG_INT(LUAT_BLE_ADV_PROP_CONNECTABLE)},
- {"ADV_PROP_SCANNABLE", ROREG_INT(LUAT_BLE_ADV_PROP_SCANNABLE)},
- {"ADV_PROP_DIRECTED", ROREG_INT(LUAT_BLE_ADV_PROP_DIRECTED)},
- {"ADV_PROP_HDC", ROREG_INT(LUAT_BLE_ADV_PROP_HDC)},
- {"ADV_PROP_ANONYMOUS", ROREG_INT(LUAT_BLE_ADV_PROP_ANONYMOUS)},
- {"ADV_PROP_LEGACY", ROREG_INT(LUAT_BLE_ADV_PROP_LEGACY)},
- {"ADV_PROP_TX_PWR", ROREG_INT(LUAT_BLE_ADV_PROP_TX_PWR)},
- {NULL, ROREG_INT(0)}};
- static int _ble_struct_newindex(lua_State *L){
- const rotable_Reg_t *reg = reg_ble;
- 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_ble(lua_State *L){
- rotable2_newlib(L, reg_ble);
- luat_ble_struct_init(L);
- return 1;
- }
|