📄 rc_ctl_data.c
字号:
memcpy(&len, data, LEN_LEN_PACKET_WEB);
if(len <= 0)
break;
data += LEN_LEN_PACKET_WEB;
type = data[0];
data += LEN_TYPE_PACKET_WEB;
len -= LEN_TYPE_PACKET_WEB;
switch(type)
{
case TYPE_P_W_INDEX://首页相关类型
if(len != sizeof(struct_lingmd))//长度不正确
return -1;
break;
case TYPE_P_W_SYSTEM://系统相关类型
if(len != sizeof(struct_web_sys))//长度不正确
return -1;
break;
case TYPE_P_W_SECURITY://安全相关类型
if(len != sizeof(struct_web_security_get))//长度不正确
return -1;
break;
case TYPE_P_W_NET://网络相关类型
if(len != sizeof(struct_web_net))//长度不正确
return -1;
break;
case TYPE_P_W_DDNS://DDNS相关类型
if(len != sizeof(struct_web_ddns))//长度不正确
return -1;
break;
case TYPE_P_W_MAILFTP://传输方式相关类型
if(len != sizeof(struct_web_mailftp))//长度不正确
return -1;
break;
case TYPE_P_W_VIDEO://视音频相关类型
if(len != sizeof(struct_web_video))//长度不正确
return -1;
break;
case TYPE_P_W_TRIGGER://应用相关类型
if(len != sizeof(struct_web_application))//长度不正确
return -1;
break;
case TYPE_P_W_TOOL://工具相关类型
if(len != sizeof(struct_web_tool))//长度不正确
return -1;
return 0;
break;
case TYPE_P_W_UPDATE://软件更新相关类型
if(len != sizeof(struct_web_update))//长度不正确
return -1;
break;
default:
return -1;
break;
}
res = rc_save_mysql_web(TYPE_ACTION_CAMERA, serial, type, data, mysql_lab, pthread_self());
data += len;
}
return 0;
}
/*
* 功 能:解析并处理网络部分的控件相关数据
* 参 数:data:数据
* len_d:数据长度
* ctlinfo:链接信息
* 返回值:成功返回值大于或者等于0,否则返回值小于0
*/
int rc_deal_act_net(unsigned char *data, int len_d, struct_msg_con *ctlinfo)
{
int res;
int state;
unsigned char ip[16];
unsigned short int port;
unsigned char type;
struct in_addr ctlip;//控件ip
struct in_addr ctlsub;//控件子网掩码
unsigned long long int ti;//时间
struct_info_link caminfo;
type = data[0];
data++;
/* 获取服务器的端口和 ip 地址 */
bzero(ip, sizeof(ip));
res = rc_get_info_ser(ip, &port);
if(res < 0)
{
bzero(ip, sizeof(ip));
port = 0;
}
switch(type)
{
case TYPE_ATX_GET_MSG_CAM://请求摄像机信息
/* 取得控件ip */
bzero(&ctlip, sizeof(struct in_addr));
memcpy(&ctlip, data, LEN_TYPE_UINT32);
data += LEN_TYPE_UINT32;
/* 取得控件子网掩码 */
bzero(&ctlsub, sizeof(struct in_addr));
memcpy(&ctlsub, data, LEN_TYPE_UINT32);
data += LEN_TYPE_UINT32;
/* 取得摄像机序列号 */
memcpy(ctlinfo->serial, data, LEN_SERIAL_CHECK);
data += LEN_SERIAL_CHECK;
/* 取得时间戳 */
memcpy(&ti, data, LEN_TYPE_UINT64);
data += LEN_TYPE_UINT64;
/* 获取摄像机状态及相关信息 */
pthread_mutex_lock(&mutex_con_t);
res = rc_get_info_cam(ctlinfo->serial, head_con, &caminfo);
pthread_mutex_unlock(&mutex_con_t);
if(res < 0)//摄像机不在线
{
// printf("\t\t |-|-|-| %s %d No camera! |-|-|-|\n", __FILE__, __LINE__);
state = STATE_CAM_ONLINE_NO;
bzero(&caminfo, sizeof(struct_info_link));
}
else
state = STATE_CAM_ONLINE_YES;
if(state != STATE_CAM_ONLINE_YES)
{
bzero(&caminfo, sizeof(struct_info_link));
}
ctlinfo->type = TYPE_CONNECT_CTL;
rc_return2ctl_cam(ctlinfo, state, &(caminfo.address), ip, port);//向控件发送信息
rc_add_log(__FILE__, __FUNCTION__, __LINE__, KEY_LOG_NET, "ActiveX %s request camera %s connect", inet_ntoa(ctlinfo->address.sin_addr), ctlinfo->serial);
break;
case TYPE_ATX_SOCKET_CLOSE://打洞成功,关闭socket
break;
case TYPE_ATX_GET_VIDEO://打洞失败,请求视频
// printf("\t\t ++++++ %s %d Get camera %s's video! ++++++\n", __FILE__, __LINE__, ctlinfo->serial);
res = rc_snd_req_cam(ctlinfo->serial, ip, port);
break;
default:
return -1;
break;
}
return 0;
}
/*
* 功 能:向控件发送摄像机中转信息
* 参 数:ctlinfo:与控件链接的相关信息
* state:摄像机的在线状态
* camsocket:与摄像机链接的socket
* serip:中转服务器的ip
* serport:中转服务器的监听端口
* cam:摄像机的外网相关信息
* 返回值:成功返回值大于等于0,否则返回值小于0
*/
int rc_return2ctl_cam(struct_msg_con *ctlinfo, int state, struct sockaddr_in *camsocket, const unsigned char *serip, unsigned short int serport)
{
int res;
unsigned short int len;
unsigned short int len_con;
unsigned long int len_buf;
unsigned char temp[512];
unsigned char tmp_con[512];
unsigned char *buf = NULL;
struct in_addr ip;
struct_cam_local cammsg;
struct_task_net_w *newsnd = NULL;
if(ctlinfo->sockfd <= 0)
return -1;
bzero(&cammsg, sizeof(struct_cam_local));
#ifdef MYSQL_SAVE_USED_YES
if(state == STATE_CAM_ONLINE_YES)
{
res = rc_get_cam_database(ctlinfo->serial, &cammsg);
if(res < 0)
bzero(&cammsg, sizeof(struct_cam_local));
}
#else
pthread_mutex_lock(&mutex_con_t);
res = rc_get_cam_local(ctlinfo->serial, head_con, &cammsg);
pthread_mutex_unlock(&mutex_con_t);
cammsg.port_nat = 0;
res = 0;
#endif
bzero(temp, sizeof(temp));
len = 0;
temp[len] = TYPE_SND_INFO_CAM_CTL;
len++;
/* 控件本身公网IP地址 */
memcpy(temp + len, (char *)&(ctlinfo->address.sin_addr.s_addr), LEN_TYPE_UINT32);
len += LEN_TYPE_UINT32;
// printf("%s %d Atx ip : %s\n", __FILE__, __LINE__, inet_ntoa(ctlinfo->address.sin_addr));
/* 摄像机本地IP地址 */
memcpy(temp + len, (char *)&(cammsg.ip.s_addr), LEN_TYPE_UINT32);
len += LEN_TYPE_UINT32;
/* 摄像机本地web端口 */
memcpy(temp + len, (char *)&(cammsg.port_web), LEN_TYPE_UINT16);
len += LEN_TYPE_UINT16;
/* 摄像机外网IP地址 */
if(state == STATE_CAM_ONLINE_NO)
bzero(temp + len, LEN_TYPE_UINT32);
else
memcpy(temp + len, (char *)&(camsocket->sin_addr.s_addr), LEN_TYPE_UINT32);
len += LEN_TYPE_UINT32;
/* 摄像机子网掩码 */
memcpy(temp + len, (char *)&(cammsg.submask.s_addr), LEN_TYPE_UINT32);
len += LEN_TYPE_UINT32;
/* 摄像机外网端口号 */
memcpy(temp + len, (char *)&(camsocket->sin_port), LEN_TYPE_UINT16);
len += LEN_TYPE_UINT16;
/* 摄像机NAT端口映射端口号 */
memcpy(temp + len, (char *)&(cammsg.port_nat), LEN_TYPE_UINT16);
len += LEN_TYPE_UINT16;
/* 中转服务器公网IP地址 */
bzero(&ip, sizeof(struct in_addr));
ip.s_addr = inet_addr(serip);
memcpy(temp + len, &(ip.s_addr), LEN_TYPE_UINT32);
len += LEN_TYPE_UINT32;
/* 中转服务器公网端口号 */
memcpy(temp + len, &serport, LEN_TYPE_UINT16);
len += LEN_TYPE_UINT16;
bzero(tmp_con, sizeof(tmp_con));
len_con = rc_create_packet_connect(temp, len, TYPE_P_C_LINK_ASK, tmp_con);
if(len_con == 0)
{
return -1;
}
buf = malloc(LEN_DATA_1024);
if(buf == NULL)
return -1;
bzero(buf, LEN_DATA_1024);
len_buf = rc_create_packet(tmp_con, len_con, TYPE_P_F_CTL_CON, buf);
if(len_buf == 0)
{
free(buf);
buf = NULL;
return -1;
}
newsnd = rc_create_task_new_w(ctlinfo, TYPE_CONNECT_CTL, NULL, buf, len_buf);
pthread_mutex_lock(&mutex_w_atx);
res = rc_add_task_w(&task_w_atx, newsnd);
pthread_mutex_unlock(&mutex_w_atx);
pthread_cond_broadcast(&cond_w_atx);
#ifdef DEBUG_MYL
// if(task_w_atx == NULL)
// printf("\t ====%s %d return to ActiveX Error (res : %d(%lu))! ====\n", __FILE__, __LINE__, res, len_buf);
// else
// printf("\t ====%s %d return to ActiveX Success (res : %d(%lu))! ====\n", __FILE__, __LINE__, res, len_buf);
#endif
return 0;
}
/*
* 功 能:获取视频中转服务器的ip地址和端口
* 参 数:ip:视频中转服务器的ip地址
* port:视频中转服务器的端口
* 返回值:成功返回值大于或者等于0,否则返回值小于0
*
*/
int rc_get_info_ser(unsigned char *ip, unsigned short int *port)
{
strcpy(ip, ip_video);
*port = port_video;
return 0;
}
/*
* 功 能:通过管道向摄像机发送视频请求
* 参 数:pid:与摄像机链接的进程的pid
* serial:摄像机序列号
* ip;中转服务器的ip地址
* port:中转服务器监听的端口
* 返回值:成功返回0,否则返回值小于0
*/
int rc_snd_req_cam(const unsigned char *serial, const unsigned char *ip, unsigned short int port)
{
int res;
unsigned char path[128];
unsigned char tmp_fps[32];
int fps;
struct in_addr temp;
struct_buf_fifo msg;
if(strlen(serial) != LEN_SERIAL_CHECK)
{
// printf("\t ~~~~~~~~~~~~~~ %s %d ~~~~~~~~~~~~~~\n", __FILE__, __LINE__);
return -1;
}
bzero(path, sizeof(path));
rc_create_path_fifo(path, sizeof(path));
bzero(&temp, sizeof(struct in_addr));
temp.s_addr = inet_addr(ip);
/* 组装数据 */
bzero(&msg, sizeof(struct_buf_fifo));
strcpy(msg.serial, serial);
msg.pid = getpid();
msg.eventtype = TYPE_REQUEST_CTL;
memcpy(msg.msg.request.ip_ser, &(temp.s_addr), LEN_TYPE_UINT32);//服务器ip
memcpy(msg.msg.request.port_ser, &port, LEN_TYPE_UINT16);//服务器端口
msg.msg.request.video = TYPE_VIDEO_REALTIME;//实时数据还是历史数据
bzero(tmp_fps, sizeof(tmp_fps));
res = rc_get_info(NAME_FILE_INI_CTL, KEY_MAX_FPS, tmp_fps);
fps = 0;
if(res >= 0)
{
fps = atoi(tmp_fps);
}
if(tmp_fps <= 0)
fps = DEFAULT_FPS_SND_CMA;
msg.msg.request.fps = fps;//要求发送的图像的帧率
res = rc_fifo_write_lock(path, (unsigned char *)&msg, sizeof(struct_buf_fifo));
if(res != sizeof(struct_buf_fifo))
{
// printf("\t ~~~~~~~~~~~~~~ %s %d res : %d(%d) ~~~~~~~~~~~~~~\n", __FILE__, __LINE__, res, sizeof(struct_buf_fifo));
return -1;
}
return 0;
}
/*
* 功 能:创建对cam的视频请求包
* 参 数:msg:请求信息
* output:输出结果
* 返回值:成功返回数据包的总长度,否则返回0
*/
unsigned short int rc_create_p_con_v_c(struct_req_cam_v msg, unsigned char *output)
{
unsigned short int len;
len = sizeof(struct_req_cam_v);
memcpy(output, &msg, len);
return len;
}
/*
* 功 能:解析并处理返回的结果
* 参 数:task:已经发送成功的任务队列的头指针地址
* serial:摄像机序列号
* data:数据
* len_d:数据长度
* 返回值:成功返回值大于或者等于0,否则返回值小于0
*/
int rc_deal_return(struct_task_sended **task, const char *serial, char *data, int len_d, struct_lab_mysql *lab_mysql)
{
int res;
unsigned short int len;
unsigned char type;
unsigned char val_return;
pid_t pid;
while(1)
{
len = 0;
memcpy(&len, data, LEN_LEN_PACKET_WEB);
if(len <= 0)
break;
data += LEN_LEN_VAL_RETURN;
type = data[0];
data += LEN_TYPE_VAL_RETRUN;
memcpy(&pid, data, LEN_PID);
data += LEN_PID;
val_return = data[0];
switch(type)
{
case TYPE_P_ERROR_W_INDEX://首页相关的错误类型
break;
case TYPE_P_ERROR_W_SYSTEM://系统相关的错误类型
break;
case TYPE_P_ERROR_W_SECURITY://安全页相关的错误类型
break;
case TYPE_P_ERROR_W_NET://网络相关的错误类型
break;
case TYPE_P_ERROR_W_DDNS://DDNS相关的错误类型
break;
case TYPE_P_ERROR_W_MAILFTP://传输方式相关的错误类型
break;
case TYPE_P_ERROR_W_VIDEO://视音频相关的错误类型
break;
case TYPE_P_ERROR_W_TRIGGER://应用相关的错误类型
break;
case TYPE_P_ERROR_W_TOOL://工具相关的错误类型
break;
case TYPE_P_ERROR_W_UPDATE://软件更新相关的错误类型
break;
default:
continue;
break;
}
if(type != TYPE_P_ERROR_W_TOOL)
{
if(val_return == 1)//val_return 1成功;2失败
{
res = rc_task_save_sended(*task, pid, serial, lab_mysql);//保存信息到数据库
if(res < 0)
val_return = ERROR_MYSQL_SAVE;
}
rc_snd_signal(pid, VAL_SIGNAL_CGI, val_return);//给cgi发送信号
rc_task_del_sended(task, pid);//删除任务
}
data += LEN_VAL_RETRUN;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -