⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 net_cmd.cpp

📁 实时监控
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#include "stdafx.h"
#include "net_av.h"
#include "net_cmd.h"
#include "net_udp.h"
#include "../NetDef.h"
#include "net_factory.h"
#include "ip_port.h"
#include "../thrd/thrd_decoder.h"
#include "../decoder/g722/G722Player.h"
#include "../../AudioRCV.h"
#include "../notif/notif_alarm.h"

extern FILE  *fppppp ;
#define vod_window			256
extern int	  nvodtype[vod_window];
extern int    nCurVodGroup[vod_window], nVodLostVideoNum[vod_window] ;
extern unsigned char   nVodDelayList[10][vod_window] ;
extern unsigned char   nVodListRr[vod_window], nVodListWr[vod_window], nVodAllFrame[vod_window] ;

PCALLBACKSTREAMPROD pcallback[vod_window];
PCALLBACKDECODEDSTREAMPROD pdecodedcallback[vod_window];

DWORD pcallback_user1[vod_window], pcallback_user2[vod_window];
DWORD pdecodedcallback_user1[vod_window], pdecodedcallback_user2[vod_window];

pDraw_Add_Image     pdrawcallback[vod_window];
DWORD pdrawcallback_user1[vod_window], pdrawcallback_user2[vod_window];

extern net_factory *   ctlcmd;

CSoundin m_psound;

#define HEADER_SIZE	4
#define CMD_SIZE	1

#define CMD_POS		4
#define DATA_POS	5

#define LOCAL_PORT	8101
#define REMOTE_PORT	8102

#define CMD_OF(x) ((x)[CMD_POS])
#define DATA_OF(x) ((x)+DATA_POS)

#define IPPORT ULONG rip, USHORT rport
#define IPP rip, rport

#define SAFE_DELETE(x) {delete (x); (x)=NULL;}

#define is ==
#define isnot !=

void shift(SHORT& s)
{
	char* p = (char*)&s;
	char& c1 = p[0];
	char& c2 = p[1];

	c1 ^= c2;
	c2 ^= c1;
	c1 ^= c2;
}

void set_cmd_header(char* cmdbuf)
{
	cmdbuf[0] = 'T';
	cmdbuf[1] = 'M';
	cmdbuf[2] = 'V';
	cmdbuf[3] = 'D';
}
void set_cmd(char* cmdbuf, char cmd)
{
	cmdbuf[CMD_POS] = cmd;
}

int set_data(char* cmdbuf, const char* data, int datalen )
{
	if( data )
	{
		memcpy(cmdbuf + DATA_POS, data, datalen);
		return datalen;
	}
	return 0;
}
	
PRIVILEGE get_login_station_version(int m_id)
{
	switch(m_id)
	{
		case 33:
			return priv4VERSION;
		case 20:
			return priv2000VERSION;	    ///<2000非实时
		case 21:
			return priv2100VERSION;
		case 47:
			return priv6008;
		case 48:
			return priv6008A4;
		case 49:
			return priv6008V;
		case 97:
			return priv6016;
		case 98:
			return priv6016V;
		case 99:
			return priv6016A8;
		default:
			return privNEWVERSION;
	}
}

/*
 *	发送网络命令
 *	输入参数: ip: 已转换, port: 未转换(look port(8101, 8102))
 */
//##ModelId=3F9A1D230112
void net_cmd::send_cmd(ULONG rip, USHORT rport, char cmd, const char* data, int datalen)
{
	int buflen = 0;
	char cmdbuf[100];

	last_ip = rip;
	last_port = rport;
	
	// 2003.8.14. nodman
	rport = htons(rport);

	set_cmd_header(cmdbuf);			buflen += HEADER_SIZE;
	set_cmd(cmdbuf, cmd);			buflen += CMD_SIZE;
	buflen += set_data(cmdbuf, data, datalen);

	net_addr ad(rip, rport);
	send((byte*)cmdbuf, buflen, ad);
}

#define vod_interval_pal	40
#define vod_interval_ntsc	33
 
#define login_station		120
#define timeout_connect		60
bool vod_mute[vod_window] ;

ip_speed vod_if[vod_window];
login_version login_if[login_station];
int m_loginlength=0;

