Browse Source

MT#55283 introduce abstract parsing framework

Change-Id: I63ba6fc7e6278e989e87a3abdb66976084b403bc
pull/1848/head
Richard Fuchs 1 year ago
parent
commit
3f8f182119
10 changed files with 253 additions and 219 deletions
  1. +86
    -80
      daemon/call_interfaces.c
  2. +58
    -47
      daemon/control_ng.c
  3. +24
    -25
      daemon/control_ng_flags_parser.c
  4. +3
    -3
      daemon/statistics.c
  5. +0
    -33
      include/call.h
  6. +25
    -27
      include/call_interfaces.h
  7. +51
    -0
      include/control_ng.h
  8. +2
    -3
      include/control_ng_flags_parser.h
  9. +1
    -1
      include/statistics.h
  10. +3
    -0
      include/types.h

+ 86
- 80
daemon/call_interfaces.c View File

@ -1300,9 +1300,8 @@ void call_ng_flags_init(sdp_ng_flags *out, enum call_opmode opmode) {
out->frequencies = g_array_new(false, false, sizeof(int));
}
static void call_ng_dict_iter(sdp_ng_flags *out, bencode_item_t *input,
enum call_opmode opmode,
void (*callback)(sdp_ng_flags *, str *key, bencode_item_t *value, enum call_opmode _opmode))
static void call_ng_dict_iter(ng_parser_ctx_t *ctx, bencode_item_t *input,
void (*callback)(ng_parser_ctx_t *, str *key, bencode_item_t *value))
{
if (input->type != BENCODE_DICTIONARY)
return;
@ -1317,8 +1316,7 @@ static void call_ng_dict_iter(sdp_ng_flags *out, bencode_item_t *input,
if (!bencode_get_str(key, &k))
continue;
callback(out, &k, value, opmode);
callback(ctx, &k, value);
}
}
void call_ng_direction_flag(sdp_ng_flags *out, bencode_item_t *value)
@ -1329,9 +1327,8 @@ void call_ng_direction_flag(sdp_ng_flags *out, bencode_item_t *value)
for (bencode_item_t *cit = value->child; cit && diridx < 2; cit = cit->sibling)
bencode_get_str(cit, &out->direction[diridx++]);
}
void call_ng_codec_flags(sdp_ng_flags *out, str *key, bencode_item_t *value,
enum call_opmode opmode)
{
void call_ng_codec_flags(ng_parser_ctx_t *ctx, str *key, bencode_item_t *value) {
sdp_ng_flags *out = ctx->flags;
switch (__csh_lookup(key)) {
case CSH_LOOKUP("except"):
call_ng_flags_str_list(out, value, call_ng_flags_str_ht, &out->codec_except);
@ -1435,11 +1432,10 @@ static void call_ng_flags_freqs(sdp_ng_flags *out, bencode_item_t *value) {
}
}
void call_ng_main_flags(sdp_ng_flags *out, str *key, bencode_item_t *value,
enum call_opmode opmode)
{
void call_ng_main_flags(ng_parser_ctx_t *ctx, str *key, bencode_item_t *value) {
str s = STR_NULL;
bencode_item_t *it;
sdp_ng_flags *out = ctx->flags;
bencode_get_str(value, &s);
@ -1524,7 +1520,7 @@ void call_ng_main_flags(sdp_ng_flags *out, str *key, bencode_item_t *value,
out->digit = s.s[0];
break;
case CSH_LOOKUP("codec"):
call_ng_dict_iter(out, value, opmode, call_ng_codec_flags);
call_ng_dict_iter(ctx, value, call_ng_codec_flags);
break;
case CSH_LOOKUP("command"):
break;
@ -1868,7 +1864,7 @@ void call_ng_main_flags(sdp_ng_flags *out, str *key, bencode_item_t *value,
case CSH_LOOKUP("rtpp-flags"):
case CSH_LOOKUP("rtpp_flags"):;
/* s - list of rtpp flags */
parse_rtpp_flags(&s, value->buffer, opmode, out);
parse_rtpp_flags(&s, ctx);
break;
case CSH_LOOKUP("SDES"):
case CSH_LOOKUP("sdes"):
@ -2013,9 +2009,11 @@ void call_ng_main_flags(sdp_ng_flags *out, str *key, bencode_item_t *value,
}
}
static void call_ng_process_flags(sdp_ng_flags *out, bencode_item_t *input, enum call_opmode opmode) {
static void call_ng_process_flags(sdp_ng_flags *out, ng_parser_ctx_t *ctx, enum call_opmode opmode) {
call_ng_flags_init(out, opmode);
call_ng_dict_iter(out, input, opmode, call_ng_main_flags);
ctx->opmode = opmode;
ctx->flags = out;
call_ng_dict_iter(ctx, ctx->req, call_ng_main_flags);
}
static void ng_sdp_attr_manipulations_free(struct sdp_manipulations * array[__MT_MAX]) {
@ -2134,8 +2132,7 @@ static enum basic_errors call_ng_basic_checks(sdp_ng_flags *flags, enum call_opm
return 0;
}
static const char *call_offer_answer_ng(ng_buffer *ngbuf, bencode_item_t *input,
bencode_item_t *output, enum call_opmode opmode, const char* addr,
static const char *call_offer_answer_ng(ng_parser_ctx_t *ctx, enum call_opmode opmode, const char* addr,
const endpoint_t *sin)
{
const char *errstr;
@ -2147,8 +2144,9 @@ static const char *call_offer_answer_ng(ng_buffer *ngbuf, bencode_item_t *input,
int ret;
g_auto(sdp_ng_flags) flags;
struct sdp_chopper *chopper;
bencode_item_t *output = ctx->resp;
call_ng_process_flags(&flags, input, opmode);
call_ng_process_flags(&flags, ctx, opmode);
if ((ret = call_ng_basic_checks(&flags, opmode)) > 0)
return _ng_basic_errors[ret];
@ -2178,7 +2176,7 @@ static const char *call_offer_answer_ng(ng_buffer *ngbuf, bencode_item_t *input,
call = call_get(&flags.call_id);
// SDP fragments for trickle ICE must always operate on an existing call
if (opmode == OP_OFFER && trickle_ice_update(ngbuf, call, &flags, &streams)) {
if (opmode == OP_OFFER && trickle_ice_update(ctx->ngbuf, call, &flags, &streams)) {
errstr = NULL;
// SDP fragments for trickle ICE are consumed with no replacement returned
goto out;
@ -2298,23 +2296,25 @@ out:
return errstr;
}
const char *call_offer_ng(ng_buffer *ngbuf, bencode_item_t *input, bencode_item_t *output,
const char *call_offer_ng(ng_parser_ctx_t *ctx,
const char* addr,
const endpoint_t *sin)
{
return call_offer_answer_ng(ngbuf, input, output, OP_OFFER, addr, sin);
return call_offer_answer_ng(ctx, OP_OFFER, addr, sin);
}
const char *call_answer_ng(ng_buffer *ngbuf, bencode_item_t *input, bencode_item_t *output) {
return call_offer_answer_ng(ngbuf, input, output, OP_ANSWER, NULL, NULL);
const char *call_answer_ng(ng_parser_ctx_t *ctx) {
return call_offer_answer_ng(ctx, OP_ANSWER, NULL, NULL);
}
const char *call_delete_ng(bencode_item_t *input, bencode_item_t *output) {
const char *call_delete_ng(ng_parser_ctx_t *ctx) {
str fromtag, totag, viabranch, callid;
bencode_item_t *flags, *it;
bool fatal = false;
bool discard = false;
int delete_delay;
bencode_item_t *input = ctx->req;
bencode_item_t *output = ctx->resp;
if (!bencode_dictionary_get_str(input, "call-id", &callid))
return "No call-id in message";
@ -2773,9 +2773,11 @@ static void ng_list_calls(bencode_item_t *output, long long int limit) {
const char *call_query_ng(bencode_item_t *input, bencode_item_t *output) {
const char *call_query_ng(ng_parser_ctx_t *ctx) {
str callid, fromtag, totag;
call_t *call;
bencode_item_t *input = ctx->req;
bencode_item_t *output = ctx->resp;
if (!bencode_dictionary_get_str(input, "call-id", &callid))
return "No call-id in message";
@ -2793,9 +2795,11 @@ const char *call_query_ng(bencode_item_t *input, bencode_item_t *output) {
}
const char *call_list_ng(bencode_item_t *input, bencode_item_t *output) {
const char *call_list_ng(ng_parser_ctx_t *ctx) {
bencode_item_t *calls = NULL;
long long int limit;
bencode_item_t *input = ctx->req;
bencode_item_t *output = ctx->resp;
limit = bencode_dictionary_get_int_str(input, "limit", 32);
@ -2810,14 +2814,15 @@ const char *call_list_ng(bencode_item_t *input, bencode_item_t *output) {
}
static const char *call_recording_common_ng(bencode_item_t *input, bencode_item_t *output,
static const char *call_recording_common_ng(ng_parser_ctx_t *ctx,
enum call_opmode opmode,
void (*fn)(bencode_item_t *input, call_t *call))
{
g_auto(sdp_ng_flags) flags;
g_autoptr(call_t) call = NULL;
bencode_item_t *input = ctx->req;
call_ng_process_flags(&flags, input, opmode);
call_ng_process_flags(&flags, ctx, opmode);
if (!bencode_dictionary_get_str(input, "call-id", &flags.call_id))
return "No call-id in message";
@ -2850,16 +2855,16 @@ static const char *call_recording_common_ng(bencode_item_t *input, bencode_item_
static void start_recording_fn(bencode_item_t *input, call_t *call) {
recording_start(call);
}
const char *call_start_recording_ng(bencode_item_t *input, bencode_item_t *output) {
return call_recording_common_ng(input, output, OP_START_RECORDING, start_recording_fn);
const char *call_start_recording_ng(ng_parser_ctx_t *ctx) {
return call_recording_common_ng(ctx, OP_START_RECORDING, start_recording_fn);
}
static void pause_recording_fn(bencode_item_t *input, call_t *call) {
recording_pause(call);
}
const char *call_pause_recording_ng(bencode_item_t *input, bencode_item_t *output) {
return call_recording_common_ng(input, output, OP_PAUSE_RECORDING, pause_recording_fn);
const char *call_pause_recording_ng(ng_parser_ctx_t *ctx) {
return call_recording_common_ng(ctx, OP_PAUSE_RECORDING, pause_recording_fn);
}
@ -2889,8 +2894,8 @@ static void stop_recording_fn(bencode_item_t *input, call_t *call) {
recording_stop(call);
}
const char *call_stop_recording_ng(bencode_item_t *input, bencode_item_t *output) {
return call_recording_common_ng(input, output, OP_STOP_RECORDING, stop_recording_fn);
const char *call_stop_recording_ng(ng_parser_ctx_t *ctx) {
return call_recording_common_ng(ctx, OP_STOP_RECORDING, stop_recording_fn);
}
@ -2940,12 +2945,12 @@ found:
return NULL;
}
static const char *media_block_match(call_t **call, struct call_monologue **monologue,
sdp_ng_flags *flags, bencode_item_t *input, enum call_opmode opmode)
sdp_ng_flags *flags, ng_parser_ctx_t *ctx, enum call_opmode opmode)
{
*call = NULL;
*monologue = NULL;
call_ng_process_flags(flags, input, opmode);
call_ng_process_flags(flags, ctx, opmode);
if (!flags->call_id.s)
return "No call-id in message";
@ -2976,9 +2981,9 @@ void add_media_to_sub_list(subscription_q *q, struct call_media *media, struct c
t_queue_push_tail(q, ms);
}
static const char *media_block_match_mult(call_t **call, subscription_q *medias,
sdp_ng_flags *flags, bencode_item_t *input, enum call_opmode opmode)
sdp_ng_flags *flags, ng_parser_ctx_t *ctx, enum call_opmode opmode)
{
call_ng_process_flags(flags, input, opmode);
call_ng_process_flags(flags, ctx, opmode);
if (!flags->call_id.s)
return "No call-id in message";
@ -3040,13 +3045,13 @@ static const char *media_block_match_mult(call_t **call, subscription_q *medias,
}
// XXX these are all identical - unify and use a flags int and/or callback
const char *call_start_forwarding_ng(bencode_item_t *input, bencode_item_t *output) {
const char *call_start_forwarding_ng(ng_parser_ctx_t *ctx) {
g_autoptr(call_t) call = NULL;
struct call_monologue *monologue;
const char *errstr = NULL;
g_auto(sdp_ng_flags) flags;
errstr = media_block_match(&call, &monologue, &flags, input, OP_START_FORWARDING);
errstr = media_block_match(&call, &monologue, &flags, ctx, OP_START_FORWARDING);
if (errstr)
return errstr;
@ -3069,13 +3074,13 @@ const char *call_start_forwarding_ng(bencode_item_t *input, bencode_item_t *outp
return NULL;
}
const char *call_stop_forwarding_ng(bencode_item_t *input, bencode_item_t *output) {
const char *call_stop_forwarding_ng(ng_parser_ctx_t *ctx) {
g_autoptr(call_t) call = NULL;
struct call_monologue *monologue;
const char *errstr = NULL;
g_auto(sdp_ng_flags) flags;
errstr = media_block_match(&call, &monologue, &flags, input, OP_STOP_FORWARDING);
errstr = media_block_match(&call, &monologue, &flags, ctx, OP_STOP_FORWARDING);
if (errstr)
return errstr;
@ -3177,13 +3182,13 @@ static void call_set_dtmf_block(call_t *call, struct call_monologue *monologue,
}
}
const char *call_block_dtmf_ng(bencode_item_t *input, bencode_item_t *output) {
const char *call_block_dtmf_ng(ng_parser_ctx_t *ctx) {
g_autoptr(call_t) call = NULL;
struct call_monologue *monologue;
const char *errstr = NULL;
g_auto(sdp_ng_flags) flags;
errstr = media_block_match(&call, &monologue, &flags, input, OP_BLOCK_DTMF);
errstr = media_block_match(&call, &monologue, &flags, ctx, OP_BLOCK_DTMF);
if (errstr)
return errstr;
@ -3192,13 +3197,13 @@ const char *call_block_dtmf_ng(bencode_item_t *input, bencode_item_t *output) {
return NULL;
}
const char *call_unblock_dtmf_ng(bencode_item_t *input, bencode_item_t *output) {
const char *call_unblock_dtmf_ng(ng_parser_ctx_t *ctx) {
g_autoptr(call_t) call = NULL;
struct call_monologue *monologue;
const char *errstr = NULL;
g_auto(sdp_ng_flags) flags;
errstr = media_block_match(&call, &monologue, &flags, input, OP_UNBLOCK_DTMF);
errstr = media_block_match(&call, &monologue, &flags, ctx, OP_UNBLOCK_DTMF);
if (errstr)
return errstr;
@ -3251,7 +3256,7 @@ const char *call_unblock_dtmf_ng(bencode_item_t *input, bencode_item_t *output)
return NULL;
}
static const char *call_block_silence_media(bencode_item_t *input, bool on_off, const char *ucase_verb,
static const char *call_block_silence_media(ng_parser_ctx_t *ctx, bool on_off, const char *ucase_verb,
const char *lcase_verb,
unsigned int call_flag, unsigned int ml_flag, size_t attr_offset)
{
@ -3261,7 +3266,7 @@ static const char *call_block_silence_media(bencode_item_t *input, bool on_off,
g_auto(sdp_ng_flags) flags;
bool found_subscriptions = false;
errstr = media_block_match(&call, &monologue, &flags, input, OP_BLOCK_SILENCE_MEDIA);
errstr = media_block_match(&call, &monologue, &flags, ctx, OP_BLOCK_SILENCE_MEDIA);
if (errstr)
return errstr;
@ -3410,35 +3415,35 @@ static const char *call_block_silence_media(bencode_item_t *input, bool on_off,
return NULL;
}
#define CALL_BLOCK_SILENCE_MEDIA(input, on_off, ucase_verb, lcase_verb, member_name, flag) \
call_block_silence_media(input, on_off, ucase_verb, lcase_verb, \
#define CALL_BLOCK_SILENCE_MEDIA(ctx, on_off, ucase_verb, lcase_verb, member_name, flag) \
call_block_silence_media(ctx, on_off, ucase_verb, lcase_verb, \
CALL_FLAG_ ## flag, \
ML_FLAG_ ## flag, \
G_STRUCT_OFFSET(struct sink_attrs, member_name))
const char *call_block_media_ng(bencode_item_t *input, bencode_item_t *output) {
return CALL_BLOCK_SILENCE_MEDIA(input, true, "Blocking", "blocking", block_media, BLOCK_MEDIA);
const char *call_block_media_ng(ng_parser_ctx_t *ctx) {
return CALL_BLOCK_SILENCE_MEDIA(ctx, true, "Blocking", "blocking", block_media, BLOCK_MEDIA);
}
const char *call_unblock_media_ng(bencode_item_t *input, bencode_item_t *output) {
return CALL_BLOCK_SILENCE_MEDIA(input, false, "Unblocking", "unblocking", block_media, BLOCK_MEDIA);
const char *call_unblock_media_ng(ng_parser_ctx_t *ctx) {
return CALL_BLOCK_SILENCE_MEDIA(ctx, false, "Unblocking", "unblocking", block_media, BLOCK_MEDIA);
}
const char *call_silence_media_ng(bencode_item_t *input, bencode_item_t *output) {
return CALL_BLOCK_SILENCE_MEDIA(input, true, "Silencing", "silencing", silence_media, SILENCE_MEDIA);
const char *call_silence_media_ng(ng_parser_ctx_t *ctx) {
return CALL_BLOCK_SILENCE_MEDIA(ctx, true, "Silencing", "silencing", silence_media, SILENCE_MEDIA);
}
const char *call_unsilence_media_ng(bencode_item_t *input, bencode_item_t *output) {
return CALL_BLOCK_SILENCE_MEDIA(input, false, "Unsilencing", "unsilencing", silence_media, SILENCE_MEDIA);
const char *call_unsilence_media_ng(ng_parser_ctx_t *ctx) {
return CALL_BLOCK_SILENCE_MEDIA(ctx, false, "Unsilencing", "unsilencing", silence_media, SILENCE_MEDIA);
}
#ifdef WITH_TRANSCODING
static const char *play_media_select_party(call_t **call, monologues_q *monologues,
bencode_item_t *input, sdp_ng_flags *flags)
ng_parser_ctx_t *ctx, sdp_ng_flags *flags)
{
struct call_monologue *monologue;
t_queue_init(monologues);
const char *err = media_block_match(call, &monologue, flags, input, OP_PLAY_MEDIA);
const char *err = media_block_match(call, &monologue, flags, ctx, OP_PLAY_MEDIA);
if (err)
return err;
if (flags->all == ALL_ALL)
@ -3452,14 +3457,14 @@ static const char *play_media_select_party(call_t **call, monologues_q *monologu
#endif
const char *call_play_media_ng(bencode_item_t *input, bencode_item_t *output) {
const char *call_play_media_ng(ng_parser_ctx_t *ctx) {
#ifdef WITH_TRANSCODING
g_autoptr(call_t) call = NULL;
g_auto(monologues_q) monologues;
const char *err = NULL;
g_auto(sdp_ng_flags) flags;
err = play_media_select_party(&call, &monologues, input, &flags);
err = play_media_select_party(&call, &monologues, ctx, &flags);
if (err)
return err;
@ -3499,7 +3504,7 @@ const char *call_play_media_ng(bencode_item_t *input, bencode_item_t *output) {
return "No media file specified";
if (l == monologues.head && monologue->player->coder.duration)
bencode_dictionary_add_integer(output, "duration", monologue->player->coder.duration);
bencode_dictionary_add_integer(ctx->resp, "duration", monologue->player->coder.duration);
}
@ -3510,7 +3515,7 @@ const char *call_play_media_ng(bencode_item_t *input, bencode_item_t *output) {
}
const char *call_stop_media_ng(bencode_item_t *input, bencode_item_t *output) {
const char *call_stop_media_ng(ng_parser_ctx_t *ctx) {
#ifdef WITH_TRANSCODING
g_autoptr(call_t) call = NULL;
g_auto(monologues_q) monologues;
@ -3518,7 +3523,7 @@ const char *call_stop_media_ng(bencode_item_t *input, bencode_item_t *output) {
long long last_frame_pos = 0;
g_auto(sdp_ng_flags) flags;
err = play_media_select_party(&call, &monologues, input, &flags);
err = play_media_select_party(&call, &monologues, ctx, &flags);
if (err)
return err;
@ -3534,7 +3539,7 @@ const char *call_stop_media_ng(bencode_item_t *input, bencode_item_t *output) {
codec_update_all_source_handlers(monologue, NULL);
update_init_subscribers(monologue, OP_STOP_MEDIA);
}
bencode_dictionary_add_integer(output, "last-frame-pos", last_frame_pos);
bencode_dictionary_add_integer(ctx->resp, "last-frame-pos", last_frame_pos);
return NULL;
#else
@ -3543,14 +3548,14 @@ const char *call_stop_media_ng(bencode_item_t *input, bencode_item_t *output) {
}
const char *call_play_dtmf_ng(bencode_item_t *input, bencode_item_t *output) {
const char *call_play_dtmf_ng(ng_parser_ctx_t *ctx) {
#ifdef WITH_TRANSCODING
g_autoptr(call_t) call = NULL;
g_auto(monologues_q) monologues;
const char *err = NULL;
g_auto(sdp_ng_flags) flags;
err = play_media_select_party(&call, &monologues, input, &flags);
err = play_media_select_party(&call, &monologues, ctx, &flags);
if (err)
return err;
@ -3645,7 +3650,7 @@ found_sink:
}
const char *call_publish_ng(ng_buffer *ngbuf, bencode_item_t *input, bencode_item_t *output,
const char *call_publish_ng(ng_parser_ctx_t *ctx,
const char *addr,
const endpoint_t *sin)
{
@ -3657,7 +3662,7 @@ const char *call_publish_ng(ng_buffer *ngbuf, bencode_item_t *input, bencode_ite
g_autoptr(call_t) call = NULL;
int ret;
call_ng_process_flags(&flags, input, OP_PUBLISH);
call_ng_process_flags(&flags, ctx, OP_PUBLISH);
if ((ret = call_ng_basic_checks(&flags, OP_PUBLISH)) > 0)
return _ng_basic_errors[ret];
@ -3671,7 +3676,7 @@ const char *call_publish_ng(ng_buffer *ngbuf, bencode_item_t *input, bencode_ite
call = call_get_or_create(&flags.call_id, false);
if (trickle_ice_update(ngbuf, call, &flags, &streams))
if (trickle_ice_update(ctx->ngbuf, call, &flags, &streams))
return NULL;
updated_created_from(call, addr, sin);
@ -3684,8 +3689,8 @@ const char *call_publish_ng(ng_buffer *ngbuf, bencode_item_t *input, bencode_ite
ret = sdp_create(&sdp_out, ml, &flags);
if (!ret) {
save_last_sdp(ml, &sdp_in, &parsed, &streams);
bencode_buffer_destroy_add(output->buffer, g_free, sdp_out.s);
bencode_dictionary_add_str(output, "sdp", &sdp_out);
bencode_buffer_destroy_add(ctx->resp->buffer, g_free, sdp_out.s);
bencode_dictionary_add_str(ctx->resp, "sdp", &sdp_out);
sdp_out = STR_NULL; // ownership passed to output
}
@ -3700,16 +3705,17 @@ const char *call_publish_ng(ng_buffer *ngbuf, bencode_item_t *input, bencode_ite
}
const char *call_subscribe_request_ng(bencode_item_t *input, bencode_item_t *output) {
const char *call_subscribe_request_ng(ng_parser_ctx_t *ctx) {
const char *err = NULL;
g_auto(sdp_ng_flags) flags;
char rand_buf[65];
g_autoptr(call_t) call = NULL;
g_auto(subscription_q) srms = TYPED_GQUEUE_INIT;
g_auto(str) sdp_out = STR_NULL;
bencode_item_t *output = ctx->resp;
/* get source monologue */
err = media_block_match_mult(&call, &srms, &flags, input, OP_REQUEST);
err = media_block_match_mult(&call, &srms, &flags, ctx, OP_REQUEST);
if (err)
return err;
@ -3809,13 +3815,13 @@ const char *call_subscribe_request_ng(bencode_item_t *input, bencode_item_t *out
}
const char *call_subscribe_answer_ng(ng_buffer *ngbuf, bencode_item_t *input, bencode_item_t *output) {
const char *call_subscribe_answer_ng(ng_parser_ctx_t *ctx) {
g_auto(sdp_ng_flags) flags;
g_auto(sdp_sessions_q) parsed = TYPED_GQUEUE_INIT;
g_auto(sdp_streams_q) streams = TYPED_GQUEUE_INIT;
g_autoptr(call_t) call = NULL;
call_ng_process_flags(&flags, input, OP_REQ_ANSWER);
call_ng_process_flags(&flags, ctx, OP_REQ_ANSWER);
if (!flags.call_id.s)
return "No call-id in message";
@ -3823,7 +3829,7 @@ const char *call_subscribe_answer_ng(ng_buffer *ngbuf, bencode_item_t *input, be
if (!call)
return "Unknown call-ID";
if (trickle_ice_update(ngbuf, call, &flags, &streams))
if (trickle_ice_update(ctx->ngbuf, call, &flags, &streams))
return NULL;
if (!flags.to_tag.s)
@ -3851,11 +3857,11 @@ const char *call_subscribe_answer_ng(ng_buffer *ngbuf, bencode_item_t *input, be
}
const char *call_unsubscribe_ng(bencode_item_t *input, bencode_item_t *output) {
const char *call_unsubscribe_ng(ng_parser_ctx_t *ctx) {
g_auto(sdp_ng_flags) flags;
g_autoptr(call_t) call = NULL;
call_ng_process_flags(&flags, input, OP_REQ_ANSWER);
call_ng_process_flags(&flags, ctx, OP_REQ_ANSWER);
if (!flags.call_id.s)
return "No call-id in message";


+ 58
- 47
daemon/control_ng.c View File

@ -78,6 +78,15 @@ typedef struct ng_ctx {
func( __VA_ARGS__); \
} while (0)
const ng_parser_t ng_parser_native = {
.collapse = bencode_collapse_str,
};
const ng_parser_t ng_parser_json = {
.collapse = bencode_collapse_str_json,
};
void init_ng_tracing(void) {
if (rtpe_config.homer_ng_on && has_homer())
trace_ng = true;
@ -214,7 +223,6 @@ ng_buffer *ng_buffer_new(struct obj *ref) {
static void control_ng_process_payload(ng_ctx *hctx, str *reply, str *data, const endpoint_t *sin, char *addr, struct obj *ref,
struct ng_buffer **ngbufp)
{
bencode_item_t *dict, *resp;
str cmd = STR_NULL, callid;
const char *errstr, *resultstr;
GString *log_str;
@ -222,12 +230,14 @@ static void control_ng_process_payload(ng_ctx *hctx, str *reply, str *data, cons
struct control_ng_stats* cur = get_control_ng_stats(&sin->address);
enum ng_command command = -1;
struct ng_buffer *ngbuf = *ngbufp = ng_buffer_new(ref);
ng_parser_ctx_t parser_ctx = {
.parser = &ng_parser_native,
};
resp = bencode_dictionary(&ngbuf->buffer);
assert(resp != NULL);
parser_ctx.ngbuf = *ngbufp = ng_buffer_new(ref);
str *(*collapse_func)(bencode_item_t *root, str *out) = bencode_collapse_str;
parser_ctx.resp = bencode_dictionary(&parser_ctx.ngbuf->buffer);
assert(parser_ctx.resp != NULL);
errstr = "Invalid data (no payload)";
if (data->len <= 0)
@ -235,23 +245,23 @@ static void control_ng_process_payload(ng_ctx *hctx, str *reply, str *data, cons
/* Bencode dictionary */
if (data->s[0] == 'd') {
dict = bencode_decode_expect_str(&ngbuf->buffer, data, BENCODE_DICTIONARY);
parser_ctx.req = bencode_decode_expect_str(&parser_ctx.ngbuf->buffer, data, BENCODE_DICTIONARY);
errstr = "Could not decode bencode dictionary";
if (!dict)
if (!parser_ctx.req)
goto err_send;
}
/* JSON */
else if (data->s[0] == '{') {
collapse_func = bencode_collapse_str_json;
parser_ctx.parser = &ng_parser_json;
JsonParser *json = json_parser_new();
bencode_buffer_destroy_add(&ngbuf->buffer, g_object_unref, json);
bencode_buffer_destroy_add(&parser_ctx.ngbuf->buffer, g_object_unref, json);
errstr = "Failed to parse JSON document";
if (!json_parser_load_from_data(json, data->s, data->len, NULL))
goto err_send;
dict = bencode_convert_json(&ngbuf->buffer, json);
parser_ctx.req = bencode_convert_json(&parser_ctx.ngbuf->buffer, json);
errstr = "Could not decode bencode dictionary";
if (!dict || dict->type != BENCODE_DICTIONARY)
if (!parser_ctx.req || parser_ctx.req->type != BENCODE_DICTIONARY)
goto err_send;
}
@ -260,12 +270,12 @@ static void control_ng_process_payload(ng_ctx *hctx, str *reply, str *data, cons
goto err_send;
}
bencode_dictionary_get_str(dict, "command", &cmd);
bencode_dictionary_get_str(parser_ctx.req, "command", &cmd);
errstr = "Dictionary contains no key \"command\"";
if (!cmd.s)
goto err_send;
bencode_dictionary_get_str(dict, "call-id", &callid);
bencode_dictionary_get_str(parser_ctx.req, "call-id", &callid);
log_info_str(&callid);
ilogs(control, LOG_INFO, "Received command '"STR_FORMAT"' from %s", STR_FMT(&cmd), addr);
@ -274,7 +284,7 @@ static void control_ng_process_payload(ng_ctx *hctx, str *reply, str *data, cons
log_str = g_string_sized_new(256);
g_string_append_printf(log_str, "Dump for '"STR_FORMAT"' from %s: %s", STR_FMT(&cmd), addr,
rtpe_config.common.log_mark_prefix);
pretty_print(dict, log_str);
pretty_print(parser_ctx.req, log_str);
g_string_append(log_str, rtpe_config.common.log_mark_suffix);
ilogs(control, LOG_DEBUG, "%.*s", (int) log_str->len, log_str->str);
g_string_free(log_str, TRUE);
@ -292,99 +302,99 @@ static void control_ng_process_payload(ng_ctx *hctx, str *reply, str *data, cons
command = NGC_PING;
break;
case CSH_LOOKUP("offer"):
errstr = call_offer_ng(ngbuf, dict, resp, addr, sin);
errstr = call_offer_ng(&parser_ctx, addr, sin);
command = NGC_OFFER;
break;
case CSH_LOOKUP("answer"):
errstr = call_answer_ng(ngbuf, dict, resp);
errstr = call_answer_ng(&parser_ctx);
command = NGC_ANSWER;
break;
case CSH_LOOKUP("delete"):
errstr = call_delete_ng(dict, resp);
errstr = call_delete_ng(&parser_ctx);
command = NGC_DELETE;
break;
case CSH_LOOKUP("query"):
errstr = call_query_ng(dict, resp);
errstr = call_query_ng(&parser_ctx);
command = NGC_QUERY;
break;
case CSH_LOOKUP("list"):
errstr = call_list_ng(dict, resp);
errstr = call_list_ng(&parser_ctx);
command = NGC_LIST;
break;
case CSH_LOOKUP("start recording"):
errstr = call_start_recording_ng(dict, resp);
errstr = call_start_recording_ng(&parser_ctx);
command = NGC_START_RECORDING;
break;
case CSH_LOOKUP("stop recording"):
errstr = call_stop_recording_ng(dict, resp);
errstr = call_stop_recording_ng(&parser_ctx);
command = NGC_STOP_RECORDING;
break;
case CSH_LOOKUP("pause recording"):
errstr = call_pause_recording_ng(dict, resp);
errstr = call_pause_recording_ng(&parser_ctx);
command = NGC_PAUSE_RECORDING;
break;
case CSH_LOOKUP("start forwarding"):
errstr = call_start_forwarding_ng(dict, resp);
errstr = call_start_forwarding_ng(&parser_ctx);
command = NGC_START_FORWARDING;
break;
case CSH_LOOKUP("stop forwarding"):
errstr = call_stop_forwarding_ng(dict, resp);
errstr = call_stop_forwarding_ng(&parser_ctx);
command = NGC_STOP_FORWARDING;
break;
case CSH_LOOKUP("block DTMF"):
errstr = call_block_dtmf_ng(dict, resp);
errstr = call_block_dtmf_ng(&parser_ctx);
command = NGC_BLOCK_DTMF;
break;
case CSH_LOOKUP("unblock DTMF"):
errstr = call_unblock_dtmf_ng(dict, resp);
errstr = call_unblock_dtmf_ng(&parser_ctx);
command = NGC_UNBLOCK_DTMF;
break;
case CSH_LOOKUP("block media"):
errstr = call_block_media_ng(dict, resp);
errstr = call_block_media_ng(&parser_ctx);
command = NGC_BLOCK_MEDIA;
break;
case CSH_LOOKUP("unblock media"):
errstr = call_unblock_media_ng(dict, resp);
errstr = call_unblock_media_ng(&parser_ctx);
command = NGC_UNBLOCK_MEDIA;
break;
case CSH_LOOKUP("silence media"):
errstr = call_silence_media_ng(dict, resp);
errstr = call_silence_media_ng(&parser_ctx);
command = NGC_SILENCE_MEDIA;
break;
case CSH_LOOKUP("unsilence media"):
errstr = call_unsilence_media_ng(dict, resp);
errstr = call_unsilence_media_ng(&parser_ctx);
command = NGC_UNSILENCE_MEDIA;
break;
case CSH_LOOKUP("play media"):
errstr = call_play_media_ng(dict, resp);
errstr = call_play_media_ng(&parser_ctx);
command = NGC_PLAY_MEDIA;
break;
case CSH_LOOKUP("stop media"):
errstr = call_stop_media_ng(dict, resp);
errstr = call_stop_media_ng(&parser_ctx);
command = NGC_STOP_MEDIA;
break;
case CSH_LOOKUP("play DTMF"):
errstr = call_play_dtmf_ng(dict, resp);
errstr = call_play_dtmf_ng(&parser_ctx);
command = NGC_PLAY_DTMF;
break;
case CSH_LOOKUP("statistics"):
errstr = statistics_ng(dict, resp);
errstr = statistics_ng(&parser_ctx);
command = NGC_STATISTICS;
break;
case CSH_LOOKUP("publish"):
errstr = call_publish_ng(ngbuf, dict, resp, addr, sin);
errstr = call_publish_ng(&parser_ctx, addr, sin);
command = NGC_PUBLISH;
break;
case CSH_LOOKUP("subscribe request"):
errstr = call_subscribe_request_ng(dict, resp);
errstr = call_subscribe_request_ng(&parser_ctx);
command = NGC_SUBSCRIBE_REQ;
break;
case CSH_LOOKUP("subscribe answer"):
errstr = call_subscribe_answer_ng(ngbuf, dict, resp);
errstr = call_subscribe_answer_ng(&parser_ctx);
command = NGC_SUBSCRIBE_ANS;
break;
case CSH_LOOKUP("unsubscribe"):
errstr = call_unsubscribe_ng(dict, resp);
errstr = call_unsubscribe_ng(&parser_ctx);
command = NGC_UNSUBSCRIBE;
break;
default:
@ -409,7 +419,7 @@ static void control_ng_process_payload(ng_ctx *hctx, str *reply, str *data, cons
if (errstr)
goto err_send;
bencode_dictionary_add_string(resp, "result", resultstr);
bencode_dictionary_add_string(parser_ctx.resp, "result", resultstr);
// update interval statistics
RTPE_STATS_INC(ng_commands[command]);
@ -422,30 +432,31 @@ err_send:
if (errstr < magic_load_limit_strings[0] || errstr > magic_load_limit_strings[__LOAD_LIMIT_MAX-1]) {
ilogs(control, LOG_WARNING, "Protocol error in packet from %s: %s [" STR_FORMAT_M "]",
addr, errstr, STR_FMT_M(data));
bencode_dictionary_add_string(resp, "result", "error");
bencode_dictionary_add_string(resp, "error-reason", errstr);
bencode_dictionary_add_string(parser_ctx.resp, "result", "error");
bencode_dictionary_add_string(parser_ctx.resp, "error-reason", errstr);
g_atomic_int_inc(&cur->errors);
cmd = STR_NULL;
}
else {
bencode_dictionary_add_string(resp, "result", "load limit");
bencode_dictionary_add_string(resp, "message", errstr);
bencode_dictionary_add_string(parser_ctx.resp, "result", "load limit");
bencode_dictionary_add_string(parser_ctx.resp, "message", errstr);
}
send_resp:
collapse_func(resp, reply);
parser_ctx.parser->collapse(parser_ctx.resp, reply);
if (cmd.s) {
ilogs(control, LOG_INFO, "Replying to '"STR_FORMAT"' from %s (elapsed time %llu.%06llu sec)", STR_FMT(&cmd), addr, (unsigned long long)cmd_process_time.tv_sec, (unsigned long long)cmd_process_time.tv_usec);
if (get_log_level(control) >= LOG_DEBUG) {
dict = bencode_decode_expect_str(&ngbuf->buffer, reply, BENCODE_DICTIONARY);
if (dict) {
parser_ctx.req = bencode_decode_expect_str(&parser_ctx.ngbuf->buffer,
reply, BENCODE_DICTIONARY);
if (parser_ctx.req) {
log_str = g_string_sized_new(256);
g_string_append_printf(log_str, "Response dump for '"STR_FORMAT"' to %s: %s",
STR_FMT(&cmd), addr,
rtpe_config.common.log_mark_prefix);
pretty_print(dict, log_str);
pretty_print(parser_ctx.req, log_str);
g_string_append(log_str, rtpe_config.common.log_mark_suffix);
ilogs(control, LOG_DEBUG, "%.*s", (int) log_str->len, log_str->str);
g_string_free(log_str, TRUE);


+ 24
- 25
daemon/control_ng_flags_parser.c View File

@ -102,7 +102,7 @@ static bool str_key_val_prefix(const str * p, const char * q,
/* parse `received-from` */
static bool parse_received_from(str * key, str * val, bencode_buffer_t * buf,
sdp_ng_flags * out, enum call_opmode opmode)
ng_parser_ctx_t *ctx)
{
bencode_item_t * item;
int ip_af = AF_UNSPEC;
@ -117,15 +117,14 @@ static bool parse_received_from(str * key, str * val, bencode_buffer_t * buf,
bencode_list_add_str(item, &ipfamily);
bencode_list_add_str(item, &s);
call_ng_main_flags(out, &STR_CONST("received-from"), item, opmode);
call_ng_main_flags(ctx, &STR_CONST("received-from"), item);
return true;
}
return false;
}
static bool parse_codec_to_dict(str * key, str * val, const char *cmp1, const char *cmp2,
const char * dictstr, sdp_ng_flags * out, bencode_buffer_t * buf,
enum call_opmode opmode)
const char * dictstr, ng_parser_ctx_t *ctx, bencode_buffer_t * buf)
{
str s;
@ -136,29 +135,29 @@ static bool parse_codec_to_dict(str * key, str * val, const char *cmp1, const ch
return false;
}
call_ng_codec_flags(out, &STR(dictstr), bencode_str(buf, &s), opmode);
call_ng_codec_flags(ctx, &STR(dictstr), bencode_str(buf, &s));
return true;
}
/* parse codec related flags */
static bool parse_codecs(enum call_opmode opmode, sdp_ng_flags * out,
static bool parse_codecs(ng_parser_ctx_t *ctx,
bencode_buffer_t * buf, str * key, str * val)
{
if (parse_codec_to_dict(key, val, "transcode",
"codec-transcode", "transcode", out, buf, opmode) ||
"codec-transcode", "transcode", ctx, buf) ||
parse_codec_to_dict(key, val, "codec-strip",
NULL, "strip", out, buf, opmode) ||
NULL, "strip", ctx, buf) ||
parse_codec_to_dict(key, val, "codec-offer",
NULL, "offer", out, buf, opmode) ||
NULL, "offer", ctx, buf) ||
parse_codec_to_dict(key, val, "codec-mask",
NULL, "mask", out, buf, opmode) ||
NULL, "mask", ctx, buf) ||
parse_codec_to_dict(key, val, "codec-set",
NULL, "set", out, buf, opmode) ||
NULL, "set", ctx, buf) ||
parse_codec_to_dict(key, val, "codec-accept",
NULL, "accept", out, buf, opmode) ||
NULL, "accept", ctx, buf) ||
parse_codec_to_dict(key, val, "codec-except",
NULL, "except", out, buf, opmode))
NULL, "except", ctx, buf))
{
return true;
}
@ -167,13 +166,13 @@ static bool parse_codecs(enum call_opmode opmode, sdp_ng_flags * out,
}
/* prase transport, such as for example RTP/AVP */
static void parse_transports(sdp_ng_flags *out, bencode_buffer_t *buf,
enum call_opmode opmode, unsigned int transport)
static void parse_transports(ng_parser_ctx_t *ctx, bencode_buffer_t *buf,
unsigned int transport)
{
const char * val = transports[transport & 0x007];
if (!val)
return;
call_ng_main_flags(out, &STR_CONST("transport-protocol"), bencode_string(buf, val), opmode);
call_ng_main_flags(ctx, &STR_CONST("transport-protocol"), bencode_string(buf, val));
}
#if 0
@ -197,12 +196,12 @@ static bool parse_str_flag(str * key, str * val, const char * name,
* @param rtpp_flags - raw str rtpp_flags
* @param dict - root dict to store encoded flags
*/
void parse_rtpp_flags(const str * rtpp_flags, bencode_buffer_t * buf,
enum call_opmode opmode, sdp_ng_flags * out)
void parse_rtpp_flags(const str * rtpp_flags, ng_parser_ctx_t *ctx)
{
str remainder, key, val;
bencode_item_t * direction;
unsigned int transport = 0;
bencode_buffer_t *buf = &ctx->ngbuf->buffer;
if (!rtpp_flags->s)
return;
@ -222,11 +221,11 @@ void parse_rtpp_flags(const str * rtpp_flags, bencode_buffer_t * buf,
break;
/* specific received-from parsing */
if (parse_received_from(&key, &val, buf, out, opmode))
if (parse_received_from(&key, &val, buf, ctx))
goto next;
/* codecs have own specific parsing as well */
if (parse_codecs(opmode, out, buf, &key, &val))
if (parse_codecs(ctx, buf, &key, &val))
goto next;
/* parse other generic flags */
@ -273,7 +272,7 @@ void parse_rtpp_flags(const str * rtpp_flags, bencode_buffer_t * buf,
transport = 0x101;
/* from-tag can be overriden, but originally has to be provided */
else if (val.s && str_eq(&key, "from-tag")) {
out->directional = 1; /* explicitly add directional for this case */
ctx->flags->directional = 1; /* explicitly add directional for this case */
goto generic;
}
/* direction */
@ -316,19 +315,19 @@ void parse_rtpp_flags(const str * rtpp_flags, bencode_buffer_t * buf,
generic:
/* generic one key flags */
if (!val.s)
call_ng_flags_flags(out, &key, NULL);
call_ng_flags_flags(ctx->flags, &key, NULL);
/* generic flags with value, but no particular processing */
else
call_ng_main_flags(out, &key, bencode_str(buf, &val), opmode);
call_ng_main_flags(ctx, &key, bencode_str(buf, &val));
next:;
}
/* define transport */
if (transport)
parse_transports(out, buf, opmode, transport);
parse_transports(ctx, buf, transport);
/* add directions to the root dict */
if (direction && direction->child)
call_ng_direction_flag(out, direction);
call_ng_direction_flag(ctx->flags, direction);
}

+ 3
- 3
daemon/statistics.c View File

@ -952,13 +952,13 @@ void statistics_init(void) {
rtpe_codec_stats = codec_stats_ht_new();
}
const char *statistics_ng(bencode_item_t *input, bencode_item_t *output) {
const char *statistics_ng(ng_parser_ctx_t *ctx) {
g_autoptr(stats_metric_q) metrics = statistics_gather_metrics(NULL);
g_auto(GQueue) bstack = G_QUEUE_INIT;
bencode_item_t *dict = output;
bencode_item_t *dict = ctx->resp;
const char *sub_label = "statistics"; // top level
bencode_buffer_t *buf = output->buffer;
bencode_buffer_t *buf = &ctx->ngbuf->buffer;
for (__auto_type l = metrics->head; l; l = l->next) {
stats_metric *m = l->data;


+ 0
- 33
include/call.h View File

@ -59,39 +59,6 @@ enum message_type {
SIP_REPLY,
};
enum call_opmode {
OP_OFFER = 0,
OP_ANSWER = 1,
OP_REQUEST,
OP_REQ_ANSWER,
OP_PUBLISH,
OP_DELETE,
OP_QUERY,
OP_LIST,
OP_PING,
OP_STATISTICS,
OP_PLAY_DTMF,
OP_BLOCK_DTMF,
OP_UNBLOCK_DTMF,
OP_BLOCK_MEDIA,
OP_UNBLOCK_MEDIA,
OP_SILENCE_MEDIA,
OP_UNSILENCE_MEDIA,
OP_BLOCK_SILENCE_MEDIA,
OP_UNBLOCK_SILENCE_MEDIA,
OP_PLAY_MEDIA,
OP_STOP_MEDIA,
OP_START_FORWARDING,
OP_STOP_FORWARDING,
OP_SUBSCRIBER_REQ,
OP_SUBSCRIBER_ANS,
OP_UNSUBSCRIBE,
OP_START_RECORDING,
OP_STOP_RECORDING,
OP_PAUSE_RECORDING,
OP_OTHER,
};
#define IS_OP_OTHER(opmode) \
((opmode == OP_DELETE || opmode == OP_QUERY) \
|| (opmode == OP_LIST || opmode == OP_PING) \


+ 25
- 27
include/call_interfaces.h View File

@ -251,33 +251,33 @@ str *call_lookup_udp(char **);
str *call_delete_udp(char **);
str *call_query_udp(char **);
const char *call_offer_ng(ng_buffer *, bencode_item_t *, bencode_item_t *, const char*,
const char *call_offer_ng(ng_parser_ctx_t *, const char*,
const endpoint_t *);
const char *call_answer_ng(ng_buffer *, bencode_item_t *, bencode_item_t *);
const char *call_delete_ng(bencode_item_t *, bencode_item_t *);
const char *call_query_ng(bencode_item_t *, bencode_item_t *);
const char *call_list_ng(bencode_item_t *, bencode_item_t *);
const char *call_start_recording_ng(bencode_item_t *, bencode_item_t *);
const char *call_stop_recording_ng(bencode_item_t *, bencode_item_t *);
const char *call_pause_recording_ng(bencode_item_t *, bencode_item_t *);
const char *call_start_forwarding_ng(bencode_item_t *, bencode_item_t *);
const char *call_stop_forwarding_ng(bencode_item_t *, bencode_item_t *);
const char *call_block_dtmf_ng(bencode_item_t *, bencode_item_t *);
const char *call_unblock_dtmf_ng(bencode_item_t *, bencode_item_t *);
const char *call_block_media_ng(bencode_item_t *, bencode_item_t *);
const char *call_unblock_media_ng(bencode_item_t *, bencode_item_t *);
const char *call_silence_media_ng(bencode_item_t *, bencode_item_t *);
const char *call_unsilence_media_ng(bencode_item_t *, bencode_item_t *);
const char *call_play_media_ng(bencode_item_t *, bencode_item_t *);
const char *call_stop_media_ng(bencode_item_t *, bencode_item_t *);
const char *call_play_dtmf_ng(bencode_item_t *, bencode_item_t *);
const char *call_answer_ng(ng_parser_ctx_t *);
const char *call_delete_ng(ng_parser_ctx_t *);
const char *call_query_ng(ng_parser_ctx_t *);
const char *call_list_ng(ng_parser_ctx_t *);
const char *call_start_recording_ng(ng_parser_ctx_t *);
const char *call_stop_recording_ng(ng_parser_ctx_t *);
const char *call_pause_recording_ng(ng_parser_ctx_t *);
const char *call_start_forwarding_ng(ng_parser_ctx_t *);
const char *call_stop_forwarding_ng(ng_parser_ctx_t *);
const char *call_block_dtmf_ng(ng_parser_ctx_t *);
const char *call_unblock_dtmf_ng(ng_parser_ctx_t *);
const char *call_block_media_ng(ng_parser_ctx_t *);
const char *call_unblock_media_ng(ng_parser_ctx_t *);
const char *call_silence_media_ng(ng_parser_ctx_t *);
const char *call_unsilence_media_ng(ng_parser_ctx_t *);
const char *call_play_media_ng(ng_parser_ctx_t *);
const char *call_stop_media_ng(ng_parser_ctx_t *);
const char *call_play_dtmf_ng(ng_parser_ctx_t *);
void ng_call_stats(call_t *call, const str *fromtag, const str *totag, bencode_item_t *output,
struct call_stats *totals);
const char *call_publish_ng(ng_buffer *, bencode_item_t *, bencode_item_t *, const char *,
const char *call_publish_ng(ng_parser_ctx_t *, const char *,
const endpoint_t *);
const char *call_subscribe_request_ng(bencode_item_t *, bencode_item_t *);
const char *call_subscribe_answer_ng(ng_buffer *, bencode_item_t *, bencode_item_t *);
const char *call_unsubscribe_ng(bencode_item_t *, bencode_item_t *);
const char *call_subscribe_request_ng(ng_parser_ctx_t *);
const char *call_subscribe_answer_ng(ng_parser_ctx_t *);
const char *call_unsubscribe_ng(ng_parser_ctx_t *);
void add_media_to_sub_list(subscription_q *q, struct call_media *media, struct call_monologue *ml);
@ -294,10 +294,8 @@ void call_interfaces_free(void);
void call_interfaces_timer(void);
void call_ng_flags_flags(sdp_ng_flags *out, str *s, helper_arg dummy);
void call_ng_main_flags(sdp_ng_flags *out, str *key, bencode_item_t *value,
enum call_opmode opmode);
void call_ng_codec_flags(sdp_ng_flags *out, str *key, bencode_item_t *value,
enum call_opmode opmode);
void call_ng_main_flags(ng_parser_ctx_t *, str *key, bencode_item_t *value);
void call_ng_codec_flags(ng_parser_ctx_t *, str *key, bencode_item_t *value);
void call_ng_direction_flag(sdp_ng_flags *out, bencode_item_t *value);
INLINE struct sdp_manipulations *sdp_manipulations_get_by_id(const sdp_ng_flags *f, enum media_type id) {


+ 51
- 0
include/control_ng.h View File

@ -63,6 +63,57 @@ struct ng_buffer {
struct obj *ref;
};
enum call_opmode {
OP_OFFER = 0,
OP_ANSWER = 1,
OP_REQUEST,
OP_REQ_ANSWER,
OP_PUBLISH,
OP_DELETE,
OP_QUERY,
OP_LIST,
OP_PING,
OP_STATISTICS,
OP_PLAY_DTMF,
OP_BLOCK_DTMF,
OP_UNBLOCK_DTMF,
OP_BLOCK_MEDIA,
OP_UNBLOCK_MEDIA,
OP_SILENCE_MEDIA,
OP_UNSILENCE_MEDIA,
OP_BLOCK_SILENCE_MEDIA,
OP_UNBLOCK_SILENCE_MEDIA,
OP_PLAY_MEDIA,
OP_STOP_MEDIA,
OP_START_FORWARDING,
OP_STOP_FORWARDING,
OP_SUBSCRIBER_REQ,
OP_SUBSCRIBER_ANS,
OP_UNSUBSCRIBE,
OP_START_RECORDING,
OP_STOP_RECORDING,
OP_PAUSE_RECORDING,
OP_OTHER,
};
struct ng_parser {
str *(*collapse)(bencode_item_t *root, str *out);
};
struct ng_parser_ctx {
const ng_parser_t *parser;
struct ng_buffer *ngbuf;
bencode_item_t *req;
bencode_item_t *resp;
sdp_ng_flags *flags;
enum call_opmode opmode;
};
extern const ng_parser_t ng_parser_native;
extern const ng_parser_t ng_parser_json;
extern const char *ng_command_strings[NGC_COUNT];
extern const char *ng_command_strings_esc[NGC_COUNT];
extern const char *ng_command_strings_short[NGC_COUNT];


+ 2
- 3
include/control_ng_flags_parser.h View File

@ -14,7 +14,6 @@
* Syntax:
* rtpp_flags: flag1=<value>, flag2-<value> ...
*/
void parse_rtpp_flags(const str * rtpp_flags, bencode_buffer_t * buf,
enum call_opmode opmode, sdp_ng_flags * out);
void parse_rtpp_flags(const str * rtpp_flags, ng_parser_ctx_t *);
#endif
#endif

+ 1
- 1
include/statistics.h View File

@ -173,7 +173,7 @@ void statistics_update_foreignown_inc(call_t * c);
stats_metric_q *statistics_gather_metrics(struct interface_sampled_rate_stats *);
void statistics_free_metrics(stats_metric_q *);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(stats_metric_q, statistics_free_metrics)
const char *statistics_ng(bencode_item_t *input, bencode_item_t *output);
const char *statistics_ng(ng_parser_ctx_t *);
enum thread_looper_action call_rate_stats_updater(void);
/**


+ 3
- 0
include/types.h View File

@ -36,6 +36,9 @@ union sdp_attr_print_arg {
} __attribute__ ((__transparent_union__));
typedef void sdp_attr_print_f(GString *, union sdp_attr_print_arg, const sdp_ng_flags *flags);
typedef struct ng_parser ng_parser_t;
typedef struct ng_parser_ctx ng_parser_ctx_t;
#include "containers.h"
struct sdp_session;


Loading…
Cancel
Save