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 */