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

220 lines
5.8 KiB
C

/*****************************************************************************
*
* File Name : wm_mcast_demo.c
*
* Description: mcast demo function
*
* Copyright (c) 2014 Winner Micro Electronic Design Co., Ltd.
* All rights reserved.
*
* Author : wanghaifang
*
* Date : 2014-6-2
*****************************************************************************/
#include <string.h>
#include "wm_include.h"
#if DEMO_UDP_MULTI_CAST
#define DEMO_MCAST_TASK_SIZE 256
tls_os_queue_t *demo_mcast_q = NULL;
static OS_STK DemoMCastTaskStk[DEMO_MCAST_TASK_SIZE];
u8 is_snd = 1;
extern ST_Demo_Sys gDemoSys;
static void demo_mcast_task(void *sdata);
#define MPORT 5100
static u8 MCASTIP[4] = {224, 1, 2, 1};
#define MCAST_BUF_SIZE 1024
int mcastsendrcv(bool snd)
{
int s;
int ret;
int size;
int ttl = 10;
int loop = 0;
int times = 0;
int i = 65;
char *buffer = NULL;
socklen_t socklen;
struct sockaddr_in localaddr, fromaddr, Multi_addr;
struct ip_mreq mreq;
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(s < 0)
{
printf("socket error");
return -1;
}
printf("multi case socket num=%d\n", s);
Multi_addr.sin_family = AF_INET;
Multi_addr.sin_port = htons(MPORT);
MEMCPY((char *)&Multi_addr.sin_addr, (char *)MCASTIP, 4);
localaddr.sin_family = AF_INET;
localaddr.sin_port = htons(MPORT);
localaddr.sin_addr.s_addr = htonl(0x00000000UL);
fromaddr.sin_family = AF_INET;
fromaddr.sin_port = htons(MPORT);
fromaddr.sin_addr.s_addr = htonl(0x00000000UL);
ret = bind(s, (struct sockaddr *)&localaddr, sizeof(localaddr));
if(ret < 0)
{
printf("bind error");
return -1;
}
//Configure multicast TTL
if(setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0)
{
printf("IP_MULTICAST_TTL");
return -1;
}
//Setting local loop for multicast
if(setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) < 0)
{
printf("IP_MULTICAST_LOOP");
return -1;
}
MEMCPY((char *)&mreq.imr_multiaddr.s_addr, (char *)MCASTIP, 4);
mreq.imr_interface.s_addr = htonl(0x00000000UL);
//join multicast group
if(setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
{
printf("IP_ADD_MEMBERSHIP");
return -1;
}
buffer = tls_mem_alloc(MCAST_BUF_SIZE);
if(NULL == buffer)
return -1;
memset(buffer, 0, MCAST_BUF_SIZE);
//loop rx or tx data
if(snd)
{
for(times = 0; times < 20; times++)
{
memset(buffer, i, MCAST_BUF_SIZE);
size = sendto(s, buffer, MCAST_BUF_SIZE, 0, (struct sockaddr *)&Multi_addr, sizeof(Multi_addr));
printf("multi case sendto buf=%s, size=%d\n", buffer, size);
tls_os_time_delay(50);
i++;
memset(buffer, 0, MCAST_BUF_SIZE);
}
}
else
{
for(times = 0; times < 5; times++)
{
socklen = sizeof(fromaddr);
recvfrom(s, buffer, MCAST_BUF_SIZE, 0, (struct sockaddr *)&fromaddr, &socklen);
printf("multi case recvfrom buf=%s, socklen=%d\n", buffer, socklen);
memset(buffer, 0, MCAST_BUF_SIZE);
}
}
tls_mem_free(buffer);
//leave multicast group
ret = setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
if(ret < 0)
{
printf("IP_DROP_MEMBERSHIP");
return -1;
}
closesocket(s);
return 0;
}
int CreateMCastDemoTask(char *buf)
{
if(strstr(buf, "recv"))
{
is_snd = 0;
}
else
is_snd = 1;
printf("is_snd=%d, para:%s\n", is_snd, buf);
tls_os_queue_create(&demo_mcast_q, DEMO_QUEUE_SIZE);
//Task to deal with socket message
tls_os_task_create(NULL, NULL,
demo_mcast_task,
NULL,
(void *)DemoMCastTaskStk, /* task's stack start address*/
DEMO_MCAST_TASK_SIZE * sizeof(u32), /* task's stack size, unit:byte */
DEMO_MCAST_TASK_PRIO,
0);
return WM_SUCCESS;
}
static void mcast_net_status_changed_event(u8 status )
{
switch(status)
{
case NETIF_WIFI_JOIN_FAILED:
tls_os_queue_send(demo_mcast_q, (void *)DEMO_MSG_WJOIN_FAILD, 0);
break;
case NETIF_WIFI_JOIN_SUCCESS:
tls_os_queue_send(demo_mcast_q, (void *)DEMO_MSG_WJOIN_SUCCESS, 0);
break;
case NETIF_IP_NET_UP:
tls_os_queue_send(demo_mcast_q, (void *)DEMO_MSG_SOCKET_CREATE, 0);
break;
default:
break;
}
}
static void demo_mcast_task(void *sdata)
{
// ST_Demo_Sys *sys = (ST_Demo_Sys *)sdata;
void *msg;
struct tls_ethif *ethif = tls_netif_get_ethif();
printf("\nmcast task\n");
if(ethif->status) /*connected to ap and get IP*/
{
tls_os_queue_send(demo_mcast_q, (void *)DEMO_MSG_SOCKET_CREATE, 0);
}
else
{
struct tls_param_ip ip_param;
tls_param_get(TLS_PARAM_ID_IP, &ip_param, TRUE);
ip_param.dhcp_enable = TRUE;
tls_param_set(TLS_PARAM_ID_IP, &ip_param, TRUE);
tls_wifi_set_oneshot_flag(1); /*Enable oneshot configuration*/
printf("\nwait one shot......\n");
}
tls_netif_add_status_event(mcast_net_status_changed_event);
for(;;)
{
tls_os_queue_receive(demo_mcast_q, (void **)&msg, 0, 0);
//printf("\n msg =%d\n",msg);
switch((u32)msg)
{
case DEMO_MSG_WJOIN_SUCCESS:
break;
case DEMO_MSG_SOCKET_CREATE:
mcastsendrcv(is_snd);
break;
case DEMO_MSG_WJOIN_FAILD:
break;
case DEMO_MSG_SOCKET_ERR:
printf("\nsocket err\n");
break;
default:
break;
}
}
}
#endif