使用GAPM_LIST_SET_CMD-GAPM_SET_WL设置白名单的经历

本文记录了蓝牙设备配置白名单过程中遇到的问题及解决方法。包括误用数据结构、使用可变长度消息、调整广播过滤政策及发现广播未正常启动等问题,并最终成功实现仅允许白名单设备连接。

1、误以为需要将包含mac地址gapm_list_set_wl_cmd结构体数据直接传到gapm_set_operation_ptr(GAPM_OP_CFG,wl)函数中,实际上在GAPM_LIST_SET_CMD对应的handler中,会自动处理该操作。
2、新增可变长度消息,KE_MSG_ALLOC_DYN
3、在gapm_list_send_hci_le_add_dev_to_wlst_cmd已经可以看到正确设置的mac地址了,但实际上任然有问题,发现手机依旧可以扫描连接
4、发现需要更改广播的过滤政策ADV_FILTER_POL,改成了ADV_ALLOW_SCAN_ANY_CON_WLST,发现不能扫描到了,更不能被连上。
5、通过修改ADV_FILTER_POL与否,发现是只需要修改这个参数就会出错。原来是广播根本没建立。在gapm_adv_create->gapm_adv_check_param中发现改了上述参数,还需要更改ADV_DISC_MODE为GAPM_ADV_MODE_NON_DISC
6、更新ADV_DISC_MODE后发现程序无法走到gapm_list_send_hci_le_add_dev_to_wlst_cmd中,在hci_le_cmd_cmp_evt_list_handler函数中发现status有误。发现是hci_le_clear_wlst_cmd_handler->llm_is_wl_accessible函数中有问题。在发现llm_env.act_info[act_id].state为LLM_ADV_EN后,判断广播政策非ADV_ALLOW_SCAN_ANY_CON_ANY,于是报错。于是我修改程序,将程序先广播后暂停,再新添白名单,再重启广播。终于白名单设备可以连接上该丛机了。