/*
 *	VOD帧请求时间间隔,默认40ms。
 *	Playx1: 40ms
 *	Playx2:	20ms
 *	Playx3:	10ms
 *	FF(B)x1: 80ms
 *	FF(B)x2: 60ms
 *	FF(B)x3: 40ms
 */
int time_vod_nub = 0;
void CALLBACK request_vod_frame(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
	if(time_vod_nub == 256) 
		time_vod_nub = 0;
	time_vod_nub = time_vod_nub + 8;

	net_cmd *cmd = net_cmd::m_netcmdp;
	if(!cmd)	return;

	for(int i=0; i<vod_window; i++)
	{
	   ip_speed* p = &vod_if[i];
	   if(!p->ip )	continue;
	   if(p->speed == VS_PLAYx1 && nvodtype[p->group] == vod_interval_ntsc) 
		   continue;

	   if(!cmd->check_vod_send_cmd(p->speed, time_vod_nub)) 
		   continue;
	   cmd->request_vod_frame(p->ip, p->port, p->mport, p->speed, p->group);
	}
}

void CALLBACK request_vod_frame_ntsc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
	net_cmd *cmd = net_cmd::m_netcmdp;
	if(!cmd)	return;

	for(int i=0; i<vod_window; i++)
	{
	   ip_speed* p = &vod_if[i];
	   if(!p->ip )	continue;
	   if(p->speed == VS_PLAYx1 && nvodtype[p->group] == vod_interval_ntsc) 
	   {
			cmd->request_vod_frame(p->ip, p->port, p->mport, p->speed, p->group);
	   }
	}
}


bool net_cmd::check_vod_send_cmd(LONG speed, int time_nub)
{
	if(speed == VS_FRAME ||speed == VS_PAUSE) return false;
	
	int vod_interval = ((speed&0xff00)>>8) ;

	if(time_nub % vod_interval == 0)
		return true;

	if(time_nub == 256 && vod_interval == 255)
		return true;	
	return false;
}



//##ModelId=3F9A1D230162

void CALLBACK shake_hand(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
	net_cmd* cmd = (net_cmd*)dwUser;
	/*
	 *	如果当前没有打开任何视频通道, 就不用"握手"了
	 */
	if( cmd->connected.empty() )
		return;
	cmd->udp_bitrate = 0;
	for(int i=0;i<vod_window;i++)
	{
		cmd->av[i]->bitrate = 0;
		if(cmd->av[i]->is_opened())
		{
			cmd->av[i]->bitrate_1 = cmd->av[i]->bitrate_2;
			cmd->av[i]->bitrate_2 = cmd->av[i]->bitrate_3;
			cmd->av[i]->bitrate_3 = cmd->av[i]->bitrate_4;
			cmd->av[i]->bitrate_4 = cmd->av[i]->bits;
			cmd->av[i]->bitrate = (cmd->av[i]->bitrate_1 + cmd->av[i]->bitrate_2 +
				cmd->av[i]->bitrate_3 + cmd->av[i]->bitrate_4)>>2;
			cmd->av[i]->bits = 0;
		}
		cmd->udp_bitrate += cmd->av[i]->bitrate;
	}
	POST_NOTIFY(cmd->cmdcb, NTM_REFRESH_BITRATE, 1, NULL);
	cmd->shake_hand();
}


