2025-05-10 21:49:39 +08:00

312 lines
7.9 KiB
C
Raw Permalink 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 <Rk_wifi.h>
#include <RkBtBase.h>
#include <RkBle.h>
#include "rk_ble_app.h"
/* Immediate wifi Service UUID */
#define BLE_UUID_SERVICE "0000180A-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 unsigned 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;
struct wifi_config {
char ssid[512];
int ssid_len;
char psk[512];
int psk_len;
char key_mgmt[512];
int key_len;
bool hide;
void (*wifi_status_callback)(int status, int reason);
};
static struct wifi_config wifi_cfg;
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;
typedef struct {
uint8_t data[6];
} mac_t;
typedef struct {
uint8_t data[16];
} uuid128_t;
void _rk_ble_status_cb(const char *bd_addr, const char *name, RK_BLE_STATE state)
{
switch (state) {
case RK_BLE_STATE_IDLE:
printf("[RK] ble status: RK_BLE_STATE_IDLE\n");
break;
case RK_BLE_STATE_CONNECT:
printf("[RK] ble status: RK_BLE_STATE_CONNECT\n");
break;
case RK_BLE_STATE_DISCONNECT:
printf("[RK] ble status: RK_BLE_STATE_DISCONNECT\n");
ble_mtu = 0;
break;
}
}
static void _rk_ble_mtu_callback(const char *bd_addr, unsigned int mtu)
{
printf("=== %s: bd_addr: %s, mtu: %d ===\n", __func__, bd_addr, mtu);
ble_mtu = mtu;
}
static int rk_blewifi_state_callback(RK_WIFI_RUNNING_State_e state, RK_WIFI_INFO_Connection_s *info)
{
uint8_t ret = 0;
printf("[RK] %s state: %d\n", __func__, state);
switch(state) {
case RK_WIFI_State_CONNECTED:
ret = 0x1;
break;
case RK_WIFI_State_CONNECTFAILED:
case RK_WIFI_State_CONNECTFAILED_WRONG_KEY:
ret = 0x2;
break;
}
if(ret)
rk_ble_write(BLE_UUID_WIFI_CHAR, &ret, 0x1);
return 0;
}
static void *rk_config_wifi_thread(void)
{
printf("[RK] rk_config_wifi_thread\n");
prctl(PR_SET_NAME,"rk_config_wifi_thread");
RK_wifi_register_callback(rk_blewifi_state_callback);
RK_wifi_enable(0);
RK_wifi_enable(1);
RK_wifi_connect(wifi_cfg.ssid, wifi_cfg.psk);
return NULL;
}
static void rk_ble_send_data(void)
{
int len, send_max_len = BT_ATT_DEFAULT_LE_MTU;
uint8_t *data;
if (scanr_len == 0) {
scanr_len_use = 0;
printf("[RK] NO WIFI SCAN_R OR READ END!!!\n");
return;
}
prctl(PR_SET_NAME,"rk_ble_send_data");
if(ble_mtu > BT_ATT_HEADER_LEN)
send_max_len = ble_mtu;
send_max_len -= BT_ATT_HEADER_LEN;
if(send_max_len > BT_ATT_MAX_VALUE_LEN)
send_max_len = BT_ATT_MAX_VALUE_LEN;
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;
usleep(100000);
rk_ble_write(BLE_UUID_WIFI_CHAR, data, len);
scanr_len -= len;
scanr_len_use += len;
}
}
void _rk_ble_recv_data_cb(const char *uuid, char *data, int len)
{
if (!strcmp(uuid, BLE_UUID_WIFI_CHAR)) {
uint8_t str[512];
RockChipBleData *ble_data;
char *wifilist;
unsigned char end_flag = 0;
memset(str, 0, 512);
memcpy(str, data, len);
str[len] = '\0';
end_flag = str[len - 1];
printf("[RK] chr_write_value: %p, %d, data: %s\n", data, len, data);
for (int i = 0; i < len; i++) {
if (!( i % 8))
printf("\n");
printf("0x%02x ", str[i]);
}
printf("\n");
ble_data = (RockChipBleData *)str;
/* Msg is valid? */
printf("[RK] ble_data.cmd: %s, ble_data.start: %d, ble_data.end: %d\n",
ble_data->cmd, ble_data->start, end_flag);
if ((ble_data->start != 0x1) || (end_flag != 0x4)) {
printf("[RK] BLE RECV DATA ERROR !!!\n");
return;
}
if (strncmp(ble_data->cmd, "wifilists", 9) == 0) {
scan_retry:
printf("[RK] RK_wifi_scan ...\n");
RK_wifi_scan();
usleep(800000);
printf("[RK] RK_wifi_scan_r_sec ...\n");
wifilist = RK_wifi_scan_r_sec(0x14);
printf("[RK] RK_wifi_scan_r_sec end wifilist: %p\n", wifilist);
if (wifilist == NULL)
goto scan_retry;
if (wifilist && (strlen(wifilist) < 3)) {
free(wifilist);
goto scan_retry;
}
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(wifilist);
pthread_create(&wificonfig_scan_tid, NULL, rk_ble_send_data, NULL);
} else if (strncmp(ble_data->cmd, "wifisetup", 9) == 0) {
strcpy(wifi_ssid, ble_data->ssid); // str + 20);
strcpy(wifi_password, ble_data->psk); // str + 52);
printf("[RK] wifi ssid is %s\n", wifi_ssid);
printf("[RK] wifi psk is %s\n", wifi_password);
strcpy(wifi_cfg.ssid, wifi_ssid);
strcpy(wifi_cfg.psk, wifi_password);
//wifi_cfg.wifi_status_callback = wifi_status_callback;
pthread_create(&wificonfig_tid, NULL, rk_config_wifi_thread, NULL);
}
}
}
void _rk_ble_request_data_cb(const char *uuid, char *data, int len)
{
printf("=== %s uuid: %s===\n", __func__, uuid);
//len <= mtu(g_mtu)
len = sizeof("hello rockchip");
memcpy(data, "hello rockchip", len);
return;
}
static unsigned char bt_is_on = 0;
static void rk_bt_state_cb(RK_BT_STATE state)
{
switch(state) {
case RK_BT_STATE_TURNING_ON:
printf("RK_BT_STATE_TURNING_ON\n");
break;
case RK_BT_STATE_ON:
bt_is_on = 1;
printf("RK_BT_STATE_ON\n");
break;
case RK_BT_STATE_TURNING_OFF:
printf("RK_BT_STATE_TURNING_OFF\n");
break;
case RK_BT_STATE_OFF:
bt_is_on = 0;
printf("RK_BT_STATE_OFF\n");
break;
}
}
void rk_ble_wifi_init(void *data)
{
RkBtContent bt_content;
printf("===== %s =====\n", __func__);
//MUST TO SET 0
memset(&bt_content, 0, sizeof(RkBtContent));
bt_content.bt_name = strdup("RockChip");
bt_content.ble_content.ble_name = strdup("RockChipBle");
bt_content.ble_content.server_uuid.uuid = BLE_UUID_SERVICE;
bt_content.ble_content.server_uuid.len = UUID_128;
bt_content.ble_content.chr_uuid[0].uuid = BLE_UUID_WIFI_CHAR;
bt_content.ble_content.chr_uuid[0].len = UUID_128;
bt_content.ble_content.chr_cnt = 1;
bt_content.ble_content.cb_ble_recv_fun = _rk_ble_recv_data_cb;
bt_content.ble_content.cb_ble_request_data = _rk_ble_request_data_cb;
bt_content.ble_content.advDataType = BLE_ADVDATA_TYPE_SYSTEM;
bt_is_on = 0;
rk_ble_register_status_callback(_rk_ble_status_cb);
rk_bt_register_state_callback(rk_bt_state_cb);
rk_bt_init(&bt_content);
while (!bt_is_on)
sleep(1);
printf(">>>>> Start ble ....\n");
rk_ble_register_mtu_callback(_rk_ble_mtu_callback);
rk_ble_start(&bt_content.ble_content);
}
void rk_ble_wifi_deinit(void *data)
{
ble_mtu = 0;
rk_ble_stop();
sleep(3);
rk_bt_deinit();
}