aboutsummaryrefslogtreecommitdiffstats
path: root/src/storage.c
blob: 2b9fb9f01321397ff5e13f473ce46b76cbe72669 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <time.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>

#include <osmocom/core/msgb.h>
#include <osmocom/abis/e1_input.h>

#include "storage.h"
#include "recorder.h"

static int g_out_fd = -1;;
static uint64_t g_written_bytes;

static const char *storage_gen_filename(void)
{
	static char buf[32];
	time_t t;
	struct tm *tmp;

	t = time(NULL);
	tmp = localtime(&t);
	strftime(buf, sizeof(buf), "%Y%m%d%H%M%S.e1cap", tmp);
	return buf;
}

static int storage_reopen_if_needed(void)
{
	if (g_written_bytes / (1024*1024) >= g_recorder.max_file_size_mb) {
		close(g_out_fd);
		g_out_fd = -1;
	}

	if (g_out_fd < 0) {
		int rc;
		const char *fname = storage_gen_filename();
		rc = chdir(g_recorder.storage_path);
		if (rc < 0) {
			LOGP(DMAIN, LOGL_ERROR, "Unable to chdir(%s): %s\n",
				g_recorder.storage_path, strerror(errno));
			return -1;
		}
		g_out_fd = open(fname, O_WRONLY|O_CREAT, 0664);
		if (g_out_fd < 0) {
			LOGP(DMAIN, LOGL_ERROR, "Unable to open(%s): %s\n",
				fname, strerror(errno));
		}
		g_written_bytes = 0;
	}

	return g_out_fd;
}

int e1frame_store(struct e1inp_ts *ts, struct msgb *msg, enum osmo_e1cap_capture_mode mode)
{
	struct osmo_e1cap_pkthdr _h, *h = &_h;
	int rc;
	struct iovec iov[2] = {
		{
			.iov_base = h,
			.iov_len = sizeof(*h),
		}, {
			.iov_base = msg->data,
			.iov_len = msg->len,
		}
	};

	h->len = htonl(msg->len);
	gettimeofday(&h->ts, NULL);
	h->line_nr = ts->line->num;
	h->ts_nr = ts->num;
	h->capture_mode = mode;
	h->flags = 0;

	storage_reopen_if_needed();

	rc = writev(g_out_fd, iov, ARRAY_SIZE(iov));
	if (rc < 0)
		return rc;

	g_written_bytes += rc;

	return 0;
}