<?
/**
 * VoiceOne Webservices Interface
 *
 * @package voiceone_webservices
 * @subpackage  Provisioning
 */

//******************************************************************************
//****************                Provisioning                 *****************
//******************************************************************************
function getProvClient($id){
  global $db;
  //set where string
  $where="";
  if((isset($id))&&($id!="")&&($id!=0)){
    $where="WHERE p.`id`=".$id."";
  }
  //get provisioning clients
  $qry="SELECT p.* ";
  $qry.="FROM `cw_prov_client` AS p ";
  $qry.="JOIN `cw_client` AS c ON c.id=p.id_client ";
  $qry.=$where." ";
  $qry.="ORDER BY c.`extension` ";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  while($arr=$res->FetchRow()) $ret[]=$arr;
  //return
  return $ret;
}
function putProvClient($client){
  global $db;
  //set update if provisioning client already exists
  if((isset($client["id"]))&&($client["id"]!="")&&($client["id"]!=0)){
    $id=$client["id"];
    delProvClient($id);
  }else{
    $id="null";
  }
  //insert provisioning client
  $qry="INSERT INTO `cw_prov_client`(`id`,`id_client`,`id_template`,`mac` ,`ip`,`external_ip`,`external_port`,`hostname`) ";
  $qry.="VALUES (".$id.",'".$client["id_client"]."','".$client["id_template"]."','".strtoupper(addslashes($client["mac"]))."',";
  $qry.="'".addslashes($client["ip"])."','".addslashes($client["external_ip"])."','".addslashes($client["external_port"])."','".addslashes($client["hostname"])."'); ";
  $res=$db->Execute($qry);
  //return
  if($res===false) return 0;
  else return 1;
}
function delProvClient($id){
  global $db;
  //If it exists, delete provisioning client
  if((isset($id))&&($id!="")&&($id!=0)){
    $qry="DELETE FROM `cw_prov_client` WHERE `id`=".$id." LIMIT 1";
    $res=$db->Execute($qry);
    if($res!==false) return 1; 
    else return 0;
  }else return 0;
}

