增加tts服务,增加ai接口 1814/1 1814/head
authorhcj <1224667075@qq.com>
Sat, 7 Jun 2025 10:46:01 +0000 (18:46 +0800)
committerhcj <1224667075@qq.com>
Sat, 7 Jun 2025 10:46:01 +0000 (18:46 +0800)
15 files changed:
code/sdk/application/wearable/service/ble_service/bleservice/bleEvent.c
code/sdk/drivers/peripheral/slip/cat1Service/CMakeLists.txt
code/sdk/drivers/peripheral/slip/cat1Service/bk_websocket.h
code/sdk/drivers/peripheral/slip/cat1Service/cat1_at_cmd.cpp
code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp
code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.h
code/sdk/drivers/peripheral/slip/cat1Service/dev_authentication.cpp [new file with mode: 0644]
code/sdk/drivers/peripheral/slip/cat1Service/dev_authentication.h [new file with mode: 0644]
code/sdk/drivers/peripheral/slip/cat1Service/http_cat1.cpp [new file with mode: 0644]
code/sdk/kernel/liteos/liteos_v207.1.0/Huawei_LiteOS/tools/build/config/brandy.config
code/sdk/middleware/services/media/foundation/sample/wrapper/audio_capture_wrapper.cpp
code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.cpp
code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.h
code/sdk/open_source/openharmony/third_party/lwip/src/apps/http/http_client.c
code/sdk/open_source/openharmony/third_party/lwip/src/include/lwip/apps/http_client.h

index fc9fdb4..988a53d 100644 (file)
@@ -782,7 +782,7 @@ void comfirmPaire(uint8_t flag)
             errcode_t code = gap_ble_pair_remote_device(&addr);\r
             if(code!=ERRCODE_SUCC)\r
             {\r
-                  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"gap_ble_pair_remote_device fail %X\r\n",code);\r
+                  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"gap_ble_pair_remote_device fail %X\r\n",code);\r
             }\r
         }\r
 \r
@@ -1217,7 +1217,8 @@ void sendBindInfor(uint8_t *data)
                     \r
                 }\r
                 \r
-                CustomEventPublish(TOPIC_EVENT_DEVICE_BIND,(uint8_t *)buf,devnamelen+2);\r
+                // CustomEventPublish(TOPIC_EVENT_DEVICE_BIND,(uint8_t *)buf,devnamelen+2);\r
+                 comfirmPaire(1);\r
                 if(devname)\r
                 {   \r
                     ym_free(devname);\r
@@ -1229,7 +1230,8 @@ void sendBindInfor(uint8_t *data)
                 memset(buf,0,2);\r
                 buf[0] = DEVICEBIND;\r
                 buf[1] = 0;\r
-                CustomEventPublish(TOPIC_EVENT_DEVICE_BIND,buf,2);\r
+                // CustomEventPublish(TOPIC_EVENT_DEVICE_BIND,buf,2);\r
+                 comfirmPaire(1);\r
                 \r
             }\r
         }\r
@@ -1239,7 +1241,8 @@ void sendBindInfor(uint8_t *data)
             buf[0] = DEVICEBIND;\r
             buf[1] = 0 ;\r
               WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"phone devname is no name!!!!!!!!!:");\r
-            CustomEventPublish(TOPIC_EVENT_DEVICE_BIND,buf,2);\r
+            // CustomEventPublish(TOPIC_EVENT_DEVICE_BIND,buf,2);\r
+             comfirmPaire(1);\r
         }\r
          #endif\r
         #endif\r
