CLASS=acm VID=0x3346 PID=0x1003 MSC_PID=0x1008 RNDIS_PID=0x1009 UVC_PID=0x100A UAC_PID=0x100B NCM_PID=0x100C ADB_VID=0x18D1 ADB_PID=0x4EE0 ADB_PID_M1=0x4EE2 ADB_PID_M2=0x4EE4 MANUFACTURER="Cvitek" PRODUCT="USB Com Port" PRODUCT_NCM="NCM" PRODUCT_RNDIS="RNDIS" PRODUCT_UVC="UVC" PRODUCT_UAC="UAC" PRODUCT_ADB="ADB" ADBD_PATH=/usr/bin/ SERIAL="0123456789" MSC_FILE=$3 CVI_DIR=/tmp/usb CVI_GADGET=$CVI_DIR/usb_gadget/cvitek CVI_FUNC=$CVI_GADGET/functions FUNC_NUM=0 MAX_EP_NUM=4 TMP_NUM=0 INTF_NUM=0 EP_IN=0 EP_OUT=0 case "$2" in acm) CLASS=acm ;; msc) CLASS=mass_storage PID=$MSC_PID ;; cvg) CLASS=cvg ;; ncm) CLASS=ncm PID=$NCM_PID PRODUCT=$PRODUCT_NCM ;; rndis) CLASS=rndis PID=$RNDIS_PID PRODUCT=$PRODUCT_RNDIS ;; uvc) CLASS=uvc PID=$UVC_PID PRODUCT=$PRODUCT_UVC ;; uac1) CLASS=uac1 PID=$UAC_PID PRODUCT=$PRODUCT_UAC ;; adb) CLASS=ffs.adb VID=$ADB_VID PID=$ADB_PID PRODUCT=$PRODUCT_ADB ;; *) if [ "$1" = "probe" ] ; then echo "Usage: $0 probe {acm|msc|cvg|ncm|rndis|uvc|uac1|adb}" exit 1 fi esac calc_func() { FUNC_NUM=$(ls $CVI_GADGET/functions -l | grep ^d | wc -l) echo "$FUNC_NUM file(s)" } res_check() { TMP_NUM=$(find $CVI_GADGET/functions/ -name "acm*" | wc -l) EP_OUT=$(($EP_OUT+$TMP_NUM)) TMP_NUM=$(($TMP_NUM * 2)) EP_IN=$(($EP_IN+$TMP_NUM)) INTF_NUM=$(($INTF_NUM+$TMP_NUM)) TMP_NUM=$(find $CVI_GADGET/functions/ -name "mass_storage*" | wc -l) EP_IN=$(($EP_IN+$TMP_NUM)) EP_OUT=$(($EP_OUT+$TMP_NUM)) INTF_NUM=$(($INTF_NUM+$TMP_NUM)) TMP_NUM=$(find $CVI_GADGET/functions/ -name "cvg*" | wc -l) EP_IN=$(($EP_IN+$TMP_NUM)) EP_OUT=$(($EP_OUT+$TMP_NUM)) INTF_NUM=$(($INTF_NUM+$TMP_NUM)) TMP_NUM=$(find $CVI_GADGET/functions/ -name "ncm*" | wc -l) TMP_NUM=$(($TMP_NUM * 2)) EP_IN=$(($EP_IN+$TMP_NUM)) EP_OUT=$(($EP_OUT+$TMP_NUM)) INTF_NUM=$(($INTF_NUM+$TMP_NUM)) TMP_NUM=$(find $CVI_GADGET/functions/ -name "rndis*" | wc -l) EP_OUT=$(($EP_OUT+$TMP_NUM)) TMP_NUM=$(($TMP_NUM * 2)) EP_IN=$(($EP_IN+$TMP_NUM)) INTF_NUM=$(($INTF_NUM+$TMP_NUM)) TMP_NUM=$(find $CVI_GADGET/functions/ -name "uvc*" | wc -l) TMP_NUM=$(($TMP_NUM * 2)) EP_IN=$(($EP_IN+$TMP_NUM)) INTF_NUM=$(($INTF_NUM+$TMP_NUM)) TMP_NUM=$(find $CVI_GADGET/functions/ -name "uac1*" | wc -l) TMP_NUM=$(($TMP_NUM * 2)) EP_IN=$(($EP_IN+$TMP_NUM)) EP_OUT=$(($EP_OUT+$TMP_NUM)) INTF_NUM=$(($INTF_NUM+$TMP_NUM)) TMP_NUM=$(find $CVI_GADGET/functions/ -name ffs.adb | wc -l) EP_IN=$(($EP_IN+$TMP_NUM)) EP_OUT=$(($EP_OUT+$TMP_NUM)) INTF_NUM=$(($INTF_NUM+$TMP_NUM)) if [ "$CLASS" = "acm" ] ; then EP_IN=$(($EP_IN+2)) EP_OUT=$(($EP_OUT+1)) fi if [ "$CLASS" = "mass_storage" ] ; then EP_IN=$(($EP_IN+1)) EP_OUT=$(($EP_OUT+1)) fi if [ "$CLASS" = "cvg" ] ; then EP_IN=$(($EP_IN+1)) EP_OUT=$(($EP_OUT+1)) fi if [ "$CLASS" = "ncm" ] ; then EP_IN=$(($EP_IN+1)) EP_OUT=$(($EP_OUT+1)) fi if [ "$CLASS" = "rndis" ] ; then EP_IN=$(($EP_IN+2)) EP_OUT=$(($EP_OUT+1)) fi if [ "$CLASS" = "uvc" ] ; then EP_IN=$(($EP_IN+2)) fi if [ "$CLASS" = "uac1" ] ; then EP_IN=$(($EP_IN+1)) EP_OUT=$(($EP_OUT+1)) fi if [ "$CLASS" = "ffs.adb" ] ; then EP_IN=$(($EP_IN+1)) EP_OUT=$(($EP_OUT+1)) fi echo "$EP_IN in ep" echo "$EP_OUT out ep" if [ $EP_IN -gt $MAX_EP_NUM ]; then echo "reach maximum resource" exit 1 fi if [ $EP_OUT -gt $MAX_EP_NUM ]; then echo "reach maximum resource" exit 1 fi } probe() { if [ ! -d $CVI_DIR ]; then mkdir $CVI_DIR fi if [ ! -d $CVI_DIR/usb_gadget ]; then # Enale USB ConfigFS mount none $CVI_DIR -t configfs # Create gadget dev mkdir $CVI_GADGET # Set the VID and PID echo $VID >$CVI_GADGET/idVendor echo $PID >$CVI_GADGET/idProduct # Set the product information string mkdir $CVI_GADGET/strings/0x409 echo $MANUFACTURER>$CVI_GADGET/strings/0x409/manufacturer echo $PRODUCT>$CVI_GADGET/strings/0x409/product echo $SERIAL>$CVI_GADGET/strings/0x409/serialnumber # Set the USB configuration mkdir $CVI_GADGET/configs/c.1 mkdir $CVI_GADGET/configs/c.1/strings/0x409 echo "config1">$CVI_GADGET/configs/c.1/strings/0x409/configuration # Set the MaxPower of USB descriptor echo 120 >$CVI_GADGET/configs/c.1/MaxPower fi # get current functions number calc_func # assign the class code for composite device if [ ! $FUNC_NUM -eq 0 ]; then echo 0xEF >$CVI_GADGET/bDeviceClass echo 0x02 >$CVI_GADGET/bDeviceSubClass echo 0x01 >$CVI_GADGET/bDeviceProtocol fi # resource check res_check # create the desired function if [ "$CLASS" = "ffs.adb" ] ; then # adb shall be the last function to probe. Override the pid/vid echo $VID >$CVI_GADGET/idVendor echo $PID >$CVI_GADGET/idProduct # choose pid for different function number if [ $INTF_NUM -eq 1 ]; then echo $ADB_PID_M1 >$CVI_GADGET/idProduct fi if [ $INTF_NUM -eq 2 ]; then echo $ADB_PID_M2 >$CVI_GADGET/idProduct fi mkdir $CVI_GADGET/functions/$CLASS else mkdir $CVI_GADGET/functions/$CLASS.usb$FUNC_NUM fi if [ "$CLASS" = "mass_storage" ] ; then echo $MSC_FILE >$CVI_GADGET/functions/$CLASS.usb$FUNC_NUM/lun.0/file fi if [ "$CLASS" = "ncm" ] ; then ln -s $CVI_FUNC/ncm.usb$FUNC_NUM $CVI_GADGET/configs/c.1 fi if [ "$CLASS" = "rndis" ] ; then #OS STRING echo 1 >$CVI_GADGET/os_desc/use echo 0xcd >$CVI_GADGET/os_desc/b_vendor_code echo MSFT100 >$CVI_GADGET/os_desc/qw_sign #COMPATIBLE ID echo RNDIS >$CVI_FUNC/rndis.usb$FUNC_NUM/os_desc/interface.rndis/compatible_id #MAKE c.1 THE ONE ASSOCIATED WITH OS DESCRIPTORS ln -s $CVI_GADGET/configs/c.1 $CVI_GADGET/os_desc #MAKE "Icons" EXTENDED PROPERTY mkdir $CVI_FUNC/rndis.usb$FUNC_NUM/os_desc/interface.rndis/Icons echo 2 >$CVI_FUNC/rndis.usb$FUNC_NUM/os_desc/interface.rndis/Icons/type echo "%SystemRoot%\\system32\\shell32.dll,-233" >$CVI_FUNC/rndis.usb$FUNC_NUM/os_desc/interface.rndis/Icons/data #MAKE "Label" EXTENDED PROPERTY mkdir $CVI_FUNC/rndis.usb$FUNC_NUM/os_desc/interface.rndis/Label echo 1 >$CVI_FUNC/rndis.usb$FUNC_NUM/os_desc/interface.rndis/Label/type echo "XYZ Device" >$CVI_FUNC/rndis.usb$FUNC_NUM/os_desc/interface.rndis/Label/data fi } start() { # link this function to the configuration calc_func if [ $FUNC_NUM -eq 0 ]; then echo "Functions Empty!" exit 1 fi if [ -d $CVI_GADGET/functions/ffs.adb ]; then FUNC_NUM=$(($FUNC_NUM-1)) fi for i in `seq 0 $(($FUNC_NUM-1))`; do find $CVI_GADGET/functions/ -name "*.usb$i" | xargs -I % ln -s % $CVI_GADGET/configs/c.1 done if [ -d $CVI_GADGET/functions/ffs.adb ]; then ln -s $CVI_GADGET/functions/ffs.adb $CVI_GADGET/configs/c.1 mkdir /dev/usb-ffs/adb -p mount -t functionfs adb /dev/usb-ffs/adb if [ -f $ADBD_PATH/adbd ]; then $ADBD_PATH/adbd & fi else # Start the gadget driver UDC=`ls /sys/class/udc/ | awk '{print $1}'` echo ${UDC} >$CVI_GADGET/UDC fi } stop() { if [ -d $CVI_GADGET/configs/c.1/ffs.adb ]; then pkill adbd rm $CVI_GADGET/configs/c.1/ffs.adb else echo "" >$CVI_GADGET/UDC fi find $CVI_GADGET/configs/ -name "*.usb*" | xargs rm -f rmdir $CVI_GADGET/configs/c.*/strings/0x409/ tmp_dirs=$(find $CVI_GADGET/os_desc/c.* -type d) if [ -n tmp_dirs ]; then echo "remove os_desc!" rm -rf $CVI_GADGET/os_desc/c.*/ find $CVI_GADGET/functions/ -name Icons | xargs rmdir find $CVI_GADGET/functions/ -name Label | xargs rmdir fi rmdir $CVI_GADGET/configs/c.*/ rmdir $CVI_GADGET/functions/* rmdir $CVI_GADGET/strings/0x409/ rmdir $CVI_GADGET umount $CVI_DIR rmdir $CVI_DIR } case "$1" in start) start ;; stop) stop ;; probe) probe ;; UDC) ls /sys/class/udc/ >$CVI_GADGET/UDC ;; *) echo "Usage: $0 probe {acm|msc|cvg|ncm|uvc|uac1} {file (msc)}" echo "Usage: $0 start" echo "Usage: $0 stop" exit 1 esac exit $?