/* * Copyright (C) 2016 Spreadtrum Communications Inc. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include #include #include #include #include "include/hci.h" #include "include/debug.h" #include "include/sdio.h" #include "include/sitm.h" #include "include/tty.h" extern int bluetooth_set_power(void* data, bool blocked); // #define assert(x) do{pr_err()} extern struct bt_data_interface_t* bt_data_interface; unsigned char own_public_addr[BD_ADDR_LEN]; unsigned char own_addr[BD_ADDR_LEN]; unsigned char dis_flag = 0; // dis_even_flag,不同场景下disconnect 标志 extern struct mtty_device* mtty_dev; extern int closeflag; struct woble_dev_t { unsigned char in_use; unsigned char type; unsigned short handler; unsigned char bd_addr[BD_ADDR_LEN]; }; static struct woble_dev_t woble_devices[WOBLE_DEVICES_SIZE]; static struct hci_cmd_t hci_cmd; static int recv_kernel_event(const unsigned char* buf, int length, int pack_enum) { unsigned short opcode = 0; unsigned char status = 0; const unsigned char* p = 0; int ret = -1; BT_DEBUG("%s +++\n", __func__); switch (pack_enum) { default: case BT_HCI_EVT_CMD_COMPLETE: p = buf + 4; STREAM_TO_UINT16(opcode, p); STREAM_TO_UINT8(status, p); break; case BT_HCI_EVT_CMD_STATUS: p = buf + 5; STREAM_TO_UINT16(opcode, p); status = buf[3]; break; } BT_DEBUG("%s opcode: 0x%04X, status: %d\n", __func__, opcode, status); if (hci_cmd.opcode == opcode) { if (0x0406 == opcode) { dis_flag = 0x64; } BT_DEBUG("%s hci_cmd.opcode %04X match, need up sem\n", __func__, opcode); up(&hci_cmd.wait); ret = 0; if (hci_cmd.opcode == BT_HCI_OP_SET_STARTSLEEP && closeflag == 1) { if (mtty_dev != NULL) { atomic_set(&mtty_dev->state, MTTY_STATE_CLOSE); sitm_cleanup(); pr_info("mtty_close device success _test!\n"); // stop_marlin(MARLIN_BLUETOOTH); bluetooth_set_power(0, 1); } else { pr_err("mtty open input tty is NULL!\n"); } closeflag = 0; } } if (opcode == 0x1009) { STREAM_TO_ARRAY(own_public_addr, p, BD_ADDR_LEN); pr_err("%s address %02x:%02x:%02x:%02x:%02x:%02x\n", __func__, own_public_addr[5], own_public_addr[4], own_public_addr[3], own_public_addr[2], own_public_addr[1], own_public_addr[0]); } BT_DEBUG("%s --- ret %d\n", __func__, ret); return ret; } #define LE_Enhanced_Connection_Complete 0x0a #define Connection_Complete 0x01 extern unsigned char resume_rxmsg[7]; extern int i; int num = 9; unsigned char red_bt_flag=0x11; //区分蓝牙,红外待机标志;0x11:红外 0x22: bt // extern int event_nu; // unsigned char dis_buf[7]={0x04,0x05,0x04,0,0x10,0x0,0x13}; //; int resume_transfer_upper(const unsigned char* buf, int count); int rx_data_recv(const unsigned char* buf, int count, int (*upper_cb)(const unsigned char* buf, int count)) { const unsigned char* rxmsg = buf; int left_length = count; int pack_length = 0; int last = 0; const unsigned char* test_buf = NULL; // add unsigned char sub_code = 0; // unsigned char res = 0; // unsigned char dis_res[2]={0,0}; if (count <= 0) { pr_err("%s count <0 !!!!!", __func__); } do { rxmsg = buf + (count - left_length); // pr_err("recv %d", left_length); // hex_dump_block(rxmsg, left_length); switch (rxmsg[PACKET_TYPE]) { case HCI_EVT: if (left_length < 3) { pr_err("%s left_length <3 !!!!!", __func__); } pack_length = rxmsg[EVT_HEADER_SIZE]; pack_length += 3; if (left_length - pack_length < 0) { pr_err("%s left_length - pack_length <0 !!!!!", __func__); } switch (rxmsg[EVT_HEADER_EVENT]) { case BT_HCI_EVT_CMD_COMPLETE: case BT_HCI_EVT_CMD_STATUS: if (recv_kernel_event(rxmsg, pack_length, rxmsg[EVT_HEADER_EVENT])) { if ( rxmsg[1] == BT_HCI_EVT_CMD_STATUS && rxmsg[5]==0x06 && rxmsg[6]==0x04 ) dis_flag = 0; upper_cb(rxmsg, pack_length); } break; case 0x05: // res = *(rxmsg+6); if ((dis_flag == 0x64) && (*(rxmsg + 4) == resume_rxmsg[4]) && (*(rxmsg + 5) == resume_rxmsg[5])) { dis_flag = 0; // upper_cb(rxmsg, pack_length); // pr_err("first_disconnect\n"); } else if( (*(rxmsg + 4) == resume_rxmsg[4]) && (*(rxmsg + 5) == resume_rxmsg[5]) ) { //应用层断遥控器, // pr_err("second_disconnect\n"); red_bt_flag = 0x11; //red upper_cb(rxmsg, pack_length); } else //其他设备断 { upper_cb(rxmsg, pack_length); } break; case 0x3e: test_buf = rxmsg + 3; STREAM_TO_UINT8(sub_code, test_buf); if (Connection_Complete == sub_code || LE_Enhanced_Connection_Complete == sub_code) { resume_rxmsg[4] = *(rxmsg + 5); resume_rxmsg[5] = *(rxmsg + 6); if ( *(rxmsg+4) == 0x00 ) //status { red_bt_flag = 0x22; //bluetooth } else red_bt_flag = 0x11; //red //cancel pair upload } default: upper_cb(rxmsg, pack_length); break; } last = left_length; left_length -= pack_length; break; case HCI_ACL: if (left_length < 5) { pr_err("%s left_length <5 !!!!!", __func__); } pack_length = rxmsg[ACL_HEADER_SIZE_HB]; pack_length <<= 8; pack_length |= rxmsg[ACL_HEADER_SIZE_LB]; pack_length += 5; if (left_length - pack_length < 0) { pr_err("%s left_length - pack_length <0 !!!!!", __func__); } upper_cb(rxmsg, pack_length); last = left_length; left_length -= pack_length; break; default: pr_err("%s unknow package left_length %d last %d data %x %x %x %x!!!!!\n", __func__, left_length, last, rxmsg[0], rxmsg[1], rxmsg[2], rxmsg[3]); if (0) { char dump[512] = { 0 }; char hexx[4] = { 0 }; int tmpi = 0; for (tmpi = 0; tmpi < left_length; tmpi++) { memset(hexx, 0, sizeof(hexx)); sprintf(hexx, "%02x ", rxmsg[tmpi]); strcat(dump, hexx); } pr_err("unknow package detail %s!!!\n", dump); mdbg_assert_interface("detect dirty data!!!!\n"); } left_length = 0; break; } // pr_info("%s left: %d\n",__func__ , left_length); } while (left_length); return count; } int hci_cmd_send_sync(unsigned short opcode, struct HC_BT_HDR* py, struct HC_BT_HDR* rsp) { unsigned char msg_req[HCI_CMD_MAX_LEN + BYTE_ALIGNMENT] = { 0 }, *p; pr_info("%s max_len=%d+++\n", __func__, HCI_CMD_MAX_LEN); p = msg_req; UINT8_TO_STREAM(p, HCI_CMD); UINT16_TO_STREAM(p, opcode); if (py == NULL) { UINT8_TO_STREAM(p, 0); } else { UINT8_TO_STREAM(p, py->len); ARRAY_TO_STREAM(p, py->data, py->len); } hci_cmd.opcode = opcode; bt_data_interface->write(msg_req, p - msg_req + BYTE_ALIGNMENT - ((p - msg_req) % BYTE_ALIGNMENT)); down(&hci_cmd.wait); hci_cmd.opcode = 0; pr_info("%s ---\n", __func__); return 0; } int del_woble_devices(unsigned char type, unsigned char* bd_addr) { int i; for (i = 0; i < WOBLE_DEVICES_SIZE; ++i) { if (woble_devices[i].in_use && !memcmp(bd_addr, woble_devices[i].bd_addr, BD_ADDR_LEN) && woble_devices[i].type == type) { memset(woble_devices + i, 0, sizeof(woble_devices[i])); } } return 0; } int update_woble_devices(unsigned char type, unsigned short handler, unsigned char* bd_addr) { int i; for (i = 0; i < WOBLE_DEVICES_SIZE; ++i) { if (woble_devices[i].in_use && !memcmp(bd_addr, woble_devices[i].bd_addr, BD_ADDR_LEN) && woble_devices[i].type == type) { woble_devices[i].in_use = 1; woble_devices[i].type = type; woble_devices[i].handler = handler; STREAM_TO_ARRAY(woble_devices[i].bd_addr, bd_addr, BD_ADDR_LEN); pr_info("%s set type: %d, handler 0x%X address: %02x:%02x:%02x:%02x:%02x:%02x\n", __func__, woble_devices[i].type, woble_devices[i].handler, woble_devices[i].bd_addr[0], woble_devices[i].bd_addr[1], woble_devices[i].bd_addr[2], woble_devices[i].bd_addr[3], woble_devices[i].bd_addr[4], woble_devices[i].bd_addr[5]); break; } } if (i < WOBLE_DEVICES_SIZE) { return 0; } for (i = 0; i < WOBLE_DEVICES_SIZE; i++) { if (woble_devices[i].in_use) { continue; } else { woble_devices[i].in_use = 1; woble_devices[i].type = type; woble_devices[i].handler = handler; STREAM_TO_ARRAY(woble_devices[i].bd_addr, bd_addr, BD_ADDR_LEN); pr_info("%s set type: %d, handler 0x%X address: %02x:%02x:%02x:%02x:%02x:%02x\n", __func__, woble_devices[i].type, woble_devices[i].handler, woble_devices[i].bd_addr[0], woble_devices[i].bd_addr[1], woble_devices[i].bd_addr[2], woble_devices[i].bd_addr[3], woble_devices[i].bd_addr[4], woble_devices[i].bd_addr[5]); } break; } if (i == WOBLE_DEVICES_SIZE) { pr_err("%s err, woble is full\n", __func__); return -1; } return 0; } void dump_woble_devices(void) { int i; for (i = 0; i < WOBLE_DEVICES_SIZE; i++) { if (woble_devices[i].in_use) { pr_info("%s type: %d, handler 0x%x address: %02x:%02x:%02x:%02x:%02x:%02x\n", __func__, woble_devices[i].type, woble_devices[i].handler, woble_devices[i].bd_addr[0], woble_devices[i].bd_addr[1], woble_devices[i].bd_addr[2], woble_devices[i].bd_addr[3], woble_devices[i].bd_addr[4], woble_devices[i].bd_addr[5]); } } pr_info("%s own address: %02x:%02x:%02x:%02x:%02x:%02x\n", __func__, own_addr[0], own_addr[1], own_addr[2], own_addr[3], own_addr[4], own_addr[5]); } int clear_woble_devices(void) { memset(&woble_devices, 0, sizeof(woble_devices)); return 0; } int set_random_address(unsigned char* bd_addr) { STREAM_TO_ARRAY(own_addr, bd_addr, BD_ADDR_LEN); return 0; } int hci_init(void) { memset(&hci_cmd, 0, sizeof(struct hci_cmd_t)); clear_woble_devices(); sema_init(&hci_cmd.wait, 0); return 0; } int hci_destory(void) { // sema_destroy(&hci_cmd.wait); memset(&hci_cmd, 0, sizeof(struct hci_cmd_t)); return 0; } void hci_woble_enable(void) { struct HC_BT_HDR* payload = (struct HC_BT_HDR*)vmalloc(sizeof(struct HC_BT_HDR) + 3); unsigned char *p, *dp = 0; int i; struct HC_BT_HDR* disc_payload = (struct HC_BT_HDR*)vmalloc(sizeof(struct HC_BT_HDR) + 3); payload->len = 3; payload->data[0] = 0; payload->data[1] = 0; payload->data[2] = 1; hci_cmd_send_sync(BT_HCI_OP_ENABLE, payload, NULL); vfree(payload); hci_cmd_send_sync(BT_HCI_OP_RESET, NULL, NULL); payload = (struct HC_BT_HDR*)vmalloc(sizeof(struct HC_BT_HDR) + 100); p = payload->data; BDADDR_TO_STREAM(p, own_addr); UINT8_TO_STREAM(p, 0); for (i = 0; i < WOBLE_DEVICES_SIZE; i++) { if (woble_devices[i].in_use) { if (woble_devices[i].handler && woble_devices[i].handler != 0xffff) { disc_payload->len = 3; dp = disc_payload->data; UINT16_TO_STREAM(dp, woble_devices[i].handler); UINT8_TO_STREAM(dp, 0x13); hci_cmd_send_sync(0x0406, disc_payload, 0); } UINT8_TO_STREAM(p, woble_devices[i].type); BDADDR_TO_STREAM(p, woble_devices[i].bd_addr); payload->data[BD_ADDR_LEN]++; pr_info("%s type: %d, address: %02x:%02x:%02x:%02x:%02x:%02x\n", __func__, woble_devices[i].type, woble_devices[i].bd_addr[0], woble_devices[i].bd_addr[1], woble_devices[i].bd_addr[2], woble_devices[i].bd_addr[3], woble_devices[i].bd_addr[4], woble_devices[i].bd_addr[5]); } } payload->len = p - payload->data; hex_dump_block(payload->data, payload->len); hci_cmd_send_sync(BT_HCI_OP_WOBLE, payload, NULL); vfree(payload); vfree(disc_payload); } void hci_cleanup(void) { } const woble_config_t s_woble_config_cust = { WOBLE_MOD_ENABLE, WOBLE_SLEEP_MOD_COULD_NOT_KNOW, 0, WOBLE_SLEEP_MOD_NOT_NEED_NOTITY }; void hci_set_ap_sleep_mode(int is_shutdown, int is_resume) { struct HC_BT_HDR* payload = (struct HC_BT_HDR*)vmalloc(sizeof(struct HC_BT_HDR) + 5); // 6 unsigned char* p; p = payload->data; pr_err("%s start\n", __func__); payload->len = 5; //6 if (is_resume) { UINT8_TO_STREAM(p, WOBLE_MOD_DISABLE); } else { UINT8_TO_STREAM(p, WOBLE_MOD_ENABLE); } UINT8_TO_STREAM(p, 0); UINT16_TO_STREAM(p, s_woble_config_cust.timeout); UINT8_TO_STREAM(p, s_woble_config_cust.notify); // UINT8_TO_STREAM(p, 0); hex_dump_block(payload->data, payload->len); hci_cmd_send_sync(BT_HCI_OP_SET_SLEEPMODE, payload, NULL); vfree(payload); pr_err("%s end\n", __func__); return; } #define BT_HCI_OP_DISCONNECT 0x0406 void hci_disconnect(void) { struct HC_BT_HDR* payload = (struct HC_BT_HDR*)vmalloc(sizeof(struct HC_BT_HDR) + 3); unsigned char* p; p = payload->data; pr_err("%s start\n", __func__); payload->len = 3; UINT8_TO_STREAM(p, resume_rxmsg[4]); UINT8_TO_STREAM(p, resume_rxmsg[5]); UINT8_TO_STREAM(p, 0x13); // 0x13 hex_dump_block(payload->data, payload->len); hci_cmd_send_sync(BT_HCI_OP_DISCONNECT, payload, NULL); vfree(payload); pr_err("mmsg[4]=%d\n", resume_rxmsg[4]); pr_err("mmsg[5]=%d\n", resume_rxmsg[5]); pr_err("%s end\n", __func__); return; } void hci_set_scan_parameters(void) { struct HC_BT_HDR* payload = (struct HC_BT_HDR*)vmalloc(sizeof(struct HC_BT_HDR) + 8); unsigned char* p; p = payload->data; pr_err("%s start\n", __func__); payload->len = 8; UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x01); UINT8_TO_STREAM(p, 0x01); UINT8_TO_STREAM(p, 0x40); UINT8_TO_STREAM(p, 0x06); // 1000ms UINT8_TO_STREAM(p, 0x20); UINT8_TO_STREAM(p, 0x02);//340ms hex_dump_block(payload->data, payload->len); hci_cmd_send_sync(BT_HCI_OP_LE_SET_EX_SCAN_PARAMETERS, payload, NULL); vfree(payload); pr_err("%s end\n", __func__); return; } void hci_set_scan_enable(int enable) { struct HC_BT_HDR* payload = (struct HC_BT_HDR*)vmalloc(sizeof(struct HC_BT_HDR) + 6); unsigned char* p; p = payload->data; pr_err("%s start\n", __func__); payload->len = 6; UINT8_TO_STREAM(p, enable); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x00); hex_dump_block(payload->data, payload->len); hci_cmd_send_sync(BT_HCI_OP_LE_SET_EX_SCAN_ENABLE, payload, NULL); vfree(payload); pr_err("%s end\n", __func__); return; } void hci_cleanup_wakeup_list(void) { pr_err("%s start\n", __func__); hci_cmd_send_sync(BT_HCI_OP_CLEANUP_WAKEUPLIST, NULL, NULL); pr_err("%s end\n", __func__); return; } void hci_add_device_to_wakeup_list(void) { struct HC_BT_HDR* payload = NULL; unsigned char* p; unsigned char adv_type = 0xff; unsigned char address[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; pr_err("%s start %s\n", __func__, WOBLE_TYPE); if (!strcmp(WOBLE_TYPE, "public")) { payload = (struct HC_BT_HDR*)vmalloc(sizeof(struct HC_BT_HDR) + 16); p = payload->data; payload->len = 16; UINT8_TO_STREAM(p, ADV_ADDRESS_FROM_WHITTLIST); ARRAY_TO_STREAM(p, address, 6); UINT16_TO_STREAM(p, 0x08); UINT8_TO_STREAM(p, 0x01); UINT8_TO_STREAM(p, 0x05); UINT8_TO_STREAM(p, 0x16); UINT8_TO_STREAM(p, UNISOC_WOBLE_UUID & 0xff); UINT8_TO_STREAM(p, (UNISOC_WOBLE_UUID >> 8) & 0xff); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x01); } else if (!strcmp(WOBLE_TYPE, "demo")) { payload = (struct HC_BT_HDR*)vmalloc(sizeof(struct HC_BT_HDR) + 49); p = payload->data; payload->len = 49; UINT8_TO_STREAM(p, ADV_ADDRESS_FROM_WHITTLIST); ARRAY_TO_STREAM(p, address, 6); UINT16_TO_STREAM(p, SUB_ADV_DATA_FILTER); UINT8_TO_STREAM(p, 0); // modify 0 UINT8_TO_STREAM(p, 0x03); UINT8_TO_STREAM(p, 0x01); UINT8_TO_STREAM(p, adv_type); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x04); UINT8_TO_STREAM(p, 0x13); // manufacturer Data UINT8_TO_STREAM(p, 0xff); UINT8_TO_STREAM(p, 0x46); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x01); UINT8_TO_STREAM(p, adv_type); UINT8_TO_STREAM(p, 0x05); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x06); ARRAY_TO_STREAM(p, own_public_addr, 6); UINT8_TO_STREAM(p, 0x01); UINT8_TO_STREAM(p, adv_type); UINT8_TO_STREAM(p, 0x0f); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x05); UINT8_TO_STREAM(p, 0x43); UINT8_TO_STREAM(p, 0x52); UINT8_TO_STREAM(p, 0x4B); UINT8_TO_STREAM(p, 0x54); UINT8_TO_STREAM(p, 0x4D); UINT16_TO_STREAM(p, 0x00C8); // time } hex_dump_block(payload->data, payload->len); hci_cmd_send_sync(BT_HCI_OP_ADD_WAKEUPLIST, payload, NULL); vfree(payload); pr_err("%s end\n", __func__); return; } /************************add************************/ void hci_add_device_to_wakeup_list_rtk(void) { struct HC_BT_HDR* payload = NULL; unsigned char* p; unsigned char adv_type = 0xff; unsigned char address[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; pr_err("%s start %s\n", __func__, WOBLE_TYPE); if (!strcmp(WOBLE_TYPE, "public")) { payload = (struct HC_BT_HDR*)vmalloc(sizeof(struct HC_BT_HDR) + 16); p = payload->data; payload->len = 16; UINT8_TO_STREAM(p, ADV_ADDRESS_FROM_WHITTLIST); ARRAY_TO_STREAM(p, address, 6); UINT16_TO_STREAM(p, 0x08); UINT8_TO_STREAM(p, 0x01); UINT8_TO_STREAM(p, 0x05); UINT8_TO_STREAM(p, 0x16); UINT8_TO_STREAM(p, UNISOC_WOBLE_UUID & 0xff); UINT8_TO_STREAM(p, (UNISOC_WOBLE_UUID >> 8) & 0xff); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x01); } else if (!strcmp(WOBLE_TYPE, "demo")) { payload = (struct HC_BT_HDR*)vmalloc(sizeof(struct HC_BT_HDR) + 40); p = payload->data; payload->len = 40; UINT8_TO_STREAM(p, ADV_ADDRESS_FROM_WHITTLIST); ARRAY_TO_STREAM(p, address, 6); /* If bit2 or bit3 of Wakeu_mode is not set, there are no Adv_filter_option, Adv_filter_length Adv_filter_data, Acl_filter_option, ACL_Filter_data_length, and ACL_Filter_data fields */ UINT16_TO_STREAM(p, SUB_ADV_DATA_FILTER); UINT8_TO_STREAM(p, 0); UINT8_TO_STREAM(p, 0x02); // Sub_Adv_Filter_count :总共3包数据 #if 0 UINT8_TO_STREAM(p, 0x01); // Filter_base UINT8_TO_STREAM(p, adv_type); // Adv_type UINT8_TO_STREAM(p, 0x00); // index,从第0个字节继续封唤醒包 UINT8_TO_STREAM(p, 0x00); // 3bit reserved UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x04); // Sub_Adv_Filter_data_length //Appearance UINT8_TO_STREAM(p, 0x03); UINT8_TO_STREAM(p, 0x19); UINT8_TO_STREAM(p, 0xC1); UINT8_TO_STREAM(p, 0x03); #endif UINT8_TO_STREAM(p, 0x01); // Filter_base UINT8_TO_STREAM(p, adv_type); // Adv_type UINT8_TO_STREAM(p, 0x00); // index UINT8_TO_STREAM(p, 0x00); // 3bit reserved UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x07); // Sub_Adv_Filter_data_length UINT8_TO_STREAM(p, 0x0D); // Adv_Filter_data_length:length UINT8_TO_STREAM(p, 0xFF); // Adv_Service_Type:Manufacturer Specific UINT8_TO_STREAM(p, 0x5D); // Manufacturer ID: MediaTek, Inc. //低字节 UINT8_TO_STREAM(p, 0x00); // Manufacturer ID: MediaTek, Inc. //高字节 UINT8_TO_STREAM(p, 0x03); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x01); UINT8_TO_STREAM(p, 0x01); // 第2包数据 UINT8_TO_STREAM(p, adv_type); UINT8_TO_STREAM(p, 0x08); // index UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x00); UINT8_TO_STREAM(p, 0x06); // Sub_Adv_Filter_data_length ARRAY_TO_STREAM(p, own_public_addr, 6); // 本机mac地址:38 ca 73 26 39 04 UINT16_TO_STREAM(p, 0x00C8); // time( 2 octets) } hex_dump_block(payload->data, payload->len); hci_cmd_send_sync(BT_HCI_OP_ADD_WAKEUPLIST, payload, NULL); vfree(payload); pr_err("%s end\n", __func__); return; } /************************/ void hci_set_ap_start_sleep(void) { pr_err("%s start\n", __func__); hci_cmd_send_sync(BT_HCI_OP_SET_STARTSLEEP, NULL, NULL); pr_err("%s end\n", __func__); return; }