index c7912d5..b4b5f30 100644 (file)
@@ -17,6 +17,9 @@ set(PRIVATE_HEADER
 )
 
 set(SOURCES
+${CMAKE_CURRENT_SOURCE_DIR}/dev_authentication.cpp
+${CMAKE_CURRENT_SOURCE_DIR}/http_cat1.cpp
+
 ${CMAKE_CURRENT_SOURCE_DIR}/cat1_at_cmd.cpp
 ${CMAKE_CURRENT_SOURCE_DIR}/cat1_server_hal.cpp
 ${CMAKE_CURRENT_SOURCE_DIR}/cat1_server.cpp
@@ -26,6 +29,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/cat_imei_map.cpp
 ${CMAKE_CURRENT_SOURCE_DIR}/cat1_ws.cpp
 
 
+
 )
 
 set(COMPONENT_PUBLIC_CCFLAGS
index 5448709..7536100 100644 (file)
@@ -2,7 +2,7 @@
 #ifndef __BK_WEBSOCKET_H__\r
 #define __BK_WEBSOCKET_H__\r
 // #include "aic_osa.h"\r
-\r
+// #include <bits/types.h>\r
 // WebSocket 消息类型枚举\r
 typedef enum {\r
     WS_CONT = 0x00,\r
@@ -23,7 +23,7 @@ typedef struct {
 \r
 \r
 // 初始化 WebSocket 客户端\r
-WebSocketClient *init_websocket_client(const char *url, const char *headers);\r
+WebSocketClient *init_websocket_client(const char *url, const char *headers,uint8_t use_dns);\r
 \r
 // 关闭 WebSocket 客户端\r
 void close_websocket_client(WebSocketClient *client) ;\r
index c6c834d..4f0220c 100644 (file)
@@ -434,6 +434,39 @@ static uint32_t start_record(uint8_t *para, uint32_t paraLen, char *strCommonCmd
     return 0;
 }
 
+extern void uapi_start_tts(void) ;
+static uint32_t starttts(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+    UNUSED(strCommonCmd);
+    uint8_t argv[PPG_MAX_ARGC][PPG_MAX_ARGV_LEN] = { 0 };
+    uint32_t argc = 0;
+    printf("ai_msg\n");
+    int ret = ConvertCmdToParam(para, paraLen, argv, &argc);
+    if (ret != PPG_SUCCESS) {
+        printf("CAT1TEST ATCMD Convert Command Failed\n");
+        return ERRCODE_FAIL;
+    }
+    uapi_start_tts();
+   
+    return 0;
+}
+
+extern void uapi_start_tts_single();
+static uint32_t sendttstxt(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+    UNUSED(strCommonCmd);
+    uint8_t argv[PPG_MAX_ARGC][PPG_MAX_ARGV_LEN] = { 0 };
+    uint32_t argc = 0;
+    printf("ai_msg\n");
+    int ret = ConvertCmdToParam(para, paraLen, argv, &argc);
+    if (ret != PPG_SUCCESS) {
+        printf("CAT1TEST ATCMD Convert Command Failed\n");
+        return ERRCODE_FAIL;
+    }
+    uapi_start_tts_single();
+
+    return 0;
+}
 
 
 static uint32_t start_asr(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
@@ -449,8 +482,6 @@ static uint32_t start_asr(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
     }
     uapi_start_asr();
 
-
-   
     return 0;
 }
 extern void record_test(void);
@@ -469,6 +500,57 @@ static uint32_t sendbindata(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
     record_test();
     return 0;
 }
+#include "dev_authentication.h"
+
+// extern void aut_active(void);
+
+static uint32_t active(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+    UNUSED(strCommonCmd);
+    uint8_t argv[PPG_MAX_ARGC][PPG_MAX_ARGV_LEN] = { 0 };
+    uint32_t argc = 0;
+    printf("ai_msg\n");
+    int ret = ConvertCmdToParam(para, paraLen, argv, &argc);
+    if (ret != PPG_SUCCESS) {
+        printf("CAT1TEST ATCMD Convert Command Failed\n");
+        return ERRCODE_FAIL;
+    }
+    aut_active();
+    return 0;
+}
+
+static uint32_t autlogin(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+    UNUSED(strCommonCmd);
+    uint8_t argv[PPG_MAX_ARGC][PPG_MAX_ARGV_LEN] = { 0 };
+    uint32_t argc = 0;
+    printf("ai_msg\n");
+    int ret = ConvertCmdToParam(para, paraLen, argv, &argc);
+    if (ret != PPG_SUCCESS) {
+        printf("CAT1TEST ATCMD Convert Command Failed\n");
+        return ERRCODE_FAIL;
+    }
+    aut_login();
+    return 0;
+}
+
+
+extern void read_file_put(void );
+
+static uint32_t readfileput(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+    UNUSED(strCommonCmd);
+    uint8_t argv[PPG_MAX_ARGC][PPG_MAX_ARGV_LEN] = { 0 };
+    uint32_t argc = 0;
+    printf("ai_msg\n");
+    int ret = ConvertCmdToParam(para, paraLen, argv, &argc);
+    if (ret != PPG_SUCCESS) {
+        printf("CAT1TEST ATCMD Convert Command Failed\n");
+        return ERRCODE_FAIL;
+    }
+    read_file_put();
+    return 0;
+}
 
 static const at_cmd_table_t g_cat1_cmd[] = {
     { (char *)"AT^CAT1POWER",      cat1_power, (char *)"1" },
@@ -495,6 +577,12 @@ static const at_cmd_table_t g_cat1_cmd[] = {
     { (char *)"AT^AI_ASR",      start_record, (char *)"1" },
     { (char *)"AT^STARTASR",      start_asr, (char *)"1" },
     { (char *)"AT^SENDBINDATA",      sendbindata, (char *)"1" },
+    { (char *)"AT^ACTIVE",      active, (char *)"1" },
+    { (char *)"AT^READPUT",      readfileput, (char *)"1" },
+    { (char *)"AT^LOGIN",      autlogin, (char *)"1" },
+    { (char *)"AT^STARTTTS",      starttts, (char *)"1" },
+    { (char *)"AT^SENDTTTS",      sendttstxt, (char *)"1" },
+    
 };
 
 at_cmd_table_t *get_cat1_cmd_table(uint32_t *cmd_count)
index 2cf3216..3765e89 100644 (file)
@@ -11,7 +11,7 @@
 #include "lwip/netif.h"
 #include "lwip/init.h"
 #include "lwip/inet_chksum.h"
-
+#include "lwip/dns.h"
 #include "lwip/err.h"
 #include "lwip/sockets.h"
 #include "lwip/sys.h"
@@ -42,6 +42,7 @@
 #include "broadcast_feature.h"
 #include "cmsis_os2.h"
 #include "cat1_ctl.h"
+#include "voice_call_volte_sample_wrapper.h"
 
 
 #ifdef __cplusplus
@@ -123,6 +124,7 @@ extern "C" {
 extern osStatus_t osDelay(uint32_t ticks);
 #define cat1_msleep(ms) osDelay(ms) /* osDelay(1) : 1ms */
 
+
 void bk_sleep(uint32_t time)
 {
     cat1_msleep(time);
@@ -131,11 +133,17 @@ void bk_sleep(uint32_t time)
 #include <stdlib.h>
 #include <string.h>
 
+extern bool read_dev_token(char *data_token);
+
+
 void * aic_zalloc(unsigned int len)
 {
     return malloc(len);
 }
 
+ void uapi_start_tts_single_txt(char *buf);
+
+
 // free
 
 // 定义一个结构体来存储解析后的URL部分
@@ -524,7 +532,8 @@ int  receive_websocket_message(WebSocketClient *client, unsigned char *buf,int l
     while(1)
     {
         bytes_received = recv(client->sockfd, frame, 1, 0);
-        if (bytes_received <= 0) {
+        if (bytes_received <= 0) 
+        {
             if (bytes_received == 0) {
                 printf("Connection closed by server.\n");
             } else {
@@ -541,8 +550,13 @@ int  receive_websocket_message(WebSocketClient *client, unsigned char *buf,int l
                 printf("receive_websocket_message:hend =0x%X,0x%X ,last_byte =0x%x ERROR222222222!!!!!!!!!",frame[0],frame[1],last_byte);
                 continue;
             }
+            if(frame[0]==0 && frame[1]==0 && last_byte==0)
+            {
+                break;
+            }
                 
-        }else
+        }
+        else
         {
             break;
         }
@@ -659,14 +673,39 @@ int  receive_websocket_message(WebSocketClient *client, unsigned char *buf,int l
     return payload_len;//parse_frame(buf, bytes_received, buf,code);
 }
 
+
+
+struct cat1_ws_init_t
+{
+    osSemaphoreId_t dns_done_sem;
+    ip_addr_t  ip;
+};
+
+static void dns_found(const char* hostname, const ip_addr_t *ipaddr, void *arg)
+{
+    struct cat1_ws_init_t * ip_sem=(struct cat1_ws_init_t *)arg;
+
+    printf("hostname %s ipaddr%d \r\n",hostname,ipaddr->u_addr.ip4);
+    memcpy(&(ip_sem->ip),ipaddr,sizeof(ipaddr));
+    (void)osSemaphoreRelease(ip_sem->dns_done_sem);
+}
+
+
 // 初始化 WebSocket 客户端
-WebSocketClient *init_websocket_client(const char *url, const char *headers) {
+WebSocketClient *init_websocket_client(const char *url, const char *headers,uint8_t use_dns) {
     //printf("init_websocket_client 1\n");
     char *buffer = NULL;
     WebSocketClient *client  =NULL;
     BK_URL parsed_url = {0};
     struct sockaddr_in server_addr;
     ssize_t bytes_received;
+    struct in_addr in_addr_t={0};
+    ip_addr_t  ip;
+    struct cat1_ws_init_t ip_sem={0};
+
+    err_t ret=0;
+
+    ip_sem.dns_done_sem = osSemaphoreNew(1, 0, NULL);
 
     parsed_url = parse_url(url);//解析url
 
@@ -695,17 +734,34 @@ WebSocketClient *init_websocket_client(const char *url, const char *headers) {
     }
 
    // printf("init_websocket_client 3\n");
+    if(use_dns)
+    {
+        ret =dns_gethostbyname(parsed_url.host,&ip,dns_found,&ip_sem);
+        // if(ERR_OK==ret)
+        {
+            osSemaphoreAcquire(ip_sem.dns_done_sem, 1000*30);
+        }
+        osSemaphoreDelete(ip_sem.dns_done_sem);
+        printf("dns_gethostbyname %d\r\n",ip_sem.ip.u_addr.ip4);
+        memcpy(&server_addr.sin_addr.s_addr, &ip_sem.ip.u_addr.ip4, 4);
+
+    }
+    else
+    {
+        inet_pton(AF_INET, parsed_url.host, &server_addr.sin_addr);
+    }
+   
+
    
     server_addr.sin_family = AF_INET;
 
     server_addr.sin_port = htons(parsed_url.port);
+   
 
-    server_addr.sin_addr.s_addr=inet_addr( parsed_url.host);
-
-    // inet_pton(AF_INET, parsed_url.host, &server_addr.sin_addr);
+    // 
 
     if (connect(client->sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
-        printf("init_websocket_client connection failed");
+        printf("init_websocket_client connection failed\r\n");
         close(client->sockfd);
         goto client_ERROR;
     }
@@ -769,7 +825,7 @@ void close_websocket_client(WebSocketClient *client) {
     if(client)
     {
         printf("close_websocket_client ");
-        close(client->sockfd);
+        // close(client->sockfd);
         free(client);
     }
     
@@ -840,35 +896,87 @@ bool chat_result_analysis(char *buf)
     }
     if(strcmp("middle",type_str)==0)
     {   
-        if(strlen(content_str)>0) {
-        memset_s(content_str_chat,64,0,64); 
-        memcpy_s(content_str_chat,64,content_str,strlen(content_str)); 
-        ble_set_ai_Answer_str(content_str_chat,2);
+        if(strlen(content_str)>0) 
+        {
+            memset_s(content_str_chat,64,0,64); 
+            memcpy_s(content_str_chat,64,content_str,strlen(content_str)); 
+            ble_set_ai_Answer_str(content_str_chat,2);
+            uapi_start_tts_single_txt(content_str_chat);
+
+
         }
 
     }
     cJSON_Delete(root);
     return true;
+}
 
+bool chat_ws_url_init(char * put_buf)
+{
+    char token[64]={0};
+    if(read_dev_token(token))
+    {
+        sprintf(put_buf,"ws://amp.raisound.com/chat/ws?dt=%s&platform=huoshan",token);
+        return true;
+    }
+    else
+    {
+        return false;
+    }
     
 }
 
+uint8_t is_bk_websocket_chat=0;
+
 void bk_websocket_demo(void *data) {
   
-    while (1)
+    // while (1)
     {
     /* code */
-        chat_client = init_websocket_client("ws://118.145.158.207:22080/chat/ws",NULL);
-        if (chat_client== NULL) {
+        is_bk_websocket_chat=1;
+
+        char url_buf[124]={0};
+        if(chat_ws_url_init(url_buf))
+        {
+            printf("%s\r\n",url_buf);
+        }
+        else
+        {
+            is_bk_websocket_chat=0;
+            return;
+        }
+        uint8_t client_count=3;
+
+        while (client_count)
+        {
+            chat_client = init_websocket_client(url_buf,NULL,1);
+
+            if (chat_client== NULL) {
+            client_count--;
             continue ;
+            }
+            else
+            {
+                break;
+            }
         }
+        if (chat_client== NULL){
+            is_bk_websocket_chat=0;
+           return;
+        }
+        
+        
         // send_ai_txt(1,"你是谁");
 
         WebSocketMessageType type;
         while (1)
         {
             memset_s(recv_buf,1024,0,1024);
-            receive_websocket_message(chat_client,(unsigned char *)recv_buf,1024,&type);
+            int len= receive_websocket_message(chat_client,(unsigned char *)recv_buf,1024,&type);
+            if(len==-1 || type == WS_CLOSE)
+            {   
+                break;
+            }
             chat_result_analysis(recv_buf);
             printf("bk_websocket_demo %s",recv_buf);
         }
@@ -876,7 +984,8 @@ void bk_websocket_demo(void *data) {
         
         close_websocket_client(chat_client);
         chat_client=NULL;
-        continue ;
+        is_bk_websocket_chat=0;
+        return ;
     }
 }
 
@@ -887,13 +996,13 @@ void bk_websocket_demo(void *data) {
 #include "common_def.h"
 #include "los_printf.h"
 
-#define CAT1_SERVICE_TASK_SIZE       (0x1000*2)
+#define CAT1_SERVICE_TASK_SIZE       (0x1000*1)
 #define CAT1_SERVICE_TASK_PRIO       5
 
 
 errcode_t chat_server_init(void)
 {
-    if(chat_client)
+    if(chat_client || is_bk_websocket_chat)
     {
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cat1_tcp_server_init is connet!\r\n");
         return ERRCODE_FAIL;
@@ -926,7 +1035,9 @@ errcode_t chat_server_init(void)
 char asr_recv_buf[1024]={0};
 WebSocketClient *asr_client;
 
+int32_t uapi_tts_paly_init(void);
 
+int32_t uapi_tts_paly_stop(void);
 //查询是否可以对话
 void uapi_start_asr(void)
 {
@@ -937,6 +1048,8 @@ void uapi_start_asr(void)
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message succ 0\n");
     else
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message  erro\n");
+
+    uapi_tts_paly_stop();
 }
 
 //停止对话
@@ -944,6 +1057,8 @@ void uapi_stop_asr(void)
 {
     char *jsonString ="{\"header\":{\"event\":\"StopTranscription\",\"trace_id\":\"3fa6b9e6a30b407ea38ad7ae69e6c291\"}}";
 
+    uapi_tts_paly_init();
+
     if (send_websocket_message(asr_client,( const unsigned char *)jsonString,strlen(jsonString),WS_TEXT)==0)
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message succ 0\n");
 }
@@ -953,11 +1068,13 @@ void uapi_stop_asr(void)
 void send_ai_bin(char *buf,uint32_t len)
 {
     // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_ai_bin 0\n");
+
     if (send_websocket_message(asr_client,( const unsigned char *)buf,len,WS_BINARY)==0)
     {
+        // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message succ 0\n");
         bk_sleep(10);
     }
-    // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message succ 0\n");
+    // 
 }
 
 void record_test(void)
@@ -1065,40 +1182,84 @@ bool aer_result_analysis(char *buf)
 
 uint8_t  is_bk_websocket_asr=0;
 
+// ws://amp.raisound.com/asr/ws?dt=95fc6dcdf5a3e9a48df535453efd097c19&platform=aliyun
+
+
+bool asr_ws_url_init(char * put_buf)
+{
+    char token[64]={0};
+    if(read_dev_token(token))
+    {
+        sprintf(put_buf,"ws://amp.raisound.com/asr/ws?dt=%s&platform=aliyun",token);
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+   
+}
 
 void bk_websocket_asr(void *data) {
   
     // while (1)
+
+    WebSocketMessageType type;
+    bool state = true;
+    
     is_bk_websocket_asr=1;
 
     {
-        asr_client = init_websocket_client("ws://118.145.158.207:22080/asr/ws",NULL);
-        if (asr_client== NULL) {
-            bk_sleep(10);
-            // continue ;
-             is_bk_websocket_asr=0;
+        //ws://amp.raisound.com/asr/ws
+        char url_buf[124]={0};
+        if(asr_ws_url_init(url_buf))
+        {
+            printf("%s\r\n",url_buf);
+        }
+        else 
+        {
             return;
         }
+
+        uint8_t client_count=3;
+
+        while (client_count)
+        {
+            // asr_client = init_websocket_client("ws://118.145.158.207:22080/asr/ws",NULL,0);
+            asr_client = init_websocket_client(url_buf,NULL,1);
+            if (asr_client== NULL) {
+                 printf("init_websocket_client fail %d\r\n",client_count);
+                client_count--;
+            continue ;
+            }
+             else
+            {
+                break;
+            }
+        }
+        if (asr_client== NULL){
+           return;
+        }
+
         uapi_cat1_keep_wakeup(1);
 
-        WebSocketMessageType type;
-        bool state = true;
-        SendMsgToUIService(UI_4G_AI_INIT_STAUS, 0,&state, sizeof(bool));
+        // uapi_start_asr();
+        // SendMsgToUIService(UI_4G_AI_INIT_STAUS, 0,&state, sizeof(bool));
 
         while (1)
         {
             memset_s(asr_recv_buf,1024,0,1024);
-            receive_websocket_message(asr_client,(unsigned char *)asr_recv_buf,1024,&type);
+            int len=  receive_websocket_message(asr_client,(unsigned char *)asr_recv_buf,1024,&type);
             // if(type==WS_CONT || 
-            if( type==WS_CLOSE)
+            if( type==WS_CLOSE || len==-1)
             {
                 printf("WS_CLOSE bk_websocket_asr\r\n");
                 break;
             }
-            printf("WS_CLOSE bk_websocket_asr %d\r\n",type);
-
+            printf(" bk_websocket_asr %d\r\n",type);
+            printf("bk_websocket_demo %s %d",asr_recv_buf,type);
             aer_result_analysis(asr_recv_buf);
-            // printf("bk_websocket_demo %s %d",asr_recv_buf,type);
+            //
         }
 
         
@@ -1112,16 +1273,15 @@ void bk_websocket_asr(void *data) {
 }
 
 
-
-
-
 errcode_t asr_server_init(void)
 {
-    if(is_bk_websocket_asr)
+    if(is_bk_websocket_asr || asr_client!=NULL)
     {
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cat1_tcp_server_init is connet!\r\n");
         return ERRCODE_FAIL;
     }
+   
+
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"asr_server_init !\r\n");
     app_task_definition_t taskcfg={0};
     taskcfg.create_queue_handle = NULL;
@@ -1141,15 +1301,283 @@ errcode_t asr_server_init(void)
     }
     return ERRCODE_SUCC;
 }
+/////////////////////////////////////////////tts接口////////////////////////////////////////////
+
+bool tts_ws_url_init(char * put_buf)
+{
+    char token[64]={0};
+    if(read_dev_token(token))
+    {
+        sprintf(put_buf,"ws://amp.raisound.com/tts/stream?dt=%s&platform=huoshan&noCache=1",token);
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+   
+}
+
+
+
+WebSocketClient *tts_client;
+
+
+void uapi_start_tts(void)
+{
+    char *jsonString =
+    "{\"header\": \
+     { \"event\": \"StartSynthesis\",\
+     \"trace_id\": \"3fa6b9e6a30b407ea38ad7ae69e6c291\"},\
+     \"payload\": \
+    {\"voice\":\"xiaoyun\",\
+     \"format\":\"pcm\",\
+     \"sample_rate\":16000,\
+     \"volume\":50,\
+     \"speech_rate\":0}\
+     }";
+
+     printf("uapi_start_tts : %s\r\n",jsonString);
+
+    if (send_websocket_message(tts_client,( const unsigned char *)jsonString,strlen(jsonString),WS_TEXT)==0)
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message succ 0\n");
+}
+void uapi_start_tts_single(void)
+{
+    char *jsonString =
+    " {  \"header\": {  \
+        \"event\": \"LongTextStream\",\
+        \"trace_id\": \"3fa6b9e6a30b407ea38ad7ae69e6c291\" \
+    }, \
+    \"payload\": { \
+        \"voice\":\"xiaoyun\", \
+        \"format\":\"pcm\", \
+        \"sample_rate\":16000, \
+        \"volume\":50, \
+        \"speech_rate\":0, \
+        \"text\":\"深圳市北科瑞声科技股份有限公司,是由国家重大人才计划特聘专家刘轶博士创办的国内人 \
+        工智能音频领军企业,专注于行业智能音频交互技术,拥有全链条核心自主知识产权,汇集世界一流的研发运营团队。\" \
+     } } ";
+
+     printf("uapi_start_tts : %s\r\n",jsonString);
+
+    if (send_websocket_message(tts_client,( const unsigned char *)jsonString,strlen(jsonString),WS_TEXT)==0)
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message succ 0\n");
+}
+
+ 
+ void uapi_start_tts_single_txt(char *buf)
+{
+    char jsonString[512] ={0};
+ 
+    sprintf(jsonString, " {  \"header\": {  \
+        \"event\": \"LongTextStream\",\
+        \"trace_id\": \"3fa6b9e6a30b407ea38ad7ae69e6c291\" \
+    }, \
+    \"payload\": { \
+        \"voice\":\"xiaoyun\", \
+        \"format\":\"pcm\", \
+        \"sample_rate\":16000, \
+        \"volume\":50, \
+        \"speech_rate\":0, \
+        \"text\":\"%s\" \
+     } } ",buf);
+
+     printf("uapi_start_tts : %s\r\n",jsonString);
+
+    if (send_websocket_message(tts_client,( const unsigned char *)jsonString,strlen(jsonString),WS_TEXT)==0)
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message succ 0\n");
+}
+
+// char *tts_txt_str=
+
+
+void send_tts_txt(char *msg)
+{   
+    char *jsonString =
+    "{ \
+    \"header\": { \
+        \"event\": \"RunSynthesis\", \
+        \"trace_id\": \"3fa6b9e6a30b407ea38ad7ae69e6c291\"\
+    }, \
+    \"payload\": { \
+        \"text\":\"深圳市北科瑞声科技股份有限公司,是由国家重大人才计划特聘专家刘轶博士创办的国内人工智能音频领军企业,\
+        专注于行业智能音频交互技术,拥有全链条核心自主知识产权,汇集世界一流的研发运营团队。\" \
+    }\
+    }";
+
+
+     if (send_websocket_message(tts_client,( const unsigned char *)jsonString,strlen(jsonString),WS_TEXT)==0)
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message succ 0\n");
+    else
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message fail 1\n");
+}
+
+
+
+
+uint8_t  is_bk_websocket_tts=0;
+
+
+void bk_websocket_tts(void *data) {
+  
+    // while (1)
+    uapi_cat1_keep_wakeup(1);
+
+    WebSocketMessageType type;
+    bool state = true;
+    
+    is_bk_websocket_tts=1;
+
+    {
+        //ws://amp.raisound.com/asr/ws
+        char url_buf[124]={0};
+        if(tts_ws_url_init(url_buf))
+        {
+            printf("%s\r\n",url_buf);
+        }
+        else 
+        {
+            is_bk_websocket_tts=0;
+            return;
+        }
+
+        uint8_t client_count=3;
+
+      
+
+        while (client_count)
+        {
+            tts_client = init_websocket_client("ws://118.145.158.207:22080/tts/stream?audio_buffer_size=4096",NULL,0);
+
+            if (tts_client== NULL) 
+            {
+                 printf("init_websocket_client fail %d\r\n",client_count);
+                client_count--;
+                continue ;
+            }
+            else
+            {
+                 printf("init_websocket_client succ \r\n");
+                break;
+            }
+        }
+        if (tts_client== NULL){
+              is_bk_websocket_tts=0;
+           return;
+        }
+
+        uapi_start_tts_single();
+        char* tts_recv_buf=(char *)malloc(1024*4);
+
+        while (1)
+        {
+            
+            
+            memset_s(tts_recv_buf,2048,0,2048);
+            int len=receive_websocket_message(tts_client,(unsigned char *)tts_recv_buf,1024*4,&type);
+            // if(type==WS_CONT || 
+            if( type==WS_CLOSE || len==-1)//|| type==WS_CONT )
+            {
+                printf("WS_CLOSE bk_websocket_tts\r\n");
+                break;
+            }
+            printf("bk_websocket_tts  bk_websocket_tts %d\r\n",type);
+            if(type==WS_BINARY)
+            {
+                AIStreamWrite((uint8_t *)tts_recv_buf,len);
+            }
+
+            // aer_result_analysis(asr_recv_buf);
+            printf("bk_websocket_demo %s %d",tts_recv_buf,type);
+        }
+
+        close_websocket_client(tts_client);
+        tts_client=NULL;
+        // return;
+    }
+      is_bk_websocket_tts=0;
+   
+}
+
+
+errcode_t tts_server_init(void)
+{
+
+    if(tts_client!=NULL || is_bk_websocket_tts)
+    {
+        return ERRCODE_FAIL;
+    }
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"asr_server_init !\r\n");
+    app_task_definition_t taskcfg={0};
+    taskcfg.create_queue_handle = NULL;
+    taskcfg.attr.name="tts_server_init";
+    taskcfg.attr.priority = TASK_PRIORITY_APP;
+    taskcfg.attr.stack_size = CAT1_SERVICE_TASK_SIZE;
+    taskcfg.func = bk_websocket_tts;
+    taskcfg.use_mem = USE_EXTEND_MEM;
+  
+    errcode_t ret=uapi_create_osThread_custom(&taskcfg);
+
+
+    if(ret != ERRCODE_SUCC)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"create cat1_service_file failed %d!\r\n",ret);
+        return ERRCODE_FAIL;
+    }
+    return ERRCODE_SUCC;
+}
+
 
 static uint8_t is_init_ai=1;
 
+
+int32_t uapi_tts_paly_init(void)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"uapi_tts_paly_init\n");
+
+    int32_t ret = ERRCODE_FAIL;
+    int32_t argc = 1;
+    uint8_t *argv = (uint8_t *)"StartAIpaly";
+    {
+        ret = VoiceCallVolteSample(argc, (const char **)&argv);
+    }
+    
+ 
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ret  %d ",ret);
+    
+    return ret;   
+}
+
+
+int32_t uapi_tts_paly_stop(void)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"uapi_tts_paly_init\n");
+
+    int32_t ret = ERRCODE_FAIL;
+    int32_t argc = 1;
+    uint8_t *argv = (uint8_t *)"stop";
+    {
+        ret = VoiceCallVolteSample(argc, (const char **)&argv);
+    }
+    
+ 
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ret  %d ",ret);
+    
+    return ret;   
+}
+
+
+
+
 bool init_ai_task(void)
 {
     if(is_init_ai)
     {
-        asr_server_init();
-        chat_server_init();
+        uapi_tts_paly_init();
+        // asr_server_init();
+        // chat_server_init();
+        tts_server_init();
         // is_init_ai=0;
     }
 
index 739ac84..508f23a 100644 (file)
@@ -12,6 +12,9 @@ void uapi_stop_asr(void);
 
 bool init_ai_task(void);
 
+ void uapi_start_tts_single_txt(char *buf);
+ 
+
 #ifdef __cplusplus
 #if __cplusplus
 }
diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/dev_authentication.cpp b/code/sdk/drivers/peripheral/slip/cat1Service/dev_authentication.cpp
new file mode 100644 (file)
index 0000000..bd47102
--- /dev/null
@@ -0,0 +1,645 @@
+//设备鉴权\r
+\r
+#define AIC_THIS_FILE    0x888899\r
+// #include <aic_errno.h>\r
+// #include <aic_init.h>\r
+// #include <aic_osa_ex.h>\r
+// // #include <aos_thread.h>\r
+// #include "app_msg.h"\r
+// #include "aic_net_pdp_mgr.h"\r
+// #include "aic_network_pcap.h"\r
+\r
+#include "cJSON.h"\r
+// #include <serial_inc.h>\r
+// #include "aic_osa.h"\r
+// #include "AI_AMP_2_5.h"\r
+#include "mbedtls/base64.h"\r
+#include "mbedtls/md5.h"\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include "mbedtls/aes.h"\r
+#include "mbedtls/cipher.h"\r
+#include "dev_authentication.h"\r
+#include "bts_br_gap.h"\r
+#include "custom_utils.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+\r
+void ase_encrypt_demo(void);\r
+\r
+// #include "aic_http_comm.h"\r
+\r
+// #define malloc malloc\r
+// #define free free\r
+// static char * dev_key = "uKLrChwrxA1LklgBc3VwawYjUkbT3BgX" ;\r
+// static char * dev_pid = "cqxJZi5CNgzjS3mX21Zw";\r
+int get_dev_pass_MAX_len(void)//获取设备密码最大长度,注意要防止内存越界\r
+{\r
+    // return sizeof(vc_cfg.dev_pass);\r
+}\r
+void save_dev_pass(char *dev_pass)//保存设备密码,dev_pass字符串\r
+{\r
+    // memset(vc_cfg.dev_pass,0,sizeof(vc_cfg.dev_pass));\r
+    // strncpy(vc_cfg.dev_pass,dev_pass,get_dev_pass_MAX_len());\r
+    // save_VC_cfg();\r
+}\r
+char *get_dev_pass(void)//获取设备密码,字符串的方式,返回字符串长度为0,即没密码\r
+{\r
+\r
+    // return vc_cfg.dev_pass;\r
+}\r
+\r
+static char aut_token[50] ={0};\r
+int str_count(char *data,char type)\r
+{\r
+    int ret = 0;\r
+    //int count = 0;\r
+    while(1)\r
+    {\r
+        if(data[ret] == type)\r
+            break;\r
+        ret++;\r
+        if(ret>65532)\r
+            return 0;\r
+    }\r
+    return ret;\r
+}\r
+void ase_encrypt_dome(void);\r
+//激活用的md5签名\r
+int active_md5_sign(const char *dev_id,const char *pid,const char *timestamp,const char *productSecret,char*md5_str)\r
+{\r
+    if(strlen(dev_id)>256)\r
+        return -1;\r
+    if(strlen(pid)>256)\r
+        return -2; \r
+    if(strlen(productSecret)>256)\r
+        return -3;\r
+    if(strlen(timestamp)>256)\r
+        return -4;\r
+    char md5_buf[16]={0};\r
+    char *sign_buf = (char *)malloc(1024);\r
+    \r
+    if(!sign_buf)\r
+        return -10;\r
+    memset(sign_buf,0,1024);\r
+    int sign_len = 0;\r
+    strcpy(sign_buf,dev_id);\r
+    sign_len = strlen(sign_buf);\r
+\r
+    strcpy(sign_buf+sign_len,pid);\r
+    sign_len = strlen(sign_buf);\r
+\r
+    strcpy(sign_buf+sign_len,timestamp);\r
+    sign_len = strlen(sign_buf);\r
+\r
+    strcpy(sign_buf+sign_len,productSecret);\r
+    sign_len = strlen(sign_buf);\r
+    printf("sign_buf:%s\r\n",sign_buf);\r
+   \r
+\r
+    mbedtls_md5_context ctx;\r
+\r
+    // 初始化MD5上下文\r
+    mbedtls_md5_init(&ctx);\r
+\r
+    // 开始计算MD5哈希\r
+    mbedtls_md5_starts(&ctx);\r
+    // 更新要计算哈希的数据\r
+    mbedtls_md5_update(&ctx, (const unsigned char *)sign_buf, sign_len);\r
+\r
+    // 完成哈希计算\r
+    mbedtls_md5_finish(&ctx, (unsigned char *)md5_buf);\r
+\r
+    // printf("md5_buf\r\n");\r
+    // for (int i = 0; i < 16; i++) {\r
+    //     printf("%02X\n", (uint8_t)md5_buf[i]);\r
+    // }\r
+    // printf("md5_buf end\r\n");\r
+\r
+    // 清理MD5上下文\r
+    mbedtls_md5_free(&ctx);\r
+    for (int i = 0; i < 16; i++) {\r
+        sprintf(&md5_str[i * 2], "%02x", (uint8_t)md5_buf[i]);\r
+    }\r
+    md5_str[32] = '\0';\r
+    \r
+    free(sign_buf);\r
+    return 0;\r
+}\r
+\r
+void active_md5_sign_demo(void)\r
+{\r
+    const char *dev_id ="1234567890";//imei号\r
+    const char *timestamp = "1717752535000";//时间戳\r
+    const char *pid = "Amg1HJ3dJkX3kLiLPNFg";//PID\r
+    const char *productSecret = "productSecret";//密钥\r
+    char md5_buf[33]={0};\r
+    active_md5_sign(dev_id,pid,timestamp,productSecret,md5_buf);\r
+    printf("md5_buf:%s",md5_buf);\r
+    ase_encrypt_demo();\r
+}\r
+#define AES_BLOCK_SIZE 16\r
+// PKCS5填充\r
+void pkcs5_padding(unsigned char *data, size_t data_len, size_t block_size) {\r
+    size_t padding_len = block_size - (data_len % block_size);\r
+    for (size_t i = 0; i < padding_len; i++) {\r
+        data[data_len + i] = (unsigned char)padding_len;\r
+    }\r
+}\r
+// 移除PKCS5填充\r
+size_t pkcs5_unpadding(unsigned char *data, size_t data_len,size_t block_size) {\r
+    size_t padding_len = data[data_len - 1];\r
+    if (padding_len > 0 && padding_len <= block_size) {\r
+        for (size_t i = 0; i < padding_len; i++) {\r
+            if (data[data_len - 1 - i] != (unsigned char)padding_len) {\r
+                return data_len;\r
+            }\r
+        }\r
+        return data_len - padding_len;\r
+    }\r
+    return data_len;\r
+}\r
+\r
+//登录用的aes256加密\r
+int aes_cbc_pkcs5_encrypt(const char *input,int input_len,const char* str_key,const char* str_iv,char *Base64_output,int *Base64_output_len)\r
+{\r
+\r
+    mbedtls_cipher_context_t ctx;\r
+    int ret;\r
+    unsigned char *aes_data =NULL;\r
+    unsigned char *padded_plaintext=NULL;\r
+    uint32_t aes_data_len = 0;\r
+    uint32_t padded_len;\r
+    // 初始化上下文\r
+    mbedtls_cipher_init(&ctx);\r
+\r
+    // 设置加密算法\r
+    ret = mbedtls_cipher_setup(&ctx, mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_CBC));\r
+    if (ret != 0) {\r
+        printf("mbedtls_cipher_setup failed: -0x%04x\n", -ret);\r
+        goto exit;\r
+    }\r
+\r
+    // 设置密钥和IV\r
+    ret = mbedtls_cipher_setkey(&ctx, ( const unsigned char *)str_key, strlen(str_key) * 8, MBEDTLS_ENCRYPT);\r
+    if (ret != 0) {\r
+        printf("mbedtls_cipher_setkey failed: -0x%04x\n", -ret);\r
+        goto exit;\r
+    }\r
+\r
+    ret = mbedtls_cipher_set_iv(&ctx, ( const unsigned char *)str_iv, strlen(str_iv));\r
+    if (ret != 0) {\r
+        printf("mbedtls_cipher_set_iv failed: -0x%04x\n", -ret);\r
+        goto exit;\r
+    }\r
+    //printf("aes_cbc_pkcs5_encrypt2");\r
+    // 计算填充后的长度\r
+    padded_len = input_len;\r
+    if (padded_len % AES_BLOCK_SIZE != 0) {\r
+        padded_len += AES_BLOCK_SIZE - (padded_len % AES_BLOCK_SIZE);\r
+    }else\r
+        padded_len+=AES_BLOCK_SIZE;\r
+    //printf("aes_cbc_pkcs5_encrypt3");\r
+    // 复制明文并进行填充\r
+    padded_plaintext = (unsigned char *)malloc(padded_len);\r
+    if (padded_plaintext == NULL) {\r
+        ret = MBEDTLS_ERR_CIPHER_ALLOC_FAILED;\r
+        printf("Memory allocation failed\n");\r
+        goto exit;\r
+    }\r
+    //printf("aes_cbc_pkcs5_encrypt4 padded_len :%d,input_len:%d",padded_len,input_len);\r
+    aes_data = (unsigned char *)malloc(padded_len);\r
+    if (aes_data == NULL) {\r
+        ret = MBEDTLS_ERR_CIPHER_ALLOC_FAILED;\r
+        printf("Memory allocation failed\n");\r
+        goto exit;\r
+    }\r
+    //printf("aes_cbc_pkcs5_encrypt5");\r
+    memcpy(padded_plaintext, input, input_len);\r
+    pkcs5_padding(padded_plaintext, input_len, AES_BLOCK_SIZE);\r
+    printf("aes_cbc_pkcs5_encrypt6");\r
+    // 加密\r
+    ret = mbedtls_cipher_update(&ctx, padded_plaintext, padded_len, aes_data, &aes_data_len);\r
+    if (ret != 0) {\r
+        printf("mbedtls_cipher_update failed: -0x%04x\n", -ret);\r
+        \r
+        goto exit;\r
+    }\r
+    printf("aes_cbc_pkcs5_encrypt7");\r
+    mbedtls_base64_encode((unsigned char *)Base64_output, *Base64_output_len,(size_t *) Base64_output_len, aes_data, aes_data_len);\r
+    Base64_output[*Base64_output_len] = 0;\r
+    printf("aes_cbc_pkcs5_encrypt8.");\r
+    free(padded_plaintext);\r
+    printf("aes_cbc_pkcs5_encrypt9");\r
+    free(aes_data);\r
+    \r
+    // 清理上下文\r
+    mbedtls_cipher_free(&ctx);\r
+    return 0;\r
+\r
+exit:\r
+    mbedtls_cipher_free(&ctx);\r
+    if(aes_data)\r
+        free(aes_data);\r
+    if(padded_plaintext)\r
+        free(padded_plaintext);\r
+    return ret;\r
+}\r
+\r
+// AES/CBC/PKCS5Padding解密\r
+int aes_cbc_pkcs5_decrypt(const char *Base64_str_input,const char* str_key,const char* str_iv,char *output,int *output_len)\r
+    // const unsigned char *key, size_t key_len,\r
+    // const unsigned char *iv, size_t iv_len,\r
+    // const unsigned char *ciphertext, size_t ciphertext_len,\r
+    // unsigned char *plaintext, size_t *plaintext_len) \r
+{\r
+    mbedtls_aes_context ctx = {0};\r
+    int ret;\r
+    char *input_buf = NULL;\r
+    size_t input_buf_len;\r
+      char vi_tmp[16];\r
+    // 初始化上下文\r
+    mbedtls_aes_init(&ctx);\r
+    //printf("aes_cbc_pkcs5_decrypt str_key:%s,str_iv:%s!!!!!!!!!!!!!!!!!!!!!!!!", str_key,str_iv);\r
+    // // 设置加密算法\r
+    // ret = mbedtls_cipher_setup(&ctx, mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_CBC));\r
+    // if (ret != 0) {\r
+    //     printf("mbedtls_cipher_setup failed: -0x%04x\n", -ret);\r
+    //     goto exit;\r
+    // }\r
+    \r
+    // 设置密钥和IV\r
+    ret = mbedtls_aes_setkey_dec(&ctx, (const unsigned char*)str_key, strlen(str_key) * 8);\r
+    if (ret != 0) {\r
+        printf("mbedtls_cipher_setkey failed: -0x%04x\n", -ret);\r
+        goto exit;\r
+    }\r
+\r
+    // ret = mbedtls_cipher_set_iv(&ctx, str_iv, strlen(str_iv));\r
+    // if (ret != 0) {\r
+    //     printf("mbedtls_cipher_set_iv failed: -0x%04x\n", -ret);\r
+    //     goto exit;\r
+    // }\r
+    input_buf_len = strlen(Base64_str_input)+1;\r
+    input_buf = (char *)malloc(input_buf_len);\r
+    memset(input_buf,0,input_buf_len);\r
+    //printf("mbedtls_base64_decode1:input_buf_len:%d,Base64_str_input:%s",input_buf_len,Base64_str_input);\r
+    mbedtls_base64_decode((unsigned char *)input_buf, input_buf_len, &input_buf_len,( const unsigned char *) Base64_str_input, strlen(Base64_str_input));\r
+    //printf("mbedtls_base64_decode2:input_buf_len:%d,output_len:%d",input_buf_len,*output_len);\r
+    // bk_print_hex(input_buf,input_buf_len);\r
+    // 解密\r
+\r
+    \r
+    memcpy(vi_tmp,str_iv,16);\r
+    ret = mbedtls_aes_crypt_cbc(&ctx,MBEDTLS_AES_DECRYPT,input_buf_len,(unsigned char *) vi_tmp,( const unsigned char *)input_buf,( unsigned char *)output);\r
+    *output_len = input_buf_len;\r
+\r
+    if (ret != 0) {\r
+        printf("mbedtls_cipher_update failed: -0x%04x\n", -ret);\r
+        goto exit;\r
+    }\r
+\r
+    // 清理上下文\r
+    mbedtls_aes_free(&ctx);\r
+    //printf("aes_cbc_pkcs5_decrypt output_len:%d output:%s",*output_len,output);\r
+    // 移除填充\r
+    *output_len = pkcs5_unpadding((unsigned char *)output, *output_len,AES_BLOCK_SIZE);\r
+    output[*output_len] = 0;\r
+    if(input_buf)\r
+        free(input_buf);\r
+    return 0;\r
+\r
+    exit:\r
+    if(input_buf)\r
+        free(input_buf);\r
+    mbedtls_cipher_free((mbedtls_cipher_context_t *)&ctx);\r
+    return ret;\r
+}\r
+void ase_encrypt_demo(void)\r
+{\r
+    const char *data = "123456789123456789001234567890";\r
+    size_t  Base64_data_len = strlen(data)*3+32;\r
+    char *Base64_data =(char *) malloc(Base64_data_len);\r
+    memset(Base64_data,0,Base64_data_len);\r
+    aes_cbc_pkcs5_encrypt(data,strlen(data),"uKLrChwrxA1LklgBc3VwawYjUkbT3BgX","5555555566666666",Base64_data,(int *)&Base64_data_len);\r
+    printf("ase_encrypt_dome:aes_cbc_pkcs5_encrypt:len:%d,Base64_data:%s",Base64_data_len,Base64_data);\r
+    char *decrypt_data = (char *)malloc(Base64_data_len);\r
+    aes_cbc_pkcs5_decrypt(Base64_data,"uKLrChwrxA1LklgBc3VwawYjUkbT3BgX","5555555566666666",decrypt_data,(int *)&Base64_data_len);\r
+    printf("ase_encrypt_dome:aes_cbc_pkcs5_decrypt:len:%d,decrypt_data:%s",Base64_data_len,decrypt_data);\r
+    if(Base64_data)\r
+        free(Base64_data);\r
+    if(decrypt_data)\r
+        free(decrypt_data);\r
+}\r
+\r
+/****************************************************************************** */\r
+int set_token(char *token)\r
+{\r
+    if(strlen(token)>=sizeof(aut_token))\r
+    {\r
+        printf("ERROR token to0 long");\r
+        return -1;\r
+    }\r
+    memset(aut_token,0,sizeof(aut_token));\r
+    strcpy(aut_token,token);\r
+    return 0;\r
+        \r
+}\r
+int get_token(char *token)\r
+{\r
+    return 0;\r
+    // return aut_token;   \r
+}\r
+\r
+\r
+//激活\r
+\r
+\r
+// 设备激活\r
+\r
+\r
+//激活->登录的密钥\r
+const char * key = "4EepovakpbqhZUnUDwH42KAADYGv4UUe" ;\r
+//每小时更新登录一次的更新定时器\r
+// static aos_timer_ptr LOGIN_1H_timer = NULL;\r
+\r
+void aut_active(void)//设备激活\r
+{\r
+    int ret;\r
+    printf("aut_active");\r
+    // AIC_HTTPS_CLIENT_INSTANCE *http_client;\r
+    char dev_pass_base64[100] ={0};\r
+    char enc_iv[65] = {0};\r
+    // http创建客户端句柄\r
+\r
+    char *json_string =NULL;\r
+    cJSON *root = NULL;\r
+\r
+\r
+    unsigned char deviceId[6] = {0};\r
+    unsigned int len = 6;\r
+\r
+\r
+    memset(deviceId,0,6);    \r
+    bluetooth_get_local_addr(&deviceId[0],len);\r
+\r
+    char deviceId_temp[20] = {0};\r
+\r
+    sprintf(deviceId_temp,"%02X%02x%02X%02x%02X%02x",deviceId[5],deviceId[4],deviceId[3],deviceId[2],deviceId[1],deviceId[0]);\r
+\r
+\r
+     time_t timestamp;\r
+    timestamp = time(NULL);\r
+    printf("2时间戳: %ld\n", (long)timestamp);\r
+    long long timestamp_ms = (long long)timestamp * 1000;\r
+\r
+    char* timestamp_str_2=(char *)malloc(20);\r
+    memset(timestamp_str_2,0,20);\r
+\r
+    // 使用 sprintf 将 long long 类型的时间戳转换为字符串\r
+    ret = sprintf(timestamp_str_2, "%lld", timestamp_ms);\r
+    // 打印转换后的字符串形式的时间戳\r
+\r
+\r
+    const char *dev_pid = "Y1DxRdBfnzVZQrXHdrNl";//PID\r
+    // const char *dev_key = "4EepovakpbqhZUnUDwH42KAADYGv4UUe";//密钥\r
+\r
+    char md5_buf[33]={0};\r
+    active_md5_sign((char *)deviceId_temp,dev_pid,timestamp_str_2,key,md5_buf);\r
+    printf("md5_buf:%s",md5_buf);\r
+\r
+\r
+    const char *signMethod ="MD5";\r
+\r
+    uint32_t response = 0;\r
+    //创建客户端实例\r
+\r
+        \r
+    // 创建JSON对象\r
+    root = cJSON_CreateObject();\r
+    if (root == NULL) {\r
+        printf( "Failed to create JSON object\n");\r
+        return;\r
+    }\r
+\r
+    // 添加字段\r
+    cJSON_AddStringToObject(root, "deviceId", (char *)deviceId_temp);\r
+    cJSON_AddStringToObject(root, "pid", dev_pid);\r
+    cJSON_AddStringToObject(root, "sign", md5_buf);\r
+\r
+    printf("时间戳(ms 转换为字符串): %s\n", timestamp_str_2);\r
+\r
+    cJSON_AddStringToObject(root, "timeStamp", timestamp_str_2);\r
+\r
+    free(timestamp_str_2);\r
+\r
+    cJSON_AddStringToObject(root, "signMethod", signMethod);\r
+\r
+    // 生成JSON字符串\r
+    json_string = cJSON_Print(root);\r
+    if (json_string == NULL) {\r
+        printf("Failed to print JSON\n");\r
+        cJSON_Delete(root);\r
+        return;\r
+    }\r
+\r
+    // 输出JSON\r
+    printf("JSON output: %s\n", json_string);\r
+    extern void put_data_by_get_file(char *data,uint16_t data_len);\r
+\r
+    put_data_by_get_file(json_string,strlen(json_string));\r
+\r
+    cJSON_free(json_string);\r
+}\r
+\r
+\r
+\r
+extern bool read_dev_pass(char *data_pass);\r
+extern void post_data_by_get_file(char *data,uint16_t data_len);\r
+\r
+\r
+void aut_login(void)//登录\r
+{\r
+    printf("dev_sign_in 1");\r
+    char dev_pass[64]={0};  \r
+    if(read_dev_pass(dev_pass)==false)\r
+    return ;\r
+\r
+\r
+    printf("dev_sign_in 2");\r
+    int count = 5;\r
+    char *encrypt_data = NULL;\r
+    char *response_data =NULL;\r
+    int aut_login_http_handle = 0;\r
+    char enc_iv[17]={0};\r
+   \r
+    // 随机生成16个字符串 设备生成做加密使用\r
+    //char *random_string= generate_random_string(); // 随机的16个字符串\r
+    // 设备端进行密码加密\r
+    /**\r
+     * password, productSecret, nonce utJMIAPRN1E81DzSDVigh/f0ZmHQdBgdAGZ/DhkPJ/s=   uKLrChwrxA1LklgBc3VwawYjUkbT3BgX   qgofeplofqeoadha\r
+     */\r
+    int encrypt_data_len = 512;\r
+    encrypt_data = (char *)malloc(encrypt_data_len);\r
+    \r
+\r
+    // 登录数据\r
+    unsigned char deviceId[20] = {0};\r
+    //aic_srv_tele_radio_get_current_slot_imei_sync(deviceId);\r
+    memset(deviceId,0,6);    \r
+    bluetooth_get_local_addr(&deviceId[0],6);\r
+\r
+    char deviceId_temp[20] = {0};\r
+\r
+    sprintf(deviceId_temp,"%02X%02x%02X%02x%02X%02x",deviceId[5],deviceId[4],deviceId[3],deviceId[2],deviceId[1],deviceId[0]);\r
+\r
+    time_t timestamp;\r
+    timestamp = time(NULL);\r
+    printf("2时间戳: %ld\n", (long)timestamp);\r
+    long long timestamp_ms = (long long)timestamp * 1000;\r
+    char timestamp_str[20] ={0};\r
+\r
+    // 使用 sprintf 将 long long 类型的时间戳转换为字符串\r
+    sprintf(timestamp_str, "%lld", timestamp_ms);\r
+    memset(enc_iv,'1',16);\r
+    memcpy(enc_iv,timestamp_str,strlen(timestamp_str));\r
+\r
+    enc_iv[16] = 0;\r
+    aes_cbc_pkcs5_encrypt(dev_pass, strlen(dev_pass), key, enc_iv,encrypt_data,&encrypt_data_len);//加密\r
+    \r
+    cJSON *root = cJSON_CreateObject();\r
+    if (root == NULL) \r
+    {\r
+        return;\r
+    }\r
+    // 添加字段\r
+    cJSON_AddStringToObject(root, "deviceId", deviceId_temp);\r
+    cJSON_AddStringToObject(root, "password", encrypt_data);\r
+    cJSON_AddStringToObject(root, "nonce", enc_iv);\r
+    // 生成JSON字符串\r
+    char *json_string = cJSON_Print(root);\r
+    if (json_string == NULL) \r
+    {\r
+        printf( "Failed to print JSON\n");\r
+        cJSON_Delete(root);\r
+        return;\r
+    }\r
+    printf("json_string:%s",json_string);\r
+\r
+    post_data_by_get_file(json_string,strlen(json_string));\r
+\r
+    cJSON_free(json_string);\r
+}\r
+\r
+\r
+// void aut_chack_token(void)//检查token\r
+// {\r
+\r
+// }\r
+ \r
+//每小时更新一次登录\r
+static void LOGIN_1H_timeout(void *param)\r
+{\r
+    // if (sizeof(dev_pass) == 0)\r
+    //     aut_active();//没有密钥走激活\r
+    // //每小时登录一次\r
+    // aut_login();\r
+    dev_authentication_MSG_put(NULL,0,AUT_LOGIN);\r
+}\r
+// static aos_thread_id dev_authentication_id = 0;\r
+// static aos_queue_ptr dev_authentication_task_queue = NULL;\r
+//鉴权消息发送\r
+void dev_authentication_MSG_put(const char *data,uint32_t len,dev_authentication_MSG_Type MSG_Type)\r
+{\r
+    dev_authentication_MSG_queue_t dev_authentication_MSG_queue_data = {0};\r
+    //bk_msg_printf("dev_authentication_MSG_put1 MSG_Type:%d",MSG_Type);\r
+    if(len >0)\r
+    {\r
+        dev_authentication_MSG_queue_data.data = (char *)malloc(len+1);\r
+        memset(dev_authentication_MSG_queue_data.data ,0,len+1);\r
+        if(!dev_authentication_MSG_queue_data.data)\r
+        {\r
+            //bk_msg_printf("AI_VC_send_data malloc ERROR!!!!!!!!!!");\r
+            return ;\r
+        }\r
+        memcpy(dev_authentication_MSG_queue_data.data,data,len);\r
+        dev_authentication_MSG_queue_data.len=len;\r
+    }\r
+    \r
+    dev_authentication_MSG_queue_data.MSG_Type=MSG_Type;\r
+    // if(dev_authentication_task_queue && AOS_SUCCESS!=aos_send_to_queue(dev_authentication_task_queue,&dev_authentication_MSG_queue_data,AOS_NO_WAIT))\r
+    {\r
+       if(!dev_authentication_MSG_queue_data.data)\r
+            free(dev_authentication_MSG_queue_data.data);\r
+        return ;\r
+    }\r
+    //bk_msg_printf("dev_authentication_MSG_put2 MSG_Type:%d",MSG_Type);\r
+    return ;\r
+}\r
+static void dev_authentication_task(void *thread_input)//鉴权逻辑线程\r
+{\r
+    dev_authentication_MSG_queue_t dev_authentication_msg = {0};\r
+    //ase_encrypt_demo();\r
+    //dev_NTP();//获取时间\r
+    //aut_active();//激活\r
+    aut_login();//登录\r
+    // if(LOGIN_1H_timer == NULL)\r
+    // {\r
+    //     LOGIN_1H_timer = aos_create_timer("AI_VC_1S_timer",\r
+    //         LOGIN_1H_timeout, &LOGIN_1H_timer,\r
+    //         60000*60,\r
+    //         AOS_AUTO_ACTIVATE, AOS_BE_PERIOD);\r
+    //     aic_assert(LOGIN_1H_timer);\r
+    // }\r
+\r
+    // /**\r
+    //  * 原来已激活过了...AuthVo(password=rPbSCNTIVYWKso6I5+6l0KIbSiIembg3p10IEny2UVg=, deviceId=860132061481751, nonce=xiRqXDqkqGFodIiw)\r
+    //  */\r
+    // while (1) {\r
+    //     if(dev_authentication_task_queue)\r
+    //     {\r
+    //         aos_recv_from_queue(dev_authentication_task_queue,&dev_authentication_msg,AOS_WAIT_FOREVER) ;\r
+    //         switch (dev_authentication_msg.MSG_Type)\r
+    //         {\r
+    //             case AUT_ACTIVE://激活\r
+    //                 aut_active();\r
+    //                 break;\r
+    //             case AUT_LOGIN://登录\r
+    //                 aut_login();\r
+    //                 break;\r
+    //             // case AUT_CHACK_TOKEN://检查token\r
+    //             //     aut_chack_token();\r
+    //             //     break;\r
+    //         }\r
+    //         if(dev_authentication_msg.data)\r
+    //             free(dev_authentication_msg.data);\r
+    //     }else\r
+    //     {\r
+    //         aos_sleep(10);\r
+    //     }\r
+    // }\r
+}\r
+void dev_authentication_init(void)\r
+{\r
+    // //创建设备激活队列\r
+    // if(dev_authentication_task_queue == NULL)\r
+    // {\r
+    //     dev_authentication_task_queue = aos_create_queue("dev_authentication_task_queue",\r
+    //         sizeof(dev_authentication_MSG_queue_t),\r
+    //         200);\r
+    // }\r
+    // dev_authentication_id = aos_create_thread(\r
+    //     "dev_authentication_task",\r
+    //     dev_authentication_task,\r
+    //     &dev_authentication_id,\r
+    //     4096u,\r
+    //     0,\r
+    //     NULL,\r
+    //     35,\r
+    //     AOS_AUTO_START);\r
+}\r
+#ifdef __cplusplus\r
+}\r
+#endif /* __cplusplus */
\ No newline at end of file
diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/dev_authentication.h b/code/sdk/drivers/peripheral/slip/cat1Service/dev_authentication.h
new file mode 100644 (file)
index 0000000..6d91265
--- /dev/null
@@ -0,0 +1,40 @@
+\r
+#ifndef __DEV_AUTHENTICATION_H__\r
+#define __DEV_AUTHENTICATION_H__\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+\r
+void active_md5_sign_demo(void);\r
+\r
+void dev_authentication_init(void);\r
+int aes_cbc_pkcs5_encrypt(const char *input,int input_len,\r
+const char* str_key,const char* str_iv,char *Base64_output,int *Base64_output_len);\r
+//激活用的md5签名\r
+int active_md5_sign(const char *dev_id,const char *pid,const char *timestamp,const char *productSecret,char*md5_str);\r
+int str_count(char *data,char type);\r
+// int get_token(void);\r
+typedef enum dev_authentication_MSG\r
+{\r
+    AUT_ACTIVE,//激活\r
+    AUT_LOGIN,//登录\r
+    //AUT_CHACK_TOKEN//检查令牌\r
+    \r
+} dev_authentication_MSG_Type;\r
+typedef struct\r
+{\r
+    char *data;\r
+    uint32_t len;\r
+    dev_authentication_MSG_Type MSG_Type;\r
+}dev_authentication_MSG_queue_t;\r
+void dev_authentication_MSG_put(const char *data,uint32_t len,dev_authentication_MSG_Type MSG_Type);\r
+\r
+void aut_active(void);//设备激活;\r
+void aut_login(void);//设备激活;\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+\r
+#endif
\ No newline at end of file
diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/http_cat1.cpp b/code/sdk/drivers/peripheral/slip/cat1Service/http_cat1.cpp
new file mode 100644 (file)
index 0000000..f3115ca
--- /dev/null
@@ -0,0 +1,308 @@
+#include "lwip/apps/http_client.h"
+
+
+#include <sys/time.h>
+
+#include "bletest.h"
+#include "custom_utils.h"
+#include "custom_runtime.h"
+#include "bleANCS.h"
+#include "cat1_tcpServer.h"
+#include "custom_utils.h"
+#include "broadcast_feature.h"
+#include "cmsis_os2.h"
+#include "cat1_ctl.h"
+#include "wearable_log.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define HTTP_JSON_SERVER_NAME "app-api.raisound.com"//"test.app.api.thisiot.com"//获取升级服务器
+#define PORT (80)// (80)http端口号  (443)//https端口号
+#define PUT_URL "/dev/auth/active"//激活接口
+#define POST_URL "/dev/auth/sign_in"//登录接口
+
+
+#define  AUTH_ACTIVE "/user/userdata/ota_report_.json"//上报升级得到的json
+
+#define  AUTH_SIGN_IN  "/user/userdata/sign_in.json"//上报升级得到的json
+
+
+
+
+static httpc_connection_t settings = {0};
+
+
+    static err_t httpc_download_headers_done_ui(httpc_state_t *connection, void *arg, struct pbuf *hdr, u16_t hdr_len, u32_t content_len)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "httpc_download_headers_done_ui hdrlen %d, file len %d\r\n",hdr_len,content_len); 
+        // file_total_len = content_len;
+        return 0;
+    }
+    static err_t httpc_download_file_recv_ui(httpc_state_t *connection, u32_t rx_len,u32_t rx_total_len)
+    {
+        // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "httpc_download_file_recv_ui recv %d bytes total received %d filelen %d\r\n",rx_len,rx_total_len,file_total_len);
+        return 0;
+    }
+
+    static void httpc_download_result_data_put(void *arg, httpc_result_t httpc_result, u32_t rx_content_len, u32_t srv_res, err_t err)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "httpc_download_result_ui");
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"httpc_download_result , httpc_result_t %d, rx_content_len %d , srv_res %d, err %d\n",
+            httpc_result,rx_content_len,srv_res,err);
+        if(srv_res==200)
+        {
+            //激活成功
+        }
+        return ;
+    }
+    // {"success":true,"msg":"登录成功","code":20001,"data":{"deviceId":"28110601009b","token":"95fc6dcdf5a3e9a48df535453efd097c19"}}
+
+    static void httpc_download_result_data_post(void *arg, httpc_result_t httpc_result, u32_t rx_content_len, u32_t srv_res, err_t err)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "httpc_download_result_ui");
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"httpc_download_result , httpc_result_t %d, rx_content_len %d , srv_res %d, err %d\n",
+            httpc_result,rx_content_len,srv_res,err);
+        if(srv_res==200)
+        {
+            //登录成功
+        }
+        return ;
+    }
+
+
+
+void put_data_by_get_file(char *data,uint16_t data_len)
+{
+    memset_s(&settings,sizeof(settings),0,sizeof(settings));
+    settings.use_proxy=0;
+    
+    settings.use_put=1;
+    settings.args=(u8_t*)data;
+    settings.arglen=data_len;
+    uint8_t *otadatapath =(uint8_t *)AUTH_ACTIVE;
+
+    settings.result_fn=httpc_download_result_data_put;
+    settings.file_rx_fn = httpc_download_file_recv_ui;
+    settings.headers_done_fn = httpc_download_headers_done_ui;
+
+    httpc_state_t* connection=NULL;
+    err_t rett= httpc_get_file_dns_to_disk(
+        HTTP_JSON_SERVER_NAME,
+        PORT,
+        PUT_URL,
+        &settings, 
+        NULL, 
+        (const char*) otadatapath, 
+            &connection);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"custom_start_ota_download %d \r\n",rett);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "use_put");      
+}
+
+
+void post_data_by_get_file(char *data,uint16_t data_len)
+{
+    memset_s(&settings,sizeof(settings),0,sizeof(settings));
+    settings.use_proxy=0;
+    
+    settings.use_post=1;
+    settings.args=(u8_t*)data;
+    settings.arglen=data_len;
+    uint8_t *otadatapath =(uint8_t *)AUTH_SIGN_IN;
+
+    settings.result_fn=httpc_download_result_data_post;
+    settings.file_rx_fn = httpc_download_file_recv_ui;
+    settings.headers_done_fn = httpc_download_headers_done_ui;
+
+    httpc_state_t* connection=NULL;
+    err_t rett= httpc_get_file_dns_to_disk(
+        HTTP_JSON_SERVER_NAME,
+        PORT,
+        POST_URL,
+        &settings, 
+        NULL, 
+        (const char*) otadatapath, 
+            &connection);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"custom_start_ota_download %d \r\n",rett);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "use_post");      
+}
+// {"success":true,
+// "msg":"激活成功.",
+// "code":20000,
+// "data":
+// {"password":
+// "mCx3DK7AqNyCXiP7/Iim4X4/e2Y5h/ZA4n9qLN3V4Z0=",
+// "deviceId":"28110601009b","nonce":"OlhdyxEkdqJVPyvr"}
+// }
+extern int aes_cbc_pkcs5_decrypt(const char *Base64_str_input,const char* str_key,const char* str_iv,char *output,int *output_len);
+
+bool read_dev_pass(char *data_pass)
+{
+    char buf[512]={0};
+
+    FILE *fp=fopen(AUTH_ACTIVE,"rb+");
+    int read_size;
+
+    uint32_t pack=512;
+
+    if(fp==NULL)
+    {
+        return false;
+    }
+    
+    memset_s(buf,512,0,512);
+    read_size=fread(buf,1,512,fp);
+    if(read_size!=0)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "buf %d %s",read_size,buf);     
+    }
+    fclose(fp);
+
+    char *p=buf;
+    while (*p!='{' && *p !='\0')
+    {
+        p++;
+    }
+
+    cJSON* root = cJSON_Parse((const char *)p);
+    if (root == NULL) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"解析失败\n");
+        return false;
+    }
+    char *password_str=NULL;
+    char * nonce_str=0;
+
+    cJSON* data = cJSON_GetObjectItem(root, "data");
+    if (data)
+    {
+        cJSON* password = cJSON_GetObjectItem(data, "password");
+        if (password && cJSON_IsString(password)) {
+            password_str= password->valuestring;
+        }
+
+        cJSON* nonce = cJSON_GetObjectItem(data, "nonce");
+        if (nonce && cJSON_IsString(nonce)) {
+            nonce_str = nonce->valuestring;
+        }
+         
+    }
+
+    int dev_pass_len =64;
+    char *dev_pass =(char *)malloc(dev_pass_len);
+    if(dev_pass)
+    {
+        memset(dev_pass,0,dev_pass_len);
+        if(strlen(nonce_str)>8 && strlen(password_str)>8)
+        {
+            aes_cbc_pkcs5_decrypt(password_str, "4EepovakpbqhZUnUDwH42KAADYGv4UUe", nonce_str,dev_pass,&dev_pass_len);//解密
+            dev_pass[dev_pass_len] = 0;
+            printf("dev_pass:%s dev_pass_len:%d\n",dev_pass,dev_pass_len);
+        }
+      
+    }else
+    {
+       printf("dev_pass malloc error!!!!!!!!!!!");
+    }
+
+    if(strlen(password_str)>=0)
+    {
+        memcpy(data_pass,dev_pass,dev_pass_len);
+        free(dev_pass);
+        return true;
+    }
+   
+    return false;
+}
+
+// {"success":true,"msg":"登录成功","code":20001,"data":{"deviceId":"28110601009b","token":"95fc6dcdf5a3e9a48df535453efd097c19"}}
+
+bool read_dev_token(char *data_token)
+{
+    char buf[512]={0};
+
+    FILE *fp=fopen(AUTH_SIGN_IN,"rb+");
+    int read_size;
+
+    uint32_t pack=512;
+
+    if(fp==NULL)
+    {
+        return false;
+    }
+    
+    memset_s(buf,512,0,512);
+    read_size=fread(buf,1,512,fp);
+    if(read_size!=0)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "buf %d %s",read_size,buf);     
+    }
+    fclose(fp);
+
+    char *p=buf;
+    while (*p!='{' && *p !='\0')
+    {
+        p++;
+    }
+
+    cJSON* root = cJSON_Parse((const char *)p);
+    if (root == NULL) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"解析失败\n");
+        return false;
+    }
+    char *token_str=NULL;
+
+    cJSON* data = cJSON_GetObjectItem(root, "data");
+    if (data)
+    {
+        cJSON* token = cJSON_GetObjectItem(data, "token");
+        if (token && cJSON_IsString(token)) {
+            token_str= token->valuestring;
+        }
+    }
+
+    if(strlen(token_str)>=0)
+    {
+        memcpy(data_token,token_str,strlen(token_str));
+        return true;
+    }
+   
+    return false;
+}
+
+void read_file_put(void )
+{
+      char buf[1024]={0};
+
+    FILE *fp=fopen(AUTH_SIGN_IN,"rb+");
+    int read_size;
+
+    uint32_t pack=1024;
+
+    if(fp==NULL)
+    {
+        return;
+    }
+    do
+    {
+        memset_s(buf,1024,0,1024);
+        read_size=fread(buf,1,1024,fp);
+
+        if(read_size!=0)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "buf %d %s",read_size,buf);     
+        }
+    
+    } while (read_size==1024);
+    fclose(fp);
+
+}
+
+
+
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
\ No newline at end of file
index 930c26c..31bbe1c 100755 (executable)
@@ -76,7 +76,7 @@ LOSCFG_TASK_JOINABLE=y
 LOSCFG_BASE_CORE_TSK_MONITOR=y
 LOSCFG_TASK_STACK_STATIC_ALLOCATION=y
 LOSCFG_TASK_STACK_DYNAMIC_ALLOCATION=y
