#!/bin/bash
#
# Get command to run
#
COMMAND="$1"
if [ -z "$COMMAND" ]
then
  echo "No command was specified"
  exit 1
fi
#
# Verify utilities are installed
#
requirementsOK=1
#
for prog in xpath xmlstarlet lua urlencode
do
  if [ -z `which $prog` ]
  then
    echo "$prog is required"
    requirementsOK=0
  fi
done
if [ "$requirementsOK" -eq 0 ]
then
  exit 1
fi
#
# URL at which to access WGMS web services entity API
#
URL='https://gliders.wgms.com/webservices/entityapi.asmx'
#
set -e
#
# All variables (COMMCHANNEL, EMAIL, PASSWORD, ORGID, ORGNAME,
# VEHICLEID, VIEWID) are defined in settings.txt
#
echo -en "*** Reading variables from settings.txt\n\n"
source settings.txt
#
# Only update credentials (re-login) if the credentials are
# more than 1 hour old
#
updatefile=0
if [ -f credentials ]
then
  FILETIME=`stat -c %Z credentials`
  NOW=`date +%s`
  AGE=`expr $NOW - $FILETIME`
  if [ "$AGE" -ge 3600 ]
  then
    echo "Credentials are stale ($AGE seconds old)"
    updatefile=1
  else
    echo "Credentials are in place ($AGE seconds old)"
  fi
else
  echo "Credentials are missing"
  updatefile=1
fi
#
# Perform login if indicated
#
if [ "$updatefile" -ne 0 ]
then
  echo -en "\n*** Logging in\n\n"
  logininfo="<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> <soap:Body><CreateLoginSession xmlns=\"http://gliders.liquidr.com/webservicesWebServices\"><login>"`echo "$EMAIL" | xmlstarlet esc`"</login><password>"`echo "$PASSWORD" | xmlstarlet esc`"</password><orgName>"`echo "$ORGNAME" | xmlstarlet esc`"</orgName></CreateLoginSession></soap:Body></soap:Envelope>"
  output=`curl 2>&1 -s -k -H 'Content-Type:text/xml;charset=utf-8' --dump-header credentials -H 'SOAPAction:' -d "$logininfo" -X POST "$URL"`
  set +e
  egrep >/dev/null '^Set-Cookie' credentials
  if [ "$?" -ne 0 ]
  then
    echo "Failed login: $output"
    exit 1
  fi
  set -e  
fi
#
# Create a command entity to execute the given command as Write
# Console Script command to board address 0 and function 0
#
#COMMAND="runshell date"
echo -en "\n\n*** Starting $COMMAND command for vehicle ID $VEHICLEID on comm channel $COMMCHANNEL\n\n"
cmdinfo="<CommandName>"`echo "Automated script" | xmlstarlet esc`"</CommandName><Payload_String>Write Console Script</Payload_String><CommandType>37120</CommandType><VehicleId>"`echo "$VEHICLEID" | xmlstarlet esc`"</VehicleId><CommunicationChannelSelect>"`echo "$COMMCHANNEL" | xmlstarlet esc`"</CommunicationChannelSelect><CommandStatus>0</CommandStatus><ScriptBuffer>"`echo "$COMMAND" | xmlstarlet esc`"</ScriptBuffer><GliderBoardAddress>0</GliderBoardAddress><OperationType>0</OperationType>"
entityxml="<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><CreateEntity xmlns=\"http://gliders.liquidr.com/webservicesWebServices\"><entityType>44</entityType><entityFieldXml>"`urlencode "<entity>$cmdinfo</entity>"`"</entityFieldXml></CreateEntity></soap:Body></soap:Envelope>"
echo -en "Un-encoded XML entity fields:\n\n$cmdinfo\n\nSOAP message:\n\n$entityxml\n\n"
output=`curl -s -X POST -L -b credentials -d "$entityxml" "$URL" --header "Content-Type:text/xml"`
echo -en "Output:\n\n$output\n\n"
entity=`echo "$output" | sed 's/[<][?]xml.*[?][>]//g' | xpath -q -e '/soap:Envelope/soap:Body/CreateEntityResponse/CreateEntityResult/text()'`
set +e
if [ -z "$entity" ]
then
  echo "No entity was returned!"
  exit 1
