-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathSipRouter.php
77 lines (70 loc) · 2.07 KB
/
SipRouter.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<?php
class SipRouter
{
public $domain;
// 经过预处理的路由表
private $table = array(
//array(in_from, in_to, out_from, out_to),
// TESTING: 收到 *->2005 时,转换成 2005->1001
// TESTING: 收到 *->221 时,转换成 221->231
array('*', '2005', '2005', '1001'),
array('*', '221', '221', '231'),
);
/*
输入一条 INVITE 消息,根据路由表配置,然后返回新的 INVITE 消息。新的消息
如果能直接送达,则直接返回。否则修改 uri, from, to,但保持 contact 不变。
*/
function route($msg){
$ret = new SipMessage();
$ret->method = 'INVITE';
$ret->uri = clone $msg->uri;
$ret->from = clone $msg->from;
$ret->to = clone $msg->to;
$ret->contact = clone $msg->contact; // 重写后的INVITE要保留原有的 contact
$ret->call_id = SIP::new_call_id();
$ret->from->set_tag(SIP::new_tag());
$ret->branch = SIP::new_branch();
$ret->cseq = SIP::new_cseq();
// 路由表处理
$from = $msg->from->username;
$to = $msg->to->username;
foreach($this->table as $item){
if($this->match_route($from, $to, $item)){
list($in_from, $in_to, $out_from, $out_to) = $item;
Logger::debug("rewrite {$from}->{$to} => {$out_from}->{$out_to}");
$ret->uri = new SipUri($out_to, $this->domain);
$ret->from = new SipContact($out_from, $this->domain);
$ret->to = new SipContact($out_to, $this->domain);
break;
}
}
return $ret;
}
private function match_route($from, $to, $route_item){
list($in_from, $in_to, $out_from, $out_to) = $route_item;
if(!$this->match_address($from, $in_from)){
return false;
}
if(!$this->match_address($to, $in_to)){
return false;
}
return true;
}
private function match_address($in, $conf){
if($conf === '*'){ // all
return true;
}
$ps = explode(',', $conf); // or
if(count($ps) > 1){
return in_array($in, $ps, true);
}
$ps = explode('-', $conf); // range
if(count($ps) == 2){
$min = intval($ps[0]);
$max = intval($ps[0]);
$in = intval($in);
return ($min<=$in) && ($in<=$max);
}
return $in === $conf; // equals
}
}