Mobile Medic

December 10, 2007

Mobile Medic

In Short: An application designed to improve the effectiveness of medical personnel in developing nations.

Why: The growing expansion of mobile phones into poor areas is far outpacing that of any other communications technology; that fact together with the numerous problems facing overworked, understaffed, and undertrained medical personnel present a very important and exciting opportunity.

Background:

The technical part (How it works):

  • Asterisk (open-source telephony program)
  • PHP (server – side programming language)
  • MySQL (data base program)

Asterisk Code

Calling a PHP script using the Asterisk Gateway Interface (AGI)


[redial_blm272]
exten => s,1,Answer();
exten => s,n,AGI(/home/blm272/asterisk_agi/mobileMedic.php);
exten => t,1,Hangup();

The PHP script (AKA the Heavy Lifting)


#!/usr/local/bin/php -q
require('/var/lib/asterisk/agi-bin/phpagi.php');
//set time limit
set_time_limit(60);
// SQL Query Helper Function
function sqlQuery($query)
{
global $mySql;
$data = null;
$result = mysql_query($query, $mySql);
# This set's up an associative array (key->value pair) for all of the data returned
if (sizeof($result) > 0)
{
$num_fields = mysql_num_fields($result);
$row_cnt = 0;
while ($row_data = mysql_fetch_array($result)) {
for ($cnt = 0; $cnt < $num_fields; $cnt++) {
$field_name = mysql_field_name($result, $cnt);
$data[$row_cnt][$field_name] = $row_data[$cnt];
}
$row_cnt++;
}
}
return $data;
}
//Audio Files turned into variables for convenience
$welcomeAudio = "/home/blm272/asterisk_sounds/welcomeAudio"; //welcome, please enter PIN
$mainMenuAudio = "/home/blm272/asterisk_sounds/mainMenuAudio"; //say main menu options
$extensionAudio = "/home/blm272/asterisk_sounds/extensionAudio"; //ask for extension
// Create an AGI Object
$agi = new AGI();
// Predefined AGI Variables, send them to the Asterisk console for debugging
$agi->conlog($agi->request["agi_request"]);
$agi->conlog($agi->request["agi_channel"]);
$agi->conlog($agi->request["agi_language"]);
$agi->conlog($agi->request["agi_uniqueid"]);
$agi->conlog($agi->request["agi_callerid"]);
$agi->conlog($agi->request["agi_dnid"]);
$agi->conlog($agi->request["agi_rdnis"]);
$agi->conlog($agi->request["agi_context"]);
$agi->conlog($agi->request["agi_extension"]);
$agi->conlog($agi->request["agi_priority"]);
$agi->conlog($agi->request["agi_enhanced"]);
$agi->conlog($agi->request["agi_accountcode"]);
$agi->conlog($agi->request["agi_network"]);
$agi->conlog($agi->request["agi_network_script"]);
// Database connection variables
$hostname = "itp.nyu.edu";
$dbname = "blm272";
$username = "blm272";
$password = "kvibn+6";
// Connect to the database
$mySql = mysql_connect($hostname, $username, $password) or die (mysql_error());
mysql_select_db($dbname, $mySql) or die(mysql_error());
//start dialplan
$agi->answer();
//$agi->wait(1);
//$agi->text2wav('Welcome to mobile medic. Please Enter Your PIN Number');
//$agi->stream_file($welcomeAudio); //answer and ask for pin (need to put in add new pin?)
//$agi->get_data($welcomeAudio);
$return = $agi->get_data($welcomeAudio);
$callerID = $agi->request["agi_callerid"];
if ($return['result'] > 0)
{
//$agi->get_data($welcomeAudio);
$extension = chr($return['result']);
$query ="INSERT INTO Voicemail (callerID, extension, time) VALUES ('" . $agi->request["agi_callerid"] ."', '" . $return['result'] . "', NOW())";
$insert_result = mysql_query($query, $mySql);
//$insert_result[2] = $extension;
//echo ($extension);
// Query the database to see if this caller has called before
$query = "SELECT id, extension, FROM Voicemail WHERE extension = '" . $return['result'] . "'";
$result = mysql_query($query, $mySql);
//$agi->say_number($ascii);
//$agi->text2wav('Thank you. Proceeding to Main Menu for'.' '.$agi->say_number($ascii));
echo ($result);
//$result = sqlQuery($query, $mySql);
if (sizeof($result) > 0)
{
//we got a result from the DB
$agi->conlog("Database ID: " . $result[0]['id']);
//play options menu and listen for response (get data = background)
$whereto = $agi->get_data($mainMenuAudio, 5000, 1);
if (is_numeric($whereto['result']))
{
$agi->conlog("Result: " . $whereto['result']);
$agi->say_number($whereto['result']);
//menu options start here
if ($whereto['result'] == 1) //emergency call to doctor
{
//ask for extension to call
$extension= $agi->get_data($extensionAudio); //max digits for extensions is 4
if(is_numeric($extension['result']))
{
$query = "SELECT doctorNumber, extension FROM Doctors WHERE extension = '". $extension['result'] . "'";
//Query DB to find doctor's number based on extension
//$query = "SELECT doctorNumber, extension FROM Doctors WHERE extension = '" . $extension['result'] . "'";
$result = SQLquery($query, $mySql);
//if (sizeof($result >0))
if (sizeof ($result > 0));
{
$agi->say_number($extension['result']);
//$docNum = 18312959612;
$docNum = $result[0]['doctorNumber'];
//$agi->say_number($result[0]['doctorNumber']);
$agi->exec('Dial', trim("SIP/itp_jnctn/" . $docNum . "|30|r"));
if (!$result)
{
die("Error " . mysql_errno() . " : " . mysql_error());
}
//$agi->goto("redial_blm272_sip","s",1);
}
}
}
elseif ($whereto['result'] == 2) //leave message in Doctor's VM, who then gets a text notification
{
//ask for extension to call
$extension= $agi->get_data($extensionAudio, 10000, 4); //max digits for extensions is 4
if(is_numeric($extension['result']))
{
$voicemail_location = "/home/blm272/asterisk_sounds/voicemail";
$callerID = $agi->request["agi_callerid"];
$record_file = $voicemail_location . time() . "vm" . $agi->request["agi_callerid"];
$agi->record_file($record_file, "WAV", "0123456789", 10000, 0, true, 5);
$query ="INSERT INTO Voicemail (callerID, record_file, time) VALUES ('" . $agi->request["agi_callerid"] . "', '" . $record_file . "', NOW())";
//$query = "insert into callers (caller_id, name_audio) values ('" . $agi->request["agi_callerid"] . "', '" . $record_file . "')";
$insert_result = mysql_query($query, $mySql);
$agi->stream_file($record_file);
if (!$result)
{
die("Error " . mysql_errno() . " : " . mysql_error());
}
}
else
{
//Timout
$agi->goto("redial_blm272","t",1);
}
}
elseif ($whereto['result'] == 3) //check messages from doctor
{
$testFile = "/home/blm272/asterisk_sounds/voicemail1197263266vm_blm272.wav";
$agi->stream_file($testFile);
$callerID = $agi->request["agi_callerid"];
$query = "SELECT callerID, record_file, time FROM Voicemail WHERE callerID = '". $agi->request["agi_callerid"] . "' ORDER BY time DESC";
$result = sqlQuery($query, $mySql);
if (sizeof($result) >0)
{
$agi->stream_file($result[0]['record_file']);
}
if (!$result)
{
die("Error " . mysql_errno() . " : " . mysql_error());
}
}
elseif ($whereto['result'] == 4) //exit (go back to PIN prompt via the dialplan)
{
function agi_goto($con='redial_blm272',$ext='s',$pri=1)
{
$this->goto($con, $ext, $pri);
}
}
else
{
// Timeout.. Probably (or send them back to the ask for PIN section...)
mysql_close ($mySql);
$agi->goto("redial_blm272","t",1);
}
}
}
}
?>

The PHP script sets up a gateway for asterisk and mysql to work together, forming a framework of user options based on dtmf input from any standard telephone.  This includes calling out directly to a doctor based on extension, directly leaving a voice mail in a specific directory, and listening to your own voice messages, with more options to come soon.
This code is not quite fully functional, but its most of the way there. Any tips or questions are also welcome.