//
// Copyright 2009
// GPL v3 http://www.gnu.org/licenses/gpl.html
$sVersion = "20091115";
// November 15th 2009
// More problem with BASEURL
// It appears that a new URL is now used for call setup.
// phone-to-phone.php
// November 11th 2009
// Fixed a change done where all betamax use the /myaccount/ URL
// instead of the old /clx/ URL
// August 31st 2008
// Fixed a bug with creditcents for balances over €1000.
// June 22nd 2008. (Uwe Gellhaus)
// New .com clone (intervoip) , but different url base.
// Version: 1.2
// Dated: 2007 July 18th.
// Just a warning that text send here should be utf-8 encoded.
// I've adjusted the example to help things there.
//
// Added CallForwarding feature.
// Added Credit check and freeminutes to the functions instead of the example.
// Added Callerid to sent SMS messages. (They must be registered with your provider using their program first)
//
// Now we parse out the Telecom Service Providers GMT time ($iTSPtime) in Unix time. (Epoch)
// This is a help when sending immediate SMSes.
// A known problem with Summer / Winter time has appeared. Finarea/Betamax don't seem to understand time correctly.
// This version will work around that.
// Function tariffwizard added. Just like the webpage !! Although I can't see much use for it :)
// ***********************************************************************************************************
// * All functions return arrays with $iResult (An integer) and $sDebug (A text string).
// * In general $iResult should be 0 if the function worked sucessfully.
// ***********************************************************************************************************
//
// Creditcents, sms with caller-id(+ delayed sms) ,call and tariffwizard implemented so far.
//
// Feedback appreciated to junk at simong dot net or a comment at http://www.voip-info.org/wiki/view/Finarea+SA
//
// You need php with curl and ssl for curl.
// See http://www.php.net/curl
// *** See an example usage at http://www.simong.net/finarea/
// Don't forget to set (Done in the example.php script) ...
// $BASEURL = "https://myaccount.".$SERVICE.".com/clx"; // Where $SERVICE is the service name eg. voipstunt
// OR $BASEURL = "https://www.".$SERVICE.".com/myaccount"; // Where $SERVICE is intervoip
//
// Then do a login followed by gomainpage BEFORE calling the other functions (call, sms etc.)
$sCookie_File = "/tmp/".$_SERVER['REMOTE_ADDR'].":".$_SERVER['REMOTE_PORT'].".cookie"; // This is where to store the cookie file. Any better suggestions ?
// **************** Some functions *****************************************************************************
function http_arraytoxform ($aData){
$sDebug = "";
$iResult = 0;
reset ($aData);
$sData = "";
$iCount = 0;
while (list ($sKey, $sVal) = each ($aData)) {
$sDebug .= "[$sKey] => [$sVal]
\n";
if ( $iCount == 0 ) {
$sData .= ($sKey . "=" . $sVal);
$iCount += 1;
} else {
$sData .= ("&" . $sKey . "=" . $sVal);
}
}
return array($sData, $iResult, $sDebug);
}
function doRequest($sUrl, $sMethod="GET", $sVars="",$bRemoveCookie=FALSE) {
global $sCookie_File; // A little unsafe maybe.
$iResult = 0;
$sDebug = "DEBUG: URL is [".$sUrl."] Method is [".$sMethod."]
\n";
$sResponse = "";
$pCh = curl_init();
if ($pCh) {
curl_setopt($pCh, CURLOPT_URL, $sUrl);
curl_setopt($pCh, CURLOPT_HEADER, 1);
curl_setopt($pCh, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // Uses the browsers user-agent. Smart !! :)
curl_setopt($pCh, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($pCh, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($pCh, CURLOPT_COOKIEJAR, $sCookie_File);
curl_setopt($pCh, CURLOPT_COOKIEFILE, $sCookie_File);
curl_setopt($pCh, CURLOPT_SSL_VERIFYPEER, false); // Verify the sites ssl cert, or not(false).
// curl_setopt($AuthNetConn, CURLOPT_CAINFO, "path:/ca-bundle.crt"); // This points to your Certs authority bundle.
// curl_setopt($pCh, CURLOPT_CONNECTTIMEOUT, 15); // Wait max 15 seconds for connection.
// curl_setopt($pCh, CURLOPT_TIMEOUT, 30); // Wait max 30 for everything.
if ($sMethod == 'POST') {
curl_setopt($pCh, CURLOPT_POST, 1);
curl_setopt($pCh, CURLOPT_POSTFIELDS, $sVars);
}
$sData = curl_exec($pCh);
} else {
$sResponse = "ERROR: Couldnt init curl";
$iResult = 1 ;
$sDebug .= $sResponse;
}
if ($sData) {
$sResponse = $sData;
} else {
$iResult = 2 ;
$sResponse = "NO DATA \n";
$sResponse .= curl_error($ch);
$sDebug .= $sResponse;
}
curl_close($pCh);
if ( $bRemoveCookie === TRUE ){
// Remove cookie file
unlink($sCookie_File);
$sDebug .= "Cookie file [".$sCookie_File."] removed.
\n";
}
return array($sResponse, $iResult, $sDebug);
}
/**
*
* This function must be used before any other.
*
**/
function login($sUSER, $sPASS){
global $BASEURL;
$iResult = 0;
$sDebug = "";
$sDebug .= "DEBUG:BASEURL[".$BASEURL."]
\n"; // u[".$sUSER."]p[".$sPASS."]
\n";
list($sXform, $iThisResult, $sThisDebug) = http_arraytoxform (array("username" => $sUSER, "password" => $sPASS));
list($sContent, $iThisResult, $sThisDebug) =
doRequest($BASEURL."/", "POST", $sXform);
// Look for "logout.gif" If it exists then we managed to log-in.
$bLOGGEDIN = strpos(strtolower($sContent),"logout.gif"); // strtolower makes the search case-insensitive (Like grep -i)
// Convert the Boolean result to 1 and 0 (true false)
if ( $bLOGGEDIN === FALSE ){
$bResult = 0;
$iResult = 1;
$sDebug .= "DEBUG: doRequest[".$sThisDebug."]
\n";
$sDebug .= "DEBUG: Content[".htmlentities ($sContent)."]
\n";
} else {
$bResult = 1;
$sDebug .= "DEBUG:[Login successfull]
\n";
}
return array($bResult, $iResult, $sDebug);
}
/**
*
* This appears to be required after logging in.
* And now this is where we get the Telecom Service Providers current time $iTSP (in Unix Epoch)
* It is needed to generate the now time for sending immediate SMSes.
*
**/
function gomainpage() {
global $BASEURL;
$iResult = 0;
$sDebug = "";
list($sContent, $iThisResult, $sThisDebug) = doRequest($BASEURL."/index.php?part=menu&justloggedin=true");
$iTSPtime = 0; // Initialise variable.
// Parse eg. 200 OK\r\nDate: Sun, 25 Mar 2007 19:52:26 GMT
// Day , 01 May 2007 19:52:26 GMT
preg_match('/200 OK\r\nDate: ([a-z|A-Z]{3}), ([0-9]+) ([a-z|A-Z]{3}) ([0-9]{4}) ([0-9]+:[0-9]+:[0-9]+) (GMT)/',
htmlentities ($sContent), $aMatches);
if ( count($aMatches) == 7){ // 0 - 6
// Unix epoch. GMT
$iTSPtime = strtotime($aMatches[2]." ".$aMatches[3]." ".$aMatches[4]." ".$aMatches[5]." ". $aMatches[6]);
} else {
$sDebug .= "Couldn't get Telecom Server Time.
\n";
$iResult = 1;
}
//$sDebug .= "DEBUG:[".htmlentities ($sContent)."]
\n";
$sDebug .= "DEBUG : iTSPtime is [".$iTSPtime."] [".date('r',$iTSPtime)."]
\n";
return array($sContent, $iTSPtime, $iResult, $sDebug);
}
function freedays ($sMainPage) {
$iResult = 0;
$sDebug = "";
// Freedays remaining:
$bResult = preg_match('/.*Freedays remaining\:\
\([0-9]*).*\<\/span/', $sMainPage, $aMatches); //
//print_r($aMatches); // DEBUG
if ($bResult){
$iFreeDays = $aMatches[1];
} else {
$iFreeDays = 0;
}
return array($iFreeDays, $iResult, $sDebug);
}
function creditcents ($sMainPage) {
// Grep the remaining credit from the main page.
// Almost the same as the fincheck shell script.
$iResult = 0;
$sDebug = "";
preg_match('/.*Remaining credit[^0-9]+([0-9.,]+).*/', $sMainPage, $aMatches);
$iCreditCents = str_replace(",", "", $aMatches[1]); // Get rid of thousand separator (,)
$iCreditCents = ($iCreditCents * 100); // Convert to cents
return array($iCreditCents, $iResult, $sDebug);
}
function call($iSourceNum, $iDestNum){
global $BASEURL;
$sResult = "";
$iResult = 0;
$sDebug = "";
if (empty($iSourceNum)){
$sResult .= "No sourcenumber. "; // No source number
$sDebug .= "$sResult";
$iResult = 1;
}
if (empty($iDestNum)){
$sResult .= "No destination number. "; // No dest number
$sDebug .= "No destination number. ";
$iResult = 2;
}
if ($iResult == 0){
list($sXform, $iThisResult, $sThisDebug) = http_arraytoxform (array("action"=>"initcall",
"panel"=>"true", "anrphonenr"=>$iSourceNum, "bnrphonenr"=>$iDestNum));
//$sThisURL = $BASEURL."/webcalls2.php";
$sThisURL = $BASEURL."/phone-to-phone.php";
list($sContent, $iThisResult, $sThisDebug) =
doRequest($sThisURL, "POST", $sXform);
$sDebug .= "RequestURL= [".$sThisURL."] CONTENT [".htmlentities ($sContent)."]
\n"; // DEBUG
}
return array($sResult, $iResult, $sDebug);
}
// function sms($iDestNum,$sMsg,$iTime, $iGmtDiff=0,$iCallerId=0)
// Where $iTime is the Unix time (Epoch) to send the SMS.
// And You can use $iTSPtime from gomainpage function as $iTime to send NOW.
// Otherwise it uses your servers time. And you better be in sync with Betamax servers.
// And a fix here for the Finarea / Betamax Winter / Summer time problem.
function sms($iDestNum,$sMsg,$iTime=0, $iGmtDiff=0,$iCallerId=0){
$bUSE_OLD_METHOD = FALSE; // Use the old websms page on immediate(NOW) SMSes.
// NOTE: $iDestNum can be multiple numbers by comma separating them.
global $BASEURL;
$iResult = 0;
$sDebug = "";
if (empty($iDestNum)){
$sThisMsg = "No destination number. "; // No dest number
$sResult .= $sThisMsg;
$sDebug .= $sThisMsg;
$iResult += 1;
}
if (empty($sMsg)){
$sThisMsg = "No smstext. ";
$sResult .= $sThisMsg;
$sDebug .= $sThisMsg;
$iResult += 2;
}
$bSMSSent = FALSE;
if ( $iTime == 0) { // Immediate SMS
$bDelaySMS = FALSE;
if ($bUSE_OLD_METHOD === TRUE){ // Use the old method
$sDebug .= "Sending immediate SMS the OLD way
\n";
list($sXform, $iThisResult, $sThisDebug) = http_arraytoxform (array("action"=>"send",
"panel"=>"true", "message" => $sMsg, "bnrphonenumber"=>$iDestNum));
list($sContent, $iThisResult, $sThisDebug) =
doRequest($BASEURL."/websms.php", "POST", $sXform);
$bSMSSent = TRUE;
} else {
$sThisMsg = "Sending immediate SMS.
\n";
$iTime = time(); // Using THIS servers time !!
$sDebug .= $sThisMsg. "WARNING: Using this servers time[".$iTime."] [".date('r',$iTime)."].
\n";
}
} else { // Timed SMS
$bDelaySMS = TRUE;
$sThisMsg = "Sending timed or immediate SMS using TSPtime.
\n";
$sDebug .= $sThisMsg;
}
if ( $bSMSSent == FALSE ){ // We didn't send an immediate SMS the OLD way. So lets send one now.
// This script sends all messages using Betamax's version of GMT+1
// (Betamax has problems with GMT and Summertime breaks the GMT offset)
// Get the Month, day, hour, minute and GMT offset, All converted to GMT+1 (As Betamax sees it. ie. wrongly !!)
$iGMTTime = ($iTime + ($iGmtDiff * -1)); // Convert $iTime to GMT.
if (date('I', $iTime) == 1 ){ // Summer time. TODO Check if a setlocale() or something is needed here.
$iBetamaxGMTTime = ($iGMTTime + (60 * 60)); // +1 hour. WORKAROUND to Betamax problem.
$sDebug .= "Summertime.
\n";
} else { // Wintertime. Now Betamax understands the GMT offsets.
$iBetamaxGMTTime = $iGMTTime;
$sDebug .= "Wintertime.
\n";
}
// Now convert to GMT+1 (Or Betamax's GMT+1) WORKAROUND to Betamax problem.
$iBetamaxTime = ($iBetamaxGMTTime + (60 * 60)); // 1 hour
// Get the Month, day, hour, minute
$iMonthToSend = gmstrftime ('%m',$iBetamaxTime);
$iDayToSend = gmstrftime ('%d' ,$iBetamaxTime);
$iHourToSend = gmstrftime ('%H' ,$iBetamaxTime);
$iMinuteToSend = gmstrftime ('%M' ,$iBetamaxTime);
$iGmtDiff = 1; // GMT+1
//
// Send SMS
list($sXform, $iThisResult, $sThisDebug) = http_arraytoxform (array("action"=>"send",
"panel"=>"true", "message"=>$sMsg, "bnrphonenumber"=>$iDestNum, "day"=> $iDayToSend,
"month"=>$iMonthToSend, "hour"=>$iHourToSend, "minute"=>$iMinuteToSend,
"gmt"=>$iGmtDiff, "callerid"=>$iCallerId));
list($sContent, $iThisResult, $sThisDebug) =
doRequest($BASEURL."/websms2.php", "POST", $sXform);
//
} // END if ( $bSMSSent == FALSE
// Parse $sContent for result, Cents left etc.
// Attempt to check all went well ??
// It appears that the balance is returned on a successful POST.
// Grep for updateBalance("1860000"). Equals 1860 cents
$iThisResult = preg_match('/.*updateBalance\("([0-9]+).*/', $sContent, $aMatches);
if ( $iThisResult == 0 ){
$sResult .= "Failed to send sms
";
// Parse out some known faults.
$iThisFault = preg_match('/The send date and time is in the past./', $sContent, $aMatches);
if ( $iThisFault ){
$iResult += 4;
$sResult .= "ERROR: Send date/time is in the past. MM/DD HH:MM[".$iMonthToSend ."/". $iDayToSend ." ".
$iHourToSend .":". $iMinuteToSend." GMT ".$iGmtDiff."]
\n";
} else {
$iResult += 32; // Unknown SMS send fault.
$sResult .= "ERROR: Unknown SMS send fault
\n";
}
//
$sResult .= "See DEBUG below.
\n";
$sThisMsg = "CONTENT [".htmlentities ($sContent)."]
\n"; // DEBUG
$sDebug .= $sThisMsg. $sThisDebug;
} else {
$iCents = ($aMatches[1] / 1000);
$sDebug .= "Credit cents left is [".$iCents."] or €[".($iCents / 100)."]
\n";
}
//
return array($sResult, $iCents, $iResult, $sDebug);
} // END function sms
function tariffwizard ($iDestNum) {
// Check a telephone numbers cheapest Betamax service cost in cents per minute.
// I wrote this by mistake, thinking that I could check this service providers call cost :)
global $BASEURL;
$sResult = "";
$iResult = 0;
$sDebug = "";
list($sXform, $iThisResult, $sThisDebug) = http_arraytoxform (array("action"=>"showoverview",
"telephonenr"=>$iDestNum));
list($sContent, $iThisResult, $sThisDebug) =
doRequest($BASEURL."/tariffwizard.php", "POST", $sXform);
// Parse $sContent for Service, Provider type, Rate per minute, Callsetup and Additional info:
// wizardlog.php?url=http%3A%2F%2Fwww.justvoip.com%2F&bnr=
$iThisResult = preg_match('/wizardlog.php\?url=http\%3A\%2F\%2F([a-z.]+)\%2F\&bnr=/', $sContent, $aMatches);
$sUrl = $aMatches[1];
// Provider type:\n