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平台实现了,只调用库函数,没有源代码)

#ifdef CA_CERT
const unsigned char app_ca1_cert[] = {
"-----BEGIN CERTIFICATE-----\r\n"
"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\r\n"
"-----END CERTIFICATE-----\r\n"
};
#endif#ifdef OWN_CERT
const unsigned char client_cert[] = {
};const unsigned char client_key[] = {
};#endifstatic struct ssl_client * ssl_client_init(int fd);
static void ssl_client_shutdown(struct ssl_client * client);
static int ssl_client_write( void *ssl, const unsigned char *buf, int len );
static int ssl_client_read( void *ssl, unsigned char *buf, int len );static unsigned int havege_rand(void *unused, unsigned char * unusedstr, size_t unusedt)
{char * p = (char *)malloc(16);unsigned int rand = (unsigned int)p;free(p);if ((rand & 0xff) == 0) {rand |= 0x96;}return rand;
}static void debug(void *userdata, int level,const char *filename, int line,const char *msg)
{//ssl_debug("%s", msg);
}//生成握手key的长度
#define WEBSOCKET_SHAKE_KEY_LEN 16struct ssl_client {mbedtls_ssl_context ssl;mbedtls_ssl_config config;mbedtls_ctr_drbg_context ctr_drbg;mbedtls_entropy_context entropy;int fd;
};struct ssl_client * ssl_c = NULL;static int ssl_client_recv(void * ctx, unsigned char * buf, unsigned int len)
{struct ssl_client * client = (struct ssl_client *)ctx;return recv(client->fd, buf, len, 0);
}static int ssl_client_send(void * ctx, const unsigned char *buf, unsigned int len)
{struct ssl_client * client = (struct ssl_client *)ctx;return send(client->fd, buf, len, 0);
}#ifdef CA_CERT
#define HOSTNAME "asr"
#endif
static struct ssl_client * ssl_client_init(int fd)
{char *pers = "ssl_client";int ret;struct ssl_client * client = (struct ssl_client *)malloc(sizeof(struct ssl_client));if (!client) {printf("Cannot malloc memory(ssl_client_init)\n");return NULL;}memset(client, 0, sizeof(struct ssl_client));#ifdef CA_CERTmbedtls_x509_crt *ca_chain; ca_chain = (mbedtls_x509_crt *)malloc(sizeof(mbedtls_x509_crt));memset(ca_chain, 0, sizeof(mbedtls_x509_crt));
#endifmbedtls_entropy_init(&client->entropy);mbedtls_ctr_drbg_init(&client->ctr_drbg);if((ret = mbedtls_ctr_drbg_seed(&client->ctr_drbg, mbedtls_entropy_func, &client->entropy,(unsigned char *)pers, strlen(pers))) != 0){printf( " failed\n  ! ctr_drbg_init returned %d\n", ret );goto failed;}mbedtls_ssl_init(&(client->ssl));mbedtls_ssl_config_init(&(client->config));client->fd = fd;mbedtls_ssl_conf_rng(&(client->config), mbedtls_ctr_drbg_random, &client->ctr_drbg);#ifdef CA_CERTmbedtls_x509_crt_parse(ca_chain,app_ca1_cert,strlen(app_ca1_cert));mbedtls_ssl_conf_ca_chain(&(client->config), ca_chain, NULL);mbedtls_ssl_set_hostname(&(client->ssl), HOSTNAME);
#endif#ifdef OWN_CERTmbedtls_x509_crt *client_chain = NULL;mbedtls_pk_context *client_rsa = NULL;client_chain = (mbedtls_x509_crt *)malloc(sizeof(mbedtls_x509_crt));memset(client_chain, 0, sizeof(mbedtls_x509_crt));mbedtls_x509_crt_parse(client_chain,client_cert,strlen(client_cert));client_rsa = (mbedtls_pk_context *)malloc(sizeof(mbedtls_pk_context));memset(client_rsa, 0, sizeof(mbedtls_rsa_context));  mbedtls_pk_parse_key(client_rsa, client_key, strlen(client_key), NULL,0);mbedtls_ssl_conf_own_cert(&client->config, client_chain, client_rsa);
#endif//mbedtls_ssl_conf_endpoint(&(client->config), MBEDTLS_SSL_IS_CLIENT);mbedtls_ssl_config_defaults(&client->config, MBEDTLS_SSL_IS_CLIENT,MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
//    mbedtls_ssl_conf_ciphersuites_for_version(&client->config, 0, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MAJOR_VERSION_3);#ifdef CA_CERTmbedtls_ssl_conf_authmode(&client->config, MBEDTLS_SSL_VERIFY_REQUIRED);
#elsembedtls_ssl_conf_authmode(&client->config, MBEDTLS_SSL_VERIFY_OPTIONAL);
#endifmbedtls_ssl_conf_rng(&client->config, mbedtls_ctr_drbg_random, &client->ctr_drbg);mbedtls_ssl_conf_dbg(&client->config, debug, NULL);//mbedtls_debug_set_threshold(1000);mbedtls_ssl_set_bio(&client->ssl, client,ssl_client_send, ssl_client_recv, NULL);mbedtls_ssl_setup(&client->ssl, &client->config);return client;
failed:
#ifdef CA_CERTif(ca_chain) free(ca_chain);
#endifif (client) free(client);return NULL;
}static int ssl_client_write( void *ssl, const unsigned char *buf, int len )
{return ssl_write(ssl, buf, len );
}static int ssl_client_read( void *ssl, unsigned char *buf, int len )
{return ssl_read( ssl, buf, len );
}

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);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/243461.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

