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