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.
91 lines
2.1 KiB
91 lines
2.1 KiB
#include "dtmf.h"
|
|
#include "media_socket.h"
|
|
#include "log.h"
|
|
#include "call.h"
|
|
|
|
|
|
struct telephone_event_payload {
|
|
uint8_t event;
|
|
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
|
unsigned volume:6;
|
|
unsigned r:1;
|
|
unsigned end:1;
|
|
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
|
unsigned end:1;
|
|
unsigned r:1;
|
|
unsigned volume:6;
|
|
#else
|
|
#error "byte order unknown"
|
|
#endif
|
|
uint16_t duration;
|
|
} __attribute__ ((packed));
|
|
|
|
|
|
|
|
|
|
static GString *dtmf_json_print(struct media_packet *mp,
|
|
struct telephone_event_payload *dtmf, int clockrate)
|
|
{
|
|
if (!dtmf->end)
|
|
return NULL;
|
|
|
|
GString *buf = g_string_new("");
|
|
|
|
if (!clockrate)
|
|
clockrate = 8000;
|
|
|
|
g_string_append_printf(buf, "{"
|
|
"\"callid\":\"" STR_FORMAT "\","
|
|
"\"source_tag\":\"" STR_FORMAT "\","
|
|
"\"tags\":[",
|
|
STR_FMT(&mp->call->callid),
|
|
STR_FMT(&mp->media->monologue->tag));
|
|
|
|
GList *tag_values = g_hash_table_get_values(mp->call->tags);
|
|
int i = 0;
|
|
for (GList *tag_it = tag_values; tag_it; tag_it = tag_it->next) {
|
|
struct call_monologue *ml = tag_it->data;
|
|
if (i != 0)
|
|
g_string_append(buf, ",");
|
|
g_string_append_printf(buf, "\"" STR_FORMAT "\"",
|
|
STR_FMT(&ml->tag));
|
|
i++;
|
|
}
|
|
g_list_free(tag_values);
|
|
|
|
g_string_append_printf(buf, "],"
|
|
"\"type\":\"DTMF\",\"timestamp\":%lu,\"source_ip\":\"%s\","
|
|
"\"event\":%u,\"duration\":%u,\"volume\":%u}",
|
|
(unsigned long) rtpe_now.tv_sec,
|
|
sockaddr_print_buf(&mp->fsin.address),
|
|
(unsigned int) dtmf->event,
|
|
(ntohs(dtmf->duration) * (1000000 / clockrate)) / 1000,
|
|
(unsigned int) dtmf->volume);
|
|
|
|
return buf;
|
|
}
|
|
|
|
int dtmf_event(struct media_packet *mp, str *payload, int clockrate) {
|
|
struct telephone_event_payload *dtmf;
|
|
if (payload->len < sizeof(*dtmf)) {
|
|
ilog(LOG_WARN | LOG_FLAG_LIMIT, "Short DTMF event packet (len %u)", payload->len);
|
|
return -1;
|
|
}
|
|
dtmf = (void *) payload->s;
|
|
|
|
ilog(LOG_DEBUG, "DTMF event: event %u, volume %u, end %u, duration %u",
|
|
dtmf->event, dtmf->volume, dtmf->end, dtmf->duration);
|
|
|
|
int ret = 0;
|
|
|
|
if (_log_facility_dtmf) {
|
|
GString *buf = dtmf_json_print(mp, dtmf, clockrate);
|
|
if (buf) {
|
|
dtmflog(buf);
|
|
ret = 1; // END event
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|