elif [ "$entity" -le 0 ]
then
  echo "Operation failed with $entity"
  exit 1
fi
set -e
echo "Entity: $entity"
#
# Read the entity to determine when the command status
# changes
#
timesleft=60
cmdstatus=0
set +e
while [ "$timesleft" -gt 0 -a "$cmdstatus" -lt 3 ]
do
  set -e
  timesleft=`expr $timesleft - 1`
  readxml="<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><ReadEntity xmlns=\"http://gliders.liquidr.com/webservicesWebServices\"><entityType>44</entityType><id>"`echo "$entity" | xmlstarlet esc`"</id></ReadEntity></soap:Body></soap:Envelope>"
  echo -en "\n*** Reading status of entity $entity (timesleft=$timesleft)\n"
  output=`curl -s -X POST -L -b credentials -d "$readxml" "$URL" --header "Content-Type:text/xml"`
  cmdstatus=`echo "$output" | sed 's/[<][?]xml.*[?][>]//g' | xpath -q -e '/soap:Envelope/soap:Body/ReadEntityResponse/ReadEntityResult/text()' | xmlstarlet unesc | sed 's/[<][?]xml.*[?][>]//g' | xpath -q -e '/DataSet/diffgr:diffgram/NewDataSet/Table1/CommandStatus/text()'`
  echo "Command Status: $cmdstatus"
  set +e
  if [ -z "$cmdstatus" ]
  then
    echo "No command status was returned!"
    exit 1
  elif [ "$cmdstatus" -lt 3 -a "$timesleft" -gt 0 ]
  then
    sleep 10
  fi
done
if [ "$cmdstatus" -ne 3 ]
then
  echo "Command status indicates failure or timeout"
  exit 1
fi
#
# Get the related entities
#
columnxml="<column type='id'>VehicleRawOutputId</column><column type='bound'>IMEI</column><column type='bound'>StructureType</column><column type='bound'>ParsedFlag</column><column type='bound'>CreatedOn</column><column type='bound'>TimeStamp</column><column type='bound'>Payload</column>"
encodedcolumnxml=`urlencode "<columns>$columnxml</columns>"`
getxml="<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><GetRelatedEntitySet xmlns=\"http://gliders.liquidr.com/webservicesWebServices\"><entityType>44</entityType><entityId>"`echo "$entity" | xmlstarlet esc`"</entityId><relatedEntityType>43</relatedEntityType><columnXml>$encodedcolumnxml</columnXml><pageNumber>1</pageNumber><pageSize>100</pageSize><sortColumn>CreatedOn</sortColumn><sortDirection>ASC</sortDirection><dataFilter></dataFilter></GetRelatedEntitySet></soap:Body></soap:Envelope>"
echo -en "\n\n*** Getting related entities to $entity\n\ncolumn XML:\n\n$columnxml\n\nSOAP Message:\n\n$getxml\n\n"
output=`curl -s -X POST -L -b credentials -d "$getxml" "$URL" --header "Content-Type:text/xml"`
echo "$output" | sed 's/[<][?]xml.*[?][>]//g' | xpath -q -e '/soap:Envelope/soap:Body/GetRelatedEntitySetResponse/GetRelatedEntitySetResult' | xmlstarlet unesc | sed 's/[<][?]xml.*[?][>]//g' | xpath -q -e '/GetRelatedEntitySetResult/DataSet/diffgr:diffgram/NewDataSet/Table1/Payload/text()' | ( index=1 ; while read payload
do
  echo "Response #$index:$payload"
  index=`expr $index + 1`
  echo "$payload" | lua -e 'line=io.read("*all") x={} for y in string.gmatch(line,"(..)") do table.insert(x,string.char(tonumber(y,16))) end w=table.concat(x) pyld=string.sub(w,52) ack=string.byte(pyld,1) len=256*string.byte(pyld,7)+string.byte(pyld,6) if (len+7 <= string.len(pyld)) then print("ACK="..tostring(ack)) print("Format="..tostring(string.byte(pyld,8))) print("Disposition="..tostring(string.byte(pyld,9))) strl=256*string.byte(pyld,11)+string.byte(pyld,10) print("Number of bytes="..tostring(strl)) print("Data="..string.sub(pyld,12,11+strl)) end'
done )




