osmo-mgw: refactor endpoint and trunk handling
The trunk and endpoint handling in osmo-mgw is still very complex and
implemented in various places (mostly mgcp_protocol.c). Also we use
still integers for endpoint identification, which is not flexible enough
to address timeslots/subslots on an E1 trunk. Some refactoring is needed.
- get rid of integers as endpoint identifiers, use strings instead and
find the endpoint based on its string name on the trunk.
- identify the trunk based on the trunk prefix given in the endpoint
name.
- refactor trunk and endpoint allocation. Aggregate functionality in
in mgcp_endp.c and mgcp_trunk.c. Also remove non-reusable code that
relates to the still exisiting, but unfinished E1 trunk support.
- refactor rate counters, put them into a separate module and do no
longer allocate them per trunk. Allocate them globally instead.
Change-Id: Ia8cf4d6caf05a4e13f1f507dc68cbabb7e6239aa
Related: OS#2659
diff --git a/src/libosmo-mgcp/mgcp_msg.c b/src/libosmo-mgcp/mgcp_msg.c
index 7124a39..019466e 100644
--- a/src/libosmo-mgcp/mgcp_msg.c
+++ b/src/libosmo-mgcp/mgcp_msg.c
@@ -129,167 +129,6 @@
return ret;
}
-/* 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. (helper function for find_endpoint()) */
-static struct mgcp_endpoint *find_e1_endpoint(struct mgcp_config *cfg,
- const char *mgcp)
-{
- char *rest = NULL;
- struct mgcp_trunk *trunk;
- int trunk_index, endp;
- struct mgcp_endpoint *endp_ptr;
-
- trunk_index = strtoul(mgcp + 6, &rest, 10);
- if (rest == NULL || rest[0] != '/' || trunk_index < 1) {
- LOGP(DLMGCP, LOGL_ERROR, "Wrong trunk name '%s'\n", mgcp);
- return NULL;
- }
-
- endp = strtoul(rest + 1, &rest, 10);
- if (rest == NULL || rest[0] != '@') {
- LOGP(DLMGCP, LOGL_ERROR, "Wrong endpoint name '%s'\n", mgcp);
- return NULL;
- }
-
- /* signalling is on timeslot 1 */
- if (endp == 1)
- return NULL;
-
- trunk = mgcp_trunk_num(cfg, trunk_index);
- if (!trunk) {
- LOGP(DLMGCP, LOGL_ERROR, "The trunk %d is not declared.\n",
- trunk_index);
- return NULL;
- }
-
- if (!trunk->endpoints) {
- LOGP(DLMGCP, LOGL_ERROR,
- "Endpoints of trunk %d not allocated.\n", trunk_index);
- return NULL;
- }
-
- if (endp < 1 || endp >= trunk->number_endpoints) {
- LOGP(DLMGCP, LOGL_ERROR, "Failed to find endpoint '%s'\n",
- mgcp);
- return NULL;
- }
-
- endp_ptr = &trunk->endpoints[endp];
- endp_ptr->wildcarded_req = false;
- return endp_ptr;
-}
-
-/* Find an endpoint that is not in use. Do this by going through the endpoint
- * array, check the callid. A callid nullpointer indicates that the endpoint
- * is free */
-static struct mgcp_endpoint *find_free_endpoint(struct mgcp_endpoint *endpoints,
- unsigned int number_endpoints)
-{
- struct mgcp_endpoint *endp;
- unsigned int i;
-
- for (i = 0; i < number_endpoints; i++) {
- if (endpoints[i].callid == NULL) {
- endp = &endpoints[i];
- LOGPENDP(endp, DLMGCP, LOGL_DEBUG,
- "found free endpoint\n");
- endp->wildcarded_req = true;
- return endp;
- }
- }
-
- LOGP(DLMGCP, LOGL_ERROR, "Not able to find a free endpoint\n");
- return NULL;
-}
-
-/* Check if the domain name, which is supplied with the endpoint name
- * matches the configuration. */
-static int check_domain_name(struct mgcp_config *cfg, const char *mgcp)
-{
- char *domain_to_check;
-
- domain_to_check = strstr(mgcp, "@");
- if (!domain_to_check)
- return -EINVAL;
-
- /* Accept any domain if configured as "*" */
- if (!strcmp(cfg->domain, "*"))
- return 0;
-
- if (strcmp(domain_to_check+1, cfg->domain) != 0) {
- LOGP(DLMGCP, LOGL_ERROR, "Wrong domain name '%s', expecting '%s'\n", mgcp, cfg->domain);
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* Search the endpoint pool for the endpoint that had been selected via the
- * MGCP message (helper function for mgcp_analyze_header()) */
-static struct mgcp_endpoint *find_endpoint(struct mgcp_config *cfg,
- const char *mgcp,
- int *cause)
-{
- char *endptr = NULL;
- unsigned int gw = INT_MAX;
- const char *endpoint_number_str;
- struct mgcp_endpoint *endp;
- struct mgcp_trunk *virt_trunk = cfg->virt_trunk;
-
- *cause = 0;
-
- /* Check if the domainname in the request is correct */
- if (check_domain_name(cfg, mgcp)) {
- *cause = -500;
- return NULL;
- }
-
- /* Check if the E1 trunk is requested */
- if (strncmp(mgcp, "ds/e1", 5) == 0) {
- endp = find_e1_endpoint(cfg, mgcp);
- if (!endp)
- *cause = -500;
- return endp;
- }
-
- /* Check if the virtual trunk is addressed (new, correct way with prefix) */
- if (strncmp
- (mgcp, MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK,
- strlen(MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK)) == 0) {
- endpoint_number_str =
- mgcp + strlen(MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK);
- if (endpoint_number_str[0] == '*') {
- endp = find_free_endpoint(virt_trunk->endpoints,
- virt_trunk->number_endpoints);
- if (!endp)
- *cause = -403;
- return endp;
- }
- gw = strtoul(endpoint_number_str, &endptr, 16);
- if (gw < virt_trunk->number_endpoints && endptr[0] == '@') {
- endp = &virt_trunk->endpoints[gw];
- endp->wildcarded_req = false;
- return endp;
- }
- }
-
- /* Deprecated method without prefix */
- LOGP(DLMGCP, LOGL_NOTICE,
- "Addressing virtual trunk without prefix (deprecated), please use %s: '%s'\n",
- MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK, mgcp);
- gw = strtoul(mgcp, &endptr, 16);
- if (gw < virt_trunk->number_endpoints && endptr[0] == '@') {
- endp = &virt_trunk->endpoints[gw];
- endp->wildcarded_req = false;
- return endp;
- }
-
- LOGP(DLMGCP, LOGL_ERROR, "Not able to find the endpoint: '%s'\n", mgcp);
- *cause = -500;
- return NULL;
-}
-
/*! Analyze and parse the the hader of an MGCP messeage string.
* \param[out] pdata caller provided memory to store the parsing results
* \param[in] data mgcp message string
@@ -317,7 +156,7 @@
pdata->trans = elem;
break;
case 1:
- pdata->endp = find_endpoint(pdata->cfg, elem, &cause);
+ pdata->endp = mgcp_endp_by_name(&cause, elem, pdata->cfg);
if (!pdata->endp) {
LOGP(DLMGCP, LOGL_ERROR,
"Unable to find Endpoint `%s'\n", elem);
@@ -391,8 +230,8 @@
const size_t line_len = strlen(line);
if (line[0] != '\0' && line_len < 2) {
LOGP(DLMGCP, LOGL_ERROR,
- "Wrong MGCP option format: '%s' on 0x%x\n",
- line, ENDPOINT_NUMBER(endp));
+ "Wrong MGCP option format: '%s' on %s\n",
+ line, endp->name);
return 0;
}