Merge branch 'zecke/mgcp-dtmf'
This commit is contained in:
commit
6d818839a9
|
@ -1,8 +1,8 @@
|
|||
/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
|
||||
|
||||
/*
|
||||
* (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009-2011 by On-Waves
|
||||
* (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009-2012 by On-Waves
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -83,6 +83,7 @@ typedef int (*mgcp_realloc)(struct mgcp_trunk_config *cfg, int endpoint);
|
|||
typedef int (*mgcp_change)(struct mgcp_trunk_config *cfg, int endpoint, int state);
|
||||
typedef int (*mgcp_policy)(struct mgcp_trunk_config *cfg, int endpoint, int state, const char *transactio_id);
|
||||
typedef int (*mgcp_reset)(struct mgcp_trunk_config *cfg);
|
||||
typedef int (*mgcp_rqnt)(struct mgcp_endpoint *endp, char tone, const char *data);
|
||||
|
||||
#define PORT_ALLOC_STATIC 0
|
||||
#define PORT_ALLOC_DYNAMIC 1
|
||||
|
@ -148,6 +149,7 @@ struct mgcp_config {
|
|||
mgcp_policy policy_cb;
|
||||
mgcp_reset reset_cb;
|
||||
mgcp_realloc realloc_cb;
|
||||
mgcp_rqnt rqnt_cb;
|
||||
void *data;
|
||||
|
||||
uint32_t last_call_id;
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
/* The protocol implementation */
|
||||
|
||||
/*
|
||||
* (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009-2011 by On-Waves
|
||||
* (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009-2012 by On-Waves
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -822,6 +822,15 @@ static struct msgb *handle_rsip(struct mgcp_config *cfg, struct msgb *msg)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static char extract_tone(const char *line)
|
||||
{
|
||||
const char *str = strstr(line, "D/");
|
||||
if (!str)
|
||||
return CHAR_MAX;
|
||||
|
||||
return str[2];
|
||||
}
|
||||
|
||||
/*
|
||||
* This can request like DTMF detection and forward, fax detection... it
|
||||
* can also request when the notification should be send and such. We don't
|
||||
|
@ -831,18 +840,45 @@ static struct msgb *handle_noti_req(struct mgcp_config *cfg, struct msgb *msg)
|
|||
{
|
||||
const char *trans_id;
|
||||
struct mgcp_endpoint *endp;
|
||||
int found;
|
||||
char *data = strtok((char *) msg->l3h, "\r\n");
|
||||
int found, res = 0;
|
||||
char *line, *save;
|
||||
char tone = 0;
|
||||
|
||||
found = mgcp_analyze_header(cfg, data, &trans_id, &endp);
|
||||
if (found != 0)
|
||||
return create_err_response(400, "RQNT", trans_id);
|
||||
for_each_line((char *) msg->l3h, line, save) {
|
||||
/* skip first line */
|
||||
if ((char *) msg->l3h == line) {
|
||||
found = mgcp_analyze_header(cfg, line, &trans_id,
|
||||
&endp);
|
||||
if (found != 0)
|
||||
return create_err_response(400, "RQNT",
|
||||
trans_id);
|
||||
|
||||
if (!endp->allocated) {
|
||||
LOGP(DMGCP, LOGL_ERROR, "Endpoint is not used. 0x%x\n", ENDPOINT_NUMBER(endp));
|
||||
return create_err_response(400, "RQNT", trans_id);
|
||||
if (!endp->allocated) {
|
||||
LOGP(DMGCP, LOGL_ERROR,
|
||||
"Endpoint is not used. 0x%x\n",
|
||||
ENDPOINT_NUMBER(endp));
|
||||
return create_err_response(400, "RQNT",
|
||||
trans_id);
|
||||
}
|
||||
}
|
||||
|
||||
switch (line[0]) {
|
||||
case 'S':
|
||||
tone = extract_tone(line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return create_ok_response(200, "RQNT", trans_id);
|
||||
|
||||
/* we didn't see a signal request with a tone */
|
||||
if (tone == CHAR_MAX)
|
||||
return create_ok_response(200, "RQNT", trans_id);
|
||||
|
||||
if (cfg->rqnt_cb)
|
||||
res = cfg->rqnt_cb(endp, tone, (const char *) msg->l3h);
|
||||
|
||||
return res == 0 ?
|
||||
create_ok_response(200, "RQNT", trans_id) :
|
||||
create_err_response(res, "RQNT", trans_id);
|
||||
}
|
||||
|
||||
struct mgcp_config *mgcp_config_alloc(void)
|
||||
|
|
|
@ -74,6 +74,15 @@
|
|||
#define DLCX_RET "250 7 OK\r\n" \
|
||||
"P: PS=0, OS=0, PR=0, OR=0, PL=0, JI=0\r\n"
|
||||
|
||||
#define RQNT "RQNT 186908780 1@mgw MGCP 1.0\r\n" \
|
||||
"X: B244F267488\r\n" \
|
||||
"S: D/9\r\n"
|
||||
|
||||
#define RQNT2 "RQNT 186908780 1@mgw MGCP 1.0\r\n" \
|
||||
"X: ADD4F26746F\r\n" \
|
||||
"R: D/[0-9#*](N), G/ft, fxr/t38\r\n"
|
||||
|
||||
#define RQNT_RET "200 186908780 OK\r\n"
|
||||
|
||||
struct mgcp_test {
|
||||
const char *name;
|
||||
|
@ -91,6 +100,8 @@ const struct mgcp_test tests[] = {
|
|||
{ "SHORT2", SHORT2, SHORT2_RET },
|
||||
{ "SHORT3", SHORT3, SHORT2_RET },
|
||||
{ "SHORT4", SHORT4, SHORT2_RET },
|
||||
{ "RQNT1", RQNT, RQNT_RET },
|
||||
{ "RQNT2", RQNT2, RQNT_RET },
|
||||
{ "DLCX", DLCX, DLCX_RET },
|
||||
};
|
||||
|
||||
|
@ -137,6 +148,52 @@ static void test_messages(void)
|
|||
talloc_free(cfg);
|
||||
}
|
||||
|
||||
static int rqnt_cb(struct mgcp_endpoint *endp, char _tone, const char *data)
|
||||
{
|
||||
ptrdiff_t tone = _tone;
|
||||
endp->cfg->data = (void *) tone;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_rqnt_cb(void)
|
||||
{
|
||||
struct mgcp_config *cfg;
|
||||
struct msgb *inp, *msg;
|
||||
|
||||
cfg = mgcp_config_alloc();
|
||||
cfg->rqnt_cb = rqnt_cb;
|
||||
|
||||
cfg->trunk.number_endpoints = 64;
|
||||
mgcp_endpoints_allocate(&cfg->trunk);
|
||||
|
||||
mgcp_endpoints_allocate(mgcp_trunk_alloc(cfg, 1));
|
||||
|
||||
inp = create_msg(CRCX);
|
||||
msgb_free(mgcp_handle_message(cfg, inp));
|
||||
msgb_free(inp);
|
||||
|
||||
/* send the RQNT and check for the CB */
|
||||
inp = create_msg(RQNT);
|
||||
msg = mgcp_handle_message(cfg, inp);
|
||||
if (strncmp((const char *) msg->l2h, "200", 3) != 0) {
|
||||
printf("FAILED: message is not 200. '%s'\n", msg->l2h);
|
||||
abort();
|
||||
}
|
||||
|
||||
if (cfg->data != (void *) '9') {
|
||||
printf("FAILED: callback not called: %p\n", cfg->data);
|
||||
abort();
|
||||
}
|
||||
|
||||
msgb_free(msg);
|
||||
msgb_free(inp);
|
||||
|
||||
inp = create_msg(DLCX);
|
||||
msgb_free(mgcp_handle_message(cfg, inp));
|
||||
msgb_free(inp);
|
||||
talloc_free(cfg);
|
||||
}
|
||||
|
||||
struct pl_test {
|
||||
int cycles;
|
||||
uint16_t base_seq;
|
||||
|
@ -195,6 +252,7 @@ int main(int argc, char **argv)
|
|||
|
||||
test_messages();
|
||||
test_packet_loss_calc();
|
||||
test_rqnt_cb();
|
||||
|
||||
printf("Done\n");
|
||||
return EXIT_SUCCESS;
|
||||
|
|
|
@ -7,6 +7,8 @@ Testing SHORT1
|
|||
Testing SHORT2
|
||||
Testing SHORT3
|
||||
Testing SHORT4
|
||||
Testing RQNT1
|
||||
Testing RQNT2
|
||||
Testing DLCX
|
||||
Testing packet loss calculation.
|
||||
Done
|
||||
|
|
Loading…
Reference in New Issue