mirror of https://github.com/sipwise/rtpengine.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
5.5 KiB
201 lines
5.5 KiB
/**
|
|
* recording.h
|
|
*
|
|
* Handles call recording to PCAP files and recording metadata.
|
|
* Mostly filesystem operations
|
|
*/
|
|
|
|
#ifndef __RECORDING_H__
|
|
#define __RECORDING_H__
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <netinet/in.h>
|
|
#include <pcap.h>
|
|
#include "str.h"
|
|
#include "aux.h"
|
|
#include "bencode.h"
|
|
|
|
|
|
struct packet_stream;
|
|
struct media_packet;
|
|
struct call;
|
|
enum call_opmode;
|
|
struct rtpengine_target_info;
|
|
struct call_monologue;
|
|
struct call_media;
|
|
|
|
|
|
struct recording_pcap {
|
|
FILE *meta_fp;
|
|
pcap_t *recording_pd;
|
|
pcap_dumper_t *recording_pdumper;
|
|
uint64_t packet_num;
|
|
char *recording_path;
|
|
|
|
mutex_t recording_lock;
|
|
};
|
|
|
|
struct recording_proc {
|
|
unsigned int call_idx;
|
|
};
|
|
struct recording_stream_proc {
|
|
unsigned int stream_idx;
|
|
};
|
|
|
|
struct recording {
|
|
union {
|
|
struct recording_pcap pcap;
|
|
struct recording_proc proc;
|
|
} u;
|
|
|
|
char *escaped_callid; // call-id with dangerous characters escaped
|
|
char *meta_prefix; // escaped call-id plus random suffix
|
|
char *meta_filepath; // full file path
|
|
};
|
|
|
|
struct recording_stream {
|
|
union {
|
|
struct recording_stream_proc proc;
|
|
} u;
|
|
};
|
|
|
|
struct recording_method {
|
|
const char *name;
|
|
int kernel_support;
|
|
|
|
int (*create_spool_dir)(const char *);
|
|
void (*init_struct)(struct call *);
|
|
|
|
void (*sdp_before)(struct recording *, const str *, struct call_monologue *, enum call_opmode);
|
|
void (*sdp_after)(struct recording *, GString *, struct call_monologue *,
|
|
enum call_opmode);
|
|
void (*meta_chunk)(struct recording *, const char *, const str *);
|
|
void (*update_flags)(struct call *call);
|
|
|
|
void (*dump_packet)(struct media_packet *, const str *s);
|
|
void (*finish)(struct call *);
|
|
void (*response)(struct recording *, bencode_item_t *);
|
|
|
|
void (*init_stream_struct)(struct packet_stream *);
|
|
void (*setup_stream)(struct packet_stream *);
|
|
void (*setup_media)(struct call_media *);
|
|
void (*setup_monologue)(struct call_monologue *);
|
|
void (*stream_kernel_info)(struct packet_stream *, struct rtpengine_target_info *);
|
|
};
|
|
|
|
extern const struct recording_method *selected_recording_method;
|
|
|
|
#define _rm_ret(method, args...) selected_recording_method->method(args)
|
|
#define _rm(method, args...) do { \
|
|
if (selected_recording_method && selected_recording_method->method) \
|
|
selected_recording_method->method(args); \
|
|
} while (0)
|
|
#define _rm_chk(method, recording, ...) do { \
|
|
if (recording) \
|
|
_rm(method, recording, ##__VA_ARGS__); \
|
|
} while (0)
|
|
|
|
|
|
|
|
/**
|
|
* Initialize RTP Engine filesystem settings and structure.
|
|
* Check for or create the RTP Engine spool directory.
|
|
*/
|
|
void recording_fs_init(const char *spooldir, const char *method, const char *format);
|
|
void recording_fs_free(void);
|
|
|
|
|
|
/**
|
|
*
|
|
* Controls the setting of recording variables on a `struct call *`.
|
|
* Sets the `record_call` value on the `struct call`, initializing the
|
|
* recording struct if necessary.
|
|
* If we do not yet have a PCAP file associated with the call, create it
|
|
* and write its file URL to the metadata file.
|
|
*
|
|
* Returns a boolean for whether or not the call is being recorded.
|
|
*/
|
|
void detect_setup_recording(struct call *call, const str *recordcall, str *metadata);
|
|
|
|
void recording_start(struct call *call, const char *prefix, str *metadata, str *output_dest);
|
|
void recording_stop(struct call *call, str *metadata);
|
|
|
|
|
|
/**
|
|
* Create a call metadata file in a temporary location.
|
|
* Attaches the filepath and the file pointer to the call struct.
|
|
* Returns path to created file.
|
|
*
|
|
* Metadata file format is (with trailing newline):
|
|
*
|
|
* /path/to/recording-pcap.pcap
|
|
*
|
|
*
|
|
* first SDP answer
|
|
*
|
|
* second SDP answer
|
|
*
|
|
* ...
|
|
*
|
|
* n-th and final SDP answer
|
|
*
|
|
*
|
|
* start timestamp (YYYY-MM-DDThh:mm:ss)
|
|
* end timestamp (YYYY-MM-DDThh:mm:ss)
|
|
*
|
|
*
|
|
* generic metadata
|
|
*
|
|
* There are two empty lines between each logic block of metadata.
|
|
* The generic metadata at the end can be any length with any number of lines.
|
|
* Temporary files go in /tmp/. They will end up in
|
|
* ${RECORDING_DIR}/metadata/. They are named like:
|
|
* ${CALL_ID}-${RAND-HEX}.pcap
|
|
*
|
|
*/
|
|
//str *meta_setup_file(struct recording *recording, str callid);
|
|
|
|
/**
|
|
* Write out a block of SDP to the metadata file.
|
|
*/
|
|
//ssize_t meta_write_sdp(struct recording *, struct iovec *sdp_iov, int iovcnt,
|
|
// enum call_opmode opmode);
|
|
#define meta_write_sdp_before(args...) _rm(sdp_before, args)
|
|
#define meta_write_sdp_after(args...) _rm(sdp_after, args)
|
|
|
|
/**
|
|
* Writes metadata to metafile, closes file, and moves it to finished location.
|
|
* Returns non-zero for failure.
|
|
*
|
|
* Metadata files are moved to ${RECORDING_DIR}/metadata/
|
|
*/
|
|
// int meta_finish_file(struct call *call);
|
|
|
|
/**
|
|
* Flushes PCAP file, closes the dumper and descriptors, and frees object memory.
|
|
*/
|
|
// void recording_finish_file(struct recording *recording);
|
|
|
|
// combines the two calls above
|
|
void recording_finish(struct call *);
|
|
|
|
/**
|
|
* Write out a PCAP packet with payload string.
|
|
* A fair amount extraneous of packet data is spoofed.
|
|
*/
|
|
// void dump_packet(struct recording *, struct packet_stream *, str *s);
|
|
#define dump_packet(args...) _rm_chk(dump_packet, args)
|
|
|
|
|
|
|
|
#define recording_setup_stream(args...) _rm(setup_stream, args)
|
|
#define recording_setup_media(args...) _rm(setup_media, args)
|
|
#define recording_setup_monologue(args...) _rm(setup_monologue, args)
|
|
#define recording_init_stream(args...) _rm(init_stream_struct, args)
|
|
#define recording_stream_kernel_info(args...) _rm(stream_kernel_info, args)
|
|
#define recording_meta_chunk(args...) _rm(meta_chunk, args)
|
|
#define recording_response(args...) _rm(response, args)
|
|
|
|
#endif
|