#!/usr/bin/php -q if (preg_match('/<([ 0-9]+)>/', $callerid, $match) ) { $cidn = trim($match[1]); } else // Did not find the <##...> look for the first number in the string to use as CID { if (preg_match('/([0-9]+)/', $callerid, $match) ) { $cidn = trim($match[1]); } else $cidn = -1; // I'm saying an error no caller id # found } // Check if we have an outstanding Wakeup Call file if ( $parm_chan_ext ) $dir_check = "$chan.$sta.call"; else $dir_check = "ext.$cidn.call"; if ($parm_debug_on) fputs( $stdlog, "Checking Directory [$parm_call_dir] Check=[$dir_check]\n" ); // I started to think we could have many outstanding wakup calls, but then // it got very confusing on how to delete just one of them. I wasn't about // to prompt each and every one. So I went back to JUST ONE wakeup call // But this will get a list of all of them incase of problems $outc=0; $dir_handle = opendir( $parm_call_dir ); while( $file = readdir($dir_handle ) ) { if ($parm_debug_on) fputs( $stdlog, "File=$file\n" ); // Check if we have an outstanding wakup call if (strstr( $file, $dir_check ) ) $out[$outc++] = $file; } closedir( $dir_handle ); //========================================================================= // This is where we interact with the caller. Answer the phone and so on //========================================================================= $rc = execute_agi( "ANSWER "); sleep(1); // Wait for the channel to get created and RTP packets to be sent // On my system the welcome you would only hear 'elcome' So I paused for 1 second if ( !$rc[result] ) $rc = execute_agi( "STREAM FILE welcome \"\" "); // They have an outstanding wakup call if ( $outc ) { $i = 0; while ( $out[$i] ) { $wtime = strtok( $out[$i], '.' ); if ($parm_debug_on) fputs( $stdlog, "wakeup found=$out[0] saying time $wtime\n" ); say_wakeup( $wtime ); $i++; } } // Check if any outstanding wakeup calls if ( $outc ) { // Start prompting them if they want to create or delete a wakeup call while ( !$rc[result] ) { if ( !$rc[result] ) $rc = execute_agi( "STREAM FILE for-wakeup-call \"12\" "); if ( !$rc[result] ) $rc = execute_agi( "STREAM FILE press-1 \"12\" "); if ( !$rc[result] ) $rc = execute_agi( "STREAM FILE to-cancel-wakeup \"12\" "); if ( !$rc[result] ) $rc = execute_agi( "STREAM FILE press-2 \"12\" "); if ( !$rc[result] ) { $rc = execute_agi( "WAIT FOR DIGIT 15000"); } if ( $rc[result] != -1 ) { if ( $rc[result] == 49 || $rc[result] == 50 ) { ; // Do nothing } else { // This was just for fun, if they press something other than 1 or 2 $rc[result] = 0; $rc = execute_agi( "STREAM FILE you-dialed-wrong-number \"\" "); $rc = execute_agi( "STREAM FILE wrong-try-again-smarty \"\" "); } } } } else // Default to Creating a wakeup call $rc[result] = '49'; // Process which key they pressed // I check most of my Return Codes incase the call is hung up // // Being a phone person, I want to be able to skip the prompts, so I allow for entry over // The prompts. Makes for more code, but make for quicker entry after you know what to key // switch( $rc[result] ) { case '49': // Pressed 1 - This is to schedule a NEW wakeup call { $rc[result] = 0; while ( !$rc[result] ) { $rc = execute_agi( "STREAM FILE please-enter-the \"0123456789\" "); if ( !$rc[result] ) $rc = execute_agi( "STREAM FILE time \"0123456789\" "); if ( !$rc[result] ) $rc = execute_agi( "STREAM FILE for \"0123456789\" "); if ( !$rc[result] ) $rc = execute_agi( "STREAM FILE your \"0123456789\" "); // If we get here, they haven't pressed anything yet. if ( !$rc[result] ) $rc = execute_agi( "GET DATA wakeup-call 15000 4"); if ( $rc[result] != -1 ) { if ($parm_debug_on) fputs( $stdlog, "We have num digits:" . strlen( $rc[result]) . "- $rc[result] \r\n\r\n" ); // This check how many digits, if 2 then they pre-pressed a digit, // Otherwise it will be 4 if ( strlen( $rc[result] ) == 2 ) { $num= $rc[result]-48; while ( strlen($num) < 4 && $rc[result] > 0 ) { $rc = execute_agi( "WAIT FOR DIGIT 15000"); if ( $rc[result] >= 48 && $rc[result] <= 57 ) $num .= $rc[result] - 48; else $rc[result] = 0; } if (strlen($num) == 4 ) $rc[result] = $num; } if ($parm_debug_on) fputs( $stdlog, "Checking Results [$rc[result]] \r\n\r\n" ); // They entered 4 digits, check if its a valid time or they hung up if ( $rc[result] > 2359 || strlen( $rc[result]) < 4 || substr($rc[result],2,2) > 59 || $rc[result] < 0) { $rc[result] = 0; //$rc = execute_agi( "STREAM FILE invalid \"\" "); //$rc = execute_agi( "STREAM FILE time \"\" "); $rc = execute_agi( "STREAM FILE please-try-again \"\" "); } if (strlen( $rc[result] ) == 4 && $rc[result] == 0 ) $rc[result] = -2; // Special 00:00 time } } if ( $rc[result] == -2 ) $rc[result] = '0000'; else if ( $rc[result] == -1 ) exit; // The user hung up // Save the time entered $wtime = $rc[result]; // We don't know who the user is, so if its less than 1300 it could be AM or PM, so prompt // them for am pm if ( $wtime != -1 && $wtime < 1300 ) { $rc[result] = 0; while ( !$rc[result] ) { if ( !$rc[result] ) $rc = execute_agi( "GET DATA 1-for-am-2-for-pm 15000 1"); } switch( $rc[result] ) { case '1': // Set to AM should be under 1159 or less if ( $wtime > 1159 ) $wtime -= 1200; $rc[result] = 0; break; case '2': // Set to PM should be equal or over 1200 if ( $wtime < 1159 ) $wtime += 1200; $rc[result] = 0; break; } } // At this point we have a millitary time in the $wtime variable if ( $parm_chan_ext ) { $wakefile = "$parm_temp_dir/$wtime.$chan.$sta.call"; $callfile = "$parm_call_dir/$wtime.$chan.$sta.call"; } else { $wakefile = "$parm_temp_dir/$wtime.ext.$cidn.call"; $callfile = "$parm_call_dir/$wtime.ext.$cidn.call"; } if ($parm_debug_on) fputs( $stdlog, "Wakeup File [$wakefile]\n" ); // Open up a wakeup file to write it out. $wuc = fopen( $wakefile, 'w'); if ( $wuc ) { // Delete any old Wakeup call files this one will override for ($i=0; $i < $outc; $i++ ) { if( file_exists( "$parm_call_dir/$out[$i]" ) ) { if ($parm_debug_on) fputs( $stdlog, "Unlinking Old File [$parm_call_dir/$out[$i]]\n" ); unlink( "$parm_call_dir/$out[$i]" ); } } // I've noticed that the other WAKEUP example has a different format. This worked for me // Here is where we either make the call to the Extension or the Channel. Extension // is the better way to go, but required the caller ID information. Where Channel // should always get you back to where you were called from, provided its on your system if ( $parm_chan_ext ) fputs( $wuc, "channel: $chan/$sta\n" ); else fputs( $wuc, "channel: Local/$cidn@$agivar[agi_context]\n" ); fputs( $wuc, "maxretries: $parm_maxretries\n"); fputs( $wuc, "retrytime: $parm_retrytime\n"); fputs( $wuc, "waittime: $parm_waittime\n"); fputs( $wuc, "callerid: $parm_wakeupcallerid\n"); fputs( $wuc, "application: $parm_application\n"); fputs( $wuc, "data: $parm_data\n"); fclose( $wuc ); $w = getdate(); $w['hours'] = substr( $wtime, 0, 2 ); $w['minutes'] = substr( $wtime, 2, 2 ); $time_wakeup = mktime( substr( $wtime, 0, 2 ), substr( $wtime, 2, 2 ), 0, $w[mon], $w[mday], $w[year] ); $time_now = time( ); if ($parm_debug_on) fputs( $stdlog, 'time_wakeup=' . date('l dS \of F Y h:i:s A', $time_wakeup) . " ($time_wakeup) | time_now=" . date('l dS \of F Y h:i:s A',$time_now) . " ($time_now)\n" ); if ( $time_wakeup <= $time_now ) $time_wakeup += 86400; // Add One Day on if ($parm_debug_on) fputs( $stdlog, 'Setting WAKEUP file to =' . date('l dS \of F Y h:i:s A', $time_wakeup) . " - $time_wakeup\n" ); touch( $wakefile, $time_wakeup, $time_wakeup ); rename( $wakefile, $callfile ); } else { // Couldn't open the file. Make sure you created the /var/lib/asterisk/wakeups directory if ($parm_debug_on) fputs( $stdlog, "Error opening file [$wakefile]\n" ); $rc = execute_agi( "STREAM FILE something-terribly-wrong \"\" "); if ( !$rc[result] ) $rc = execute_agi( "STREAM FILE goodbye \"\" "); if ( !$rc[result] ) $rc = execute_agi( "HANGUP"); exit; } // If we have a caller ID and waking up by extension say the extension number //if ( $cidn && $parm_chan_ext == 0 ) //{ // $rc = execute_agi( "STREAM FILE for \"\" "); // // if ( !$rc[result] ) // $rc = execute_agi( "STREAM FILE extension \"\" "); // // // if ( !$rc[result] ) // $rc = execute_agi( "SAY DIGITS $cidn \"\" "); // //} say_wakeup( $wtime ); $rc[result] = 0; } break; // This is the END Of a new wakeup call case '50': // Pressed 2 - Delete old wakeup calls { // Go through the list of old files and unlink/delete them for ($i=0; $i < $outc; $i++ ) { if( file_exists( "$parm_call_dir/$out[$i]" ) ) { if ($parm_debug_on) fputs( $stdlog, "Unlinking Wakeup File [$parm_call_dir/$out[$i]]\n" ); unlink( "$parm_call_dir/$out[$i]" ); } } // If Caller ID and recording by Extension then say the extension if ( $cidn && $parm_chan_ext == 0 ) { $rc = execute_agi( "STREAM FILE for \"\" "); if ( !$rc[result] ) $rc = execute_agi( "STREAM FILE extension \"\" "); $L = strlen( $cidn ); for( $i = 0; $i < $L && !$rc[result]; $i++ ) { $cid_digits = substr( $cidn, $i, 1 ); if ( !$rc[result] ) $rc = execute_agi( "SAY NUMBER $cid_digits \"\" "); } } $rc = execute_agi( "STREAM FILE wakeup-call-cancelled \"\" "); } break; } if ( !$rc[result] ) $rc = execute_agi( "STREAM FILE goodbye \"\" "); if ( !$rc[result] ) $rc = execute_agi( "HANGUP"); if ($parm_debug_on) fclose($stdlog); exit; } // ---------------------------------------------- // This will say military time in AM/PM format // ---------------------------------------------- function say_wakeup( $wtime ) { GLOBAL $stdin, $stdout, $stdlog, $parm_debug_on; $pm = 0; if ($wtime > 1159 ) { $wtime -=1200; $pm = 1; } if ($wtime <= 59 ) $wtime += 1200; if ( strlen( $wtime ) == 3 ) $wtime = '0' . $wtime; $h = substr( $wtime, 0, 2 ); $h1 = substr( $wtime, 0, 1 ); $h2 = substr( $wtime, 1, 1 ); $m = substr( $wtime, 2, 2 ); $m1 = substr( $wtime, 2, 1); $m2 = substr( $wtime, 3, 1); if ($parm_debug_on) fputs( $stdlog, "Wakeup time is set to $wtime\n" ); $rc = execute_agi( "STREAM FILE rqsted-wakeup-for \"\" "); if ( !$rc[result] ) { if ( $h1 == 0 ) $rc = execute_agi( "SAY NUMBER $h2 \"\""); else $rc = execute_agi( "SAY NUMBER $h \"\""); if ( !$rc[result] ) { if ($m == 0 ) $rc = execute_agi( "STREAM FILE digits/oclock \"\" "); else { if ( $m1 == 0 ) { $rc = execute_agi( "STREAM FILE digits/oh \"\" "); $rc = execute_agi( "SAY NUMBER $m2 \"\" "); } else $rc = execute_agi( "SAY NUMBER $m \"\""); } if ( !$rc[result] ) { if ( $pm ) $rc = execute_agi( "STREAM FILE digits/p-m \"\" "); else $rc = execute_agi( "STREAM FILE digits/a-m \"\" "); } } } } //-------------------------------------------------- // This function will send out the command and get // the response back //-------------------------------------------------- function execute_agi( $command ) { GLOBAL $stdin, $stdout, $stdlog, $parm_debug_on; fputs( $stdout, $command . "\n" ); fflush( $stdout ); if ($parm_debug_on) fputs( $stdlog, $command . "\n" ); $resp = fgets( $stdin, 4096 ); if ($parm_debug_on) fputs( $stdlog, $resp ); if ( preg_match("/^([0-9]{1,3}) (.*)/", $resp, $matches) ) { if (preg_match('/result=([-0-9a-zA-Z]*)(.*)/', $matches[2], $match)) { $arr['code'] = $matches[1]; $arr['result'] = $match[1]; if (isset($match[3]) && $match[3]) $arr['data'] = $match[3]; return $arr; } else { if ($parm_debug_on) fputs( $stdlog, "Couldn't figure out returned string, Returning code=$matches[1] result=0\n" ); $arr['code'] = $matches[1]; $arr['result'] = 0; return $arr; } } else { if ($parm_debug_on) fputs( $stdlog, "Could not process string, Returning -1\n" ); $arr['code'] = -1; $arr['result'] = -1; return $arr; } } ?>