• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#line 2 "suites/target_test.function"
2
3#include "greentea-client/test_env.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    TEST_HELPER_ASSERT( ( p ) >= ( start ) );                               \
17    TEST_HELPER_ASSERT( sizeof( *( p ) ) == sizeof( *( start ) ) );         \
18    /* <= is checked to support use inside a loop where         \
19       pointer is incremented after reading data.       */      \
20    TEST_HELPER_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 * \brief       Receives hex string on serial interface, and converts to a byte.
64 *
65 * \param none
66 *
67 * \return      unsigned int8
68 */
69uint8_t receive_byte()
70{
71    uint8_t byte;
72    uint8_t c[3];
73    char *endptr;
74    c[0] = greentea_getc();
75    c[1] = greentea_getc();
76    c[2] = '\0';
77
78    TEST_HELPER_ASSERT( mbedtls_test_unhexify( &byte, c ) != 2 );
79    return( byte );
80}
81
82/**
83 * \brief       Receives unsigned integer on serial interface.
84 *              Integers are encoded in network order, and sent as hex ascii string.
85 *
86 * \param none
87 *
88 * \return      unsigned int
89 */
90uint32_t receive_uint32()
91{
92    uint32_t value;
93    const uint8_t c_be[8] = { greentea_getc(),
94                              greentea_getc(),
95                              greentea_getc(),
96                              greentea_getc(),
97                              greentea_getc(),
98                              greentea_getc(),
99                              greentea_getc(),
100                              greentea_getc()
101                             };
102    const uint8_t c[9] = { c_be[6], c_be[7], c_be[4], c_be[5], c_be[2],
103                           c_be[3], c_be[0], c_be[1], '\0' };
104    TEST_HELPER_ASSERT( mbedtls_test_unhexify( (uint8_t*)&value, c ) != 8 );
105    return( value );
106}
107
108/**
109 * \brief       Parses out an unsigned 32 int value from the byte array.
110 *              Integers are encoded in network order.
111 *
112 * \param p     Pointer to byte array
113 *
114 * \return      unsigned int
115 */
116uint32_t parse_uint32( uint8_t * p )
117{
118    uint32_t value;
119    value =  *p++ << 24;
120    value |= *p++ << 16;
121    value |= *p++ << 8;
122    value |= *p;
123    return( value );
124}
125
126
127/**
128 * \brief       Receives test data on serial as greentea key,value pair:
129 *              {{<length>;<byte array>}}
130 *
131 * \param data_len  Out pointer to hold received data length.
132 *
133 * \return      Byte array.
134 */
135uint8_t * receive_data( uint32_t * data_len )
136{
137    uint32_t i = 0, errors = 0;
138    char c;
139    uint8_t * data = NULL;
140
141    /* Read opening braces */
142    i = 0;
143    while ( i < 2 )
144    {
145        c = greentea_getc();
146        /* Ignore any prevous CR LF characters */
147        if ( c == '\n' || c == '\r' )
148            continue;
149        i++;
150        if ( c != '{' )
151            return( NULL );
152    }
153
154    /* Read data length */
155    *data_len = receive_uint32();
156    data = (uint8_t *)malloc( *data_len );
157    TEST_HELPER_ASSERT( data != NULL );
158
159    greentea_getc(); // read ';' received after key i.e. *data_len
160
161    for( i = 0; i < *data_len; i++ )
162        data[i] = receive_byte();
163
164    /* Read closing braces */
165    for( i = 0; i < 2; i++ )
166    {
167        c = greentea_getc();
168        if ( c != '}' )
169        {
170            errors++;
171            break;
172        }
173    }
174
175    if ( errors )
176    {
177        free( data );
178        data = NULL;
179        *data_len = 0;
180    }
181
182    return( data );
183}
184
185/**
186 * \brief       Parse the received byte array and count the number of arguments
187 *              to the test function passed as type hex.
188 *
189 * \param count     Parameter count
190 * \param data      Received Byte array
191 * \param data_len  Byte array length
192 *
193 * \return      count of hex params
194 */
195uint32_t find_hex_count( uint8_t count, uint8_t * data, uint32_t data_len )
196{
197    uint32_t i = 0, sz = 0;
198    char c;
199    uint8_t * p = NULL;
200    uint32_t hex_count = 0;
201
202    p = data;
203
204    for( i = 0; i < count; i++ )
205    {
206        c = (char)*p;
207        INCR_ASSERT( p, data, data_len, 1 );
208
209        /* Align p to 4 bytes for int, expression, string len or hex length */
210        ALIGN_32BIT( p, data, data_len );
211
212        /* Network to host conversion */
213        sz = (int32_t)parse_uint32( p );
214
215        INCR_ASSERT( p, data, data_len, sizeof( int32_t ) );
216
217        if ( c == 'H' || c == 'S' )
218        {
219            INCR_ASSERT( p, data, data_len, sz );
220            hex_count += ( c == 'H' )?1:0;
221        }
222    }
223
224    return( hex_count );
225}
226
227/**
228 * \brief       Parses received byte array for test parameters.
229 *
230 * \param count     Parameter count
231 * \param data      Received Byte array
232 * \param data_len  Byte array length
233 * \param error     Parsing error out variable.
234 *
235 * \return      Array of parsed parameters allocated on heap.
236 *              Note: Caller has the responsibility to delete
237 *                    the memory after use.
238 */
239void ** parse_parameters( uint8_t count, uint8_t * data, uint32_t data_len,
240                          int * error )
241{
242    uint32_t i = 0, hex_count = 0;
243    char c;
244    void ** params = NULL;
245    void ** cur = NULL;
246    uint8_t * p = NULL;
247
248    hex_count = find_hex_count(count, data, data_len);
249
250    params = (void **)malloc( sizeof( void *) * ( count + hex_count ) );
251    TEST_HELPER_ASSERT( params != NULL );
252    cur = params;
253
254    p = data;
255
256    /* Parameters */
257    for( i = 0; i < count; i++ )
258    {
259        c = (char)*p;
260        INCR_ASSERT( p, data, data_len, 1 );
261
262        /* Align p to 4 bytes for int, expression, string len or hex length */
263        ALIGN_32BIT( p, data, data_len );
264
265        /* Network to host conversion */
266        *( (int32_t *)p ) = (int32_t)parse_uint32( p );
267
268        switch( c )
269        {
270            case 'E':
271                {
272                    if ( get_expression( *( (int32_t *)p ), (int32_t *)p ) )
273                    {
274                        *error = KEY_VALUE_MAPPING_NOT_FOUND;
275                        goto exit;
276                    }
277                } /* Intentional fall through */
278            case 'I':
279                {
280                    *cur++ = (void *)p;
281                    INCR_ASSERT( p, data, data_len, sizeof( int32_t ) );
282                }
283                break;
284            case 'H': /* Intentional fall through */
285            case 'S':
286                {
287                    uint32_t * sz = (uint32_t *)p;
288                    INCR_ASSERT( p, data, data_len, sizeof( int32_t ) );
289                    *cur++ = (void *)p;
290                    if ( c == 'H' )
291                        *cur++ = (void *)sz;
292                    INCR_ASSERT( p, data, data_len, ( *sz ) );
293                }
294                break;
295            default:
296                    {
297                        *error = DISPATCH_INVALID_TEST_DATA;
298                        goto exit;
299                    }
300                break;
301        }
302    }
303
304exit:
305    if ( *error )
306    {
307        free( params );
308        params = NULL;
309    }
310
311    return( params );
312}
313
314/**
315 * \brief       Sends greentea key and int value pair to host.
316 *
317 * \param key   key string
318 * \param value integer value
319 *
320 * \return      void
321 */
322void send_key_integer( char * key, int value )
323{
324    char str[50];
325    snprintf( str, sizeof( str ), "%d", value );
326    greentea_send_kv( key, str );
327}
328
329/**
330 * \brief       Sends test setup failure to the host.
331 *
332 * \param failure   Test set failure
333 *
334 * \return      void
335 */
336void send_failure( int failure )
337{
338    send_key_integer( "F", failure );
339}
340
341/**
342 * \brief       Sends test status to the host.
343 *
344 * \param status    Test status (PASS=0/FAIL=!0)
345 *
346 * \return      void
347 */
348void send_status( int status )
349{
350    send_key_integer( "R", status );
351}
352
353
354/**
355 * \brief       Embedded implementation of execute_tests().
356 *              Ignores command line and received test data
357 *              on serial.
358 *
359 * \param argc  not used
360 * \param argv  not used
361 *
362 * \return      Program exit status.
363 */
364int execute_tests( int args, const char ** argv )
365{
366    int ret = 0;
367    uint32_t data_len = 0;
368    uint8_t count = 0, function_id;
369    void ** params = NULL;
370    uint8_t * data = NULL, * p = NULL;
371
372    GREENTEA_SETUP( 800, "mbedtls_test" );
373    greentea_send_kv( "GO", " " );
374
375    while ( 1 )
376    {
377        ret = 0;
378        test_info.result = TEST_RESULT_SUCCESS;
379        data_len = 0;
380
381        data = receive_data( &data_len );
382        if ( data == NULL )
383            continue;
384        p = data;
385
386        do
387        {
388            /* Read dependency count */
389            count = *p;
390            TEST_HELPER_ASSERT( count < data_len );
391            INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
392            ret = verify_dependencies( count, p );
393            if ( ret != DEPENDENCY_SUPPORTED )
394                break;
395
396            if ( count )
397                INCR_ASSERT( p, data, data_len, count );
398
399            /* Read function id */
400            function_id = *p;
401            INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
402            if ( ( ret = check_test( function_id ) ) != DISPATCH_TEST_SUCCESS )
403                break;
404
405            /* Read number of parameters */
406            count = *p;
407            INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
408
409            /* Parse parameters if present */
410            if ( count )
411            {
412                params = parse_parameters( count, p, data_len - ( p - data ), &ret );
413                if ( ret )
414                    break;
415            }
416
417            ret = dispatch_test( function_id, params );
418        }
419        while ( 0 );
420
421        if ( data )
422        {
423            free( data );
424            data = NULL;
425        }
426
427        if ( params )
428        {
429            free( params );
430            params = NULL;
431        }
432
433        if ( ret )
434            send_failure( ret );
435        else
436            send_status( test_info.result );
437    }
438    return( 0 );
439}
440
441