FreeCalypso > hg > fc-tourmaline
comparison src/g23m-gprs/sm/sm_debug.c @ 1:fa8dc04885d8
src/g23m-*: import from Magnetite
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Fri, 16 Oct 2020 06:25:50 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:4e78acac3d88 | 1:fa8dc04885d8 |
|---|---|
| 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 ==========================================================*/ |
