asr1601芯片平台实现ssl加密的websocket
生活随笔
收集整理的这篇文章主要介绍了
asr1601芯片平台实现ssl加密的websocket
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
首先感谢SGuniver_22,本文实现内容,是在他实现的websocket基础上,移植而来。
他的博客:https://blog.csdn.net/SGuniver_22
他的github:https://github.com/wexiangis/websocket_for_linux
移植代码下载:https://download.csdn.net/download/zn2857/16671309
1.首先去git下载websocket源码
。。。
2.实现ssl(asr1601平台实现了,只调用库函数,没有源代码)
3.在ws_connectToServer函数里将socket创建,连接,改为asr1601芯片平台实现方式。注意有的websocket服务器不需要调用fcntl函数设置非阻塞
int ws_createSocket(char *ip, int port) {int ret, sock = -1;struct addrinfo hints;struct addrinfo *result, *rp;int port_buf[10] = {0};printf("websocket_createSocket!\n");memset(&hints, 0, sizeof(hints));hints.ai_family = AF_UNSPEC;hints.ai_socktype = SOCK_STREAM;hints.ai_flags = 0;hints.ai_protocol = 0;itoa(port,port_buf);ret = getaddrinfo(ip, port_buf, &hints, &result);if (ret != 0) {printf("ws_createSocket: resolve error\n");return result;}for (rp = result; rp; rp = rp->ai_next) {sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);if (sock < 0) {printf("ws_createSocket: socket error\n");continue;} // ret = fcntl(sock, F_GETFL, 0); // fcntl(sock, F_SETFL, ret | O_NONBLOCK);ret = connect(sock, rp->ai_addr, rp->ai_addrlen);if (ret < 0) {printf("ws_createSocket:socket connect error\n");close(sock);sock = -1;continue;} else {break;}}freeaddrinfo(result);return sock;}int ws_connectToServer(char *ip, int port, char *path, int timeoutMs) {int32_t ret, fd = -1;int32_t timeoutCount = 0;char retBuff[512] = {0};char httpHead[512] = {0};char shakeKey[128] = {0};char *p;fd = ws_createSocket(ip,port);if(fd < 0)return fd;if(!ssl_c){ssl_c = ssl_client_init(fd);if(NULL == ssl_c)return -1;}//发送http协议头memset(shakeKey, 0, sizeof(shakeKey));ws_buildShakeKey(shakeKey); //创建握手keymemset(httpHead, 0, sizeof(httpHead)); //创建协议包ws_buildHttpHead(ip, port, path, shakeKey, (char *)httpHead); //组装http请求头ssl_client_write(&(ssl_c->ssl), httpHead, strlen((const char *)httpHead));#ifdef WS_DEBUGsdk_uart_printf("ws_connectToServer: \r\n%s\r\n", httpHead); #endifwhile (1){memset(retBuff, 0, sizeof(retBuff));ret = ssl_client_read(&(ssl_c->ssl), retBuff, sizeof(retBuff));if (ret > 0){ #ifdef WS_DEBUG//显示http返回sdk_uart_printf("ws_connectToServer: %d \r\n%s\r\n", ret, retBuff); #endif//返回的是http回应信息if (strncmp((const char *)retBuff, "HTTP", 4) == 0){//定位到握手字符串if ((p = strstr((char *)retBuff, "sec-websocket-accept: ")) != NULL){p += strlen("sec-websocket-accept: ");sscanf((const char *)p, "%s\r\n", p);//比对握手信息if (ws_matchShakeKey(shakeKey, strlen((const char *)shakeKey), p, strlen((const char *)p)) == 0){sdk_uart_printf("shake hands success\r\n");return ssl_c;}//握手信号不对, 重发协议包else{sdk_uart_printf("shake hands info err, resend pkg\r\n");ret = ssl_client_write(&(ssl_c->ssl), httpHead, strlen((const char *)httpHead));}}//重发协议包else{sdk_uart_printf("shake hands signal err, resend pkg\r\n");ret = ssl_client_write(&(ssl_c->ssl), httpHead, strlen((const char *)httpHead));}}//显示异常返回数据else{//#ifdef WS_DEBUGif (retBuff[0] >= ' ' && retBuff[0] <= '~')sdk_uart_printf("ws_connectToServer: %d\r\n%s\r\n", ret, retBuff);else{p = retBuff;sdk_uart_printf("ws_connectToServer: %d\r\n", ret);while (*p)sdk_uart_printf("%.2X ", *p++);sdk_uart_printf("\r\n");}//#endif}}else{ssl_client_write(&(ssl_c->ssl), httpHead, strlen((const char *)httpHead));sdk_uart_printf("ws_connectToServer: \r\n%s\r\n", httpHead);}ws_delayms(1000);//超时检查if (++timeoutCount > timeoutMs * 2)break;}//连接失败,返回耗时(负值)ws_close(fd);sdk_uart_printf("connect err\n");return -timeoutCount; }4.实现初始化
// extern void update_the_cp_ver(char *cp_ver); // max length 128 // Device bootup hook before Phase1Inits. // If you have some work to be init, you may implete it here. // ex: you may start your task here. or do some initialize here. void Phase1PreInits(void) {sdk_uart_printf("[CUST] enter %s\n", __func__);sdk_uart_printf("[CUST] enter %s\n", __func__); }// Device bootup hook after Phase1Inits. // If you have some work to be init, you may implete it here. // ex: you may start your task here. or do some initialize here. void Phase1PostInits(void) {sdk_uart_printf("[CUST] enter %s\n", __func__);sdk_uart_printf("[CUST] enter %s\n", __func__); }// Device bootup hook before Phase2Inits. // If you have some work to be init, you may implete it here. // ex: you may start your task here. or do some initialize here. void Phase2PreInits(void) {sdk_uart_printf("[CUST] enter %s\n", __func__);sdk_uart_printf("[CUST] enter %s\n", __func__); }// Device bootup hook after Phase2Inits. // If you have some work to be init, you may implete it here. // ex: you may start your task here. or do some initialize here. void Phase2PostInits(void) {int ret;sdk_uart_printf("[CUST] enter %s\n", __func__);sdk_uart_printf("[CUST] enter %s\n", __func__);ret = OSAFlagCreate(&_flag_app_ref);ASSERT(ret == OS_SUCCESS);ret = OSATaskCreate(&_task_app_ref, _task_app_stack, _TASK_APP_STACK_SIZE, 120, "_task_app", _task_app, NULL);ASSERT(ret == OS_SUCCESS);ret = OSATimerCreate(&_timer_ref);ASSERT(ret == OS_SUCCESS); }5.实现任务函数
static void _timer_callback(UINT32 tmrId) {OSAFlagSet(_flag_app_ref, TASK_TIMER_CHANGE_FLAG_BIT, OSA_FLAG_OR); }static int wait_dialer_reg_net(void) {while (!CM_GetDefaultConnectStatus()) {sdk_uart_printf("[app]wait net ...");ws_delayms(5000);}sdk_uart_printf("[app]NetWork dialer success");return OS_SUCCESS; } static void _task_app(void *ptr) {int ret;OSA_STATUS status;UINT32 flag_value;UINT32 flag_mask = TASK_TIMER_CHANGE_FLAG_BIT;char send_buff[4096];memset(send_buff, 0, sizeof(send_buff));sprintf(send_buff, "Say hi~ from client");WsData_Type retPkgType;char recv_buff[4096];//等待网络附着wait_dialer_reg_net();//连接websocket,尝试10次if ((fd = ws_connectToServer(ip, port, "/api/ws", 5)) <= 0) //1-ssl {sdk_uart_printf("ws failed !\r\n");}else{sdk_uart_printf("ws connect success! \n");}//开启定时器,驱动代码执行OSATimerStart(_timer_ref, 3 * 200, 3 * 200, _timer_callback, 0); // 30 seconds timerwhile(1) {status = OSAFlagWait(_flag_app_ref, flag_mask, OSA_FLAG_OR_CLEAR, &flag_value, OSA_SUSPEND);ASSERT(status == OS_SUCCESS);if(fd){ret = ws_send(fd, send_buff, strlen(send_buff), true, WDT_TXTDATA);if(ret <= 0) sdk_uart_printf("ws send err\n");elsesdk_uart_printf("wst send: %s\n",send_buff);memset(recv_buff, 0, sizeof(recv_buff));ret = ws_recv(fd,recv_buff,sizeof(recv_buff) - 1,NULL);if (ret <= 0) {sdk_uart_printf("ws: recv error: %d", ret);ws_close(fd);} sdk_uart_printf("ws ssl rcv: %s,len: %d\n",recv_buff,ret); }}ws_close(fd); }总结
以上是生活随笔为你收集整理的asr1601芯片平台实现ssl加密的websocket的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 滴滴出行:即日起恢复“滴滴出行”的新用户
- 下一篇: handle和handler的理解