linuxOS_AP06/external/rkwifibt-app/test/rk_ble_app.c
2025-06-03 12:28:32 +08:00

354 lines
9.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <linux/prctl.h>
#include <sys/signalfd.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <sys/prctl.h>
#include <pthread.h>
#include <Rk_wifi.h>
#include "rk_ble_app.h"
#include "utility.h"
#include "bt_test.h"
/* Immediate wifi Service UUID */
#define AD_SERVICE_UUID16 "2222"
#define BLE_UUID_SERVICE "00008888-0000-1000-8000-00805F9B34FB"
#define BLE_UUID_WIFI_CHAR "00009999-0000-1000-8000-00805F9B34FB"
#define BLE_UUID_PROXIMITY "7B931104-1810-4CBC-94DA-875C8067F845"
#define UUID_MAX_LEN 36
typedef enum {
RK_BLE_WIFI_State_IDLE = 0,
RK_BLE_WIFI_State_CONNECTTING,
RK_BLE_WIFI_State_SUCCESS,
RK_BLE_WIFI_State_FAIL,
RK_BLE_WIFI_State_WRONGKEY_FAIL,
RK_BLE_WIFI_State_DISCONNECT
} RK_BLE_WIFI_State_e;
const char *MSG_BLE_WIFI_LIST_FORMAT = "{\"cmd\":\"wifilists\", \"ret\":%s}";
static char rk_wifi_list_buf[20 * 1024];
static int scanr_len = 0, scanr_len_use = 0;
static pthread_t wificonfig_tid = 0;
static pthread_t wificonfig_scan_tid = 0;
static char wifi_ssid[256];
static char wifi_password[256];
//static unsigned int ble_mtu = 0;
static RkBtContent bt_content;
typedef int (*RK_blewifi_state_callback)(RK_BLE_WIFI_State_e state);
#define RK_BLE_DATA_CMD_LEN 12
#define RK_BLE_DATA_SSID_LEN 32
#define RK_BLE_DATA_PSK_LEN 32
/* 消息开头必须为0x01结尾必须为0x04 */
typedef struct {
unsigned char start; // 段, 01Byte 固定为 0x01
char cmd[RK_BLE_DATA_CMD_LEN]; // 段, 12Byte 值为:"wifisetup"、"wifilists"
char ssid[RK_BLE_DATA_SSID_LEN]; // 段, 32Byte 需要连接的 WiFi ssid 长度不足 32 的部分填充 0
char psk[RK_BLE_DATA_PSK_LEN]; // 段, 32Byte 需要连接的 wifi password 长度不足 32 的部分填充 0
//unsigned char end; // 段, 01Byte 固定位 0x04
} RockChipBleData;
static bool confirm_done = 0;
static int rk_blewifi_state_callback(RK_WIFI_RUNNING_State_e state, RK_WIFI_INFO_Connection_s *info)
{
printf("[RK] %s state: %d\n", __func__, state);
switch(state) {
case RK_WIFI_State_CONNECTED:
rk_ble_send_notify(BLE_UUID_WIFI_CHAR, "wifi ok", 7);
break;
case RK_WIFI_State_CONNECTFAILED:
case RK_WIFI_State_CONNECTFAILED_WRONG_KEY:
rk_ble_send_notify(BLE_UUID_WIFI_CHAR, "wifi fail", 9);
break;
default:
break;
}
return 0;
}
void *rk_config_wifi_thread(void *arg)
{
printf("[RK] rk_config_wifi_thread\n");
prctl(PR_SET_NAME,"rk_config_wifi_thread");
RK_wifi_connect(wifi_ssid, wifi_password, WPA3, NULL);
return NULL;
}
void *rk_ble_send_data(void *arg)
{
int len, send_max_len = 120;
char *data;
char *wifilist;
prctl(PR_SET_NAME,"rk_ble_send_data");
scan_retry:
printf("[RK] RK_wifi_scan ...\n");
RK_wifi_scan();
usleep(800000);
//get scan list
wifilist = RK_wifi_scan_r();
//scan list is null
if (wifilist == NULL)
goto scan_retry;
//scan list too few
if (wifilist && (strlen(wifilist) < 3)) {
free(wifilist);
goto scan_retry;
}
//copy to static buff
memset(rk_wifi_list_buf, 0, sizeof(rk_wifi_list_buf));
snprintf(rk_wifi_list_buf, sizeof(rk_wifi_list_buf), MSG_BLE_WIFI_LIST_FORMAT, wifilist);
scanr_len = strlen(rk_wifi_list_buf);
scanr_len_use = 0;
printf("[RK] wifi scan_r: %s, len: %d\n", rk_wifi_list_buf, scanr_len);
//free
free(wifilist);
//max att mtu
send_max_len = bt_content.ble_content.att_mtu;
while (scanr_len) {
printf("[RK] %s: wifi use: %d, remain len: %d\n", __func__, scanr_len_use, scanr_len);
len = (scanr_len > send_max_len) ? send_max_len : scanr_len;
data = rk_wifi_list_buf + scanr_len_use;
//send data
confirm_done = false;
rk_ble_send_notify(BLE_UUID_WIFI_CHAR, data, len);
//waiting write resp
while (!confirm_done) {
usleep(10 * 1000);
}
printf("[RK] received confirm\n");
//resize
scanr_len -= len;
scanr_len_use += len;
}
return NULL;
}
static void ble_wifi_recv_data_cb(const char *uuid, char *data, int *len)
{
if (!strcmp(uuid, BLE_UUID_WIFI_CHAR)) {
if (strncmp(data, "wifi_scan", 9) == 0) {
pthread_create(&wificonfig_scan_tid, NULL, rk_ble_send_data, NULL);
} else if (strncmp(data, "wifi_setup", 10) == 0) {
char cmd[12];
memset(cmd, 0, 12);
memset(wifi_ssid, 0, 256);
memset(wifi_password, 0, 256);
sscanf(data, "%s %s %s", cmd, wifi_ssid, wifi_password);
printf("cmd: %s, ssid: %s, psk: %s\n", cmd, wifi_ssid, wifi_password);
pthread_create(&wificonfig_tid, NULL, rk_config_wifi_thread, NULL);
}
}
}
static void bt_test_ble_recv_data_callback(const char *uuid, char *data, int *len, RK_BLE_GATT_STATE state)
{
switch (state) {
//SERVER ROLE
case RK_BLE_GATT_SERVER_READ_BY_REMOTE:
//The remote dev reads characteristic and put data to *data.
printf("+++ ble server is read by remote uuid: %s\n", uuid);
*len = strlen("hello rockchip");
memcpy(data, "hello rockchip", strlen("hello rockchip"));
break;
case RK_BLE_GATT_SERVER_WRITE_BY_REMOTE:
//The remote dev writes data to characteristic so print there.
printf("+++ ble server is writeen by remote uuid: %s\n", uuid);
for (int i = 0 ; i < *len; i++) {
printf("%02x ", data[i]);
}
printf("\n");
//wifi config handle
ble_wifi_recv_data_cb(uuid, data, len);
break;
case RK_BLE_GATT_SERVER_ENABLE_NOTIFY_BY_REMOTE:
case RK_BLE_GATT_SERVER_DISABLE_NOTIFY_BY_REMOTE:
//The remote dev enable notify for characteristic
printf("+++ ble server notify is %s by remote uuid: %s\n",
(state == RK_BLE_GATT_SERVER_ENABLE_NOTIFY_BY_REMOTE) ? "enable" : "disabled", uuid);
break;
case RK_BLE_GATT_MTU:
bt_content.ble_content.att_mtu = *(uint16_t *)data;
printf("+++ ble server MTU: %d ===\n", *(uint16_t *)data);
break;
case RK_BLE_GATT_SERVER_INDICATE_RESP_BY_REMOTE:
//The service sends notify to remote dev and recv indicate from remote dev.
printf("+++ ble server receive remote indicate resp uuid: %s\n", uuid);
//set confirm flag
confirm_done = true;
break;
default:
break;
}
}
void rk_ble_wifi_init(char *data)
{
RkBleGattService *gs;
struct bt_conf conf;
static char *chr_props[] = { "read", "write", "indicate", "write-without-response", NULL };
printf(" %s \n", __func__);
memset(&bt_content, 0, sizeof(RkBtContent));
//BREDR CLASS BT NAME
memset(bt_content.bt_name, 0, sizeof(bt_content.bt_name));
strcpy(bt_content.bt_name, "rkbt");
//BLE NAME
memset(bt_content.ble_content.ble_name, 0, sizeof(bt_content.ble_content.ble_name));
strcpy(bt_content.ble_content.ble_name, "rkble");
//1234
FILE *fp;
fp = fopen("/data/bt_id.txt", "r");
if (fp) {
char bt_id[6];
fscanf(fp, "%s", bt_id); // Read the MAC address
fclose(fp);
char buf[38];
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf), "%s_%s", bt_content.bt_name, bt_id);
memcpy(bt_content.bt_name, buf, sizeof(bt_content.bt_name));
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf), "%s_%s", bt_content.ble_content.ble_name, bt_id);
memcpy(bt_content.ble_content.ble_name, buf, sizeof(bt_content.ble_content.ble_name));
}
//IO CAPABILITY
bt_content.io_capability = IO_CAPABILITY_DISPLAYYESNO;
//enable ble
bt_content.profile = PROFILE_BLE;
if (bt_content.profile & PROFILE_BLE) {
/* GATT SERVICE/CHARACTERISTIC */
//SERVICE_UUID
gs = &(bt_content.ble_content.gatt_instance[0]);
gs->server_uuid.uuid = BLE_UUID_SERVICE;
gs->chr_uuid[0].uuid = BLE_UUID_WIFI_CHAR;
gs->chr_uuid[0].chr_props = chr_props;
gs->chr_cnt = 1;
bt_content.ble_content.srv_cnt = 1;
/* Fill adv data */
/* Appearance */
bt_content.ble_content.Appearance = 0x0080;
/* manufacturer data */
bt_content.ble_content.manufacturer_id = 0x0059;
for (int i = 0; i < 16; i++)
bt_content.ble_content.manufacturer_data[i] = i;
/* Service UUID */
bt_content.ble_content.adv_server_uuid.uuid = AD_SERVICE_UUID16;
//callback
bt_content.ble_content.cb_ble_recv_fun = bt_test_ble_recv_data_callback;
}
rk_bt_register_state_callback(bt_test_state_cb);
rk_bt_register_vendor_callback(bt_test_vendor_cb);
//default state
bt_content.init = false;
bt_content.connecting = false;
bt_content.scanning = false;
bt_content.discoverable = false;
bt_content.pairable = false;
bt_content.power = false;
//global init
//ancs_is_support = false;
//ancs_is_enable = false;
//bt config file
memset(&conf, 0, sizeof(struct bt_conf));
//both BR/EDR and LE enabled, "dual", "le" or "bredr"
conf.mode = "le";
conf.BleName = bt_content.ble_content.ble_name;
conf.gatt_client_cache = "no";
create_bt_conf(&conf);
rk_debug_init(true);
rk_bt_init(&bt_content);
//enable adv
printf("Start BLE ADV ....\n");
rk_ble_adv_start();
//enble wifi
RK_wifi_register_callback(rk_blewifi_state_callback);
RK_wifi_enable(1, "/data/cfg/wpa_supplicant.conf");
printf(" %s end \n", __func__);
return;
}
void rk_ble_wifi_deinit(char *data)
{
printf(" %s \n", __func__);
//disable wifi
RK_wifi_enable(0, NULL);
//disable adv
rk_ble_adv_stop();
rk_bt_deinit();
printf(" %s end\n", __func__);
}
void rk_ble_wifi_init_onoff_test(char *data)
{
int test_cnt = 5000, cnt = 0;
if (data)
test_cnt = atoi(data);
printf("%s test times: %d(%d)\n", __func__, test_cnt, data ? atoi(data) : 0);
while (cnt < test_cnt) {
rk_ble_wifi_init(NULL);
rk_ble_wifi_deinit(NULL);
printf("BLE WiFi ON/OFF LOOPTEST CNT: [====== %d ======]\n", ++cnt);
}
}