//##ModelId=3F9A1D23013A
void net_cmd::request_vod_frame(ULONG ip,USHORT port, USHORT mport, LONG speed,int group)
{
	unsigned char  m_temstr[5];
	int m_length=0;
	int m_version = get_login_version(ip, port);
	if(!m_version) 
	{
	   m_temstr[0]=speed;
       m_length=1;
	}
	else 
	{
	   m_temstr[0] = speed;
	   if(m_version == 1)
	   {
		   m_temstr[1] = mport;
		   m_temstr[2] = (mport>>8);
	   }
	   else if(m_version == 2)
	   {
		   m_temstr[1] = 0;
		   m_temstr[2] = 0;
	   }
	   m_length=3;
	}
	
	switch (speed)  {
		case  VS_PLAYx1 :
			if (nVodListRr[group] != nVodListWr[group])  
			{
				//fprintf(fppppp, "request vod : nVodDelayList[nVodListRr[group]][group] =%d group = %d nVodListRr[group]=%d nVodListWr[group] = %d\n",nVodDelayList[nVodListRr[group]][group],group,nVodListRr[group],nVodListWr[group]);
				if (--nVodDelayList[nVodListRr[group]][group] <= 0 || !nVodAllFrame[group]) 
				{
					if (++nVodListRr[group] >= 10)
						nVodListRr[group] = 0 ;
					  send_cmd_data(ip,port, NETCOM_VOD_RECFILE_CON, (char*)m_temstr, m_length, group) ;
					  nVodLostVideoNum[group] ++ ;
				}
				else if (nVodLostVideoNum[group] > 1)  
				{
					  send_cmd_data(ip,port, NETCOM_VOD_RECFILE_CON, (char*)m_temstr, m_length, group) ;	  
				}
			}
			else 
			{
			    send_cmd_data(ip,port, NETCOM_VOD_RECFILE_CON, (char*)m_temstr, m_length, group) ;
				nVodLostVideoNum[group] ++ ;
			}
			//fprintf(fppppp, "send operation : ip = %x mport = %x speed = %ld group = %ld time: %s\n",ip, mport, speed, group,m_tt) ;
			break ;
		case  VS_PLAYx2 :
			break ;
		case  VS_PLAYx3 :
			break ;
		case  VS_FFx1 :
		case  VS_FFx2 :
		case  VS_FFx3 :
		case  VS_FFx4 :
		case  VS_FBx1 :
		case  VS_FBx2 :
		case  VS_FBx3 :
		case  VS_FBx4 :
			send_cmd_data(ip, port, NETCOM_VOD_RECFILE_CON, (char*)m_temstr, m_length, group) ;
			break ;
		case  VS_FRAME :
			send_cmd_data(ip, port, NETCOM_VOD_RECFILE_CON, (char*)&m_temstr, m_length, group) ;
			break ;
		default :
			break ;
	}
}

void net_cmd::send_cmd_data(ULONG ip, USHORT port, char cmd, const char* data, int datalen, int group)
{
	int m_version = get_login_version(ip, port);

	if(!m_version || m_version == 1)	
	{
		send_cmd(ip,port, cmd, data, datalen);
		return;
	}

	int buflen = 0;
	char cmdbuf[100];
	
	port = htons(port);

	set_cmd_header(cmdbuf);			buflen += HEADER_SIZE;
	set_cmd(cmdbuf, cmd);			buflen += CMD_SIZE;
	buflen += set_data(cmdbuf, data, datalen);

	net_addr ad(ip, port) ;
	av[group]->send((byte*)cmdbuf, buflen, ad) ;
}

//##ModelId=3F9A1D23037F
BOOL net_cmd::is_voding(int group) {return vod_if[group].ip;}
//##ModelId=3F9A1D23014E
void net_cmd::close_vod(int group)
{
	if( !is_voding(group) )
		return;
	ZeroMemory(&vod_if[group], sizeof(ip_speed));

	pcallback[group] = NULL;
	pdrawcallback[group] = NULL;

	pcallback_user1[group] = 0;
	pcallback_user2[group] = 0;

	pdrawcallback_user1[group] = 0;
	pdrawcallback_user2[group] = 0;

	av[group]->leave();
	net_av::clear_audio();
}

void net_cmd::close_vod()
{
	vod_group = -1 ;
	for(int i=0;i<max_channel;i++)
		nCurVodGroup[i] = -1 ;
}
//////////////////////////////////////////////////////////////////////////
// 网络初始化
//##ModelId=3F9A1D230203
net_cmd * net_cmd::m_netcmdp = NULL;