function touchProvClient($id,$id_client){
  $entry=array(
      "id_client" => $id_client,
      "id_template" => 0,
      "mac" => "",
      "ip" => "",
      "external_ip" => "",
      "external_port" => ""
    );
  if((isset($id))&&($id!="")&&($id!=0)){
  	$entry["id"]=$id;
  }
  $ret=putProvClient($entry);
  return $ret;
}
function getProvClientFromEntity($id_client){
  global $db;
  if((isset($id_client))&&($id_client!="")&&($id_client!=0)){
    $qry="SELECT * FROM `cw_prov_client` WHERE `id_client`='".$id_client."'";
    $res=$db->Execute($qry);
    if($res===false) return 0;
    $ret=$res->FetchRow();
    return $ret;
  }
  return 0;
}
function getProvClientAddress($id){
  global $db;
  if((isset($id))&&($id!="")&&($id!=0)){
    $qry="SELECT pc.*, pt.`local`";
    $qry.="FROM `cw_prov_client` AS pc ";
    $qry.="JOIN `cw_prov_template` AS pt ON pt.`id`=pc.`id_template` ";
    $qry.="WHERE pc.`id`='".$id."'";
    $res=$db->Execute($qry);
    if($res===false) return 0;
    if($arr=$res->FetchRow()){
    	if(($arr["local"]==1)||($arr["local"]=="1")) $ret=$arr["ip"];
      else $ret=$arr["external_ip"].":".$arr["external_port"];
    }
    if(trim($ret)!="") return $ret;
  }
  return 0;
}
/*****************************  PHONE TYPE  ***********************************/
function getPhoneType($id){
  global $db;
  //set where string
  $where="";
  if((isset($id))&&($id!="")&&($id!=0)){
    $where="WHERE `id`='".$id."'";
  }
  //get provisioning clients
  $qry="SELECT * FROM `cw_prov_phone_type` ".$where."";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  while($arr=$res->FetchRow()) $ret[]=$arr;
  //return
  return $ret;
}
function putPhoneMac($macArr){
  global $db;
  $ret=1;
  if(is_array($macArr)){
    foreach($macArr as $p){
      if((!isset($p['id']))||($p['id']==0)){
        $ret=0;
        continue;
      }
      $qry="UPDATE `cw_prov_phone_type` SET ";
      $qry.="`mac`='".string2sql($p["mac"])."', ";
      $qry.="`check`='".string2sql($p["check"])."' ";
      $qry.="WHERE `id`='".string2sql($p["id"])."' ";
      $res=$db->Execute($qry);
      if(res===false) $ret=0;
    }
  }
  //return
  return $ret;
}
function getPhoneOptions($id){
  global $db;
  //check phone id
  if((!isset($id))||($id=="")||($id==0)) return 0;
  //get provisioning clients
  $qry="SELECT o.* ";
  $qry.="FROM `cw_prov_phone_option` AS po ";
  $qry.="JOIN `cw_prov_option` AS o ON po.`id_option`=o.`id` ";
  $qry.="WHERE po.`id_phone`='".$id."' ";
  $qry.="ORDER BY o.`description`,o.`name`";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  while($arr=$res->FetchRow()) $ret[]=$arr;
  //return
  return $ret;
}
/*****************************  TEMPLATE  *************************************/
function getProvTemplate($id){
  global $db;
  //set where string
  $where="";
  if((isset($id))&&($id!="")&&($id!=0)){
    $where="WHERE `id`='".$id."'";
  }
  //get provisioning template
  $qry="SELECT * FROM `cw_prov_template` ".$where." ORDER BY `name`,`id_phone`";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  while($arr=$res->FetchRow()){
    //get template's options
    $options=array();
    $qry="SELECT * FROM `cw_prov_template_option` WHERE `id_template`='".$arr["id"]."'";
    $res_opt=$db->Execute($qry);
    if($res_opt!==false){
      while($opt=$res_opt->FetchRow()){
        $options[]=array(
            "key"=>$opt["id_option"],
            "value"=>$opt["value"],
            "mode"=>$opt["mode"]
          );
      }
    }
    $arr["options"]=$options;
    $ret[]=$arr;
  }
  //return
  return $ret;
}
function putProvTemplate($template){
  global $db;
  if(!is_array($template)) return 0;
  if((isset($template["id"]))&&($template["id"]!="")&&($template["id"]!=0)){
    $id=$template["id"];
    delProvTemplate($id);
  }else{
    $id="NULL";
  }
  //put provisioning template
  $qry="INSERT INTO `cw_prov_template`(`id`,`id_phone`,`name`,`description`,`dhcp`,`local`,`netmask`,`gateway`,`domain`,`dns1`,`dns2`,";
  $qry.="`registrar`,`firmware`,`directory`,`http_username`,`http_password`,`http_scheme`,`ldap`) ";
  $qry.="VALUES ($id,'".addslashes($template["id_phone"])."','".addslashes($template["name"])."','".addslashes($template["description"])."',";
  $qry.="'".addslashes($template["dhcp"])."','".addslashes($template["local"])."','".addslashes($template["netmask"])."','".$template["gateway"]."',";
  $qry.="'".addslashes($template["domain"])."','".addslashes($template["dns1"])."','".addslashes($template["dns2"])."',";
  $qry.="'".addslashes($template["registrar"])."','".addslashes($template["firmware"])."','".addslashes($template["directory"])."',";
  $qry.="'".addslashes($template["http_username"])."','".addslashes($template["http_password"])."','".addslashes($template["http_scheme"])."',";
  $qry.="'".addslashes($template["ldap"])."'); ";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  if($id=="NULL") $id=$db->Insert_ID();
  //put template options
  if(is_array($template["options"])){
    foreach($template["options"] as $options){
      $qry="INSERT INTO `cw_prov_template_option`(`id_template`,`id_option`,`value`,`mode`) ";
      $qry.="VALUES ('".$id."','".$options["key"]."','".addslashes($options["value"])."','".addslashes($options["mode"])."'); ";
      $res_opt=$db->Execute($qry);
      if($res_opt===false) return 0;
    }
  }
  //return
  return 1;
}
function delProvTemplate($id){
  global $db;
  //check phone id
  if((!isset($id))||($id=="")||($id==0)) return 0;
  //delete template options
  $qry="DELETE FROM `cw_prov_template_option` WHERE `id_template`='".$id."' ";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  //delete template
  $qry="DELETE FROM `cw_prov_template` WHERE `id`='".$id."' ";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  //return
  return 1;
}
/*****************************  FIRMWARE  *************************************/
function getProvFirmware($id){
  global $db;
  //set where string
  $where="";
  if((isset($id))&&($id!="")&&($id!=0)) $where="WHERE `id`='".$id."'";
  //get provisioning template
  $qry="SELECT * FROM `cw_prov_firmware` ".$where." ORDER BY `id_phone`,`name`";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  while($arr=$res->FetchRow()){
    $ret[]=$arr;
  }
  //return
  return $ret;
}
function getProvFirmwareFromPhone($id_phone){
  global $db;
  if((!isset($id_phone))||($id_phone=="")||($id_phone==0)) return 0;
  //get provisioning template
  $qry="SELECT * FROM `cw_prov_firmware` WHERE id_phone='".$id_phone."' ORDER BY `name`";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  while($arr=$res->FetchRow()){
    $ret[]=$arr;
  }
  //return
  return $ret;
}
function putProvFirmware($firmware,$file_contents){
  global $db,$voiceoneWSDocumentRoot;
  if(!is_array($firmware)) return 0;
  //check write permission
  $file_path=$voiceoneWSDocumentRoot."/utility/provisioning/firmware/data/";
  if(trim($file_contents)!=""){
  	if((is_dir($file_path))&&(!is_writable($file_path))){
    	@chmod($file_path,777);
    }
    if(!is_writable($file_path)) return -1;
  }
  if((isset($firmware["id"]))&&($firmware["id"]!="")&&($firmware["id"]!=0)){
    $id=$firmware["id"];
    delProvFirmware($id,false);
  }else{
    $id="NULL";
  }
  //check tftp
  $phoneType=getPhoneType($firmware["id_phone"]);
  if((!is_array($phoneType))||(!is_array($phoneType[0]))) return 0;
  $tftp_file_name=$phoneType[0]['vendor'].$phoneType[0]['model'].".bin";
  if(($firmware["tftp"]!=1)&&($firmware["tftp"]!='1')){
    $firmware["tftp"]=0;
  }else{
    $qry="UPDATE `cw_prov_firmware` SET `tftp`='0' WHERE `id_phone`='".addslashes($firmware["id_phone"])."' ";
    $db->Execute($qry);
  }
  //put provisioning template
  $qry="INSERT INTO `cw_prov_firmware`(`id`,`id_phone`,`name`,`description`,`tftp`) ";
  $qry.="VALUES ($id,'".addslashes($firmware["id_phone"])."','".addslashes($firmware["name"])."',";
  $qry.="'".addslashes($firmware["description"])."','".addslashes($firmware["tftp"])."'); ";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  if($id=="NULL") $id=$db->Insert_ID();
  // open and write firmware file (if file doesn't exist crete it)
  $file_name="firmware_".$id.".bin";
  if(trim($file_contents)!=""){
    if($soapWrapper===true){
  		// if web service is emulated the file_content have to be decoded
      $file_contents=base64_decode($file_contents);
    }
    $filehandle=fopen($file_path.$file_name,'w');
    if(!(fwrite($filehandle,$file_contents)>0)) return 0; 
    if(!(fclose($filehandle)===true)) return 0;
  }
  // write tftp file
  if($firmware["tftp"]!=0){
    @unlink($file_path.$tftp_file_name);
    if(!(copy($file_path.$file_name,$file_path.$tftp_file_name)===true)) return 0; 
  }
  //delete tftp file if no firware is selected
  $qry="SELECT id ";
  $qry.="FROM `cw_prov_firmware` "; 
  $qry.="WHERE `id_phone`='".addslashes($firmware["id_phone"])."' ";
  $qry.="AND `tftp`='1' ";
  $res=$db->Execute($qry);
  if($res->RecordCount()==0){
    @unlink($file_path.$tftp_file_name);
  }
  //return
  return 1;
}
function delProvFirmware($id,$deleteFs=true){
  global $db,$voiceoneWSDocumentRoot;
  //check phone id
  if((!isset($id))||($id=="")||($id==0)) return 0;
  //get phone type
  $tftp_file_name='';
  $provFirmware=getProvFirmware($id);
  if((is_array($provFirmware))&&(is_array($provFirmware[0]))&&($provFirmware[0]['tftp']==1)){
    $phoneType=getPhoneType($provFirmware[0]["id_phone"]);
    if((is_array($phoneType))&&(is_array($phoneType[0]))){ 
      $tftp_file_name=$phoneType[0]['vendor'].$phoneType[0]['model'].".bin";
    }
  }
  //delete template
  $qry="DELETE FROM `cw_prov_firmware` WHERE `id`='".$id."' ";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  //delete from FS
  if($deleteFs){
  	@unlink($voiceoneWSDocumentRoot."/utility/provisioning/firmware/data/firmware_".$id.".bin");
    if(trim($tftp_file_name)!=''){
      @unlink($voiceoneWSDocumentRoot."/utility/provisioning/firmware/data/".$tftp_file_name);
    }
  }
  //return
  return 1;
}
/**
 * DEPRECATED
 */