-LOSCFG_BASE_CORE_TSK_LIMIT=64
+LOSCFG_BASE_CORE_TSK_LIMIT=72
 LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE=1024
 LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE=2048
 LOSCFG_BASE_CORE_TSK_SWTMR_STACK_SIZE=3072
index 63c020a..028b4c4 100755 (executable)
@@ -27,6 +27,7 @@
 #include "audio_manager.h"
 #include "media_log.h"
 #include "media_thread_adapt.h"
+#include "voice_call_volte_sample_wrapper.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -495,19 +496,20 @@ int32_t streamingRecordAndSend_AI(int type)
 {
     // 定义argv数组在更大的作用域
     const char *argv[6];
-    if(ai_4g_enable_flag == 1)
+    // if(ai_4g_enable_flag == 1)
     {
         argv[0] = "01"; argv[1] = "mp3"; argv[2] = "16000"; 
         argv[3] = "1";  argv[4] = "16";  argv[5] = "/user/aiRecord.sbc";
     }
-    else
-    {
-        argv[0] = "01"; argv[1] = "sbc"; argv[2] = "16000"; 
-        argv[3] = "1";  argv[4] = "16";  argv[5] = "/user/aiRecord.sbc";
-    }
+    // else
+    // {
+    //     argv[0] = "01"; argv[1] = "sbc"; argv[2] = "16000"; 
+    //     argv[3] = "1";  argv[4] = "16";  argv[5] = "/user/aiRecord.sbc";
+    // }
     int32_t argc = 6;
     Cur_AI_Model = type;
     if (g_audioSourceProcessInput.bThreadRun) {
+        MEDIA_ERR_LOG("g_audioSourceProcessInput.bThreadRun");
         return HandleAudioCaptureCmd(argc, argv);
     }
     std::string filePath = "";
@@ -560,6 +562,8 @@ int32_t streamingRecordAndSend_AI(int type)
         #endif
         g_audioCap.reset();
         (void)g_amInstance.DeactivateAudioInterrupt(g_sample.interrupt);
+        MEDIA_ERR_LOG("AudioCaptureSetInfo failed");
+
         goto EXIT;
     }
     g_sample.audioCaptureProcess = MediaThreadCreate(AudioCaptureProcess_AI, pfd, &attr);
