comparison gsm-fw/ccd/asn1_choice.c @ 648:970d6199f2c5

gsm-fw/ccd/*.[ch]: initial import from the LoCosto source
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Thu, 04 Sep 2014 05:48:57 +0000
parents
children
comparison
equal deleted inserted replaced
647:a60b375014e3 648:970d6199f2c5
1 /*
2 +-----------------------------------------------------------------------------
3 | Project :
4 | Modul : asn1_choice.c
5 +-----------------------------------------------------------------------------
6 | Copyright 2002 Texas Instruments Berlin, AG
7 | All rights reserved.
8 |
9 | This file is confidential and a trade secret of Texas
10 | Instruments Berlin, AG
11 | The receipt of or possession of this file does not convey
12 | any rights to reproduce or disclose its contents or to
13 | manufacture, use, or sell anything it may describe, in
14 | whole, or in part, without the specific written consent of
15 | Texas Instruments Berlin, AG.
16 +-----------------------------------------------------------------------------
17 | Purpose : Definition of encoding and decoding functions for ASN1_CHOICE
18 | elements
19 +-----------------------------------------------------------------------------
20 */
21
22 /*
23 * Standard definitions like UCHAR, ERROR etc.
24 */
25 #include "typedefs.h"
26 #include "header.h"
27
28 /*
29 * Prototypes of ccd (USE_DRIVER EQ undef) for prototypes only
30 * look at ccdapi.h
31 */
32 #undef USE_DRIVER
33 #include "ccdapi.h"
34
35 /*
36 * Types and functions for bit access and manipulation
37 */
38 #include "ccd_globs.h"
39 #include "bitfun.h"
40
41 /*
42 * Prototypes and constants in the common part of ccd
43 */
44 #include "ccd.h"
45 #include "ccd_codingtypes.h"
46
47 /*
48 * Declaration of coder/decoder tables
49 */
50 #include "ccdtable.h"
51 #include "ccddata.h"
52
53 EXTERN T_FUNC_POINTER codec[MAX_CODEC_ID+1][2];
54
55 #ifndef RUN_INT_RAM
56 const UBYTE bitSize[] = {0, 1, 1, 2, 2, 3, 3, 3, 3,
57 4, 4, 4, 4, 4, 4, 4, 4,
58 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
59 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
60 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
61 #endif /* !RUN_INT_RAM */
62
63 #ifndef RUN_INT_RAM
64 /*
65 +--------------------------------------------------------------------+
66 | PROJECT : CCD (6144) MODULE : asn1_choice |
67 | STATE : code ROUTINE : PER_Decode_ASN1_CHOICE_altervative |
68 +--------------------------------------------------------------------+
69
70 PURPOSE : Decode a chosen alternative of an ASN.1 CHOICE type
71 Use the parameter union tag bit-size to read the CHOICE
72 index. Because of the ascending enumeration of union tags
73 it is easy to calculate the e_ref for the chosen element
74 which is to be decoded. Then the appropriate decoding
75 function for the chosen element is called.
76
77 No actions for pointer types (dynamic arrays), as CHOICE
78 clauses contain no information in themselves. Memory is
79 allocated in the containing SEQUENCE instead.
80 */
81 void PER_Decode_ASN1_CHOICE_alterative (const ULONG e_ref, T_ENUM UnionTag, T_CCD_Globs *globs)
82 {
83 UBYTE *old_pstruct;
84 ULONG elem_ref, c_ref;
85
86 c_ref = (ULONG) melem[e_ref].elemRef;
87
88 /*
89 * Calculate the elem_ref for the chosen element.
90 * Write the CHOICE tag value in the C-structure.
91 */
92 elem_ref = mcomp[c_ref].componentRef + (ULONG) UnionTag;
93 *(T_ENUM *) (globs->pstruct+globs->pstructOffs) = (T_ENUM) UnionTag;
94
95 /*
96 * Prepare for decoding next element.
97 * Store the current value of the C-structure pointer. After decoding the CHOICE component
98 * we will set the pointer to this stored value. Then we will use pstructOffs for pointing
99 * to the next element.
100 */
101 old_pstruct = globs->pstruct;
102 globs->pstruct += (globs->pstructOffs + sizeof(T_ENUM));
103
104 #ifdef DYNAMIC_ARRAYS
105 /*
106 * Allocate memory for this whole composition, if elemType is
107 * one of the pointer types.
108 */
109 if ( is_pointer_type(e_ref) AND
110 PER_allocmem_and_update(e_ref, 1, globs) NEQ ccdOK ) {
111 return;
112 } else
113 #endif
114
115 /*
116 * Call the decode function for the chosen element.
117 */
118 (void) codec[melem[elem_ref].codingType][DECODE_FUN]
119 (c_ref, elem_ref, globs);
120 /*
121 * Prepare for decoding the next element.
122 */
123 globs->pstruct = old_pstruct;
124 }
125 #endif /* !RUN_INT_RAM */
126
127 #ifndef RUN_INT_RAM
128 /*
129 +--------------------------------------------------------------------+
130 | PROJECT : CCD (6144) MODULE : asn1_choice |
131 | STATE : code ROUTINE : cdc_asn1_choice_decode |
132 +--------------------------------------------------------------------+
133
134 PURPOSE : Decode ASN.1 CHOICE type according to PER
135 CHOICE index is read from the message bit string. Its
136 bit-size can be extracted from the number of CHOICE
137 alternatives.
138 For decoding the CHOICE alternative itself, call the same
139 function as for extensible CHOICE types.
140 */
141 SHORT cdc_asn1_choice_decode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
142 {
143 T_ENUM UnionTag=0; /* default: only one alternative */
144 ULONG num_of_comps, mcomp_ref;
145
146 mcomp_ref = (ULONG) melem[e_ref].elemRef;
147
148 #ifdef DEBUG_CCD
149 #ifndef CCD_SYMBOLS
150 TRACE_CCD (globs, "cdc_asn1_choice_decode()");
151 #else
152 TRACE_CCD (globs, "cdc_asn1_choice_decode() %s", mcomp[mcomp_ref].name);
153 #endif
154 #endif
155
156 /* Don't do anything for empty choices */
157 if (mcomp[mcomp_ref].numOfComponents == 0)
158 {
159 return 1;
160 }
161
162 globs->pstructOffs = melem[e_ref].structOffs;
163
164 /* For optional elements we have already set the valid flag in the
165 * C-structure. We have done it while processing ASN1_SEQ.
166 */
167 if ( ! cdc_isPresent(e_ref, globs) ) {
168 return 1;
169 }
170
171 /*
172 * Get the bit size of the CHOICE index.
173 * Then read the bits representing the index in the air message.
174 */
175 num_of_comps = (ULONG) mcomp[mcomp_ref].numOfComponents;
176 /* CHOICE index is encoded only if there are more than one alternatives. */
177 if (num_of_comps NEQ 1)
178 {
179 UnionTag = bf_getBits ((U32)bitSize[num_of_comps], globs);
180 /*
181 * Check correctness of the read CHOICE index.
182 */
183 if ((ULONG)UnionTag >= num_of_comps)
184 {
185 ccd_recordFault (globs, ERR_ASN1_ENCODING, BREAK, (USHORT) e_ref, globs->pstruct+globs->pstructOffs);
186 }
187 }
188 PER_Decode_ASN1_CHOICE_alterative (e_ref, UnionTag, globs);
189 return 1;
190 }
191 #endif /* !RUN_INT_RAM */
192
193 #ifndef RUN_INT_RAM
194 /*
195 +--------------------------------------------------------------------+
196 | PROJECT : CCD (6144) MODULE : asn1_choice |
197 | STATE : code ROUTINE : PER_Encode_ASN1_CHOICE_altervative |
198 +--------------------------------------------------------------------+
199
200 PURPOSE : Encode a chosen alternative of an ASN.1 CHOICE type.
201
202 Because of ascending enumeration of union tags it is
203 easy to calculate the e_ref for the chosen element to be
204 encoded. Then the appropriate encoding function for the
205 chosen element is called.
206
207 No actions for pointer types (dynamic arrays), as CHOICE
208 clauses contain no information in themselves. Memory is
209 allocated in the containing SEQUENCE instead.
210 */
211 void PER_Encode_ASN1_CHOICE_alterative (const ULONG e_ref, T_ENUM UnionTag, T_CCD_Globs *globs)
212 {
213 UBYTE *old_pstruct;
214 ULONG elem_ref, c_ref;
215
216 c_ref = (ULONG) melem[e_ref].elemRef;
217
218 /*
219 * Prepare for encoding next element.
220 * Store the current value of the C-structure pointer. After encoding
221 * the CHOICE component we will set the pointer to this stored value.
222 * Then we will use pstructOffs for pointing to the next element.
223 */
224 old_pstruct = globs->pstruct;
225 globs->pstruct += (globs->pstructOffs + sizeof(T_ENUM));
226
227 #ifdef DYNAMIC_ARRAYS
228 /*
229 * Dereference pointer if this is a pointer types (dynamic arrays)
230 * globs->pstruct was saved above, so no need to do it again.
231 */
232 if ( is_pointer_type(e_ref) ) {
233 if (ccd_check_pointer(*(U8 **)(globs->pstruct)) == ccdOK)
234 globs->pstruct = *(U8 **)(globs->pstruct);
235 else {
236 ccd_recordFault (globs, ERR_INVALID_PTR, BREAK, (USHORT) e_ref,
237 &globs->pstruct[globs->pstructOffs]);
238 return;
239 }
240 }
241 #endif
242
243 elem_ref = mcomp[c_ref].componentRef + (USHORT) UnionTag;
244
245 /*
246 * Call the decode function for the chosen element.
247 */
248 (void) codec[melem[elem_ref].codingType][ENCODE_FUN]
249 (c_ref, elem_ref, globs);
250 /*
251 * Prepare for encoding the next element.
252 */
253 globs->pstruct = old_pstruct;
254 }
255 #endif /* !RUN_INT_RAM */
256
257 #ifndef RUN_INT_RAM
258 /*
259 +--------------------------------------------------------------------+
260 | PROJECT : CCD (6144) MODULE : asn1_choice |
261 | STATE : code ROUTINE : cdc_asn1_choice_encode |
262 +--------------------------------------------------------------------+
263
264 PURPOSE : Encoding of CHOICE type for UMTS
265 The size of the union tag must be calculated. Then its value
266 is written in the air message.
267 For encoding the CHOICE alternative itself, call the same
268 function as for extensible CHOICE types.
269 */
270 SHORT cdc_asn1_choice_encode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs)
271 {
272 T_ENUM UnionTag=0; /* default: only one alternative */
273 ULONG num_of_comps, mcomp_ref;
274
275 mcomp_ref = (ULONG) melem[e_ref].elemRef;
276
277 #ifdef DEBUG_CCD
278 #ifndef CCD_SYMBOLS
279 TRACE_CCD (globs, "cdc_asn1_choice_encode()");
280 #else
281 TRACE_CCD (globs, "cdc_asn1_choice_encode() %s", mcomp[mcomp_ref].name);
282 #endif
283 #endif
284
285 /* Don't do anything for empty choices */
286 if (mcomp[mcomp_ref].numOfComponents == 0)
287 {
288 return 1;
289 }
290
291 globs->pstructOffs = melem[e_ref].structOffs;
292
293 /* For optional elements we have already set the valid flag in the
294 * C-structure. We have done it while processing ASN1_SEQ.
295 */
296 if ( ! cdc_isPresent(e_ref, globs) )
297 return 1;
298
299 /*
300 * Get the value of CHOICE index (= union controller) from the C-structure.
301 * Check its correctness. Write it in the air message.
302 * Afterwards encode the chosen CHOICE altervative.
303 */
304 num_of_comps = mcomp[mcomp_ref].numOfComponents;
305 /* CHOICE index is encoded only if there are more than one alternatives. */
306 if (num_of_comps NEQ 1)
307 {
308 UnionTag = *(T_ENUM *) (globs->pstruct+globs->pstructOffs);
309 if (UnionTag >= (T_ENUM)num_of_comps)
310 {
311 ccd_recordFault (globs, ERR_ASN1_ENCODING, BREAK, (USHORT) e_ref,
312 globs->pstruct+globs->pstructOffs);
313 }
314 bf_writeVal ((ULONG) UnionTag, (ULONG) bitSize[num_of_comps], globs);
315 }
316 PER_Encode_ASN1_CHOICE_alterative (e_ref, UnionTag, globs);
317
318 return 1;
319 }
320 #endif /* !RUN_INT_RAM */