blob: 2b9fb9f01321397ff5e13f473ce46b76cbe72669 [file] [log] [blame]
#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;
}