ssize_t
_user_recv(int socket, void *data, size_t length, int flags)
{
	if (data == NULL || !IS_USER_ADDRESS(data))
		return B_BAD_ADDRESS;

	SyscallRestartWrapper<ssize_t> result;
	return result = common_recv(socket, data, length, flags, false);
}
//传输图片数据
static int trans_image_data_v2(int sock_fd, struct protocal_common *common_data)
{
	int head_len;
	int data_len;
	int ret;
	struct prot_trans_image_v1 pack_head;
	unsigned char * pack_data = NULL;
	int image_data_offset; //对整张图片的偏移
	int pack_index;
	struct protocal_common resp_common;
	struct image_t save_image;

	unsigned char * rgb888_buff = NULL;
	struct image_data_format image_format;

	if (common_data == NULL)
	{
		print("param error\n");
		return -1;
	}

	head_len = ntohl(common_data->head_len);
	data_len = ntohl(common_data->data_len);

	if (head_len != sizeof(pack_head))
	{
		print("head len is error\n");
		goto _err;
	}
	
	ret = common_recv(sock_fd, (unsigned char *)&pack_head, head_len);
	if (ret != head_len)
	{
		print("recv data error, should: %d really: %d\n", head_len, ret);
		goto _err;
	}

	if ((ntohl(pack_head.lask_pack) == 0) && (data_len != IMAGE_PAKE_SIZE))
	{
		print("this version of protocal is only support %d pack\n", IMAGE_PAKE_SIZE);
		goto _err;
	}

	if ((pack_head.pic_time.tv_sec != curr_image_info.pic_time.tv_sec) || (pack_head.pic_time.tv_usec != curr_image_info.pic_time.tv_usec))
	{
		print("pic time is not equal, this pack will ignore\n");
		goto _err;
	}

	pack_index = ntohl(pack_head.pack_index);
	if ((pack_index < 0) || (pack_index > curr_image_info.curr_image_size/IMAGE_PAKE_SIZE+(curr_image_info.curr_image_size%IMAGE_PAKE_SIZE == 0?0:1)))
	{
		print("index is error, pack_index: %d curr_image_info.curr_image_size:%d\n", pack_index, curr_image_info.curr_image_size);
		goto _err;
	}
	pack_data = (unsigned char *)malloc(data_len);
	if (pack_data == NULL)
	{
		print("malloc mem error\n");
		goto _err;
	}

	//读取数据
	ret = common_recv(sock_fd, pack_data, data_len);
	if (ret != data_len)
	{
		print("pack data may be %d  , but really: %d\n", data_len, ret);
		goto _err;
	}

	//将数据存储到分配的图片中
	image_data_offset = pack_index * IMAGE_PAKE_SIZE;
	CURR_IMAGE_DATA_LOCK;
	memcpy(curr_image_info.p_curr_image_buf+image_data_offset, pack_data, data_len);
	CURR_IMAGE_DATA_UNLOCK;

	//回应客户端
	//回应客户端
	resp_common.head_len = htonl(0);
	resp_common.data_len = htonl(0);
	resp_common.version = htonl(1);
	resp_common.command = htonl(PROT_RESPONSE_OK);
	common_send(sock_fd, (unsigned char *)&resp_common, sizeof(resp_common));

	//需要将图片放入内存池
	if (ntohl(pack_head.lask_pack) == 1)
	{
		rgb888_buff = malloc(curr_image_info.width * curr_image_info.height * 3);
		if (rgb888_buff == NULL)
		{
			goto _err;
		}
		image_format.format = IMAGE_FORMAT_YUYV;
		image_format.width = curr_image_info.width;
		image_format.height = curr_image_info.height;
		ret = yuyv_to_rgb888(&image_format, curr_image_info.p_curr_image_buf, 
			curr_image_info.curr_image_size, rgb888_buff, curr_image_info.width * curr_image_info.height * 3);
		if (ret < 0)
		{
			goto _err;
		}
		//1 保存图片到数据库
		save_image.width = curr_image_info.width;
		save_image.height = curr_image_info.height;
		save_image.format = IMAGE_FORMAT_RGB888_SIGNAL;
		save_image.data_len = 0;
		cgettimeofday(&save_image.time);

		pool_save(&save_image, rgb888_buff, curr_image_info.width * curr_image_info.height *3);
		printf("copy image to mem pool\n");
		
	}

	if (pack_data != NULL)
		free(pack_data);
	if (rgb888_buff != NULL)
		free(rgb888_buff);

	return 0;
_err:
	if (pack_data != NULL)
	{
		free(pack_data);
		pack_data = NULL;
	}
	//回应客户端
	resp_common.head_len = htonl(0);
	resp_common.data_len = htonl(0);
	resp_common.version = htonl(1);
	resp_common.command = htonl(PROT_RESPONSE_ERROR);
	common_send(sock_fd, (unsigned char *)&resp_common, sizeof(resp_common));
	
	return -1;

}
//接收图片命令处理
static int trans_handler_v1(int sock_fd, struct protocal_common *common_data)
{
	print("trans image trans_handler_v1\n");
	struct prot_trans_head_v1 recv_head;
	unsigned char * recv_data = NULL;
	int recv_data_len = 0;
	int ret;

	struct protocal_common resp_common;
	
	if ((common_data == NULL) || (sock_fd < 0))
	{
		print("param error\n");
		goto _err;
	}

	if (ntohl(common_data->head_len) != sizeof(recv_head))
	{
		print("trans_handler_v1 head size error\n");
		goto _err;
	}

	ret = common_recv(sock_fd, (unsigned char *)&recv_head, sizeof(recv_head));
	if (ret != sizeof(recv_head))
	{
		print("recv_head error, should: %ld really: %d\n", sizeof(recv_head), ret);
		goto _err;
	}

	recv_data_len = ntohl(common_data->data_len);

	CURR_IMAGE_DATA_LOCK;
	if (curr_image_info.p_curr_image_buf != NULL)
	{
		//如果不为空,说明上一张图片传输未完成,返回错误
		print("new image come, but previos is not complate\n");
		//goto _err; //开始新的图片
		free(curr_image_info.p_curr_image_buf);
		curr_image_info.p_curr_image_buf = NULL;
	}

	if (curr_image_info.p_curr_image_buf == NULL)
	{
		recv_data = (unsigned char *)malloc(recv_data_len);
		if (recv_data == NULL)
		{
			print("malloc mem %d error\n", recv_data_len);
			goto _err;
		}
		memset(recv_data, 0, recv_data_len);
	}
		
	curr_image_info.p_curr_image_buf = recv_data;
	curr_image_info.curr_image_size = recv_data_len;
	curr_image_info.recv_size = 0;
	curr_image_info.pic_time = recv_head.time;

	curr_image_info.width = ntohl(recv_head.width);
	curr_image_info.height = ntohl(recv_head.height);
	curr_image_info.image_type = ntohl(recv_head.image_type);
	curr_image_info.image_formate = ntohl(recv_head.format);
	CURR_IMAGE_DATA_UNLOCK;

	//回应客户端
	resp_common.head_len = htonl(0);
	resp_common.data_len = htonl(0);
	resp_common.version = htonl(1);
	resp_common.command = htonl(PROT_RESPONSE_OK);
	common_send(sock_fd, (unsigned char *)&resp_common, sizeof(resp_common));

	
	return 0;

_err:
	if (recv_data != NULL)
		free(recv_data);
	
	//回应客户端
	resp_common.head_len = htonl(0);
	resp_common.data_len = htonl(0);
	resp_common.version = htonl(1);
	resp_common.command = htonl(PROT_RESPONSE_ERROR);
	common_send(sock_fd, (unsigned char *)&resp_common, sizeof(resp_common));
	
	return -1;
}
ssize_t
recv(int socket, void *data, size_t length, int flags)
{
	SyscallFlagUnsetter _;
	RETURN_AND_SET_ERRNO(common_recv(socket, data, length, flags, true));
}