99#include <sof/lib/notifier.h>
1010
1111#include <ctype.h>
12+ #include <errno.h>
1213#include <stdint.h>
1314#include <stdio.h>
1415#include <stdlib.h>
@@ -388,10 +389,141 @@ static int tb_parse_amixer(struct testbench_prm *tp, char *line)
388389 return ret ;
389390}
390391
392+ static int tb_parse_sofctl (struct testbench_prm * tp , char * line )
393+ {
394+ struct tb_ctl * ctl ;
395+ uint32_t * blob_bin = NULL ;
396+ char * blob_name = NULL ;
397+ char * blob_str = NULL ;
398+ char * control_name = NULL ;
399+ char * end ;
400+ char * find_ctl_name_str = "-c name=\"" ;
401+ char * find_end_str = "\" " ;
402+ char * find_set_switch_str = "-s" ;
403+ char * name_str ;
404+ char * rest ;
405+ char * token ;
406+ int copy_len ;
407+ int find_len = strlen (find_ctl_name_str );
408+ int n = 0 ;
409+ int ret = 0 ;
410+ FILE * fh ;
411+
412+ name_str = strstr (line , find_ctl_name_str );
413+ if (!name_str ) {
414+ fprintf (stderr , "error: no control name in script line: %s\n" , line );
415+ return - EINVAL ;
416+ }
417+
418+ end = strstr (& name_str [find_len ], find_end_str );
419+ if (!end ) {
420+ fprintf (stderr , "error: no control name end quote in script line: %s\n" , line );
421+ return - EINVAL ;
422+ }
423+
424+ copy_len = end - name_str - find_len ;
425+ control_name = strndup (name_str + find_len , copy_len );
426+ if (!control_name ) {
427+ fprintf (stderr , "error: failed to duplicate control name.\n" );
428+ return - errno ;
429+ }
430+
431+ name_str = strstr (line , find_set_switch_str );
432+ if (!name_str ) {
433+ fprintf (stderr , "error: no sof-ctl control set switch in command: %s.\n" ,
434+ line );
435+ ret = - EINVAL ;
436+ goto err ;
437+ }
438+
439+ name_str += strlen (find_set_switch_str ) + 1 ;
440+ end = line + strlen (line );
441+ copy_len = end - name_str ;
442+ blob_name = strndup (name_str , copy_len );
443+ if (!blob_name ) {
444+ fprintf (stderr , "error: failed to duplicate blob name.\n" );
445+ ret = - errno ;
446+ goto err ;
447+ }
448+
449+ ctl = tb_find_control_by_name (tp , control_name );
450+ if (!ctl ) {
451+ fprintf (stderr , "error: control %s not found in topology.\n" , control_name );
452+ ret = - EINVAL ;
453+ goto err ;
454+ }
455+
456+ if (ctl -> type != SND_SOC_TPLG_TYPE_BYTES ) {
457+ fprintf (stderr , "error: control %s type %d is not supported.\n" ,
458+ control_name , ctl -> type );
459+ ret = - EINVAL ;
460+ goto err ;
461+ }
462+
463+ blob_str = malloc (TB_MAX_BLOB_CONTENT_CHARS );
464+ if (!blob_str ) {
465+ fprintf (stderr , "error: failed to allocate memory for blob file content.\n" );
466+ ret = - ENOMEM ;
467+ goto err ;
468+ }
469+
470+ blob_bin = malloc (TB_MAX_BYTES_DATA_SIZE );
471+ if (!blob_bin ) {
472+ fprintf (stderr , "error: failed to allocate memory for blob data.\n" );
473+ ret = - ENOMEM ;
474+ goto err ;
475+ }
476+
477+ printf ("Info: Setting control name '%s' to blob '%s'\n" , control_name , blob_name );
478+ fh = fopen (blob_name , "r" );
479+ if (!fh ) {
480+ fprintf (stderr , "error: could not open file.\n" );
481+ ret = - errno ;
482+ goto err ;
483+ }
484+
485+ end = fgets (blob_str , TB_MAX_BLOB_CONTENT_CHARS , fh );
486+ fclose (fh );
487+ if (!end ) {
488+ fprintf (stderr , "error: failed to read data from blob file.\n" );
489+ ret = - ENODATA ;
490+ goto err ;
491+ }
492+
493+ rest = blob_str ;
494+ while ((token = strtok_r (rest , "," , & rest ))) {
495+ if (n == TB_MAX_BYTES_DATA_SIZE ) {
496+ fprintf (stderr , "error: data read exceeds max control data size.\n" );
497+ ret = - EINVAL ;
498+ goto err ;
499+ }
500+
501+ blob_bin [n ] = atoi (token );
502+ n ++ ;
503+ }
504+
505+ if (n < 2 ) {
506+ fprintf (stderr , "error: at least two values are required in the blob file.\n" );
507+ ret = - EINVAL ;
508+ goto err ;
509+ }
510+
511+ /* Ignore TLV header from beginning. */
512+ ret = tb_set_bytes_control (tp , ctl , & blob_bin [2 ]);
513+
514+ err :
515+ free (blob_str );
516+ free (blob_bin );
517+ free (blob_name );
518+ free (control_name );
519+ return ret ;
520+ }
521+
391522int tb_read_controls (struct testbench_prm * tp , int64_t * sleep_ns )
392523{
393524 char * sleep_cmd = "sleep " ;
394525 char * amixer_cmd = "amixer " ;
526+ char * sofctl_cmd = "sof-ctl " ;
395527 char * raw_line ;
396528 char * line ;
397529 int ret = 0 ;
@@ -411,7 +543,7 @@ int tb_read_controls(struct testbench_prm *tp, int64_t *sleep_ns)
411543 if (line [0 ] == '#' || strlen (line ) == 0 )
412544 continue ;
413545
414- if (strncmp (line , sleep_cmd , sizeof ( * sleep_cmd )) == 0 ) {
546+ if (strncmp (line , sleep_cmd , strlen ( sleep_cmd )) == 0 ) {
415547 ret = tb_parse_sleep (line , sleep_ns );
416548 if (ret ) {
417549 fprintf (stderr , "error: failed parse of sleep command.\n" );
@@ -420,12 +552,22 @@ int tb_read_controls(struct testbench_prm *tp, int64_t *sleep_ns)
420552 break ;
421553 }
422554
423- if (strncmp (line , amixer_cmd , sizeof ( * amixer_cmd )) == 0 ) {
555+ if (strncmp (line , amixer_cmd , strlen ( amixer_cmd )) == 0 ) {
424556 ret = tb_parse_amixer (tp , line );
425557 if (ret ) {
426558 fprintf (stderr , "error: failed parse of amixer command.\n" );
427559 break ;
428560 }
561+ continue ;
562+ }
563+
564+ if (strncmp (line , sofctl_cmd , strlen (sofctl_cmd )) == 0 ) {
565+ ret = tb_parse_sofctl (tp , line );
566+ if (ret ) {
567+ fprintf (stderr , "error: failed parse of sof-ctl command.\n" );
568+ break ;
569+ }
570+ continue ;
429571 }
430572 }
431573
0 commit comments