#!/bin/sh
# licence GPLv2 ; this scripts designed by Isamu.Yamauchi 2015.2.10 update 2015.2.23
# pepowiredioctl for contorl TWE-Lite DIP(Tocos wireless engine) digital-IN/digital-OUT signal.
# pepowirelessdioctl $1:ch[1-4] [$2:0 or 1] [$3: timer->1 to 65535ms]
PATH=$PATH:/usr/local/bin:/usr/local/sbin
usage(){
  echo "usage $0 read->chno:0-4 | write->chno:1-4 [DO:0|1] [timer->1 to 65535ms]" >/dev/stderr
  exit -1
}
if [ $# -eq 0 ];then
  usage
elif [ "$1" -gt 4 -o "$1" -lt 0 ];then
  usage
elif [ $# -eq 2 ];then
  if [ "$2" -gt 1 ];then
   usage
  fi
elif [ $# -eq 3 ];then
  if [ "$2" -gt 0 -a "$2" -gt 1 -o "$3" -gt 65535 -o "$3" -lt 1 ];then
    usage
  fi
fi
prog=pepowirelessdioctl
HEDER=":"
ADDR="788001"
DUMMY="0000000000000000"
DO4ON="0808"
DO4OF="0008"
ALLON="0F0F"
ALLOF="0F00"
#TOCOS_TTY=ttyUSB0
LOCK=/var/lock/LCK..${TOCOS_TTY}
WAIT=20
TRY=5
READTM=1
READCT=49
pid=`echo -en $$`
DIO_DEV="/dev/${TOCOS_TTY}"
CHECK_SUM=/usr/local/bin/pepochecksum
DIR=/www/remote-hand/tmp
ALIAS_DI=${DIR}/.alias_di
CMD="${DIR}/$prog.${pid}"
TCOSWD=$DIR/.tocos_write_data
tTCOSWD=$DIR/.tocos_write_data.tmp
[ -e $ALIAS_DI ] && . "$ALIAS_DI"
[ ! -z "{$TOCOS_TTY}" ] && DIO_DEV="/dev/"${TOCOS_TTY} || DIO_DEV=/dev/none_tocos
if [ ! -e $DIO_DEV ];then
  echo -en "-1" >/dev/stderr
  exit -1
fi
RETRY=$TRY
while [ -e $LOCK ]
do
  msleep `echo -en  $RANDOM |cut -c 1-2`
  RETRY=$(($RETRY - 1))
  if [ $RETRY -eq 0 ];then
    echo -en "-1" >/dev/stderr
    exit -1
  fi
done

error(){
  [ -e ${CMD} ] && rm -f ${CMD}
  exit 0
}
trap error SIGHUP SIGTERM SIGQUIT SIGKILL SIGINT SIGCHLD

#check_sum(){
#This script takes very long time.
#  length=`echo -n $1 |wc -c`;val=0x00
#  for (( i=1;i < "$length" ; i = i + 2 )) {
#    j=`echo -n $1| cut -c ${i}-$(($i + 1))`
#    j=$((0x${j}))
#    val=$(($val + $j))
#  }
#  val=$(($(($(($val & 0xff)) ^ 0xff)) + 1))
#  printf "%02x" $val | tr /[a-z]/ /[A-Z]/
#}

CMD_DIO="/usr/local/bin/epicon -s 115200 -d 5 -ql ${DIO_DEV} -c ${CMD}"
send_dio(){
# send_dio data{one byte}
  local send d4off d4on tmp RD
  tmp=${ADDR}${1}${DUMMY}
  send=${HEDER}${tmp}`${CHECK_SUM} ${tmp}`
  tmp=${ADDR}${DO4OF}${DUMMY}
  d4on=${HEDER}${tmp}`${CHECK_SUM} ${tmp}`
  tmp=${ADDR}${DO4ON}${DUMMY}
  d4of=${HEDER}${tmp}`${CHECK_SUM} ${tmp}`
  cat >${CMD}<<EOF
#!/bin/sh
RETRY=$TRY
while [ \${RETRY} -ne 0 ];do
  echo -en "${send}\\r\\n"
  msleep ${WAIT}
  echo -en "${d4on}\\r\\n"
  msleep ${WAIT}
  echo -en "${d4of}\\r\\n"
  msleep $WAIT
  read -s -n ${READCT} -t ${READTM} RD || RD="-1"
  if [ \$? != "0" ];then
    echo -en "-1" >/dev/stderr
  fi
  TMP=\`echo -en \${RD} | awk '{ printf(length(\$0))}'\`
  [ \${TMP} -eq ${READCT} ] && break
  RETRY=\$((\${RETRY} - 1))
done
  
if [ \${RETRY} -eq 0 ];then
  echo -en "-1" >/dev/stderr
else
  echo -en \${RD} >/dev/stderr
fi
EOF
  msleep ${WAIT}
  chmod +x ${CMD}
  ${CMD_DIO}
}

write_dio(){
# write_dio CH 0-1 Timer
  local RD SD CH DO DATA TM TMP
  [ $# -eq 3 ] && TM=$3 || TM=0
  SD=$(($2 ^ 1))
  case $1 in
    1) CH="01" ; DO=TO1 ;;
    2) CH="02" ; DO=TO2 ;;
    3) CH="04" ; DO=TO3 ;;
    4) CH="08" ; DO=TO4 ;;
  esac
  [ $SD -eq 1 ] && DATA=${CH}${CH} || DATA="00"${CH}
  RD=`send_dio ${DATA} 2>&1`
  if [ ${TM} -ne 0 ];then
    SD=$(($SD ^ 1))  
    [ `echo -en ${RD} | awk '{ printf(length($0))}'` != 49 ] && RD="-1" || RD=$SD
    if [ ${RD} != "-1" ];then
      if [ -e ${TCOSWD} ];then
        cat ${TCOSWD} | grep -v $DO >${tTCOSWD}
        echo -en "${DO}=${SD}" >>${tTCOSWD}
        mv ${tTCOSWD} ${TCOSWD}
      else
        echo -en "${DO}=${SD}" >>${TCOSWD}
      fi
      msleep ${TM}
      [ $SD -eq 1 ] && DATA=${CH}${CH} || DATA="00"${CH}
      RD=`send_dio ${DATA} 2>&1`
    fi
  fi
  SD=$(($SD ^ 1))
  TMP=`echo -en ${RD} | awk '{ printf(length($0))}'`
  [ ${TMP} != 49 ] && RD="-1" || RD=$SD
  if [ ${RD} != "-1" ];then
    if [ -e ${TCOSWD} ];then
      cat ${TCOSWD} | grep -v $DO >${tTCOSWD}
      echo -en "${DO}=${SD}" >>${tTCOSWD}
      mv ${tTCOSWD} ${TCOSWD}
    else
      echo -en "${DO}=${SD}" >>${TCOSWD}
    fi
    echo -en ${SD} >/dev/stderr
  else 
    echo -en -1 >/dev/stderr
  fi
}

read_dio(){
  local CH XCH DATA RD RESULT TMP
  case $1 in
    0) CH="0F" ; XCH=0xff ;;
    1) CH="01" ; XCH=0x01 ;;
    2) CH="02" ; XCH=0x02 ;;
    3) CH="04" ; XCH=0x04 ;;
    4) CH="08" ; XCH=0x08 ;;
  esac
  DATA=${DO4OF}
  RD=`send_dio ${DATA} 2>&1`
  TMP=`echo -en ${RD} | awk '{ printf(length($0))}'`
  [ ${TMP} != 49 ] && TMP="-1" || TMP="1"
  if [ ${TMP} != "-1" ];then
    TMP=`echo -en ${RD} | awk '{i=substr(\$0,34,2);printf i}'`
    if [ $1 -eq 0 ];then
      DATA=$((0x${TMP} & 0x${CH}))
      DATA=$(($DATA ^ 0x0f))
    else      
      DATA=$(($((0x${TMP} & 0x${CH})) / ${XCH}))
      DATA=$(($DATA ^ 0x01))
    fi
    printf "%1x" ${DATA} >/dev/stderr
  else
    echo -en "-1" >/dev/stderr
  fi
}

if [ $# -eq 1 ];then
  read_dio $1
elif [ $# -eq 2 ];then
  write_dio $1 $2
elif [ $# -eq 3 ];then
  write_dio $1 $2 $3
fi
rm -f ${CMD}
