--- /dev/null
+
+
+
+#include "os_api.h"
+#include "sci_types.h"
+#include "mmk_app.h"
+#include "http_api.h"
+#include "version.h"
+#include "IN_Message.h"
+#include "mmi_appmsg.h"
+
+#include <socket_api.h>
+
+#include "mn_type.h"
+#include "mmk_type.h"
+#include "mmk_timer.h"
+#include "mmi_module.h"
+#include "mmiconnection_export.h"
+#include "mmiphone_export.h"
+#include "mmipdp_export.h"
+#include "mmi_aigc_net.h"
+
+
+#ifdef MMI_CUSTOM_AIGC_SUPPORT
+
+static char * s_aigc_server_ip = "118.145.158.207"; // amp.raisound.com
+static uint32 s_aigc_server_port = 80;
+static char * s_aigc_ws_url = "ws://118.145.158.207:80/tts/stream";
+
+static TCPIP_NETID_T s_aigc_net_id = 0;
+static TCPIP_SOCKET_T s_aigc_net_socket_id = TCPIP_SOCKET_INVALID;
+static BLOCK_ID s_aigc_socket_task_id = SCI_INVALID_BLOCK_ID;
+
+static char s_aigc_net_recv_data[MMI_AIGC_SOCKET_DATA_BUFFER_SIZE] = {0};
+static uint32 s_aigc_net_recv_len = 0;
+static char s_aigc_net_send_data[MMI_AIGC_SOCKET_DATA_BUFFER_SIZE] = {0};
+static uint32 s_aigc_net_send_len = 0;
+
+#if defined(MMI_GPRS_SUPPORT)
+#endif
+
+static void mmi_aigc_socket_gethostbyname(void);
+static int mmi_aigc_socket_create(unsigned long ip_addr);
+static void mmi_aigc_socket_data_send(void);
+static void mmi_aigc_socket_data_recv(void);
+static void mmi_aigc_socket_connected(void);
+
+
+
+static void mmi_aigc_socket_task_handle(void * sig_ptr)
+{
+ uint32 msg_id = ((xSignalHeaderRec *)sig_ptr)->SignalCode;
+ TCPIP_SOCKET_T socket_id = -1;
+ int32 socket_error = 0;
+ int socket_ret = 0;
+
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: msg_id=%d\n",__FUNCTION__,__LINE__, msg_id);
+ switch(msg_id)
+ {
+ case SOCKET_READ_EVENT_IND:
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: SOCKET_READ_EVENT_IND\n", __FUNCTION__, __LINE__);
+ socket_id = ((SOCKET_READ_EVENT_IND_SIG_T *)sig_ptr)->socket_id;
+ SCI_MEMSET(s_aigc_net_recv_data, 0x0, MMI_AIGC_SOCKET_DATA_BUFFER_SIZE);
+ socket_ret = sci_sock_recv(socket_id, s_aigc_net_recv_data, MMI_AIGC_SOCKET_DATA_BUFFER_SIZE, 0);
+ if(0 > socket_ret)
+ {
+ // recv fail
+ socket_error = sci_sock_errno(socket_id);
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: socket_error=%d\n", __FUNCTION__, __LINE__, socket_error);
+ }
+ else if(0 < socket_ret)
+ {
+ s_aigc_net_recv_len = socket_ret;
+ mmi_aigc_socket_data_recv();
+ }
+ else
+ {
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: connection close\n", __FUNCTION__, __LINE__);
+ }
+ break;
+
+ case SOCKET_WRITE_EVENT_IND:
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: SOCKET_WRITE_EVENT_IND\n", __FUNCTION__, __LINE__);
+ socket_id = ((SOCKET_WRITE_EVENT_IND_SIG_T *)sig_ptr)->socket_id;
+ socket_ret = sci_sock_send(socket_id, s_aigc_net_send_data, s_aigc_net_send_len, 0);
+ if(0 > socket_ret)
+ {
+ // send fail
+ socket_error = sci_sock_errno(socket_id);
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: socket_error=%d\n", __FUNCTION__, __LINE__, socket_error);
+ }
+ else
+ {
+ s_aigc_net_send_len -= socket_ret;
+ if(0 < s_aigc_net_send_len)
+ {
+ // part data send
+ char * temp_ptr = SCI_ALLOC_APPZ(s_aigc_net_send_len);
+ if(PNULL == temp_ptr)
+ {
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: memory alloc fail\n", __FUNCTION__, __LINE__);
+ return;
+ }
+ SCI_MEMSET(temp_ptr, 0x0, s_aigc_net_send_len);
+ SCI_MEMCPY(temp_ptr, s_aigc_net_send_data + socket_ret, s_aigc_net_send_len);
+
+ SCI_MEMSET(s_aigc_net_send_data, 0x0, MMI_AIGC_SOCKET_DATA_BUFFER_SIZE);
+ SCI_MEMCPY(s_aigc_net_send_data, temp_ptr, s_aigc_net_send_len);
+
+ SCI_FREE(temp_ptr);
+ temp_ptr = PNULL;
+ }
+ else
+ {
+ // all data send
+ SCI_MEMSET(s_aigc_net_send_data, 0x0, MMI_AIGC_SOCKET_DATA_BUFFER_SIZE);
+ }
+ }
+ break;
+
+ case SOCKET_CONNECT_EVENT_IND:
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: SOCKET_CONNECT_EVENT_IND\n", __FUNCTION__, __LINE__);
+ socket_id = ((SOCKET_CONNECT_EVENT_IND_SIG_T *)sig_ptr)->socket_id;
+ socket_error = ((SOCKET_CONNECT_EVENT_IND_SIG_T *)sig_ptr)->error_code;
+
+ mmi_aigc_socket_connected();
+ break;
+
+ case SOCKET_FULL_CLOSED_EVENT_IND:
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: SOCKET_FULL_CLOSED_EVENT_IND\n", __FUNCTION__, __LINE__);
+ socket_id = ((SOCKET_FULL_CLOSED_EVENT_IND_SIG_T *)sig_ptr)->socket_id;
+
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void mmi_aigc_socket_task_entry(uint32 argc, void *argv)
+{
+ if(SCI_INVALID_BLOCK_ID == s_aigc_socket_task_id)
+ {
+ return;
+ }
+
+ while(1)
+ {
+ // receive message
+ MMI_AIGC_NET_DATA_SIG_T * sig_ptr = (MMI_AIGC_NET_DATA_SIG_T *)SCI_GetSignal(s_aigc_socket_task_id);
+ if(PNULL != sig_ptr)
+ {
+ mmi_aigc_socket_task_handle(sig_ptr);
+
+ if(PNULL != sig_ptr->data_ptr)
+ SCI_FREE(sig_ptr->data_ptr);
+ SCI_FREE(sig_ptr);
+ sig_ptr = PNULL;
+ }
+ }
+
+ SCI_ThreadExit();
+}
+
+static void mmi_aigc_socket_task_create(void)
+{
+ if(SCI_INVALID_BLOCK_ID != s_aigc_socket_task_id)
+ return;
+
+ s_aigc_socket_task_id = SCI_CreateThread("T_AIGC_SOCKET_TASK",
+ "Q_AIGC_SOCKET_TASK",
+ mmi_aigc_socket_task_entry,
+ 0,
+ 0,
+ MMI_AIGC_SOCKET_TASK_STACK_SIZE,
+ MMI_AIGC_SOCKET_TASK_MSG_QUEUE_SIZE,
+ MMI_AIGC_SOCKET_TASK_PRIORITY,
+ SCI_PREEMPT,
+ SCI_AUTO_START);
+
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: task_id=0x%x\n",__FUNCTION__,__LINE__, s_aigc_socket_task_id);
+}
+
+
+static void mmi_aigc_pdp_msg_cb(MMIPDP_CNF_INFO_T * msg_ptr)
+{
+ if(PNULL == msg_ptr)
+ {
+ return;
+ }
+
+ switch(msg_ptr->msg_id)
+ {
+ case MMIPDP_ACTIVE_CNF:
+ if (MMIPDP_RESULT_SUCC == msg_ptr->result)
+ {
+ mmi_aigc_socket_task_create();
+ s_aigc_net_id = msg_ptr->nsapi;
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: net_id=%d\n", __FUNCTION__, __LINE__, s_aigc_net_id);
+ mmi_aigc_socket_gethostbyname();
+ }
+ else
+ {
+ MMIAPIPDP_Deactive(msg_ptr->app_handler);
+ }
+ break;
+
+ case MMIPDP_DEACTIVE_CNF:
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+ s_aigc_net_id = 0;
+ break;
+
+ case MMIPDP_DEACTIVE_IND:
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+ s_aigc_net_id = 0;
+ break;
+
+ default:
+ break;
+ }
+}
+
+static BOOLEAN mmi_aigc_pdp_active(void)
+{
+ MN_DUAL_SYS_E dual_sys = MN_DUAL_SYS_1;
+ uint8 index = 0;
+ uint8 linkset_num = 0;
+ MMIPDP_ACTIVE_INFO_T active_info = {0};
+ MMICONNECTION_LINKSETTING_DETAIL_T * linksetting = PNULL;
+
+ if (FALSE == MMIAPIPHONE_GetDataServiceSIM(&dual_sys))
+ {
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+ goto __EXIT;
+ }
+
+ linkset_num = MMIAPICONNECTION_GetLinkSettingNum(dual_sys);
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: linkset_num=%d\n", __FUNCTION__, __LINE__, linkset_num);
+ if(0 < linkset_num)
+ {
+ MMICONNECTION_APNTYPEINDEX_T * apn_type_index = MMIAPICONNECTION_GetApnTypeIndex(dual_sys);
+ if ((PNULL != apn_type_index) && (TRUE == apn_type_index->internet_index[dual_sys].is_valid))
+ {
+ index = apn_type_index->internet_index[dual_sys].index;
+ }
+ else
+ {
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+ goto __EXIT;
+ }
+
+ linksetting = MMIAPICONNECTION_GetLinkSettingItemByIndex(dual_sys, index);
+ if(PNULL != linksetting && 0 != linksetting->apn_len)
+ {
+ active_info.dual_sys = dual_sys;
+ active_info.auth_type = linksetting->auth_type;
+ active_info.priority = 3;
+ active_info.app_handler = MMI_MODULE_AIGC;
+ active_info.handle_msg_callback = mmi_aigc_pdp_msg_cb;
+ active_info.apn_ptr = linksetting->apn;
+ active_info.user_name_ptr = linksetting->username;
+ active_info.psw_ptr = linksetting->password;
+ active_info.ps_service_rat = MN_UNSPECIFIED;
+ active_info.ps_service_type = STREAMING_E; // BROWSER_E; // STREAMING_E
+ active_info.storage = MN_GPRS_STORAGE_ALL;
+ active_info.ps_interface = MMIPDP_INTERFACE_GPRS;
+ #ifdef IPVERSION_SUPPORT_V4_V6
+ active_info.ip_type = linksetting->ip_type;
+ #endif
+
+ if(MMIAPIPDP_Active(&active_info))
+ {
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+ return TRUE;
+ }
+ }
+ }
+
+__EXIT:
+ return FALSE;
+}
+
+
+/*
+static void mmi_aigc_socket_task_msg_send(MMI_AIGC_NET_MSG_ID_E msg_id, void * param, uint32 param_size)
+{
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: msg_id=%d\n",__FUNCTION__,__LINE__, msg_id);
+
+ if(SCI_INVALID_BLOCK_ID != s_aigc_socket_task_id)
+ {
+ MMI_AIGC_NET_DATA_SIG_T * signal = PNULL;
+ void * temp_ptr = PNULL;
+
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+ if(NULL != param && 0 != param_size)
+ {
+ temp_ptr = SCI_ALLOC_APPZ(param_size + 1);
+ if(NULL == temp_ptr)
+ {
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: memory alloc fail\n", __FUNCTION__, __LINE__);
+ return;
+ }
+ SCI_MEMSET(temp_ptr, 0x0, param_size + 1);
+ SCI_MEMCPY(temp_ptr, param, param_size);
+ }
+
+ signal = SCI_ALLOC_APPZ(sizeof (MMI_AIGC_NET_DATA_SIG_T));
+ SCI_MEMSET(signal, 0x0, sizeof (MMI_AIGC_NET_DATA_SIG_T));
+ signal->SignalCode = msg_id;
+ signal->SignalSize = sizeof (MMI_AIGC_NET_DATA_SIG_T);
+ signal->Sender = SCI_IdentifyThread();
+ signal->data_ptr = temp_ptr;
+ signal->data_size = param_size;
+ SCI_SendSignal (signal, s_aigc_socket_task_id);
+ }
+}
+*/
+
+
+void mmi_aigc_net_close(void)
+{
+ if(TCPIP_SOCKET_INVALID != s_aigc_net_socket_id)
+ {
+ int socket_ret = sci_sock_socketclose(s_aigc_net_socket_id);
+ if(0 > socket_ret)
+ {
+ int32 socket_error = sci_sock_errno(s_aigc_net_socket_id);
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: socket_error=%d\n", __FUNCTION__, __LINE__, socket_error);
+ }
+ }
+
+ if(SCI_INVALID_BLOCK_ID != s_aigc_socket_task_id)
+ {
+ SCI_DeleteThread(s_aigc_socket_task_id);
+ s_aigc_socket_task_id = SCI_INVALID_BLOCK_ID;
+ }
+
+ //deative pdp
+ MMIAPIPDP_Deactive(MMI_MODULE_AIGC);
+
+}
+
+static void mmi_aigc_socket_gethostbyname(void)
+{
+#if 0
+ TCPIP_HOST_HANDLE host_handle = 0;
+
+ host_handle = sci_async_gethostbyname(s_aigc_server_ip, s_aigc_socket_task_id, 20000, s_aigc_net_id);
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: host_handle=%d\n", __FUNCTION__, __LINE__, host_handle);
+ if(0 == host_handle)
+ {
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: fail\n", __FUNCTION__, __LINE__);
+
+ }
+#endif
+
+ mmi_aigc_socket_create(0);
+}
+
+static int mmi_aigc_socket_create(unsigned long ip_addr)
+{
+ TCPIP_SOCKET_T socket_id = TCPIP_SOCKET_INVALID;
+ struct sci_sockaddr socker_addr = {0};
+ int32 socket_error = 0;
+ int buf_size = 0;
+ int socket_result = 0;
+ int connect_ret = 0;
+ int i = 0;
+
+ socket_id = sci_sock_socket(AF_INET, SOCK_STREAM, 0, s_aigc_net_id);
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: socket_id=%d\n", __FUNCTION__, __LINE__, socket_id);
+ if (TCPIP_SOCKET_INVALID == socket_id)
+ {
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: socket create fail\n", __FUNCTION__, __LINE__);
+ goto result_msg;
+ }
+ s_aigc_net_socket_id = socket_id;
+
+ buf_size = MMI_AIGC_SOCKET_DATA_BUFFER_SIZE;
+ sci_sock_setsockopt(socket_id, SO_SNDBUF, &buf_size);
+ sci_sock_setsockopt(socket_id, SO_RCVBUF, &buf_size);
+
+ if(TCPIP_SOCKET_ERROR == sci_sock_setsockopt(socket_id, SO_NBIO, NULL))
+ {
+ socket_error = sci_sock_errno(socket_id);
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: socket_error=%d\n", __FUNCTION__, __LINE__, socket_error);
+ }
+
+ if ( TCPIP_SOCKET_ERROR == sci_sock_asyncselect(socket_id, s_aigc_socket_task_id, AS_CONNECT|AS_CLOSE|AS_READ|AS_WRITE | AS_FULLCLOSED))
+ {
+ socket_error = sci_sock_errno(socket_id);
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: socket_error=%d\n", __FUNCTION__, __LINE__, socket_error);
+ goto close_msg;
+ }
+
+ if(0 == ip_addr)
+ {
+ unsigned long ip_addr_ext = 0;
+ if(1 == inet_aton(s_aigc_server_ip, &ip_addr_ext))
+ {
+ socker_addr.ip_addr = ip_addr_ext;
+ }
+ else
+ {
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: ip error\n", __FUNCTION__, __LINE__);
+ goto close_msg;
+ }
+ }
+ else
+ {
+ socker_addr.ip_addr = ip_addr;
+ }
+ socker_addr.family = AF_INET;
+ socker_addr.port = htons(s_aigc_server_port);
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: ip=%d,port=%d\n", __FUNCTION__, __LINE__, socker_addr.ip_addr, socker_addr.port);
+
+ for(i = 0; i < 10; i++)
+ {
+ connect_ret = sci_sock_connect(socket_id, &socker_addr, sizeof(struct sci_sockaddr));
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: connect_ret=%d\n", __FUNCTION__, __LINE__, connect_ret);
+ if(SCI_SUCCESS == connect_ret)
+ {
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: connect success\n", __FUNCTION__, __LINE__);
+ goto result_msg;
+ }
+ else
+ {
+ socket_error = sci_sock_errno(socket_id);
+ if((socket_error == EINPROGRESS) || (socket_error == EWOULDBLOCK))
+ {
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: connect wait\n", __FUNCTION__, __LINE__);
+ }
+ else
+ {
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: connect fail\n", __FUNCTION__, __LINE__);
+ goto close_msg;
+ }
+ }
+
+ SCI_Sleep(50);
+ }
+
+result_msg:
+ return socket_result;
+
+close_msg:
+ sci_sock_socketclose(s_aigc_net_socket_id);
+ s_aigc_net_socket_id = TCPIP_SOCKET_INVALID;
+ return socket_result;
+}
+
+static void mmi_aigc_socket_data_send(void)
+{
+
+}
+
+static void mmi_aigc_socket_data_recv(void)
+{
+ // store recv data
+
+
+ // process recv data
+ {
+ static MMI_AIGC_WS_FRAME_STATE_T s_ws_frame_t = {0};
+
+ if(0 == s_ws_frame_t.payload_len && 0 == s_ws_frame_t.remain_len)
+ {
+ memset(s_ws_frame_t, 0x0, sizeof(MMI_AIGC_WS_FRAME_STATE_T));
+ }
+
+ mmi_wb_data_process(&s_ws_frame_t, data_ptr, data_len);
+ }
+}
+
+static void mmi_aigc_socket_connected(void)
+{
+ char * buffer = PNULL;
+
+
+
+ mmi_wb_connect(buffer, url, ip, port);
+
+
+
+
+}
+
+
+
+
+
+
+void __aigc_net_test(void)
+{
+ mmi_aigc_pdp_active();
+}
+
+
+#if 0
+LOCAL void __HandlePdpEvent(MN_DUAL_SYS_E dual_sys, MMIPDP_NOTIFY_EVENT_E notify_event)
+{
+ if(MMIPDP_NOTIFY_EVENT_ACTIVED == notify_event)
+ {
+ SCI_TraceLow("[MMISPM] MMIPDP_NOTIFY_EVENT_ACTIVED");
+ }
+}
+
+PUBLIC void __InitModule(void)
+{
+ MMIPDP_NOTIFY_EVENT_E pdp_event[MMIPDP_NOTIFY_EVENT_MAX] = {
+ MMIPDP_NOTIFY_EVENT_ACTIVED,
+ MMIPDP_NOTIFY_EVENT_DEACTIVED,
+ MMIPDP_NOTIFY_EVENT_ATTACH,
+ MMIPDP_NOTIFY_EVENT_DETTACH
+ };
+
+ MMIAPIPDP_SubscribeEvent(MMI_MODULE_SPM,
+ __HandlePdpEvent,
+ MMIPDP_NOTIFY_EVENT_MAX,
+ (MMIPDP_NOTIFY_EVENT_E *)pdp_event);
+}
+#endif
+
+#endif
+
--- /dev/null
+
+
+
+#include "os_api.h"
+#include "sci_types.h"
+#include "mmk_app.h"
+#include "http_api.h"
+#include "version.h"
+#include "IN_Message.h"
+#include "mmi_appmsg.h"
+
+#include <socket_api.h>
+
+#include "mn_type.h"
+#include "mmk_type.h"
+#include "mmk_timer.h"
+#include "mmi_module.h"
+#include "mmiconnection_export.h"
+#include "mmiphone_export.h"
+#include "mmipdp_export.h"
+#include "mmi_aigc_net_common.h"
+
+
+#ifdef MMI_CUSTOM_AIGC_SUPPORT
+
+int mmi_wb_random_get(void * buf, uint32 len)
+{
+ uint8 * buf_bytes = (uint8 *)buf;
+
+ if (PNULL == buf || 0 == len)
+ {
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: param error\n",__FUNCTION__,__LINE__);
+ return -1;
+ }
+
+ while (len > 0)
+ {
+ int word = rand();
+ uint32 to_copy = MIN(sizeof(word), len);
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: random word=%d\n",__FUNCTION__,__LINE__, word);
+
+ SCI_MEMCPY(buf_bytes, &word, to_copy);
+ buf_bytes += to_copy;
+ len -= to_copy;
+ }
+
+ return len;
+}
+
+int mmi_tcp_send(char * data_ptr, int date_len)
+{
+ int ret = 0;
+
+
+ return ret;
+}
+
+int mmi_wb_connect(char * buffer, char * url, char * ip, uint32 port)
+{
+ uint8 random_key[16] = {0};
+ // Size of base64 coded string is equal '((input_size * 4) / 3) + (input_size / 96) + 6' including Z-term
+ uint8 client_key[28] = {0};
+ uint32 outlen = 0;
+ int len = 0;
+
+ if(PNULL == buffer || PNULL == url || PNULL == ip || NULL == port)
+ {
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: param error\n",__FUNCTION__,__LINE__);
+ return -1;
+ }
+
+ mmi_wb_random_get(random_key, sizeof(random_key));
+ mbedtls_base64_encode(client_key, sizeof(client_key), &outlen, random_key, sizeof(random_key));
+
+ len = sprintf(buffer,
+ /*"GET /?encoding=text HTTP/1.1\r\n"*/
+ "GET %s HTTP/1.1\r\n"
+ "Host: %s:%d\r\n"
+ "Connection: Upgrade\r\n"
+ "Pragma: no-cache\r\n"
+ "Cache-Control: no-cache\r\n"
+ "User-Agent: Websocket Client\r\n"
+ "Upgrade: websocket\r\n"
+ ////"Origin: http://oktools.net\r\n"
+ "Sec-WebSocket-Version: 13\r\n"
+ "Accept-Encoding: gzip, deflate\r\n"
+ "Accept-Language: zh-CN,zh;q=0.9\r\n"
+ "Sec-WebSocket-Key: %s\r\n"
+ "Sec-Websocket-Extensions: permessage-deflate; client_max_window_bits\r\n",
+ s_aigc_ws_url,
+ s_aigc_server_ip,
+ s_aigc_server_port,
+ client_key);
+
+
+
+static int ws_connect(wb_esp_transport_handle_t t, const char *host, int port, int timeout_ms)
+{
+ transport_ws_t *ws = wb_esp_transport_get_context_data(t);
+ if (wb_esp_transport_connect(ws->parent, host, port, timeout_ms) < 0) {
+ ESP_LOGE("Error connecting to host %s:%d", host, port);
+ return -1;
+ }
+
+ unsigned char random_key[16];
+ wb_getrandom(random_key, sizeof(random_key), 0);
+ //ESP_LOGE("random_key: %s", random_key);
+
+ // Size of base64 coded string is equal '((input_size * 4) / 3) + (input_size / 96) + 6' including Z-term
+ unsigned char client_key[28] = {0};
+
+ size_t outlen = 0;
+ mbedtls_base64_encode(client_key, sizeof(client_key), &outlen, random_key, sizeof(random_key));
+ int len = snprintf(ws->buffer, DEFAULT_WS_BUFFER,
+ /*"GET /?encoding=text HTTP/1.1\r\n"*/
+ "GET %s HTTP/1.1\r\n"
+ "Host: %s:%d\r\n"
+ "Connection: Upgrade\r\n"
+ "Pragma: no-cache\r\n"
+ "Cache-Control: no-cache\r\n"
+ "User-Agent: ASR Websocket Client\r\n"
+ "Upgrade: websocket\r\n"
+ "Origin: http://oktools.net\r\n"
+ "Sec-WebSocket-Version: 13\r\n"
+ "Accept-Encoding: gzip, deflate\r\n"
+ "Accept-Language: zh-CN,zh;q=0.9\r\n"
+ "Sec-WebSocket-Key: %s\r\n"
+ "Sec-Websocket-Extensions: permessage-deflate; client_max_window_bits\r\n",
+ //"\r\n",
+ ws->path,
+ host,
+ port,
+ client_key);
+ if (len <= 0 || len >= DEFAULT_WS_BUFFER) {
+ ESP_LOGE("Error in request generation, %d", len);
+ return -1;
+ }
+ if (ws->sub_protocol) {
+ int r = snprintf(ws->buffer + len, DEFAULT_WS_BUFFER - len, "Sec-WebSocket-Protocol: %s\r\n", ws->sub_protocol);
+ len += r;
+ if (r <= 0 || len >= DEFAULT_WS_BUFFER) {
+ ESP_LOGE("Error in request generation"
+ "(snprintf of subprotocol returned %d, desired request len: %d, buffer size: %d", r, len, DEFAULT_WS_BUFFER);
+ return -1;
+ }
+ }
+ int r = snprintf(ws->buffer + len, DEFAULT_WS_BUFFER - len, "\r\n");
+ len += r;
+ if (r <= 0 || len >= DEFAULT_WS_BUFFER) {
+ ESP_LOGE("Error in request generation"
+ "(snprintf of header terminal returned %d, desired request len: %d, buffer size: %d", r, len, DEFAULT_WS_BUFFER);
+ return -1;
+ }
+ ESP_LOGD("%s, len is %d and Write upgrate request\r\n%s", __FUNCTION__, len, ws->buffer);
+ if (wb_esp_transport_write(ws->parent, ws->buffer, len, timeout_ms) <= 0) {
+ ESP_LOGE("Error write Upgrade header %s", ws->buffer);
+ return -1;
+ }
+ int header_len = 0;
+ do {
+ if ((len = wb_esp_transport_read(ws->parent, ws->buffer + header_len, DEFAULT_WS_BUFFER - header_len, timeout_ms)) <= 0) {
+ ESP_LOGE("Error read response for Upgrade header %s", ws->buffer);
+ return -1;
+ }
+ header_len += len;
+ ws->buffer[header_len] = '\0';
+ ESP_LOGD("Read header chunk %d, current header size: %d", len, header_len);
+ } while (NULL == strstr(ws->buffer, "\r\n\r\n") && header_len < DEFAULT_WS_BUFFER);
+
+ char *server_key = get_http_header(ws->buffer, "Sec-WebSocket-Accept:");
+ if (server_key == NULL) {
+ ESP_LOGE("Sec-WebSocket-Accept not found");
+ return -1;
+ }
+
+ // See mbedtls_sha1_ret() arg size
+ unsigned char expected_server_sha1[20];
+ // Size of base64 coded string see above
+ unsigned char expected_server_key[33] = {0};
+ // If you are interested, see https://tools.ietf.org/html/rfc6455
+ const char expected_server_magic[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+ unsigned char expected_server_text[sizeof(client_key) + sizeof(expected_server_magic) + 1];
+ strcpy((char*)expected_server_text, (char*)client_key);
+ strcat((char*)expected_server_text, expected_server_magic);
+
+ size_t key_len = strlen((char*)expected_server_text);
+ mbedtls_sha1_ret(expected_server_text, key_len, expected_server_sha1);
+ mbedtls_base64_encode(expected_server_key, sizeof(expected_server_key), &outlen, expected_server_sha1, sizeof(expected_server_sha1));
+ expected_server_key[ (outlen < sizeof(expected_server_key)) ? outlen : (sizeof(expected_server_key) - 1) ] = 0;
+ ESP_LOGD("server key=%s, send_key=%s, expected_server_key=%s", (char *)server_key, (char*)client_key, expected_server_key);
+ if (strcmp((char*)expected_server_key, (char*)server_key) != 0) {
+ ESP_LOGE("Invalid websocket key");
+ return -1;
+ }
+ return 0;
+}
+
+
+
+
+}
+
+int mmi_wb_send(int opcode, const char * data, int len)
+{
+ char * buffer = (char *)data;
+ char ws_header[MAX_WEBSOCKET_HEADER_SIZE] = {0};
+ char * mask = PNULL;
+ int mask_flag = MMI_AIGC_WS_MASK;
+ int header_len = 0, i = 0;
+ int ret = 0;
+
+ opcode |= MMI_AIGC_WS_OPCODES_FIN;
+
+ header_len = 0;
+ ws_header[header_len++] = opcode;
+
+ if (len <= 125)
+ {
+ ws_header[header_len++] = (uint8_t)(len | mask_flag);
+ }
+ else if (len < 65536)
+ {
+ ws_header[header_len++] = MMI_AIGC_WS_SIZE16 | mask_flag;
+ ws_header[header_len++] = (uint8_t)(len >> 8);
+ ws_header[header_len++] = (uint8_t)(len & 0xFF);
+ }
+ else
+ {
+ ws_header[header_len++] = MMI_AIGC_WS_SIZE64 | mask_flag;
+ /* Support maximum 4 bytes length */
+ ws_header[header_len++] = 0; //(uint8_t)((len >> 56) & 0xFF);
+ ws_header[header_len++] = 0; //(uint8_t)((len >> 48) & 0xFF);
+ ws_header[header_len++] = 0; //(uint8_t)((len >> 40) & 0xFF);
+ ws_header[header_len++] = 0; //(uint8_t)((len >> 32) & 0xFF);
+ ws_header[header_len++] = (uint8_t)((len >> 24) & 0xFF);
+ ws_header[header_len++] = (uint8_t)((len >> 16) & 0xFF);
+ ws_header[header_len++] = (uint8_t)((len >> 8) & 0xFF);
+ ws_header[header_len++] = (uint8_t)((len >> 0) & 0xFF);
+ }
+
+ if(mmi_tcp_send(ws_header, header_len) != header_len)
+ {
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: send error\n",__FUNCTION__,__LINE__);
+ return -1;
+ }
+
+ if (0 == len)
+ {
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: no data\n",__FUNCTION__,__LINE__);
+ return 0;
+ }
+
+ if (mask_flag)
+ {
+ mask = &ws_header[header_len];
+ mmi_wb_random_get(ws_header + header_len, 4);
+ header_len += 4;
+
+ for (i = 0; i < len; ++i) {
+ buffer[i] = (buffer[i] ^ mask[i % 4]);
+ }
+ }
+
+ ret = mmi_tcp_send(buffer, len);
+ // in case of masked transport we have to revert back to the original data, as ws layer
+ // does not create its own copy of data to be sent
+ if (mask_flag)
+ {
+ mask = &ws_header[header_len-4];
+ for (i = 0; i < len; ++i) {
+ buffer[i] = (buffer[i] ^ mask[i % 4]);
+ }
+ }
+
+ return ret;
+}
+
+
+
+static int ws_connect(wb_esp_transport_handle_t t, const char *host, int port, int timeout_ms)
+{
+ transport_ws_t *ws = wb_esp_transport_get_context_data(t);
+ if (wb_esp_transport_connect(ws->parent, host, port, timeout_ms) < 0) {
+ ESP_LOGE("Error connecting to host %s:%d", host, port);
+ return -1;
+ }
+
+ unsigned char random_key[16];
+ wb_getrandom(random_key, sizeof(random_key), 0);
+ //ESP_LOGE("random_key: %s", random_key);
+
+ // Size of base64 coded string is equal '((input_size * 4) / 3) + (input_size / 96) + 6' including Z-term
+ unsigned char client_key[28] = {0};
+
+ size_t outlen = 0;
+ mbedtls_base64_encode(client_key, sizeof(client_key), &outlen, random_key, sizeof(random_key));
+ int len = snprintf(ws->buffer, DEFAULT_WS_BUFFER,
+ /*"GET /?encoding=text HTTP/1.1\r\n"*/
+ "GET %s HTTP/1.1\r\n"
+ "Host: %s:%d\r\n"
+ "Connection: Upgrade\r\n"
+ "Pragma: no-cache\r\n"
+ "Cache-Control: no-cache\r\n"
+ "User-Agent: ASR Websocket Client\r\n"
+ "Upgrade: websocket\r\n"
+ "Origin: http://oktools.net\r\n"
+ "Sec-WebSocket-Version: 13\r\n"
+ "Accept-Encoding: gzip, deflate\r\n"
+ "Accept-Language: zh-CN,zh;q=0.9\r\n"
+ "Sec-WebSocket-Key: %s\r\n"
+ "Sec-Websocket-Extensions: permessage-deflate; client_max_window_bits\r\n",
+ //"\r\n",
+ ws->path,
+ host,
+ port,
+ client_key);
+ if (len <= 0 || len >= DEFAULT_WS_BUFFER) {
+ ESP_LOGE("Error in request generation, %d", len);
+ return -1;
+ }
+ if (ws->sub_protocol) {
+ int r = snprintf(ws->buffer + len, DEFAULT_WS_BUFFER - len, "Sec-WebSocket-Protocol: %s\r\n", ws->sub_protocol);
+ len += r;
+ if (r <= 0 || len >= DEFAULT_WS_BUFFER) {
+ ESP_LOGE("Error in request generation"
+ "(snprintf of subprotocol returned %d, desired request len: %d, buffer size: %d", r, len, DEFAULT_WS_BUFFER);
+ return -1;
+ }
+ }
+ int r = snprintf(ws->buffer + len, DEFAULT_WS_BUFFER - len, "\r\n");
+ len += r;
+ if (r <= 0 || len >= DEFAULT_WS_BUFFER) {
+ ESP_LOGE("Error in request generation"
+ "(snprintf of header terminal returned %d, desired request len: %d, buffer size: %d", r, len, DEFAULT_WS_BUFFER);
+ return -1;
+ }
+ ESP_LOGD("%s, len is %d and Write upgrate request\r\n%s", __FUNCTION__, len, ws->buffer);
+ if (wb_esp_transport_write(ws->parent, ws->buffer, len, timeout_ms) <= 0) {
+ ESP_LOGE("Error write Upgrade header %s", ws->buffer);
+ return -1;
+ }
+ int header_len = 0;
+ do {
+ if ((len = wb_esp_transport_read(ws->parent, ws->buffer + header_len, DEFAULT_WS_BUFFER - header_len, timeout_ms)) <= 0) {
+ ESP_LOGE("Error read response for Upgrade header %s", ws->buffer);
+ return -1;
+ }
+ header_len += len;
+ ws->buffer[header_len] = '\0';
+ ESP_LOGD("Read header chunk %d, current header size: %d", len, header_len);
+ } while (NULL == strstr(ws->buffer, "\r\n\r\n") && header_len < DEFAULT_WS_BUFFER);
+
+ char *server_key = get_http_header(ws->buffer, "Sec-WebSocket-Accept:");
+ if (server_key == NULL) {
+ ESP_LOGE("Sec-WebSocket-Accept not found");
+ return -1;
+ }
+
+ // See mbedtls_sha1_ret() arg size
+ unsigned char expected_server_sha1[20];
+ // Size of base64 coded string see above
+ unsigned char expected_server_key[33] = {0};
+ // If you are interested, see https://tools.ietf.org/html/rfc6455
+ const char expected_server_magic[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+ unsigned char expected_server_text[sizeof(client_key) + sizeof(expected_server_magic) + 1];
+ strcpy((char*)expected_server_text, (char*)client_key);
+ strcat((char*)expected_server_text, expected_server_magic);
+
+ size_t key_len = strlen((char*)expected_server_text);
+ mbedtls_sha1_ret(expected_server_text, key_len, expected_server_sha1);
+ mbedtls_base64_encode(expected_server_key, sizeof(expected_server_key), &outlen, expected_server_sha1, sizeof(expected_server_sha1));
+ expected_server_key[ (outlen < sizeof(expected_server_key)) ? outlen : (sizeof(expected_server_key) - 1) ] = 0;
+ ESP_LOGD("server key=%s, send_key=%s, expected_server_key=%s", (char *)server_key, (char*)client_key, expected_server_key);
+ if (strcmp((char*)expected_server_key, (char*)server_key) != 0) {
+ ESP_LOGE("Invalid websocket key");
+ return -1;
+ }
+ return 0;
+}
+
+
+static int ws_read_payload(char *buffer, int len, int timeout_ms)
+{
+ int i = 0;
+ int bytes_to_read = 0;
+ int rlen = 0;
+
+ if (ws->frame_state.bytes_remaining > len) {
+ ESP_LOGD("Actual data to receive (%d) are longer than ws buffer (%d)", ws->frame_state.bytes_remaining, len);
+ bytes_to_read = len;
+
+ } else {
+ bytes_to_read = ws->frame_state.bytes_remaining;
+ }
+
+ // Receive and process payload
+ if (bytes_to_read != 0 && (rlen = wb_esp_transport_read(ws->parent, buffer, bytes_to_read, timeout_ms)) <= 0) {
+ ESP_LOGE("Error read data");
+ return rlen;
+ }
+ ws->frame_state.bytes_remaining -= rlen;
+
+ if (ws->frame_state.mask_key) {
+ for (i = 0; i < bytes_to_read; i++) {
+ buffer[i] = (buffer[i] ^ ws->frame_state.mask_key[i % 4]);
+ }
+ }
+ return rlen;
+}
+
+
+/* Read and parse the WS header, determine length of payload */
+static int ws_read_header(char *buffer, int len)
+{
+ int payload_len = 0;
+ char ws_header[MAX_WEBSOCKET_HEADER_SIZE] = {0};
+ char * data_ptr = ws_header;
+ char * mask = NULL;
+
+ // Receive and process header first (based on header size)
+ int header = 2;
+ int opcode = 0;
+ int mask_len = 4;
+ char mask_key[4] = {0};
+ int offset = 0;
+
+ memcpy(data_ptr, buffer + offset, header);
+ offset += header;
+
+ opcode = (*data_ptr & 0x0F);
+ data_ptr ++;
+ mask = ((*data_ptr >> 7) & 0x01);
+ payload_len = (*data_ptr & 0x7F);
+ data_ptr++;
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: opcode=%d,mask=%d,payload_len=%d\n", __FUNCTION__, __LINE__, opcode, mask, payload_len);
+
+ if (payload_len == 126)
+ {
+ // headerLen += 2;
+ memcpy(data_ptr, buffer + offset, header);
+ offset += header;
+
+ payload_len = data_ptr[0] << 8 | data_ptr[1];
+ }
+ else if (payload_len == 127)
+ {
+ // headerLen += 8;
+ header = 8;
+ memcpy(data_ptr, buffer + offset, header);
+ offset += header;
+
+ if (data_ptr[0] != 0 || data_ptr[1] != 0 || data_ptr[2] != 0 || data_ptr[3] != 0)
+ {
+ // really too big!
+ payload_len = 0xFFFFFFFF;
+ }
+ else
+ {
+ payload_len = data_ptr[4] << 24 | data_ptr[5] << 16 | data_ptr[6] << 8 | data_ptr[7];
+ }
+ }
+
+ if (mask)
+ {
+ memcpy(mask_key, buffer + offset, mask_len);
+ offset += mask_len;
+ }
+ else
+ {
+ memset(mask_key, 0, mask_len);
+ }
+
+ ws->frame_state.payload_len = payload_len;
+ ws->frame_state.bytes_remaining = payload_len;
+
+ return payload_len;
+}
+
+int mmi_wb_data_process(MMI_AIGC_WS_FRAME_STATE_T * ws_frame_t, char * buffer, int len)
+{
+ int ret = 0;
+
+ // If message exceeds buffer len then subsequent reads will skip reading header and read whatever is left of the payload
+ if (ws_frame_t.bytes_remaining <= 0)
+ {
+ if ( (rlen = ws_read_header(t, buffer, len, timeout_ms)) <= 0) {
+ // If something when wrong then we prepare for reading a new header
+ ws->frame_state.bytes_remaining = 0;
+ return rlen;
+ }
+
+
+ /* Read and parse the WS header, determine length of payload */
+ {
+ int payload_len = 0;
+ char ws_header[MAX_WEBSOCKET_HEADER_SIZE] = {0};
+ char * data_ptr = ws_header;
+ char * mask = NULL;
+
+ // Receive and process header first (based on header size)
+ int header = 2;
+ int opcode = 0;
+ int mask_len = 4;
+ char mask_key[4] = {0};
+ int offset = 0;
+
+ memcpy(data_ptr, buffer + offset, header);
+ offset += header;
+
+ opcode = (*data_ptr & 0x0F);
+ data_ptr ++;
+ mask = ((*data_ptr >> 7) & 0x01);
+ payload_len = (*data_ptr & 0x7F);
+ data_ptr++;
+ AIGC_NET_DEBUG("[@CHENG_DEBUG][%s][%d]: opcode=%d,mask=%d,payload_len=%d\n", __FUNCTION__, __LINE__, opcode, mask, payload_len);
+
+ if (payload_len == 126)
+ {
+ // headerLen += 2;
+ memcpy(data_ptr, buffer + offset, header);
+ offset += header;
+
+ payload_len = data_ptr[0] << 8 | data_ptr[1];
+ }
+ else if (payload_len == 127)
+ {
+ // headerLen += 8;
+ header = 8;
+ memcpy(data_ptr, buffer + offset, header);
+ offset += header;
+
+ if (data_ptr[0] != 0 || data_ptr[1] != 0 || data_ptr[2] != 0 || data_ptr[3] != 0)
+ {
+ // really too big!
+ payload_len = 0xFFFFFFFF;
+ }
+ else
+ {
+ payload_len = data_ptr[4] << 24 | data_ptr[5] << 16 | data_ptr[6] << 8 | data_ptr[7];
+ }
+ }
+
+ if (mask)
+ {
+ memcpy(mask_key, buffer + offset, mask_len);
+ offset += mask_len;
+ }
+ else
+ {
+ memset(mask_key, 0, mask_len);
+ }
+
+ ws_frame_t->opcode = opcode;
+ memset(ws_frame_t->mask_key, mask_key, mask_len);
+ ws_frame_t->payload_len = payload_len;
+ ws_frame_t->remain_len = payload_len;
+
+ return payload_len;
+ }
+
+
+ }
+ if (s_ws_frame_t.payload_len)
+ {
+ if ( (rlen = ws_read_payload(t, buffer, len, timeout_ms)) <= 0) {
+ ESP_LOGE("Error reading payload data");
+ ws->frame_state.bytes_remaining = 0;
+ return rlen;
+ }
+ }
+
+ return ret;
+}
+
+
+
+#endif
+