1
|
/*
|
2
|
///////////////////////////////////////////////////////////////////////////////
|
3
|
// Copyright (c) 2000-2015 Ericsson Telecom AB
|
4
|
// All rights reserved. This program and the accompanying materials
|
5
|
// are made available under the terms of the Eclipse Public License v1.0
|
6
|
// which accompanies this distribution, and is available at
|
7
|
// http://www.eclipse.org/legal/epl-v10.html
|
8
|
///////////////////////////////////////////////////////////////////////////////
|
9
|
|
10
|
//
|
11
|
// File: CAM_EncDec.cc
|
12
|
// Rev:
|
13
|
// Prodnr:
|
14
|
// Updated: 2015-09-08
|
15
|
// Contact: http://ttcn.ericsson.se
|
16
|
// Reference:
|
17
|
|
18
|
*/
|
19
|
|
20
|
#include "CAM_Types.hh"
|
21
|
#include "CAM.h"
|
22
|
#include <asn_application.h>
|
23
|
#include <asn_internal.h> /* for _ASN_DEFAULT_STACK_MAX */
|
24
|
#include <string.h>
|
25
|
#include <stdarg.h>
|
26
|
|
27
|
unsigned char* res = NULL;
|
28
|
size_t res_size = 0;
|
29
|
|
30
|
namespace CAM__Types {
|
31
|
|
32
|
TTCN_Module CAM__EncDec("CAM_EncDec", __DATE__, __TIME__);
|
33
|
|
34
|
// This function is called multiple times while ber and per decoding
|
35
|
static int write_out(const void *buffer, size_t size, void *key) {
|
36
|
unsigned char * temp = (unsigned char*)realloc(res, (res_size + size) * sizeof(unsigned char));
|
37
|
unsigned char *tempbuf = temp + res_size;
|
38
|
res = temp;
|
39
|
memcpy(tempbuf, buffer, size);
|
40
|
res_size += size;
|
41
|
return 0;
|
42
|
}
|
43
|
|
44
|
//////////////////////////////////
|
45
|
// Encoding function for CAM
|
46
|
//////////////////////////////////
|
47
|
|
48
|
OCTETSTRING enc__CAM__PDU(const CAM__PDU__Descriptions::CAM& pdu)
|
49
|
{
|
50
|
boolean Debugging;
|
51
|
if (TTCN_Logger::log_this_event(TTCN_DEBUG)) Debugging = TRUE;
|
52
|
else Debugging = FALSE;
|
53
|
|
54
|
|
55
|
// PDU_CAM is a union the union element will show us which BER encoding
|
56
|
// function shall be chosen
|
57
|
|
58
|
CAM_t *cam = 0; /* Type to encode */
|
59
|
cam = (CAM_t*)calloc(1, sizeof(CAM_t));
|
60
|
asn_enc_rval_t erv; /* Encoder return value */
|
61
|
asn_dec_rval_t rval; /* Decoder return value */
|
62
|
|
63
|
//set error behavior
|
64
|
TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,TTCN_EncDec::EB_WARNING);
|
65
|
|
66
|
TTCN_Buffer TTCN_buf;
|
67
|
TTCN_buf.clear();
|
68
|
|
69
|
pdu.encode(CAM__PDU__Descriptions::CAM_descr_,TTCN_buf,TTCN_EncDec::CT_BER,BER_ENCODE_DER);
|
70
|
|
71
|
|
72
|
// After BER encoding, we are calling the BER decoder function of asn1c tool
|
73
|
//TTCN_buf.get_len() returns the length of encoded data
|
74
|
//TTCN_buf.get_data() returns the pointer of recorded data
|
75
|
|
76
|
size_t length = TTCN_buf.get_len();
|
77
|
unsigned char *tempbuf = new unsigned char [length];
|
78
|
unsigned char *value = tempbuf;
|
79
|
memcpy(value, TTCN_buf.get_data(), length);
|
80
|
|
81
|
TTCN_buf.cut();
|
82
|
|
83
|
if (Debugging) {
|
84
|
TTCN_Logger::begin_event(TTCN_DEBUG);
|
85
|
TTCN_Logger::log_event("Encoded CAM PDU in BER: ");
|
86
|
OCTETSTRING(length,value).log();
|
87
|
TTCN_Logger::end_event();
|
88
|
}
|
89
|
|
90
|
//Decode the BER values from the value buffer into the cam variable
|
91
|
if(Debugging){
|
92
|
TTCN_Logger::begin_event(TTCN_DEBUG);
|
93
|
TTCN_Logger::log_event("Starting ASN1C BER decoding: ");
|
94
|
}
|
95
|
rval = ber_decode(0, &asn_DEF_CAM, (void **)&cam, value, length);
|
96
|
|
97
|
if(rval.code != RC_OK) {
|
98
|
/* Free partially decoded rect */
|
99
|
asn_DEF_CAM.free_struct(&asn_DEF_CAM, cam, 0);
|
100
|
TTCN_error("ASN1C BER decoding failed");
|
101
|
}else {
|
102
|
TTCN_Logger::log(TTCN_DEBUG, "BER2PER: CAM BER decoding successful.");
|
103
|
}
|
104
|
|
105
|
// Free and reset the buffers for the write_out function
|
106
|
free(res);
|
107
|
res = NULL;
|
108
|
res_size = 0;
|
109
|
|
110
|
// Unaligned PER encoding
|
111
|
if (Debugging) {
|
112
|
TTCN_Logger::begin_event(TTCN_DEBUG);
|
113
|
TTCN_Logger::log_event("Starting ASN1C PER encoding: ");
|
114
|
}
|
115
|
erv = uper_encode(&asn_DEF_CAM, cam, write_out, NULL);
|
116
|
|
117
|
|
118
|
if(erv.encoded < 0){
|
119
|
TTCN_error("ASN1C PER encoding failed.");
|
120
|
}else {
|
121
|
TTCN_Logger::log(TTCN_DEBUG, "CAM PER decoding successful.");
|
122
|
}
|
123
|
|
124
|
OCTETSTRING ret_val(res_size, res);
|
125
|
|
126
|
if (Debugging) {
|
127
|
TTCN_Logger::begin_event(TTCN_DEBUG);
|
128
|
TTCN_Logger::log_event("Encoded PDU in PER: ");
|
129
|
ret_val.log();
|
130
|
TTCN_Logger::end_event();
|
131
|
}
|
132
|
|
133
|
free(cam);
|
134
|
free(res);
|
135
|
res = NULL;
|
136
|
res_size = 0;
|
137
|
|
138
|
// Return the PER encoded data as an OCTETSTRING
|
139
|
return ret_val;
|
140
|
}
|
141
|
|
142
|
//////////////////////////////////
|
143
|
// Decoding function for CAM
|
144
|
//////////////////////////////////
|
145
|
|
146
|
CAM__PDU__Descriptions::CAM dec__CAM__PDU(const OCTETSTRING& stream)
|
147
|
{
|
148
|
boolean Debugging;
|
149
|
if (TTCN_Logger::log_this_event(TTCN_DEBUG)) Debugging = TRUE;
|
150
|
else Debugging = FALSE;
|
151
|
|
152
|
if (Debugging) {
|
153
|
TTCN_Logger::begin_event(TTCN_DEBUG);
|
154
|
TTCN_Logger::log_event("dec_CAM_PDU was called with: ");
|
155
|
stream.log();
|
156
|
TTCN_Logger::end_event();
|
157
|
}
|
158
|
|
159
|
CAM *cam = 0; /* Type to encode */
|
160
|
cam = (CAM_t*)calloc(1, sizeof(CAM_t));
|
161
|
asn_enc_rval_t erv; /* Encoder return value */
|
162
|
asn_dec_rval_t rval; /* Decoder return value */
|
163
|
|
164
|
res_size = stream.lengthof();
|
165
|
unsigned char *tempbuf = new unsigned char [res_size];
|
166
|
res = tempbuf;
|
167
|
memcpy(tempbuf, (const unsigned char*)stream, res_size);
|
168
|
|
169
|
if (Debugging) {
|
170
|
TTCN_Logger::begin_event(TTCN_DEBUG);
|
171
|
TTCN_Logger::log_event("Starting ASN1C PER decoding: ");
|
172
|
}
|
173
|
|
174
|
// Decode the Unaligned PER into the cam variable
|
175
|
rval = uper_decode_complete(NULL, &asn_DEF_CAM, (void **)&cam, res, res_size);
|
176
|
|
177
|
if(rval.code != RC_OK) {
|
178
|
/* Free partially decoded rect */
|
179
|
asn_DEF_CAM.free_struct(&asn_DEF_CAM, cam,0);
|
180
|
TTCN_error("ASN1C PER decoding failed");
|
181
|
}else {
|
182
|
TTCN_Logger::log(TTCN_DEBUG, "BER2PER: CAM PER decoding successful.");
|
183
|
}
|
184
|
|
185
|
// Free and reset the buffers for the write_out function
|
186
|
free(res);
|
187
|
res = NULL;
|
188
|
res_size = 0;
|
189
|
|
190
|
if (Debugging) {
|
191
|
TTCN_Logger::begin_event(TTCN_DEBUG);
|
192
|
TTCN_Logger::log_event("Starting ASN1C BER encoding: ");
|
193
|
}
|
194
|
// Encode the cam variable into BER
|
195
|
erv = der_encode(&asn_DEF_CAM, cam, write_out, NULL);
|
196
|
|
197
|
if(erv.encoded < 0){
|
198
|
TTCN_error("ASN1C BER encoding failed.");
|
199
|
}else {
|
200
|
TTCN_Logger::log(TTCN_DEBUG, "CAM BER decoding successful.");
|
201
|
}
|
202
|
|
203
|
if (Debugging) {
|
204
|
TTCN_Logger::begin_event(TTCN_DEBUG);
|
205
|
TTCN_Logger::log_event("Encoded PDU in BER: ");
|
206
|
OCTETSTRING(res_size, res).log();
|
207
|
TTCN_Logger::end_event();
|
208
|
}
|
209
|
|
210
|
TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,TTCN_EncDec::EB_WARNING);
|
211
|
CAM__PDU__Descriptions::CAM ret_cam;
|
212
|
TTCN_Buffer TTCN_buf;
|
213
|
TTCN_buf.clear();
|
214
|
TTCN_buf.put_s(res_size, res);
|
215
|
|
216
|
ret_cam.decode(CAM__PDU__Descriptions::CAM_descr_,TTCN_buf,TTCN_EncDec::CT_BER,BER_ACCEPT_ALL);
|
217
|
|
218
|
free(cam);
|
219
|
free(res);
|
220
|
res = NULL;
|
221
|
res_size = 0;
|
222
|
|
223
|
return ret_cam;
|
224
|
}
|
225
|
|
226
|
void CAM__EncDec_init(){}
|
227
|
|
228
|
}//namespace
|