function send_im($user, $recipient, $message, $opt, &$errors) { global $config, $lang_set; $sip_msg = "MESSAGE\n" . addslashes($recipient) . "\n" . ".\n" . "From: " . $user->get_uri() . "\n" . "To: <" . addslashes($recipient) . ">\n" . "p-version: " . $config->psignature . "\n" . "Contact: <" . $config->web_contact . ">\n" . "Content-Type: text/plain; charset=" . $lang_set['charset'] . "\n.\n" . str_Replace("\n.\n", "\n. \n", $message) . "\n.\n\n"; if ($config->use_rpc) { if (!$this->connect_to_xml_rpc(null, $errors)) { return false; } $params = array(new XML_RPC_Value($sip_msg, 'string')); $msg = new XML_RPC_Message('t_uac_dlg', $params); $res = $this->rpc->send($msg); if ($this->rpc_is_error($res)) { log_errors($res, $errors); return false; } } else { /* construct FIFO command */ $fifo_cmd = ":t_uac_dlg:" . $config->reply_fifo_filename . "\n" . $sip_msg; if (false === write2fifo($fifo_cmd, $errors, $status)) { return false; } /* we accept any status code beginning with 2 as ok */ if (substr($status, 0, 1) != "2") { $errors[] = $status; return false; } } return true; }
/** * delete contact from USRLOC * * @param string $uid UID of the owner of the contact * @param string $contact contact which should be removed * @param array $errors * @return bool TRUE on success, FALSE on failure */ function del_contact($uid, $contact, &$errors) { global $config; if ($config->use_rpc) { if (!$this->connect_to_xml_rpc(null, $errors)) { return false; } $params = array(new XML_RPC_Value($config->ul_table, 'string'), new XML_RPC_Value($uid, 'string'), new XML_RPC_Value($contact, 'string')); $msg = new XML_RPC_Message('usrloc.delete_contact', $params); $res = $this->rpc->send($msg); if ($this->rpc_is_error($res)) { log_errors($res, $errors); return false; } return true; } else { /* construct FIFO command */ $fifo_cmd = ":usrloc.delete_contact:" . $config->reply_fifo_filename . "\n" . $config->ul_table . "\n" . $uid . "\n" . $contact . "\n\n"; //contact $message = write2fifo($fifo_cmd, $errors, $status); if ($errors) { return false; } /* we accept any 2xx as ok */ if (substr($status, 0, 1) != "2") { $errors[] = $status; return false; } } return true; }
/** * reload domains table of SER from DB * * Possible options parameters: * none * * @param array $opt associative array of options * @param array $errors error messages * @return bool TRUE on success, FALSE on failure */ function reload_domains($opt, &$errors) { global $config; $ga_h =& Global_Attrs::singleton(); /* get current timestamp on DB server */ if (false === ($now = $this->get_DB_time(null))) { return false; } /* update attribute holding timestamp of last data change */ if (false === $ga_h->set_attribute($config->attr_names['domain_data_version'], $now)) { return false; } /* If notifing of sip proxies to reload the data is disabled, * finish here */ if (empty($config->domain_reload_ser_notify)) { return true; } /* If SER does not caches domain table, the reload is not needed * (and also is not possible) */ if (empty($config->ser_domain_cache)) { return true; } if ($config->use_rpc) { // if (!$this->connect_to_xml_rpc(null, $errors)) return false; $params = array(); $msg = new XML_RPC_Message('domain.reload', $params); $res = $this->rpc_send_to_all($msg, array('break_on_error' => false)); if (!$res->ok) { $cache_varning = false; foreach ($res->results as $v) { if (PEAR::isError($v)) { ErrorHandler::log_errors($v); if ($v->getCode() == 400) { $cache_varning = true; } } } if ($cache_varning) { sw_log("Domain reload failed. May be the domain cache in SER is disabled. " . "Try either enable the cache by set modparam(\"domain\", \"db_mode\", 1) " . "in your ser.cfg or disable reloading domains in serweb by setting " . "\$config->ser_domain_cache = false in config_data_layer.php", PEAR_LOG_ERR); } return false; } return true; } else { /* construct FIFO command */ $fifo_cmd = ":domain_reload:" . $config->reply_fifo_filename . "\n"; $message = write2fifo($fifo_cmd, $errors, $status); if ($errors) { return false; } if (substr($status, 0, 1) != "2") { $errors[] = $status; return false; } } return true; }
/** * reload domains table of SER from DB * * Possible options parameters: * none * * @param array $opt associative array of options * @param array $errors error messages * @return bool TRUE on success, FALSE on failure */ function reload_global_attrs($opt, &$errors) { global $config; $ga_h =& Global_Attrs::singleton(); /* get current timestamp on DB server */ if (false === ($now = $this->get_DB_time(null))) { return false; } /* update attribute holding timestamp of last data change */ if (false === $ga_h->set_attribute($config->attr_names['gattr_timestamp'], $now)) { return false; } /* If notifing of sip proxies to reload the data is disabled, * finish here */ if (empty($config->g_attrs_reload_ser_notify)) { return true; } if ($config->use_rpc) { // if (!$this->connect_to_xml_rpc(null, $errors)) return false; $params = array(); $msg = new XML_RPC_Message('gflags.reload', $params); $res = $this->rpc_send_to_all($msg, array('break_on_error' => false)); if (!$res->ok) { foreach ($res->results as $v) { if (PEAR::isError($v)) { ErrorHandler::log_errors($v); } } return false; } return true; } else { /* construct FIFO command */ $fifo_cmd = ":gflags.reload:" . $config->reply_fifo_filename . "\n"; $message = write2fifo($fifo_cmd, $errors, $status); if ($errors) { return false; } if (substr($status, 0, 1) != "2") { $errors[] = $status; return false; } } return true; }
/** * add contact to USRLOC * * @param string $uid uid of the owner of the contact * @param string $contact contact which should be added * @param string $expires when should the contact expire * @param array $errors * @return bool TRUE on success, FALSE on failure */ function add_contact($uid, $contact, $expires, &$errors) { global $config; $replication = "0"; $flags = "0"; if ($expires > 567640000 or $expires <= 0) { //contact that should expire later than 18 year, never expire $expires = -1; $flags = "128"; } if ($config->use_rpc) { if (!$this->connect_to_xml_rpc(null, $errors)) { return false; } $params = array(new XML_RPC_Value($config->ul_table, 'string'), new XML_RPC_Value($uid, 'string'), new XML_RPC_Value($contact, 'string'), new XML_RPC_Value($expires, 'int'), new XML_RPC_Value($config->ul_priority, 'double'), new XML_RPC_Value($flags, 'int')); $msg = new XML_RPC_Message('usrloc.add_contact', $params); $res = $this->rpc->send($msg); if ($this->rpc_is_error($res)) { log_errors($res, $errors); return false; } } else { /* construct FIFO command */ $fifo_cmd = ":usrloc.add_contact:" . $config->reply_fifo_filename . "\n" . $config->ul_table . "\n" . $uid . "\n" . $contact . "\n" . $expires . "\n" . $config->ul_priority . "\n" . $flags . "\n" . "\n"; $message = write2fifo($fifo_cmd, $errors, $status); if ($errors) { return false; } /* we accept any 2xx as ok */ if (substr($status, 0, 1) != "2") { $errors[] = $status; return false; } } return true; }
function _remove_cpl() { global $log; $log->log("call _remove_cpl"); global $config, $log; $fifo_cmd=":REMOVE_CPL:" . $config->reply_fifo_filename ."\n$this->uname@$this->udomain\n\n"; $log->log("writing to fifo:--\n$fifo_cmd--- ",LOG_DEBUG); write2fifo($fifo_cmd, $errors, $status); $log->log("wrote to fifo $status:$error",LOG_DEBUG); if (preg_match("/OK/", $status)) { return true ; } else { return false ; } }
function get_status($sip_uri, &$errors){ global $config; $reg=new Creg; if (!eregi("^sip:([^@]+@)?".$reg->host, $sip_uri, $regs)) return "<div class=\"statusunknown\">non-local</div>"; if (strtolower($regs[2])!=strtolower($config->default_domain)) return "<div class=\"statusunknown\">non-local</div>"; $user=substr($regs[1],0,-1); switch($this->container_type){ case 'sql': $q="select count(*) from ".$config->data_sql->table_subscriber. " where username='******' and domain='$config->realm'"; $res=$this->db->query($q); if (DB::isError($res)) {log_errors($res, $errors); return "<div class=\"statusunknown\">unknown</div>";} $row=$res->fetchRow(DB_FETCHMODE_ORDERED); $res->free(); if (!$row[0]) return "<div class=\"statusunknown\">non-existent</div>"; break; case 'ldap': die('NOT IMPLEMENTED: '.__FILE__.":".__LINE__); } $fifo_cmd=":ul_show_contact:".$config->reply_fifo_filename."\n". $config->ul_table."\n". //table $user."@".$config->default_domain."\n\n"; //username $out=write2fifo($fifo_cmd, $errors, $status); if ($errors) return; if (substr($status,0,3)=="200") return "<div class=\"statusonline\">on line</div>"; else return "<div class=\"statusoffline\">off line</div>"; }
function get_usrloc($uid, &$errors) { global $config, $sess; $contacts = array(); if ($config->use_rpc) { /* * get contacts useing xml-rpc and store them into array $contacts */ if (!$this->connect_to_xml_rpc(null, $errors)) { return false; } $params = array(new XML_RPC_Value($config->ul_table, 'string'), new XML_RPC_Value($uid, 'string')); $msg = new XML_RPC_Message('usrloc.show_contacts', $params); $res = $this->rpc->send($msg); if ($this->rpc_is_error($res)) { /* if usrloc of user is empty */ if ($res->getCode() == "404") { return array(); } log_errors($res, $errors); return false; } $val = $res->value(); if ($val->kindOf() != "array") { log_errors(PEAR::RaiseError("sorry invalid output from SER"), $errors); return false; } $size = $val->arraySize(); for ($i = 0; $i < $size; $i++) { $contact = $val->arrayMem($i); if ($contact->kindOf() != "struct") { log_errors(PEAR::RaiseError("sorry invalid output from SER"), $errors); return false; } $contacts[$i] = new stdClass(); $contacts[$i]->contact = $contact->structMem("contact"); $contacts[$i]->q = $contact->structMem("q"); $contacts[$i]->expires = $contact->structMem("expires"); $contacts[$i]->contact = $contacts[$i]->contact->scalarval(); $contacts[$i]->q = $contacts[$i]->q->scalarval(); $contacts[$i]->expires = $contacts[$i]->expires->scalarval(); } } else { /* * get contacts useing xml-rpc and store them into array $contacts */ $fifo_cmd = ":usrloc.show_contacts:" . $config->reply_fifo_filename . "\n" . $config->ul_table . "\n" . $uid . "\n" . "\n"; $fifo_out = write2fifo($fifo_cmd, $err, $status); if ($err) { $errors = array_merge($errors, $err); return false; } if (substr($status, 0, 1) != "2" and substr($status, 0, 3) != "404") { $errors[] = $status; return false; } /* * Example of FIFO output: * * expires:834277,q:1.000000,contact:sip\okk@kk.cz * expires:34303,q:1.000000,contact:sip\osdaf@dfdf.cd * expires:3335,q:0.000000,contact:sip\odsa@iptel.org * expires:3191,q:0.000000,contact:sip\osdaf@iptedfl.org */ $out_arr = explode("\n", $fifo_out); $i = 0; foreach ($out_arr as $val) { if (!ereg("^[[:space:]]*\$", $val)) { // if (ereg("<([^>]*)>;q=([0-9.]*);expires=(-?[0-9]*)", $val, $regs)){ if (ereg('expires:(-?[0-9]*),q:([0-9.]*),contact:(.*)$', $val, $regs)) { $contacts[$i] = new stdClass(); $contacts[$i]->contact = str_replace('\\o', ':', $regs[3]); $contacts[$i]->q = $regs[2]; $contacts[$i]->expires = $regs[1]; $i++; } else { log_errors(PEAR::RaiseError("sorry invalid output from fifo"), $errors); return false; } } } } /* * format array of contact for output */ $i = 0; $out = array(); foreach ($contacts as $val) { $exp_timestamp = time() + $val->expires; $expires = date('Y-m-d H:i', $exp_timestamp); if (substr($expires, 0, 10) == date('Y-m-d')) { $date = substr($expires, 11, 5); } else { $date = substr($expires, 0, 10); } // 567640000 means 18 years if ((int) $val->expires < 0 or (int) $val->expires > 567640000) { $date = "never"; $exp_timestamp = -1; } $out[$i]['uri'] = $val->contact; $out[$i]['q'] = $val->q; $out[$i]['expires'] = $date; $out[$i]['exp_timestamp'] = $exp_timestamp; $out[$i]['geo_loc'] = $this->get_location($val->contact, $errors); $i++; } return $out; }
function test_ser_management() { global $config; $out = ""; $errors = array(); $data = CData_Layer::singleton("auth_user", $errors); if ($config->use_rpc) { $out .= "SerWeb is configured to use XML-RPC to connect to SER<br />"; if (!$data->connect_to_xml_rpc(null, $errors)) { $out .= "Can't use XML-RPC. Error: " . implode("; ", $errors); return array(3, $out); } $params = array(); $msg = new XML_RPC_Message('core.version', $params); $res = $data->rpc->send($msg); if ($data->rpc_is_error($res)) { log_errors($res, $errors); $out .= "Can't use XML-RPC. Error: " . implode("; ", $errors); return array(3, $out); } $val = $res->value(); if ($val->kindOf() != "scalar") { $out .= "Can't use XML-RPC. Invalid output from SER"; return array(3, $out); } $out .= "connected to SER version: \"" . $val->scalarval() . "\""; } else { $out .= "SerWeb is configured to use FIFO to connect to SER<br />"; $fifo_cmd = ":core.version:" . $config->reply_fifo_filename . "\n" . "\n"; $fifo_out = write2fifo($fifo_cmd, $err, $status); if ($err) { $errors = array_merge($errors, $err); $out .= "Can't use FIFO. Error: " . implode("; ", $errors); return array(3, $out); } if (substr($status, 0, 1) != "2") { $errors[] = $status; $out .= "Can't use FIFO. Error: " . implode("; ", $errors); return array(3, $out); } $out .= "connected to SER version: \"" . $fifo_out . "\""; } return array(1, $out); }
function click_to_dial($target, $uri, &$errors){ global $config; $from="<".$config->ctd_from.">"; $callidnr = uniqid(""); $callid = $callidnr.".fifouacctd"; $cseq=1; $fixed_dlg="From: ".$from.";tag=".$callidnr."\nCall-ID: ".$callid."\nContact: <sip:caller@!!>"; $status=""; /* initiate dummy INVITE with pre-3261 "on-hold" (note the dots -- they mean in order of appearance: outbound uri, end of headers, end of body; eventualy the FIFO request must be terminated with an empty line) */ $fifo_cmd=":t_uac_dlg:".$config->reply_fifo_filename."\n". "INVITE\n". $uri."\n". ".\n". "$fixed_dlg\n". "To: <".$uri.">\n". "CSeq: ".$cseq." INVITE\n". 'Reject-Contact: *;automata="YES"'."\n". "Content-Type: application/sdp\n". ".\n". "v=0\n". "o=click-to-dial 0 0 IN IP4 0.0.0.0\n". "s=session\n". "c=IN IP4 0.0.0.0\n". "b=CT:1000\n". "t=0 0\n". "m=audio 9 RTP/AVP 0\n". "a=rtpmap:0 PCMU/8000\n". ".\n\n"; $dlg=write2fifo($fifo_cmd, $errors, $status); if (substr($status,0,1)!="2") {$errors[]=$status; return; } $dlg=filter_fl($dlg); $cseq++; // start reader now so that it is ready for replies // immediately after a request is out $fifo_cmd=":t_uac_dlg:".$config->reply_fifo_filename."\n". "REFER\n". $dlg. //"\n". "$fixed_dlg\n". "CSeq: ".$cseq." REFER\n". "Referred-By: ".$from."\n". "Refer-To: ".$target."\n". ".\n". ".\n\n"; write2fifo($fifo_cmd, $errors, $status); if (substr($status,0,1)!="2") {$errors[]=$status; return; } $cseq++; /* well, URI is trying to call TARGET but still maintains the dummy call we established with previous INVITE transaction: tear it down */ $fifo_cmd=":t_uac_dlg:".$config->reply_fifo_filename."\n". "BYE\n". $dlg. // "\n". $fixed_dlg."\n". "CSeq: ".$cseq." BYE\n". ".\n". ".\n\n"; write2fifo($fifo_cmd, $errors, $status); if (substr($status,0,1)!="2") {$errors[]=$status; return; } }
if ($errors) { foreach ($errors as $err) { echo $err . "\n"; } unset($errors); continue; } /* we accept any status code beginning with 2 as ok */ if (substr($status, 0, 1) != "2") { echo $status . "\n"; continue; } } if ($send_na) { //no data is accesible for this user, send n/a message $fifo_cmd = ":t_uac_from:" . $config->reply_fifo_filename . "\n" . "MESSAGE\n" . $config->metar_from_sip_uri . "\n" . "sip:" . $row->username . "@" . $config->default_domain . "\n" . "p-version: " . $config->psignature . "\n" . "Contact: " . $config->web_contact . "\n" . "Content-Type: text/plain; charset=UTF-8\n\n" . $config->metar_na_message . "\n.\n\n"; write2fifo($fifo_cmd, $errors, $status); if ($errors) { foreach ($errors as $err) { echo $err . "\n"; } unset($errors); continue; } /* we accept any status code beginning with 2 as ok */ if (substr($status, 0, 1) != "2") { echo $status . "\n"; continue; } } }