blob: eae15982e42178594239aac9a9b218692bb0ff2f [file] [log] [blame]
Holger Hans Peter Freyther280cd512010-04-15 10:10:39 +02001/* (C) 2009,2010 by Holger Hans Peter Freyther <zecke@selfish.org>
2 * (C) 2009,2010 by On-Waves
3 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 */
20
Pablo Neira Ayuso83419342011-03-22 16:36:13 +010021#include <osmocom/gsm/gsm0808.h>
22#include <osmocom/gsm/protocol/gsm_08_08.h>
23#include <osmocom/gsm/gsm48.h>
Holger Hans Peter Freyther280cd512010-04-15 10:10:39 +020024
25#include <arpa/inet.h>
26
27#define BSSMAP_MSG_SIZE 512
28#define BSSMAP_MSG_HEADROOM 128
29
Holger Hans Peter Freyther06f795c2010-07-23 18:20:02 +080030static void put_data_16(uint8_t *data, const uint16_t val)
31{
32 memcpy(data, &val, sizeof(val));
33}
34
35struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, uint16_t cc, int lac, uint16_t _ci)
Holger Hans Peter Freyther280cd512010-04-15 10:10:39 +020036{
37 uint8_t *data;
Holger Hans Peter Freyther06f795c2010-07-23 18:20:02 +080038 uint8_t *ci;
Holger Hans Peter Freyther280cd512010-04-15 10:10:39 +020039 struct msgb* msg;
40 struct gsm48_loc_area_id *lai;
41
42 msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
43 "bssmap cmpl l3");
44 if (!msg)
45 return NULL;
46
47 /* create the bssmap header */
48 msg->l3h = msgb_put(msg, 2);
49 msg->l3h[0] = 0x0;
50
51 /* create layer 3 header */
52 data = msgb_put(msg, 1);
53 data[0] = BSS_MAP_MSG_COMPLETE_LAYER_3;
54
55 /* create the cell header */
56 data = msgb_put(msg, 3);
57 data[0] = GSM0808_IE_CELL_IDENTIFIER;
58 data[1] = 1 + sizeof(*lai) + 2;
59 data[2] = CELL_IDENT_WHOLE_GLOBAL;
60
61 lai = (struct gsm48_loc_area_id *) msgb_put(msg, sizeof(*lai));
62 gsm48_generate_lai(lai, cc, nc, lac);
63
Holger Hans Peter Freyther06f795c2010-07-23 18:20:02 +080064 ci = msgb_put(msg, 2);
65 put_data_16(ci, htons(_ci));
Holger Hans Peter Freyther280cd512010-04-15 10:10:39 +020066
67 /* copy the layer3 data */
68 data = msgb_put(msg, msgb_l3len(msg_l3) + 2);
69 data[0] = GSM0808_IE_LAYER_3_INFORMATION;
70 data[1] = msgb_l3len(msg_l3);
71 memcpy(&data[2], msg_l3->l3h, data[1]);
72
73 /* update the size */
74 msg->l3h[1] = msgb_l3len(msg) - 2;
75
76 return msg;
77}
78
79struct msgb *gsm0808_create_reset(void)
80{
81 struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
82 "bssmap: reset");
83 if (!msg)
84 return NULL;
85
86 msg->l3h = msgb_put(msg, 6);
87 msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
88 msg->l3h[1] = 0x04;
89 msg->l3h[2] = 0x30;
90 msg->l3h[3] = 0x04;
91 msg->l3h[4] = 0x01;
92 msg->l3h[5] = 0x20;
93 return msg;
94}
95
96struct msgb *gsm0808_create_clear_complete(void)
97{
98 struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
99 "bssmap: clear complete");
100 if (!msg)
101 return NULL;
102
103 msg->l3h = msgb_put(msg, 3);
104 msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
105 msg->l3h[1] = 1;
106 msg->l3h[2] = BSS_MAP_MSG_CLEAR_COMPLETE;
107
108 return msg;
109}
110
Holger Hans Peter Freythera3f05d82010-10-27 11:49:24 +0200111struct msgb *gsm0808_create_clear_command(uint8_t reason)
112{
113 struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
114 "bssmap: clear command");
115 if (!msg)
116 return NULL;
117
Holger Hans Peter Freytheraeebe392010-10-27 12:36:05 +0200118 msg->l3h = msgb_tv_put(msg, BSSAP_MSG_BSS_MANAGEMENT, 4);
119 msgb_v_put(msg, BSS_MAP_MSG_CLEAR_CMD);
120 msgb_tlv_put(msg, GSM0808_IE_CAUSE, 1, &reason);
Holger Hans Peter Freythera3f05d82010-10-27 11:49:24 +0200121 return msg;
122}
123
Holger Hans Peter Freyther81716d52010-04-17 06:16:35 +0200124struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id)
125{
126 struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
127 "cipher-complete");
128 if (!msg)
129 return NULL;
130
131 /* send response with BSS override for A5/1... cheating */
132 msg->l3h = msgb_put(msg, 3);
133 msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
134 msg->l3h[1] = 0xff;
135 msg->l3h[2] = BSS_MAP_MSG_CIPHER_MODE_COMPLETE;
136
137 /* include layer3 in case we have at least two octets */
138 if (layer3 && msgb_l3len(layer3) > 2) {
139 msg->l4h = msgb_put(msg, msgb_l3len(layer3) + 2);
140 msg->l4h[0] = GSM0808_IE_LAYER_3_MESSAGE_CONTENTS;
141 msg->l4h[1] = msgb_l3len(layer3);
142 memcpy(&msg->l4h[2], layer3->l3h, msgb_l3len(layer3));
143 }
144
145 /* and the optional BSS message */
146 msg->l4h = msgb_put(msg, 2);
147 msg->l4h[0] = GSM0808_IE_CHOSEN_ENCR_ALG;
148 msg->l4h[1] = alg_id;
149
150 /* update the size */
151 msg->l3h[1] = msgb_l3len(msg) - 2;
152 return msg;
153}
154
Holger Hans Peter Freyther280cd512010-04-15 10:10:39 +0200155struct msgb *gsm0808_create_cipher_reject(uint8_t cause)
156{
157 struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
158 "bssmap: clear complete");
159 if (!msg)
160 return NULL;
161
Harald Welte0c836702011-07-12 00:02:09 +0200162 msg->l3h = msgb_put(msg, 4);
Holger Hans Peter Freyther280cd512010-04-15 10:10:39 +0200163 msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
164 msg->l3h[1] = 2;
165 msg->l3h[2] = BSS_MAP_MSG_CIPHER_MODE_REJECT;
166 msg->l3h[3] = cause;
167
168 return msg;
169}
170
Sylvain Munauta074ec42010-04-28 10:05:29 +0200171struct msgb *gsm0808_create_classmark_update(const uint8_t *classmark_data, uint8_t length)
Holger Hans Peter Freyther280cd512010-04-15 10:10:39 +0200172{
173 struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
174 "classmark-update");
175 if (!msg)
176 return NULL;
177
178 msg->l3h = msgb_put(msg, 3);
179 msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
180 msg->l3h[1] = 0xff;
181 msg->l3h[2] = BSS_MAP_MSG_CLASSMARK_UPDATE;
182
183 msg->l4h = msgb_put(msg, length);
184 memcpy(msg->l4h, classmark_data, length);
185
186 /* update the size */
187 msg->l3h[1] = msgb_l3len(msg) - 2;
188 return msg;
189}
190
191struct msgb *gsm0808_create_sapi_reject(uint8_t link_id)
192{
193 struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
194 "bssmap: sapi 'n' reject");
195 if (!msg)
196 return NULL;
197
198 msg->l3h = msgb_put(msg, 5);
199 msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
200 msg->l3h[1] = 3;
201 msg->l3h[2] = BSS_MAP_MSG_SAPI_N_REJECT;
202 msg->l3h[3] = link_id;
203 msg->l3h[4] = GSM0808_CAUSE_BSS_NOT_EQUIPPED;
204
205 return msg;
206}
207
Holger Hans Peter Freytherb60a4b32010-07-23 18:35:59 +0800208struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause,
Holger Hans Peter Freytherba6172a2010-04-17 06:21:49 +0200209 uint8_t chosen_channel, uint8_t encr_alg_id,
210 uint8_t speech_mode)
211{
Sylvain Munauta074ec42010-04-28 10:05:29 +0200212 uint8_t *data;
Holger Hans Peter Freytherba6172a2010-04-17 06:21:49 +0200213
214 struct msgb *msg = msgb_alloc(35, "bssmap: ass compl");
215 if (!msg)
216 return NULL;
217
218 msg->l3h = msgb_put(msg, 3);
219 msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
220 msg->l3h[1] = 0xff;
221 msg->l3h[2] = BSS_MAP_MSG_ASSIGMENT_COMPLETE;
222
223 /* write 3.2.2.22 */
224 data = msgb_put(msg, 2);
225 data[0] = GSM0808_IE_RR_CAUSE;
226 data[1] = rr_cause;
227
228 /* write cirtcuit identity code 3.2.2.2 */
229 /* write cell identifier 3.2.2.17 */
230 /* write chosen channel 3.2.2.33 when BTS picked it */
231 data = msgb_put(msg, 2);
232 data[0] = GSM0808_IE_CHOSEN_CHANNEL;
233 data[1] = chosen_channel;
234
235 /* write chosen encryption algorithm 3.2.2.44 */
236 data = msgb_put(msg, 2);
237 data[0] = GSM0808_IE_CHOSEN_ENCR_ALG;
238 data[1] = encr_alg_id;
239
240 /* write circuit pool 3.2.2.45 */
241 /* write speech version chosen: 3.2.2.51 when BTS picked it */
242 if (speech_mode != 0) {
243 data = msgb_put(msg, 2);
244 data[0] = GSM0808_IE_SPEECH_VERSION;
245 data[1] = speech_mode;
246 }
247
248 /* write LSA identifier 3.2.2.15 */
249
250
251 /* update the size */
252 msg->l3h[1] = msgb_l3len(msg) - 2;
253 return msg;
254}
255
Holger Hans Peter Freyther280cd512010-04-15 10:10:39 +0200256struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause)
257{
258 uint8_t *data;
259 struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
260 "bssmap: ass fail");
261 if (!msg)
262 return NULL;
263
264 msg->l3h = msgb_put(msg, 6);
265 msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
266 msg->l3h[1] = 0xff;
267 msg->l3h[2] = BSS_MAP_MSG_ASSIGMENT_FAILURE;
268 msg->l3h[3] = GSM0808_IE_CAUSE;
269 msg->l3h[4] = 1;
270 msg->l3h[5] = cause;
271
272 /* RR cause 3.2.2.22 */
273 if (rr_cause) {
274 data = msgb_put(msg, 2);
275 data[0] = GSM0808_IE_RR_CAUSE;
276 data[1] = *rr_cause;
277 }
278
279 /* Circuit pool 3.22.45 */
280 /* Circuit pool list 3.2.2.46 */
281
282 /* update the size */
283 msg->l3h[1] = msgb_l3len(msg) - 2;
284 return msg;
285}
Holger Hans Peter Freyther7daa01c2010-04-17 05:14:36 +0200286
Holger Hans Peter Freytheraf270a42010-11-04 12:42:50 +0100287struct msgb *gsm0808_create_clear_rqst(uint8_t cause)
288{
289 struct msgb *msg;
290
291 msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
292 "bssmap: clear rqst");
293 if (!msg)
294 return NULL;
295
296 msg->l3h = msgb_put(msg, 2 + 4);
297 msg->l3h[0] = BSSAP_MSG_BSS_MANAGEMENT;
298 msg->l3h[1] = 4;
299
300 msg->l3h[2] = BSS_MAP_MSG_CLEAR_RQST;
301 msg->l3h[3] = GSM0808_IE_CAUSE;
302 msg->l3h[4] = 1;
303 msg->l3h[5] = cause;
304 return msg;
305}
306
Holger Hans Peter Freyther9a3dec02010-05-16 08:15:40 +0800307void gsm0808_prepend_dtap_header(struct msgb *msg, uint8_t link_id)
308{
309 uint8_t *hh = msgb_push(msg, 3);
310 hh[0] = BSSAP_MSG_DTAP;
311 hh[1] = link_id;
312 hh[2] = msg->len - 3;
313}
314
Holger Hans Peter Freytherc25c6682010-11-04 12:26:06 +0100315struct msgb *gsm0808_create_dtap(struct msgb *msg_l3, uint8_t link_id)
316{
317 struct dtap_header *header;
318 uint8_t *data;
319 struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
320 "dtap");
321 if (!msg)
322 return NULL;
323
324 /* DTAP header */
325 msg->l3h = msgb_put(msg, sizeof(*header));
326 header = (struct dtap_header *) &msg->l3h[0];
327 header->type = BSSAP_MSG_DTAP;
328 header->link_id = link_id;
329 header->length = msgb_l3len(msg_l3);
330
331 /* Payload */
332 data = msgb_put(msg, header->length);
333 memcpy(data, msg_l3->l3h, header->length);
334
335 return msg;
336}
337
Holger Hans Peter Freyther7daa01c2010-04-17 05:14:36 +0200338static const struct tlv_definition bss_att_tlvdef = {
339 .def = {
340 [GSM0808_IE_IMSI] = { TLV_TYPE_TLV },
341 [GSM0808_IE_TMSI] = { TLV_TYPE_TLV },
342 [GSM0808_IE_CELL_IDENTIFIER_LIST] = { TLV_TYPE_TLV },
343 [GSM0808_IE_CHANNEL_NEEDED] = { TLV_TYPE_TV },
344 [GSM0808_IE_EMLPP_PRIORITY] = { TLV_TYPE_TV },
345 [GSM0808_IE_CHANNEL_TYPE] = { TLV_TYPE_TLV },
346 [GSM0808_IE_PRIORITY] = { TLV_TYPE_TLV },
Holger Hans Peter Freythera55caad2010-09-20 01:23:15 +0800347 [GSM0808_IE_CIRCUIT_IDENTITY_CODE] = { TLV_TYPE_FIXED, 2 },
Holger Hans Peter Freyther7daa01c2010-04-17 05:14:36 +0200348 [GSM0808_IE_DOWNLINK_DTX_FLAG] = { TLV_TYPE_TV },
349 [GSM0808_IE_INTERFERENCE_BAND_TO_USE] = { TLV_TYPE_TV },
350 [GSM0808_IE_CLASSMARK_INFORMATION_T2] = { TLV_TYPE_TLV },
351 [GSM0808_IE_GROUP_CALL_REFERENCE] = { TLV_TYPE_TLV },
352 [GSM0808_IE_TALKER_FLAG] = { TLV_TYPE_T },
353 [GSM0808_IE_CONFIG_EVO_INDI] = { TLV_TYPE_TV },
354 [GSM0808_IE_LSA_ACCESS_CTRL_SUPPR] = { TLV_TYPE_TV },
Holger Hans Peter Freythera55caad2010-09-20 01:23:15 +0800355 [GSM0808_IE_SERVICE_HANDOVER] = { TLV_TYPE_TLV },
Holger Hans Peter Freyther7daa01c2010-04-17 05:14:36 +0200356 [GSM0808_IE_ENCRYPTION_INFORMATION] = { TLV_TYPE_TLV },
357 [GSM0808_IE_CIPHER_RESPONSE_MODE] = { TLV_TYPE_TV },
Holger Hans Peter Freyther102bcaf2010-05-14 07:25:01 +0800358 [GSM0808_IE_CELL_IDENTIFIER] = { TLV_TYPE_TLV },
359 [GSM0808_IE_CHOSEN_CHANNEL] = { TLV_TYPE_TV },
360 [GSM0808_IE_LAYER_3_INFORMATION] = { TLV_TYPE_TLV },
Holger Hans Peter Freytherc2b7f922010-08-04 18:50:43 +0800361 [GSM0808_IE_SPEECH_VERSION] = { TLV_TYPE_TV },
362 [GSM0808_IE_CHOSEN_ENCR_ALG] = { TLV_TYPE_TV },
Holger Hans Peter Freyther7daa01c2010-04-17 05:14:36 +0200363 },
364};
365
366const struct tlv_definition *gsm0808_att_tlvdef()
367{
368 return &bss_att_tlvdef;
369}
Harald Welte9b837e62011-07-11 17:43:19 +0200370
371static const struct value_string gsm0808_msgt_names[] = {
372 { BSS_MAP_MSG_ASSIGMENT_RQST, "ASSIGNMENT REQ" },
373 { BSS_MAP_MSG_ASSIGMENT_COMPLETE, "ASSIGNMENT COMPL" },
374 { BSS_MAP_MSG_ASSIGMENT_FAILURE, "ASSIGNMENT FAIL" },
375
376 { BSS_MAP_MSG_HANDOVER_RQST, "HANDOVER REQ" },
377 { BSS_MAP_MSG_HANDOVER_REQUIRED, "HANDOVER REQUIRED" },
378 { BSS_MAP_MSG_HANDOVER_RQST_ACKNOWLEDGE,"HANDOVER REQ ACK" },
379 { BSS_MAP_MSG_HANDOVER_CMD, "HANDOVER CMD" },
380 { BSS_MAP_MSG_HANDOVER_COMPLETE, "HANDOVER COMPLETE" },
381 { BSS_MAP_MSG_HANDOVER_SUCCEEDED, "HANDOVER SUCCESS" },
382 { BSS_MAP_MSG_HANDOVER_FAILURE, "HANDOVER FAILURE" },
383 { BSS_MAP_MSG_HANDOVER_PERFORMED, "HANDOVER PERFORMED" },
384 { BSS_MAP_MSG_HANDOVER_CANDIDATE_ENQUIRE, "HANDOVER CAND ENQ" },
385 { BSS_MAP_MSG_HANDOVER_CANDIDATE_RESPONSE, "HANDOVER CAND RESP" },
386 { BSS_MAP_MSG_HANDOVER_REQUIRED_REJECT, "HANDOVER REQ REJ" },
387 { BSS_MAP_MSG_HANDOVER_DETECT, "HANDOVER DETECT" },
388
389 { BSS_MAP_MSG_CLEAR_CMD, "CLEAR COMMAND" },
390 { BSS_MAP_MSG_CLEAR_COMPLETE, "CLEAR COMPLETE" },
391 { BSS_MAP_MSG_CLEAR_RQST, "CLEAR REQUEST" },
392 { BSS_MAP_MSG_SAPI_N_REJECT, "SAPI N REJECT" },
393 { BSS_MAP_MSG_CONFUSION, "CONFUSION" },
394
395 { BSS_MAP_MSG_SUSPEND, "SUSPEND" },
396 { BSS_MAP_MSG_RESUME, "RESUME" },
397 { BSS_MAP_MSG_CONNECTION_ORIENTED_INFORMATION, "CONN ORIENT INFO" },
398 { BSS_MAP_MSG_PERFORM_LOCATION_RQST, "PERFORM LOC REQ" },
399 { BSS_MAP_MSG_LSA_INFORMATION, "LSA INFORMATION" },
400 { BSS_MAP_MSG_PERFORM_LOCATION_RESPONSE, "PERFORM LOC RESP" },
401 { BSS_MAP_MSG_PERFORM_LOCATION_ABORT, "PERFORM LOC ABORT" },
402 { BSS_MAP_MSG_COMMON_ID, "COMMON ID" },
403
404 { BSS_MAP_MSG_RESET, "RESET" },
405 { BSS_MAP_MSG_RESET_ACKNOWLEDGE, "RESET ACK" },
406 { BSS_MAP_MSG_OVERLOAD, "OVERLOAD" },
407 { BSS_MAP_MSG_RESET_CIRCUIT, "RESET CIRCUIT" },
408 { BSS_MAP_MSG_RESET_CIRCUIT_ACKNOWLEDGE, "RESET CIRCUIT ACK" },
409 { BSS_MAP_MSG_MSC_INVOKE_TRACE, "MSC INVOKE TRACE" },
410 { BSS_MAP_MSG_BSS_INVOKE_TRACE, "BSS INVOKE TRACE" },
411 { BSS_MAP_MSG_CONNECTIONLESS_INFORMATION, "CONNLESS INFO" },
412
413 { BSS_MAP_MSG_BLOCK, "BLOCK" },
414 { BSS_MAP_MSG_BLOCKING_ACKNOWLEDGE, "BLOCK ACK" },
415 { BSS_MAP_MSG_UNBLOCK, "UNBLOCK" },
416 { BSS_MAP_MSG_UNBLOCKING_ACKNOWLEDGE, "UNBLOCK ACK" },
417 { BSS_MAP_MSG_CIRCUIT_GROUP_BLOCK, "CIRC GROUP BLOCK" },
418 { BSS_MAP_MSG_CIRCUIT_GROUP_BLOCKING_ACKNOWLEDGE, "CIRC GORUP BLOCK ACK" },
419 { BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCK, "CIRC GROUP UNBLOCK" },
420 { BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCKING_ACKNOWLEDGE, "CIRC GROUP UNBLOCK ACK" },
421 { BSS_MAP_MSG_UNEQUIPPED_CIRCUIT, "UNEQUIPPED CIRCUIT" },
422 { BSS_MAP_MSG_CHANGE_CIRCUIT, "CHANGE CIRCUIT" },
423 { BSS_MAP_MSG_CHANGE_CIRCUIT_ACKNOWLEDGE, "CHANGE CIRCUIT ACK" },
424
425 { BSS_MAP_MSG_RESOURCE_RQST, "RESOURCE REQ" },
426 { BSS_MAP_MSG_RESOURCE_INDICATION, "RESOURCE IND" },
427 { BSS_MAP_MSG_PAGING, "PAGING" },
428 { BSS_MAP_MSG_CIPHER_MODE_CMD, "CIPHER MODE CMD" },
429 { BSS_MAP_MSG_CLASSMARK_UPDATE, "CLASSMARK UPDATE" },
430 { BSS_MAP_MSG_CIPHER_MODE_COMPLETE, "CIPHER MODE COMPLETE" },
431 { BSS_MAP_MSG_QUEUING_INDICATION, "QUEUING INDICATION" },
432 { BSS_MAP_MSG_COMPLETE_LAYER_3, "COMPLETE LAYER 3" },
433 { BSS_MAP_MSG_CLASSMARK_RQST, "CLASSMARK REQ" },
434 { BSS_MAP_MSG_CIPHER_MODE_REJECT, "CIPHER MODE REJECT" },
435 { BSS_MAP_MSG_LOAD_INDICATION, "LOAD IND" },
436
437 /* FIXME: VGCS/VBS */
438
439 { 0, NULL }
440};
441
442const char *gsm0808_bssmap_name(uint8_t msg_type)
443{
444 return get_value_string(gsm0808_msgt_names, msg_type);
445}
446
447static const struct value_string gsm0808_bssap_names[] = {
448 { BSSAP_MSG_BSS_MANAGEMENT, "MANAGEMENT" },
449 { BSSAP_MSG_DTAP, "DTAP" },
450};
451
452const char *gsm0808_bssap_name(uint8_t msg_type)
453{
454 return get_value_string(gsm0808_bssap_names, msg_type);
455}