FreeCalypso > hg > freecalypso-sw
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 */ |