blob: e885a0e99f252fd48b57fc99c35b4072de65ab28 [file] [log] [blame]
Mohammad Azim Khanfff49042017-03-28 01:48:31 +01001#line 2 "embedded_test.function"
2
3#include "greentea-client/test_env_c.h"
4
5/**
6 * \brief Increments pointer and asserts that it does not overflow.
7 *
8 * \param p Pointer to byte array
9 * \param start Pointer to start of byte array
10 * \param len Length of byte array
11 * \param step Increment size
12 *
13 */
14#define INCR_ASSERT(p, start, len, step) do \
15{ \
16 assert( p >= start ); \
17 assert( sizeof( *p ) == sizeof( *start ) ); \
18 /* <= is checked to support use inside a loop where \
19 pointer is incremented after reading data. */ \
20 assert( (uint32_t)( (p - start) + step ) <= len ); \
21 p += step; \
22} \
23while( 0 )
24
25
26/**
27 * \brief 4 byte align unsigned char pointer
28 *
29 * \param p Pointer to byte array
30 * \param start Pointer to start of byte array
31 * \param len Length of byte array
32 *
33 */
34#define ALIGN_32BIT(p, start, len) do \
35{ \
36 uint32_t align = ( - (uintptr_t)p ) % 4; \
37 INCR_ASSERT(p, start, len, align); \
38} \
39while( 0 )
40
41
42/**
43 * \brief Verify dependencies. Dependency identifiers are
44 * encoded in the buffer as 8 bit unsigned integers.
45 *
46 * \param count Number of dependencies.
47 * \param dep_p Pointer to buffer.
48 *
49 * \return DEPENDENCY_SUPPORTED if success else DEPENDENCY_NOT_SUPPORTED.
50 */
51int verify_dependencies( uint8_t count, uint8_t * dep_p )
52{
53 uint8_t i;
54 for ( i = 0; i < count; i++ )
55 {
56 if ( dep_check( (int)(dep_p[i]) ) != DEPENDENCY_SUPPORTED )
57 return( DEPENDENCY_NOT_SUPPORTED );
58 }
59 return( DEPENDENCY_SUPPORTED );
60}
61
62
63/**
64 * \brief Receives unsigned integer on serial interface.
65 * Integers are encoded in network order.
66 *
67 * \param none
68 *
69 * \return unsigned int
70 */
71uint32_t receive_uint32()
72{
73 uint32_t value;
74 value = (uint8_t)greentea_getc() << 24;
75 value |= (uint8_t)greentea_getc() << 16;
76 value |= (uint8_t)greentea_getc() << 8;
77 value |= (uint8_t)greentea_getc();
78 return( (uint32_t)value );
79}
80
81/**
82 * \brief Parses out an unsigned 32 int value from the byte array.
83 * Integers are encoded in network order.
84 *
85 * \param p Pointer to byte array
86 *
87 * \return unsigned int
88 */
89uint32_t parse_uint32( uint8_t * p )
90{
91 uint32_t value;
92 value = *p++ << 24;
93 value |= *p++ << 16;
94 value |= *p++ << 8;
95 value |= *p;
96 return( value );
97}
98
99
100/**
101 * \brief Receives test data on serial as greentea key,value pair:
102 * {{<length>;<byte array>}}
103 *
104 * \param data_len Out pointer to hold received data length.
105 *
106 * \return Byte array.
107 */
108uint8_t * receive_data( uint32_t * data_len )
109{
110 uint32_t i = 0, errors = 0;
111 char c;
112 uint8_t * data = NULL;
113
114 /* Read opening braces */
115 i = 0;
116 while ( i < 2 )
117 {
118 c = greentea_getc();
119 /* Ignore any prevous CR LF characters */
120 if ( c == '\n' || c == '\r' )
121 continue;
122 i++;
123 if ( c != '{' )
124 return( NULL );
125 }
126
127 /* Read data length */
128 *data_len = receive_uint32();
129 data = (uint8_t *)malloc( *data_len );
130 assert( data != NULL );
131
132 greentea_getc(); // read ';' received after key i.e. *data_len
133
134 for( i = 0; i < *data_len; i++ )
135 data[i] = greentea_getc();
136
137 /* Read closing braces */
138 for( i = 0; i < 2; i++ )
139 {
140 c = greentea_getc();
141 if ( c != '}' )
142 {
143 errors++;
144 break;
145 }
146 }
147
148 if ( errors )
149 {
150 free( data );
151 data = NULL;
152 *data_len = 0;
153 }
154
155 return( data );
156}
157
158/**
159 * \brief Parses received byte array for test parameters.
160 *
161 * \param count Parameter count
162 * \param data Received Byte array
163 * \param data_len Byte array length
164 * \param error Parsing error out variable.
165 *
166 * \return Array of parsed parameters allocated on heap.
167 * Note: Caller has the responsibility to delete
168 * the memory after use.
169 */
170void ** parse_parameters( uint8_t count, uint8_t * data, uint32_t data_len,
171 int * error )
172{
173 uint32_t i = 0;
174 char c;
175 void ** params = NULL;
176 void ** cur = NULL;
177 uint8_t * p = NULL;
178
179 params = (void **)malloc( sizeof( void *) * ( count + 1 ) );
180 assert( params != NULL );
181 params[count] = NULL;
182 cur = params;
183
184 p = data;
185
186 /* Parameters */
187 for( i = 0; i < count; i++ )
188 {
189 c = (char)*p;
190 INCR_ASSERT( p, data, data_len, 1 );
191
192 /* Align p to 4 bytes for int, expression, string len or hex length */
193 ALIGN_32BIT( p, data, data_len );
194
195 /* Network to host conversion */
196 *( (int32_t *)p ) = (int32_t)parse_uint32( p );
197
198 switch( c )
199 {
200 case 'E':
201 {
202 if ( get_expression( *( (int32_t *)p ), (int32_t *)p ) )
203 {
204 *error = KEY_VALUE_MAPPING_NOT_FOUND;
205 goto exit;
206 }
207 } /* Intentional fall through */
208 case 'I':
209 {
210 *cur++ = (void *)p;
211 INCR_ASSERT( p, data, data_len, sizeof( int32_t ) );
212 }
213 break;
214 case 'H':
215 {
216 *cur++ = (void *)p;
217 } /* Intentional fall through */
218 case 'S':
219 {
220 uint32_t sz = *( (int32_t *)p );
221 INCR_ASSERT( p, data, data_len, sizeof( int32_t ) );
222 *cur++ = (void *)p;
223 INCR_ASSERT( p, data, data_len, sz );
224 }
225 break;
226 default:
227 {
228 *error = DISPATCH_INVALID_TEST_DATA;
229 goto exit;
230 }
231 break;
232 }
233 }
234
235exit:
236 if ( *error )
237 {
238 free( params );
239 params = NULL;
240 }
241
242 return( params );
243}
244
245/**
246 * \brief Sends greentea key and int value pair to host.
247 *
248 * \param key key string
249 * \param value integer value
250 *
251 * \return void
252 */
253void send_key_integer( char * key, int value )
254{
255 char str[50];
256 snprintf( str, sizeof( str ), "%d", value );
Azim Khan05746322017-05-23 13:00:35 +0100257 greentea_send_kv( key, str );
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100258}
259
260/**
261 * \brief Sends test setup failure to the host.
262 *
263 * \param failure Test set failure
264 *
265 * \return void
266 */
267void send_failure( int failure )
268{
269 send_key_integer( "F", failure );
270}
271
272/**
273 * \brief Sends test status to the host.
274 *
275 * \param status Test status (PASS=0/FAIL=!0)
276 *
277 * \return void
278 */
279void send_status( int status )
280{
281 send_key_integer( "R", status );
282}
283
284
285/**
286 * \brief Embedded implementation of execute_tests().
287 * Ignores command line and received test data
288 * on serial.
289 *
290 * \param argc not used
291 * \param argv not used
292 *
293 * \return Program exit status.
294 */
295int execute_tests( int args, const char ** argv )
296{
297 int ret = 0;
298 uint32_t data_len = 0;
299 uint8_t count = 0, function_id;
300 void ** params = NULL;
301 uint8_t * data = NULL, * p = NULL;
302
Azim Khan05746322017-05-23 13:00:35 +0100303 GREENTEA_SETUP( 180, "mbedtls_test" );
304 greentea_send_kv( "GO", " " );
Mohammad Azim Khanfff49042017-03-28 01:48:31 +0100305
306 while ( 1 )
307 {
308 ret = 0;
309 test_info.failed = 0;
310 data_len = 0;
311
312 data = receive_data( &data_len );
313 if ( data == NULL )
314 continue;
315 p = data;
316
317 do
318 {
319 /* Read dependency count */
320 count = *p;
321 assert( count < data_len );
322 INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
323 ret = verify_dependencies( count, p );
324 if ( ret != DEPENDENCY_SUPPORTED )
325 break;
326
327 INCR_ASSERT( p, data, data_len, count );
328
329 /* Read function id */
330 function_id = *p;
331 INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
332
333 /* Read number of parameters */
334 count = *p;
335 INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
336
337 params = parse_parameters( count, p, data_len - (p - data), &ret );
338 if ( ret )
339 break;
340
341 ret = dispatch_test( function_id, params );
342 }
343 while ( 0 );
344
345 if ( data )
346 {
347 free(data);
348 data = NULL;
349 }
350
351 if ( params )
352 {
353 free( params );
354 params = NULL;
355 }
356
357 if ( ret )
358 send_failure( ret );
359 else
360 send_status( test_info.failed );
361 }
362 return( 0 );
363}
364