#!/usr/bin/bash

# Created by John Chmielewski
# Last edited: July 12, 2023 by John Chmielewski

# Server Hangup Extension
# Script is not called if caller number or name is in ncidd.whitelist.
# Check for valid North American number plan callers.
# as described by https://en.wikipedia.org/wiki/North_American_Numbering_Plan
#
# This hangup script catches north american phone numbers with names that
# include a postal code inctead of a person or company.  For the Unites States
# it is usually <city> <state>

# if this file must be present
POSTALCODES=/etc/ncid/postal-codes

# Make sure you 'set hupmode = 1|2|3' in ncidd.conf.

# If using hupmode=3, change RECORDING to whatever you want to be played
# when this script indicates hangup.  Normally not needed because it will
# default to the 'set announce' value in ncidd.conf.
RECORDING="CannotBeCompleted.rmd"

########################
# Function Definitions #
########################

usage() {
   cat | more <<EOF

Usage: $script [options] <string>

       Server hangup extension to check for valid North American number plan callers.

       Input: The server passes one <string> on one line to this script:

              *DATE*<mmddyyyy>\\
              *TIME*<hhmm>\\
              *LINE*<lineid>\\
              *NMBR*<number>\\
              *MODE*<1|2|3>\\
              *FNMBR*<formatted number>\\
              *NTYPE*<type of device>\\
              *CTRY*<country code>\\
              *LOCA*<location>\\
              *CARI*<carrier>\\
              *NAME*<name>*

              <number> and <name> have already been changed to aliases
              if applicable.

              There is NO guarantee that the order of the field pairs will
              remain the same in future NCID versions (e.g., *LINE*<lineid>*
              might be moved to the end of the string). Your code must
              take this into account. This example script handles this
              properly.

              When testing, just use the input fields needed. This
              example script only requires the NMBR field. The <string>
              must be enclosed in double quotes.

              For example:
                  $script "*NMBR*4075551212*"

       Output: hupmode value received and description
               if hangup required:
                    if MODE=3, Recording: <file name or full path>
                    HangupReason: <brief reason text>
                    hangup
               if hangup not required:
                    OK

Options are only used for manual testing and are NEVER SENT by the server:

       [-h] [-v]

       -h = show this help

       -v = turns verbose on and sends additional data to STDOUT for
            troubleshooting

EOF
exit 1
}

hangup_exit()
{
   if [ "$MODE" = 3 ]; then
      echo "Recording: $RECORDING";
   fi
   [ -n "$HUPReason" ] && echo "HangupReason: $HUPReason"
   echo "hangup"
   exit 0
}

###############################
# End of function definitions #
###############################

script=`basename $0`

# Options on command line

show_usage=0

while getopts :hv opt ; do
    case $opt in
        h) show_usage=1;;
        v) verbose=1;;
       \?) echo "Invalid option: -$OPTARG"
           show_usage=1;;
        :) echo "Option -$OPTARG requires an argument."
           show_usage=1;;
    esac
done

[ $show_usage = 1 ] && usage

shift $((OPTIND-1)) # skip over command line args (if any)

# All passed fields from the server are parsed below, use only fields needed.
tmp=${1#*NAME?}; NAME=${tmp%%\**}
tmp=${1#*NMBR?}; NMBR=${tmp%%\**}
tmp=${1#*LINE?}; LINE=${tmp%%\**}
tmp=${1#*DATE?}; DATE=${tmp%%\**}
tmp=${1#*TIME?}; TIME=${tmp%%\**}
tmp=${1#*MODE?}; MODE=${tmp%%\**}

: ${NMBR:=_nmbr_} # default value if null
: ${NAME:=_name_} # default value if null
: ${MODE:=3}      # default value if null

HUPReason="name is <city> <state>"

if [ -n "$verbose" ]
then
    echo "NAME:  $NAME"
    echo "NMBR:  $NMBR"
    echo "LINE:  $LINE"
    echo "DATE:  $DATE"
    echo "TIME:  $TIME"
    echo "MODE:  $MODE"

   echo -n "Using HUPMODE $MODE - "
   case $MODE in
       1) echo "Normal hangup" ;;
       2) echo "FAX hangup" ;;
       3) echo "VOICE hangup" ;;
       *) echo "unknown MODE" ;;
   esac
fi

if [ -f $POSTALCODES ]
then
   # search $POSTALCODES for a postal code in $NAME
   POSTAL_CODE=`echo "$NAME" | sed 's/^[a-zA-Z0-9 ]* //'`
   if grep -q "$POSTAL_CODE$" $POSTALCODES
   then
      # postal code found in $NAME
      if [ -n "$verbose" ]; then
      echo "postal code found in name"
      fi
      hangup_exit
   else
      if [ -n "$verbose" ]; then
      echo "no postal code in name"
      fi
   fi
else
   # no $POSTALCODES file
   if [ -n "$verbose" ]; then
       echo "$POSTALCODES file not found"
   fi
fi

# the name looks good
echo "OK"
exit 0