@@ -572,6 +576,9 @@ EXIT:
     g_audioSourceProcessInput.bThreadRun = false;
     return -1;
 }
+
+
+
 #ifdef __cplusplus
 };
 #endif
index 452c064..55ab83a 100755 (executable)
@@ -75,6 +75,7 @@ static int32_t VoiceCallMicMute(const char **param);
 static int32_t StartHFPVoiceCall(const char **param);
 static int32_t NO_LOCAL_VOICE_CALL_RequsetAudioFocus(const char **param);
 static int32_t ReleaseAudioFocus_HFP(const char **param);
+static int32_t StartAIpaly(const char **param);
 // static int32_t updata_Audio_code_hfp(const char **param);
 
 static AudioSession g_sessionId=0;
@@ -112,7 +113,8 @@ static FuncsMap g_voiceCallVolteFuncs[] = {
     { "startSCO",StartHFPVoiceCall},
     { "stopcall",stopcall},
     // { "RequsetAudioFocus",NO_LOCAL_VOICE_CALL_RequsetAudioFocus},
-    { "ReleaseAudioFocus",ReleaseAudioFocus_HFP}
+    { "ReleaseAudioFocus",ReleaseAudioFocus_HFP},
+    { "StartAIpaly",StartAIpaly},
     // { "updata_Audio_code_hfp",updata_Audio_code_hfp}
 };
 
