blob: f60c6418ef5f037d4b370be7e73ec2d079f83fe6 [file] [log] [blame]
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +08001/* Create GSM 08.08 messages */
2/*
3 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
4 * (C) 2010 by On-Waves
5 * All Rights Reserved
6 *
Holger Hans Peter Freytherde56c222011-01-16 17:45:14 +01007 * 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
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080010 * (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
Holger Hans Peter Freytherde56c222011-01-16 17:45:14 +010015 * GNU Affero General Public License for more details.
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080016 *
Holger Hans Peter Freytherde56c222011-01-16 17:45:14 +010017 * 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/>.
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080019 *
20 */
21
22#include <bssap_sccp.h>
Holger Hans Peter Freythercbf7d182010-07-31 05:25:35 +080023#include <cellmgr_debug.h>
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080024
Harald Welteff397ed2011-05-08 10:29:23 +020025#include <osmocom/core/msgb.h>
26#include <osmocom/gsm/protocol/gsm_08_08.h>
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080027
28#include <string.h>
29
30
31struct msgb *create_clear_command(struct sccp_source_reference *dest_ref)
32{
33 struct sccp_data_form1 *form1;
34 struct msgb *msg;
35
36 msg = msgb_alloc_headroom(4096, 128, "clear command");
37 if (!msg) {
38 LOGP(DINP, LOGL_ERROR, "Failed to allocate clear command.\n");
39 return NULL;
40 }
41
42 msg->l2h = msgb_put(msg, sizeof(*form1));
43 form1 = (struct sccp_data_form1 *) msg->l2h;
44 form1->type = SCCP_MSG_TYPE_DT1;
45 form1->destination_local_reference = *dest_ref;
46 form1->segmenting = 0;
47 form1->variable_start = 1;
48
49 /* create a Clear Command Call Control msg */
50 msg->l3h = msgb_put(msg, 7);
51 msg->l3h[0] = msgb_l3len(msg) - 1;
52 msg->l3h[1] = BSSAP_MSG_BSS_MANAGEMENT;
53 msg->l3h[2] = msg->l3h[0] - 2;
54 msg->l3h[3] = BSS_MAP_MSG_CLEAR_CMD;
55 msg->l3h[4] = 4;
56 msg->l3h[5] = 1;
57 msg->l3h[6] = 0x09;
58
59 return msg;
60}
61
62struct msgb *create_sccp_rlsd(struct sccp_source_reference *src_ref,
63 struct sccp_source_reference *dst_ref)
64{
65 struct sccp_connection_released *rel;
66 struct msgb *msg;
67
68 msg = msgb_alloc_headroom(4096, 128, "rlsd");
69 if (!msg) {
70 LOGP(DINP, LOGL_ERROR, "Failed to allocate clear command.\n");
71 return NULL;
72 }
73
74 msg->l2h = msgb_put(msg, sizeof(*rel));
75 rel = (struct sccp_connection_released *) msg->l2h;
76 rel->type = SCCP_MSG_TYPE_RLSD;
77 rel->release_cause = SCCP_RELEASE_CAUSE_END_USER_ORIGINATED;
78 rel->destination_local_reference = *dst_ref;
79 rel->source_local_reference = *src_ref;
80
81 return msg;
82}
83
84struct msgb *create_sccp_rlc(struct sccp_source_reference *src_ref,
85 struct sccp_source_reference *dst_ref)
86{
87 struct sccp_connection_release_complete *rlc;
88 struct msgb *msg;
89
90 msg = msgb_alloc_headroom(4096, 128, "rlc");
91 if (!msg) {
92 LOGP(DINP, LOGL_ERROR, "Failed to allocate rlc.\n");
93 return NULL;
94 }
95
96 msg->l2h = msgb_put(msg, sizeof(*rlc));
97 rlc = (struct sccp_connection_release_complete *) msg->l2h;
98 rlc->type = SCCP_MSG_TYPE_RLC;
99 rlc->destination_local_reference = *dst_ref;
100 rlc->source_local_reference = *src_ref;
101
102 return msg;
103}
104
105struct msgb *create_sccp_refuse(struct sccp_source_reference *dest_ref)
106{
107 struct sccp_connection_refused *ref;
108 struct msgb *msg;
109
110 msg = msgb_alloc_headroom(4096, 128, "rlsd");
111 if (!msg) {
112 LOGP(DINP, LOGL_ERROR, "Failed to allocate connection refuse.\n");
113 return NULL;
114 }
115
116 msg->l2h = msgb_put(msg, sizeof(*ref));
117 ref = (struct sccp_connection_refused *) msg->l2h;
118 ref->type = SCCP_MSG_TYPE_CREF;
119 ref->destination_local_reference = *dest_ref;
120 ref->cause = SCCP_REFUSAL_END_USER_ORIGINATED;
121 ref->optional_start = 1;
122
123 msg->l3h = msgb_put(msg, 1);
124 msg->l3h[0] = SCCP_PNC_END_OF_OPTIONAL;
125
126 return msg;
127}
128
129struct msgb *create_reset()
130{
Holger Hans Peter Freyther5aa17012010-07-31 04:37:26 +0800131 static const uint8_t reset[] = {
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800132 0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe,
133 0x02, 0x42, 0xfe, 0x06, 0x00, 0x04, 0x30, 0x04,
134 0x01, 0x20
135 };
136
137 struct msgb *msg;
138
139 msg = msgb_alloc_headroom(4096, 128, "reset");
140 if (!msg) {
141 LOGP(DMSC, LOGL_ERROR, "Failed to allocate reset msg.\n");
142 return NULL;
143 }
144
145 msg->l2h = msgb_put(msg, sizeof(reset));
146 memcpy(msg->l2h, reset, msgb_l2len(msg));
147 return msg;
148}