You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

344 lines
14 KiB

12 years ago
12 years ago
12 years ago
12 years ago
  1. <?php
  2. class JingletoSDP {
  3. private $sdp = '';
  4. private $jingle;
  5. private $action;
  6. // Only used for ICE Candidate (Jingle transport-info)
  7. public $media;
  8. private $values = array(
  9. 'session_sdp_id' => 1,
  10. 'session_version' => 0,
  11. 'nettype' => 'IN',
  12. 'addrtype' => 'IP4',
  13. 'unicast_address' => '0.0.0.0'
  14. );
  15. function __construct($jingle) {
  16. $this->jingle = $jingle;
  17. if(isset($this->jingle->attributes()->sid)) {
  18. $sid = (string)$this->jingle->attributes()->sid;
  19. //$sid = substr(base_convert($sid, 30, 10), 0, 6);
  20. $s = Session::start();
  21. $s->set('jingleSid', $sid);
  22. //$this->values['session_id'] = $sid;
  23. }
  24. $this->action = (string)$this->jingle->attributes()->action;
  25. }
  26. function getSessionId(){
  27. $s = Session::start();
  28. /*if($sid = $s->get('jingleSid')){
  29. return $sid;
  30. }
  31. else{
  32. $sessid = $this->jingle->attributes()->sid;
  33. return substr(base_convert($sessid, 30, 10), 0, 6);
  34. }*/
  35. return substr(base_convert($s->get('jingleSid'), 30, 10), 0, 6);
  36. }
  37. function generate() {
  38. if($this->jingle->attributes()->initiator) {
  39. $username = explode('@', (string)$this->jingle->attributes()->initiator);
  40. $username = $username[0];
  41. } else
  42. $username = '-';
  43. $this->values['session_sdp_id'] = $this->getSessionId();
  44. $sdp_version =
  45. 'v=0';
  46. $sdp_origin =
  47. 'o='.
  48. $username.' '.
  49. $this->values['session_sdp_id'].' '.
  50. $this->values['session_version'].' '.
  51. $this->values['nettype'].' '.
  52. $this->values['addrtype'].' '.
  53. $this->values['unicast_address'];
  54. $sdp_session_name =
  55. 's=SIP Call'; // Use the sessid ?
  56. $sdp_timing =
  57. 't=0 0';
  58. $sdp_medias = '';
  59. foreach($this->jingle->children() as $content) {
  60. $media_header_ids = array();
  61. $media_header_first_port = null;
  62. $media_header_last_ip = null;
  63. $sdp_media = '';
  64. // http://xmpp.org/extensions/xep-0338.html
  65. if((string)$content->getName() == 'group') {
  66. $sdp_media .=
  67. "\r\na=group:".
  68. (string)$content->attributes()->semantics;
  69. foreach($content->children() as $content) {
  70. $sdp_media .= " ".(string)$content->attributes()->name;
  71. }
  72. }
  73. if($content->getName() != 'content')
  74. break;
  75. if(isset($content->transport->attributes()->ufrag))
  76. $sdp_media .= "\r\na=ice-ufrag:".$content->transport->attributes()->ufrag;
  77. if(isset($content->transport->attributes()->pwd))
  78. $sdp_media .= "\r\na=ice-pwd:".$content->transport->attributes()->pwd;
  79. if(isset($content->description)) {
  80. foreach($content->description->children() as $payload) {
  81. switch($payload->getName()) {
  82. case 'rtp-hdrext':
  83. $sdp_media .=
  84. "\r\na=extmap:".
  85. $payload->attributes()->id;
  86. if(isset($payload->attributes()->senders))
  87. $sdp_media .= ' '.$payload->attributes()->senders;
  88. $sdp_media .= ' '.$payload->attributes()->uri;
  89. break;
  90. case 'rtcp-mux':
  91. $sdp_media .=
  92. "\r\na=rtcp-mux";
  93. case 'encryption':
  94. if(isset($payload->crypto)) {
  95. $sdp_media .=
  96. "\r\na=crypto:".
  97. $payload->crypto->attributes()->tag.' '.
  98. $payload->crypto->attributes()->{'crypto-suite'}.' '.
  99. $payload->crypto->attributes()->{'key-params'};
  100. // TODO session params ?
  101. }
  102. if(isset($payload->{'zrtp-hash'})) {
  103. $sdp_media .=
  104. "\r\na=zrtp-hash:".
  105. $payload->{'zrtp-hash'}->attributes()->version.' '.
  106. (string)$payload->{'zrtp-hash'};
  107. }
  108. break;
  109. case 'payload-type':
  110. $sdp_media .=
  111. "\r\na=rtpmap:".
  112. $payload->attributes()->id;
  113. array_push($media_header_ids, $payload->attributes()->id);
  114. if(isset($payload->attributes()->name)) {
  115. $sdp_media .= ' '.$payload->attributes()->name;
  116. if(isset($payload->attributes()->clockrate)) {
  117. $sdp_media .= '/'.$payload->attributes()->clockrate;
  118. if(isset($payload->attributes()->channels)) {
  119. $sdp_media .= '/'.$payload->attributes()->channels;
  120. }
  121. }
  122. }
  123. $first_fmtp = true;
  124. foreach($payload->children() as $param) {
  125. switch($param->getName()) {
  126. case 'rtcp-fb' :
  127. $sdp_media .=
  128. "\r\na=rtcp-fb:".
  129. $param->attributes()->id.' '.
  130. $param->attributes()->type;
  131. if(isset($param->attributes()->subtype)) {
  132. $sdp_media .= ' '.$param->attributes()->subtype;
  133. }
  134. break;
  135. // http://xmpp.org/extensions/xep-0167.html#format
  136. case 'parameter' :
  137. if($first_fmtp) {
  138. $sdp_media .=
  139. "\r\na=fmtp:".
  140. $payload->attributes()->id.
  141. ' ';
  142. } else {
  143. $sdp_media .= '; ';
  144. }
  145. if(isset($param->attributes()->name)) {
  146. $sdp_media .=
  147. $param->attributes()->name.
  148. '=';
  149. }
  150. $sdp_media .=
  151. $param->attributes()->value;
  152. $first_fmtp = false;
  153. break;
  154. }
  155. // TODO rtcp_fb_trr_int ?
  156. }
  157. break;
  158. /*case 'source':
  159. foreach($payload->children() as $s) {
  160. $sdp_media .=
  161. "\r\na=ssrc:".$payload->attributes()->id.' '.
  162. $s->attributes()->name.':'.
  163. $s->attributes()->value;
  164. }
  165. break;*/
  166. }
  167. // TODO sendrecv ?
  168. }
  169. }
  170. if(isset($content->description)
  171. && isset($content->description->attributes()->ptime)) {
  172. $sdp_media .=
  173. "\r\na=ptime:".$content->description->attributes()->ptime;
  174. }
  175. if(isset($content->description)
  176. && isset($content->description->attributes()->maxptime)) {
  177. $sdp_media .=
  178. "\r\na=maxptime:".$content->description->attributes()->maxptime;
  179. }
  180. foreach($content->transport->children() as $payload) {
  181. switch($payload->getName()) {
  182. case 'fingerprint':
  183. if(isset($content->transport->fingerprint->attributes()->hash)) {
  184. $sdp_media .=
  185. "\r\na=fingerprint:".
  186. $content->transport->fingerprint->attributes()->hash.
  187. ' '.
  188. $content->transport->fingerprint;
  189. }
  190. if(isset($content->transport->fingerprint->attributes()->setup)) {
  191. $sdp_media .=
  192. "\r\na=setup:".
  193. $content->transport->fingerprint->attributes()->setup;
  194. }
  195. break;
  196. // http://xmpp.org/extensions/inbox/jingle-dtls.html
  197. case 'sctpmap':
  198. $sdp_media .=
  199. "\r\na=sctpmap:".
  200. $payload->attributes()->number.' '.
  201. $payload->attributes()->protocol.' '.
  202. $payload->attributes()->streams.' '
  203. ;
  204. array_push($media_header_ids, $payload->attributes()->number);
  205. break;
  206. case 'candidate':
  207. $sdp_media .=
  208. "\r\na=candidate:".
  209. $payload->attributes()->foundation.' '.
  210. $payload->attributes()->component.' '.
  211. $payload->attributes()->protocol.' '.
  212. $payload->attributes()->priority.' '.
  213. $payload->attributes()->ip.' '.
  214. $payload->attributes()->port.' '.
  215. 'typ '.$payload->attributes()->type;
  216. if(isset($payload->attributes()->{'rel-addr'})
  217. && isset($payload->attributes()->{'rel-port'})) {
  218. $sdp_media .=
  219. ' raddr '.$payload->attributes()->{'rel-addr'}.
  220. ' rport '.$payload->attributes()->{'rel-port'};
  221. if($media_header_first_port == null)
  222. $media_header_first_port = $payload->attributes()->port;
  223. }
  224. if(isset($payload->attributes()->generation)) {
  225. $sdp_media .=
  226. ' generation '.$payload->attributes()->generation.
  227. ' network '.$payload->attributes()->network.
  228. ' id '.$payload->attributes()->id;
  229. }
  230. $media_header_last_ip = $payload->attributes()->ip;
  231. break;
  232. }
  233. }
  234. if($media_header_first_port == null)
  235. $media_header_first_port = 1;
  236. if($media_header_last_ip == null)
  237. $media_header_last_ip = '0.0.0.0';
  238. if(isset($content->description))
  239. $this->media = (string)$content->description->attributes()->media;
  240. else
  241. $this->media = (string)$content->attributes()->name;
  242. if($this->action != 'transport-info') {
  243. $sdp_media_header =
  244. "\r\nm=".$this->media.
  245. ' '.$media_header_first_port.' ';
  246. if(isset($content->transport->sctpmap)) {
  247. $sdp_media_header .= 'DTLS/SCTP';
  248. } elseif(isset($content->description->crypto)
  249. || isset($content->transport->fingerprint)) {
  250. $sdp_media_header .= 'RTP/SAVPF';
  251. } else {
  252. $sdp_media_header .= 'RTP/AVP';
  253. }
  254. $sdp_media_header = $sdp_media_header.' '.implode(' ', $media_header_ids);
  255. $sdp_medias .=
  256. $sdp_media_header.
  257. "\r\nc=IN IP4 ".$media_header_last_ip.
  258. $sdp_media;
  259. //"\r\na=sendrecv";
  260. } else {
  261. $sdp_medias = $sdp_media;
  262. }
  263. }
  264. if($this->action != 'transport-info') {
  265. $this->sdp .= /*"\r\n".*/$sdp_version;
  266. $this->sdp .= "\r\n".$sdp_origin;
  267. $this->sdp .= "\r\n".$sdp_session_name;
  268. $this->sdp .= "\r\n".$sdp_timing;
  269. }
  270. $this->sdp .= $sdp_medias;
  271. return $this->sdp."\r\n";
  272. }
  273. }