function isFirmwareWritable(){
	global $voiceoneWSDocumentRoot;
  //verify if firmware/data is writable
  if(!(
  		(fileperms($voiceoneWSDocumentRoot."/utility/provisioning/firmware/data") & 0x0001)&&
      (fileperms($voiceoneWSDocumentRoot."/utility/provisioning/firmware/data") & 0x0002)&&
      (fileperms($voiceoneWSDocumentRoot."/utility/provisioning/firmware/data") & 0x0004)
      )
    ){
  	return $voiceoneWSDocumentRoot."/utility/provisioning/firmware/data";
  } 
  return "1";
}
/*****************************  DIRECTORY  ************************************/
function getProvDirectory($id){
  global $db;
  //set where string
  $where="";
  if((isset($id))&&($id!="")&&($id!=0)){
    $where="WHERE `id`='".$id."'";
  }
  //get provisioning template
  $qry="SELECT * FROM `cw_prov_directory` ".$where." ORDER BY `name` ";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  while($arr=$res->FetchRow()){
    //get template's options
    $contacts=array();
    $qry="SELECT dc.* ";
    $qry.="FROM `cw_prov_directory_contacts` AS dc ";
    $qry.="JOIN `cw_contacts` AS c ON c.`id`=dc.`id_contact` ";
    $qry.="WHERE dc.`id_directory`='".$arr["id"]."' ";
    $qry.="ORDER BY c.`order_field`";
    $res_con=$db->Execute($qry);
    if($res_con!==false){
      while($con=$res_con->FetchRow()){
        $contacts[]=array(
            "key"=>$con["id_contact"],
            "value"=>$con["type"]
          );
      }
    }
    $arr["contacts"]=$contacts;
    $ret[]=$arr;
  }
  //return
  return $ret;
}
function putProvDirectory($directory){
  global $db;
  if(!is_array($directory)) return 0;
  if((isset($directory["id"]))&&($directory["id"]!="")&&($directory["id"]!=0)){
    $id=$directory["id"];
    delProvDirectory($id);
  }else{
    $id="NULL";
  }
  //put provisioning template
  $qry="INSERT INTO `cw_prov_directory`(`id`,`name`,`description`,`phonenumber_prefix`,`mobile_prefix`) ";
  $qry.="VALUES ($id,'".addslashes($directory["name"])."','".addslashes($directory["description"])."',";
  $qry.="'".addslashes(trim($directory["phonenumber_prefix"]))."','".addslashes(trim($directory["mobile_prefix"]))."'); ";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  if($id=="NULL") $id=$db->Insert_ID();
  //put template options
  if(is_array($directory["contacts"])){
    foreach($directory["contacts"] as $contact){
      $qry="INSERT INTO `cw_prov_directory_contacts`(`id_directory`,`id_contact`,`type`) ";
      $qry.="VALUES ('".$id."','".$contact["key"]."','".addslashes($contact["value"])."'); ";
      $res_con=$db->Execute($qry);
      if($res_con===false) return 0;
    }
  }
  //return
  return 1;
}
function delProvDirectory($id){
  global $db;
  //check phone id
  if((!isset($id))||($id=="")||($id==0)) return 0;
  //delete template options
  $qry="DELETE FROM `cw_prov_directory_contacts` WHERE `id_directory`='".$id."' ";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  //delete template
  $qry="DELETE FROM `cw_prov_directory` WHERE `id`='".$id."' ";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  //return
  return 1;
}
//******************************************************************************
//*******************          PHONE ATIONS            *************************
//******************************************************************************
function templatePhoneAction($action,$id_template,$params,$http_username,$http_password,$http_scheme){
	global $db;
	//get provisioning clients
  $qry="SELECT id FROM `cw_prov_client` WHERE `id_template`='".$id_template."' ";
  $res=$db->Execute($qry);
  if($res===false) return 0;
  while($arr=$res->FetchRow()){
  	//error_log("phoneAction(".$action.",".getProvClientAddress($arr["id"]).",".$params.",".$http_username.",".$http_password.",".$http_scheme.");");
  	phoneAction($action,getProvClientAddress($arr["id"]),$params,$http_username,$http_password,$http_scheme);
  }
  //return
  return 1;
}
function phoneAction($action,$ip,$params,$http_username,$http_password,$http_scheme){
  //set url
  if((trim($action)=="")||(trim($ip)=="")) return 0;
  //set action
  $postval="";
  switch (trim($action)){
  	case "dial":
			$url="http://".$ip."/index.html";
    	$postval = "DIAL=Dial";
  	break;
    case "hangup":
			$url="http://".$ip."/index.html";
    	$postval = "DIAL=Dial";
  	break;
    case "ring":
    	$url="http://".$ip."/index.html";
    	$postval = "PLAY_RINGER:1=Play Ringer";
    break;
    case "reregister":
    	$url="http://".$ip."/index.html";
    	$postval = "REREGISTER:1=Re-Register";
    break;
    case "reboot":
    	$url="http://".$ip."/confirm.html";
    	$postval = "REBOOT=Yes";
    break;
    case "reset":
    	$url="http://".$ip."/confirm.html";
    	$postval = "RESET=Yes";
    break;
  }
  if($postval=="") return 0;
  if(is_array($params)){
  	foreach($params as $p){
    	$postval=trim($p["key"])."=".trim($p["value"])."&".$postval;
    }
  }  
  //set headers
  $ch = curl_init();                              // initialize curl handle
  curl_setopt($ch, CURLOPT_URL,$url);         		// set url to post to
  curl_setopt($ch, CURLOPT_FAILONERROR, 1);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);     // return into a variable
  curl_setopt($ch, CURLOPT_POST, 1);              // set POST method
  curl_setopt($ch, CURLOPT_POSTFIELDS, $postval); // add POST fields
  curl_setopt($ch, CURLOPT_TIMEOUT, 3);         	// times out after 4s
  //set authentication
  if((trim($http_username)!="")&&(trim($http_password)!="")){
  	if(($http_scheme==1)||($http_scheme=="1")) curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); // auth method digest
    else curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); 																				// auth method basic
    curl_setopt($ch, CURLOPT_USERPWD, trim($http_username).":".trim($http_password)); 							// auth username and password
  }
  //send request
  $result = curl_exec($ch);                       // run the whole process
  curl_close($ch);
	//return
	return 1;
}

?>