#!/bin/bash
# usage: rigol-waveform <command> <filename>
#        e.g.: rigol-waveform ':WAV:DATA?' foo.wfm
#   fetches a blob of raw waveform data (depending on <command>) with TMC header from Rigol DS1000 series, via ethernet
# TODO: proper handling of broken connection to Rigol, check netcat / read return code

RIGOL_IP=192.168.4.52   # adapt to your local situation, I used fixed DHCP IP for rigol in my router

set -e -u
debug=0

send_cmd(){
  echo "$1" | netcat -w 1 $RIGOL_IP 5555
}



send_cmds(){
  # parameters: cmd [delaytime [cmd [delaytime]]...]
  # return stdout: response from Rigol
  # returncode: from netcat
#  declare cmds=""
  (while [ $# -ge 1 ]; do
#    cmds="$cmds echo \"$1\";"
    echo "$1;"
    shift
    if [ $# -ge 1 ]; then
      if ! [[ "$1" =~ ^[0-9\.]*$ ]]; then
        echo "error: $1 is not numeric" >&2
        exit 1
      fi      
#      cmds="$cmds sleep ${1##*(0)};"
      sleep ${1##*(0)}
      shift
    fi
  done) | netcat -w 1 $RIGOL_IP 5555
  return
  
  [ $debug -gt 2 ] && echo "$cmds" >&2
  ($cmds) | netcat -w 1 $RIGOL_IP 5555
}



fetch_chunk(){
  send_cmd "$1"\
   | (shopt -s extglob;\
      read -N 1 -t 0.5 magichash;
      read -N 1 -t 0.5 lenofnum; 
      read -N $lenofnum -t 0.5 numofbytes; 
      [ $debug -gt 2 ] && echo "magic: $magichash; len: $lenofnum; bytes: ${numofbytes##*(0)}" >&2
      echo "${numofbytes##*(0)}" >&3
      if ! [ $(( ${numofbytes##*(0)} )) -gt 0 ]; then
        echo "TMC header error: magic: $magichash; len: $lenofnum; bytes_raw: ${numofbytes}" >&2
        exit 1
      fi
      head -c ${numofbytes##*(0)} ; 
     )\
}

w=0.2
bufferstart=1
send_cmd ':WAVeform:MODE RAW'
sleep $w
send_cmd ':SYST:ERR:next?'
sleep $w
send_cmd ':WAVeform:MODE?'
sleep $w
send_cmd ':SYST:ERR:next?'
sleep $w
send_cmd ":WAV:START $bufferstart"
sleep $w
send_cmd ':SYST:ERR:next?'
sleep $w
mdepth=`send_cmd ':ACQUIRE:MDEPTH?'`
sleep $w
send_cmd ':SYST:ERR:next?'
sleep $w
echo ":ACQUIRE:MDEPTH? -> $mdepth"
[ "$mdepth" -ne "24000000" ] && echo "mdepth-error" && exit 1

chunksize=200000
: > "$2"
while :; do
  bufferend=$(( bufferstart - 1 + chunksize ))
  if [ $bufferend -gt $mdepth ]; then
    bufferend=$mdepth
  fi;
  send_cmd ":WAV:STOP $bufferend"
  sleep $w
  send_cmd ':SYST:ERR:next?'
  sleep $w
  bytes_read=$(fetch_chunk "$1" 3>&1 >>"$2")
  sleep $w
  echo "`date +%H:%M:%S`   last read: start:$bufferstart; (+)bytes_read:$bytes_read; filesize: `ls -o $2|cut -d ' ' -f4,9`"
#  if [ "$bytes_read" == "" ]; then break; fi
  bufferstart=$(( bufferstart + bytes_read ))
  if [ $bufferstart -ge $mdepth ]; then 
    echo "total bytes read: $(( bufferstart - 1 )); finished"; 
    exit; 
  fi
  send_cmd ":WAV:START $bufferstart"
  sleep $w
  send_cmd ':SYST:ERR:next?'
  sleep $w
done