香港印象:维多利亚港湾·张学友的手印

维多利亚港。今天有雾&#xff0c;所以不是很清晰&#xff0c;与传说中的有一定距离。 上空的鹰&#xff0c;飞的很有姿态。 张学友的手印&#xff0c;和我很贴&#xff0c;哈哈。 李小龙是这里的主角&#xff0c;他的标志性姿势吸引了很多粉丝。 香港的出租车太贵了&#xff0…

综合单元库

综合单元库 1、电路系统工作原理 一些基本的元件:加法器、比较器、寄存器。电路中比较大的元件都是由基本单元组成的,所以在设计复杂电路芯片时,就需要由上至下地搭建,而最底层就是单元。根据不同的需要,使用不同的元件搭建不同的电路芯片。 2、VHDL语言描述方法及语法分…

才子佳人文学传统的戏拟与嘲仿

读着余华的《古典爱情》&#xff08;见《北京文学》88年第12期&#xff09;&#xff0c;我感到意外&#xff0c;一位据说是在阅读上具有颠覆意义的小说实验者&#xff0c;&#xff08;见《文艺报》李陀的《阅读的颠覆》&#xff09;竟然会津津乐道地讲起了一个老掉牙的艳情故事…

Java入门, 线程

// implement file: MyThread.java //package org.lxh.demo16.thd;/*** 定义一个线程类* author Owner**/ class MyThd extends Thread {private String name;public MyThd(String name) {this.name name;}public void run() {for(int i 0; i < 100; i) {System.out.print…

我从草原来:自由摄影人李伟 (内蒙古电视台“蔚蓝的故乡”20110407)

内蒙古电视台“蔚蓝的故乡”节目不久前拍摄了我的朋友——自由摄影师李伟的艺术创作经历&#xff0c;我作为嘉宾在节目中说了几句话。李伟是出生在呼和浩特的汉人&#xff0c;但是他多年关注内蒙古草原的普通蒙古人&#xff0c;与他们结交成非常要好的朋友&#xff0c;所以&…

MATLAB快速拟合二组数据

MATLAB快速拟合二组数据 第一步&#xff1a;打开MATLAB&#xff0c;点击主页中的新建变量&#xff0c;点击修改变量名为a&#xff0c;然后复制数据进去&#xff0c;接着新建变量b&#xff0c;复制数据进去。 第二步&#xff1a;点击上端的APP&#xff0c;选择第一个图标 第三…

handle和handler的理解

维基百科对handler的解释&#xff1a; Handler, an asynchronous callback (computer programming) subroutine in computing ... Event handler, a routine for processing a programming event Interrupt handler, a routine for processing CPU interrupts Signal handler,…

《北京作家》·史铁生·维格拉姆

