From 7e0936ee52a9fb35e8921b49f0df0ca04aa60d00 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 6 Jan 2011 19:48:55 +0100 Subject: mgcp: Merge new mgcp_protocol to parse digital trunks. --- src/mgcp/mgcp_protocol.c | 108 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 75 insertions(+), 33 deletions(-) (limited to 'src/mgcp/mgcp_protocol.c') 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; -- cgit v1.2.3