/******************************************************************************
°æȨËùÓÐ (C), 2001-2011, ÉñÖÝÊýÂëÍøÂçÓÐÏÞ¹«Ë¾
******************************************************************************
ÎÄ ¼þ Ãû : pthread_send_udp5_org.c
°æ ±¾ ºÅ : ³õ¸å
×÷ Õß : wei
Éú³ÉÈÕÆÚ : 2014Äê3ÔÂ28ÈÕÐÇÆÚÎå
×î½üÐÞ¸Ä :
¹¦ÄÜÃèÊö :
º¯ÊýÁбí :
command_kill
command_play_new_ts
command_show_list
create_new_node
debug_malloc
GetLocalIp
get_input
read_config_by_line
main
parse_command
parse_config
sig_usr
test_malloc
udp_send_ts_package
ÐÞ¸ÄÀúÊ· :
1.ÈÕ ÆÚ : 2014Äê3ÔÂ28ÈÕÐÇÆÚÎå
×÷ Õß : wei
ÐÞ¸ÄÄÚÈÝ : ´´½¨Îļþ
******************************************************************************/
/*----------------------------------------------*
* °üº¬Í·Îļþ *
*----------------------------------------------*/
#include <stdio.h> //printf()
#include <unistd.h> //pause()
#include <signal.h> //signal()
#include <string.h> //memset()
#include <sys/time.h> //struct itimerval, setitimer()
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <bits/pthreadtypes.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <netdb.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <sys/ioctl.h>
#include <ifaddrs.h>
#include <semaphore.h>
#include <assert.h>
/*----------------------------------------------*
* ºê¶¨Òå *
*----------------------------------------------*/
#define MAX_PEER_COUNT 250
#define GROUP_NAME_LINE 1
#define PATH_NAME_LINE 2
#define IP_LINE 3
#define PORT_LINE 4
#define BITRATE_LINE 5
#define MAX_PATH_LENGTH 255
#define SEND_LENGTH 7*188
#define MAX_COMMOND_SIZE 255
#define SLEEP_TIME_MS 4
int bits=sizeof(long);
#if bits == 32
#define s64 long
#else
#define s64 long long
#endif
//typedef signed long long s64;
#define U32_AT(n) ( (((u32)((u8*)&(n))[0]) << 24) \
| (((u32)((u8*)&(n))[1]) << 16) \
| (((u32)((u8*)&(n))[2]) << 8) \
| (((u32)((u8*)&(n))[3])) )
//#define s64 long long
#define MAX_PACKAGE_COUNT 5
#define MAX_PACKAGE_LENGTH 188
typedef unsigned long u32;
typedef unsigned char u8;
typedef int BOOL;
#ifdef DEBUG
void *debug_malloc(size_t size, const char *file, int line, const char *func)
{
void *p;
p = malloc(size);
printf("%s:%d:%s:malloc(%ld): p=0x%lx\n",file, line, func, size, (unsigned long)p);
return p;
}
#define malloc(s) debug_malloc(s, __FILE__, __LINE__, __func__)
#define free(p) do { \
printf("%s:%d:%s:free(0x%lx)\n", __FILE__, __LINE__, \
__func__, (unsigned long)p); \
if(p) { \
free(p); \
p= NULL; \
} \
} while (0)
#endif
/*----------------------------------------------*
* Íⲿ±äÁ¿ËµÃ÷ *
*----------------------------------------------*/
/*----------------------------------------------*
* Íⲿº¯ÊýÔÐÍ˵Ã÷ *
*----------------------------------------------*/
/*----------------------------------------------*
* ÄÚ²¿º¯ÊýÔÐÍ˵Ã÷ *
*----------------------------------------------*/
/*----------------------------------------------*
* È«¾Ö±äÁ¿ *
*----------------------------------------------*/
static unsigned char *p_max_buffer;
static signed long long g_pcr_base[MAX_PACKAGE_COUNT];
static unsigned long g_pcr_ext[MAX_PACKAGE_COUNT];
static int g_byte_per_Xms;
//static struct timeval g_start;
//static s64 pcr_time;
struct adjoin_pcr
{
int pcr_byte_count;
s64 l_pcr;
}pcr_info[MAX_PACKAGE_COUNT];
static int g_pcr_interval;
/*----------------------------------------------*
* Ä£¿é¼¶±äÁ¿ *
*----------------------------------------------*/
struct day
{
int hour;
int minute;
int second;
};
struct udp_send_info
{
int beused;
time_t current;
time_t totle_time;
char *path;
struct sockaddr_in peeraddr;
unsigned long long bit_rate;
};
struct config_info
{
int count;
struct udp_send_info peer[MAX_PEER_COUNT];
}CONFIG_INFO;
/*----------------------------------------------*
* ³£Á¿¶¨Òå *
*----------------------------------------------*/
static u8 g_stream_count;
static char g_argv[5][255];
static int g_fd_id[MAX_PEER_COUNT];
static int sockid[MAX_PEER_COUNT];
static int g_argc;
static pthread_mutex_t g_work_mutex;
void test_malloc(void)
{
char *p_test = NULL;
//while ( 1 )
{
p_test = (char *)malloc(100);
if ( p_test )
{
printf("malloc sucess \n");
free(p_test);
}
}
}
char * get_local_ip(void)
{
struct ifaddrs *ifaddr, *ifa;
int family, s;
char host[NI_MAXHOST];
if ( getifaddrs(&ifaddr) == -1 )
{
perror("getifaddrs");
exit(EXIT_FAILURE);
}
/* Walk through linked list, maintaining head pointer so we
* can free list later */
for ( ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next )
{
if (ifa->ifa_addr == NULL)
continue;
family = ifa->ifa_addr->sa_family;
/* Display interface name and family (including symbolic
* form of the latter for the common families) */
printf("%s address family: %d%s\n",
ifa->ifa_name, family,
(family == AF_PACKET) ? " (AF_PACKET)" :
(family == AF_INET) ? " (AF_INET)" :
(family == AF_INET6) ? " (AF_INET6)" : "");
/* For an AF_INET* interface address, display the address */
if (family == AF_INET /* family == AF_INET6*/) {
s = getnameinfo(ifa->ifa_addr,
(family == AF_INET) ? sizeof(struct sockaddr_in) :
sizeof(struct sockaddr_in6),
host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if (s != 0)
{
printf("getnameinfo() failed: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
if((strncmp(ifa->ifa_name,"p5p1",4) == 0) ||(strncmp(ifa->ifa_name,"eth0",4) == 0))
{
printf("\t we want address: <%s>\n", host);
break;
}
printf("\taddress: <%s>\n", host);
}
}
freeifaddrs(ifaddr);
return 0;//host;
}
/*****************************************************************************
º¯ Êý Ãû : parse_ts_package
¹¦ÄÜÃèÊö : ½âÎöÒ»¸öts°ü
ÊäÈë²ÎÊý : char * package
Êä³ö²ÎÊý : ÎÞ
·µ »Ø Öµ :
µ÷Óú¯Êý :
±»µ÷º¯Êý :
ÐÞ¸ÄÀúÊ· :
1.ÈÕ ÆÚ : 2014Äê4ÔÂ1ÈÕÐÇÆÚ¶þ
×÷ Õß : wei
ÐÞ¸ÄÄÚÈÝ : ÐÂÉú³Éº¯Êý
*****************************************************************************/
void parse_ts_package(unsigned char * package, int * pcr_count)
{
int index;
unsigned char *p;
signed long long pcr_time;
assert(package);
p = package;
/*p[3]:control field :01 11 10 00 first bit :control filed exit or not
* seconde bit :data exist or not
* p[4]:control field length
* p[5]:pcr exist or not 0001 0000
*/
if ( (p[3] & 0x20) && p[4] && (p[5] & 0x10))
{
// µ± PCR_flag ÓÐЧʱ£¬¶Á PCR Öµµ½»º´æ , 6B
pcr_time = ((s64)U32_AT(p[6])) << 1;
pcr_time |= (s64)(0x1&((p[10]) >> 7));
index = (* pcr_count);
g_pcr_base[index] = pcr_time;
g_pcr_ext[index] = ((u32)(p[10] & 0x1)<<8) | p[11];
pcr_info[index].pcr_byte_count = g_pcr_interval*MAX_PACKAGE_LENGTH + 11;
(* pcr_count)++;
//PCR Êý¾Ý¶ÁÈ¡Íê±Ï±êÖ¾
}
}
/*****************************************************************************
º¯ Êý Ãû : main
¹¦ÄÜÃèÊö : ´ò¿ªÎļþ·¾¶
ÊäÈë²ÎÊý : int argc
char *argv[]
Êä³ö²ÎÊý : ÎÞ
·µ »Ø Öµ :
µ÷Óú¯Êý :
±»µ÷º¯Êý :
ÐÞ¸ÄÀúÊ· :
1.ÈÕ ÆÚ : 2014Äê4ÔÂ1ÈÕÐÇÆÚ¶þ
×÷ Õß : wei
ÐÞ¸ÄÄÚÈÝ : ÐÂÉú³Éº¯Êý
*****************************************************************************/
int get_ts_transport_rate(char * path)
{
int package_count = 0,len;
int fd,i;
unsigned long long data_interval , time_interval;
unsigned long long transport_rate_tmp;
unsigned char ts_package[MAX_PACKAGE_LENGTH];
assert(path);
fd = open(path, O_RDONLY);
if ( -1 == fd )
{
printf(" open the file failed %s\n",path);
return -1;
}
while ( package_count < MAX_PACKAGE_COUNT )
{
memset(ts_package, 0, MAX_PACKAGE_LENGTH);
if ( (len = read(fd, ts_package, MAX_PACKAGE_LENGTH)) == 0 )
{
printf("read file end \n");
break;
}
parse_ts_package(ts_package,&package_count);
g_pcr_interval++;
}
for ( i = 0 ; i < package_count; i++ )
{
pcr_info[i].l_pcr = (g_pcr_base[i]*300 + g_pcr_ext[i]);
}
//give up first point ,get the average rate (totole bytes / totle pcr time)
data_interval = ((unsigned long long)(pcr_info[4].pcr_byte_count - pcr_info[1].pcr_byte_count) *1000000);
time_interval = ((pcr_info[4].l_pcr-pcr_info[1].l_pcr)/27);
transport_rate_tmp = (unsigned long long)(8* (data_interval/time_interval));
transport_rate_tmp -= (transport_rate_tmp%1000);
printf("transport rate: %lld \n",transport_rate_tmp);
return transport_rate_tmp;
}
//find a sign or num(0~9) position
void get_char_position(int *p_index, char *line, int size,int ascii_sign, int ascii_num)
{
int index ;
if ( !p_index || !line || size < 0 || *p_index >= size)
{
return;
}
index = *p_index;
while( index < size )
{
if ( (line[index]>='0') && (line[index]<='9') && ascii_num == 1)
{
*p_index = index;
return;
}
if(line[index] == ascii_sign && ascii_num == 0)
{
*p_index = index;
return;
}
index++;
}
*p_index = 0;
}
void parse_config_item(int item, int line_size, int index,char *p_line, int group_index)
{
char *p;
if ( !p_line || item > PORT_LINE || item < GROUP_NAME_LINE || line_size < 0)
{
printf("out: %d %d ",item,line_size);
return;
}
p = p_line;
switch(item)
{
case GROUP_NAME_LINE:
printf("%s\n",p_line);
break;
case PATH_NAME_LINE:
get_char_position(&index, p_line, line_size,'/',0);
if(NULL != (CONFIG_INFO.peer[group_index].path = (char *)malloc(line_size -index+1)))
{
memset(CONFIG_INFO.peer[group_index].path, 0, (line_size -index+1));
(p_line+index)[line_size -index] = 0;
strncpy(CONFIG_INFO.peer[group_index].path, p_line+index, line_size -index+1);
CONFIG_INFO.peer[group_index].path[line_size -index] = 0;
CONFIG_INFO.peer[group_index].bit_rate = get_ts_transport_rate(CONFIG_INFO.peer[group_index].path);
printf("path :%s \n", CONFIG_INFO.peer[group_index].path);
}
else
{
printf("allocate memory failed path\n");
}
break;
case IP_LINE:
get_char_position(&index, p_line, line_size,0,1);
printf("ip: %s \n",(p+index));
if ( inet_pton(AF_INET,(p+index),&CONFIG_INFO.peer[group_index].peeraddr.sin_addr) < 0 )
{
printf("wrong group address \n");
exit(EXIT_FAILURE);
}
break;
case PORT_LINE:
get_char_position(&index, p_line, line_size,0,1);
CONFIG_INFO.peer[group_index].peeraddr.sin_family =AF_INET;
printf("port : %s \n",p+index,atoi(p+index));
CONFIG_INFO.peer[group_index].peeraddr.sin_port = htons( atoi(p+index) );
break;
default:
break;
}
}
int parse_config(char *string_line, int size, int line)
{
int index = 0, equal_mark = 0 ,local_port = 10000;
char *p_buffer,*p,*p_equalmark =NULL,*p_temp,*p_slash = NULL;
static int group_index = 0;
static int item = 1;
string_line[size] = 0;
if( !string_line || size <= 0 || line <= 0 || (group_index+1) >= MAX_PEER_COUNT )
{
printf("parametre false \n");
exit(EXIT_FAILURE);
}
p_buffer = (char *)malloc(size + 1);
if ( !p_buffer)
{
printf("malloc mm failed \n");
return;
}
memset(p_buffer, 0, size + 1);
strncpy(p_buffer, string_line, size);
p_slash = p = p_buffer;
p_buffer[size] = 0;
get_char_position(&index, string_line, size, '=',0);
//printf("index %d %c totle :%d\n",index,string_line[index],totle);
if( line == 1 )
{
get_char_position(&index, string_line, size, 0,1);
CONFIG_INFO.count = atoi(p+index);
printf(" stream count :%d index :%d\n",CONFIG_INFO.count,index);
}
else
{
parse_config_item(item, size,index, p_buffer, group_index);
if(item == PORT_LINE)
{
item = 0;
group_index++;
g_stream_count = group_index;
}
item++;
}
free(p_buffer);
p_buffer = NULL;
return 0;
}
int read_config_by_line(char *pInputName)
{
char *pTempString, *pbuf_file;
u8 *p_file_buffer,*p_line_buffer;
int read_length,config_file,file_length;
long int len=0;
int i,m,n,line;
char item[512]={0};
u8 line_flag;
config_file = open(pInputName,O_RDONLY);
if( config_file >= 0 )
{
line = 1;
file_length=lseek(config_file,0,SEEK_END);
lseek(config_file,0,SEEK_SET);
if(NULL !=(p_file_buffer = (u8*)malloc(file_length)))
{
pbuf_file = p_file_buffer;
memset(pbuf_file, 0, file_length);
if( file_length == read(config_file, pbuf_file, file_length) )
{
m=n=0;
line_flag=0;
while( n < file_length )
{
if( line_flag )
{
if( pbuf_file[n]<0x20)
{
if( line_flag )
{
if( n>m )
{
parse_config(pbuf_file+m, n-m, line);
line++;
}
line_flag=0;
}
}
}
else if( pbuf_file[n]>=0x20 )
{
m=n;
line_flag=1;
}
n++;
}
if( (n > m) && (line_flag) )
{
parse_config(pbuf_file+m, n-m, ++line);
}
}
}
free(p_file_buffer);
close(config_file);
}
return 0;
}
int set_peer_parameter(int index, int *is_realloc)
{
int i;
struct stat buf;
i = index;
if ( index > CONFIG_INFO.count || index < 0 || !CONFIG_INFO.peer[i].path)
{
return -1;
}
g_fd_id[i] = open(CONFIG_INFO.peer[i].path, O_RDONLY);
if( g_fd_id[i] == -1)
{
printf("creat or open failed index :%d path :%s\n",i,CONFIG_INFO.peer[i].path);
perror("socket");
return;
}
sockid[i] = socket(AF_INET, SOCK_DGRAM, 0);
if( sockid[i] < 0 )
{
printf("creat or open failed index :%d path :%s\n",i,CONFIG_INFO.peer[i].path);
perror("socket");
return -1;
}
stat(CONFIG_INFO.peer[i].path, &buf);
if ( -1 != buf.st_size )
{
CONFIG_INFO.peer[i].totle_time = ((8*(buf.st_size))/CONFIG_INFO.peer[i].bit_rate);
printf(" totle time :%d bitrate :%d\n",CONFIG_INFO.peer[i].totle_time ,CONFIG_INFO.peer[i].bit_rate );
}
CONFIG_INFO.peer[i].bit_rate = get_ts_transport_rate(CONFIG_INFO.peer[i].path);
if ( g_byte_per_Xms < (CONFIG_INFO.peer[i].bit_rate/(8*(1000/SLEEP_TIME_MS))))
{
g_byte_per_Xms = (CONFIG_INFO.peer[i].bit_rate/(8*(1000/SLEEP_TIME_MS)));
*is_realloc = 1;
}
CONFIG_INFO.peer[i].beused = 1;
return 0;
}
void play_ts_timer(int times)
{
int i;
if ( times %(1000/SLEEP_TIME_MS) == 0 && times != 0)
{
for ( i = 0 ; i < CONFIG_INFO.count; i++ )
{
if ( CONFIG_INFO.peer[i].beused )
{
CONFIG_INFO.peer[i].current++;
}
}
}
}
void sleep_xms( struct timeval start, struct timeval current,int times)
{
long next_start,current_begin;
unsigned long diff;
gettimeofday(¤t, NULL);
next_start = (1000000*start.tv_sec + (start.tv_usec + times *1000*SLEEP_TIME_MS));
current_begin = (1000000*current.tv_sec + current.tv_usec);
if ( next_start > current_begin )
{
diff = next_start - current_begin;
}
else
{
diff = 0;
}
//printf(" sleep %ld \n",diff);
usleep(diff);
}
void udp_send_ts_package(void)
{
int i,index = 0;
int res,len,is_realloc;
char *p_buffer;
int times = 0,send_len = 0;
char *p = NULL;
long send_length = 0;
int read_length;
struct sockaddr_in srv,local;
struct timeval start;
struct timeval current;
unsigned char send_buf[SEND_LENGTH+1];
for ( i = 0 ; i < CONFIG_INFO.count; i++ )
{
set_peer_parameter(i, &is_realloc);
}
p_buffer = (char *)malloc(g_byte_per_Xms+1);
if ( !p_buffer )
{
printf("[producer_read_file] allocate buffer failed \n");
return;
}
gettimeofday(&start, NULL);
while ( 1 )
{
if ( !CONFIG_INFO.peer[index].beused )
{
index++;
if ( index >= (CONFIG_INFO.count-1))
{
index = 0;
}
continue;
}
memset( &local, 0, sizeof(local) );
memset( &srv, 0, sizeof(srv) );
pthread_mutex_lock(&g_work_mutex);
srv.sin_family = AF_INET;
srv.sin_port = CONFIG_INFO.peer[index].peeraddr.sin_port;//htons(PUERTO);
srv.sin_addr = CONFIG_INFO.peer[index].peeraddr.sin_addr;
g_byte_per_Xms = (CONFIG_INFO.peer[index].bit_rate/(8*(1000/SLEEP_TIME_MS)));
pthread_mutex_unlock(&g_work_mutex);
if ( (read_length = read(g_fd_id[index],p_buffer,g_byte_per_Xms)) == 0 )
{
lseek(g_fd_id[index], 0, SEEK_SET);
gettimeofday(&start, NULL);
times = 0;
CONFIG_INFO.peer[index].current = 0;
pthread_mutex_unlock(&g_work_mutex);
continue;
}
pthread_mutex_unlock(&g_work_mutex);
p = p_buffer;
send_length = 0;
while ( send_length < read_length)
{
len = SEND_LENGTH;
if ( (read_length - send_length) < SEND_LENGTH )
{
len = (read_length - send_length);
}
memcpy(send_buf, p, len);
send_buf[len] = 0;
if( (send_len = sendto(sockid[index], send_buf, len, 0, (struct sockaddr *)&srv, sizeof(srv))) < 0 )
{
perror("sendto erro");
}
else
{
//fprintf(stdout, "Enviado a send: %d totole: %d \n", send_len,g_byte_per_Xms);
}
send_length += SEND_LENGTH;
p += SEND_LENGTH;
}
if ( index < (CONFIG_INFO.count-1))
{
index++;
}
else
{
index = 0;
times++;
sleep_xms(start, current, times);
play_ts_timer(times);
}
}
free(p_buffer);
printf("send SUCCESS \n");
}
int parse_command(char *command)
{
int flag = 0,argc = 0;
char *p,*pstart_point,*pend_point,len,command_num = 0,index = 0;
char buf[MAX_COMMOND_SIZE] = {0};
if ( !command )
{
printf("invalible pointer \n");
return 0;
}
//printf(" command : %d \n",strlen(command));
strncpy(buf, command, strlen(command));
len = strlen(command);
memset(g_argv, 0, 5*255);
//printf("current command :%s len:%d\n",buf,len);
p= pstart_point = buf;
while ( index < len )
{
if ( p[0] != ' ' && flag == 0)
{
pstart_point = p;
flag = 1;
}
if( ((index == (len - 1)) || (p[0] == ' ')) && (pstart_point != pend_point) )
{
pend_point = p;
strncpy(g_argv[command_num], pstart_point, (pend_point-pstart_point));
g_argv[command_num][pend_point-pstart_point] = 0;
command_num++;
pstart_point = pend_point;
flag = 0;
}
p++;
index++;
}
argc = command_num;
return argc;
}
void add_peer_info(int index)
{
int len = 0,is_realloc = 0;
struct stat buf;
printf("create_new_node come in \n");
len = strlen(g_argv[1]);
if ( len > MAX_PATH_LENGTH )
{
printf("too deep path ,failed :%d\n",len);
exit(EXIT_FAILURE);
}
strncpy(CONFIG_INFO.peer[index].path, g_argv[1], len);
CONFIG_INFO.peer[index].path[len] = 0;
printf("name :%s \n",CONFIG_INFO.peer[index].path);
//start /tmp/bmw.mpg 192.168.102.8 12345 3473000
if ( inet_pton(AF_INET,(char *)&g_argv[2],(char *)&CONFIG_INFO.peer[index].peeraddr.sin_addr) < 0 )
{
printf("wrong group address \n");
exit(EXIT_FAILURE);
}
CONFIG_INFO.peer[index].peeraddr.sin_family =AF_INET;
CONFIG_INFO.peer[index].peeraddr.sin_port = htons(atoi(g_argv[3]));
set_peer_parameter(index, &is_realloc);
if ( 1 == is_realloc )
{
pthread_mutex_lock(&g_work_mutex);
unsigned char *q = (unsigned char *)realloc(p_max_buffer, g_byte_per_Xms);
if(q != NULL)
{
p_max_buffer = q;
}
pthread_mutex_unlock(&g_work_mutex);
}
}
void check_unused_peer(int *p_index)
{
int i;
for ( i = 0 ; i < CONFIG_INFO.count; i++ )
{
if ( CONFIG_INFO.peer[i].beused == 0)
{
CONFIG_INFO.peer[i].beused = 1;
CONFIG_INFO.peer[i].current = 0;
*p_index = i;
return;
}
}
CONFIG_INFO.count++;
CONFIG_INFO.peer[i].current = 0;
CONFIG_INFO.peer[i].path =(char *) malloc(strlen(g_argv[1]) + 1);
if ( !CONFIG_INFO.peer[i].path )
{
printf("allocate memory failed \n");
return;
}
CONFIG_INFO.peer[i].path[strlen(g_argv[1])] = 0;
*p_index = i;
}
void do_command_start(void)
{
printf("command_play_new_ts come in \n");
int i,len = 0;
if ( g_argc != 5 )
{
return;
}
check_unused_peer(&i);
add_peer_info(i);
}
void show_ts_time(int index)
{
struct day tm_now_info;
struct day tm_totle_info;
if ( (index >= CONFIG_INFO.count) || index < 0 )
{
return;
}
tm_now_info.hour = CONFIG_INFO.peer[index].current/3600;
tm_now_info.minute = (CONFIG_INFO.peer[index].current - tm_now_info.hour*3600)/60;
tm_now_info.second = (CONFIG_INFO.peer[index].current - tm_now_info.hour*3600 - tm_now_info.minute*60);
tm_totle_info.hour = CONFIG_INFO.peer[index].totle_time/3600;
tm_totle_info.minute = (CONFIG_INFO.peer[index].totle_time - tm_totle_info.hour*3600)/60;
tm_totle_info.second = (CONFIG_INFO.peer[index].totle_time - tm_totle_info.hour*3600 - tm_totle_info.minute*60);
printf(" %d %s %d:%d:%d %d:%d:%d \n",index,CONFIG_INFO.peer[index].path,\
tm_now_info.hour, tm_now_info.minute, tm_now_info.second,\
tm_totle_info.hour, tm_totle_info.minute, tm_totle_info.second);
}
void do_command_list(void)
{
int i,index = 0;
index= g_argv[1][0] - '0';
if ( g_argc > 2 || g_argc < 0)
{
return;
}
if ( g_argc == 2 && index < CONFIG_INFO.count && index > 0)
{
if ( CONFIG_INFO.peer[index].beused )
{
show_ts_time(index);
}
return ;
}
for ( i = 0 ; i < CONFIG_INFO.count; i++ )
{
if ( CONFIG_INFO.peer[i].beused )
{
show_ts_time(i);
}
}
}
void do_command_kill(void)
{
int i,index = 0;
index = g_argv[1][0] - '0';
if ( 2 != g_argc && index >= CONFIG_INFO.count && index < 0)
{
return;
}
if ( CONFIG_INFO.peer[index].beused )
{
pthread_mutex_lock(&g_work_mutex);
CONFIG_INFO.peer[i].beused = 0;
close(g_fd_id[i]);
pthread_mutex_unlock(&g_work_mutex);
}
}
void * get_user_command(void *arg)
{
char *p;
int index = 0,i, free_node = 0,len = 0;
char buf[MAX_COMMOND_SIZE] = {0};
memset(buf, 0, MAX_COMMOND_SIZE);
while ( 1 )
{
printf("input the control commond \n");
printf("you can use command : \n\
1. list eg : list (all) ,l or list n \n\
2. start eg : start/s path ip port bitrate \n\
3. kill eg : kill (all) , k or kill n \n\
\n>");
memset(g_argv, 0, 5*255);
fgets(buf, MAX_COMMOND_SIZE-1, stdin);
g_argc = parse_command(buf);
//printf("command parse finish,start to process :%s \n", g_argv[0]);
if ( !strncasecmp(g_argv[0], "list", 4)||((strlen(buf) == 1)&&(strncasecmp(g_argv[0], "l", 1))))
{
printf(" index file start time end time \n");
do_command_list();
continue;
}
else if ( !strncasecmp(g_argv[0], "start", 4)||((strlen(buf) == 1)&&(strncasecmp(g_argv[0], "s", 1))))
{
pthread_mutex_lock(&g_work_mutex);
do_command_start();
pthread_mutex_unlock(&g_work_mutex);
continue;
}
else if ( !strncasecmp(g_argv[0], "kill", 4)||((strlen(buf) == 1)&&(strncasecmp(g_argv[0], "k", 1))))
{
do_command_kill();
continue;
}
else
{
printf("do nothing \n");
continue;
}
}
}
int main(int argc, char *argv[])
{
int i,res;
char *ip;
char *path = "udp_config";
char function_name[255] ={0};
pthread_t id[MAX_PEER_COUNT];
memset(&CONFIG_INFO, 0, sizeof(CONFIG_INFO));
read_config_by_line(path);
if( g_stream_count != CONFIG_INFO.count )
{
CONFIG_INFO.count = g_stream_count;
printf("config mistake ,real stream count :%d \n",CONFIG_INFO.count);
}
res = pthread_mutex_init(&g_work_mutex, NULL);
if ( 0 != res )
{
printf("Mutex initialization failed \n");
return -1;
}
pthread_create(&id[0], NULL, (void *) *get_user_command, NULL);
udp_send_ts_package();
//send_ts_package();
return 0;
}
°æȨËùÓÐ (C), 2001-2011, ÉñÖÝÊýÂëÍøÂçÓÐÏÞ¹«Ë¾
******************************************************************************
ÎÄ ¼þ Ãû : pthread_send_udp5_org.c
°æ ±¾ ºÅ : ³õ¸å
×÷ Õß : wei
Éú³ÉÈÕÆÚ : 2014Äê3ÔÂ28ÈÕÐÇÆÚÎå
×î½üÐÞ¸Ä :
¹¦ÄÜÃèÊö :
º¯ÊýÁбí :
command_kill
command_play_new_ts
command_show_list
create_new_node
debug_malloc
GetLocalIp
get_input
read_config_by_line
main
parse_command
parse_config
sig_usr
test_malloc
udp_send_ts_package
ÐÞ¸ÄÀúÊ· :
1.ÈÕ ÆÚ : 2014Äê3ÔÂ28ÈÕÐÇÆÚÎå
×÷ Õß : wei
ÐÞ¸ÄÄÚÈÝ : ´´½¨Îļþ
******************************************************************************/
/*----------------------------------------------*
* °üº¬Í·Îļþ *
*----------------------------------------------*/
#include <stdio.h> //printf()
#include <unistd.h> //pause()
#include <signal.h> //signal()
#include <string.h> //memset()
#include <sys/time.h> //struct itimerval, setitimer()
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <bits/pthreadtypes.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <netdb.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <sys/ioctl.h>
#include <ifaddrs.h>
#include <semaphore.h>
#include <assert.h>
/*----------------------------------------------*
* ºê¶¨Òå *
*----------------------------------------------*/
#define MAX_PEER_COUNT 250
#define GROUP_NAME_LINE 1
#define PATH_NAME_LINE 2
#define IP_LINE 3
#define PORT_LINE 4
#define BITRATE_LINE 5
#define MAX_PATH_LENGTH 255
#define SEND_LENGTH 7*188
#define MAX_COMMOND_SIZE 255
#define SLEEP_TIME_MS 4
int bits=sizeof(long);
#if bits == 32
#define s64 long
#else
#define s64 long long
#endif
//typedef signed long long s64;
#define U32_AT(n) ( (((u32)((u8*)&(n))[0]) << 24) \
| (((u32)((u8*)&(n))[1]) << 16) \
| (((u32)((u8*)&(n))[2]) << 8) \
| (((u32)((u8*)&(n))[3])) )
//#define s64 long long
#define MAX_PACKAGE_COUNT 5
#define MAX_PACKAGE_LENGTH 188
typedef unsigned long u32;
typedef unsigned char u8;
typedef int BOOL;
#ifdef DEBUG
void *debug_malloc(size_t size, const char *file, int line, const char *func)
{
void *p;
p = malloc(size);
printf("%s:%d:%s:malloc(%ld): p=0x%lx\n",file, line, func, size, (unsigned long)p);
return p;
}
#define malloc(s) debug_malloc(s, __FILE__, __LINE__, __func__)
#define free(p) do { \
printf("%s:%d:%s:free(0x%lx)\n", __FILE__, __LINE__, \
__func__, (unsigned long)p); \
if(p) { \
free(p); \
p= NULL; \
} \
} while (0)
#endif
/*----------------------------------------------*
* Íⲿ±äÁ¿ËµÃ÷ *
*----------------------------------------------*/
/*----------------------------------------------*
* Íⲿº¯ÊýÔÐÍ˵Ã÷ *
*----------------------------------------------*/
/*----------------------------------------------*
* ÄÚ²¿º¯ÊýÔÐÍ˵Ã÷ *
*----------------------------------------------*/
/*----------------------------------------------*
* È«¾Ö±äÁ¿ *
*----------------------------------------------*/
static unsigned char *p_max_buffer;
static signed long long g_pcr_base[MAX_PACKAGE_COUNT];
static unsigned long g_pcr_ext[MAX_PACKAGE_COUNT];
static int g_byte_per_Xms;
//static struct timeval g_start;
//static s64 pcr_time;
struct adjoin_pcr
{
int pcr_byte_count;
s64 l_pcr;
}pcr_info[MAX_PACKAGE_COUNT];
static int g_pcr_interval;
/*----------------------------------------------*
* Ä£¿é¼¶±äÁ¿ *
*----------------------------------------------*/
struct day
{
int hour;
int minute;
int second;
};
struct udp_send_info
{
int beused;
time_t current;
time_t totle_time;
char *path;
struct sockaddr_in peeraddr;
unsigned long long bit_rate;
};
struct config_info
{
int count;
struct udp_send_info peer[MAX_PEER_COUNT];
}CONFIG_INFO;
/*----------------------------------------------*
* ³£Á¿¶¨Òå *
*----------------------------------------------*/
static u8 g_stream_count;
static char g_argv[5][255];
static int g_fd_id[MAX_PEER_COUNT];
static int sockid[MAX_PEER_COUNT];
static int g_argc;
static pthread_mutex_t g_work_mutex;
void test_malloc(void)
{
char *p_test = NULL;
//while ( 1 )
{
p_test = (char *)malloc(100);
if ( p_test )
{
printf("malloc sucess \n");
free(p_test);
}
}
}
char * get_local_ip(void)
{
struct ifaddrs *ifaddr, *ifa;
int family, s;
char host[NI_MAXHOST];
if ( getifaddrs(&ifaddr) == -1 )
{
perror("getifaddrs");
exit(EXIT_FAILURE);
}
/* Walk through linked list, maintaining head pointer so we
* can free list later */
for ( ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next )
{
if (ifa->ifa_addr == NULL)
continue;
family = ifa->ifa_addr->sa_family;
/* Display interface name and family (including symbolic
* form of the latter for the common families) */
printf("%s address family: %d%s\n",
ifa->ifa_name, family,
(family == AF_PACKET) ? " (AF_PACKET)" :
(family == AF_INET) ? " (AF_INET)" :
(family == AF_INET6) ? " (AF_INET6)" : "");
/* For an AF_INET* interface address, display the address */
if (family == AF_INET /* family == AF_INET6*/) {
s = getnameinfo(ifa->ifa_addr,
(family == AF_INET) ? sizeof(struct sockaddr_in) :
sizeof(struct sockaddr_in6),
host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if (s != 0)
{
printf("getnameinfo() failed: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
if((strncmp(ifa->ifa_name,"p5p1",4) == 0) ||(strncmp(ifa->ifa_name,"eth0",4) == 0))
{
printf("\t we want address: <%s>\n", host);
break;
}
printf("\taddress: <%s>\n", host);
}
}
freeifaddrs(ifaddr);
return 0;//host;
}
/*****************************************************************************
º¯ Êý Ãû : parse_ts_package
¹¦ÄÜÃèÊö : ½âÎöÒ»¸öts°ü
ÊäÈë²ÎÊý : char * package
Êä³ö²ÎÊý : ÎÞ
·µ »Ø Öµ :
µ÷Óú¯Êý :
±»µ÷º¯Êý :
ÐÞ¸ÄÀúÊ· :
1.ÈÕ ÆÚ : 2014Äê4ÔÂ1ÈÕÐÇÆÚ¶þ
×÷ Õß : wei
ÐÞ¸ÄÄÚÈÝ : ÐÂÉú³Éº¯Êý
*****************************************************************************/
void parse_ts_package(unsigned char * package, int * pcr_count)
{
int index;
unsigned char *p;
signed long long pcr_time;
assert(package);
p = package;
/*p[3]:control field :01 11 10 00 first bit :control filed exit or not
* seconde bit :data exist or not
* p[4]:control field length
* p[5]:pcr exist or not 0001 0000
*/
if ( (p[3] & 0x20) && p[4] && (p[5] & 0x10))
{
// µ± PCR_flag ÓÐЧʱ£¬¶Á PCR Öµµ½»º´æ , 6B
pcr_time = ((s64)U32_AT(p[6])) << 1;
pcr_time |= (s64)(0x1&((p[10]) >> 7));
index = (* pcr_count);
g_pcr_base[index] = pcr_time;
g_pcr_ext[index] = ((u32)(p[10] & 0x1)<<8) | p[11];
pcr_info[index].pcr_byte_count = g_pcr_interval*MAX_PACKAGE_LENGTH + 11;
(* pcr_count)++;
//PCR Êý¾Ý¶ÁÈ¡Íê±Ï±êÖ¾
}
}
/*****************************************************************************
º¯ Êý Ãû : main
¹¦ÄÜÃèÊö : ´ò¿ªÎļþ·¾¶
ÊäÈë²ÎÊý : int argc
char *argv[]
Êä³ö²ÎÊý : ÎÞ
·µ »Ø Öµ :
µ÷Óú¯Êý :
±»µ÷º¯Êý :
ÐÞ¸ÄÀúÊ· :
1.ÈÕ ÆÚ : 2014Äê4ÔÂ1ÈÕÐÇÆÚ¶þ
×÷ Õß : wei
ÐÞ¸ÄÄÚÈÝ : ÐÂÉú³Éº¯Êý
*****************************************************************************/
int get_ts_transport_rate(char * path)
{
int package_count = 0,len;
int fd,i;
unsigned long long data_interval , time_interval;
unsigned long long transport_rate_tmp;
unsigned char ts_package[MAX_PACKAGE_LENGTH];
assert(path);
fd = open(path, O_RDONLY);
if ( -1 == fd )
{
printf(" open the file failed %s\n",path);
return -1;
}
while ( package_count < MAX_PACKAGE_COUNT )
{
memset(ts_package, 0, MAX_PACKAGE_LENGTH);
if ( (len = read(fd, ts_package, MAX_PACKAGE_LENGTH)) == 0 )
{
printf("read file end \n");
break;
}
parse_ts_package(ts_package,&package_count);
g_pcr_interval++;
}
for ( i = 0 ; i < package_count; i++ )
{
pcr_info[i].l_pcr = (g_pcr_base[i]*300 + g_pcr_ext[i]);
}
//give up first point ,get the average rate (totole bytes / totle pcr time)
data_interval = ((unsigned long long)(pcr_info[4].pcr_byte_count - pcr_info[1].pcr_byte_count) *1000000);
time_interval = ((pcr_info[4].l_pcr-pcr_info[1].l_pcr)/27);
transport_rate_tmp = (unsigned long long)(8* (data_interval/time_interval));
transport_rate_tmp -= (transport_rate_tmp%1000);
printf("transport rate: %lld \n",transport_rate_tmp);
return transport_rate_tmp;
}
//find a sign or num(0~9) position
void get_char_position(int *p_index, char *line, int size,int ascii_sign, int ascii_num)
{
int index ;
if ( !p_index || !line || size < 0 || *p_index >= size)
{
return;
}
index = *p_index;
while( index < size )
{
if ( (line[index]>='0') && (line[index]<='9') && ascii_num == 1)
{
*p_index = index;
return;
}
if(line[index] == ascii_sign && ascii_num == 0)
{
*p_index = index;
return;
}
index++;
}
*p_index = 0;
}
void parse_config_item(int item, int line_size, int index,char *p_line, int group_index)
{
char *p;
if ( !p_line || item > PORT_LINE || item < GROUP_NAME_LINE || line_size < 0)
{
printf("out: %d %d ",item,line_size);
return;
}
p = p_line;
switch(item)
{
case GROUP_NAME_LINE:
printf("%s\n",p_line);
break;
case PATH_NAME_LINE:
get_char_position(&index, p_line, line_size,'/',0);
if(NULL != (CONFIG_INFO.peer[group_index].path = (char *)malloc(line_size -index+1)))
{
memset(CONFIG_INFO.peer[group_index].path, 0, (line_size -index+1));
(p_line+index)[line_size -index] = 0;
strncpy(CONFIG_INFO.peer[group_index].path, p_line+index, line_size -index+1);
CONFIG_INFO.peer[group_index].path[line_size -index] = 0;
CONFIG_INFO.peer[group_index].bit_rate = get_ts_transport_rate(CONFIG_INFO.peer[group_index].path);
printf("path :%s \n", CONFIG_INFO.peer[group_index].path);
}
else
{
printf("allocate memory failed path\n");
}
break;
case IP_LINE:
get_char_position(&index, p_line, line_size,0,1);
printf("ip: %s \n",(p+index));
if ( inet_pton(AF_INET,(p+index),&CONFIG_INFO.peer[group_index].peeraddr.sin_addr) < 0 )
{
printf("wrong group address \n");
exit(EXIT_FAILURE);
}
break;
case PORT_LINE:
get_char_position(&index, p_line, line_size,0,1);
CONFIG_INFO.peer[group_index].peeraddr.sin_family =AF_INET;
printf("port : %s \n",p+index,atoi(p+index));
CONFIG_INFO.peer[group_index].peeraddr.sin_port = htons( atoi(p+index) );
break;
default:
break;
}
}
int parse_config(char *string_line, int size, int line)
{
int index = 0, equal_mark = 0 ,local_port = 10000;
char *p_buffer,*p,*p_equalmark =NULL,*p_temp,*p_slash = NULL;
static int group_index = 0;
static int item = 1;
string_line[size] = 0;
if( !string_line || size <= 0 || line <= 0 || (group_index+1) >= MAX_PEER_COUNT )
{
printf("parametre false \n");
exit(EXIT_FAILURE);
}
p_buffer = (char *)malloc(size + 1);
if ( !p_buffer)
{
printf("malloc mm failed \n");
return;
}
memset(p_buffer, 0, size + 1);
strncpy(p_buffer, string_line, size);
p_slash = p = p_buffer;
p_buffer[size] = 0;
get_char_position(&index, string_line, size, '=',0);
//printf("index %d %c totle :%d\n",index,string_line[index],totle);
if( line == 1 )
{
get_char_position(&index, string_line, size, 0,1);
CONFIG_INFO.count = atoi(p+index);
printf(" stream count :%d index :%d\n",CONFIG_INFO.count,index);
}
else
{
parse_config_item(item, size,index, p_buffer, group_index);
if(item == PORT_LINE)
{
item = 0;
group_index++;
g_stream_count = group_index;
}
item++;
}
free(p_buffer);
p_buffer = NULL;
return 0;
}
int read_config_by_line(char *pInputName)
{
char *pTempString, *pbuf_file;
u8 *p_file_buffer,*p_line_buffer;
int read_length,config_file,file_length;
long int len=0;
int i,m,n,line;
char item[512]={0};
u8 line_flag;
config_file = open(pInputName,O_RDONLY);
if( config_file >= 0 )
{
line = 1;
file_length=lseek(config_file,0,SEEK_END);
lseek(config_file,0,SEEK_SET);
if(NULL !=(p_file_buffer = (u8*)malloc(file_length)))
{
pbuf_file = p_file_buffer;
memset(pbuf_file, 0, file_length);
if( file_length == read(config_file, pbuf_file, file_length) )
{
m=n=0;
line_flag=0;
while( n < file_length )
{
if( line_flag )
{
if( pbuf_file[n]<0x20)
{
if( line_flag )
{
if( n>m )
{
parse_config(pbuf_file+m, n-m, line);
line++;
}
line_flag=0;
}
}
}
else if( pbuf_file[n]>=0x20 )
{
m=n;
line_flag=1;
}
n++;
}
if( (n > m) && (line_flag) )
{
parse_config(pbuf_file+m, n-m, ++line);
}
}
}
free(p_file_buffer);
close(config_file);
}
return 0;
}
int set_peer_parameter(int index, int *is_realloc)
{
int i;
struct stat buf;
i = index;
if ( index > CONFIG_INFO.count || index < 0 || !CONFIG_INFO.peer[i].path)
{
return -1;
}
g_fd_id[i] = open(CONFIG_INFO.peer[i].path, O_RDONLY);
if( g_fd_id[i] == -1)
{
printf("creat or open failed index :%d path :%s\n",i,CONFIG_INFO.peer[i].path);
perror("socket");
return;
}
sockid[i] = socket(AF_INET, SOCK_DGRAM, 0);
if( sockid[i] < 0 )
{
printf("creat or open failed index :%d path :%s\n",i,CONFIG_INFO.peer[i].path);
perror("socket");
return -1;
}
stat(CONFIG_INFO.peer[i].path, &buf);
if ( -1 != buf.st_size )
{
CONFIG_INFO.peer[i].totle_time = ((8*(buf.st_size))/CONFIG_INFO.peer[i].bit_rate);
printf(" totle time :%d bitrate :%d\n",CONFIG_INFO.peer[i].totle_time ,CONFIG_INFO.peer[i].bit_rate );
}
CONFIG_INFO.peer[i].bit_rate = get_ts_transport_rate(CONFIG_INFO.peer[i].path);
if ( g_byte_per_Xms < (CONFIG_INFO.peer[i].bit_rate/(8*(1000/SLEEP_TIME_MS))))
{
g_byte_per_Xms = (CONFIG_INFO.peer[i].bit_rate/(8*(1000/SLEEP_TIME_MS)));
*is_realloc = 1;
}
CONFIG_INFO.peer[i].beused = 1;
return 0;
}
void play_ts_timer(int times)
{
int i;
if ( times %(1000/SLEEP_TIME_MS) == 0 && times != 0)
{
for ( i = 0 ; i < CONFIG_INFO.count; i++ )
{
if ( CONFIG_INFO.peer[i].beused )
{
CONFIG_INFO.peer[i].current++;
}
}
}
}
void sleep_xms( struct timeval start, struct timeval current,int times)
{
long next_start,current_begin;
unsigned long diff;
gettimeofday(¤t, NULL);
next_start = (1000000*start.tv_sec + (start.tv_usec + times *1000*SLEEP_TIME_MS));
current_begin = (1000000*current.tv_sec + current.tv_usec);
if ( next_start > current_begin )
{
diff = next_start - current_begin;
}
else
{
diff = 0;
}
//printf(" sleep %ld \n",diff);
usleep(diff);
}
void udp_send_ts_package(void)
{
int i,index = 0;
int res,len,is_realloc;
char *p_buffer;
int times = 0,send_len = 0;
char *p = NULL;
long send_length = 0;
int read_length;
struct sockaddr_in srv,local;
struct timeval start;
struct timeval current;
unsigned char send_buf[SEND_LENGTH+1];
for ( i = 0 ; i < CONFIG_INFO.count; i++ )
{
set_peer_parameter(i, &is_realloc);
}
p_buffer = (char *)malloc(g_byte_per_Xms+1);
if ( !p_buffer )
{
printf("[producer_read_file] allocate buffer failed \n");
return;
}
gettimeofday(&start, NULL);
while ( 1 )
{
if ( !CONFIG_INFO.peer[index].beused )
{
index++;
if ( index >= (CONFIG_INFO.count-1))
{
index = 0;
}
continue;
}
memset( &local, 0, sizeof(local) );
memset( &srv, 0, sizeof(srv) );
pthread_mutex_lock(&g_work_mutex);
srv.sin_family = AF_INET;
srv.sin_port = CONFIG_INFO.peer[index].peeraddr.sin_port;//htons(PUERTO);
srv.sin_addr = CONFIG_INFO.peer[index].peeraddr.sin_addr;
g_byte_per_Xms = (CONFIG_INFO.peer[index].bit_rate/(8*(1000/SLEEP_TIME_MS)));
pthread_mutex_unlock(&g_work_mutex);
if ( (read_length = read(g_fd_id[index],p_buffer,g_byte_per_Xms)) == 0 )
{
lseek(g_fd_id[index], 0, SEEK_SET);
gettimeofday(&start, NULL);
times = 0;
CONFIG_INFO.peer[index].current = 0;
pthread_mutex_unlock(&g_work_mutex);
continue;
}
pthread_mutex_unlock(&g_work_mutex);
p = p_buffer;
send_length = 0;
while ( send_length < read_length)
{
len = SEND_LENGTH;
if ( (read_length - send_length) < SEND_LENGTH )
{
len = (read_length - send_length);
}
memcpy(send_buf, p, len);
send_buf[len] = 0;
if( (send_len = sendto(sockid[index], send_buf, len, 0, (struct sockaddr *)&srv, sizeof(srv))) < 0 )
{
perror("sendto erro");
}
else
{
//fprintf(stdout, "Enviado a send: %d totole: %d \n", send_len,g_byte_per_Xms);
}
send_length += SEND_LENGTH;
p += SEND_LENGTH;
}
if ( index < (CONFIG_INFO.count-1))
{
index++;
}
else
{
index = 0;
times++;
sleep_xms(start, current, times);
play_ts_timer(times);
}
}
free(p_buffer);
printf("send SUCCESS \n");
}
int parse_command(char *command)
{
int flag = 0,argc = 0;
char *p,*pstart_point,*pend_point,len,command_num = 0,index = 0;
char buf[MAX_COMMOND_SIZE] = {0};
if ( !command )
{
printf("invalible pointer \n");
return 0;
}
//printf(" command : %d \n",strlen(command));
strncpy(buf, command, strlen(command));
len = strlen(command);
memset(g_argv, 0, 5*255);
//printf("current command :%s len:%d\n",buf,len);
p= pstart_point = buf;
while ( index < len )
{
if ( p[0] != ' ' && flag == 0)
{
pstart_point = p;
flag = 1;
}
if( ((index == (len - 1)) || (p[0] == ' ')) && (pstart_point != pend_point) )
{
pend_point = p;
strncpy(g_argv[command_num], pstart_point, (pend_point-pstart_point));
g_argv[command_num][pend_point-pstart_point] = 0;
command_num++;
pstart_point = pend_point;
flag = 0;
}
p++;
index++;
}
argc = command_num;
return argc;
}
void add_peer_info(int index)
{
int len = 0,is_realloc = 0;
struct stat buf;
printf("create_new_node come in \n");
len = strlen(g_argv[1]);
if ( len > MAX_PATH_LENGTH )
{
printf("too deep path ,failed :%d\n",len);
exit(EXIT_FAILURE);
}
strncpy(CONFIG_INFO.peer[index].path, g_argv[1], len);
CONFIG_INFO.peer[index].path[len] = 0;
printf("name :%s \n",CONFIG_INFO.peer[index].path);
//start /tmp/bmw.mpg 192.168.102.8 12345 3473000
if ( inet_pton(AF_INET,(char *)&g_argv[2],(char *)&CONFIG_INFO.peer[index].peeraddr.sin_addr) < 0 )
{
printf("wrong group address \n");
exit(EXIT_FAILURE);
}
CONFIG_INFO.peer[index].peeraddr.sin_family =AF_INET;
CONFIG_INFO.peer[index].peeraddr.sin_port = htons(atoi(g_argv[3]));
set_peer_parameter(index, &is_realloc);
if ( 1 == is_realloc )
{
pthread_mutex_lock(&g_work_mutex);
unsigned char *q = (unsigned char *)realloc(p_max_buffer, g_byte_per_Xms);
if(q != NULL)
{
p_max_buffer = q;
}
pthread_mutex_unlock(&g_work_mutex);
}
}
void check_unused_peer(int *p_index)
{
int i;
for ( i = 0 ; i < CONFIG_INFO.count; i++ )
{
if ( CONFIG_INFO.peer[i].beused == 0)
{
CONFIG_INFO.peer[i].beused = 1;
CONFIG_INFO.peer[i].current = 0;
*p_index = i;
return;
}
}
CONFIG_INFO.count++;
CONFIG_INFO.peer[i].current = 0;
CONFIG_INFO.peer[i].path =(char *) malloc(strlen(g_argv[1]) + 1);
if ( !CONFIG_INFO.peer[i].path )
{
printf("allocate memory failed \n");
return;
}
CONFIG_INFO.peer[i].path[strlen(g_argv[1])] = 0;
*p_index = i;
}
void do_command_start(void)
{
printf("command_play_new_ts come in \n");
int i,len = 0;
if ( g_argc != 5 )
{
return;
}
check_unused_peer(&i);
add_peer_info(i);
}
void show_ts_time(int index)
{
struct day tm_now_info;
struct day tm_totle_info;
if ( (index >= CONFIG_INFO.count) || index < 0 )
{
return;
}
tm_now_info.hour = CONFIG_INFO.peer[index].current/3600;
tm_now_info.minute = (CONFIG_INFO.peer[index].current - tm_now_info.hour*3600)/60;
tm_now_info.second = (CONFIG_INFO.peer[index].current - tm_now_info.hour*3600 - tm_now_info.minute*60);
tm_totle_info.hour = CONFIG_INFO.peer[index].totle_time/3600;
tm_totle_info.minute = (CONFIG_INFO.peer[index].totle_time - tm_totle_info.hour*3600)/60;
tm_totle_info.second = (CONFIG_INFO.peer[index].totle_time - tm_totle_info.hour*3600 - tm_totle_info.minute*60);
printf(" %d %s %d:%d:%d %d:%d:%d \n",index,CONFIG_INFO.peer[index].path,\
tm_now_info.hour, tm_now_info.minute, tm_now_info.second,\
tm_totle_info.hour, tm_totle_info.minute, tm_totle_info.second);
}
void do_command_list(void)
{
int i,index = 0;
index= g_argv[1][0] - '0';
if ( g_argc > 2 || g_argc < 0)
{
return;
}
if ( g_argc == 2 && index < CONFIG_INFO.count && index > 0)
{
if ( CONFIG_INFO.peer[index].beused )
{
show_ts_time(index);
}
return ;
}
for ( i = 0 ; i < CONFIG_INFO.count; i++ )
{
if ( CONFIG_INFO.peer[i].beused )
{
show_ts_time(i);
}
}
}
void do_command_kill(void)
{
int i,index = 0;
index = g_argv[1][0] - '0';
if ( 2 != g_argc && index >= CONFIG_INFO.count && index < 0)
{
return;
}
if ( CONFIG_INFO.peer[index].beused )
{
pthread_mutex_lock(&g_work_mutex);
CONFIG_INFO.peer[i].beused = 0;
close(g_fd_id[i]);
pthread_mutex_unlock(&g_work_mutex);
}
}
void * get_user_command(void *arg)
{
char *p;
int index = 0,i, free_node = 0,len = 0;
char buf[MAX_COMMOND_SIZE] = {0};
memset(buf, 0, MAX_COMMOND_SIZE);
while ( 1 )
{
printf("input the control commond \n");
printf("you can use command : \n\
1. list eg : list (all) ,l or list n \n\
2. start eg : start/s path ip port bitrate \n\
3. kill eg : kill (all) , k or kill n \n\
\n>");
memset(g_argv, 0, 5*255);
fgets(buf, MAX_COMMOND_SIZE-1, stdin);
g_argc = parse_command(buf);
//printf("command parse finish,start to process :%s \n", g_argv[0]);
if ( !strncasecmp(g_argv[0], "list", 4)||((strlen(buf) == 1)&&(strncasecmp(g_argv[0], "l", 1))))
{
printf(" index file start time end time \n");
do_command_list();
continue;
}
else if ( !strncasecmp(g_argv[0], "start", 4)||((strlen(buf) == 1)&&(strncasecmp(g_argv[0], "s", 1))))
{
pthread_mutex_lock(&g_work_mutex);
do_command_start();
pthread_mutex_unlock(&g_work_mutex);
continue;
}
else if ( !strncasecmp(g_argv[0], "kill", 4)||((strlen(buf) == 1)&&(strncasecmp(g_argv[0], "k", 1))))
{
do_command_kill();
continue;
}
else
{
printf("do nothing \n");
continue;
}
}
}
int main(int argc, char *argv[])
{
int i,res;
char *ip;
char *path = "udp_config";
char function_name[255] ={0};
pthread_t id[MAX_PEER_COUNT];
memset(&CONFIG_INFO, 0, sizeof(CONFIG_INFO));
read_config_by_line(path);
if( g_stream_count != CONFIG_INFO.count )
{
CONFIG_INFO.count = g_stream_count;
printf("config mistake ,real stream count :%d \n",CONFIG_INFO.count);
}
res = pthread_mutex_init(&g_work_mutex, NULL);
if ( 0 != res )
{
printf("Mutex initialization failed \n");
return -1;
}
pthread_create(&id[0], NULL, (void *) *get_user_command, NULL);
udp_send_ts_package();
//send_ts_package();
return 0;
}