fujianhao 1 天之前
父節點
當前提交
10b6a93840
共有 2 個文件被更改,包括 201 次插入5 次删除
  1. 二進制
      client/bluetoothctl
  2. 201 5
      client/main.c

二進制
client/bluetoothctl


+ 201 - 5
client/main.c

@@ -19,6 +19,8 @@
 #include <stdlib.h>
 #include <stdbool.h>
 #include <wordexp.h>
+#include "hiredis/hiredis.h"
+#include <iniparser.h>
 
 #include <ctype.h>
 
@@ -41,6 +43,11 @@
 #define PROMPT_ON	COLOR_BLUE "[bluetooth]" COLOR_OFF "# "
 #define PROMPT_OFF	"Waiting to connect to bluetoothd..."
 
+#define BLUETOOTH_CHAN      0
+
+#define BLUETOOTH_CONF    "/oem/etc/schedule.conf"
+#define unix_socket_path "/tmp/redis.sock"
+
 static DBusConnection *dbus_conn;
 
 static GDBusProxy *agent_manager;
@@ -53,6 +60,12 @@ struct adapter {
 	GList *devices;
 };
 
+typedef struct {
+    redisContext *context;
+    const char *socket_path;
+    time_t last_activity;
+} redis_client_t;
+
 static struct adapter *default_ctrl;
 static GDBusProxy *default_dev;
 static GDBusProxy *default_attr;
@@ -60,6 +73,11 @@ static GList *ctrl_list;
 static GList *battery_proxies;
 static GList *admin_devices_proxies;
 
+static redis_client_t *redisClient;
+
+// 存放当前正在处理的 proxy
+static GDBusProxy *g_current_proxy = NULL;
+
 static const char *agent_arguments[] = {
 	"on",
 	"off",
@@ -157,14 +175,161 @@ static void print_device(GDBusProxy *proxy, const char *description)
 #endif	
 }
 
