FreeCalypso > hg > fc-magnetite
view src/g23m-gprs/llc/llc_f.c @ 366:042be096c669
configs/2092: FCHG enabled
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 31 Dec 2017 23:57:20 +0000 |
parents | 219afcfc6250 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : | Modul : +----------------------------------------------------------------------------- | Copyright 2002 Texas Instruments Berlin, AG | All rights reserved. | | This file is confidential and a trade secret of Texas | Instruments Berlin, AG | The receipt of or possession of this file does not convey | any rights to reproduce or disclose its contents or to | manufacture, use, or sell anything it may describe, in | whole, or in part, without the specific written consent of | Texas Instruments Berlin, AG. +----------------------------------------------------------------------------- | Purpose : Contains global functions of Logical Link Control (LLC) +----------------------------------------------------------------------------- */ #define LLC_F_C #define ENTITY_LLC /*==== INCLUDES =============================================================*/ #include "typedefs.h" /* to get Condat data types */ #include "vsi.h" /* to get a lot of macros */ #include "macdef.h" #include "gprs.h" #include "gsm.h" /* to get a lot of macros */ #include "cnf_llc.h" /* to get cnf-definitions */ #include "mon_llc.h" /* to get mon-definitions */ #include "prim.h" /* to get the definitions of used SAP and directions */ #include "llc.h" /* to get the global entity definitions */ #include "llc_par.h" /* to get the default values of the LLC paramters */ #include "llc_uf.h" /* to get the XID parameter definitions */ /*==== CONST ================================================================*/ /*==== LOCAL VARS ===========================================================*/ /*==== PRIVATE FUNCTIONS ====================================================*/ /*==== PUBLIC FUNCTIONS =====================================================*/ /* +------------------------------------------------------------------------------ | Function : llc_init_parameters +------------------------------------------------------------------------------ | Description : This procedure initialises the LLC layer parameters with | their default values as they are defined in LLC_PAR.H. | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void llc_init_parameters (void) { UBYTE incarnation; TRACE_FUNCTION ("llc_init_parameters"); llc_data->version = LLC_VERSION_ALL_SAPIS; llc_data->iov_ui = LLC_IOV_UI_ALL_SAPIS; llc_data->iov_i_base[IMAP(LL_SAPI_3)] = LLC_IOV_I_SAPI_3; llc_data->iov_i_base[IMAP(LL_SAPI_5)] = LLC_IOV_I_SAPI_5; llc_data->iov_i_base[IMAP(LL_SAPI_9)] = LLC_IOV_I_SAPI_9; llc_data->iov_i_base[IMAP(LL_SAPI_11)] = LLC_IOV_I_SAPI_11; /* * The LLC parameters for T200 are contained in T200 service data. */ llc_data->t200_base[UIMAP(LL_SAPI_1)].length = LLC_T200_SAPI_1; llc_data->t200_base[UIMAP(LL_SAPI_3)].length = LLC_T200_SAPI_3; llc_data->t200_base[UIMAP(LL_SAPI_5)].length = LLC_T200_SAPI_5; llc_data->t200_base[UIMAP(LL_SAPI_7)].length = LLC_T200_SAPI_7; llc_data->t200_base[UIMAP(LL_SAPI_9)].length = LLC_T200_SAPI_9; llc_data->t200_base[UIMAP(LL_SAPI_11)].length = LLC_T200_SAPI_11; /* * The LLC parameters for T201 are contained in T201 service data. * T201 is being set to the same values as T200 for all SAPIs. * <R.LLC.LLC_PAR.A.015> */ llc_data->n200_base[UIMAP(LL_SAPI_1)] = LLC_N200_SAPI_1; llc_data->n200_base[UIMAP(LL_SAPI_3)] = LLC_N200_SAPI_3; llc_data->n200_base[UIMAP(LL_SAPI_5)] = LLC_N200_SAPI_5; llc_data->n200_base[UIMAP(LL_SAPI_7)] = LLC_N200_SAPI_7; llc_data->n200_base[UIMAP(LL_SAPI_9)] = LLC_N200_SAPI_9; llc_data->n200_base[UIMAP(LL_SAPI_11)] = LLC_N200_SAPI_11; llc_data->n201_u_base[UIMAP(LL_SAPI_1)] = LLC_N201_U_SAPI_1; llc_data->n201_u_base[UIMAP(LL_SAPI_3)] = LLC_N201_U_SAPI_3; llc_data->n201_u_base[UIMAP(LL_SAPI_5)] = LLC_N201_U_SAPI_5; llc_data->n201_u_base[UIMAP(LL_SAPI_7)] = LLC_N201_U_SAPI_7; llc_data->n201_u_base[UIMAP(LL_SAPI_9)] = LLC_N201_U_SAPI_9; llc_data->n201_u_base[UIMAP(LL_SAPI_11)] = LLC_N201_U_SAPI_11; llc_data->n201_i_base[IMAP(LL_SAPI_3)] = LLC_N201_I_SAPI_3; llc_data->n201_i_base[IMAP(LL_SAPI_5)] = LLC_N201_I_SAPI_5; llc_data->n201_i_base[IMAP(LL_SAPI_9)] = LLC_N201_I_SAPI_9; llc_data->n201_i_base[IMAP(LL_SAPI_11)] = LLC_N201_I_SAPI_11; llc_data->md_base[IMAP(LL_SAPI_3)] = LLC_MD_SAPI_3; llc_data->md_base[IMAP(LL_SAPI_5)] = LLC_MD_SAPI_5; llc_data->md_base[IMAP(LL_SAPI_9)] = LLC_MD_SAPI_9; llc_data->md_base[IMAP(LL_SAPI_11)] = LLC_MD_SAPI_11; llc_data->mu_base[IMAP(LL_SAPI_3)] = LLC_MU_SAPI_3; llc_data->mu_base[IMAP(LL_SAPI_5)] = LLC_MU_SAPI_5; llc_data->mu_base[IMAP(LL_SAPI_9)] = LLC_MU_SAPI_9; llc_data->mu_base[IMAP(LL_SAPI_11)] = LLC_MU_SAPI_11; llc_data->kd_base[IMAP(LL_SAPI_3)] = LLC_KD_SAPI_3; llc_data->kd_base[IMAP(LL_SAPI_5)] = LLC_KD_SAPI_5; llc_data->kd_base[IMAP(LL_SAPI_9)] = LLC_KD_SAPI_9; llc_data->kd_base[IMAP(LL_SAPI_11)] = LLC_KD_SAPI_11; llc_data->ku_base[IMAP(LL_SAPI_3)] = LLC_KU_SAPI_3; llc_data->ku_base[IMAP(LL_SAPI_5)] = LLC_KU_SAPI_5; llc_data->ku_base[IMAP(LL_SAPI_9)] = LLC_KU_SAPI_9; llc_data->ku_base[IMAP(LL_SAPI_11)] = LLC_KU_SAPI_11; /* * Reset all OCs for unacknowledged transfer. */ for (incarnation = 0; incarnation < MAX_SAPI_INC; incarnation++) { llc_data->sapi_base[incarnation].oc_ui_tx = 0L; llc_data->sapi_base[incarnation].oc_ui_rx = 0L; } return; } /* llc_init_parameters() */ /* +------------------------------------------------------------------------------ | Function : llc_get_ffs_data +------------------------------------------------------------------------------ | Description : Load configured LLC parameter from FFS. In case of _SIMULATION_ | only default values are returned. | | Parameters : type - XID Paramter type | sapi_array_index - Array index of Sapi !!! | +------------------------------------------------------------------------------ */ LOCAL USHORT llc_get_ffs_data (UBYTE type, UBYTE sapi_array_index) { switch (type) { #ifdef _SIMULATION_ case XID_T200: if (llc_data->ffs_xid.t200[sapi_array_index].valid) return llc_data->ffs_xid.t200[sapi_array_index].value; /* 50 = 5 sec !!! */ else return (USHORT)INT2XID(llc_data->t200_base[sapi_array_index].length); case XID_N200: if (llc_data->ffs_xid.n200[sapi_array_index].valid) return (USHORT)llc_data->ffs_xid.n200[sapi_array_index].value; else return (USHORT)llc_data->n200_base[sapi_array_index]; case XID_MD: if (llc_data->ffs_xid.md[sapi_array_index].valid) return llc_data->ffs_xid.md[sapi_array_index].value; else return llc_data->md_base[sapi_array_index]; case XID_MU: if (llc_data->ffs_xid.mu[sapi_array_index].valid) return (USHORT)llc_data->ffs_xid.mu[sapi_array_index].value; else return (USHORT)llc_data->mu_base[sapi_array_index]; case XID_N201_U: if (llc_data->ffs_xid.n201_u[sapi_array_index].valid) return llc_data->ffs_xid.n201_u[sapi_array_index].value; else return llc_data->n201_u_base[sapi_array_index]; case XID_N201_I: if (llc_data->ffs_xid.n201_i[sapi_array_index].valid) return llc_data->ffs_xid.n201_i[sapi_array_index].value; else return llc_data->n201_i_base[sapi_array_index]; case XID_KD: if (llc_data->ffs_xid.kd[sapi_array_index].valid) return (USHORT)llc_data->ffs_xid.kd[sapi_array_index].value; else return (USHORT)llc_data->kd_base[sapi_array_index]; case XID_KU: if (llc_data->ffs_xid.ku[sapi_array_index].valid) return (USHORT)llc_data->ffs_xid.ku[sapi_array_index].value; else return (USHORT)llc_data->ku_base[sapi_array_index]; #else case XID_T200: return (USHORT)INT2XID(llc_data->t200_base[sapi_array_index].length); case XID_N200: return (USHORT)llc_data->n200_base[sapi_array_index]; /* case XID_N201_U: return (USHORT)llc_data->n201_u_base[sapi_array_index]; */ /* case XID_KD: return (USHORT)llc_data->kd_base[sapi_array_index]; */ /* case XID_KU: return (USHORT)llc_data->ku_base[sapi_array_index]; */ case XID_N201_I: return (USHORT)N201_I_SUPPORTED; case XID_N201_U: return (USHORT)N201_U_SUPPORTED; case XID_KD: return (USHORT)KD_KD_SUPPORTED; case XID_KU: return (USHORT)KD_KU_SUPPORTED; case XID_MD: return (USHORT)KD_MD_SUPPORTED; case XID_MU: return (USHORT)KD_MU_SUPPORTED; #endif /* _SIMULATION_ */ default: TRACE_ERROR ("Illegal FFS parameter used"); return 0; } } /* llc_get_ffs_data */ /* +------------------------------------------------------------------------------ | Function : llc_init_requested_xid +------------------------------------------------------------------------------ | Description : Fill in requested XID parameters into requested_xid structure | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void llc_init_requested_xid (void) { UBYTE u_inc, i_inc, sapi; USHORT requested_value; for (u_inc = 0; u_inc < ACKNOWLEDGED_INC; u_inc++) { llc_data->requested_l3_xid_base[u_inc].valid = FALSE; } for (sapi = LL_SAPI_1; sapi <= LL_SAPI_11; sapi += 2) { u_inc = UIMAP(sapi); llc_data->u_base[u_inc].requested_xid.version.valid = FALSE; llc_data->u_base[u_inc].requested_xid.iov_ui.valid = FALSE; llc_data->u_base[u_inc].requested_xid.iov_i.valid = FALSE; llc_data->u_base[u_inc].requested_xid.reset.valid = FALSE; llc_data->u_base[u_inc].requested_xid.t200.valid = FALSE; llc_data->u_base[u_inc].requested_xid.n200.valid = FALSE; llc_data->u_base[u_inc].requested_xid.n201_u.valid = FALSE; llc_data->u_base[u_inc].requested_xid.n201_i.valid = FALSE; llc_data->u_base[u_inc].requested_xid.kd.valid = FALSE; llc_data->u_base[u_inc].requested_xid.ku.valid = FALSE; llc_data->u_base[u_inc].requested_xid.md.valid = FALSE; llc_data->u_base[u_inc].requested_xid.mu.valid = FALSE; requested_value = llc_get_ffs_data (XID_T200, u_inc); if (requested_value != (USHORT)INT2XID(llc_data->t200_base[u_inc].length)) { llc_data->u_base[u_inc].requested_xid.t200.valid = TRUE; llc_data->u_base[u_inc].requested_xid.t200.value = requested_value; } requested_value = llc_get_ffs_data (XID_N200, u_inc); if (requested_value != llc_data->n200_base[u_inc]) { llc_data->u_base[u_inc].requested_xid.n200.valid = TRUE; llc_data->u_base[u_inc].requested_xid.n200.value = (UBYTE)requested_value; } requested_value = llc_get_ffs_data (XID_N201_U, u_inc); if (requested_value != llc_data->n201_u_base[u_inc]) { llc_data->u_base[u_inc].requested_xid.n201_u.valid = TRUE; llc_data->u_base[u_inc].requested_xid.n201_u.value = requested_value; } if ((sapi != LL_SAPI_1) && (sapi != LL_SAPI_7)) { i_inc = (UBYTE)IMAP(sapi); requested_value = llc_get_ffs_data (XID_N201_I, i_inc); if (requested_value != llc_data->n201_i_base[i_inc]) { llc_data->u_base[u_inc].requested_xid.n201_i.valid = TRUE; llc_data->u_base[u_inc].requested_xid.n201_i.value = requested_value; } requested_value = llc_get_ffs_data (XID_MD, i_inc); if (requested_value != llc_data->md_base[i_inc]) { llc_data->u_base[u_inc].requested_xid.md.valid = TRUE; llc_data->u_base[u_inc].requested_xid.md.value = requested_value; } requested_value = llc_get_ffs_data (XID_MU, i_inc); if (requested_value != llc_data->mu_base[i_inc]) { llc_data->u_base[u_inc].requested_xid.mu.valid = TRUE; llc_data->u_base[u_inc].requested_xid.mu.value = requested_value; } requested_value = llc_get_ffs_data (XID_KD, i_inc); if (requested_value != llc_data->kd_base[i_inc]) { llc_data->u_base[u_inc].requested_xid.kd.valid = TRUE; llc_data->u_base[u_inc].requested_xid.kd.value = (UBYTE)requested_value; } requested_value = llc_get_ffs_data (XID_KU, i_inc); if (requested_value != llc_data->ku_base[i_inc]) { llc_data->u_base[u_inc].requested_xid.ku.valid = TRUE; llc_data->u_base[u_inc].requested_xid.ku.value = (UBYTE)requested_value; } } } } /* llc_init_requested_xid() */ /* +------------------------------------------------------------------------------ | Function : llc_init_requested_xid_sapi +------------------------------------------------------------------------------ | Description : Fill in requested XID parameters into requested_xid structure | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void llc_init_requested_xid_sapi (T_SAPI sapi) { UBYTE u_inc, i_inc; USHORT requested_value; u_inc = UIMAP(sapi); llc_data->u_base[u_inc].requested_xid.t200.valid = FALSE; llc_data->u_base[u_inc].requested_xid.n200.valid = FALSE; llc_data->u_base[u_inc].requested_xid.n201_u.valid = FALSE; llc_data->u_base[u_inc].requested_xid.n201_i.valid = FALSE; llc_data->u_base[u_inc].requested_xid.kd.valid = FALSE; llc_data->u_base[u_inc].requested_xid.ku.valid = FALSE; llc_data->u_base[u_inc].requested_xid.md.valid = FALSE; llc_data->u_base[u_inc].requested_xid.mu.valid = FALSE; requested_value = llc_get_ffs_data (XID_T200, u_inc); if (requested_value != (USHORT)INT2XID(llc_data->t200_base[u_inc].length)) { llc_data->u_base[u_inc].requested_xid.t200.valid = TRUE; llc_data->u_base[u_inc].requested_xid.t200.value = requested_value; } requested_value = llc_get_ffs_data (XID_N200, u_inc); if (requested_value != llc_data->n200_base[u_inc]) { llc_data->u_base[u_inc].requested_xid.n200.valid = TRUE; llc_data->u_base[u_inc].requested_xid.n200.value = (UBYTE)requested_value; } requested_value = llc_get_ffs_data (XID_N201_U, u_inc); if (requested_value != llc_data->n201_u_base[u_inc]) { llc_data->u_base[u_inc].requested_xid.n201_u.valid = TRUE; llc_data->u_base[u_inc].requested_xid.n201_u.value = requested_value; } if ((sapi != LL_SAPI_1) && (sapi != LL_SAPI_7)) { i_inc = (UBYTE)IMAP(sapi); requested_value = llc_get_ffs_data (XID_N201_I, i_inc); if (requested_value != llc_data->n201_i_base[i_inc]) { llc_data->u_base[u_inc].requested_xid.n201_i.valid = TRUE; llc_data->u_base[u_inc].requested_xid.n201_i.value = requested_value; } requested_value = llc_get_ffs_data (XID_MD, i_inc); if (requested_value != llc_data->md_base[i_inc]) { llc_data->u_base[u_inc].requested_xid.md.valid = TRUE; llc_data->u_base[u_inc].requested_xid.md.value = requested_value; } requested_value = llc_get_ffs_data (XID_MU, i_inc); if (requested_value != llc_data->mu_base[i_inc]) { llc_data->u_base[u_inc].requested_xid.mu.valid = TRUE; llc_data->u_base[u_inc].requested_xid.mu.value = requested_value; } requested_value = llc_get_ffs_data (XID_KD, i_inc); if (requested_value != llc_data->kd_base[i_inc]) { llc_data->u_base[u_inc].requested_xid.kd.valid = TRUE; llc_data->u_base[u_inc].requested_xid.kd.value = (UBYTE)requested_value; } requested_value = llc_get_ffs_data (XID_KU, i_inc); if (requested_value != llc_data->ku_base[i_inc]) { llc_data->u_base[u_inc].requested_xid.ku.valid = TRUE; llc_data->u_base[u_inc].requested_xid.ku.value = (UBYTE)requested_value; } } } /* llc_init_requested_xid_sapi() */ /* +------------------------------------------------------------------------------ | Function : llc_generate_input +------------------------------------------------------------------------------ | Description : This procedure calculates the frame-dependent input for | UI_FRAMES / I_FRAMES. S_FRAMES are treated like I_FRAMES. | Parameter direction must be one of | CCI_DIRECTION_UPLINK/DOWNLINK. The input is generated | according to section A.2.1 in GSM 04.64, and written to | paramete input. This procedure is called from services | TX and RX. | | Parameters : sapi - valid SAPI number | frame_type - indicates acknowledged/unacknowledged frames | lfn - LLC frame number | direction - CCI_DIRECTION_UPLINK/CCI_DIRECTION_DOWNLINK | cipher_input - generated ciphering input | +------------------------------------------------------------------------------ */ GLOBAL void llc_generate_input (UBYTE sapi, T_PDU_TYPE frame_type, T_FRAME_NUM lfn, ULONG *cipher_input, ULONG oc) { ULONG sx; TRACE_FUNCTION ("llc_generate_input"); /* * According to 04.64, Annex A.2.1: * SX = 2exp27 * SAPI + 2exp31 */ sx = 134217728 * sapi + 2147483648; if ((frame_type EQ I_FRAME) OR (frame_type EQ S_FRAME)) { /* * According to 04.64, Annex A.2.1: * Input = ((IOV-I + LFN + OC) modulo 2exp32 */ *cipher_input = (ULONG)(*(llc_data->iov_i) + lfn + oc); } else /* unacknowledged mode */ { /* * According to 04.64, Annex A.2.1: * Input = ((IOV-UI XOR SX) + LFN + OC) modulo 2exp32 */ *cipher_input = (ULONG)((llc_data->iov_ui ^ sx) + lfn + oc); } return; } /* llc_generate_input() */ /* +------------------------------------------------------------------------------ | Function : llc_build_crc24 +------------------------------------------------------------------------------ | Description : This procedure builds a CRC24 checksum according to RFC2440, | which is needed by LLC to build and check the Frame Check | Sequence (FCS) which is included in each frame. | | Parameters : octets - a valid pointer to the frame contents | len - number of valid octets | +------------------------------------------------------------------------------ */ /* * Precomputed table for polynomial : 0x00ad85dd (high term in LSB) * 24-bit masks are packed in 16-bits words * */ const USHORT a_fcs24_tab_rev_packed[384] = { 0x0000, 0x7600, 0xd6a7, 0x4557, 0x21f6, 0x20e2, 0x8115, 0x63b7, 0x6126, 0xc442, 0x3441, 0x9763, 0x0991, 0xe734, 0xe2ae, 0x4cc6, 0xb0c2, 0x14eb, 0x8884, 0xf283, 0x552f, 0xcdd3, 0xa575, 0xa36a, 0x1322, 0x5468, 0xbeb4, 0x5675, 0x039e, 0x48f1, 0x9237, 0x41df, 0x0935, 0xd760, 0x1629, 0xff70, 0x1ab3, 0xc55c, 0x8abd, 0x5fe4, 0x92aa, 0x7cf8, 0x9ba6, 0xd0eb, 0x3d3c, 0xdef1, 0x871d, 0xcb79, 0x2644, 0x32d0, 0x0681, 0x6313, 0x6526, 0xf0c4, 0xa751, 0x2767, 0xb100, 0xe206, 0x7091, 0x4745, 0x2fd5, 0xa3e4, 0x3288, 0x6a82, 0xf412, 0xc4cd, 0xaec0, 0xb653, 0x8509, 0xeb97, 0xe1a5, 0x734c, 0x3566, 0x10b8, 0x6e92, 0x7031, 0x474e, 0x98d7, 0xb473, 0x050f, 0xd913, 0xf124, 0x52f9, 0x2f56, 0x3cf7, 0x818c, 0x5a9b, 0x79a0, 0xd67a, 0xacde, 0xbde2, 0x943b, 0xed1a, 0xf8b5, 0xc3cd, 0x1b5f, 0x4733, 0x45fb, 0x2de0, 0x0264, 0x120d, 0xdba5, 0xc626, 0x504c, 0x9a61, 0x8371, 0x07ba, 0x6c24, 0x4ea2, 0xd4cf, 0x19e9, 0x0bf5, 0x8339, 0xefac, 0xcfb7, 0xc178, 0xae68, 0x8ae0, 0x968e, 0x582d, 0x5411, 0x6793, 0x45f3, 0x1146, 0x3065, 0xb3b6, 0xd504, 0x7224, 0xf272, 0x9053, 0x25d2, 0x0437, 0x5d80, 0xf6a7, 0x71fa, 0x18d7, 0xa151, 0x87bf, 0xdc95, 0xe310, 0xc67b, 0x99c2, 0xb4e6, 0x303e, 0x6177, 0x012b, 0xfdc6, 0x2420, 0x56dd, 0x0b83, 0xe062, 0x149c, 0x4a47, 0xa535, 0x436a, 0xbc02, 0x68e6, 0x901f, 0xc9cf, 0x2db1, 0xc7e9, 0x3f8a, 0xe9f3, 0x85a8, 0x7e4e, 0xaca4, 0xd25e, 0x880b, 0x7255, 0x2343, 0x95d5, 0x3702, 0x74b5, 0x6390, 0xf340, 0x36f4, 0x2254, 0xb617, 0x6102, 0xd411, 0x7bc4, 0xb277, 0xa1dc, 0x3e93, 0xe581, 0x5799, 0xfad1, 0xa7c0, 0x165d, 0xbf86, 0xf036, 0xe018, 0x85dd, 0xabad, 0x7b22, 0xc08a, 0xfc5b, 0x8d67, 0x04c8, 0xbe1a, 0xcca3, 0x419f, 0xe9ec, 0x3ae6, 0x8c4c, 0x3a99, 0x4f2b, 0xc91b, 0x6d6f, 0xb96e, 0x0d59, 0x2f2e, 0xf8aa, 0x480e, 0x78d8, 0x0eef, 0x96ff, 0x89c5, 0x1331, 0xd3a8, 0xde33, 0xe574, 0x17ea, 0x9c72, 0xa4b0, 0x52bd, 0xcb84, 0x52f5, 0x9f6e, 0x18f1, 0x2738, 0xda39, 0x4f07, 0xd17d, 0x1e7b, 0x0d46, 0x90b9, 0x5b2c, 0x5ab0, 0x66fc, 0xa399, 0xef7d, 0xab04, 0xe6ce, 0xb88b, 0x5d41, 0x228c, 0xfaca, 0x1c85, 0x67db, 0xad3c, 0xeac0, 0xaa08, 0x7e49, 0x9f0d, 0xef5f, 0x29bf, 0x6948, 0x2b1d, 0x6bfe, 0x288c, 0x6e4a, 0x3c08, 0xdec9, 0xb0bb, 0xcd15, 0xc317, 0xf5ec, 0x9ae3, 0x3552, 0x31ae, 0xd8a2, 0x7496, 0x74f9, 0x8f54, 0x82d3, 0xb92a, 0x5c21, 0xf71e, 0xfc7d, 0x0bd7, 0x015b, 0x383f, 0x4996, 0x409f, 0x7d68, 0x1e60, 0xb6da, 0xc2ee, 0x9856, 0x8065, 0x87b9, 0xcfa0, 0x7620, 0x43fb, 0x8de1, 0x37e4, 0x06ac, 0xda17, 0xc1a1, 0xcb7f, 0x0962, 0xb46c, 0x8e28, 0x5e94, 0x4229, 0x4a6a, 0x1cd5, 0x03ed, 0x0f3d, 0x4b23, 0xf5a8, 0xd1cc, 0xba3e, 0xe876, 0x949b, 0xedc8, 0x1e33, 0x50d9, 0xaf89, 0x5ff7, 0x158e, 0xf87f, 0xa9b2, 0xd85d, 0x2b0a, 0xdc7f, 0x9d0a, 0x7cfc, 0x2a3a, 0x5948, 0x3ebd, 0x6bfe, 0x1c1f, 0x694b, 0x9dbb, 0xe4aa, 0xdc86, 0x5043, 0xa1fd, 0x8b70, 0xa606, 0x65bf, 0xc931, 0xe7c2, 0x20e8, 0x9ec7, 0x1187, 0xed3b, 0x4db2, 0x644a, 0xa86c, 0x1a44, 0x920f, 0x6c2e, 0x5805, 0xd3cb, 0x2979, 0x0ff3, 0x258e, 0xf788, 0xfeee, 0x3850, 0xb2df, 0xa918, 0xce15, 0x769d, 0xeb59, 0x8fd1, 0x33ca, 0xbcaf, 0x7994, 0xfe19, 0x6fda, 0x0c59, 0xbb4e, 0x382c, 0xfa1c, 0x7f0c, 0x7a6d, 0xbbd8, 0x3a5b, 0x2d9b, 0x4d9d }; /****************************************************************************** * * FUNCTION NAME: f_crc24_tab * * The function compute the 24-bit FCS and is using table for it * * ARGUMENT LIST: * * Argument Type IO Description * ------------- -------- -- --------------------------------------------- * data_p T_BYTE* I Pointer on the input buffer * d_length T_UINT16 I Number of bytes to process * d_l_crc_init T_UINT16 I Init value of the CRC * * RETURN VALUE: * Argument Type Description * ------------- -------- --------------------------------------------- * d_l_crc T_UINT32 24-bit FCS stored in a 32-bit word * *****************************************************************************/ GLOBAL ULONG llc_build_crc24 (UBYTE *d_data_p, USHORT d_length) { /* GLOBAL VARIABLES: * * Variables Type IO Description * ------------- -------- -- ------------------------------------------- * none */ /* LOCAL VARIABLES: * * Variables Type Description * ------------- ------- ---------------------------------------------- * d_l_crc T_UINT32 24-bit FCS stored in a 32-bit word * d_l_tab_res T_UINT32 FCS mask extracted from the table * d_l_tab_index T_UINT32 Index of the FCS mask into the table * d_byte_msb T_UINT16 Intermediate variable used to know the position * FCSof the 24-bit FCS into two 16-bits words */ ULONG d_l_crc, d_l_tab_res, d_l_tab_index; USHORT d_byte_msb; d_l_crc = 0x00ffffff; do { /* Most efficient C implementation with 32-bits tables but require more d_data rom */ /* d_l_crc = (d_l_crc >> 8) ^ a_fcs24_tab_rev[(d_l_crc ^ *d_data_p++) & 0xff]; */ /* Details very close to the ASM implementation */ d_l_tab_index = (d_l_crc ^ *d_data_p++) & 0x0ff; d_l_crc >>= 8; if(d_l_tab_index & 0x01) d_byte_msb = 1; else d_byte_msb = 0; d_l_tab_index *= 3; d_l_tab_index >>= 1; d_l_crc &= 0x0000ffff; /* Replace the code in comment below */ d_l_tab_res = a_fcs24_tab_rev_packed[d_l_tab_index]; d_l_tab_res |= (a_fcs24_tab_rev_packed[d_l_tab_index+1] << 16); if(d_byte_msb == 1) d_l_tab_res >>= 8; d_l_crc ^= d_l_tab_res; } while (--d_length); d_l_crc = (~d_l_crc) & 0x00ffffff; return (d_l_crc); } /* llc_build_crc24() */ /* +------------------------------------------------------------------------------ | Function : llc_xid_value_acceptable +------------------------------------------------------------------------------ | Description : This procedure checks if the value of the XID parameter for | the given SAPI is acceptable, or not. The return value is TRUE | for an accepted value, and FALSE for an unaccepted value. | | Parameters : sapi - SAPI number | xid_parameter - XID parameter (defined in llc_uf.h) | xid_value - value of XID parameter (actually UBYTE/USHORT/ | ULONG, depending on the parameter) | +------------------------------------------------------------------------------ */ GLOBAL BOOL llc_xid_value_acceptable (UBYTE sapi, UBYTE xid_parameter, ULONG xid_value) { BOOL rc; UBYTE u_inc, i_inc; TRACE_FUNCTION ("llc_xid_value_acceptable"); /* * Preset rc in case of unknown XID parameters or unknown SAPI values. */ rc = FALSE; u_inc = UIMAP(sapi); i_inc = IMAP(sapi); /* * Accept only possible (valid) values for now (defined in llc_uf.h). */ switch (xid_parameter) { case XID_VERSION: if (xid_value EQ LLC_VERSION_ALL_SAPIS) { rc = TRUE; TRACE_EVENT ("Version value accepted"); } else { TRACE_EVENT ("Version value NOT accepted"); } break; case XID_IOV_UI: /* * Must not be checked, ignored. */ TRACE_EVENT ("IOV-UI values are not checked."); break; case XID_IOV_I: /* * Must not be checked, ignored. */ TRACE_EVENT ("IOV-I values are not checked."); break; case XID_T200: switch (sapi) { case LL_SAPI_1: case LL_SAPI_3: case LL_SAPI_5: case LL_SAPI_7: case LL_SAPI_9: case LL_SAPI_11: if ( (xid_value >= (llc_data->u_base[u_inc].requested_xid.t200.valid ? llc_get_ffs_data(XID_T200, u_inc): XID_T200_MIN)) AND (xid_value <= XID_T200_MAX) ) { rc = TRUE; TRACE_EVENT ("T200 value accepted"); } else { TRACE_EVENT ("T200 value NOT accepted"); } break; default: TRACE_ERROR ("invalid SAPI value for T200"); break; } break; case XID_N200: switch (sapi) { case LL_SAPI_1: case LL_SAPI_3: case LL_SAPI_5: case LL_SAPI_7: case LL_SAPI_9: case LL_SAPI_11: if ( (xid_value >= (llc_data->u_base[u_inc].requested_xid.n200.valid ? llc_get_ffs_data(XID_N200, u_inc): XID_N200_MIN)) AND (xid_value <= XID_N200_MAX) ) { rc = TRUE; TRACE_EVENT ("N200 value accepted"); } else { TRACE_EVENT ("N200 value NOT accepted"); } break; default: TRACE_ERROR ("invalid SAPI value for N200"); break; } break; case XID_N201_U: switch (sapi) { case LL_SAPI_1: case LL_SAPI_3: case LL_SAPI_5: case LL_SAPI_7: case LL_SAPI_9: case LL_SAPI_11: if ( (xid_value >= (USHORT)XID_N201_U_MIN) AND (xid_value <= (llc_data->u_base[u_inc].requested_xid.n201_u.valid ? llc_get_ffs_data(XID_N201_U, u_inc): XID_N201_U_MAX)) ) { rc = TRUE; TRACE_EVENT ("N201-U value accepted"); } else { TRACE_EVENT ("N201-U value NOT accepted"); } break; default: TRACE_ERROR ("invalid SAPI value for N201-U"); break; } break; case XID_N201_I: switch (sapi) { case LL_SAPI_3: case LL_SAPI_5: case LL_SAPI_9: case LL_SAPI_11: if ( (xid_value >= XID_N201_I_MIN) AND (xid_value <= (llc_data->u_base[u_inc].requested_xid.n201_i.valid ? llc_get_ffs_data(XID_N201_I, i_inc): XID_N201_I_MAX)) ) { rc = TRUE; TRACE_EVENT ("N201-I value accepted"); } else { TRACE_EVENT ("N201-I value NOT accepted"); } break; default: TRACE_ERROR ("invalid SAPI value for N201-I"); break; } break; case XID_MD: switch (sapi) { case LL_SAPI_3: case LL_SAPI_5: case LL_SAPI_9: case LL_SAPI_11: if ( (xid_value == XID_MD_OFF) OR ((xid_value >= XID_MD_MIN) AND (xid_value <= (llc_data->u_base[u_inc].requested_xid.md.valid ? llc_get_ffs_data(XID_MD, i_inc): XID_MD_MAX)) )) { rc = TRUE; TRACE_EVENT ("mD value accepted"); } else { TRACE_EVENT ("mD value NOT accepted"); } break; default: TRACE_ERROR ("invalid SAPI value for mD"); break; } break; case XID_MU: switch (sapi) { case LL_SAPI_3: case LL_SAPI_5: case LL_SAPI_9: case LL_SAPI_11: if ( (xid_value == XID_MU_OFF) OR ((xid_value >= XID_MU_MIN) AND (xid_value <= (llc_data->u_base[u_inc].requested_xid.mu.valid ? llc_get_ffs_data(XID_MU, i_inc): XID_MU_MAX)) )) { rc = TRUE; TRACE_EVENT ("mU value accepted"); } else { TRACE_EVENT ("mU value NOT accepted"); } break; default: TRACE_ERROR ("invalid SAPI value for mU"); break; } break; case XID_KD: switch (sapi) { case LL_SAPI_3: case LL_SAPI_5: case LL_SAPI_9: case LL_SAPI_11: if ( (xid_value >= XID_KD_MIN) AND (xid_value <= (llc_data->u_base[u_inc].requested_xid.kd.valid ? llc_get_ffs_data(XID_KD, i_inc): XID_KD_MAX)) ) { rc = TRUE; TRACE_EVENT ("kD value accepted"); } else { TRACE_EVENT ("kD value NOT accepted"); } break; default: TRACE_ERROR ("invalid SAPI value for kD"); break; } break; case XID_KU: switch (sapi) { case LL_SAPI_3: case LL_SAPI_5: case LL_SAPI_9: case LL_SAPI_11: if ( (xid_value >= XID_KU_MIN) AND (xid_value <= (llc_data->u_base[u_inc].requested_xid.ku.valid ? llc_get_ffs_data(XID_KU, i_inc): XID_KU_MAX)) ) { rc = TRUE; TRACE_EVENT ("kU value accepted"); } else { TRACE_EVENT ("kU value NOT accepted"); } break; default: TRACE_ERROR ("invalid SAPI value for kU"); break; } break; case XID_LAYER_3: /* * Must not be checked, ignored. */ TRACE_EVENT ("Layer-3 values are not checked."); break; case XID_RESET: /* * Must not be checked, ignored. */ TRACE_EVENT ("Reset is not checked."); break; default: TRACE_ERROR ("unknown XID parameter"); break; } return rc; } /* llc_xid_value_acceptable() */ /* +------------------------------------------------------------------------------ | Function : llc_palloc_desc +------------------------------------------------------------------------------ | Description : This function allocates a descriptor of type T_DESC3 | | Parameters : len - length of descriptor | : offset offset of descriptor | | Return : poniter to T_DESC3 | +------------------------------------------------------------------------------ */ #ifdef LL_DESC GLOBAL T_desc3* llc_palloc_desc( U16 len, U16 offset) { T_desc3 *desc3; U8 *buffer; TRACE_FUNCTION ("llc_palloc_desc"); MALLOC (desc3, (USHORT)(sizeof(T_desc3))); MALLOC (buffer, len + offset); desc3->next = NULL; desc3->offset = offset; desc3->len = len; desc3->buffer = (ULONG)buffer; return desc3; } /* +------------------------------------------------------------------------------ | Function : llc_cl_desc3_free +------------------------------------------------------------------------------ | Description : Frees the descriptor connected to the desc3 descriptor. This | free will when applicable cause the frame to decrease a | connected counter attached to the allocation or really free | the memory in case the counter is zero. | | Parameters : T_desc3* pointer to desc3 descriptor. | +------------------------------------------------------------------------------ */ GLOBAL void llc_cl_desc3_free(T_desc3* p_desc3) { T_desc3* help; while(p_desc3) { help = (T_desc3*)p_desc3->next; MFREE(p_desc3->buffer); MFREE(p_desc3); p_desc3 = help; } } #endif /* LL_DESC */ #ifndef TI_PS_OP_CIPH_DRIVER /* +------------------------------------------------------------------------------ | Function : llc_fbs_init +------------------------------------------------------------------------------ | Description : The function fbs_init() initializes service | variablaes | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL void llc_fbs_init ( void ) { TRACE_FUNCTION( "llc_fbs_init" ); llc_data->fbs.initialized = FALSE; } #endif /* +------------------------------------------------------------------------------ | Function : llc_copy_ul_data_to_list +------------------------------------------------------------------------------ | Description : The function copy_data_to_list copies the length and the pointer | of the linked descriptor list to the in_data_list. | It is used in uplink direction | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void llc_copy_ul_data_to_list ( T_CCI_CIPHER_DESC_REQ *cipher_req, T_CIPH_in_data_list *in_data_list ) { T_desc3* cipher_desc; U16 cnt = 0; T_CIPH_in_data* in_data_array; /* * Count the number of descriptors in the incoming desc_list */ cipher_desc = (T_desc3*)cipher_req->desc_list3.first; while (cipher_desc){ cipher_desc = (T_desc3*)cipher_desc->next; cnt ++; } /* * Allocate an array for T_CIPH_in_data_list */ MALLOC(in_data_array,(sizeof(T_CIPH_in_data) * cnt)); in_data_list->ptr_in_data = in_data_array; /* * Copy buf and len parameters from descriptors to the in_data's */ cipher_desc = (T_desc3*)cipher_req->desc_list3.first; cnt = 0; while (cipher_desc) { in_data_list->ptr_in_data[cnt].buf = (U32)&((U8*)cipher_desc->buffer)[cipher_desc->offset]; in_data_list->ptr_in_data[cnt].len = cipher_desc->len; cipher_desc = (T_desc3*)cipher_desc->next; cnt++; } in_data_list->c_in_data = cnt; } /* llc_copy_ul_data_to_list */ /* +------------------------------------------------------------------------------ | Function : llc_copy_dl_data_to_list +------------------------------------------------------------------------------ | Description : The function copy_data_to_list copies the length and the pointer | of the linked descriptor list to the in_data_list. | It is used in downlink direction | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void llc_copy_dl_data_to_list ( T_CCI_DECIPHER_REQ *decipher_req, T_CIPH_in_data_list *in_data_list ) { T_desc* decipher_desc; T_CIPH_in_data* in_data_array; USHORT cnt = 0; /* * Count the number of descriptors in the incoming desc_list */ decipher_desc = (T_desc*)decipher_req->desc_list.first; while (decipher_desc){ decipher_desc = (T_desc*)decipher_desc->next; cnt ++; } /* * Allocate an array of for T_CIPH_in_data */ MALLOC(in_data_array, (sizeof(T_CIPH_in_data) * cnt)); in_data_list->ptr_in_data = in_data_array; /* * Copy buf and len parameters from descriptors to the in_data's */ decipher_desc = (T_desc*)decipher_req->desc_list.first; cnt = 0; while (decipher_desc) { in_data_list->ptr_in_data[cnt].buf = (U32)decipher_desc->buffer; in_data_list->ptr_in_data[cnt].len = decipher_desc->len; decipher_desc = (T_desc*)decipher_desc->next; cnt++; } in_data_list->c_in_data = cnt; } /* llc_copy_dl_data_to_list */ /* +------------------------------------------------------------------------------ | Function : llc_fbs_enable_cci_info_trace +------------------------------------------------------------------------------ | Description : The llc_fbs_enable_cci_info_trace sets the variable | llc_data->fbs.cci_info_trace to TRUE | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL void llc_fbs_enable_cci_info_trace ( void ) { TRACE_FUNCTION( "llc_fbs_enable_cci_info_trace" ); llc_data->fbs.cci_info_trace = TRUE; } #ifdef LLC_TRACE_CIPHERING /* +------------------------------------------------------------------------------ | Function : llc_trace_desc_list3_content +------------------------------------------------------------------------------ | Description : traces content of a desc3 descriptor list | | Parameters : desc_list3 descriptor list | +------------------------------------------------------------------------------ */ GLOBAL void llc_trace_desc_list3_content(T_desc_list3 desc_list3) { U16 current_pos = 0; U16 dif; U16 data_len = 0; /* The length of the data to be traced including data offset */ U8* p_data = NULL; /* Pointer to byte data element */ T_desc3* p_desc3 = (T_desc3*)desc_list3.first; /* Pointer to the actual desc3 descriptor element */ while(p_desc3 != NULL) { current_pos = p_desc3->offset; dif=0; p_data = (U8*)p_desc3->buffer; data_len = current_pos + p_desc3->len; while(current_pos < data_len) { if (current_pos +8 <= data_len) { TRACE_EVENT_P8 ("%02x %02x %02x %02x %02x %02x %02x %02x", p_data[current_pos], p_data[current_pos+1], p_data[current_pos+2], p_data[current_pos+3], p_data[current_pos+4], p_data[current_pos+5], p_data[current_pos+6], p_data[current_pos+7] ); current_pos += 8; } else { dif = data_len - current_pos; switch(dif) { case 1: TRACE_EVENT_P1 ("%02x", p_data[current_pos] ); current_pos += 1; break; case 2: TRACE_EVENT_P2 ("%02x %02x", p_data[current_pos], p_data[current_pos+1] ); current_pos += 2; break; case 3: TRACE_EVENT_P3 ("%02x %02x %02x", p_data[current_pos], p_data[current_pos+1], p_data[current_pos+2] ); current_pos += 3; break; case 4: TRACE_EVENT_P4 ("%02x %02x %02x %02x", p_data[current_pos], p_data[current_pos+1], p_data[current_pos+2], p_data[current_pos+3] ); current_pos += 4; break; case 5: TRACE_EVENT_P5 ("%02x %02x %02x %02x %02x", p_data[current_pos], p_data[current_pos+1], p_data[current_pos+2], p_data[current_pos+3], p_data[current_pos+4] ); current_pos += 5; break; case 6: TRACE_EVENT_P6 ("%02x %02x %02x %02x %02x %02x", p_data[current_pos], p_data[current_pos+1], p_data[current_pos+2], p_data[current_pos+3], p_data[current_pos+4], p_data[current_pos+5] ); current_pos += 6; break; case 7: TRACE_EVENT_P7 ("%02x %02x %02x %02x %02x %02x %02x", p_data[current_pos], p_data[current_pos+1], p_data[current_pos+2], p_data[current_pos+3], p_data[current_pos+4], p_data[current_pos+5], p_data[current_pos+6] ); current_pos += 7; break; } } } p_desc3 = (T_desc3*)p_desc3->next; } } /* +------------------------------------------------------------------------------ | Function : llc_trace_sdu +------------------------------------------------------------------------------ | Description : traces content of one sdu | | Parameters : pointer to sdu | +------------------------------------------------------------------------------ */ GLOBAL void llc_trace_sdu(T_sdu* sdu) { USHORT pos = sdu->o_buf >> 3; USHORT frame_len = (sdu->l_buf + 7) / 8; TRACE_FUNCTION("llc_trace_sdu"); while(pos < (frame_len + (sdu->o_buf >> 3))) { if (pos + 8 <= (frame_len + (sdu->o_buf >> 3))) { TRACE_EVENT_P8 ("%02x %02x %02x %02x %02x %02x %02x %02x", sdu->buf[pos], sdu->buf[pos + 1], sdu->buf[pos + 2], sdu->buf[pos + 3], sdu->buf[pos + 4], sdu->buf[pos + 5], sdu->buf[pos + 6], sdu->buf[pos + 7] ); pos += 8; } else if (pos + 7 <= (frame_len + (sdu->o_buf >> 3))){ TRACE_EVENT_P7 ("%02x %02x %02x %02x %02x %02x %02x", sdu->buf[pos], sdu->buf[pos + 1], sdu->buf[pos + 2], sdu->buf[pos + 3], sdu->buf[pos + 4], sdu->buf[pos + 5], sdu->buf[pos + 6] ); pos += 7; } else if (pos + 6 <= (frame_len + (sdu->o_buf >> 3))){ TRACE_EVENT_P6 ("%02x %02x %02x %02x %02x %02x", sdu->buf[pos], sdu->buf[pos + 1], sdu->buf[pos + 2], sdu->buf[pos + 3], sdu->buf[pos + 4], sdu->buf[pos + 5] ); pos += 6; } else if (pos + 5 <= (frame_len + (sdu->o_buf >> 3))){ TRACE_EVENT_P5 ("%02x %02x %02x %02x %02x", sdu->buf[pos], sdu->buf[pos + 1], sdu->buf[pos + 2], sdu->buf[pos + 3], sdu->buf[pos + 4] ); pos += 5; } else if (pos + 4 <= (frame_len + (sdu->o_buf >> 3))){ TRACE_EVENT_P4 ("%02x %02x %02x %02x", sdu->buf[pos], sdu->buf[pos + 1], sdu->buf[pos + 2], sdu->buf[pos + 3] ); pos += 4; } else if (pos + 3 <= (frame_len + (sdu->o_buf >> 3))){ TRACE_EVENT_P3 ("%02x %02x %02x", sdu->buf[pos], sdu->buf[pos + 1], sdu->buf[pos + 2] ); pos += 3; } else if (pos + 2 <= (frame_len + (sdu->o_buf >> 3))){ TRACE_EVENT_P2 ("%02x %02x", sdu->buf[pos], sdu->buf[pos + 1] ); pos += 2; } else if (pos + 1 <= (frame_len + (sdu->o_buf >> 3))){ TRACE_EVENT_P1 ("%02x", sdu->buf[pos] ); pos++; } } } /* +------------------------------------------------------------------------------ | Function : llc_trace_desc_list +------------------------------------------------------------------------------ | Description : traces content of one desc_list | | Parameters : pointer to desc_list | +------------------------------------------------------------------------------ */ GLOBAL void llc_trace_desc_list(T_desc_list* desc_list) { USHORT frame_len = desc_list->list_len; T_desc* desc = (T_desc*)desc_list->first; USHORT list_pos = 0; USHORT desc_pos = 0; TRACE_FUNCTION("llc_trace_desc_list"); while(list_pos < frame_len) { if (desc != NULL) { if (desc_pos >= desc->len) { desc_pos = 0; desc = (T_desc*)desc->next; } } if (desc == NULL) { return; } if (desc_pos + 8 <= desc->len) { TRACE_EVENT_P8 ("%02x %02x %02x %02x %02x %02x %02x %02x ", desc->buffer[desc_pos], desc->buffer[desc_pos + 1], desc->buffer[desc_pos + 2], desc->buffer[desc_pos + 3], desc->buffer[desc_pos + 4], desc->buffer[desc_pos + 5], desc->buffer[desc_pos + 6], desc->buffer[desc_pos + 7] ); list_pos+= 8; desc_pos+= 8; } else if (desc_pos + 7 <= desc->len) { TRACE_EVENT_P7 ("%02x %02x %02x %02x %02x %02x %02x ", desc->buffer[desc_pos], desc->buffer[desc_pos + 1], desc->buffer[desc_pos + 2], desc->buffer[desc_pos + 3], desc->buffer[desc_pos + 4], desc->buffer[desc_pos + 5], desc->buffer[desc_pos + 6] ); list_pos+= 7; desc_pos+= 7; } else if (desc_pos + 6 <= desc->len) { TRACE_EVENT_P6 ("%02x %02x %02x %02x %02x %02x ", desc->buffer[desc_pos], desc->buffer[desc_pos + 1], desc->buffer[desc_pos + 2], desc->buffer[desc_pos + 3], desc->buffer[desc_pos + 4], desc->buffer[desc_pos + 5] ); list_pos+= 6; desc_pos+= 6; } else if (desc_pos + 5 <= desc->len) { TRACE_EVENT_P5 ("%02x %02x %02x %02x %02x ", desc->buffer[desc_pos], desc->buffer[desc_pos + 1], desc->buffer[desc_pos + 2], desc->buffer[desc_pos + 3], desc->buffer[desc_pos + 4] ); list_pos+= 5; desc_pos+= 5; } else if (desc_pos + 4 <= desc->len) { TRACE_EVENT_P4 ("%02x %02x %02x %02x ", desc->buffer[desc_pos], desc->buffer[desc_pos + 1], desc->buffer[desc_pos + 2], desc->buffer[desc_pos + 3] ); list_pos+= 4; desc_pos+= 4; } else if (desc_pos + 3 <= desc->len) { TRACE_EVENT_P3 ("%02x %02x %02x ", desc->buffer[desc_pos], desc->buffer[desc_pos + 1], desc->buffer[desc_pos + 2] ); list_pos+= 3; desc_pos+= 3; } else if (desc_pos + 2 <= desc->len) { TRACE_EVENT_P2 ("%02x %02x ", desc->buffer[desc_pos], desc->buffer[desc_pos + 1] ); list_pos+= 2; desc_pos+= 2; } else if (desc_pos + 1 <= desc->len) { TRACE_EVENT_P1 ("%02x ", desc->buffer[desc_pos] ); list_pos++; desc_pos++; } } /* while(list_pos < frame_len) */ } #endif /*LLC_TRACE_CIPHERING */