@@ -583,6 +585,47 @@ static int32_t NO_LOCAL_VOICE_CALL_RequsetAudioFocus(const char **param)
 }
 
 
+static int32_t AIRequsetAudioFocus(const char **param)
+{
+    bool success;
+
+    success = g_amInstance.Initialize();
+    if (!success) {
+        MEDIA_ERR_LOG("audiomanager init failed");
+        return -1;
+    }
+
+    AudioSession sessionId;
+
+    sessionId = g_amInstance.MakeSessionId();
+
+    if (sessionId == AUDIO_SESSION_ID_NONE) {
+        MEDIA_ERR_LOG("audio session id invalid");
+        return -1;
+    }
+
+
+    std::shared_ptr<VoiceCallVolteInterruptListener> interruptListener =
+        std::make_shared<VoiceCallVolteInterruptListener>((VoiceCallVolteContext*)NULL);
+    if (interruptListener == nullptr || interruptListener.get() == nullptr) {
+        MEDIA_ERR_LOG("voice call volte interrupt listener is nullptr");
+        return -1;
+    }
+
+    AudioInterrupt interrupt = { AUDIO_STREAM_VOICE_ASSISTANT, sessionId, interruptListener };
+    if (g_amInstance.ActivateAudioInterrupt(interrupt) == INTERRUPT_FAILED) {
+        MEDIA_ERR_LOG("activate audio interrupt failed");
+        return -1;
+    }
+
+    g_sessionId = sessionId;
+    g_interrupt = interrupt;
+
+
+    return 0;
+}
+
+
 
 
 #ifdef LOCAL_VOICE_CALL