《北京作家》今年第一期&#xff08;总第七期&#xff09;最近和读者见面了。这期重点推出了纪念刚刚故去的史铁生的专辑。首发了史铁生生前几个时期四张照片&#xff0c;并发表了他的好友曹文轩、林莽、甘铁生的纪念文章&#xff0c;文章字字真切&#xff0c;句句深情&#xf…

七值逻辑与基本数据类型

七值逻辑与基本数据类型 1、逻辑系统原理 数字系统内部信息的表示和传输通常有两个状态,分别表示0和1,这是理想化模型。但是数字系统时千变万化的,而且在大部分情况下都不可能达到理想化的程度。因此,有必要使用多值逻辑,如三值逻辑、六值逻辑、七值逻辑以及九值逻辑等。…

一道3G门户的面试题 (Java)

给一个大小为100的&#xff08;整型&#xff09;数组&#xff0c;分配0-1000的随机数100个&#xff0c;但这100个数不能重复&#xff0c;然后把它从小到大排序&#xff0c;并输出来。&#xff08;时间10分钟&#xff09; Java代码如下&#xff1a; package org.lxh.demo16…

他是我们内心世界的一员 (见信息时报2011年7月10日)

上世纪八十年代&#xff0c;弗洛伊德的理论刚刚进入中国的时候&#xff0c;他的书夸张地说“要比今天周杰伦演唱会的票更抢手”。当时&#xff0c;《精神分析引论》&#xff08;商务印书馆出版&#xff09;、《少女杜拉的故事》&#xff08;民间文艺出版社出版&#xff0c;后北…

IE 10的新HTML​解析规则​

HTML 5的重要变化之一是引入了针对非标准HTML特别是错误格式HTML的标准化解析规则。浏览器在遇到存在错误的HTML如缺少结束标记时通常表现得很宽松。这种大度被广受赞誉&#xff0c;因为相比对手XHTML来说&#xff0c;HTML​在此种情况下会继续正常处理。​\u0026#xD;\nHTML最新…

VHDL中的函数

VHDL中的函数 (1)函数的一般形式 函数的一般形式如下: 函数定义 is 函数说明部分 begin 函数语句部分 end [函数类型] [函数名] 在函数定义部分,要说明函数名、函数的参数及返回的类型; 函数说明部分,有类似于进程语句的说明区,说明变量、常量和类型,但不能说明信号;…

乱七八糟的备份

package org.lxh.demo16.common;//import java.awt.List; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.Map; import java.util.Random;/*** implement file: Tfrk.java* desc: 给一个大小为100的&#xff08;整型&#xff09;…

造化之美与美的忧虑

苏珊桑塔格说&#xff1a;“收集照片就是收集世界。”我以为摄影就是一种收集&#xff0c;摄影师将世间万物凝固并收藏在小小的镜头里和照片中&#xff0c;为自己和历史留下记忆。当然&#xff0c;摄影还有一种审视的功能&#xff0c;它帮助我们发现生活中的美和残缺&#xff0…

MDK编译生成bin文件

fromelf --bin -o “$LL.bin” “#L” 把这一行复制到User -> After Build/Rebuild -> Run #1后面

Windows Azure SDK 1.6让Visual Studio下的Azure开发更高效

微软已发布Windows Azure SDK 1.6&#xff0c;其中包括适用于Visual Studio 2010的Windows Azure Tools、以及适用于.NET的Windows Azure Libraries两项更新&#xff0c;除此之外其中还包括另外一些修复和性能改进。\u0026#xD;\n微软发布适用于Visual Studio 2010的Windows Azu…

VHDL中的分辨函数

VHDL中的分辨函数 分辨函数(resolved function)是VHDL语言中具有代表性的一类函数,本例是一个线或(WiredOr)分辨函数。 分辨函数的功能 根据驱动器件工艺的不同,有多个驱动源的信号可以表现为竞争信号的“或”关系或者“与”关系,分辨函数就是为了解决这一问题而设计的…

阿里云物联网平台,三要素生成hmacmd5,hmacsha1和hmacsha256,password算法+hashmd5,hashsha1,hashsha256算法

程序在ubuntu上测试通过 测试函数&#xff1a; #include "infra_md5.h" #include "infra_sha1.h" #include "infra_sha256.h"#include <stdio.h> #include <string.h>void aliyun_generate_sign_str(const char *client_id, const…