comparison src/g23m-gprs/sm/sm_debug.c @ 1:d393cd9bb723

src/g23m-*: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:40:46 +0000
parents
children
comparison
equal deleted inserted replaced
0:b6a5e36de839 1:d393cd9bb723
1 /*----------------------------------------------------------------------------
2 | Project : 3G PS
3 | Module : SM
4 +-----------------------------------------------------------------------------
5 | Copyright 2003 Texas Instruments.
6 | All rights reserved.
7 |
8 | This file is confidential and a trade secret of Texas
9 | Instruments .
10 | The receipt of or possession of this file does not convey
11 | any rights to reproduce or disclose its contents or to
12 | manufacture, use, or sell anything it may describe, in
13 | whole, or in part, without the specific written consent of
14 | Texas Instruments.
15 +-----------------------------------------------------------------------------
16 | Purpose: Debug functions implementation in the SM entity.
17 | For design details, see:
18 | 8010.908 SM Detailed Specification
19 +---------------------------------------------------------------------------*/
20
21 /*==== DECLARATION CONTROL =================================================*/
22
23 /*==== INCLUDES =============================================================*/
24
25 #include <stdio.h>
26 #include "sm.h"
27
28 #include "sm_timer_handler.h"
29
30 /*==== CONSTS ===============================================================*/
31
32 /*==== TYPES ================================================================*/
33
34 /*==== LOCALS ===============================================================*/
35
36 /*==== PRIVATE FUNCTIONS ====================================================*/
37
38 /*==== PUBLIC FUNCTIONS =====================================================*/
39
40 #ifdef DEBUG
41 /*
42 * Debug function for dumping the contents of an QoS structure.
43 */
44 static void sm_qos_dump_r97_qos(T_PS_qos_r97 *qos_r97)
45 {
46 /*@observer@*/const char *indent = " - ";
47
48 /*@observer@*/const char *peak_text[16] = {
49 /* NAS_PEAK_SUB */ "SUBSCRIBED",
50 /* NAS_PEAK_1K */ "Up to 1000 octet/s",
51 /* NAS_PEAK_2K */ "Up to 2000 octet/s",
52 /* NAS_PEAK_4K */ "Up to 4000 octet/s",
53 /* NAS_PEAK_8K */ "Up to 8000 octet/s",
54 /* NAS_PEAK_16K */ "Up to 16000 octet/s",
55 /* NAS_PEAK_32K */ "Up to 32000 octet/s",
56 /* NAS_PEAK_64K */ "Up to 64000 octet/s",
57 /* NAS_PEAK_128K */ "Up to 128000 octet/s",
58 /* NAS_PEAK_256K */ "Up to 256000 octet/s",
59 /* 10 */ "RESERVED - 1000 octets/s",
60 /* 11 */ "RESERVED - 1000 octets/s",
61 /* 12 */ "RESERVED - 1000 octets/s",
62 /* 13 */ "RESERVED - 1000 octets/s",
63 /* 14 */ "RESERVED - 1000 octets/s",
64 /* 15 */ "RESERVED",
65 };
66
67 /*@observer@*/const char *mean_text[32] = {
68 /* NAS_MEAN_SUB */ "SUBSCRIBED",
69 /* NAS_MEAN_100 */ "100 octets/h",
70 /* NAS_MEAN_200 */ "200 octets/h",
71 /* NAS_MEAN_500 */ "500 octets/h",
72 /* NAS_MEAN_1K */ "1000 octets/h",
73 /* NAS_MEAN_2K */ "2000 octets/h",
74 /* NAS_MEAN_5K */ "5000 octets/h",
75 /* NAS_MEAN_10K */ "10000 octets/h",
76 /* NAS_MEAN_20K */ "20000 octets/h",
77 /* NAS_MEAN_50K */ "50000 octets/h",
78 /* NAS_MEAN_100K */ "100000 octets/h",
79 /* NAS_MEAN_200K */ "200000 octets/h",
80 /* NAS_MEAN_500K */ "500000 octets/h",
81 /* NAS_MEAN_1M */ "1000000 octets/h",
82 /* NAS_MEAN_2M */ "2000000 octets/h",
83 /* NAS_MEAN_5M */ "5000000 octets/h",
84 /* NAS_MEAN_10M */ "10000000 octets/h",
85 /* NAS_MEAN_20M */ "20000000 octets/h",
86 /* NAS_MEAN_50M */ "50000000 octets/h",
87 /* 19 */ "RESERVED",
88 /* 20 */ "RESERVED",
89 /* 21 */ "RESERVED",
90 /* 22 */ "RESERVED",
91 /* 23 */ "RESERVED",
92 /* 24 */ "RESERVED",
93 /* 25 */ "RESERVED",
94 /* 26 */ "RESERVED",
95 /* 27 */ "RESERVED",
96 /* 28 */ "RESERVED",
97 /* 29 */ "RESERVED",
98 /* 30 */ "RESERVED",
99 /* NAS_MEAN_BEST */"BEST EFFORT"
100 };
101 /*@observer@*/const char *rel_text[8] = {
102 /* NAS_RELCLASS_SUB */ "Subscribed reliability class",
103 /* NAS_GTP_LLC_RLC_PROT */ "Ack'ed GTP, LLC, and RLC; Protected data",
104 /* NAS_LLC_RLC_PROT */ "Unack'ed GTP; Ack'ed LLC and RLC, Protected data",
105 /* NAS_RLC_PROT */ "Unack'ed GTP and LLC; Ack'ed RLC, Protected data",
106 /* NAS_PROT */ "Unack'ed GTP, LLC, and RLC, Protected data",
107 /* NAS_NO_PROT */ "Unack'ed GTP, LLC, and RLC, Unprotected data",
108 /* 6 */ "UNKNOWN VALUE",
109 /* 7 */ "RESERVED"
110 };
111
112 (void)TRACE_EVENT_P3("%sDelay class: 0x%02x (Class %d)",
113 indent, qos_r97->delay, qos_r97->delay);
114 (void)TRACE_EVENT_P3("%sReliability class: 0x%02x (%s)",
115 indent, qos_r97->relclass, rel_text[(U16)qos_r97->relclass]);
116 (void)TRACE_EVENT_P3("%sPeak bitrate 0x%02x (%s)",
117 indent, qos_r97->peak, peak_text[(U16)qos_r97->peak]);
118 (void)TRACE_EVENT_P2("%sPrecedence class: 0x%02x",
119 indent, qos_r97->preced);
120 (void)TRACE_EVENT_P3("%sMean bitrate 0x%02x (%s)",
121 indent, qos_r97->mean, mean_text[(U16)qos_r97->mean]);
122 }
123
124 static void sm_qos_dump_r99_qos(T_PS_qos_r99 *qos_r99)
125 {
126 /*@observer@*/const char *indent = " - ";
127
128 (void)TRACE_EVENT_P3("%sTraffic class: 0x%02x (%s)",
129 indent, qos_r99->tc,
130 (qos_r99->tc == (U8)PS_TC_CONV ? "CONVERSATIONAL" :
131 (qos_r99->tc == (U8)PS_TC_STREAM ? "STREAMING" :
132 (qos_r99->tc == (U8)PS_TC_INTER ? "INTERACTIVE" :
133 (qos_r99->tc == (U8)PS_TC_BG ? "BACKGROUND" :
134 (qos_r99->tc == (U8)PS_TC_SUB ? "SUBSCRIBED" :
135 "UNKNOWN"))))));
136 (void)TRACE_EVENT_P3("%sDelivery order: 0x%02x (%s)",
137 indent, qos_r99->order,
138 (qos_r99->order == (U8)PS_ORDER_YES ? "YES" :
139 (qos_r99->order == (U8)PS_ORDER_NO ? "NO" :
140 (qos_r99->order == (U8)PS_ORDER_SUB ? "SUBSCRIBED" :
141 "UNKNOWN"))));
142 (void)TRACE_EVENT_P3("%sDeliver erroneous SDUs: 0x%02x (%s)",
143 indent, qos_r99->del_err_sdu,
144 (qos_r99->del_err_sdu == (U8)PS_DEL_ERR_YES ? "YES" :
145 (qos_r99->del_err_sdu == (U8)PS_DEL_ERR_NO ? "NO" :
146 (qos_r99->del_err_sdu == (U8)PS_DEL_ERR_NODETECT ? "NODETECT" :
147 (qos_r99->del_err_sdu == (U8)PS_DEL_ERR_SUB ? "SUBSCRIBED" :
148 "UNKNOWN")))));
149 (void)TRACE_EVENT_P3("%sMax SDU size: 0x%04x (%d octets)",
150 indent, qos_r99->max_sdu, qos_r99->max_sdu);
151 (void)TRACE_EVENT_P3("%sMax bit-rate uplink: 0x%04x (%dkbps)",
152 indent, qos_r99->max_rate_ul, qos_r99->max_rate_ul);
153 (void)TRACE_EVENT_P3("%sMax bit-rate downlink: 0x%04x (%dkbps)",
154 indent, qos_r99->max_rate_dl, qos_r99->max_rate_dl);
155 (void)TRACE_EVENT_P3("%sMax residual BER: %dE-%d",
156 indent, qos_r99->ber.ratio_mant, qos_r99->ber.ratio_exp);
157 (void)TRACE_EVENT_P3("%sMax SDU error ratio: %dE-%d",
158 indent, qos_r99->sdu_err_ratio.ratio_mant,
159 qos_r99->sdu_err_ratio.ratio_exp);
160 (void)TRACE_EVENT_P3("%sTransfer delay: 0x%04x (%dms)",
161 indent, qos_r99->xfer_delay, qos_r99->xfer_delay);
162 (void)TRACE_EVENT_P3("%sTraffic handling prio: 0x%02x (%d)",
163 indent, qos_r99->handling_pri, qos_r99->handling_pri);
164 (void)TRACE_EVENT_P3("%sGuar. bit-rate uplink: 0x%04x (%dkbps)",
165 indent, qos_r99->guar_br_ul, qos_r99->guar_br_ul);
166 (void)TRACE_EVENT_P3("%sGuar. bit-rate downlink: 0x%04x (%dkbps)",
167 indent, qos_r99->guar_br_dl, qos_r99->guar_br_dl);
168 }
169
170 static void sm_qos_dump_qos(T_SM_qos *qos, const char *type)
171 {
172 if (qos->ctrl_qos == PS_is_R97)
173 {
174 (void)TRACE_EVENT_P1( " R97 %s QoS:", type);
175 sm_qos_dump_r97_qos(&qos->qos.qos_r97);
176 } else if (qos->ctrl_qos == PS_is_R99) {
177 (void)TRACE_EVENT_P1( " R99 %s QoS:", type);
178 sm_qos_dump_r99_qos(&qos->qos.qos_r99);
179 } else {
180 (void)TRACE_EVENT_P2("ERROR! Invalid union controller == %d in %s QoS!",
181 qos->ctrl_qos, type);
182 }
183 }
184
185 static BOOL sm_debug_is_port_range(U16 low_limit, U16 high_limit)
186 {
187 return (high_limit != 0 && low_limit < high_limit);
188 }
189
190 static /*@observer@*/char *
191 sm_debug_dump_port_range(U16 low_limit, U16 high_limit)
192 {
193 static char range[sizeof("65535-65535")];
194
195 /*@-bufferoverflowhigh@*/
196 if (sm_debug_is_port_range(low_limit, high_limit))
197 {
198 sprintf(range, "%5hu-%5hu", low_limit, high_limit);
199 } else {
200 sprintf(range, "%5hu", low_limit);
201 }
202 /*@=bufferoverflowhigh@*/
203 return range;
204 }
205
206 static U32 sm_debug_octet_as_bits(U8 octet) /*@*/
207 {
208 const U32 bit_masks[16] = {
209 0000UL, 0001UL, 0010UL, 0011UL, 0100UL, 0101UL, 0110UL, 0111UL,
210 1000UL, 1001UL, 1010UL, 1011UL, 1100UL, 1101UL, 1110UL, 1111UL
211 };
212 return (bit_masks[(U16)octet >> 4] * 10000UL + bit_masks[(U16)octet & 15]);
213 }
214
215 static void sm_debug_dump_ipv4_tft(T_NAS_tft_pf_ipv4 *pf, U8 valid_bits)
216 {
217 if ( (valid_bits & NAS_TFT_ID_PROTOCOL_OR_NEXT_HDR) != (U8)0)
218 {
219 (void)TRACE_EVENT_P1(" + IPv4 protocol number = %hu",
220 (U16)pf->tft_protocol);
221 }
222 if ( (valid_bits & NAS_TFT_ID_TOS_AND_MASK) != (U8)0)
223 {
224 (void)TRACE_EVENT_P2(" + IPv4 ToS and mask = 0x%02x/0x%02x",
225 pf->tft_tos_and_mask.tos_value,
226 pf->tft_tos_and_mask.tos_mask);
227 }
228 if ( (valid_bits & NAS_TFT_ID_DEST_PORT_RANGE) != (U8)0)
229 {
230 (void)TRACE_EVENT_P1(" + Dest port (range) = %s",
231 sm_debug_dump_port_range(pf->tft_dest_port_range.low_limit, pf->tft_dest_port_range.high_limit));
232 }
233 if ( (valid_bits & NAS_TFT_ID_SRC_PORT_RANGE) != (U8)0)
234 {
235 (void)TRACE_EVENT_P1(" + Source port (range) = %s",
236 sm_debug_dump_port_range(pf->tft_src_port_range.low_limit, pf->tft_src_port_range.high_limit));
237 }
238 if ( (valid_bits & NAS_TFT_ID_IPSEC_SPI) != (U8)0)
239 {
240 (void)TRACE_EVENT_P1(" + IPv4 IPSEC SPI = %08x",
241 pf->tft_ipsec_spi);
242 }
243 if ( (valid_bits & NAS_TFT_ID_IPv4_SRC_ADDR_MASK) != (U8)0)
244 {
245 U8 *a4 = pf->tft_ipv4_src_addr_mask.tft_ipv4_addr;
246 (void)TRACE_EVENT_P8(" + IPv4 src address/mask = %hu.%hu.%hu.%hu"
247 "/%hu.%hu.%hu.%hu",
248 (U16)a4[0], (U16)a4[1], (U16)a4[2], (U16)a4[3],
249 (U16)a4[0], (U16)a4[1], (U16)a4[2], (U16)a4[3]);
250 }
251 }
252
253 static void sm_debug_dump_ipv6_tft(T_NAS_tft_pf_ipv6 *pf, U8 valid_bits)
254 {
255 if ( (valid_bits & NAS_TFT_ID_PROTOCOL_OR_NEXT_HDR) != (U8)0)
256 {
257 (void)TRACE_EVENT_P1(" + IPv6 next header = %hu",
258 (U16)pf->tft_next_hdr);
259 }
260 if ( (valid_bits & NAS_TFT_ID_TOS_AND_MASK) != (U8)0)
261 {
262 (void)TRACE_EVENT_P2(" + IPv6 traffic class/mask= 0x%02x/0x%02x",
263 pf->tft_tos_and_mask.tos_value,
264 pf->tft_tos_and_mask.tos_mask);
265 }
266 if ( (valid_bits & NAS_TFT_ID_DEST_PORT_RANGE) != (U8)0)
267 {
268 (void)TRACE_EVENT_P1(" + Dest port (range) = %s",
269 sm_debug_dump_port_range(pf->tft_dest_port_range.low_limit, pf->tft_dest_port_range.high_limit));
270 }
271 if ( (valid_bits & NAS_TFT_ID_SRC_PORT_RANGE) != (U8)0)
272 {
273 (void)TRACE_EVENT_P1(" + Source port (range) = %s",
274 sm_debug_dump_port_range(pf->tft_src_port_range.low_limit, pf->tft_src_port_range.high_limit));
275 }
276 if ( (valid_bits & NAS_TFT_ID_IPSEC_SPI) != (U8)0)
277 {
278 (void)TRACE_EVENT_P1(" + IPv6 IPSEC SPI = %08x",
279 pf->tft_ipsec_spi);
280 }
281 if ( (valid_bits & NAS_TFT_ID_FLOW_LABEL) != (U8)0)
282 {
283 (void)TRACE_EVENT_P1(" + IPv6 flow label = %06x",
284 pf->tft_flow_label);
285 }
286 if ( (valid_bits & NAS_TFT_ID_IPv6_SRC_ADDR_MASK) != (U8)0)
287 {
288 char src_addr [SM_SIZE_FORMATTED_IPv6_ADDR],
289 addr_mask[SM_SIZE_FORMATTED_IPv6_ADDR];
290 (void)sm_format_ipv6_addr(pf->tft_ipv6_src_addr_mask.tft_ipv6_addr, src_addr);
291 (void)sm_format_ipv6_addr(pf->tft_ipv6_src_addr_mask.tft_ipv6_mask, addr_mask);
292 (void)TRACE_EVENT_P2(" + IPv6 src address/mask = %s/%s",
293 src_addr, addr_mask);
294 }
295 }
296
297 static void sm_debug_dump_tft_pf(T_NAS_tft_pf *tft_pf, U16 index)
298 {
299 (void)TRACE_EVENT_P3(" #%-2u: ID=%u, precedence=%3u, valid_mask=%08ul",
300 index, tft_pf->tft_pf_precedence,
301 sm_debug_octet_as_bits(tft_pf->tft_pf_valid_bits));
302 if (tft_pf->ctrl_tft_pf_entry == NAS_is_tft_pf_ipv4) {
303 sm_debug_dump_ipv4_tft(&tft_pf->tft_pf_entry.tft_pf_ipv4,
304 tft_pf->tft_pf_valid_bits);
305 } else if (tft_pf->ctrl_tft_pf_entry == NAS_is_tft_pf_ipv6) {
306 sm_debug_dump_ipv6_tft(&tft_pf->tft_pf_entry.tft_pf_ipv6,
307 tft_pf->tft_pf_valid_bits);
308 } else {
309 (void)TRACE_EVENT_P1(" ERROR! Wrong union controller (%d) "
310 "for tft_pf_entry; discarded...",
311 tft_pf->ctrl_tft_pf_entry);
312 }
313 }
314
315 static void sm_debug_dump_tft(T_SM_tft *tft)
316 {
317 if (tft->ptr_tft_pf != NULL && tft->c_tft_pf > (U8)0)
318 {
319 U16 index;
320
321 (void)TRACE_EVENT_P3(" TFT [%08x] with %d filters (mask 0b%08ul)",
322 tft->ptr_tft_pf, tft->c_tft_pf,
323 sm_debug_octet_as_bits(tft->tft_precence_mask));
324 for (index = 0; index < (U16)NAS_SIZE_TFT_FILTER; index++) {
325 if ( (tft->tft_precence_mask & (1UL << index)) != 0)
326 {
327 sm_debug_dump_tft_pf(&tft->ptr_tft_pf[index], index);
328 }
329 }
330 } else {
331 (void)TRACE_EVENT (" TFT [ NULL ]");
332 }
333 }
334
335 /*@observer@*/char *
336 sm_format_ipv6_addr(U8 *addr, /*@out@*/ /*@returned@*/ char *dest)
337 {
338 /*@-bufferoverflowhigh@*/
339 (void)sprintf(dest, "%04hx:%04hx:%04hx:%04hx:%04hx:%04hx:%04hx:%04hx",
340 ((U16)addr[ 0] << 8) | (U16)addr[ 1], ((U16)addr[ 2] << 8) | (U16)addr[ 3],
341 ((U16)addr[ 4] << 8) | (U16)addr[ 5], ((U16)addr[ 6] << 8) | (U16)addr[ 7],
342 ((U16)addr[ 8] << 8) | (U16)addr[ 9], ((U16)addr[10] << 8) | (U16)addr[11],
343 ((U16)addr[12] << 8) | (U16)addr[13], ((U16)addr[14] << 8) | (U16)addr[15]);
344 /*@=bufferoverflowhigh@*/
345 return dest;
346 }
347
348 static void sm_format_ip_address(T_NAS_ip *ip_addr, /*@out@*/char *dest)
349 {
350 if (ip_addr->ctrl_ip_address == NAS_is_ip_not_present)
351 {
352 strcpy(dest, "NOT_PRESENT");
353 } else if (ip_addr->ctrl_ip_address == NAS_is_ipv4) {
354 U8 *ptr_addr = ip_addr->ip_address.ipv4_addr.a4;
355 /*@-bufferoverflowhigh@*/
356 (void)sprintf(dest, "%hu.%hu.%hu.%hu",
357 (U16)ptr_addr[0], (U16)ptr_addr[1],
358 (U16)ptr_addr[2], (U16)ptr_addr[3]);
359 /*@=bufferoverflowhigh@*/
360 } else if (ip_addr->ctrl_ip_address == NAS_is_ipv6) {
361 (void)sm_format_ipv6_addr(ip_addr->ip_address.ipv6_addr.a6, dest);
362 } else {
363 strcpy(dest, "INVALID_CTRL");
364 }
365 }
366
367 struct T_SM_FLAG_STRING {
368 U16 flag;
369 /*@null@*/ /*@observer@*/const char *name;
370 };
371
372 static const struct T_SM_FLAG_STRING sm_context_flags[7] = {
373 {(U16)SM_CONTEXT_FLAG_COMP_PARAMS, "COMP_PARAMS"},
374 {(U16)SM_CONTEXT_FLAG_STARTED_DURING_SUSPEND, "STARTED_DURING_SUSPEND"},
375 {(U16)SM_CONTEXT_FLAG_SECONDARY_CONTEXT, "SECONDARY_CONTEXT"},
376 {(U16)SM_CONTEXT_FLAG_PENDING_DEALLOCATION, "PENDING_DEALLOCATION"},
377 {(U16)SM_CONTEXT_FLAG_PENDING_REACTIVATION, "PENDING_REACTIVATION"},
378 {(U16)SM_CONTEXT_FLAG_PFI_PRESENT, "PFI_PRESENT"},
379 {(U16)0, NULL}
380 };
381
382 static void sm_flags_to_string(const struct T_SM_FLAG_STRING *flag_string,
383 /*@out@*/ char *dest,
384 U16 flags)
385 {
386 U16 index, flag_count;
387
388 flag_count = 0;
389
390 for (index = 0; index < (U16)16 && flag_string->flag != 0; index++)
391 {
392 if ((flags & flag_string->flag) != 0 && flag_string->name != NULL)
393 {
394 if (flag_count != 0)
395 {
396 *dest++ = ','; *dest++ = ' ';
397 } else {
398 flag_count++;
399 }
400 strcpy(dest, flag_string->name);
401 dest = &dest[strlen(flag_string->name)];
402 } /* if */
403 flag_string++;
404 } /* for */
405 *dest = '\0';
406 }
407
408 /*@observer@*/static const char *sm_pdp_type_name(U8 pdp_type)
409 {
410 switch ((T_SMREG_pdp_type) pdp_type) {
411 case SMREG_PDP_PPP: return "PPP";
412 case SMREG_PDP_IPV4: return "IPv4";
413 case SMREG_PDP_IPV6: return "IPv6";
414 case SMREG_PDP_EMPTY: return "DYNAMIC";
415 default: return "INVALID!";
416 }
417 }
418
419 /*@observer@*/const char *sm_timer_name(U8 timer)
420 {
421 switch ((T_SM_TIMER_TYPE) timer) {
422 case SM_TIMER_NONE: return "NONE";
423 case SM_TIMER_T3380: return "T3380";
424 case SM_TIMER_T3381: return "T3381";
425 case SM_TIMER_T3390: return "T3390";
426 default: return "UNKNOWN";
427 }
428 }
429
430 /*@observer@*/static const char *sm_pfi_name(U8 pfi)
431 {
432 switch ((T_PS_pkt_flow_id) pfi) {
433 case PS_PFI_BEST_EFFORT: return "Best Effort";
434 case PS_PFI_SIGNALING: return "Signalling";
435 case PS_PFI_SMS: return "SMS";
436 case PS_PKT_FLOW_ID_NOT_PRES: return "NONE";
437 default: return "UNKNOWN";
438 }
439 }
440
441 static void sm_format_apn(T_SMREG_apn *apn, /*@out@*/char *dest)
442 {
443 U16 index;
444
445 assert(apn != NULL && apn->c_apn_buf > (U8)0);
446
447 /* First, copy (all) APN text skipping first length byte. */
448 if (apn == NULL) {
449 return; /*Fix for Lint warning*/
450 }
451
452 memcpy(dest, &apn->apn_buf[1], (size_t)apn->c_apn_buf - 1);
453
454 index = (U16)apn->apn_buf[0];
455 while (index < (U16)apn->c_apn_buf) {
456 dest[index] = '.';
457 index += (U16)apn->apn_buf[index];
458 }
459 dest[(U16)apn->c_apn_buf - 1] = '\0';
460 }
461
462 /*@observer@*/char *sm_context_bitfield(/*@out@*/ /*@returned@*/char *status,
463 U16 status_bits)
464 {
465 U16 index;
466
467 for (index = 0; index < (U16)SM_MAX_NSAPI_OFFSET; index++)
468 {
469 U16 nsapi = sm_index_to_nsapi(index);
470 status[index] = (sm_is_nsapi_in_nsapi_set(nsapi, status_bits) ? '1' : '0');
471 }
472 status[SM_MAX_NSAPI_OFFSET] = '\0';
473
474 return status;
475 }
476
477 void sm_dump_state(void)
478 {
479 int nsapi;
480 char req_addr[SM_SIZE_FORMATTED_IPv6_ADDR],
481 neg_addr[SM_SIZE_FORMATTED_IPv6_ADDR];
482 char context_status[SM_MAX_NSAPI_OFFSET + 1];
483
484 (void)TRACE_FUNCTION("sm_dump_state");
485
486 (void)TRACE_EVENT_P3("SM is active in a(n) %s network in %s RAT; SM is%s suspended",
487 (sm_get_current_nw_release() == PS_SGSN_98_OLDER ? "pre-R99" :
488 (sm_get_current_nw_release() == PS_SGSN_99_ONWARDS ? "R99" : "UNKNOWN")),
489 (sm_get_current_rat() == PS_RAT_GSM ? "GSM" :
490 (sm_get_current_rat() == PS_RAT_UMTS_FDD ? "UMTS" : "NONE")),
491 (sm_is_suspended() ? "" : " not"));
492 (void)TRACE_EVENT_P1("Context activation status: %s",
493 sm_context_bitfield(context_status, sm_data.sm_context_activation_status));
494
495 for (nsapi = (int)NAS_NSAPI_5; nsapi < NAS_SIZE_NSAPI; nsapi++)
496 {
497 struct T_SM_CONTEXT_DATA *context;
498
499 context = sm_get_context_data_from_nsapi(nsapi);
500 if (context != NULL)
501 {
502 char flags[256];
503
504 (void)TRACE_EVENT_P7("NSAPI%3d: [%08x] nsapi=%d, ti=%d, linked_ti=%d, "
505 "active_timer=%s, timeouts=%d",
506 nsapi, context, context->nsapi, context->ti,
507 context->linked_ti,
508 sm_timer_name(context->active_timer),
509 context->timeouts);
510 (void)TRACE_EVENT_P4(" sapi=%d, radio_prio=%d, pfi=%d (%s)",
511 context->sapi, context->radio_prio, context->pfi,
512 sm_pfi_name(context->pfi));
513
514 sm_flags_to_string(sm_context_flags, flags, (U16)context->flags);
515 (void)TRACE_EVENT_P2(" flags=0x%02x (%s)",
516 context->flags, flags);
517 (void)TRACE_EVENT_P1(" Network Control state: %s",
518 sm_network_control_state(context));
519 (void)TRACE_EVENT_P1(" Context Control state: %s",
520 sm_context_control_state(context));
521 (void)TRACE_EVENT_P1(" Context Deactivate Control state: %s",
522 sm_context_deactivate_control_state(context));
523 (void)TRACE_EVENT_P1(" User Plane Control state: %s",
524 sm_user_plane_control_state(context));
525 if (!sm_is_secondary(context))
526 {
527 sm_format_ip_address(&context->requested_address, req_addr);
528 sm_format_ip_address(&context->negotiated_address, neg_addr);
529 (void)TRACE_EVENT_P4(" PDP type=0x%02x (%s), "
530 "requested_address=%s, negotiated_address=%s",
531 context->pdp_type,
532 sm_pdp_type_name(context->pdp_type),
533 req_addr, neg_addr);
534 }
535 sm_qos_dump_qos(&context->minimum_qos, "minimum");
536 sm_qos_dump_qos(&context->requested_qos, "requested");
537 sm_qos_dump_qos(&context->accepted_qos, "negotiated");
538 if (!sm_is_secondary(context))
539 {
540 if (context->apn == NULL)
541 {
542 (void)TRACE_EVENT (" APN [ NULL ]");
543 } else {
544 char apn[103];
545 sm_format_apn(context->apn, apn);
546 (void)TRACE_EVENT_P2(" APN [%08x]: %s", context->apn, apn);
547 }
548 }
549 sm_debug_dump_tft(&context->active_tft);
550 } else {
551 (void)TRACE_EVENT_P1("NSAPI%3d: [ NULL ]", nsapi);
552 }
553 }
554 }
555 #endif /* DEBUG */
556
557 /*==== END OF FILE ==========================================================*/