+redis_client_t* create_redis_client(const char *socket_path) {
+    redis_client_t *client = malloc(sizeof(redis_client_t));
+    client->socket_path = socket_path;
+    client->context = redisConnectUnix(socket_path);
+    client->last_activity = time(NULL);
+    return client;
+}
+
+int ensure_connected(redis_client_t *client) {
+    if (client->context == NULL || client->context->err) {
+        if (client->context) {
+            redisFree(client->context);
+        }
+        client->context = redisConnectUnix(client->socket_path);
+        if (client->context == NULL || client->context->err) {
+            return -1; // 连接失败
+        }
+    }
+    client->last_activity = time(NULL);
+    return 0;
+}
+
+void redis_command_safe(const char *format, char *value) {
+    if (ensure_connected(redisClient) == 0) {
+        redisReply *reply = redisCommand(redisClient->context, format, value);
+        if (reply) {
+            // 处理回复
+            freeReplyObject(reply);
+        }
+    }
+}
+
+static int mac_in_bind_list(const char *addr, char **mac_list, int mac_cnt)
+{
+    int i;
+
+    if (!addr || !mac_list)
+        return 0;
+
+    for (i = 0; i < mac_cnt; i++) {
+        if (mac_list[i] && strcmp(addr, mac_list[i]) == 0)
+            return 1;
+    }
+    return 0;
+}
+
+
+int GetCmdValue(char *file, char *key, char *value, int lenth)
+{
+	dictionary  *   ini ;
+	ini = iniparser_load(file);
+	
+    if (ini==NULL) {
+        fprintf(stderr, "cannot parse file: %s\n", file);
+        return FALSE ;
+    }
+	strcpy(value, iniparser_getstring(ini, key, ""));
+	printf("keystr: \"%s\" ; value: %s.\n", key, value);
+	iniparser_freedict(ini);
+	return TRUE;
+}
+
+//发送控制指令
+void control_cmd(int channel, char *cmd)
+{
+    char redisCmd[256];
+    switch (channel)
+    {
+        case BLUETOOTH_CHAN:
+            printf( "bluetooth-channel [%s]\n", cmd );
+            redis_command_safe("LPUSH bluetooth-channel %s", cmd );
+            break;
+        default:
+            redis_command_safe("LPUSH control-channel %s", cmd );
+            break;
+    }
+}
+
+int parse_bind_list_dynamic(const char *src, char ***out_list)
+{
+    int count = 0;
+    const char *p = src;
+    char **list = NULL;
+
+    while (*p) {
+        if (*p == '"') {
+            p++;
+            char *end = strchr(p, '"');
+            if (!end) break;
+
+            list = realloc(list, sizeof(char *) * (count + 1));
+            list[count] = malloc(18);
+            memset(list[count], 0, 18);
+
+            strncpy(list[count], p, 17);
+            list[count][17] = '\0';
+
+            count++;
+            p = end + 1;
+        } else {
+            p++;
+        }
+    }
+
+    *out_list = list;
+    return count;
+}
+
+static dbus_bool_t is_device_in_bind_list(const char *current_mac)
+{
+    char value[512];
+    char **mac_list = NULL;
+    int mac_cnt = 0;
+    dbus_bool_t found = FALSE;
+
+    if (current_mac == NULL || strlen(current_mac) < 17)
+        return FALSE;
+
+    // 获取并解析绑定列表
+    if (GetCmdValue(BLUETOOTH_CONF, "bluetooth:bind_list", value, sizeof(value)) <= 0)
+        return FALSE;
+
+    mac_cnt = parse_bind_list_dynamic(value, &mac_list);
+    if (!mac_list)
+        return FALSE;
+
+    // 遍历比较
+    for (int i = 0; i < mac_cnt; i++) {
+        if (mac_list[i] != NULL && strcmp(current_mac, mac_list[i]) == 0) {
+            found = TRUE;
+            break;
+        }
+    }
+
+    // 释放内存
+    for (int i = 0; i < mac_cnt; i++) {
+        free(mac_list[i]);
+    }
+    free(mac_list);
+
+    return found;
+}
+
+/* Note2 */
 void ble_proc(unsigned char sigType, const unsigned char *buf, size_t len, int vals)
 {
+	char cmd[256];
 	if(sigType == 1){
 		printf("RSSI=%d\n", vals);
 	}else if(sigType == 2){
 		if(len == 23){
-			bt_shell_printf("=SOS key status=0x%02x\n", buf[22]);
+			//bt_shell_printf("=SOS key status=0x%02x\n", buf[22]);
 			if(buf[22] & 0x01){
+				sprintf(cmd,"{\"type\":\"Bluetooth\",\"key_action\":\"yes\"}");
+				control_cmd(BLUETOOTH_CHAN, cmd);
 				printf("got a sos and bvolt=%d\n", buf[22]>>2 );
 			  	/**********************************************************
 				*buf[22]: bit0=sos key value; bit[7-2]/10 = battery voltage
@@ -251,16 +416,44 @@ static void print_iter(const char *label, const char *name,
 	const char *valstr;
 	DBusMessageIter subiter;
 	char *entry;
-	char des_mac[] = "F0:C9:10:01:03:E2";
+
+	// char **bind_list = NULL;
+    // int bind_count = 0;
+    // char config_macs[512] = {0};
+    bool is_matched = false;
+	char *p;
+
+	char *des_mac[] = {"F0:C9:10:01:03:E2","F0:C9:10:01:03:E3"};
 	//char des_mac[] = "EA:C9:BA:DD:C0:D9";
 	if (iter == NULL) {
 		bt_shell_printf("%s%s is nil\n", label, name);
 		return;
 	}
 
-	char* p = strstr(label, des_mac);
-
-	if( p!= NULL){
+	// GetCmdValue(BLUETOOTH_CONF, "bluetooth:bind_list", config_macs, sizeof(config_macs));
+	// bind_count = parse_bind_list_dynamic(config_macs, &bind_list);
+
+	// for (int i = 0; i < bind_count; i++) {
+    //     // 检查 label 中是否包含该 MAC
+    //     if (strstr(label, bind_list[i])) {
+    //         is_matched = true;
+    //         break;
+    //     }
+	// }
+	// for (int i = 0; i < bind_count; i++) free(bind_list[i]);
+    // free(bind_list);
+	for (int i = 0; i < 2; i++) {
+        p = strstr(label, des_mac[i]);
+        if (p != NULL) {
+			is_matched = true;
+            // 只要匹配到了其中一个,就跳出循环
+            break; 
+        }
+    }
+
+	// p = strstr(label, des_mac);
+
+	if( is_matched == true ){
 		switch (dbus_message_iter_get_arg_type(iter)) {
 		case DBUS_TYPE_INVALID:
 			bt_shell_printf("%s%s is invalid\n", label, name);
@@ -330,6 +523,7 @@ static void print_iter(const char *label, const char *name,
 			break;
 		}	//end of ' switch (dbus_message_iter_get_arg_type(iter)) '
 	}	//end of ' if( p!= NULL) '
+
 }
 
 static void print_property_with_label(GDBusProxy *proxy, const char *name,
@@ -3203,6 +3397,8 @@ int main(int argc, char *argv[])
 	GDBusClient *client;
 	int status;
 
+	redisClient = create_redis_client(unix_socket_path);
+
 	bt_shell_init(argc, argv, &opt);
 	bt_shell_set_menu(&main_menu);
 	bt_shell_add_submenu(&advertise_menu);