#!/bin/sh
#
# setup configfs for adbd, usb mass storage and MTP....
# For kernel v4.4/v4.19 usb configfs without udev
#
# Load default env variables from profiles

RNDIS_EN=off
ADB_EN=off
MTP_EN=off
RNDIS_ADDR=192.168.1.100

USB_ATTRIBUTE=0x409
USB_GROUP=rockchip
USB_SKELETON=b.1

CONFIGFS_DIR=/sys/kernel/config
USB_CONFIGFS_DIR=${CONFIGFS_DIR}/usb_gadget/${USB_GROUP}
USB_STRINGS_DIR=${USB_CONFIGFS_DIR}/strings/${USB_ATTRIBUTE}
USB_FUNCTIONS_DIR=${USB_CONFIGFS_DIR}/functions
USB_CONFIGS_DIR=${USB_CONFIGFS_DIR}/configs/${USB_SKELETON}

syslink_function()
{
	ln -s ${USB_FUNCTIONS_DIR}/$1 ${USB_CONFIGS_DIR}/f${USB_FUNCTIONS_CNT}
	let USB_FUNCTIONS_CNT=USB_FUNCTIONS_CNT+1
}

bind_functions()
{
	USB_FUNCTIONS_CNT=1
	test $MTP_EN = on && syslink_function mtp.gs0
	test $RNDIS_EN = on && syslink_function rndis.gs0
	test $ADB_EN = on && syslink_function ffs.adb

	echo ${CONFIG_STRING} > ${USB_CONFIGS_DIR}/strings/${USB_ATTRIBUTE}/configuration
}

function_init()
{
	test $RNDIS_EN = on && mkdir ${USB_FUNCTIONS_DIR}/rndis.gs0
	test $MTP_EN = on && mkdir ${USB_FUNCTIONS_DIR}/mtp.gs0

	if [ $ADB_EN = on ];then
		mkdir ${USB_FUNCTIONS_DIR}/ffs.adb
		mkdir /dev/usb-ffs/adb -m 0770
		mount -o uid=2000,gid=2000 -t functionfs adb /dev/usb-ffs/adb
	fi
}

configfs_init()
{
	insmod /usr/lib/modules/phy-rockchip-naneng-usb2.ko
	insmod /usr/lib/modules/dwc3-of-simple.ko
	insmod /usr/lib/modules/dwc3.ko
	insmod /usr/lib/modules/dwc3-rockchip-inno.ko
	sleep 1

	mkdir /dev/usb-ffs

	mount -t configfs none ${CONFIGFS_DIR}
	mkdir ${USB_CONFIGFS_DIR} -m 0770
	echo 0x2207 > ${USB_CONFIGFS_DIR}/idVendor
	echo 0x0310 > ${USB_CONFIGFS_DIR}/bcdDevice
	echo 0x0200 > ${USB_CONFIGFS_DIR}/bcdUSB
	mkdir ${USB_STRINGS_DIR}   -m 0770
	SERIAL=`cat /proc/cpuinfo | grep Serial | awk '{print $3}'`
	if [ -z $SERIAL ];then
		SERIAL=0123456789ABCDEF
	fi
	echo $SERIAL > ${USB_STRINGS_DIR}/serialnumber
	echo "rockchip"  > ${USB_STRINGS_DIR}/manufacturer
	echo "rk3xxx"  > ${USB_STRINGS_DIR}/product

	function_init

	mkdir ${USB_CONFIGS_DIR}  -m 0770
	mkdir ${USB_CONFIGS_DIR}/strings/${USB_ATTRIBUTE}  -m 0770

	echo 0x1 > ${USB_CONFIGFS_DIR}/os_desc/b_vendor_code
	echo "MSFT100" > ${USB_CONFIGFS_DIR}/os_desc/qw_sign
	echo 500 > ${USB_CONFIGS_DIR}/MaxPower
	ln -s ${USB_CONFIGS_DIR} ${USB_CONFIGFS_DIR}/os_desc/b.1
}

make_config_string()
{
	tmp=$CONFIG_STRING
	if [ -n "$CONFIG_STRING" ]; then
		CONFIG_STRING=${tmp}_${1}
	else
		CONFIG_STRING=$1
	fi
}

parameter_init()
{
	while read line
	do
		case "$line" in
			usb_adb_en)
				ADB_EN=on
				make_config_string adb
				;;
			usb_rndis_en)
				RNDIS_EN=on
				make_config_string rndis
				;;
			usb_mtp_en)
				MTP_EN=on
				make_config_string mtp
				;;
		esac
	done < $USB_CONFIG_FILE

	case "$CONFIG_STRING" in
		mtp)
			PID=0x0001
			;;
		adb)
			PID=0x0006
			;;
		mtp_adb | adb_mtp)
			PID=0x0011
			;;
		*)
			PID=0x0019
	esac
}

use_os_desc()
{
	if [ $MTP_EN = on ];then
		echo "MTP" > ${USB_FUNCTIONS_DIR}/mtp.gs0/os_desc/interface.MTP/compatible_id
		echo 1 > ${USB_CONFIGFS_DIR}/os_desc/use
	fi
}

pre_run_binary()
{
	if [ $ADB_EN = on ];then
		# insmod /vendor/lib/modules/rfkill.ko
		# insmod /vendor/lib/modules/cfg80211.ko
		ifconfig lo up
		start-stop-daemon --start --quiet --background --exec /usr/bin/adbd
		sleep 1
	fi
}

run_binary()
{
	if [ $RNDIS_EN = on ];then
		ifconfig usb0 $RNDIS_ADDR
		ifconfig usb0 up
	fi

	if [ $MTP_EN = on ];then
		start-stop-daemon --start --quiet --background --exec /usr/bin/mtp-server
	fi
}

program_kill()
{
	P_PID=`ps | grep $1 | grep -v grep | awk '{print $1}'`
	test -z ${P_PID} || kill -9 ${P_PID}
}

usb_device_stop()
{
	echo "none" > ${USB_CONFIGFS_DIR}/UDC
	program_kill adbd
	program_kill mtp-server
	ls ${USB_CONFIGS_DIR} | grep f[0-9] | xargs -I {} rm ${USB_CONFIGS_DIR}/{}
}

case "$1" in
start)
	{
		DIR=$(cd `dirname $0`; pwd)
		if [ ! -e "$DIR/.usb_config" ]; then
			echo "$0: Cannot find .usb_config"
			exit 0
		fi

		if [ -e /tmp/.usb_config ]; then
			USB_CONFIG_FILE=/tmp/.usb_config
		else
			USB_CONFIG_FILE=$DIR/.usb_config
			cp $DIR/.usb_config /tmp/.usb_config
		fi

		parameter_init
		if [ -z $CONFIG_STRING ];then
			echo "$0: no functions be selected"
			exit 0
		fi

		test -d ${USB_CONFIGFS_DIR} || configfs_init
		use_os_desc
		echo $PID > ${USB_CONFIGFS_DIR}/idProduct
		bind_functions
		pre_run_binary

		UDC=`ls /sys/class/udc/| awk '{print $1}'`
		echo $UDC > ${USB_CONFIGFS_DIR}/UDC
		run_binary
	}&
	;;
stop)
	usb_device_stop
	;;
restart)
	usb_device_stop
	sleep 1
	$0 start
	;;
*)
	echo "Usage: $0 {start|stop|restart}"
	exit 1
	;;
esac

exit 0