#include <stdlib.h> #include <string.h> #include <unistd.h> #include "tss.h" #include "certificate.h" #include "tss_cloud.h" #include "tss_loop.h" #include "tss_ubus.h" #define TSSC_SCAN_DETECTION_INTERVAL 10000 #define TSSC_JOINING_DETECTION_INTERVAL 10000 #define TSSC_JOINING_TIMEOUT 180 #define TSSC_SCANING_TIMEOUT 30 #define TSSC_FULL_SCAN_INTERVAL_MIN 10 /* 10s */ #define TSSC_FULL_SCAN_INTERVAL_MAX 120 /* 120s */ #define TSSC_FULL_SCAN_REMAIN_TIME 3 /* 有ER回复,仍执行几次全信道扫描 */ #define TSSC_SCAN_TIMEOUT (30 * 60) /* 30min */ static struct tssc_context *tssc_ctx = NULL; static struct tss_loop_fd *inotify_fd = NULL; static struct tss_loop_timer *scan_timer = NULL; static struct tss_loop_timer *tssc_joining_timer = NULL; static void tssc_set_state(enum provisionee_connect_state state) { time_t now = tss_get_timestamp(); if (!tssc_ctx) { return; } tssc_ctx->state = state; if (state == SCANNING) tssc_ctx->scaning_time = now; else if (state == CONNECTING) { tssc_ctx->joining_time = now; tss_add_loop_timer(tssc_joining_timer, TSSC_JOINING_DETECTION_INTERVAL); } return; } static uint8_t *tssc_build_tss_req_payload(struct provisionee *ee, uint8_t *target_bssid, uint16_t *payload_len) { struct tss_context *tss_ctx = tss_ctx_get(); struct tss_request req = {{0}}; uint8_t *req_data = NULL; if (!tss_ctx) return NULL; memcpy(req.addr, ee->addr, ETH_ADDR_LEN); if (target_bssid) memcpy(req.target_bssid, target_bssid, ETH_ADDR_LEN); req.sysmode = ee->sysmode; memcpy(&req.cap, &ee->cap, sizeof(struct tss_capability)); req.inter_ca = tss_ctx->inter_ca; req.inter_ca_len = tss_ctx->inter_ca_len; req.end_ca = tss_ctx->end_ca; req.end_ca_len = tss_ctx->end_ca_len; tss_get_group_id(req.gid); if (SYSTEM_MODE_SUPPORT_AP(ee->sysmode)) req.dev_crypto = tss_get_device_crypto(&req.dev_crypto_len, tss_ctx->ecc_private_key, tss_ctx->ecc_private_key_len); tss_get_model_name(req.dev_model); tss_get_device_type(req.dev_type); tss_get_hardware_ver(req.dev_hw_ver); tss_get_country(req.dev_country); req_data = build_tss_req_data(&req, payload_len); if (req.dev_crypto) free(req.dev_crypto); return req_data; } static TSS_STATUS tssc_send_tss_resp_ack(int sd, uint8_t *da, uint8_t *sa, uint16_t freq) { TSS_STATUS ret = TSS_NOK; uint8_t freq_option[6] = {TLCP_FREQ, 0x2, 0x0, 0x0, TLCP_END_CODE, 0x0}; uint8_t headroom = TSS_FRAME_HEADROOM + 6; struct tssp_info tssp_info = {0}; struct tss_frame_buff *tfb = NULL; tss_print("Reply tss response ack on chan %d", frequency_to_channel(freq)); tfb = tss_frame_alloc(headroom, headroom); if (!tfb){ tss_print("Alloc tss frame buff failed!"); return ret; } tssp_info.type = TSSP_RESP_ACK; memcpy(&freq_option[2], &freq, 2); ret = tss_send(sd, tfb, TLCP_PROTO_TSSP, &tssp_info, da, sa, freq_option, 6, 0xff); tss_frame_free(tfb); return ret; } static TSS_STATUS tssc_send_tss_req(int sd, uint8_t *payload, uint16_t payload_len, uint8_t *da, uint8_t *sa, uint16_t freq) { TSS_STATUS ret = TSS_NOK; uint8_t freq_option[6] = {TLCP_FREQ, 0x2, 0x0, 0x0, TLCP_END_CODE, 0x0}; uint8_t headroom = TSS_FRAME_HEADROOM + 6; struct tssp_info tssp_info = {0}; struct tss_frame_buff *tfb = NULL; if (!payload || freq == 0) return ret; tss_print("Send tss req on chan %d", frequency_to_channel(freq)); tssp_info.type = TSSP_REQ; tssp_info.is_bcast = 1; tfb = tss_frame_alloc(payload_len + headroom, headroom); if (!tfb){ tss_print("Alloc tss frame buff failed!"); return ret; } memcpy(tfb->data, payload, payload_len); memcpy(&freq_option[2], &freq, 2); ret = tss_send(sd, tfb, TLCP_PROTO_TSSP, &tssp_info, da, sa, freq_option, 6, 0); tss_frame_free(tfb); return ret; } static void tssc_fill_scan_list(uint16_t freq) { int i; uint16_t *list = NULL; enum tss_wifi_band band; if (!tssc_ctx) { return; } band = frequency_to_band(freq); if (band >= BAND_MAX) return; list = tssc_ctx->partial_scan_list[band]; for (i = 0; i < MAX_CHANNEL_NUM; i++) { if (list[i] == 0 || list[i] == freq) break; } if (i < MAX_CHANNEL_NUM) list[i] = freq; return; } static void tssc_scan_handler(struct tss_loop_timer *timer) { struct tss_context *tss_ctx = tss_ctx_get(); TSS_BOOL full_scan = TSS_TRUE; #ifdef TSS_SUPPORT_REACCESS TSS_BOOL reaccess = TSS_FALSE; #endif uint8_t *tss_req_payload = NULL; uint16_t tss_req_payload_len; time_t now = tss_get_timestamp(); int i, j; if (!tssc_ctx) { return; } if (tssc_ctx->scan_time + TSSC_SCAN_TIMEOUT < now) return; /* Only certificate are present and not being updated can execute scan process */ if (!tss_ctx || !tss_ctx->inter_ca || !tss_ctx->end_ca) goto out; #ifdef TP_BLE if (tss_ctx->stop_tss_scan == 1) { tss_print("stop tss scan"); goto out; } #endif /* Only IDLE and SCANNING timeout can execute scan process */ if (!(tssc_ctx->state == IDLE || (tssc_ctx->state == SCANNING && tssc_ctx->scaning_time + TSSC_SCANING_TIMEOUT < now))) goto out; for (i = BAND_2G; i < BAND_MAX; i++) { /* Check scan type, full or partial */ if (tssc_ctx->partial_scan_list[i][0]) full_scan = TSS_FALSE; #ifdef TSS_SUPPORT_REACCESS /* Check if reaccess */ if (memcmp(tss_ctx->connected_bssid[i], zero_addr, ETH_ADDR_LEN)) reaccess = TSS_TRUE; #endif } if (full_scan) { /* The time for the next full scan was not reached */ if (tssc_ctx->full_scan_time + tssc_ctx->full_scan_interval > now) goto out; } else { tssc_ctx->full_scan_interval = TSSC_FULL_SCAN_INTERVAL_MIN; if (tssc_ctx->full_scan_remain_time < TSSC_FULL_SCAN_REMAIN_TIME) tssc_ctx->full_scan_remain_time++; /* A full scan is performed after successive partial scans occur */ if (tssc_ctx->full_scan_time + TSSC_FULL_SCAN_INTERVAL_MAX < now) full_scan = TSS_TRUE; } tss_print("Process tss scan"); tssc_set_state(SCANNING); if (full_scan) { tssc_ctx->full_scan_time = now; tssc_ctx->full_scan_interval *= 2; if (tssc_ctx->full_scan_interval > TSSC_FULL_SCAN_INTERVAL_MAX) tssc_ctx->full_scan_interval = TSSC_FULL_SCAN_INTERVAL_MAX; } for (i = BAND_2G; i < BAND_MAX; i++) { #ifdef TSS_SUPPORT_REACCESS if (reaccess) { if (memcmp(tss_ctx->connected_bssid[i], zero_addr, ETH_ADDR_LEN)) tss_req_payload = tssc_build_tss_req_payload(tssc_ctx->ee, tss_ctx->connected_bssid[i], &tss_req_payload_len); } else tss_req_payload = tssc_build_tss_req_payload(tssc_ctx->ee, NULL, &tss_req_payload_len); #else tss_req_payload = tssc_build_tss_req_payload(tssc_ctx->ee, NULL, &tss_req_payload_len); #endif if (tss_req_payload) { for (j = 0; j < MAX_CHANNEL_NUM; j ++) { /* EE可能只在邻频收到了req ack,再重复几次全信道扫描确保能在主信道收到req ack */ if (full_scan || tssc_ctx->full_scan_remain_time < TSSC_FULL_SCAN_REMAIN_TIME) { if (tssc_ctx->full_scan_list[i][j] == 0) break; tssc_send_tss_req(tss_ctx->socket_fd, tss_req_payload, tss_req_payload_len, bcast_addr, tssc_ctx->ee->trans_addr[i], tssc_ctx->full_scan_list[i][j]); } else { if (tssc_ctx->partial_scan_list[i][j] == 0) break; tssc_send_tss_req(tss_ctx->socket_fd, tss_req_payload, tss_req_payload_len, bcast_addr, tssc_ctx->ee->trans_addr[i], tssc_ctx->partial_scan_list[i][j]); } } free(tss_req_payload); tss_req_payload = NULL; } } /* Clear partial scan list */ if (full_scan) { tssc_ctx->full_scan_remain_time = 0; memset(tssc_ctx->partial_scan_list, 0, BAND_MAX * MAX_CHANNEL_NUM * sizeof(uint16_t)); } out: tss_add_loop_timer(timer, TSSC_SCAN_DETECTION_INTERVAL); return; } static void tssc_joining_handler(struct tss_loop_timer *timer) { time_t now = tss_get_timestamp(); if (!tssc_ctx) { return; } if (tssc_ctx->state != CONNECTING) return; if (tssc_ctx->joining_time + TSSC_JOINING_TIMEOUT < now) { tssc_set_state(IDLE); tss_print("tssc connecting for a long time, change to IDLE"); return; } tss_add_loop_timer(timer, TSSC_JOINING_DETECTION_INTERVAL); return; } static void tssc_handle_cmd(struct tss_command *command, uint8_t command_cnt) { enum tss_system_mode sysmode = 0; uint8_t sysmode_ctype = 0; struct tss_command *cmd = NULL; int i = 0; for (i = 0; i < command_cnt; i++) { cmd = command + i; if (!cmd) break; if (cmd->dtype == TSS_FORMAT_STRUCT) { switch (cmd->format) { case TSS_CLOUD: tss_print("Handle cloud command"); tss_set_cloud_config(&cmd->cloud, cmd->ctype); break; case TSS_NETWORK: tss_print("Handle network command"); tss_set_network_config(&cmd->net_conf, cmd->ctype); break; case TSS_WIRELESS_CONFIG: tss_print("Handle wireless command"); tss_set_wireless_config(cmd->wl_conf, cmd->wl_conf_cnt, cmd->ctype); break; default: tss_print("Unexpected command"); break; } } else if (cmd->dtype == TSS_SYSTEM_MODE) { tss_print("Handle sysmode command"); sysmode = cmd->sysmode; sysmode_ctype = cmd->ctype; } else if (cmd->dtype == TSS_MESH_TYPE) { tss_print("Handle mesh command"); tss_set_mesh_type(cmd->mesh_type, cmd->ctype); } else if (cmd->dtype == TSS_LOCATION) { tss_print("Handle location command"); tss_set_location(cmd->location, cmd->ctype); } else if (cmd->dtype == TSS_TIME_ZONE) { tss_print("Handle timezone command"); tss_set_time_zone(cmd->time_zone, cmd->ctype); } } if (sysmode > 0 && sysmode_ctype > 0) tss_set_sysmode(sysmode, sysmode_ctype); return; } static TSS_STATUS tssc_tss_req_ack_handler(struct tss_frame_buff *tfb) { uint8_t *freq = tlcp_get_specific_option(tfb, TLCP_FREQ); if (!freq) { tss_print("Without frequence infomation"); return TSS_NOK; } tssc_fill_scan_list(*((uint16_t *)freq)); return TSS_OK; } static TSS_STATUS tssc_tss_resp_handler(struct tss_frame_buff *tfb) { struct tss_context *tss_ctx = tss_ctx_get(); struct ether_hdr *eth_h = tss_eth_get_header(tfb); struct tss_response resp = {0}; struct tss_ecc_key_pair pair = {0}; uint8_t *freq; TSS_STATUS ret = TSS_NOK; #ifdef AMAZON_FFS_SUPPORT AMAZON_FFS_ONBOARDING_MSG ffs_msg = {0}; #endif if (!tss_ctx || !tssc_ctx) goto out; freq = tlcp_get_specific_option(tfb, TLCP_FREQ); if (!freq) { tss_print("Without frequence infomation"); goto out; } tssc_send_tss_resp_ack(tss_ctx->socket_fd, eth_h->src_addr, eth_h->dst_addr, *((uint16_t *)freq)); if (tssc_ctx->state >= CONNECTING) goto out; pair.ecc_prikey = tss_ctx->ecc_private_key; pair.ecc_prikey_len = tss_ctx->ecc_private_key_len; if (parse_tss_resp_data(tfb->data, tfb->data_len, &resp, &pair) == TSS_NOK || resp.cmd_cnt == 0) goto out; #ifdef AMAZON_FFS_SUPPORT /* tssc执行connecting时,关闭ffs,避免冲突 */ ffs_msg.type = AMAZON_FFS_STOP; msg_send(AMAZON_FFS_ONBOARDING_STATUS_MID, (U8 *)&ffs_msg, sizeof(ffs_msg)); #endif tssc_set_state(CONNECTING); tssc_handle_cmd(resp.command, resp.cmd_cnt); ret = TSS_OK; out: return ret; } static void tssc_bss_connect_handler() { tssc_set_state(CONNECTED); tss_change_role(TSS_ROLE_TSSD); return; } static int tssc_bss_connect_callback(TBUS_JSON req_obj, TBUS_JSON *resp_obj) { tssc_bss_connect_handler(); return 0; } void tssc_handle_tssp(struct tss_frame_buff *tfb) { struct tlcp_hdr *tlcp_h = tlcp_get_header(tfb); struct tssp_hdr *tssp_h = tssp_get_header(tfb); uint8_t *msg; if (!tssc_ctx) return; /* TLCP MSG */ if ((tlcp_h->flags & TLCP_OPTION) && (tlcp_h->total_length == 0)) { msg = tlcp_get_specific_option(tfb, TLCP_MSG); if (msg) { switch (*msg) { case TLCP_MSG_SCAN_FINISH: tss_print("TSS Scan finish"); if (tssc_ctx->state == SCANNING) tssc_set_state(IDLE); break; case TLCP_MSG_BSS_CONNECT: tss_print("TSS bss connectd"); tssc_bss_connect_handler(); break; default: break; } } return; } tssp_h = tssp_get_header(tfb); switch (tssp_h->frame_type) { case TSSP_REQ_ACK: tssc_tss_req_ack_handler(tfb); break; case TSSP_RESP: tssc_tss_resp_handler(tfb); break; default: //tss_print("Unsupported frame type %d", tssp_h->frame_type); break; } return; } void tssc_bind_file_changed_handler(int fd) { char buf[128] = {0}; /* Just clear modify event */ read(fd, buf, sizeof(buf)-1); if (!tss_dev_is_restore_state()) { tss_change_role(TSS_ROLE_TSSD); } return; } /*------------------------------------------------------INIT------------------------------------------*/ static void tssc_provisionee_fini(struct provisionee *ee) { if (!ee) return; free(ee); return; } static struct provisionee *tssc_provisionee_init() { struct provisionee *ee = calloc(1, sizeof(struct provisionee)); int i = 0; if (!ee) return NULL; tss_get_dev_addr(ee->addr); for (i = BAND_2G; i < BAND_MAX; i++) tss_get_transition_addr(i, ee->trans_addr[i]); ee->sysmode = tss_get_sysmode_capability(); ee->cap.modem_type = tss_get_modem_type_capability(); ee->cap.mesh_type = tss_get_mesh_type_capability(); ee->cap.wl_freq = tss_get_wireless_freq_capability(); ee->cap.band = tss_get_wifi_band_capability(); ee->cap.key_type = tss_get_wifi_key_type_capability(); return ee; } static void tssc_ctx_fini(struct tssc_context **ctx) { if (ctx == NULL || *ctx == NULL) return; if ((*ctx)->ee) tssc_provisionee_fini((*ctx)->ee); if ((*ctx)->inotify_fd > 0) tss_destroy_notify_fd((*ctx)->inotify_fd); free(*ctx); *ctx = NULL; return; } static struct tssc_context *tssc_ctx_init() { struct tssc_context *ctx; char *restore_state_file = NULL; uint8_t trans_addr[ETH_ADDR_LEN]; int i; ctx = calloc(1, sizeof(struct tssc_context)); if (!ctx) return NULL; ctx->ee = tssc_provisionee_init(); if (!ctx->ee) goto failed; restore_state_file = tss_get_restore_state_file(); if (restore_state_file) { ctx->inotify_fd = tss_create_notify_fd(restore_state_file); if (ctx->inotify_fd < 0) goto failed; } for (i = BAND_2G; i < BAND_MAX; i++) { /* Only scan bands with trans_addr configured */ if (!memcmp(ctx->ee->trans_addr[i], zero_addr, ETH_ADDR_LEN)) continue; tss_get_channel_list(i, ctx->full_scan_list[i]); } ctx->state = IDLE; ctx->scan_time = tss_get_timestamp(); ctx->full_scan_time = 0; ctx->full_scan_interval = TSSC_FULL_SCAN_INTERVAL_MIN; ctx->scaning_time = 0; ctx->joining_time = 0; return ctx; failed: tssc_ctx_fini(&ctx); return NULL; } static void tssc_loop_fini(void) { tss_del_loop_timer(scan_timer); tss_del_loop_timer(tssc_joining_timer); if (tssc_ctx && tssc_ctx->inotify_fd > 0) tss_del_loop_fd(inotify_fd); return; } static void tssc_loop_init(struct tssc_context *ctx) { if (!ctx) { return; } if (ctx->inotify_fd > 0) inotify_fd = tss_loop_fd_init(ctx->inotify_fd, tssc_bind_file_changed_handler); scan_timer = tss_loop_timer_init(ctx, tssc_scan_handler); tssc_joining_timer = tss_loop_timer_init(ctx, tssc_joining_handler); if (ctx->inotify_fd > 0) tss_add_loop_fd(inotify_fd); tss_add_loop_timer(scan_timer, TSSC_SCAN_DETECTION_INTERVAL); return; } void tssc_fini() { tss_ubus_action_unregister(TSS_UBUS_BSS_CONNECT); tssc_loop_fini(); tssc_ctx_fini(&tssc_ctx); tss_print("tssc finish"); return; } TSS_STATUS tssc_init() { tssc_ctx = tssc_ctx_init(); if (!tssc_ctx) { tss_print("Tssc context init failed"); return TSS_NOK; } #ifdef TSS_SUPPORT_REACCESS /* Clear connected bssid when the device is restore state */ if (tss_dev_is_restore_state()) tss_update_connected_bssid(TSS_TRUE); #endif tssc_loop_init(tssc_ctx); tss_ubus_action_register(TSS_UBUS_BSS_CONNECT, tssc_bss_connect_callback); tss_print("tssc init"); return TSS_OK; }
最新发布
11-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值