3rd party apps development for the OBi 110/100

Started by QBZappy, October 03, 2011, 03:40:36 PM

Previous topic - Next topic

QBZappy

Well it has come to my attention that the "mother of all 3rd party apps for OBi devices" is graciously being offered by our long time friend and top contributor RonR.

Dial Plan Generator for OBi100/110/202
http://www.dslreports.com/forum/r28024065-Dial-Plan-Generator-for-OBi100-110-202

Welcome back to the voip cumminity. Considering that your offering at DSL Reports is an "OBi" Dial Plan Generator, it surely belongs in this thread, and on this forum.

Why don't you personally offer it to us in this thread.
Owner of the 1st OBi110/100 units in service in Canada & South America. 1st OBi202 on my street. 1st OBi1032 in Montreal.

John_Sauter

In the nearly two years since Stewart's posting ffmpeg has changed.  Instead of -ab 32000 you should use -ar 8k.  Here is the script I use to upload my Auto Attendant prompts:

#!/bin/bash
# Create with espeak -m -f <text file> -w <wave file>
# wave files for each synthesized Obihai prompt.
espeak -m -f welcome.txt -w welcome.wav
espeak -m -f main.txt -w main.wav
# Convert all of the prompts to g726 format using ffmpeg:
ffmpeg -y -i welcome.wav -acodec g726 -ar 8k user1.wav
ffmpeg -y -i noise_2sec.wav -acodec g726 -ar 8k user2.wav
ffmpeg -y -i main.wav -acodec g726 -ar 8k user3.wav
ffmpeg -y -i silence_1sec.wav -acodec g726 -ar 8k user4.wav
#
# Convert the user1.wav through up to user10.wav files
# into Okihai's upload format:
perl aa.pl
#
# Use the upload firmware feature of the Oki110.
# Specify the file useraa.dat created by the above
# perl script.  After a reboot the new voices
# will be available.
#

For completeness, and to prevent it from being lost, here is Stuart's perl program referenced above.  If this is whitespace-damaged you should download it from Stuart's original posting, a few replies ago in this thread.

#!/usr/bin/perl -w
use Digest::MD5 qw(md5);
$data = $names = '';
$filcnt = 0;
for $i (1 .. 10) {
    next unless open(IN, "user$i.wav");
    print "Reading user$i.wav\n";
    binmode(IN);
    unless (($cnt = read(IN, $rbuf, 60 * 4000)) > 1000 && $cnt < 60 * 4000
            && ($pos = index($rbuf, "data")) > 20 && $pos < 100) {
        print "Invalid size or format -- ignoring file\n";
        next;
    }
    $samps = ($cnt - $pos - 8) & ~7; # truncate to multiple of 8 bytes
    $names .= pack("a8 N N N", "\%USER$i\%", length($data), 0, 0);
    $data .= pack("N N", $samps, 0) . substr($rbuf, $pos + 8, $samps);
    ++$filcnt;
}
length($data) < 120 * 4000 or die "Total exceeds 120 seconds -- aborting\n";
$body = pack("N N", length($data), 0) . $data;
$body .= pack("N N", $filcnt, 0) . $names;
open(OUT, ">useraa.dat") or die "Can't write output file\n";
binmode(OUT);
print OUT "OBUSRLGE", pack("N", length($body)), md5($body), "\0\0\0\0", $body;
close(OUT) or die "Error writing output file\n";
print "Wrote useraa.dat\n";


DMcK

#22
Hi,

Here's my caller ID to xbmc and YAC Listener script!  It's not pretty, but it seems to work (with very little testing!)  You'll need a linux server for this to work. I'm using Ubuntu 12.04 and the following instructions are for that. You'll need to enable syslog on your OBi (System Management>Device Admin>Syslog and add your server IP, Port 514, Level 7)

~/YourScript.sh:
#!/bin/bash
##############
## lockfile ##
##############
exec 9>/tmp/callerid-lockfile
if ! flock -n 9  ; then
  exit 1
fi
# this script now runs under the lock until 9 is closed. it will be closed automatically when the script ends.

####################
##  Configuration ##
####################
LOGLOCATION="/var/log/obi202.log"    # the location of your syslog log
IPADDRESSSTART="192.168.0."   # only the first 3 values and dots for your LAN IP Address
XBMCIPs=(116 115 112)    # the last value(s) of the ip address(es) of your xbmc devices(s)
XBMCPORT="8080"        # default port for xbmc webserver
XBMCPOPUPDURATION="7000"     # in msecs (i.e., 7000 = an xbmc popup for 7 seconds)
YACIPs=(234 190)      # the last value(s) of ip address(es) for computer you want YAC popups
YACPORT="10629"     # default port for YAC is 10629.

