blob: f4a857967321fde29b2deb01594f3a0e84866874 [file] [log] [blame]
Holger Hans Peter Freytherb1dfc462011-09-15 19:30:20 +02001/* MGCP message patching */
2/*
3 * (C) 2011 by Holger Hans Peter Freyther <zecke@selfish.org>
4 * (C) 2011 by On-Waves
5 * All Rights Reserved
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <mgcp_patch.h>
22#include <cellmgr_debug.h>
23#include <ss7_application.h>
24#include <string.h>
25
26#include <osmocom/gsm/tlv.h>
27
28
29struct msgb *mgcp_patch(struct ss7_application *app, struct msgb *msg)
30{
31 char *token, *remaining;
32 struct msgb *out;
33 int len, out_len, state, i;
34
35 if (!app->mgcp_domain_name)
36 return msg;
37
38 if (msgb_tailroom(msg) <= strlen(app->mgcp_domain_name)) {
39 LOGP(DMGCP, LOGL_ERROR, "Not enough space to add a zero line.\n");
40 return msg;
41 }
42
43 msg->l2h[msgb_l2len(msg)] = '\0';
44
45 /**
46 * We now need to rewrite the message, but actually only the first
47 * line and the rest can be copied.
48 */
49 out = msgb_alloc_headroom(4096, 128, "MGCP Patch Copy");
50 if (!out) {
51 LOGP(DMGCP, LOGL_ERROR, "Failed to create the MSGB copy.\n");
52 return NULL;
53 }
54
55
56 remaining = (char *) msg->l2h;
57 token = strsep(&remaining, "\n");
58 if (!token) {
59 LOGP(DMGCP, LOGL_ERROR, "Failed to split the MGCP.\n");
60 msgb_free(out);
61 return msg;
62 }
63
64 len = strlen(token);
65 out->l2h = msgb_put(out, 0);
66
67 /*
68 * State machine for copying and modifying the MGCP line, first find
69 * half of the endpoint, put ours, copy the rest of the line
70 */
71 state = 0;
72 for (i = 0; i < len; ++i) {
73 switch (state) {
74 case 2:
75 if (token[i] == '@')
76 state += 1;
77 msgb_v_put(out, token[i]);
78 break;
79 case 3:
80 /* copy the new name */
81 out->l3h = msgb_put(out, strlen(app->mgcp_domain_name));
82 memcpy(out->l3h, app->mgcp_domain_name, msgb_l3len(out));
83
84 /* skip everything to the next whitespace */
85 for (; i < len; ++i) {
86 if (token[i] == ' ') {
87 break;
88 }
89 }
90
91 for (; i < len; ++i)
92 msgb_v_put(out, token[i]);
93 msgb_v_put(out, '\n');
94 break;
95 default:
96 if (token[i] == ' ')
97 state += 1;
98 msgb_v_put(out, token[i]);
99 break;
100 }
101 }
102
103 /* append the rest */
104 out_len = msgb_l2len(msg) - len - 1;
105 out->l3h = msgb_put(out, out_len);
106 memcpy(out->l3h, &msg->l2h[len + 1], out_len);
107
108 msgb_free(msg);
109 return out;
110}
111