The BePhoney Scripting Interface:

The BePhoneyd program will launch a particular file when it comes time to answer a call. This file is configured for each modem on the system and is always found in the scripts/ directory. The file needs to be executable and is usually written in some scripting language like bash, but it could be a C++ program. For the rest of this document I will call the file that is executed a script for simplicity.

BePhoneyd passes three arguments to the script. They are:

The script is free to do what it likes with this information. This includes doing nothing at all if it wants.

However, most scripts will want to tell BePhoneyd to do something with the call. There are two ways to do this. You can use a program included with BePhoney called "tellModem" to give commands to BePhoney or you can use the messaging API in the BeOS to send the commands yourself.

The tellModem Program:

The tellModem program is meant to be run from scripts or at a commandline (with this program, you can playback messages callers have left without dealing with the GUI if that's what you want). There are six different commands you can pass to BePhoneyd through tellModem:

CommandDescription
playThis command will play a voice message on the current device. If you follow the play command with a filename, it will attempt to play that file. If you omit the filename, it will play the greeting configured for this modem
recordThis command will attempt to record a message to the file that must be supplied after the record argument. It will record from the current device using the encoding supplied on the commandline or the default recording encoding configured for this modem
stopThis command will stop BePhoneyd from playing a message, recording a greeting or kill the login session of a user on a data call. It takes no argument after the command
contThis command will allow your script to continue waiting for some kind of event. For example, if you are playing a greeting and the caller presses DTMF 1, the tellModem command specifying the play will return that the DTMF was pressed. The script may decide to continue playing the greeting, in which case it can do a cont which will tell BePhoneyd to send the next event, error or successful termination of the playing of the greeting.
dataThis command is used to tell BePhoneyd to switch to data mode (if necessary) and start the executable specified after the data command on the modem. Normally you will use the "login" executable with the data command, but you could specify a BBS type program you have written etc.
faxThis command is used to tell BePhoneyd to switch to fax mode (if necessary) and receive a fax into the file specified.

Just before evey command, you must supply the name of the serial port you want this command run on. This is passed in as the second argument so you just need to pass it back. Optionally, with each of these commands, you can pass in an argument which changes the state of the modem:

OptionDescription
-VThis option will tell you the version of tellModem and give you usage information. It will not execute any command given to tellModem
-dThis option allows you to change the device the modem is currently connected to. You have to specify one of:
  • "onhook" which hangs up the modem
  • "offhook" which tells the modem to pick up the phone
  • "localphone" which tells the modem to use the telephone jack on the unit. This is normally used for recording or playing back messages
  • "microphone" which tells the modem to use the microphone jack on the unit. You cannot play messages on a microphone!
  • "speaker" which tells the modem to use the internal speaker. You cannot record messages on a speaker!
If the command specifies to play or record a message, the device is set and then the playing/recording starts. If the command is stop, the device is set after everything is stopped. It usually doesn't make sense to use this with cont.
-eThis option allows you to select the encoding used with recording. It will set the the encoding for playing, but if the encoding of the message is different from the encoding of the message, BePhoneyd will change it automatically. The encoding supplied must be one of:
  • "2bit" which is 2 bit ADPCM encoding
  • "3bit" which is 3 bit ADPCM encoding
  • "new3bit" which is new 3 bit ADPCM encoding
  • "4bit" which is 4 bit ADPCM encoding
  • "8bit" which is 7200 Hz PCM encoding
  • "8bit11025Hz" which is 11025 Hz PCM encoding
You will get an error if you try to use an encoding your modem doesn't support
-DThis option allows you to send a DTMF tone which I often use as a beep to indicate that a message is being recorded. You must specify a number from 0-9, *, #, A, B, C or D. The letters are not on standard phones but are tones that are defined and most modems can produce them

The tellModem program returns its results by sending them to standard output. The output can be one of:

It is worth noting that a record will never result in an "OK" since a recording is never really complete. It is up to the script to tell the modem to stop. You might do this when you detect silence or a hangup but that is entirely up to you.

Example tellModem Script:

Here is an example of a very basic script with no error checking that you can use to answer the phone and record an incoming message:

#!/bin/sh

cd "$1"
MODEM="$2"
MESSAGE="$3"

./tellModem -d offhook "$MODEM" play
./tellModem -D 6 "$MODEM" record "$MESSAGE"
./tellModem -d onhook "$MODEM" stop

The first thing I do in the script is set the current working directory to the install directory of BePhoney. I store the modem name and the path to the incoming call into a couple of variables. Then, I tell BePhoneyd to go offhook (answer the call) and play the default greeting on the modem. Once that finishes, I tell BePhoneyd to play a DTMF 6 (this is the beep before recording the message) and record the message into the path given to the script. Once that finishes, I tell BePhoneyd stop recording the message and go back onhook (hangup the phone). That's all there is to it.

If you want to get the results of the tellModem commands to take some action, the easiest thing is to do something like this:

RESULT=`./tellModem -d offhook "$MODEM" play`

The output from tellModem will be in the variable RESULT once the command has been run be BePhoneyd. You can use usual tools like "sed", "awk" or "grep" to decide what to do next.

For more complete examples, read the scripts in the scripts/ directory. I have tried to comment them a bit so people can understand what is going on but you need to know some bash to really figure it out.

But I don't want to use Bash:

And you don't have to. Other scripting languages like perl, tcl and python have been ported to the BeOS (I know a bit of perl, a bit more tcl and no Python for those thinking of asking me questions about these). As long as these languages allow you to run Be executables and capture standard output so you can parse it, you should be able to use the language to control BePhoneyd. Let me know if you successfully use another scripting language with BePhoney.

But I am writing my own Scripting Language:

If you are writing a scripting language and you are including support for Be's messaging system or you have access to such a scripting language, cool! Let me know!

This section will document the actual BMessages you can send to BePhoneyd to control its actions. These are only useful if you are writing your "script" in C++ or you have a scripting language with native BMessage support (I believe this is in the works for the python port).

BMessages should be sent to BePhoneyd by using a BMesseneger pointing to the "application/x-jsr-BePhoneyd" signature. Each message needs a specifier containing the name of the serial port the command is supposed to be sent to. I add the specifier in my code using something like:

aMessage.AddSpecifier("serial1");

I am not sure if I am using specifiers correctly since I really don't understand the documentation completely yet. If you know, send me some mail.

The "what" should be one of:

The message to record expects to get a entry_ref in the message called "Record". Similarly, the play message expects to get an entry_ref called "Play". If a message isn't passed in as an entry_ref called "Play", BePhoneyd will play the default greeting.

The message to start a data call expects to get a command in a string called "Command". It should be a full path to the command to run like "/bin/login".

The message to receive a fax takes an entry_ref called "Fax". This is the name of the file in which to store the incoming fax data.

Other things you can add to the message include:

BePhoneyd will send a reply to that message. The reply will be one of:

whatDescription
"VMok"This is sent by BePhoneyd to say that the command was completed successfully.
"VMer"This is sent by BePhoneyd to say that an error has occurred. A text description of the error can be found by looking at the "Why" string.
"VMev"This is sent by BePhoned to say that an event has occurred. The event can be found by looking for one of the following in the message:
  • "DTMF" is a Int8 that contains the DTMF that was received
  • "Fax" is a bool that has no particular value. The existance of this option indicates a fax tone was detected
  • "Max" is a bool that has no particular value. The existance of this option indicates the message being recorded has reached its maximum size
  • "Data" is a bool that has no particular value. The existance of this option indicates a data tone was detected
  • "Silence" is a bool that has no particular value. The existance of this option indicates a silence was detected
  • "Hungup" is a bool that has no particular value. The existance of this option indicates a hangup was detected

That should be enough information to send and receive BMessage to and from BePhoneyd and control its actions. If you are having any problems scripting BePhoneyd or you don't understand something in the documentation, mail me at jrand@magma.ca.