aboutsummaryrefslogtreecommitdiffstats
path: root/src/mgcp
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2011-01-06 19:48:55 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2011-01-06 19:50:32 +0100
commit7e0936ee52a9fb35e8921b49f0df0ca04aa60d00 (patch)
treefa4059796b4d42ae02f436966ef7797ed03941b7 /src/mgcp
parent7a7255657797ae9fa72a93cab4e1f1d71d094ca3 (diff)
mgcp: Merge new mgcp_protocol to parse digital trunks.
Diffstat (limited to 'src/mgcp')
-rw-r--r--src/mgcp/mgcp_protocol.c108
1 files changed, 75 insertions, 33 deletions
diff --git a/src/mgcp/mgcp_protocol.c b/src/mgcp/mgcp_protocol.c
index 48b302f..9d9bf15 100644
--- a/src/mgcp/mgcp_protocol.c
+++ b/src/mgcp/mgcp_protocol.c
@@ -136,8 +136,9 @@ static struct msgb *mgcp_msgb_alloc(void)
return msg;
}
-struct msgb *mgcp_create_response_with_data(int code, const char *msg, const char *trans,
- const char *data)
+struct msgb *mgcp_create_response_with_data(int code, const char *txt,
+ const char *msg, const char *trans,
+ const char *data)
{
int len;
struct msgb *res;
@@ -147,9 +148,9 @@ struct msgb *mgcp_create_response_with_data(int code, const char *msg, const cha
return NULL;
if (data) {
- len = snprintf((char *) res->data, 2048, "%d %s\n%s", code, trans, data);
+ len = snprintf((char *) res->data, 2048, "%d %s%s\r\n%s", code, trans, txt, data);
} else {
- len = snprintf((char *) res->data, 2048, "%d %s\n", code, trans);
+ len = snprintf((char *) res->data, 2048, "%d %s%s\r\n", code, trans, txt);
}
res->l2h = msgb_put(res, len);
@@ -157,9 +158,14 @@ struct msgb *mgcp_create_response_with_data(int code, const char *msg, const cha
return res;
}
-static struct msgb *create_response(int code, const char *msg, const char *trans)
+static struct msgb *create_ok_response(int code, const char *msg, const char *trans)
{
- return mgcp_create_response_with_data(code, msg, trans, NULL);
+ return mgcp_create_response_with_data(code, " OK", msg, trans, NULL);
+}
+
+static struct msgb *create_err_response(int code, const char *msg, const char *trans)
+{
+ return mgcp_create_response_with_data(code, " FAIL", msg, trans, NULL);
}
static struct msgb *create_response_with_sdp(struct mgcp_endpoint *endp,
@@ -180,7 +186,7 @@ static struct msgb *create_response_with_sdp(struct mgcp_endpoint *endp,
endp->ci, addr, endp->rtp_port,
endp->bts_payload_type, endp->bts_payload_type,
endp->cfg->audio_name);
- return mgcp_create_response_with_data(200, msg, trans_id, sdp_record);
+ return mgcp_create_response_with_data(200, " OK", msg, trans_id, sdp_record);
}
/*
@@ -254,18 +260,56 @@ static int find_msg_pointers(struct msgb *msg, struct mgcp_msg_ptr *ptrs, int pt
return found;
}
+/**
+ * We have a null terminated string with the endpoint name here. We only
+ * support two kinds. Simple ones as seen on the BSC level and the ones
+ * seen on the trunk side.
+ */
+static struct mgcp_endpoint *find_e1_endpoint(struct mgcp_config *cfg,
+ const char *mgcp)
+{
+ char *rest = NULL;
+ int trunk, endp, mgcp_endp;
+
+ trunk = strtoul(mgcp + 6, &rest, 10);
+ if (rest == NULL || rest[0] != '/') {
+ LOGP(DMGCP, LOGL_ERROR, "Wrong trunk name '%s'\n", mgcp);
+ return NULL;
+ }
+
+ endp = strtoul(rest + 1, &rest, 10);
+ if (rest == NULL || rest[0] != '@') {
+ LOGP(DMGCP, LOGL_ERROR, "Wrong trunk name '%s'\n", mgcp);
+ return NULL;
+ }
+
+ /* signalling is on timeslot 1 */
+ if (endp == 1)
+ return NULL;
+
+ mgcp_endp = mgcp_timeslot_to_endpoint(trunk, endp);
+ if (mgcp_endp < 1 || mgcp_endp >= cfg->number_endpoints) {
+ LOGP(DMGCP, LOGL_ERROR, "Failed to find endpoint '%s'\n", mgcp);
+ }
+
+ return &cfg->endpoints[mgcp_endp];
+}
+
static struct mgcp_endpoint *find_endpoint(struct mgcp_config *cfg, const char *mgcp)
{
char *endptr = NULL;
unsigned int gw = INT_MAX;
- gw = strtoul(mgcp, &endptr, 16);
- if (gw == 0 || gw >= cfg->number_endpoints || strcmp(endptr, "@mgw") != 0) {
- LOGP(DMGCP, LOGL_ERROR, "Not able to find endpoint: '%s'\n", mgcp);
- return NULL;
+ if (strncmp(mgcp, "ds/e1", 5) == 0) {
+ return find_e1_endpoint(cfg, mgcp);
+ } else {
+ gw = strtoul(mgcp, &endptr, 16);
+ if (gw > 0 && gw < cfg->number_endpoints && strcmp(endptr, "@mgw") == 0)
+ return &cfg->endpoints[gw];
}
- return &cfg->endpoints[gw];
+ LOGP(DMGCP, LOGL_ERROR, "Not able to find endpoint: '%s'\n", mgcp);
+ return NULL;
}
int mgcp_analyze_header(struct mgcp_config *cfg, struct msgb *msg,
@@ -342,17 +386,15 @@ static int verify_ci(const struct mgcp_endpoint *endp,
static struct msgb *handle_audit_endpoint(struct mgcp_config *cfg, struct msgb *msg)
{
struct mgcp_msg_ptr data_ptrs[6];
- int found, response;
+ int found;
const char *trans_id;
struct mgcp_endpoint *endp;
found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
if (found != 0)
- response = 500;
+ return create_err_response(500, "AUEP", trans_id);
else
- response = 200;
-
- return create_response(response, "AUEP", trans_id);
+ return create_ok_response(200, "AUEP", trans_id);
}
static int parse_conn_mode(const char* msg, int *conn_mode)
@@ -385,7 +427,7 @@ static struct msgb *handle_create_con(struct mgcp_config *cfg, struct msgb *msg)
found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
if (found != 0)
- return create_response(500, "CRCX", trans_id);
+ return create_err_response(510, "CRCX", trans_id);
if (endp->ci != CI_UNUSED) {
if (cfg->force_realloc) {
@@ -397,7 +439,7 @@ static struct msgb *handle_create_con(struct mgcp_config *cfg, struct msgb *msg)
} else {
LOGP(DMGCP, LOGL_ERROR, "Endpoint is already used. 0x%x\n",
ENDPOINT_NUMBER(endp));
- return create_response(500, "CRCX", trans_id);
+ return create_err_response(400, "CRCX", trans_id);
}
}
@@ -456,7 +498,7 @@ static struct msgb *handle_create_con(struct mgcp_config *cfg, struct msgb *msg)
LOGP(DMGCP, LOGL_NOTICE, "CRCX rejected by policy on 0x%x\n",
ENDPOINT_NUMBER(endp));
mgcp_free_endp(endp);
- return create_response(500, "CRCX", trans_id);
+ return create_err_response(400, "CRCX", trans_id);
break;
case MGCP_POLICY_DEFER:
/* stop processing */
@@ -478,11 +520,11 @@ error:
LOGP(DMGCP, LOGL_ERROR, "Malformed line: %s on 0x%x with: line_start: %d %d\n",
hexdump(msg->l3h, msgb_l3len(msg)),
ENDPOINT_NUMBER(endp), line_start, i);
- return create_response(error_code, "CRCX", trans_id);
+ return create_err_response(error_code, "CRCX", trans_id);
error2:
LOGP(DMGCP, LOGL_NOTICE, "Resource error on 0x%x\n", ENDPOINT_NUMBER(endp));
- return create_response(error_code, "CRCX", trans_id);
+ return create_err_response(error_code, "CRCX", trans_id);
}
static struct msgb *handle_modify_con(struct mgcp_config *cfg, struct msgb *msg)
@@ -496,11 +538,11 @@ static struct msgb *handle_modify_con(struct mgcp_config *cfg, struct msgb *msg)
found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
if (found != 0)
- return create_response(error_code, "MDCX", trans_id);
+ return create_err_response(510, "MDCX", trans_id);
if (endp->ci == CI_UNUSED) {
LOGP(DMGCP, LOGL_ERROR, "Endpoint is not holding a connection. 0x%x\n", ENDPOINT_NUMBER(endp));
- return create_response(error_code, "MDCX", trans_id);
+ return create_err_response(400, "MDCX", trans_id);
}
MSG_TOKENIZE_START
@@ -576,7 +618,7 @@ static struct msgb *handle_modify_con(struct mgcp_config *cfg, struct msgb *msg)
ENDPOINT_NUMBER(endp));
if (silent)
goto out_silent;
- return create_response(500, "MDCX", trans_id);
+ return create_err_response(400, "MDCX", trans_id);
break;
case MGCP_POLICY_DEFER:
/* stop processing */
@@ -602,10 +644,10 @@ error:
LOGP(DMGCP, LOGL_ERROR, "Malformed line: %s on 0x%x with: line_start: %d %d %d\n",
hexdump(msg->l3h, msgb_l3len(msg)),
ENDPOINT_NUMBER(endp), line_start, i, msg->l3h[line_start]);
- return create_response(error_code, "MDCX", trans_id);
+ return create_err_response(error_code, "MDCX", trans_id);
error3:
- return create_response(error_code, "MDCX", trans_id);
+ return create_err_response(error_code, "MDCX", trans_id);
out_silent:
@@ -623,11 +665,11 @@ static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg)
found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
if (found != 0)
- return create_response(error_code, "DLCX", trans_id);
+ return create_err_response(error_code, "DLCX", trans_id);
if (endp->ci == CI_UNUSED) {
LOGP(DMGCP, LOGL_ERROR, "Endpoint is not used. 0x%x\n", ENDPOINT_NUMBER(endp));
- return create_response(error_code, "DLCX", trans_id);
+ return create_err_response(400, "DLCX", trans_id);
}
MSG_TOKENIZE_START
@@ -661,7 +703,7 @@ static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg)
ENDPOINT_NUMBER(endp));
if (silent)
goto out_silent;
- return create_response(500, "DLCX", trans_id);
+ return create_err_response(400, "DLCX", trans_id);
break;
case MGCP_POLICY_DEFER:
/* stop processing */
@@ -682,16 +724,16 @@ static struct msgb *handle_delete_con(struct mgcp_config *cfg, struct msgb *msg)
if (silent)
goto out_silent;
- return create_response(250, "DLCX", trans_id);
+ return create_ok_response(250, "DLCX", trans_id);
error:
LOGP(DMGCP, LOGL_ERROR, "Malformed line: %s on 0x%x with: line_start: %d %d\n",
hexdump(msg->l3h, msgb_l3len(msg)),
ENDPOINT_NUMBER(endp), line_start, i);
- return create_response(error_code, "DLCX", trans_id);
+ return create_err_response(error_code, "DLCX", trans_id);
error3:
- return create_response(error_code, "DLCX", trans_id);
+ return create_err_response(error_code, "DLCX", trans_id);
out_silent:
return NULL;