net_cmd::net_cmd(): last_ip(0), last_port(0), bkcb(NULL) ,
 vod_group(-1), last_group(0), cmdcb(NULL)
{
	m_netcmdp = this;
	m_vod_mport = 0;
	m_real_mport = 0;
	palarmserver = NULL;
	udp_bitrate  = 0;
	for( int i=0; i<max_channel; i++ )
	{
		av[i] = new net_av(i) ;
		vod_mute[i] = false ;
	}
	memset(bk_ip,     0,  MAX_BACKUP_THREAD_NUM * sizeof(ULONG)) ;
	memset(bk_port,   0,  MAX_BACKUP_THREAD_NUM * sizeof(ULONG)) ;
	memset(timeout,   0,  MAX_BACKUP_THREAD_NUM * sizeof(UCHAR)) ;
	memset(pBackupTh, 0,  MAX_BACKUP_THREAD_NUM * sizeof(net_bk *)) ;

	memset(talk_timeout,     0,  MAX_TALKING_THREAD_NUM * sizeof(UCHAR)) ;
	memset(talk_ip,     0,  MAX_TALKING_THREAD_NUM * sizeof(ULONG)) ;
	memset(talk_port,   0,  MAX_TALKING_THREAD_NUM * sizeof(ULONG)) ;
	memset(ptalkTh,   0,  MAX_TALKING_THREAD_NUM * sizeof(net_bk *)) ;
}

//##ModelId=3F9A1D230217
net_cmd::~net_cmd()
{
	destroy();
    
	for(int i=0; i<max_channel; i++)
	{
		SAFE_DELETE(av[i]);
	}
	m_netcmdp = NULL;
}

//##ModelId=3F9A1D2301E5
void net_cmd::shake_hand()
{
	if (connected.empty())
		return ;
	
	for (pit it = connected.begin(); it != connected.end(); it++)  
	{
		server& ref = *it ;
		ULONG channels = send_open_channel(ref.ip(), ref.port());
        
		unsigned char portinfo[14];
		portinfo[12] = channels & 0x00ff;
		portinfo[13] = channels >> 8;
		send_cmd(ref.ip(), ref.port(), NETCOM_SHAKE_HAND, (char *)portinfo, 14);	
	}

	send_keep_port();
    check_connect_timeout();
	check_backup() ;
	check_talk();
}

ULONG net_cmd::send_open_channel(IPPORT)
{
	ULONG m_channels = 0;

     for( int i=0; i<max_channel; i++ )
	 {
		if( av[i]->svr_ip() == rip && av[i]->svr_port() == rport && !is_voding(i))
		{
			m_channels = m_channels | operation_btye(av[i]->svr_chnl());
			//fprintf(fppppp, "bit operation : ip = %ld, port = %ld, channels = %ld\n", rip, rport, av[i]->svr_chnl()) ;
		}

	 }
	 return m_channels;
}

ULONG net_cmd::operation_btye(int m)
{
	ULONG k = 1;
	return k<<m;
}


//##ModelId=3F9A1D230221
BOOL net_cmd::create(IPPORT, CMD_CALLEE cb)
{
	net_addr ad(rip, htons(rport));
	if( !net_udp::create(ad, TRUE) )
		return false;

	net_av::init_audio();

	cmdcb = cb ;

	/*
	 *	握手协议, 2003-10-11, nodman
	 *	每隔1秒, 发给主机一个信号: 0x38
	 *	主机回复0x38, 另外有12个字节, 每段4个字节, 3段分别为:
	 *	1. 探头报警
	 *	2. 移动报警
	 *	3. 视频丢失报警
	 */
	timer_shake_hand.start(1000, ::shake_hand, (DWORD)this) ;
// 	dec_timer.start(40, request_decode, (DWORD)av);

	//connect_timeout.start(timeout_connect*1000,::check_connect_timeout,(DWORD)this);

	return true;
}

void net_cmd::send_keep_port()
{
	if(connected.empty() )
		return;

	ULONG ip;
	USHORT mport , port;
	unsigned char    SndBuf[30] ;
	set_cmd_header((char *)SndBuf) ;
	SndBuf[4] = NET_CLIENT_BURROW1 ;

	for(int i=0;i<vod_window;i++)
	{
		if(av[i]->is_opened())
		{
			ip = av[i]->svr_ip();
			port = av[i]->svr_port();
			mport = av[i]->get_port();
			SndBuf[5] = (mport>>8);
			SndBuf[6] = mport & 0x00ff;

			net_addr ad(ip, htons(port)) ;
			av[i]->send(SndBuf, 7, ad) ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -