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

📄 rc_ctl_data.c

📁 epoll机制的收发程序 只能在2.6内核上使用
💻 C
📖 第 1 页 / 共 3 页
字号:
		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 + -