예제 #1
0
int janus_text2pcap_close(janus_text2pcap *instance) {
	if(instance == NULL)
		return -1;
	janus_mutex_lock_nodebug(&instance->mutex);
	if(!g_atomic_int_compare_and_exchange(&instance->writable, 1, 0)) {
		janus_mutex_unlock_nodebug(&instance->mutex);
		return 0;
	}
	fclose(instance->file);
	instance->file = NULL;
	janus_mutex_unlock_nodebug(&instance->mutex);
	return 0;
}
예제 #2
0
int janus_recorder_close(janus_recorder *recorder) {
	if(!recorder || !recorder->writable)
		return -1;
	janus_mutex_lock_nodebug(&recorder->mutex);
	recorder->writable = 0;
	if(recorder->file) {
		fseek(recorder->file, 0L, SEEK_END);
		size_t fsize = ftell(recorder->file);
		fseek(recorder->file, 0L, SEEK_SET);
		JANUS_LOG(LOG_INFO, "File is %zu bytes: %s\n", fsize, recorder->filename);
	}
	janus_mutex_unlock_nodebug(&recorder->mutex);
	return 0;
}
예제 #3
0
int janus_recorder_free(janus_recorder *recorder) {
	if(!recorder)
		return -1;
	janus_recorder_close(recorder);
	janus_mutex_lock_nodebug(&recorder->mutex);
	g_free(recorder->dir);
	recorder->dir = NULL;
	g_free(recorder->filename);
	recorder->filename = NULL;
	fclose(recorder->file);
	recorder->file = NULL;
	g_free(recorder->codec);
	recorder->codec = NULL;
	janus_mutex_unlock_nodebug(&recorder->mutex);
	g_free(recorder);
	return 0;
}
예제 #4
0
int janus_recorder_close(janus_recorder *recorder) {
	if(!recorder || !recorder->writable)
		return -1;
	janus_mutex_lock_nodebug(&recorder->mutex);
	recorder->writable = 0;
	if(recorder->file) {
		fseek(recorder->file, 0L, SEEK_END);
		size_t fsize = ftell(recorder->file);
		fseek(recorder->file, 0L, SEEK_SET);
		JANUS_LOG(LOG_INFO, "File is %zu bytes: %s\n", fsize, recorder->filename);
	}
	if(rec_tempname) {
		/* We need to rename the file, to remove the temporary extension */
		char newname[1024];
		memset(newname, 0, 1024);
		g_snprintf(newname, strlen(recorder->filename)-strlen(rec_tempext), "%s", recorder->filename);
		char oldpath[1024];
		memset(oldpath, 0, 1024);
		char newpath[1024];
		memset(newpath, 0, 1024);
		if(recorder->dir) {
			g_snprintf(newpath, 1024, "%s/%s", recorder->dir, newname);
			g_snprintf(oldpath, 1024, "%s/%s", recorder->dir, recorder->filename);
		} else {
			g_snprintf(newpath, 1024, "%s", newname);
			g_snprintf(oldpath, 1024, "%s", recorder->filename);
		}
		if(rename(oldpath, newpath) != 0) {
			JANUS_LOG(LOG_ERR, "Error renaming %s to %s...\n", recorder->filename, newname);
		} else {
			JANUS_LOG(LOG_INFO, "Recording renamed: %s\n", newname);
			g_free(recorder->filename);
			recorder->filename = g_strdup(newname);
		}
	}
	janus_mutex_unlock_nodebug(&recorder->mutex);
	return 0;
}
예제 #5
0
int janus_recorder_save_frame(janus_recorder *recorder, char *buffer, uint length) {
	if(!recorder)
		return -1;
	janus_mutex_lock_nodebug(&recorder->mutex);
	if(!buffer || length < 1) {
		janus_mutex_unlock_nodebug(&recorder->mutex);
		return -2;
	}
	if(!recorder->file) {
		janus_mutex_unlock_nodebug(&recorder->mutex);
		return -3;
	}
	if(!recorder->writable) {
		janus_mutex_unlock_nodebug(&recorder->mutex);
		return -4;
	}
	if(!recorder->header) {
		/* Write info header as a JSON formatted info */
		json_t *info = json_object();
		/* FIXME Codecs should be configurable in the future */
		const char *type = NULL;
		if(recorder->type == JANUS_RECORDER_AUDIO)
			type = "a";
		else if(recorder->type == JANUS_RECORDER_VIDEO)
			type = "v";
		else if(recorder->type == JANUS_RECORDER_DATA)
			type = "d";
		json_object_set_new(info, "t", json_string(type));								/* Audio/Video/Data */
		json_object_set_new(info, "c", json_string(recorder->codec));					/* Media codec */
		json_object_set_new(info, "s", json_integer(recorder->created));				/* Created time */
		json_object_set_new(info, "u", json_integer(janus_get_real_time()));			/* First frame written time */
		gchar *info_text = json_dumps(info, JSON_PRESERVE_ORDER);
		json_decref(info);
		uint16_t info_bytes = htons(strlen(info_text));
		fwrite(&info_bytes, sizeof(uint16_t), 1, recorder->file);
		fwrite(info_text, sizeof(char), strlen(info_text), recorder->file);
		free(info_text);
		/* Done */
		recorder->header = 1;
	}
	/* Write frame header */
	fwrite(frame_header, sizeof(char), strlen(frame_header), recorder->file);
	uint16_t header_bytes = htons(recorder->type == JANUS_RECORDER_DATA ? (length+sizeof(gint64)) : length);
	fwrite(&header_bytes, sizeof(uint16_t), 1, recorder->file);
	if(recorder->type == JANUS_RECORDER_DATA) {
		/* If it's data, then we need to prepend timing related info, as it's not there by itself */
		gint64 now = htonll(janus_get_real_time());
		fwrite(&now, sizeof(gint64), 1, recorder->file);
	}
	/* Save packet on file */
	int temp = 0, tot = length;
	while(tot > 0) {
		temp = fwrite(buffer+length-tot, sizeof(char), tot, recorder->file);
		if(temp <= 0) {
			JANUS_LOG(LOG_ERR, "Error saving frame...\n");
			janus_mutex_unlock_nodebug(&recorder->mutex);
			return -5;
		}
		tot -= temp;
	}
	/* Done */
	janus_mutex_unlock_nodebug(&recorder->mutex);
	return 0;
}
예제 #6
0
int janus_text2pcap_dump(janus_text2pcap *instance,
		janus_text2pcap_packet type, gboolean incoming, char *buf, int len, const char *format, ...) {
	if(instance == NULL || buf == NULL || len < 1)
		return -1;
	janus_mutex_lock_nodebug(&instance->mutex);
	if(instance->file == NULL || !g_atomic_int_get(&instance->writable)) {
		janus_mutex_unlock_nodebug(&instance->mutex);
		return -1;
	}
	/* If we're saving to .pcap directly, generate a packet header and save the payload */
	if(!instance->text) {
		/* Are we truncating? */
		int size = instance->truncate ? (len > instance->truncate ? instance->truncate : len) : len;
		int hsize = sizeof(janus_text2pcap_ethernet_header) + sizeof(janus_text2pcap_ip_header) +
			sizeof(janus_text2pcap_udp_header);
		int hsize_cut = hsize + size;
		int hsize_tot = hsize + len;
		/* We need a fake Ethernet/IP/UDP encapsulation for this packet */
		janus_text2pcap_ethernet_header eth;
		janus_text2pcap_ethernet_header_init(&eth);
		janus_text2pcap_ip_header ip;
		janus_text2pcap_ip_header_init(&ip, incoming, len);
		janus_text2pcap_udp_header udp;
		janus_text2pcap_udp_header_init(&udp, incoming, len);
		/* Now prepare the packet header */
		struct timeval tv;
		gettimeofday(&tv, NULL);
		janus_text2pcap_packet_header header = {
			tv.tv_sec, tv.tv_usec, hsize_cut, hsize_tot
		};
		fwrite(&header, sizeof(char), sizeof(header), instance->file);
		fwrite(&eth, sizeof(char), sizeof(eth), instance->file);
		fwrite(&ip, sizeof(char), sizeof(ip), instance->file);
		fwrite(&udp, sizeof(char), sizeof(udp), instance->file);
		/* The write the packet itself (or part of it) */
		int temp = 0, tot = size;
		while(tot > 0) {
			temp = fwrite(buf+size-tot, sizeof(char), tot, instance->file);
			if(temp <= 0) {
				JANUS_LOG(LOG_ERR, "Error dumping packet...\n");
				janus_mutex_unlock_nodebug(&instance->mutex);
				return -2;
			}
			tot -= temp;
		}
		/* Done */
		janus_mutex_unlock_nodebug(&instance->mutex);
		return 0;
	}
	/* If we got here, we need to prepare a text representation of the packet */
	char buffer[5000], timestamp[20], usec[10], byte[10];
	memset(timestamp, 0, sizeof(timestamp));
	memset(usec, 0, sizeof(usec));
	time_t t = time(NULL);
	struct tm *tm = localtime(&t);
	struct timeval tv;
	gettimeofday(&tv, NULL);
	strftime(timestamp, sizeof(timestamp), "%H:%M:%S", tm);
	g_snprintf(usec, sizeof(usec), ".%06ld", tv.tv_usec);
	g_strlcat(timestamp, usec, sizeof(timestamp));
	memset(buffer, 0, sizeof(buffer));
	g_snprintf(buffer, sizeof(buffer), "%s %s 000000 ", incoming ? "I" : "O", timestamp);
	int i=0;
	int stop = instance->truncate ? (len > instance->truncate ? instance->truncate : len) : len;
	for(i=0; i<stop; i++) {
		memset(byte, 0, sizeof(byte));
		g_snprintf(byte, sizeof(byte), " %02x", (unsigned char)buf[i]);
		g_strlcat(buffer, byte, sizeof(buffer));
	}
	g_strlcat(buffer, " ", sizeof(buffer));
	g_strlcat(buffer, janus_text2pcap_packet_string(type), sizeof(buffer));
	if(format) {
		/* This callback has variable arguments (error string) */
		char custom[512];
		va_list ap;
		va_start(ap, format);
		g_vsnprintf(custom, sizeof(custom), format, ap);
		va_end(ap);
		g_strlcat(buffer, " ", sizeof(buffer));
		g_strlcat(buffer, custom, sizeof(buffer));
	}
	g_strlcat(buffer, "\r\n", sizeof(buffer));
	/* Save textified packet on file */
	int temp = 0, buflen = strlen(buffer), tot = buflen;
	while(tot > 0) {
		temp = fwrite(buffer+buflen-tot, sizeof(char), tot, instance->file);
		if(temp <= 0) {
			JANUS_LOG(LOG_ERR, "Error dumping packet...\n");
			janus_mutex_unlock_nodebug(&instance->mutex);
			return -2;
		}
		tot -= temp;
	}
	/* Done */
	janus_mutex_unlock_nodebug(&instance->mutex);
	return 0;
}