@@ -1068,13 +1111,171 @@ static int32_t StartHFPVoiceCall(const char **param)
     return 0;
 }
 
+/////////////////////////////////////////////////////////////////////////////////////
 
+static int32_t ReleaseAIAudioFocus(const char **param)
+{
+    if (g_amInstance.DeactivateAudioInterrupt(g_interrupt) != 0) {
+        MEDIA_ERR_LOG("deactivate audio interrupt failed");
+        return -1;
+    }
+    g_sessionId=0;
+    MEDIA_ERR_LOG("succ ReleaseAIAudioFocus");
+    return 0;
+}
+
+static void AiDeinitVoiceCallVolteResources(VoiceCallVolteContext *context)
+{
+    (void)g_stream_out_downink.reset();
+
+    (void)MediaThreadCondDestroy(&context->cond);
+    (void)MediaMutexDestroy(&context->mutex);
+       
+    if (g_voiceCallVolteContext != nullptr) {
+        free(g_voiceCallVolteContext);
+        g_voiceCallVolteContext = nullptr;
+    }
+}
+
+
+
+static int32_t RunVoiceCallVolteAI(VoiceCallVolteContext *context)
+{
+    bool success = InitVoiceCallVolteResources(context);
+    if (!success) {
+        MEDIA_ERR_LOG("init voice call volte resources failed");
+        return -1;
+    }
+    int32_t ret ;
+
+    g_stream_out_downink = std::make_shared<AudioStreamOut>();
+    // 16000 32000 44100 48000
+    AudioRendererConfig renderConfig = {};
+    renderConfig.audioFormat =  PCM;
+    renderConfig.channelCount = 1;
+    renderConfig.linkDir = AUDIO_DOWN_LINK;
+    renderConfig.sampleRate = 16000;
+    renderConfig.sessionID = context->sessionId;
+    renderConfig.streamType = AUDIO_STREAM_VOICE_ASSISTANT;
+
+    ret = g_stream_out_downink->Init(renderConfig);
+    if (ret != 0) {
+        MEDIA_ERR_LOG("audio stream out uplink init failed");
+    }
+
+    ret = g_stream_out_downink->Play();
+    if (ret != 0) {
+        MEDIA_ERR_LOG("audio stream out downink play failed");
+    }
 
 
+    // uint32_t asiDownlinkChannelId = 0;
 
+    // MEDIA_INFO_LOG("asiDownlinkChannelId: 0x%x", asiDownlinkChannelId);
 
+    // g_stream_out_downink->AttachFrontend(asiDownlinkChannelId);
 
 
+    MediaMutexLock(context->mutex);
+    while (!context->isVoiceCallVolteStopped) {
+        MediaThreadCondWait(context->cond, context->mutex);
+    }
+    MediaMutexUnLock(context->mutex);
+
+
+    ret = g_stream_out_downink->Stop();
+    if (ret != 0) {
+        MEDIA_ERR_LOG("audio stream out downink stop failed");
+    }
+
+    ret = g_stream_out_downink->Release();
+    if (ret != 0) {
+        MEDIA_ERR_LOG("audio stream out downink release failed");
+    }
+
+
+    AiDeinitVoiceCallVolteResources(context);
+
+    return 0;
+}
+AudioSession get_ai_g_sessionId(void)
+{
+    MEDIA_ERR_LOG("get_ai_g_sessionId %d",g_sessionId);
+    return g_sessionId;
+}
+
+
+static void *VoiceAIThread(void *priv)
+{
+    VoiceCallVolteContext *context = (VoiceCallVolteContext *)priv;
+    if(g_sessionId==0)
+    {
+        AIRequsetAudioFocus(NULL);
+    }
+    context->sessionId=g_sessionId;
+    MEDIA_ERR_LOG("VoiceAIThread %d",g_sessionId);
+
+    int32_t ret = RunVoiceCallVolteAI(context);
+    if (ret != 0) {
+        MEDIA_ERR_LOG("run voice call volte failed");
+        return nullptr;
+    }
+    
+    ReleaseAIAudioFocus(NULL);
+    printf("VoiceCallVolteHFPThread END");
+    return nullptr;
+}
+
+
+
+int32_t AIStreamWrite(uint8_t *buf,uint32_t size)
+{
+    int32_t ret;
+
+    uint64_t writeLen = 0;
+    AudioRendererConfig renderConfig;
+    ret = g_stream_out_downink->StreamWrite(buf,size, writeLen, renderConfig);
+
+    return ret;
+}
+
+
+
+
+static int32_t StartAIpaly(const char **param)
+{
+    MediaMutexLock(g_voiceCallVolteContextMutex);
+    if (g_voiceCallVolteContext != nullptr) {
+        MEDIA_ERR_LOG("invalid operation");
+        return -1;
+    }
+
+    // 1. create VoiceCallVolteContext
+    g_voiceCallVolteContext = (VoiceCallVolteContext *)malloc(sizeof(VoiceCallVolteContext));
+    if (g_voiceCallVolteContext == nullptr) {
+        MEDIA_ERR_LOG("malloc failed");
+        MediaMutexUnLock(g_voiceCallVolteContextMutex);
+        return -1;
+    }
+    if (memset_s(g_voiceCallVolteContext, sizeof(VoiceCallVolteContext), 0, sizeof(VoiceCallVolteContext)) != EOK) {
+        MEDIA_ERR_LOG("memset_s failed");
+    }
+    MediaMutexUnLock(g_voiceCallVolteContextMutex);
+
+    // 3. create voice call volte thread
+    MediaThreadattr attr = { "VoiceCallVolteHFPThread", 0x2000, THREAD_SCHED_INVALID, 0, false };
+    g_voiceCallVolteContext->taskHandle  = MediaThreadCreate(VoiceAIThread, g_voiceCallVolteContext, &attr);
+    if ( g_voiceCallVolteContext->taskHandle == nullptr) {
+        MEDIA_ERR_LOG("create voice call volte  thread failed");
+        free(g_voiceCallVolteContext);
+        g_voiceCallVolteContext = nullptr;
+        return -1;
+    }
+
+    // will free g_voiceCallVolteContext when sub thread play exit
+    return 0;
+}
+
 
 
 
