W801_SDK_dev_env/demo/wm_https_demo.c
2023-03-08 08:23:45 +01:00

217 lines
6.8 KiB
C

/*****************************************************************************
*
* File Name : wm_https_demo.c
*
* Description: ssl client demo function
*
* Copyright (c) 2015 Winner Micro Electronic Design Co., Ltd.
* All rights reserved.
*
* Author : LiLimin
*
* Date : 2015-3-24
*****************************************************************************/
#include <string.h>
#include "wm_include.h"
#include "wm_netif.h"
#include "wm_demo.h"
#include "tls_common.h"
#include "lwip/netif.h"
#include "wm_sockets.h"
#include "lwip/inet.h"
#include "wm_sockets.h"
#include "HTTPClientWrapper.h"
#if DEMO_HTTPS
#define HTTPS_DEMO_TASK_PRIO 38
#define HTTPS_DEMO_TASK_SIZE 2048 //1024
#define HTTPS_DEMO_QUEUE_SIZE 4
#define HTTPS_RECV_BUF_LEN_MAX 1024
#define HTTPS_DEMO_CMD_START 0x1
#define HTTPS_DEMO_SERVER "www.tencent.com"
#define HTTPS_DEMO_PORT 443
static bool https_demo_inited = FALSE;
static OS_STK https_demo_task_stk[HTTPS_DEMO_TASK_SIZE];
static tls_os_queue_t *https_demo_task_queue = NULL;
static const char *https_request = "GET /legal/html/zh-cn/index.html HTTP/1.0\r\n"
"Host: "HTTPS_DEMO_SERVER"\r\n"
"User-Agent: W80X\r\n"
"\r\n";
extern struct netif *tls_get_netif(void);
extern int wm_printf(const char *fmt, ...);
static void https_demo_net_status(u8 status)
{
struct netif *netif = tls_get_netif();
switch(status)
{
case NETIF_WIFI_JOIN_FAILED:
wm_printf("sta join net failed\n");
break;
case NETIF_WIFI_DISCONNECTED:
wm_printf("sta net disconnected\n");
break;
case NETIF_IP_NET_UP:
wm_printf("sta ip: %v\n", netif->ip_addr.addr);
tls_os_queue_send(https_demo_task_queue, (void *)HTTPS_DEMO_CMD_START, 0);
break;
default:
break;
}
}
static void https_demo_task(void *p)
{
int ret;
void *msg;
tls_ssl_t *ssl_p;
int fd;
struct hostent *hp;
struct sockaddr_in server;
char *recvbuf;
int total = 0;
struct tls_ethif *ether_if = tls_netif_get_ethif();
if (ether_if->status)
{
wm_printf("sta ip: %v\n", ether_if->ip_addr.addr);
tls_os_queue_send(https_demo_task_queue, (void *)HTTPS_DEMO_CMD_START, 0);
}
for( ; ; )
{
ret = tls_os_queue_receive(https_demo_task_queue, (void **)&msg, 0, 0);
if (!ret)
{
switch((u32)msg)
{
case HTTPS_DEMO_CMD_START:
do
{
hp = gethostbyname(HTTPS_DEMO_SERVER);
if (hp == NULL )
{
wm_printf("get address error\r\n");
break;
}
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0)
{
wm_printf("create socket error\r\n");
break;
}
memset(&server, 0, sizeof(struct sockaddr_in));
memcpy(&(server.sin_addr), hp->h_addr, hp->h_length);
server.sin_family = AF_INET;
server.sin_port = htons(HTTPS_DEMO_PORT);
wm_printf("step 1: ssl connect to...\r\n");
ret = HTTPWrapperSSLConnect(&ssl_p, fd, (const struct sockaddr *)&server, sizeof(server), HTTPS_DEMO_SERVER);
if (ret < 0)
{
wm_printf("https connect error\r\n");
close(fd);
break;
}
recvbuf = tls_mem_alloc(HTTPS_RECV_BUF_LEN_MAX + 1);
if (!recvbuf)
{
wm_printf("https malloc error\r\n");
HTTPWrapperSSLClose(ssl_p, fd);
close(fd);
break;
}
wm_printf("step 2: send https request [%s]\r\n", https_request);
ret = HTTPWrapperSSLSend(ssl_p, fd, (char *)https_request, strlen(https_request), 0);
if (ret < 0)
{
wm_printf("https send error\r\n");
tls_mem_free(recvbuf);
HTTPWrapperSSLClose(ssl_p, fd);
close(fd);
break;
}
do
{
ret = HTTPWrapperSSLRecv(ssl_p, fd, recvbuf, HTTPS_RECV_BUF_LEN_MAX, 0);
if (ret <= 0)
{
if (SOCKET_SSL_MORE_DATA == ret)
{
recvbuf[HTTPS_RECV_BUF_LEN_MAX] = '\0';
wm_printf("step 3: recvd https resp %d bytes [%s]\r\n", HTTPS_RECV_BUF_LEN_MAX, recvbuf);
total += HTTPS_RECV_BUF_LEN_MAX;
ret = 1;
}
else
{
wm_printf("https recv closed\r\n");
break;
}
}
else
{
recvbuf[ret] = '\0';
wm_printf("step 3: recvd https resp %d bytes [%s]\r\n", ret, recvbuf);
total += ret;
}
}
while (ret > 0);
wm_printf("step 3: recvd https resp total %d bytes.\r\n", total);
tls_mem_free(recvbuf);
HTTPWrapperSSLClose(ssl_p, fd);
close(fd);
wm_printf("\r\nhttps demo end.\r\n");
}
while (0);
break;
default:
break;
}
}
}
}
//https request demo
//This example should make STA connected to AP firstly, then access web page https://www.tencent.com/legal/html/zh-cn/index.html
int https_demo(void)
{
if (!https_demo_inited)
{
tls_os_task_create(NULL, NULL, https_demo_task,
NULL, (void *)https_demo_task_stk, /* task's stack start address */
HTTPS_DEMO_TASK_SIZE * sizeof(u32),/* task's stack size, unit:byte */
HTTPS_DEMO_TASK_PRIO, 0);
tls_os_queue_create(&https_demo_task_queue, HTTPS_DEMO_QUEUE_SIZE);
tls_netif_add_status_event(https_demo_net_status);
https_demo_inited = TRUE;
}
return WM_SUCCESS;
}
#endif