@@ -187,6 +187,7 @@ struct chan_simpleusb_pvt {
187187
188188 char devicenum ;
189189 char devstr [128 ];
190+ char serial [128 ];
190191 int spkrmax ;
191192 int micmax ;
192193 int micplaymax ;
@@ -791,14 +792,17 @@ static int load_tune_config(struct chan_simpleusb_pvt *o, const struct ast_confi
791792 int opened = 0 ;
792793 int configured = 0 ;
793794 char devstr [sizeof (o -> devstr )];
795+ char serial [sizeof (o -> serial )];
794796
795797 o -> rxmixerset = 500 ;
796798 o -> txmixaset = 500 ;
797799 o -> txmixbset = 500 ;
798800
799801 devstr [0 ] = '\0' ;
802+ serial [0 ] = '\0' ;
800803 if (!reload ) {
801- o -> devstr [0 ] = 0 ;
804+ o -> devstr [0 ] = '\0' ;
805+ o -> serial [0 ] = '\0' ;
802806 }
803807
804808 if (!cfg ) {
@@ -819,11 +823,13 @@ static int load_tune_config(struct chan_simpleusb_pvt *o, const struct ast_confi
819823 CV_UINT ("txmixaset" , o -> txmixaset );
820824 CV_UINT ("txmixbset" , o -> txmixbset );
821825 CV_STR ("devstr" , devstr );
826+ CV_STR ("serial" , serial );
822827 CV_END ;
823828 }
824829 if (!reload ) {
825830 /* Using the ternary operator in CV_STR won't work, due to butchering the sizeof, so copy after if needed */
826831 strcpy (o -> devstr , devstr ); /* Safe */
832+ strcpy (o -> serial , serial ); /* Safe */
827833 }
828834 if (opened ) {
829835 ast_config_destroy (cfg2 );
@@ -893,6 +899,8 @@ static void *hidthread(void *arg)
893899 * with the usb hid device
894900 */
895901 while (!o -> stophid ) {
902+ char serial [sizeof (o -> serial )] = { '\0' };
903+
896904 ast_radio_time (& o -> lasthidtime );
897905 ast_mutex_lock (& usb_dev_lock );
898906 o -> hasusb = 0 ;
@@ -913,7 +921,37 @@ static void *hidthread(void *arg)
913921 * found device.
914922 */
915923 ast_radio_time (& o -> lasthidtime );
916-
924+
925+ /* If configuration has a serial number defined, find the device */
926+ if (!ast_strlen_zero (o -> serial )) {
927+ int index ;
928+ char * index_devstr = NULL ;
929+
930+ for (index = 0 ;; index ++ ) {
931+ index_devstr = ast_radio_usb_get_devstr (index );
932+ if (ast_strlen_zero (index_devstr )) {
933+ /* if no more devices */
934+ break ;
935+ }
936+
937+ /* get the device serial number */
938+ if (ast_radio_usb_get_serial (index_devstr , serial , sizeof (serial )) == 0 ) {
939+ /* if no serial number */
940+ continue ;
941+ }
942+
943+ if (strcmp (o -> serial , serial ) == 0 ) {
944+ /*
945+ * We found a device with the matching serial number, set
946+ * the devstr to the matching device.
947+ */
948+ ast_log (LOG_NOTICE , "Matched device serial %s to %s\n" , o -> serial , o -> name );
949+ ast_copy_string (o -> devstr , index_devstr , sizeof (o -> devstr ));
950+ break ;
951+ }
952+ }
953+ }
954+
917955 /* Automatically assign a devstr if one was not specified in the configuration. */
918956 if (ast_strlen_zero (o -> devstr )) {
919957 int index = 0 ;
@@ -943,6 +981,9 @@ static void *hidthread(void *arg)
943981 /* We found an unused device assign it to our node */
944982 ast_copy_string (o -> devstr , index_devstr , sizeof (o -> devstr ));
945983 ast_log (LOG_NOTICE , "Channel %s: Automatically assigned USB device %s to SimpleUSB channel\n" , o -> name , o -> devstr );
984+ if (ast_radio_usb_get_serial (index_devstr , serial , sizeof (serial )) > 0 ) {
985+ ast_copy_string (o -> serial , serial , sizeof (o -> serial ));
986+ }
946987 break ;
947988 }
948989 if (ast_strlen_zero (o -> devstr )) {
@@ -3118,6 +3159,9 @@ static void _menu_print(int fd, struct chan_simpleusb_pvt *o)
31183159 ast_cli (fd , "Active radio interface is [%s]\n" , simpleusb_active );
31193160 ast_mutex_lock (& usb_dev_lock );
31203161 ast_cli (fd , "Device String is %s\n" , o -> devstr );
3162+ if (!ast_strlen_zero (o -> serial )) {
3163+ ast_cli (fd , "Device Serial is %s\n" , o -> serial );
3164+ }
31213165 ast_mutex_unlock (& usb_dev_lock );
31223166 ast_cli (fd , "Card is %i\n" , ast_radio_usb_get_usbdev (o -> devstr ));
31233167 ast_cli (fd , "Rx Level currently set to %d\n" , o -> rxmixerset );
@@ -3320,7 +3364,36 @@ static void tune_write(struct chan_simpleusb_pvt *o)
33203364 if (!category ) {
33213365 ast_log (LOG_ERROR , "No category '%s' exists?\n" , o -> name );
33223366 } else {
3323- CONFIG_UPDATE_STR (devstr );
3367+ /*
3368+ * To simplify channel driver setup we allow the "devstr=" value
3369+ * to be empty/blank indicating that we should match the first
3370+ * available interface.
3371+ *
3372+ * This works (and will continue to work) well as long as the
3373+ * "devstr=" value in the configuration file remains empty/blank.
3374+ * But, if the value is ever provided then we only match interfaces
3375+ * with the specified string. Moving the interface (accidentally
3376+ * or intentionally) to a different "port" will result in not
3377+ * finding/matching the interface.
3378+ *
3379+ * To minimize conflicts, we want to avoid writing out the specific
3380+ * "devstr=" value to the configuration file unless needed. Here,
3381+ * we check if the current "devstr=" value is empty/blank and
3382+ * that there is only a single audio interface connected to the
3383+ * system. If so, we leave the value empty/blank.
3384+ */
3385+ const char * val ;
3386+ char * dev ;
3387+
3388+ val = ast_variable_retrieve (cfg , o -> name , "devstr" );
3389+ dev = ast_radio_usb_get_devstr (1 );
3390+ if (!ast_strlen_zero (val ) || !ast_strlen_zero (dev )) {
3391+ /* if the "devstr=" value exists or there is more than 1 sound device */
3392+ CONFIG_UPDATE_STR (devstr );
3393+ if (!ast_strlen_zero (o -> serial )) {
3394+ CONFIG_UPDATE_STR (serial );
3395+ }
3396+ }
33243397 CONFIG_UPDATE_INT (rxmixerset );
33253398 CONFIG_UPDATE_INT (txmixaset );
33263399 CONFIG_UPDATE_INT (txmixbset );
0 commit comments