Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / mbedtls / repo / tests / suites / target_test.function
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     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 }                                                               \
23 while( 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 }                                                   \
39 while( 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  */
51 int 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  */
71 uint32_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  */
89 uint32_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  */
108 uint8_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       Parse the received byte array and count the number of arguments
160  *              to the test function passed as type hex.
161  *
162  * \param count     Parameter count
163  * \param data      Received Byte array
164  * \param data_len  Byte array length
165  *
166  * \return      count of hex params
167  */
168 uint32_t find_hex_count( uint8_t count, uint8_t * data, uint32_t data_len )
169 {
170     uint32_t i = 0, sz = 0;
171     char c;
172     uint8_t * p = NULL;
173     uint32_t hex_count = 0;
174
175     p = data;
176
177     for( i = 0; i < count; i++ )
178     {
179         c = (char)*p;
180         INCR_ASSERT( p, data, data_len, 1 );
181
182         /* Align p to 4 bytes for int, expression, string len or hex length */
183         ALIGN_32BIT( p, data, data_len );
184
185         /* Network to host conversion */
186         sz = (int32_t)parse_uint32( p );
187
188         INCR_ASSERT( p, data, data_len, sizeof( int32_t ) );
189
190         if ( c == 'H' || c == 'S' )
191         {
192             INCR_ASSERT( p, data, data_len, sz );
193             hex_count += ( c == 'H' )?1:0;
194         }
195     }
196
197     return( hex_count );
198 }
199
200 /**
201  * \brief       Parses received byte array for test parameters.
202  *
203  * \param count     Parameter count
204  * \param data      Received Byte array
205  * \param data_len  Byte array length
206  * \param error     Parsing error out variable.
207  *
208  * \return      Array of parsed parameters allocated on heap.
209  *              Note: Caller has the responsibility to delete
210  *                    the memory after use.
211  */
212 void ** parse_parameters( uint8_t count, uint8_t * data, uint32_t data_len,
213                           int * error )
214 {
215     uint32_t i = 0, hex_count = 0;
216     char c;
217     void ** params = NULL;
218     void ** cur = NULL;
219     uint8_t * p = NULL;
220
221     hex_count = find_hex_count(count, data, data_len);
222
223     params = (void **)malloc( sizeof( void *) * ( count + hex_count ) );
224     assert( params != NULL );
225     cur = params;
226
227     p = data;
228
229     /* Parameters */
230     for( i = 0; i < count; i++ )
231     {
232         c = (char)*p;
233         INCR_ASSERT( p, data, data_len, 1 );
234
235         /* Align p to 4 bytes for int, expression, string len or hex length */
236         ALIGN_32BIT( p, data, data_len );
237
238         /* Network to host conversion */
239         *( (int32_t *)p ) = (int32_t)parse_uint32( p );
240
241         switch( c )
242         {
243             case 'E':
244                 {
245                     if ( get_expression( *( (int32_t *)p ), (int32_t *)p ) )
246                     {
247                         *error = KEY_VALUE_MAPPING_NOT_FOUND;
248                         goto exit;
249                     }
250                 } /* Intentional fall through */
251             case 'I':
252                 {
253                     *cur++ = (void *)p;
254                     INCR_ASSERT( p, data, data_len, sizeof( int32_t ) );
255                 }
256                 break;
257             case 'H': /* Intentional fall through */
258             case 'S':
259                 {
260                     uint32_t * sz = (uint32_t *)p;
261                     INCR_ASSERT( p, data, data_len, sizeof( int32_t ) );
262                     *cur++ = (void *)p;
263                     if ( c == 'H' )
264                         *cur++ = (void *)sz;
265                     INCR_ASSERT( p, data, data_len, ( *sz ) );
266                 }
267                 break;
268             default:
269                     {
270                         *error = DISPATCH_INVALID_TEST_DATA;
271                         goto exit;
272                     }
273                 break;
274         }
275     }
276
277 exit:
278     if ( *error )
279     {
280         free( params );
281         params = NULL;
282     }
283
284     return( params );
285 }
286
287 /**
288  * \brief       Sends greentea key and int value pair to host.
289  *
290  * \param key   key string
291  * \param value integer value
292  *
293  * \return      void
294  */
295 void send_key_integer( char * key, int value )
296 {
297     char str[50];
298     snprintf( str, sizeof( str ), "%d", value );
299     greentea_send_kv( key, str );
300 }
301
302 /**
303  * \brief       Sends test setup failure to the host.
304  *
305  * \param failure   Test set failure
306  *
307  * \return      void
308  */
309 void send_failure( int failure )
310 {
311     send_key_integer( "F", failure );
312 }
313
314 /**
315  * \brief       Sends test status to the host.
316  *
317  * \param status    Test status (PASS=0/FAIL=!0)
318  *
319  * \return      void
320  */
321 void send_status( int status )
322 {
323     send_key_integer( "R", status );
324 }
325
326
327 /**
328  * \brief       Embedded implementation of execute_tests().
329  *              Ignores command line and received test data
330  *              on serial.
331  *
332  * \param argc  not used
333  * \param argv  not used
334  *
335  * \return      Program exit status.
336  */
337 int execute_tests( int args, const char ** argv )
338 {
339     int ret = 0;
340     uint32_t data_len = 0;
341     uint8_t count = 0, function_id;
342     void ** params = NULL;
343     uint8_t * data = NULL, * p = NULL;
344
345     GREENTEA_SETUP( 180, "mbedtls_test" );
346     greentea_send_kv( "GO", " " );
347
348     while ( 1 )
349     {
350         ret = 0;
351         test_info.failed = 0;
352         data_len = 0;
353
354         data = receive_data( &data_len );
355         if ( data == NULL )
356             continue;
357         p = data;
358
359         do
360         {
361             /* Read dependency count */
362             count = *p;
363             assert( count < data_len );
364             INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
365             ret = verify_dependencies( count, p );
366             if ( ret != DEPENDENCY_SUPPORTED )
367                 break;
368
369             if ( count )
370                 INCR_ASSERT( p, data, data_len, count );
371
372             /* Read function id */
373             function_id = *p;
374             INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
375             if ( ( ret = check_test( function_id ) ) != DISPATCH_TEST_SUCCESS )
376                 break;
377
378             /* Read number of parameters */
379             count = *p;
380             INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
381
382             /* Parse parameters if present */
383             if ( count )
384             {
385                 params = parse_parameters( count, p, data_len - ( p - data ), &ret );
386                 if ( ret )
387                     break;
388             }
389
390             ret = dispatch_test( function_id, params );
391         }
392         while ( 0 );
393
394         if ( data )
395         {
396             free( data );
397             data = NULL;
398         }
399
400         if ( params )
401         {
402             free( params );
403             params = NULL;
404         }
405
406         if ( ret )
407             send_failure( ret );
408         else
409             send_status( test_info.failed );
410     }
411     return( 0 );
412 }
413