index bfeb415..8a1f455 100755 (executable)
@@ -9,6 +9,7 @@
 #define VOICE_CALL_VOLTE_SAMPLE_WRAPPER_H
 
 #include <stdint.h>
+#include "audio_base_type.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -18,6 +19,10 @@ int32_t VoiceCallVolteSample(int32_t argc, const char *argv[]);
 
 void updata_Audio_code_hfp(uint32_t type);
 
+int32_t AIStreamWrite(uint8_t *buf,uint32_t size);
+
+AudioSession get_ai_g_sessionId(void);
+
 #ifdef __cplusplus
 };
 #endif
index 2891ef1..2e767db 100644 (file)
       
 #define HTTPC_REQ_11_HOST_FORMAT_POST(uri, srv_name, arglen, args) HTTPC_REQ_11_HOST_POST, uri, HTTPC_CLIENT_AGENT, srv_name, arglen, args
 
+////////////////////////////////////////PUT报文///////////////////////////////////////////////////
+/* PUT request basic */  
+#define HTTPC_REQ_11_PUT "PUT %s HTTP/1.1\r\n" /* URI */\
+    "User-Agent: %s\r\n" /* User-Agent */ \
+    "Accept: */*\r\n" \
+    "Content-Type: application/json\r\n" \
+    "Content-Length: %d\r\n" \
+    "Connection: Close\r\n" /* we don't support persistent connections, yet */\
+    "\r\n" \
+    "%s"
+      
+#define HTTPC_REQ_11_FORMAT_PUT(uri, arglen, args)  HTTPC_REQ_11_PUT, uri, HTTPC_CLIENT_AGENT, arglen, args
+      
+//       PUT /api/user HTTP/1.1
+// Host: example.com
+// Content-Type: application/json
+// Content-Length: 123
+
+// {
+// "id": 123,
+// "name": "John Doe",
+// "email": "johndoe@example.com",
+// "age": 30
+// }
+/* PUT request with host */
+#define HTTPC_REQ_11_HOST_PUT "PUT %s HTTP/1.1\r\n" /* URI */\
+    "User-Agent: %s\r\n" /* User-Agent */ \
+    "Accept: */*\r\n" \
+    "Host: %s\r\n" /* server name */ \
+    "Content-Type: application/json\r\n" \
+    "Content-Length: %d\r\n" \
+    "Connection: Close\r\n" /* we don't support persistent connections, yet */ \
+    "\r\n" \
+    "%s"
+      
+#define HTTPC_REQ_11_HOST_FORMAT_PUT(uri, srv_name, arglen, args) HTTPC_REQ_11_HOST_PUT, uri, HTTPC_CLIENT_AGENT, srv_name, arglen, args
+
+
+
 typedef enum ehttpc_parse_state {
   HTTPC_PARSE_WAIT_FIRST_LINE = 0,
   HTTPC_PARSE_WAIT_HEADERS,
@@ -546,11 +585,23 @@ httpc_create_request_string(const httpc_connection_t *settings, const char* serv
                  return snprintf(buffer, buffer_size, HTTPC_REQ_11_HOST_FORMAT_POST(uri, server_name, settings->arglen, settings->args));
       // printf("%s\r\n",buffer);
          }
+    if (settings->use_put)
+    {
+                 return snprintf(buffer, buffer_size, HTTPC_REQ_11_HOST_FORMAT_PUT(uri, server_name, settings->arglen, settings->args));
+      // printf("%s\r\n",buffer);
+         }
+
     return snprintf(buffer, buffer_size, HTTPC_REQ_11_HOST_FORMAT(uri, server_name));
   } 
   else 
   {
 
+     if (settings->use_put)
+    {
+                 return snprintf(buffer, buffer_size, HTTPC_REQ_11_HOST_FORMAT_PUT(uri, server_name, settings->arglen, settings->args));
+      // printf("%s\r\n",buffer);
+         }
+
     if (settings->use_post){
        return snprintf(buffer, buffer_size, HTTPC_REQ_11_FORMAT_POST(uri, settings->arglen, settings->args));
       
@@ -631,7 +682,8 @@ httpc_init_connection_common(httpc_state_t **connection, const httpc_connection_
   /* set up request buffer */
   req_len2 = httpc_create_request_string(settings, server_name, server_port, uri, use_host,
     (char *)req->request->payload, req_len + 1);
-  // printf("%s\r\n",(char *)req->request->payload);
+  printf("%s\r\n",(char *)req->request->payload);
+
   if (req_len2 != req_len) {
     httpc_free_state(req);
     return ERR_VAL;