📄 net_cmd.cpp
字号:
#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 + -