#include #include "bk_airkiss.h" #include "airkiss.h" #include #include "lwip/sockets.h" #include #include "bk_wifi.h" static int bk_airkiss_decode_status; uint32_t airkiss_start_flag = 0; static volatile uint8_t airkiss_current_channel; beken_thread_t airkiss_thread_handle = NULL; static beken_semaphore_t airkiss_decode_over_sema; static airkiss_context_t *airkiss_context_ptr = NULL; static beken_timer_t airkiss_switch_channel_timer; static beken_timer_t airkiss_lock_channel_timer; const airkiss_config_t airkiss_cfg_ptr = { (airkiss_memset_fn) &os_memset, (airkiss_memcpy_fn) &os_memcpy, (airkiss_memcmp_fn) &os_memcmp, (airkiss_printf_fn) &os_printf, }; void bk_airkiss_set_start_flag(void) { airkiss_start_flag = 1; } void bk_airkiss_clear_start_flag(void) { airkiss_start_flag = 0; } uint32_t bk_airkiss_is_start(void) { return airkiss_start_flag; } static void bk_airkiss_switch_channel_timer_handler(void *parameter) { wifi_channel_t chan = {0}; airkiss_current_channel ++; if (airkiss_current_channel > MAX_CHANNEL_NUM) airkiss_current_channel = 1; BK_AIRKISS_PRT("switch_channel_to_index:%d \n", airkiss_current_channel); chan.primary = airkiss_current_channel; BK_LOG_ON_ERR(bk_wifi_monitor_set_channel(&chan)); airkiss_change_channel(airkiss_context_ptr); } static void bk_airkiss_lock_timeout_handler(void *parameter) { int ret; BK_AIRKISS_PRT("\r\nairkiss_lock_timeout_handler\r\n"); ret = airkiss_init(airkiss_context_ptr, &airkiss_cfg_ptr); if (ret != 0) BK_AIRKISS_PRT("airkiss_init_failed\r\n"); rtos_start_timer(&airkiss_switch_channel_timer); } static int bk_airkiss_monitor_callback(const uint8_t *data, uint32_t len, const wifi_frame_info_t *user_data) { bk_airkiss_decode_status = airkiss_recv(airkiss_context_ptr, data, len); if (bk_airkiss_decode_status == AIRKISS_STATUS_CHANNEL_LOCKED) { rtos_stop_timer(&airkiss_switch_channel_timer); BK_AIRKISS_PRT("lock_channel in %d \n", airkiss_current_channel); rtos_start_timer(&airkiss_lock_channel_timer); } else if (bk_airkiss_decode_status == AIRKISS_STATUS_COMPLETE) { rtos_stop_timer(&airkiss_lock_channel_timer); rtos_set_semaphore(&airkiss_decode_over_sema); BK_AIRKISS_PRT("AIRKISS_STATUS_COMPLETE \n"); } return BK_OK; } uint32_t bk_airkiss_resource_destroy(void) { BK_AIRKISS_PRT("bk_airkiss_resource_destroy\r\n"); if (airkiss_context_ptr != NULL) { os_free(airkiss_context_ptr); airkiss_context_ptr = NULL; } rtos_stop_timer(&airkiss_switch_channel_timer); rtos_deinit_timer(&airkiss_switch_channel_timer); rtos_stop_timer(&airkiss_lock_channel_timer); rtos_deinit_timer(&airkiss_lock_channel_timer); if (airkiss_decode_over_sema) { rtos_deinit_semaphore(&airkiss_decode_over_sema); airkiss_decode_over_sema = 0; } return AIRKISS_SUCCESS; } uint32_t bk_airkiss_resource_create(void) { int result = AIRKISS_SUCCESS; BK_AIRKISS_PRT("bk_airkiss_resource_create\r\n"); result = rtos_init_timer(&airkiss_switch_channel_timer, BK_AIRKISS_SWITCH_TIMER, bk_airkiss_switch_channel_timer_handler, (void *)0); BK_ASSERT(kNoErr == result); result = rtos_init_timer(&airkiss_lock_channel_timer, BK_AIRKISS_CYCLE_TIMER, bk_airkiss_lock_timeout_handler, (void *)0); BK_ASSERT(kNoErr == result); if (NULL == airkiss_decode_over_sema) { result = rtos_init_semaphore(&airkiss_decode_over_sema, 1); BK_ASSERT(kNoErr == result); } airkiss_context_ptr = (airkiss_context_t *)os_malloc(sizeof(airkiss_context_t)); if (!airkiss_context_ptr) { BK_AIRKISS_PRT("Malloc memory for airkiss context \n"); result = AIRKISS_FAILURE; goto init_exit; } os_memset(airkiss_context_ptr, 0, sizeof(airkiss_context_t)); result = airkiss_init(airkiss_context_ptr, &airkiss_cfg_ptr); if (result != 0) { BK_AIRKISS_PRT("Airkiss init failed!!\r\n"); result = AIRKISS_FAILURE; goto init_exit; } BK_AIRKISS_PRT("Airkiss version: %s\r\n", airkiss_version()); init_exit: return result; } static void bk_airkiss_wifi_connect(airkiss_result_t *airkiss_result) { BK_AIRKISS_PRT("wifi_connect_req %s, %s\n", airkiss_result->ssid, airkiss_result->pwd); BK_AIRKISS_PRT("wifi_connect_req %d, %d\n", airkiss_result->ssid_length, airkiss_result->pwd_length); demo_sta_app_init(airkiss_result->ssid, airkiss_result->pwd); } void bk_airkiss_start_udp_boardcast(u8 random_data) { int err, i; int udp_broadcast_fd = -1; struct sockaddr_in remote_skt; BK_AIRKISS_PRT("bk_airkiss_start_udp_boardcast\n"); udp_broadcast_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (udp_broadcast_fd == -1) { BK_AIRKISS_WARN("Socket failed\r\n"); return; } os_memset(&remote_skt, 0, sizeof(struct sockaddr_in)); remote_skt.sin_family = AF_INET; remote_skt.sin_addr.s_addr = INADDR_BROADCAST;//INADDR_ANY; remote_skt.sin_port = htons(10000); i = MAX_UDP_RANDOM_SEND; while (i --) { BK_AIRKISS_PRT("udp-sendto:%d\r\n", i); err = sendto(udp_broadcast_fd, &random_data, 1, 0, (struct sockaddr *)&remote_skt, sizeof(remote_skt)); rtos_delay_milliseconds(2); if (err == -1) BK_AIRKISS_WARN("send udp boardcast failed\r\n"); } BK_AIRKISS_PRT("close socket\r\n"); close(udp_broadcast_fd); } void bk_airkiss_decode_complete_handle(void) { int8_t err, chunk = 0; airkiss_result_t airkiss_result; BK_AIRKISS_PRT("bk_airkiss_decode_complete_handle\r\n"); err = airkiss_get_result(airkiss_context_ptr, &airkiss_result); if (0 == err) { BK_AIRKISS_PRT("airkiss_get_result() ok!\n"); BK_AIRKISS_PRT(" ssid = %s \n pwd = %s \n ssid_length = %d \n pwd_length = %d \n, random = 0x%02x\r\n", airkiss_result.ssid, airkiss_result.pwd, airkiss_result.ssid_length, airkiss_result.pwd_length, airkiss_result.random); } BK_LOG_ON_ERR(bk_wifi_monitor_stop()); BK_LOG_ON_ERR(bk_wifi_monitor_register_cb(NULL)); BK_AIRKISS_PRT("bk_airkiss_wifi_connecting\r\n"); bk_airkiss_wifi_connect(&airkiss_result); BK_AIRKISS_PRT("bk_airkiss_wifi_connect\r\n"); do { chunk ++; rtos_delay_milliseconds(1000); BK_AIRKISS_PRT("airkiss is waiting for network connection\r\n"); if (chunk >= 30) { BK_AIRKISS_PRT("GET IP Time Out!!! \n"); return; } } while (!wifi_netif_sta_is_got_ip()); bk_airkiss_start_udp_boardcast(airkiss_result.random); } uint32_t bk_airkiss_get_decode_status(void) { return bk_airkiss_decode_status; } uint32_t bk_airkiss_decode_isnot_over(void) { return (AIRKISS_STATUS_COMPLETE != bk_airkiss_decode_status); } static void bk_airkiss_thread_entry(void *parameter) { wifi_channel_t chan = {0}; uint32_t ret; /*step 0: init resource of airkiss*/ ret = bk_airkiss_resource_create(); if (AIRKISS_FAILURE == ret) goto _exit; /*step 1: init the parameter of switching channel, and then monitor*/ airkiss_current_channel = 1; chan.primary = airkiss_current_channel; BK_LOG_ON_ERR(bk_wifi_monitor_set_channel(&chan)); BK_LOG_ON_ERR(bk_wifi_monitor_register_cb(bk_airkiss_monitor_callback)); BK_LOG_ON_ERR(bk_wifi_monitor_start()); rtos_start_timer(&airkiss_switch_channel_timer); /*step 2: waiting for airkiss decode completion, or timeout*/ if (rtos_get_semaphore(airkiss_decode_over_sema, BK_AIRKISS_TIMEOUT) != kNoErr) BK_AIRKISS_PRT("airkiss_thread_timeout\r\n"); /*step 3: handle decode phase*/ bk_wifi_monitor_stop(); if (AIRKISS_STATUS_COMPLETE == bk_airkiss_decode_status) bk_airkiss_decode_complete_handle(); _exit: bk_airkiss_clear_start_flag(); bk_airkiss_resource_destroy(); BK_AIRKISS_PRT("bk_airkiss_thread_entry exit:%d\r\n", rtos_get_free_heap_size()); airkiss_thread_handle = NULL; rtos_delete_thread(NULL); } uint32_t bk_airkiss_init(void) { bk_err_t ret; BK_AIRKISS_PRT("bk_airkiss_init:%d\r\n", rtos_get_free_heap_size()); BK_LOG_ON_ERR(bk_wifi_monitor_stop()); bk_airkiss_set_start_flag(); if (NULL == airkiss_thread_handle) { ret = rtos_create_thread(&airkiss_thread_handle, BK_AIRKISS_THD_PRIORITY, "air_kiss", (beken_thread_function_t)bk_airkiss_thread_entry, 2048, (beken_thread_arg_t)0); if (ret != kNoErr) { BK_AIRKISS_PRT("Error: airkiss_start_process: %d\r\n", ret); return -1; } } return AIRKISS_SUCCESS; } uint32_t bk_airkiss_uninit(void) { BK_AIRKISS_PRT("bk_airkiss_uninit\r\n"); return AIRKISS_SUCCESS; } uint32_t bk_airkiss_stop(void) { BK_AIRKISS_PRT("bk_airkiss_stop\r\n"); if (rtos_is_timer_init(&airkiss_switch_channel_timer) && rtos_is_timer_running(&airkiss_switch_channel_timer)) rtos_stop_timer(&airkiss_switch_channel_timer); if (rtos_is_timer_init(&airkiss_lock_channel_timer) && rtos_is_timer_running(&airkiss_lock_channel_timer)) rtos_stop_timer(&airkiss_lock_channel_timer); if (bk_airkiss_is_start() && bk_airkiss_decode_isnot_over()) rtos_set_semaphore(&airkiss_decode_over_sema); return AIRKISS_SUCCESS; } uint32_t bk_airkiss_start(void) { BK_AIRKISS_PRT("bk_airkiss_start\r\n"); return bk_airkiss_init(); } uint32_t bk_airkiss_process(uint32_t start) { uint32_t ret; if (start) ret = bk_airkiss_start(); else ret = bk_airkiss_stop(); return ret; } // eof