1use std::fmt;
16use std::io::Read;
17use std::sync::Arc;
18
19use crate::ffi::log::platform_log;
20use crate::internet::body::Body;
21use crate::internet::body::BodySerializationError;
22use crate::internet::header;
23use crate::internet::header::headers_get_readers;
24use crate::internet::header::Header;
25use crate::internet::header_field::AsHeaderField;
26use crate::internet::header_field::HeaderField;
27
28use crate::io::DynamicChain;
29use crate::io::Serializable;
30
31use crate::sip::sip_dialog::GetDialogHeaders;
32use crate::sip::sip_headers::cseq::AsCSeq;
33
34use crate::util::raw_string::ToInt;
35
36const SIP2_0_BYTES: &[u8] = b"SIP/2.0";
37
38pub const ACK: &[u8] = b"ACK";
39pub const BYE: &[u8] = b"BYE";
40pub const CANCEL: &[u8] = b"CANCEL";
41pub const INVITE: &[u8] = b"INVITE";
42pub const MESSAGE: &[u8] = b"MESSAGE";
43pub const NOTIFY: &[u8] = b"NOTIFY";
44pub const OPTIONS: &[u8] = b"OPTIONS";
45pub const REFER: &[u8] = b"REFER";
46pub const REGISTER: &[u8] = b"REGISTER";
47pub const SUBSCRIBE: &[u8] = b"SUBSCRIBE";
48pub const UPDATE: &[u8] = b"UPDATE";
49
50const LOG_TAG: &str = "sip_message";
51
52pub enum SipVersion {
53 V2_0,
54}
55
56impl ToString for SipVersion {
57 fn to_string(&self) -> String {
58 match self {
59 SipVersion::V2_0 => return String::from("SIP/2.0"),
60 }
61 }
62}
63
64impl fmt::Debug for SipVersion {
65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66 f.write_str("SIP/2.0")
67 }
68}
69
70pub struct SipRequestLine {
71 pub method: Vec<u8>,
72 pub uri: Vec<u8>,
73 pub version: SipVersion,
74}
75
76impl SipRequestLine {
77 pub fn reader(&self) -> SipRequestLineReader {
78 SipRequestLineReader {
79 method: &self.method,
80 uri: &self.uri,
81 version: match self.version {
82 SipVersion::V2_0 => SipVersion::V2_0,
83 },
84 pos: 0,
85 }
86 }
87}
88
89impl Serializable for SipRequestLine {
90 fn estimated_size(&self) -> usize {
104 let mut size = 0;
105 size += self.method.len();
106 size += 1;
107 size += self.uri.len();
108 match &self.version {
109 SipVersion::V2_0 => {
110 size += 8;
111 }
112 }
113 size
114 }
115}
116
117impl fmt::Debug for SipRequestLine {
118 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119 write!(
120 f,
121 "{} {} {}",
122 String::from_utf8_lossy(&self.method),
123 String::from_utf8_lossy(&self.uri),
124 self.version.to_string()
125 )
126 }
127}
128
129pub struct SipRequestLineReader<'a> {
130 method: &'a [u8],
131 uri: &'a [u8],
132 version: SipVersion,
133 pos: usize,
134}
135
136impl<'a> Read for SipRequestLineReader<'a> {
137 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
138 let mut i = 0;
139 while self.pos + i < self.method.len() && i < buf.len() {
140 buf[i] = self.method[self.pos + i];
141 i += 1;
142 }
143 while self.pos + i >= self.method.len()
144 && self.pos + i < self.method.len() + 1
145 && i < buf.len()
146 {
147 buf[i] = b' ';
148 i += 1;
149 }
150 while self.pos + i >= self.method.len() + 1
151 && self.pos + i < self.method.len() + 1 + self.uri.len()
152 && i < buf.len()
153 {
154 buf[i] = self.uri[self.pos + i - self.method.len() - 1];
155 i += 1;
156 }
157 match self.version {
158 SipVersion::V2_0 => {
159 while self.pos + i >= self.method.len() + 1 + self.uri.len()
160 && self.pos + i < self.method.len() + 1 + self.uri.len() + 8
161 && i < buf.len()
162 {
163 buf[i] = b" SIP/2.0"[self.pos + i - self.method.len() - 1 - self.uri.len()];
164 i += 1;
165 }
166 }
167 }
168 self.pos += i;
169 Ok(i)
170 }
171}
172
173pub struct SipResponseLine {
174 pub version: SipVersion,
175 pub status_code: u16,
176 pub reason_phrase: Vec<u8>,
177}
178
179impl SipResponseLine {
180 pub fn reader(&self) -> SipResponseLineReader {
181 SipResponseLineReader {
182 version: match self.version {
183 SipVersion::V2_0 => SipVersion::V2_0,
184 },
185 status_code: format!("{:0>3}", self.status_code),
186 reason_phrase: &self.reason_phrase,
187 pos: 0,
188 }
189 }
190}
191
192impl Serializable for SipResponseLine {
193 fn estimated_size(&self) -> usize {
207 let mut size = 0;
208 match self.version {
209 SipVersion::V2_0 => {
210 size += 8;
211 }
212 }
213 size += self.status_code.to_string().len();
214 size += 1;
215 size += self.reason_phrase.len();
216 size
217 }
218}
219
220impl fmt::Debug for SipResponseLine {
221 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
222 write!(
223 f,
224 "{} {} {}",
225 self.version.to_string(),
226 self.status_code,
227 String::from_utf8_lossy(&self.reason_phrase)
228 )
229 }
230}
231
232pub struct SipResponseLineReader<'a> {
233 version: SipVersion,
234 status_code: String,
235 reason_phrase: &'a [u8],
236 pos: usize,
237}
238
239impl<'a> Read for SipResponseLineReader<'a> {
240 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
241 let mut i = 0;
242 let version_length;
243 match self.version {
244 SipVersion::V2_0 => {
245 version_length = 8;
246 while self.pos + i < 8 && i < buf.len() {
247 buf[i] = b"SIP/2.0 "[self.pos + i];
248 i += 1;
249 }
250 }
251 }
252 while self.pos + i >= version_length
253 && self.pos + i < version_length + self.status_code.as_bytes().len()
254 && i < buf.len()
255 {
256 buf[i] = self.status_code.as_bytes()[self.pos + i - version_length];
257 i += 1;
258 }
259 while self.pos + i >= version_length + self.status_code.as_bytes().len()
260 && self.pos + i < version_length + self.status_code.as_bytes().len() + 1
261 && i < buf.len()
262 {
263 buf[i] = b' ';
264 i += 1;
265 }
266 while self.pos + i >= version_length + self.status_code.as_bytes().len() + 1
267 && self.pos + i
268 < version_length + self.status_code.as_bytes().len() + 1 + self.reason_phrase.len()
269 && i < buf.len()
270 {
271 buf[i] = self.reason_phrase
272 [self.pos + i - version_length - self.status_code.as_bytes().len() - 1];
273 i += 1;
274 }
275 self.pos += i;
276 Ok(i)
277 }
278}
279
280pub enum SipFirstLine {
281 Request(SipRequestLine),
282 Response(SipResponseLine),
283}
284
285impl SipFirstLine {
286 pub fn decode_first_line(s: &[u8]) -> Result<Option<(SipFirstLine, usize)>, &str> {
287 let mut iter = s.iter();
288
289 if let Some(position) = iter.position(|c| *c == b'\r') {
290 if let Some(c) = iter.next() {
291 if *c == b'\n' {
292 let mut iter = s[..position].splitn(3, |c| *c == b' ');
293
294 if let Some(s1) = iter.next() {
295 if let Some(s2) = iter.next() {
296 if let Some(s3) = iter.next() {
297 if s1 == SIP2_0_BYTES {
298 if let Ok(status_code) = s2.to_int() {
299 return Ok(Some((
300 SipFirstLine::Response(SipResponseLine {
301 version: SipVersion::V2_0,
302 status_code,
303 reason_phrase: s3.to_vec(),
304 }),
305 s1.len() + 1 + s2.len() + 1 + s3.len() + 2,
306 )));
307 } else {
308 return Err("invalid status code");
309 }
310 } else if s3 == SIP2_0_BYTES {
311 return Ok(Some((
312 SipFirstLine::Request(SipRequestLine {
313 method: s1.to_vec(),
314 uri: s2.to_vec(),
315 version: SipVersion::V2_0,
316 }),
317 s1.len() + 1 + s2.len() + 1 + s3.len() + 2,
318 )));
319 } else {
320 return Err("unknown sip version");
321 }
322 }
323 }
324 }
325 } else {
326 return Err("bad format");
327 }
328 }
329 }
330
331 Ok(None)
332 }
333}
334
335pub enum SipMessage {
336 Request(SipRequestLine, Option<Vec<Header>>, Option<Arc<Body>>),
337 Response(SipResponseLine, Option<Vec<Header>>, Option<Arc<Body>>),
338 Ping,
339 Pong,
340}
341
342impl SipMessage {
343 pub fn new(
344 first_line: SipFirstLine,
345 headers: Option<Vec<Header>>,
346 body: Option<Arc<Body>>,
347 ) -> SipMessage {
348 match first_line {
349 SipFirstLine::Request(line) => SipMessage::Request(line, headers, body),
350 SipFirstLine::Response(line) => SipMessage::Response(line, headers, body),
351 }
352 }
353
354 pub fn new_request(method: &[u8], uri: &[u8]) -> SipMessage {
355 SipMessage::Request(
356 SipRequestLine {
357 method: method.to_vec(),
358 uri: uri.to_vec(),
359 version: SipVersion::V2_0,
360 },
361 None,
362 None,
363 )
364 }
365
366 pub fn new_response(status_code: u16, reason_phrase: &[u8]) -> SipMessage {
367 SipMessage::Response(
368 SipResponseLine {
369 version: SipVersion::V2_0,
370 status_code,
371 reason_phrase: reason_phrase.to_vec(),
372 },
373 None,
374 None,
375 )
376 }
377
378 pub fn headers(&self) -> Option<&[Header]> {
379 match self {
380 SipMessage::Request(_, headers, _) => {
381 if let Some(headers) = headers {
382 return Some(&*headers);
383 }
384 }
385 SipMessage::Response(_, headers, _) => {
386 if let Some(headers) = headers {
387 return Some(&*headers);
388 }
389 }
390 _ => {}
391 }
392
393 None
394 }
395
396 pub fn copy_headers(&self) -> Vec<Header> {
397 match self {
398 SipMessage::Request(_, headers, _) => {
399 if let Some(headers) = headers {
400 return headers.clone();
401 }
402 }
403 SipMessage::Response(_, headers, _) => {
404 if let Some(headers) = headers {
405 return headers.clone();
406 }
407 }
408 _ => {}
409 }
410
411 Vec::new()
412 }
413
414 pub fn add_header(&mut self, header: Header) {
415 match self {
416 SipMessage::Request(_, headers, _) => match headers {
417 Some(headers) => {
418 headers.push(header);
419 }
420 None => {
421 let mut v = Vec::new();
422 v.push(header);
423 headers.replace(v);
424 }
425 },
426 SipMessage::Response(_, headers, _) => match headers {
427 Some(headers) => {
428 headers.push(header);
429 }
430 None => {
431 let mut v = Vec::new();
432 v.push(header);
433 headers.replace(v);
434 }
435 },
436 _ => {}
437 }
438 }
439
440 pub fn add_header_at_front(&mut self, header: Header) {
441 match self {
442 SipMessage::Request(_, headers, _) => match headers {
443 Some(headers) => {
444 let mut new_headers = Vec::new();
445 new_headers.push(header);
446 new_headers.append(headers);
447 *headers = new_headers;
448 }
449 None => {
450 let mut v = Vec::new();
451 v.push(header);
452 headers.replace(v);
453 }
454 },
455 SipMessage::Response(_, headers, _) => match headers {
456 Some(headers) => {
457 let mut new_headers = Vec::new();
458 new_headers.push(header);
459 new_headers.append(headers);
460 *headers = new_headers;
461 }
462 None => {
463 let mut v = Vec::new();
464 v.push(header);
465 headers.replace(v);
466 }
467 },
468 _ => {}
469 }
470 }
471
472 pub fn set_body(&mut self, b: Arc<Body>) {
473 match self {
474 SipMessage::Request(_, _, body) => {
475 body.replace(b);
476 }
477 SipMessage::Response(_, _, body) => {
478 body.replace(b);
479 }
480 _ => {}
481 }
482 }
483
484 pub fn get_body(&self) -> Option<Arc<Body>> {
485 match self {
486 SipMessage::Request(_, _, body) | SipMessage::Response(_, _, body) => {
487 if let Some(body) = body {
488 Some(Arc::clone(body))
489 } else {
490 None
491 }
492 }
493 _ => None,
494 }
495 }
496
497 pub fn has_body(&self) -> bool {
498 match self {
499 SipMessage::Request(_, _, body) | SipMessage::Response(_, _, body) => body.is_some(),
500 _ => false,
501 }
502 }
503
504 pub fn get_readers<'a>(
505 &'a self,
506 readers: &mut Vec<Box<dyn Read + Send + 'a>>,
507 ) -> Result<(), BodySerializationError> {
508 match &self {
509 SipMessage::Request(line, headers, body) => {
510 readers.push(Box::new(line.reader()));
511 readers.push(Box::new(&b"\r\n"[..]));
512 if let Some(headers) = headers {
513 headers_get_readers(headers, readers);
514 }
515 readers.push(Box::new(&b"\r\n"[..]));
516 if let Some(body) = body {
517 readers.push(Box::new(body.reader()?));
518 }
519 }
520 SipMessage::Response(line, headers, body) => {
521 readers.push(Box::new(line.reader()));
522 readers.push(Box::new(&b"\r\n"[..]));
523 if let Some(headers) = headers {
524 headers_get_readers(headers, readers);
525 }
526 readers.push(Box::new(&b"\r\n"[..]));
527 if let Some(body) = body {
528 readers.push(Box::new(body.reader()?));
529 }
530 }
531 SipMessage::Ping => {
532 readers.push(Box::new(&b"\r\n\r\n"[..]));
533 }
534 SipMessage::Pong => {
535 readers.push(Box::new(&b"\r\n"[..]));
536 }
537 }
538
539 Ok(())
540 }
541}
542
543impl fmt::Debug for SipMessage {
544 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
545 match self {
546 SipMessage::Request(req_line, headers, body) => f
547 .debug_tuple("SipMessage")
548 .field(req_line)
549 .field(headers)
550 .field(body)
551 .finish(),
552 SipMessage::Response(resp_line, headers, body) => f
553 .debug_tuple("SipMessage")
554 .field(resp_line)
555 .field(headers)
556 .field(body)
557 .finish(),
558 SipMessage::Ping => write!(f, "Ping"),
559 SipMessage::Pong => write!(f, "Pong"),
560 }
561 }
562}
563
564impl fmt::Display for SipMessage {
565 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
566 fmt::Debug::fmt(self, f)
567 }
568}
569
570impl Serializable for SipMessage {
571 fn estimated_size(&self) -> usize {
607 let mut size = 0;
608 match &self {
609 SipMessage::Request(line, headers, body) => {
610 size += line.estimated_size();
611 size += 2;
612 if let Some(headers) = headers {
613 size += headers.estimated_size();
614 }
615 size += 2;
616 if let Some(body) = body {
617 size += body.estimated_size();
618 }
619 }
620 SipMessage::Response(line, headers, body) => {
621 size += line.estimated_size();
622 size += 2;
623 if let Some(headers) = headers {
624 size += headers.estimated_size();
625 }
626 size += 2;
627 if let Some(body) = body {
628 size += body.estimated_size();
629 }
630 }
631 SipMessage::Ping => {
632 size += 4;
633 }
634 SipMessage::Pong => {
635 size += 2;
636 }
637 }
638 size
639 }
640}
641
642impl GetDialogHeaders for SipMessage {
643 fn get_dialog_headers<'a>(&'a self) -> Option<(&'a Header, HeaderField<'a>, HeaderField<'a>)> {
644 if let Some(headers) = self.headers() {
645 if let (Some(call_id_header), Some(from_header), Some(to_header)) = (
646 header::search(headers, b"Call-ID", true),
647 header::search(headers, b"From", true),
648 header::search(headers, b"To", true),
649 ) {
650 return Some((
651 call_id_header,
652 from_header.get_value().as_header_field(),
653 to_header.get_value().as_header_field(),
654 ));
655 }
656 }
657
658 None
659 }
660}
661
662pub fn corresponding_cancel(invite_message: &SipMessage) -> Result<SipMessage, &'static str> {
664 match invite_message {
665 SipMessage::Request(req_line, headers, _) => {
666 if let Some(headers) = headers {
667 let call_id_header = header::search(headers, b"Call-ID", true);
668 let cseq_header = header::search(headers, b"CSeq", true);
669 let from_header = header::search(headers, b"From", true);
670 let to_header = header::search(headers, b"To", true);
671 let via_header = header::search(headers, b"Via", true);
672
673 if let (
674 Some(call_id_header),
675 Some(cseq_header),
676 Some(from_header),
677 Some(to_header),
678 Some(via_header),
679 ) = (
680 call_id_header,
681 cseq_header,
682 from_header,
683 to_header,
684 via_header,
685 ) {
686 let cseq_header_field = cseq_header.get_value().as_header_field();
687 let cseq = cseq_header_field.as_cseq();
688 if let Some(cseq) = cseq {
689 let mut message = SipMessage::new_request(CANCEL, &req_line.uri);
690
691 message.add_header(Header::new(
692 b"Call-ID",
693 call_id_header.get_value().to_vec(),
694 ));
695
696 let cseq = format!("{} CANCEL", cseq.seq);
697
698 message.add_header(Header::new(b"CSeq", cseq));
699
700 message.add_header(Header::new(b"From", from_header.get_value().to_vec()));
701
702 message.add_header(Header::new(b"To", to_header.get_value().to_vec()));
703
704 message.add_header(Header::new(b"Via", via_header.get_value().to_vec()));
705
706 return Ok(message);
707 }
708 }
709 }
710 }
711
712 _ => {}
713 }
714
715 Err("Missing information")
716}
717
718pub fn build_message_data(message: &SipMessage) -> Vec<u8> {
719 platform_log(LOG_TAG, "calling sip_message->build_message_data()");
720
721 let data_size = message.estimated_size();
722 let mut data = Vec::with_capacity(data_size);
723 {
724 let mut readers = Vec::new();
725 match message.get_readers(&mut readers) {
726 Ok(_) => {
727 match DynamicChain::new(readers).read_to_end(&mut data) {
728 Ok(_) => {}
729 Err(_) => {
730 platform_log(LOG_TAG, "build_message_data() read error");
731 }
733 }
734 }
735 Err(_) => {
736 platform_log(LOG_TAG, "build_message_data() read error");
737 }
739 }
740 }
741
742 data
743}