####################################
##   Extract string from the log  ##
####################################
sleep 0.1        # allow a bit of time for log messages to complete.
STRINGFROMLOG=$(tac $LOGLOCATION | grep -B 1 -m1 'Command: 1, 3, 0, 0, 4, 1086133200,' | tac)         # invert log to find first line before "Command: 1, 3, 0...". This is the last Caller ID entry.
STRINGFROMLOG=$(sed -n -e 's/^.*1086133200, //p' <<< $STRINGFROMLOG)         # Strip off everything after "1086133200, " to leave just the CID info.
DATE=${STRINGFROMLOG:0:15}
UNIXDATE=$(date --date "$DATE" +%s)
NOW=$(date +%s)
TIMEDIFF=$(($NOW-$UNIXDATE))
if [ "$TIMEDIFF" -gt "10" ]    # if the current date/time and the date/time from the log are more that 10s apart, then the log updated from something other than an incoming call. exit.
then exit
fi
NAME=$(sed "s/.*'\(.*\)'[^']*$/\1/" <<< $STRINGFROMLOG)    # strip out the name between the single quotes
NAMEFORCURL=${NAME// /%20}                        # curl command doesn't like spaces so use %20 instead
NUMBER=$(sed 's/.*\ //' <<< $STRINGFROMLOG)       # gets all characters after the last space (i.e., the number)

####################
##  XBMC Portion  ##
####################
MIDDLE='","message":"'
END='"\},"displaytime":'$XBMCPOPUPDURATION',"id":1\}'
for i in ${XBMCIPs[@]}; do
   START='http://'$IPADDRESSSTART${i}':'$XBMCPORT'/jsonrpc?request=\{"jsonrpc":"2.0","method":"GUI.ShowNotification","params":\{"title":"'
   URL=$START$NAMEFORCURL$MIDDLE$NUMBER$END   # assemble the URL string for curl
   curl --request GET $URL    # send the notification request to xbmc
done

####################
##   YAC Portion  ##
####################
START="@CALL"
MIDDLE="~"
for i in ${YACIPs[@]}; do
   MESSAGE=$START$NAME$MIDDLE$NUMBER      # assemble the message string for netcat
   echo $MESSAGE| nc -w 1 $IPADDRESSSTART${i} $YACPORT       # send the message to the YAC Listeners
done

exit 0


Change the configuration section of the script as required. Enable the webserver (Settings>Services>Webserver>Allow control of XBMC via HTTP) in xbmc.  Install YAC on any computers you want Caller ID notification and put a YAC Listener shortcut in your start folder. If you have passwords set up in the xbmc webserver, you'll need to modify the START variable in the xbmc section accordingly (i.e., 'http://' becomes 'http://username:password@'.  

Make the script executable:
sudo chmod 777 ~/YourScript.sh

My syslog is going to /var/log/obi202.log. configure rsyslog to write the log file there:
sudo touch /var/log/obi202.log
sudo nano /etc/rsyslog.conf
->Add the following:
#
# Log from OBI202
#
local7.*    /var/log/obi202.log



Add the '-r" switch as shown below:
sudo nano /etc/default/rsyslog
->change the last line to:         RSYSLOGD_OPTIONS="-c5 -r"


I changed ownership of the file while testing. I think you'll need to also, but I'm not sure. It doesn't hurt:
sudo chown yourusername:yourusername /var/log/obi202.log

Rotate the log occasionally so it doesn't get too big:
sudo nano /etc/logrotate.d/obi202.log
->Add the following:
/var/log/obi202.log monthly
{
   rotate 4
   missingok
   notifyempty
   compress
   create }


restart rsyslog:
sudo service rsyslog restart

Change the ownership and permissions of the lockfile:
sudo chown yourusername:yourusername callerid-lockfile
sudo chmod 777 callerid-lockfile


I monitor the log file and launch the script using incron:
sudo apt-get install incron
sudo nano /etc/incron.allow
->Add this:    root
sudo incrontab -e
->Add this:   /var/log/obi202.log IN_MODIFY /bin/bash /home/yourusername/YourScript.sh


I think that's everything. With the exception of the script, much of that was from memory or some simple notes. So I hope I got it all.

Enjoy!

lucaspiller

Here is John's script in code tags, so that emoticons aren't processed.


#!/usr/bin/perl -w
use Digest::MD5 qw(md5);
$data = $names = '';
$filcnt = 0;
for $i (1 .. 10) {
    next unless open(IN, "user$i.wav");
    print "Reading user$i.wav\n";
    binmode(IN);
    unless (($cnt = read(IN, $rbuf, 60 * 4000)) > 1000 && $cnt < 60 * 4000
            && ($pos = index($rbuf, "data")) > 20 && $pos < 100) {
        print "Invalid size or format -- ignoring file\n";
        next;
    }
    $samps = ($cnt - $pos - 8) & ~7; # truncate to multiple of 8 bytes
    $names .= pack("a8 N N N", "\%USER$i\%", length($data), 0, 0);
    $data .= pack("N N", $samps, 0) . substr($rbuf, $pos + 8, $samps);
    ++$filcnt;
}
length($data) < 120 * 4000 or die "Total exceeds 120 seconds -- aborting\n";
$body = pack("N N", length($data), 0) . $data;
$body .= pack("N N", $filcnt, 0) . $names;
open(OUT, ">useraa.dat") or die "Can't write output file\n";
binmode(OUT);
print OUT "OBUSRLGE", pack("N", length($body)), md5($body), "\0\0\0\0", $body;
close(OUT) or die "Error writing output file\n";
print "Wrote useraa.dat\n";