1use nom::{branch::alt, character::*, IResult};
2
3use std::fmt;
4
5use crate::{
6 core::{code::error_code_to_str, method::parse_method, version::parse_version},
7 headers::parse_header,
8 parse::{parse_byte_vec, parse_u32, slice_to_string},
9 uri::parse_uri,
10 SipMessageExt, *,
11};
12
13#[derive(Debug, PartialEq, Clone)]
15pub enum SipMessage {
16 Request {
17 method: Method,
18 uri: Uri,
19 version: Version,
20 headers: Headers,
21 body: Vec<u8>,
22 },
23 Response {
24 code: u32,
25 version: Version,
26 headers: Headers,
27 body: Vec<u8>,
28 },
29}
30
31impl SipMessage {
32 pub fn is_request(&self) -> bool {
34 if let SipMessage::Request { .. } = self {
35 true
36 } else {
37 false
38 }
39 }
40
41 pub fn is_response(&self) -> bool {
43 if let SipMessage::Response { .. } = self {
44 true
45 } else {
46 false
47 }
48 }
49
50 pub fn method(&self) -> Option<Method> {
51 match self {
52 Self::Request { method, .. } => Some(*method),
53 Self::Response { .. } => self.cseq().map(|(_, method)| method),
54 }
55 }
56
57 pub fn status_code(&self) -> Option<u32> {
60 if let SipMessage::Response { code, .. } = self {
61 Some(*code)
62 } else {
63 None
64 }
65 }
66
67 pub fn body(&self) -> &Vec<u8> {
69 match self {
70 SipMessage::Request { body, .. } => body,
71 SipMessage::Response { body, .. } => body,
72 }
73 }
74
75 pub fn body_mut(&mut self) -> &mut Vec<u8> {
77 match self {
78 SipMessage::Request { body, .. } => body,
79 SipMessage::Response { body, .. } => body,
80 }
81 }
82
83 pub fn headers(&self) -> &Headers {
85 match self {
86 SipMessage::Request { headers, .. } => headers,
87 SipMessage::Response { headers, .. } => headers,
88 }
89 }
90
91 pub fn headers_mut(&mut self) -> &mut Headers {
93 match self {
94 SipMessage::Request { headers, .. } => headers,
95 SipMessage::Response { headers, .. } => headers,
96 }
97 }
98}
99
100impl fmt::Display for SipMessage {
101 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
102 match self {
103 SipMessage::Request {
104 method,
105 uri,
106 version,
107 headers,
108 body,
109 } => {
110 writeln!(f, "{} {} {}\r", method, uri, version)?;
111 display_headers_and_body(f, headers, body)
112 },
113 SipMessage::Response {
114 code,
115 version,
116 headers,
117 body,
118 } => {
119 if let Some(desc) = error_code_to_str(*code) {
120 writeln!(f, "{} {} {}\r", version, code, desc)?;
121 } else {
122 writeln!(f, "{} {}\r", version, code)?;
123 }
124 display_headers_and_body(f, headers, body)
125 },
126 }
127 }
128}
129
130pub fn display_headers_and_body(
132 f: &mut fmt::Formatter,
133 headers: &Headers,
134 body: &[u8],
135) -> Result<(), fmt::Error> {
136 for header in headers.iter() {
137 writeln!(f, "{}\r", header)?;
138 }
139 writeln!(f, "\r")?;
140 f.write_str(&String::from_utf8_lossy(&body))?;
141 Ok(())
142}
143
144pub fn parse_headers<'a, E: ParseError<&'a [u8]>>(
146 input: &'a [u8],
147) -> IResult<&'a [u8], Headers, E> {
148 let mut headers = Headers(vec![]);
149 let mut input = input;
150 while let Ok((data, value)) = parse_header::<E>(input) {
151 headers.push(value);
152 input = data;
153 }
154 Ok((input, headers))
155}
156
157use nom::{
158 bytes::complete::{tag, take_while},
159 character::complete::char,
160 combinator::{map_res, opt},
161 error::ParseError,
162};
163
164pub fn parse_response<'a, E: ParseError<&'a [u8]>>(
166 input: &'a [u8],
167) -> IResult<&'a [u8], SipMessage, E> {
168 let (input, version) = parse_version::<E>(input)?;
169 let (input, _) = char(' ')(input)?;
170 let (input, code) = map_res(take_while(is_digit), parse_u32)(input)?;
171 let (input, _) = char(' ')(input)?;
172 let (input, _) = opt(map_res::<_, _, _, _, E, _, _>(
173 take_while(|item| is_alphabetic(item) || is_space(item)),
174 slice_to_string,
175 ))(input)?;
176 let (input, _) = opt(char(' '))(input)?;
177 let (input, _) = tag("\r\n")(input)?;
178 let (input, headers) = parse_headers::<E>(input)?;
179 let (input, _) = tag("\r\n")(input)?;
180 let (input, body) = parse_byte_vec::<E>(input)?;
181 Ok((
182 input,
183 SipMessage::Response {
184 code,
185 version,
186 headers,
187 body,
188 },
189 ))
190}
191
192pub fn parse_request<'a, E: ParseError<&'a [u8]>>(
194 input: &'a [u8],
195) -> IResult<&'a [u8], SipMessage, E> {
196 let (input, method) = parse_method(input)?;
197 let (input, _) = char(' ')(input)?;
198 let (input, uri) = parse_uri(input)?;
199 let (input, _) = char(' ')(input)?;
200 let (input, version) = parse_version(input)?;
201 let (input, _) = opt(char(' '))(input)?;
202 let (input, _) = tag("\r\n")(input)?;
203 let (input, headers) = parse_headers(input)?;
204 let (input, _) = tag("\r\n")(input)?;
205 let (input, body) = parse_byte_vec(input)?;
206 Ok((
207 input,
208 SipMessage::Request {
209 method,
210 uri,
211 version,
212 headers,
213 body,
214 },
215 ))
216}
217
218pub fn parse_message<'a, E: ParseError<&'a [u8]>>(
220 input: &'a [u8],
221) -> IResult<&'a [u8], SipMessage, E> {
222 alt::<_, _, E, _>((parse_request::<E>, parse_response::<E>))(input)
223}