1 /* $Id$ */
2 /*
3 * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 #include <pjsua2/types.hpp>
20 #include <pjsua2/siptypes.hpp>
21 #include "util.hpp"
22
23 using namespace pj;
24 using namespace std;
25
26 #define THIS_FILE "siptypes.cpp"
27
28 ///////////////////////////////////////////////////////////////////////////////
29 namespace pj
30 {
readIntVector(ContainerNode & node,const string & array_name,IntVector & v)31 void readIntVector( ContainerNode &node,
32 const string &array_name,
33 IntVector &v) PJSUA2_THROW(Error)
34 {
35 ContainerNode array_node = node.readArray(array_name);
36 v.resize(0);
37 while (array_node.hasUnread()) {
38 v.push_back((int)array_node.readNumber());
39 }
40 }
41
writeIntVector(ContainerNode & node,const string & array_name,const IntVector & v)42 void writeIntVector(ContainerNode &node,
43 const string &array_name,
44 const IntVector &v) PJSUA2_THROW(Error)
45 {
46 ContainerNode array_node = node.writeNewArray(array_name);
47 for (unsigned i=0; i<v.size(); ++i) {
48 array_node.writeNumber("", (float)v[i]);
49 }
50 }
51
readQosParams(ContainerNode & node,pj_qos_params & qos)52 void readQosParams( ContainerNode &node,
53 pj_qos_params &qos) PJSUA2_THROW(Error)
54 {
55 ContainerNode this_node = node.readContainer("qosParams");
56
57 NODE_READ_NUM_T( this_node, pj_uint8_t, qos.flags);
58 NODE_READ_NUM_T( this_node, pj_uint8_t, qos.dscp_val);
59 NODE_READ_NUM_T( this_node, pj_uint8_t, qos.so_prio);
60 NODE_READ_NUM_T( this_node, pj_qos_wmm_prio, qos.wmm_prio);
61 }
62
writeQosParams(ContainerNode & node,const pj_qos_params & qos)63 void writeQosParams( ContainerNode &node,
64 const pj_qos_params &qos) PJSUA2_THROW(Error)
65 {
66 ContainerNode this_node = node.writeNewContainer("qosParams");
67
68 NODE_WRITE_NUM_T( this_node, pj_uint8_t, qos.flags);
69 NODE_WRITE_NUM_T( this_node, pj_uint8_t, qos.dscp_val);
70 NODE_WRITE_NUM_T( this_node, pj_uint8_t, qos.so_prio);
71 NODE_WRITE_NUM_T( this_node, pj_qos_wmm_prio, qos.wmm_prio);
72 }
73
readSipHeaders(const ContainerNode & node,const string & array_name,SipHeaderVector & headers)74 void readSipHeaders( const ContainerNode &node,
75 const string &array_name,
76 SipHeaderVector &headers) PJSUA2_THROW(Error)
77 {
78 ContainerNode headers_node = node.readArray(array_name);
79 headers.resize(0);
80 while (headers_node.hasUnread()) {
81 SipHeader hdr;
82
83 ContainerNode header_node = headers_node.readContainer("header");
84 hdr.hName = header_node.readString("hname");
85 hdr.hValue = header_node.readString("hvalue");
86 headers.push_back(hdr);
87 }
88 }
89
writeSipHeaders(ContainerNode & node,const string & array_name,const SipHeaderVector & headers)90 void writeSipHeaders(ContainerNode &node,
91 const string &array_name,
92 const SipHeaderVector &headers) PJSUA2_THROW(Error)
93 {
94 ContainerNode headers_node = node.writeNewArray(array_name);
95 for (unsigned i=0; i<headers.size(); ++i) {
96 ContainerNode header_node = headers_node.writeNewContainer("header");
97 header_node.writeString("hname", headers[i].hName);
98 header_node.writeString("hvalue", headers[i].hValue);
99 }
100 }
101
102 } // namespace
103 ///////////////////////////////////////////////////////////////////////////////
104
AuthCredInfo()105 AuthCredInfo::AuthCredInfo()
106 : scheme("digest"), realm("*"), dataType(0)
107 {
108 }
109
AuthCredInfo(const string & param_scheme,const string & param_realm,const string & param_user_name,const int param_data_type,const string param_data)110 AuthCredInfo::AuthCredInfo(const string ¶m_scheme,
111 const string ¶m_realm,
112 const string ¶m_user_name,
113 const int param_data_type,
114 const string param_data)
115 : scheme(param_scheme), realm(param_realm), username(param_user_name),
116 dataType(param_data_type), data(param_data)
117 {
118 }
119
readObject(const ContainerNode & node)120 void AuthCredInfo::readObject(const ContainerNode &node) PJSUA2_THROW(Error)
121 {
122 ContainerNode this_node = node.readContainer("AuthCredInfo");
123
124 NODE_READ_STRING( this_node, scheme);
125 NODE_READ_STRING( this_node, realm);
126 NODE_READ_STRING( this_node, username);
127 NODE_READ_INT ( this_node, dataType);
128 NODE_READ_STRING( this_node, data);
129 NODE_READ_STRING( this_node, akaK);
130 NODE_READ_STRING( this_node, akaOp);
131 NODE_READ_STRING( this_node, akaAmf);
132 }
133
writeObject(ContainerNode & node) const134 void AuthCredInfo::writeObject(ContainerNode &node) const PJSUA2_THROW(Error)
135 {
136 ContainerNode this_node = node.writeNewContainer("AuthCredInfo");
137
138 NODE_WRITE_STRING( this_node, scheme);
139 NODE_WRITE_STRING( this_node, realm);
140 NODE_WRITE_STRING( this_node, username);
141 NODE_WRITE_INT ( this_node, dataType);
142 NODE_WRITE_STRING( this_node, data);
143 NODE_WRITE_STRING( this_node, akaK);
144 NODE_WRITE_STRING( this_node, akaOp);
145 NODE_WRITE_STRING( this_node, akaAmf);
146 }
147
148 ///////////////////////////////////////////////////////////////////////////////
149
TlsConfig()150 TlsConfig::TlsConfig() : method(PJSIP_SSL_UNSPECIFIED_METHOD),
151 qosType(PJ_QOS_TYPE_BEST_EFFORT)
152 {
153 pjsip_tls_setting ts;
154 pjsip_tls_setting_default(&ts);
155 this->fromPj(ts);
156 }
157
toPj() const158 pjsip_tls_setting TlsConfig::toPj() const
159 {
160 pjsip_tls_setting ts;
161 pjsip_tls_setting_default(&ts);
162
163 ts.ca_list_file = str2Pj(this->CaListFile);
164 ts.cert_file = str2Pj(this->certFile);
165 ts.privkey_file = str2Pj(this->privKeyFile);
166 ts.password = str2Pj(this->password);
167 ts.ca_buf = str2Pj(this->CaBuf);
168 ts.cert_buf = str2Pj(this->certBuf);
169 ts.privkey_buf = str2Pj(this->privKeyBuf);
170 ts.method = this->method;
171 ts.ciphers_num = (unsigned)this->ciphers.size();
172 ts.proto = this->proto;
173 // The following will only work if sizeof(enum)==sizeof(int)
174 pj_assert(sizeof(ts.ciphers[0]) == sizeof(int));
175 ts.ciphers = ts.ciphers_num?
176 (pj_ssl_cipher*)&this->ciphers[0] : NULL;
177 ts.verify_server = this->verifyServer;
178 ts.verify_client = this->verifyClient;
179 ts.require_client_cert = this->requireClientCert;
180 ts.timeout.sec = this->msecTimeout / 1000;
181 ts.timeout.msec = this->msecTimeout % 1000;
182 ts.qos_type = this->qosType;
183 ts.qos_params = this->qosParams;
184 ts.qos_ignore_error = this->qosIgnoreError;
185
186 return ts;
187 }
188
fromPj(const pjsip_tls_setting & prm)189 void TlsConfig::fromPj(const pjsip_tls_setting &prm)
190 {
191 this->CaListFile = pj2Str(prm.ca_list_file);
192 this->certFile = pj2Str(prm.cert_file);
193 this->privKeyFile = pj2Str(prm.privkey_file);
194 this->password = pj2Str(prm.password);
195 this->CaBuf = pj2Str(prm.ca_buf);
196 this->certBuf = pj2Str(prm.cert_buf);
197 this->privKeyBuf = pj2Str(prm.privkey_buf);
198 this->method = (pjsip_ssl_method)prm.method;
199 this->proto = prm.proto;
200 // The following will only work if sizeof(enum)==sizeof(int)
201 pj_assert(sizeof(prm.ciphers[0]) == sizeof(int));
202 this->ciphers = IntVector(prm.ciphers, prm.ciphers+prm.ciphers_num);
203 this->verifyServer = PJ2BOOL(prm.verify_server);
204 this->verifyClient = PJ2BOOL(prm.verify_client);
205 this->requireClientCert = PJ2BOOL(prm.require_client_cert);
206 this->msecTimeout = PJ_TIME_VAL_MSEC(prm.timeout);
207 this->qosType = prm.qos_type;
208 this->qosParams = prm.qos_params;
209 this->qosIgnoreError = PJ2BOOL(prm.qos_ignore_error);
210 }
211
readObject(const ContainerNode & node)212 void TlsConfig::readObject(const ContainerNode &node) PJSUA2_THROW(Error)
213 {
214 ContainerNode this_node = node.readContainer("TlsConfig");
215
216 NODE_READ_STRING ( this_node, CaListFile);
217 NODE_READ_STRING ( this_node, certFile);
218 NODE_READ_STRING ( this_node, privKeyFile);
219 NODE_READ_STRING ( this_node, password);
220 NODE_READ_STRING ( this_node, CaBuf);
221 NODE_READ_STRING ( this_node, certBuf);
222 NODE_READ_STRING ( this_node, privKeyBuf);
223 NODE_READ_NUM_T ( this_node, pjsip_ssl_method, method);
224 readIntVector ( this_node, "ciphers", ciphers);
225 NODE_READ_BOOL ( this_node, verifyServer);
226 NODE_READ_BOOL ( this_node, verifyClient);
227 NODE_READ_BOOL ( this_node, requireClientCert);
228 NODE_READ_UNSIGNED( this_node, msecTimeout);
229 NODE_READ_NUM_T ( this_node, pj_qos_type, qosType);
230 readQosParams ( this_node, qosParams);
231 NODE_READ_BOOL ( this_node, qosIgnoreError);
232 }
233
writeObject(ContainerNode & node) const234 void TlsConfig::writeObject(ContainerNode &node) const PJSUA2_THROW(Error)
235 {
236 ContainerNode this_node = node.writeNewContainer("TlsConfig");
237
238 NODE_WRITE_STRING ( this_node, CaListFile);
239 NODE_WRITE_STRING ( this_node, certFile);
240 NODE_WRITE_STRING ( this_node, privKeyFile);
241 NODE_WRITE_STRING ( this_node, password);
242 NODE_WRITE_STRING ( this_node, CaBuf);
243 NODE_WRITE_STRING ( this_node, certBuf);
244 NODE_WRITE_STRING ( this_node, privKeyBuf);
245 NODE_WRITE_NUM_T ( this_node, pjsip_ssl_method, method);
246 writeIntVector ( this_node, "ciphers", ciphers);
247 NODE_WRITE_BOOL ( this_node, verifyServer);
248 NODE_WRITE_BOOL ( this_node, verifyClient);
249 NODE_WRITE_BOOL ( this_node, requireClientCert);
250 NODE_WRITE_UNSIGNED( this_node, msecTimeout);
251 NODE_WRITE_NUM_T ( this_node, pj_qos_type, qosType);
252 writeQosParams ( this_node, qosParams);
253 NODE_WRITE_BOOL ( this_node, qosIgnoreError);
254 }
255
256 ///////////////////////////////////////////////////////////////////////////////
257
TransportConfig()258 TransportConfig::TransportConfig() : qosType(PJ_QOS_TYPE_BEST_EFFORT)
259 {
260 pjsua_transport_config tc;
261 pjsua_transport_config_default(&tc);
262 this->fromPj(tc);
263 }
264
fromPj(const pjsua_transport_config & prm)265 void TransportConfig::fromPj(const pjsua_transport_config &prm)
266 {
267 this->port = prm.port;
268 this->portRange = prm.port_range;
269 this->publicAddress = pj2Str(prm.public_addr);
270 this->boundAddress = pj2Str(prm.bound_addr);
271 this->tlsConfig.fromPj(prm.tls_setting);
272 this->qosType = prm.qos_type;
273 this->qosParams = prm.qos_params;
274 }
275
toPj() const276 pjsua_transport_config TransportConfig::toPj() const
277 {
278 pjsua_transport_config tc;
279 pjsua_transport_config_default(&tc);
280
281 tc.port = this->port;
282 tc.port_range = this->portRange;
283 tc.public_addr = str2Pj(this->publicAddress);
284 tc.bound_addr = str2Pj(this->boundAddress);
285 tc.tls_setting = this->tlsConfig.toPj();
286 tc.qos_type = this->qosType;
287 tc.qos_params = this->qosParams;
288
289 return tc;
290 }
291
readObject(const ContainerNode & node)292 void TransportConfig::readObject(const ContainerNode &node) PJSUA2_THROW(Error)
293 {
294 ContainerNode this_node = node.readContainer("TransportConfig");
295
296 NODE_READ_UNSIGNED ( this_node, port);
297 NODE_READ_UNSIGNED ( this_node, portRange);
298 NODE_READ_STRING ( this_node, publicAddress);
299 NODE_READ_STRING ( this_node, boundAddress);
300 NODE_READ_NUM_T ( this_node, pj_qos_type, qosType);
301 readQosParams ( this_node, qosParams);
302 NODE_READ_OBJ ( this_node, tlsConfig);
303 }
304
writeObject(ContainerNode & node) const305 void TransportConfig::writeObject(ContainerNode &node) const
306 PJSUA2_THROW(Error)
307 {
308 ContainerNode this_node = node.writeNewContainer("TransportConfig");
309
310 NODE_WRITE_UNSIGNED ( this_node, port);
311 NODE_WRITE_UNSIGNED ( this_node, portRange);
312 NODE_WRITE_STRING ( this_node, publicAddress);
313 NODE_WRITE_STRING ( this_node, boundAddress);
314 NODE_WRITE_NUM_T ( this_node, pj_qos_type, qosType);
315 writeQosParams ( this_node, qosParams);
316 NODE_WRITE_OBJ ( this_node, tlsConfig);
317 }
318
319 ///////////////////////////////////////////////////////////////////////////////
320
TransportInfo()321 TransportInfo::TransportInfo()
322 : id(), type(PJSIP_TRANSPORT_UNSPECIFIED), flags(), usageCount()
323 {
324 }
325
fromPj(const pjsua_transport_info & tinfo)326 void TransportInfo::fromPj(const pjsua_transport_info &tinfo)
327 {
328 this->id = tinfo.id;
329 this->type = tinfo.type;
330 this->typeName = pj2Str(tinfo.type_name);
331 this->info = pj2Str(tinfo.info);
332 this->flags = tinfo.flag;
333
334 char straddr[PJ_INET6_ADDRSTRLEN+10];
335 pj_sockaddr_print(&tinfo.local_addr, straddr, sizeof(straddr), 3);
336 this->localAddress = straddr;
337
338 pj_ansi_snprintf(straddr, sizeof(straddr), "%.*s:%d",
339 (int)tinfo.local_name.host.slen,
340 tinfo.local_name.host.ptr,
341 tinfo.local_name.port);
342 this->localName = straddr;
343 this->usageCount = tinfo.usage_count;
344 }
345
346 ///////////////////////////////////////////////////////////////////////////////
347
SipRxData()348 SipRxData::SipRxData()
349 : pjRxData(NULL)
350 {
351 }
352
fromPj(pjsip_rx_data & rdata)353 void SipRxData::fromPj(pjsip_rx_data &rdata)
354 {
355 char straddr[PJ_INET6_ADDRSTRLEN+10];
356
357 info = pjsip_rx_data_get_info(&rdata);
358 wholeMsg = string(rdata.msg_info.msg_buf, rdata.msg_info.len);
359 pj_sockaddr_print(&rdata.pkt_info.src_addr, straddr, sizeof(straddr), 3);
360 srcAddress = straddr;
361 pjRxData = (void *)&rdata;
362 }
363
364 ///////////////////////////////////////////////////////////////////////////////
365
fromPj(const pjsip_media_type & prm)366 void SipMediaType::fromPj(const pjsip_media_type &prm)
367 {
368 type = pj2Str(prm.type);
369 subType = pj2Str(prm.subtype);
370 }
371
toPj() const372 pjsip_media_type SipMediaType::toPj() const
373 {
374 pjsip_media_type pj_mt;
375 pj_bzero(&pj_mt, sizeof(pj_mt));
376 pj_mt.type = str2Pj(type);
377 pj_mt.subtype = str2Pj(subType);
378 return pj_mt;
379 }
380
381 ///////////////////////////////////////////////////////////////////////////////
382
fromPj(const pjsip_hdr * hdr)383 void SipHeader::fromPj(const pjsip_hdr *hdr) PJSUA2_THROW(Error)
384 {
385 char *buf = NULL;
386 int len = 0;
387 unsigned buf_size = 256>>1;
388
389 /* Print header to a 256 bytes buffer first.
390 * If buffer is not sufficient, try 512, 1024, soon
391 * until > PJSIP_MAX_PKT_LEN
392 */
393 do {
394 buf_size <<= 1;
395 buf = (char*)malloc(buf_size);
396 if (!buf)
397 PJSUA2_RAISE_ERROR(PJ_ENOMEM);
398
399 len = pjsip_hdr_print_on((void*)hdr, buf, buf_size-1);
400 if (len < 0)
401 free(buf);
402
403 } while ((buf_size < PJSIP_MAX_PKT_LEN) && (len < 0));
404
405 if (len < 0)
406 PJSUA2_RAISE_ERROR(PJ_ETOOSMALL);
407
408 buf[len] = '\0';
409
410 char *pos = strchr(buf, ':');
411 if (!pos) {
412 free(buf);
413 PJSUA2_RAISE_ERROR(PJSIP_EINVALIDHDR);
414 }
415
416 // Trim white space after header name
417 char *end_name = pos;
418 while (end_name>buf && pj_isspace(*(end_name-1))) --end_name;
419
420 // Trim whitespaces after colon
421 char *start_val = pos+1;
422 while (*start_val && pj_isspace(*start_val)) ++start_val;
423
424 hName = string(buf, end_name);
425 hValue = string(start_val);
426 free(buf);
427 }
428
toPj() const429 pjsip_generic_string_hdr &SipHeader::toPj() const
430 {
431 pj_str_t hname = str2Pj(hName);
432 pj_str_t hvalue = str2Pj(hValue);
433
434 pjsip_generic_string_hdr_init2(&pjHdr, &hname, &hvalue);
435 return pjHdr;
436 }
437
438 ///////////////////////////////////////////////////////////////////////////////
439
fromPj(const pjsip_multipart_part & prm)440 void SipMultipartPart::fromPj(const pjsip_multipart_part &prm)
441 PJSUA2_THROW(Error)
442 {
443 headers.clear();
444 pjsip_hdr* pj_hdr = prm.hdr.next;
445 while (pj_hdr != &prm.hdr) {
446 SipHeader sh;
447 sh.fromPj(pj_hdr);
448 headers.push_back(sh);
449 pj_hdr = pj_hdr->next;
450 }
451
452 if (!prm.body)
453 PJSUA2_RAISE_ERROR(PJ_EINVAL);
454
455 contentType.fromPj(prm.body->content_type);
456 body = string((char*)prm.body->data, prm.body->len);
457 }
458
toPj() const459 pjsip_multipart_part& SipMultipartPart::toPj() const
460 {
461 pj_list_init(&pjMpp.hdr);
462 for (unsigned i = 0; i < headers.size(); i++) {
463 pjsip_generic_string_hdr& pj_hdr = headers[i].toPj();
464 pj_list_push_back(&pjMpp.hdr, &pj_hdr);
465 }
466
467 pj_bzero(&pjMsgBody, sizeof(pjMsgBody));
468 pjMsgBody.content_type = contentType.toPj();
469 pjMsgBody.print_body = &pjsip_print_text_body;
470 pjMsgBody.clone_data = &pjsip_clone_text_data;
471 pjMsgBody.data = (void*)body.c_str();
472 pjMsgBody.len = (unsigned)body.size();
473 pjMpp.body = &pjMsgBody;
474
475 return pjMpp;
476 }
477
478 ///////////////////////////////////////////////////////////////////////////////
479
SipEvent()480 SipEvent::SipEvent()
481 : type(PJSIP_EVENT_UNKNOWN), pjEvent(NULL)
482 {
483 }
484
fromPj(const pjsip_event & ev)485 void SipEvent::fromPj(const pjsip_event &ev)
486 {
487 type = ev.type;
488 if (type == PJSIP_EVENT_TIMER) {
489 body.timer.entry = ev.body.timer.entry;
490 } else if (type == PJSIP_EVENT_TSX_STATE) {
491 body.tsxState.prevState = (pjsip_tsx_state_e)
492 ev.body.tsx_state.prev_state;
493 body.tsxState.tsx.fromPj(*ev.body.tsx_state.tsx);
494 body.tsxState.type = ev.body.tsx_state.type;
495 if (body.tsxState.type == PJSIP_EVENT_TX_MSG) {
496 if (ev.body.tsx_state.src.tdata)
497 body.tsxState.src.tdata.fromPj(*ev.body.tsx_state.src.tdata);
498 } else if (body.tsxState.type == PJSIP_EVENT_RX_MSG) {
499 if (ev.body.tsx_state.src.rdata)
500 body.tsxState.src.rdata.fromPj(*ev.body.tsx_state.src.rdata);
501 } else if (body.tsxState.type == PJSIP_EVENT_TRANSPORT_ERROR) {
502 body.tsxState.src.status = ev.body.tsx_state.src.status;
503 } else if (body.tsxState.type == PJSIP_EVENT_TIMER) {
504 body.tsxState.src.timer = ev.body.tsx_state.src.timer;
505 } else if (body.tsxState.type == PJSIP_EVENT_USER) {
506 body.tsxState.src.data = ev.body.tsx_state.src.data;
507 }
508 } else if (type == PJSIP_EVENT_TX_MSG) {
509 if (ev.body.tx_msg.tdata)
510 body.txMsg.tdata.fromPj(*ev.body.tx_msg.tdata);
511 } else if (type == PJSIP_EVENT_RX_MSG) {
512 if (ev.body.rx_msg.rdata)
513 body.rxMsg.rdata.fromPj(*ev.body.rx_msg.rdata);
514 } else if (type == PJSIP_EVENT_TRANSPORT_ERROR) {
515 if (ev.body.tx_error.tdata)
516 body.txError.tdata.fromPj(*ev.body.tx_error.tdata);
517 if (ev.body.tx_error.tsx)
518 body.txError.tsx.fromPj(*ev.body.tx_error.tsx);
519 } else if (type == PJSIP_EVENT_USER) {
520 body.user.user1 = ev.body.user.user1;
521 body.user.user2 = ev.body.user.user2;
522 body.user.user3 = ev.body.user.user3;
523 body.user.user4 = ev.body.user.user4;
524 }
525 pjEvent = (void *)&ev;
526 }
527
SipTxData()528 SipTxData::SipTxData()
529 : pjTxData(NULL)
530 {
531 }
532
fromPj(pjsip_tx_data & tdata)533 void SipTxData::fromPj(pjsip_tx_data &tdata)
534 {
535 char straddr[PJ_INET6_ADDRSTRLEN+10];
536
537 info = pjsip_tx_data_get_info(&tdata);
538 pjsip_tx_data_encode(&tdata);
539 wholeMsg = string(tdata.buf.start, tdata.buf.cur - tdata.buf.start);
540 if (pj_sockaddr_has_addr(&tdata.tp_info.dst_addr)) {
541 pj_sockaddr_print(&tdata.tp_info.dst_addr, straddr, sizeof(straddr), 3);
542 dstAddress = straddr;
543 } else {
544 dstAddress = "";
545 }
546 pjTxData = (void *)&tdata;
547 }
548
SipTransaction()549 SipTransaction::SipTransaction()
550 : role(PJSIP_ROLE_UAC), statusCode(PJSIP_SC_NULL),
551 state(PJSIP_TSX_STATE_NULL), pjTransaction(NULL)
552 {
553 }
554
fromPj(pjsip_transaction & tsx)555 void SipTransaction::fromPj(pjsip_transaction &tsx)
556 {
557 this->role = tsx.role;
558 this->method = pj2Str(tsx.method.name);
559 this->statusCode = tsx.status_code;
560 this->statusText = pj2Str(tsx.status_text);
561 this->state = tsx.state;
562 if (tsx.last_tx)
563 this->lastTx.fromPj(*tsx.last_tx);
564 else
565 this->lastTx.pjTxData = NULL;
566 this->pjTransaction = (void *)&tsx;
567 }
568
TsxStateEvent()569 TsxStateEvent::TsxStateEvent()
570 : prevState(PJSIP_TSX_STATE_NULL), type(PJSIP_EVENT_UNKNOWN)
571 {
572 }
573
isEmpty() const574 bool SipTxOption::isEmpty() const
575 {
576 return (targetUri == "" && headers.size() == 0 && contentType == "" &&
577 msgBody == "" && multipartContentType.type == "" &&
578 multipartContentType.subType == "" && multipartParts.size() == 0);
579 }
580
fromPj(const pjsua_msg_data & prm)581 void SipTxOption::fromPj(const pjsua_msg_data &prm) PJSUA2_THROW(Error)
582 {
583 targetUri = pj2Str(prm.target_uri);
584
585 headers.clear();
586 pjsip_hdr* pj_hdr = prm.hdr_list.next;
587 while (pj_hdr != &prm.hdr_list) {
588 SipHeader sh;
589 sh.fromPj(pj_hdr);
590 headers.push_back(sh);
591 pj_hdr = pj_hdr->next;
592 }
593
594 contentType = pj2Str(prm.content_type);
595 msgBody = pj2Str(prm.msg_body);
596 multipartContentType.fromPj(prm.multipart_ctype);
597
598 multipartParts.clear();
599 pjsip_multipart_part* pj_mp = prm.multipart_parts.next;
600 while (pj_mp != &prm.multipart_parts) {
601 SipMultipartPart smp;
602 smp.fromPj(*pj_mp);
603 multipartParts.push_back(smp);
604 pj_mp = pj_mp->next;
605 }
606 }
607
toPj(pjsua_msg_data & msg_data) const608 void SipTxOption::toPj(pjsua_msg_data &msg_data) const
609 {
610 unsigned i;
611
612 pjsua_msg_data_init(&msg_data);
613
614 msg_data.target_uri = str2Pj(targetUri);
615
616 pj_list_init(&msg_data.hdr_list);
617 for (i = 0; i < headers.size(); i++) {
618 pjsip_generic_string_hdr& pj_hdr = headers[i].toPj();
619 pj_list_push_back(&msg_data.hdr_list, &pj_hdr);
620 }
621
622 msg_data.content_type = str2Pj(contentType);
623 msg_data.msg_body = str2Pj(msgBody);
624 msg_data.multipart_ctype = multipartContentType.toPj();
625
626 pj_list_init(&msg_data.multipart_parts);
627 for (i = 0; i < multipartParts.size(); i++) {
628 pjsip_multipart_part& pj_part = multipartParts[i].toPj();
629 pj_list_push_back(&msg_data.multipart_parts, &pj_part);
630 }
631 }
632
633 //////////////////////////////////////////////////////////////////////////////
634
SendInstantMessageParam()635 SendInstantMessageParam::SendInstantMessageParam()
636 : contentType("text/plain"), content(""), userData(NULL)
637 {
638 }
639
SendTypingIndicationParam()640 SendTypingIndicationParam::SendTypingIndicationParam()
641 : isTyping(false)
642 {
643 }
644