FreeCalypso > hg > freecalypso-sw
comparison gsm-fw/ccd/asn1_choice_ext.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_ext.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 : Encoding and decoding functions for ASN1_CHOICE_EXTENSIBLE type | |
18 +----------------------------------------------------------------------------- | |
19 */ | |
20 | |
21 /* | |
22 * Standard definitions like UCHAR, ERROR etc. | |
23 */ | |
24 #include "typedefs.h" | |
25 #include "header.h" | |
26 | |
27 /* | |
28 * Prototypes of ccd (USE_DRIVER EQ undef) for prototypes only | |
29 * look at ccdapi.h | |
30 */ | |
31 #undef USE_DRIVER | |
32 #include "ccdapi.h" | |
33 | |
34 /* | |
35 * Types and functions for bit access and manipulation | |
36 */ | |
37 #include "ccd_globs.h" | |
38 #include "bitfun.h" | |
39 | |
40 /* | |
41 * Prototypes and constants in the common part of ccd | |
42 */ | |
43 #include "ccd.h" | |
44 | |
45 /* | |
46 * Declaration of coder/decoder tables | |
47 */ | |
48 #include "ccdtable.h" | |
49 #include "ccddata.h" | |
50 | |
51 #ifndef RUN_INT_RAM | |
52 /* | |
53 +------------------------------------------------------------------------+ | |
54 | PROJECT : CCD (6144) MODULE : asn1_choice_ext | | |
55 | STATE : code ROUTINE : cdc_asn1_choice_ext_decode | | |
56 +------------------------------------------------------------------------+ | |
57 | |
58 PURPOSE : Decode PER extensible CHOICE type | |
59 | |
60 The value of the union tag must be calculated from the encoded | |
61 CHOICE index in the air message. | |
62 For CHOICE alternatives within the extension root: the index | |
63 bit-size relates to max index value in the extension root. | |
64 For CHOICE alternatives within the extension part: the index | |
65 is encoded as a normally small non-negative whole number. | |
66 | |
67 For decoding the CHOICE alternative itself, call the same | |
68 function as for non-extensible CHOICE types. | |
69 */ | |
70 SHORT cdc_asn1_choice_ext_decode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs) | |
71 { | |
72 U32 extensionBegin; | |
73 T_ENUM UnionTag; /* default: only one alternative */ | |
74 ULONG calc_ref = calcidx[melem[e_ref].calcIdxRef].condCalcRef; | |
75 | |
76 #ifdef DEBUG_CCD | |
77 #ifndef CCD_SYMBOLS | |
78 TRACE_CCD (globs, "cdc_asn1_choice_ext_decode()"); | |
79 #else | |
80 TRACE_CCD (globs, "cdc_asn1_choice_ext_decode() %s", mcomp[melem[e_ref].elemRef].name); | |
81 #endif | |
82 #endif | |
83 | |
84 /* Don't do anything for empty choices */ | |
85 if (mcomp[melem[e_ref].elemRef].numOfComponents == 0) | |
86 { | |
87 return 1; | |
88 } | |
89 | |
90 globs->pstructOffs = melem[e_ref].structOffs; | |
91 | |
92 /* For optional elements we have already set the valid flag in the | |
93 * C-structure. We have done it while processing ASN1_SEQ. | |
94 */ | |
95 if ( ! cdc_isPresent(e_ref, globs) ) { | |
96 return 1; | |
97 } | |
98 | |
99 /* | |
100 * Get max value of CHOICE index within the extension root. | |
101 */ | |
102 if (calc_ref EQ NO_REF | |
103 OR | |
104 calc[calc_ref].operation NEQ 'P') | |
105 { | |
106 ccd_recordFault (globs, ERR_DEFECT_CCDDATA, BREAK, (USHORT) e_ref, | |
107 globs->pstruct+globs->pstructOffs); | |
108 return 1; | |
109 } | |
110 else | |
111 { | |
112 extensionBegin = calc[calc_ref].operand; | |
113 } | |
114 | |
115 /* | |
116 * Read the extensinon bit. | |
117 * If set to 1, read the CHOICE index as a normally samll | |
118 * non-negative whole number. Otherwise read it according | |
119 * to the bitSize of index in the extension root. | |
120 */ | |
121 if (bf_readBit (globs) EQ 0) | |
122 { | |
123 /* CHOICE index is encoded only if there are more than one alternatives. */ | |
124 if (mcomp[melem[e_ref].elemRef].numOfComponents > 1) | |
125 { | |
126 UnionTag = (T_ENUM)bf_getBits (bitSize[extensionBegin], globs); | |
127 } | |
128 else | |
129 UnionTag = 0; | |
130 | |
131 if (UnionTag >= (T_ENUM)extensionBegin) | |
132 { | |
133 ccd_recordFault (globs, ERR_ASN1_ENCODING, BREAK, (USHORT) e_ref, | |
134 globs->pstruct+globs->pstructOffs); | |
135 } | |
136 PER_Decode_ASN1_CHOICE_alterative (e_ref, UnionTag, globs); | |
137 } | |
138 else | |
139 { | |
140 U32 finalBP=0; | |
141 UnionTag = (T_ENUM)Read_NormallySmallNonNegativeWholeNr (globs); | |
142 UnionTag += extensionBegin; | |
143 finalBP = Read_OpenTpye_Length (globs)*8; | |
144 finalBP += globs->bitpos; | |
145 | |
146 /* | |
147 * For unknown extension skip over the octets. | |
148 */ | |
149 if (UnionTag <= (T_ENUM)mcomp[melem[e_ref].elemRef].numOfComponents) | |
150 { | |
151 PER_Decode_ASN1_CHOICE_alterative (e_ref, UnionTag, globs); | |
152 } | |
153 else | |
154 { | |
155 #ifdef DEBUG_CCD | |
156 TRACE_CCD (globs, "Unknown extension with CHOICE index = %ld...skipped to the bit %ld", UnionTag, finalBP); | |
157 #endif | |
158 } | |
159 bf_setBitpos (finalBP, globs); | |
160 } | |
161 | |
162 return 1; | |
163 } | |
164 #endif /* !RUN_INT_RAM */ | |
165 | |
166 #ifndef RUN_INT_RAM | |
167 /* | |
168 +------------------------------------------------------------------------+ | |
169 | PROJECT : CCD (6144) MODULE : asn1_choice_ext | | |
170 | STATE : code ROUTINE : cdc_asn1_choice_ext_encode | | |
171 +------------------------------------------------------------------------+ | |
172 | |
173 PURPOSE : Encode PER extensible CHOICE type | |
174 | |
175 Evaluate the union controller. | |
176 1) It refers to a CHOICE alternative within the extension root: | |
177 Set the extension bit to 0. | |
178 Write the CHOICE index. | |
179 Then encode the chosen alternative. | |
180 ------------------------------------ | |
181 | extension | CHOICE | encoded | | |
182 | bit | index | alternative | | |
183 ------------------------------------ | |
184 | |
185 2) It refers to a CHOICE alternative within the extension list: | |
186 Set the extension bit to 1. | |
187 Encode the CHOICE index as a normally small non-negative whole nr. | |
188 Skip over 6 bits dedicated to length determinant. | |
189 Encode the chosen alternative. | |
190 Calculate the bit size of the encoded alternative. | |
191 Encode the calculated bit size into the field of length | |
192 determinant. Right shift the encoded alternative, if 6 bits | |
193 are not enough for the length determinant. | |
194 ------------------------------------------------ | |
195 | extension | CHOICE | length | encoded | | |
196 | bit | index | determinant | alternative | | |
197 ------------------------------------------------ | |
198 | |
199 For encoding the CHOICE alternative itself, call the same | |
200 function as for non-extensible CHOICE types. | |
201 */ | |
202 SHORT cdc_asn1_choice_ext_encode (const ULONG c_ref, const ULONG e_ref, T_CCD_Globs *globs) | |
203 { | |
204 U16 startBitpos, Len, EndBitPos; | |
205 T_ENUM UnionTag; /* default: only one alternative */ | |
206 U32 extensionBegin; | |
207 ULONG calc_ref= calcidx[melem[e_ref].calcIdxRef].condCalcRef; | |
208 | |
209 #ifdef DEBUG_CCD | |
210 #ifndef CCD_SYMBOLS | |
211 TRACE_CCD (globs, "cdc_asn1_choice_ext_encode()"); | |
212 #else | |
213 TRACE_CCD (globs, "cdc_asn1_choice_ext_encode() %s", mcomp[melem[e_ref].elemRef].name); | |
214 #endif | |
215 #endif | |
216 | |
217 /* Don't do anything for empty choices */ | |
218 if (mcomp[melem[e_ref].elemRef].numOfComponents == 0) | |
219 { | |
220 return 1; | |
221 } | |
222 | |
223 globs->pstructOffs = melem[e_ref].structOffs; | |
224 | |
225 /* For optional elements we have already set the valid flag in the | |
226 * C-structure. We have done it while processing ASN1_SEQ. | |
227 */ | |
228 if ( ! cdc_isPresent(e_ref, globs) ) | |
229 return 1; | |
230 | |
231 /* | |
232 * Get max value of CHOICE index within the extension root. | |
233 */ | |
234 if (calc_ref EQ NO_REF | |
235 OR | |
236 calc[calc_ref].operation NEQ 'P') | |
237 { | |
238 ccd_recordFault (globs, ERR_DEFECT_CCDDATA, BREAK,(USHORT) e_ref, | |
239 globs->pstruct+globs->pstructOffs); | |
240 return 1; | |
241 } | |
242 else | |
243 { | |
244 extensionBegin = calc[calc_ref].operand; | |
245 } | |
246 | |
247 /* | |
248 * Get the value of chosen index (= union controller). | |
249 */ | |
250 UnionTag = *(T_ENUM *) (globs->pstruct+globs->pstructOffs); | |
251 | |
252 /* | |
253 * The chosen alternative belongs to the extension list. | |
254 */ | |
255 if ((U32)UnionTag >= extensionBegin) | |
256 { | |
257 /* Encode the extension bit first */ | |
258 bf_writeBit (1, globs); | |
259 /* Encode the CHOICE index. */ | |
260 Write_NormallySmallNonNegativeWholeNr (((U32)UnionTag - extensionBegin), globs); | |
261 | |
262 /* Skip over the bits estimated for the length determinant. */ | |
263 bf_incBitpos (8, globs); | |
264 startBitpos = globs->bitpos; | |
265 PER_Encode_ASN1_CHOICE_alterative (e_ref, UnionTag, globs); | |
266 | |
267 /* | |
268 * Check if zero padding bits are necessary. If encoding | |
269 * consumed no bits, insert a zero-octet in the bit string. | |
270 * Then calculate length of the encoded open type in octets. | |
271 */ | |
272 if ((Len = globs->bitpos - startBitpos) EQ 0) | |
273 { | |
274 bf_writeVal (0, 8, globs); | |
275 Len = 1; | |
276 } | |
277 else | |
278 { | |
279 if ((Len&7) NEQ 0) | |
280 bf_incBitpos (8 - (Len&7), globs); | |
281 Len = (U16)(globs->bitpos - startBitpos) >> 3; | |
282 } | |
283 EndBitPos = globs->bitpos; | |
284 | |
285 /* | |
286 * Encode the length determinant. | |
287 */ | |
288 if (Len < 128) | |
289 { | |
290 bf_setBitpos (startBitpos-8, globs); | |
291 Write_OpenTpye_Length ((U32)Len, globs); | |
292 } | |
293 /* | |
294 * This case does not seem to happen very often. | |
295 */ | |
296 else | |
297 { | |
298 ccd_recordFault (globs, ERR_ASN1_ENCODING, BREAK,(USHORT) e_ref, | |
299 globs->pstruct+globs->pstructOffs); | |
300 } | |
301 /* | |
302 * Encoding for the extensible choice is finished. | |
303 * Set the bit position pointer to the end of encoded open type. | |
304 */ | |
305 bf_setBitpos (EndBitPos, globs); | |
306 } | |
307 /* | |
308 * The chosen alternative belongs to the extension root. | |
309 */ | |
310 else | |
311 { | |
312 bf_writeBit (0, globs); | |
313 /* CHOICE index is encoded only if there are more than one alternatives. */ | |
314 if (mcomp[melem[e_ref].elemRef].numOfComponents > 1) | |
315 { | |
316 bf_writeVal ((ULONG) UnionTag, (ULONG) bitSize[extensionBegin], globs); | |
317 } | |
318 PER_Encode_ASN1_CHOICE_alterative (e_ref, UnionTag, globs); | |
319 } | |
320 | |
321 return 1; | |
322 } | |
323 #endif /* !RUN_INT_RAM */ |