blob: b025a5190c02bca319334a8c7bda633b2c2c0b7b [file] [log] [blame]
Benny Prijono1f63cc42007-09-10 16:54:22 +00001/* $Id$ */
2/*
3 * Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org>
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#ifndef __PY_PJSUA_H__
20#define __PY_PJSUA_H__
21
22#include <Python.h>
23#include <structmember.h>
24#include <pjsua-lib/pjsua.h>
25
26
27PJ_INLINE(pj_str_t) PyString_to_pj_str(const PyObject *obj)
28{
29 pj_str_t str;
30
Benny Prijonod7ea6052007-09-17 15:44:47 +000031 if (obj) {
32 str.ptr = PyString_AS_STRING(obj);
33 str.slen = PyString_GET_SIZE(obj);
34 } else {
35 str.ptr = NULL;
36 str.slen = 0;
37 }
Benny Prijono1f63cc42007-09-10 16:54:22 +000038
39 return str;
40}
41
42
43//////////////////////////////////////////////////////////////////////////////
44/*
45 * PyObj_pj_pool
46 */
47typedef struct
48{
49 PyObject_HEAD
50 /* Type-specific fields go here. */
51 pj_pool_t * pool;
52} PyObj_pj_pool;
53
54
55/*
56 * PyTyp_pj_pool_t
57 */
58static PyTypeObject PyTyp_pj_pool_t =
59{
60 PyObject_HEAD_INIT(NULL)
61 0, /*ob_size*/
62 "py_pjsua.Pj_Pool", /*tp_name*/
63 sizeof(PyObj_pj_pool), /*tp_basicsize*/
64 0, /*tp_itemsize*/
65 0, /*tp_dealloc*/
66 0, /*tp_print*/
67 0, /*tp_getattr*/
68 0, /*tp_setattr*/
69 0, /*tp_compare*/
70 0, /*tp_repr*/
71 0, /*tp_as_number*/
72 0, /*tp_as_sequence*/
73 0, /*tp_as_mapping*/
74 0, /*tp_hash */
75 0, /*tp_call*/
76 0, /*tp_str*/
77 0, /*tp_getattro*/
78 0, /*tp_setattro*/
79 0, /*tp_as_buffer*/
80 Py_TPFLAGS_DEFAULT, /*tp_flags*/
81 "pj_pool_t objects", /* tp_doc */
82
83};
84
85
86//////////////////////////////////////////////////////////////////////////////
87/*
88 * PyObj_pjsip_endpoint
89 */
90typedef struct
91{
92 PyObject_HEAD
93 /* Type-specific fields go here. */
94 pjsip_endpoint * endpt;
95} PyObj_pjsip_endpoint;
96
97
98/*
99 * PyTyp_pjsip_endpoint
100 */
101static PyTypeObject PyTyp_pjsip_endpoint =
102{
103 PyObject_HEAD_INIT(NULL)
104 0, /*ob_size*/
105 "py_pjsua.Pjsip_Endpoint", /*tp_name*/
106 sizeof(PyObj_pjsip_endpoint),/*tp_basicsize*/
107 0, /*tp_itemsize*/
108 0, /*tp_dealloc*/
109 0, /*tp_print*/
110 0, /*tp_getattr*/
111 0, /*tp_setattr*/
112 0, /*tp_compare*/
113 0, /*tp_repr*/
114 0, /*tp_as_number*/
115 0, /*tp_as_sequence*/
116 0, /*tp_as_mapping*/
117 0, /*tp_hash */
118 0, /*tp_call*/
119 0, /*tp_str*/
120 0, /*tp_getattro*/
121 0, /*tp_setattro*/
122 0, /*tp_as_buffer*/
123 Py_TPFLAGS_DEFAULT, /*tp_flags*/
124 "pjsip_endpoint objects", /* tp_doc */
125};
126
127
128/*
129 * PyObj_pjmedia_endpt
130 */
131typedef struct
132{
133 PyObject_HEAD
134 /* Type-specific fields go here. */
135 pjmedia_endpt * endpt;
136} PyObj_pjmedia_endpt;
137
138
139//////////////////////////////////////////////////////////////////////////////
140/*
141 * PyTyp_pjmedia_endpt
142 */
143static PyTypeObject PyTyp_pjmedia_endpt =
144{
145 PyObject_HEAD_INIT(NULL)
146 0, /*ob_size*/
147 "py_pjsua.Pjmedia_Endpt", /*tp_name*/
148 sizeof(PyObj_pjmedia_endpt), /*tp_basicsize*/
149 0, /*tp_itemsize*/
150 0, /*tp_dealloc*/
151 0, /*tp_print*/
152 0, /*tp_getattr*/
153 0, /*tp_setattr*/
154 0, /*tp_compare*/
155 0, /*tp_repr*/
156 0, /*tp_as_number*/
157 0, /*tp_as_sequence*/
158 0, /*tp_as_mapping*/
159 0, /*tp_hash */
160 0, /*tp_call*/
161 0, /*tp_str*/
162 0, /*tp_getattro*/
163 0, /*tp_setattro*/
164 0, /*tp_as_buffer*/
165 Py_TPFLAGS_DEFAULT, /*tp_flags*/
166 "pjmedia_endpt objects", /* tp_doc */
167
168};
169
170
171//////////////////////////////////////////////////////////////////////////////
172/*
173 * PyObj_pj_pool_factory
174 */
175typedef struct
176{
177 PyObject_HEAD
178 /* Type-specific fields go here. */
179 pj_pool_factory * pool_fact;
180} PyObj_pj_pool_factory;
181
182
183
184/*
185 * PyTyp_pj_pool_factory
186 */
187static PyTypeObject PyTyp_pj_pool_factory =
188{
189 PyObject_HEAD_INIT(NULL)
190 0, /*ob_size*/
191 "py_pjsua.Pj_Pool_Factory",/*tp_name*/
192 sizeof(PyObj_pj_pool_factory), /*tp_basicsize*/
193 0, /*tp_itemsize*/
194 0, /*tp_dealloc*/
195 0, /*tp_print*/
196 0, /*tp_getattr*/
197 0, /*tp_setattr*/
198 0, /*tp_compare*/
199 0, /*tp_repr*/
200 0, /*tp_as_number*/
201 0, /*tp_as_sequence*/
202 0, /*tp_as_mapping*/
203 0, /*tp_hash */
204 0, /*tp_call*/
205 0, /*tp_str*/
206 0, /*tp_getattro*/
207 0, /*tp_setattro*/
208 0, /*tp_as_buffer*/
209 Py_TPFLAGS_DEFAULT, /*tp_flags*/
210 "pj_pool_factory objects", /* tp_doc */
211
212};
213
214
215//////////////////////////////////////////////////////////////////////////////
216/*
217 * PyObj_pjsip_cred_info
218 */
219typedef struct
220{
221 PyObject_HEAD
222
223 /* Type-specific fields go here. */
224 PyObject *realm;
225 PyObject *scheme;
226 PyObject *username;
227 int data_type;
228 PyObject *data;
229
230} PyObj_pjsip_cred_info;
231
232/*
233 * cred_info_dealloc
234 * deletes a cred info from memory
235 */
236static void PyObj_pjsip_cred_info_delete(PyObj_pjsip_cred_info* self)
237{
238 Py_XDECREF(self->realm);
239 Py_XDECREF(self->scheme);
240 Py_XDECREF(self->username);
241 Py_XDECREF(self->data);
242 self->ob_type->tp_free((PyObject*)self);
243}
244
245
246static void PyObj_pjsip_cred_info_import(PyObj_pjsip_cred_info *obj,
247 const pjsip_cred_info *cfg)
248{
249 Py_XDECREF(obj->realm);
250 obj->realm = PyString_FromStringAndSize(cfg->realm.ptr, cfg->realm.slen);
251 Py_XDECREF(obj->scheme);
252 obj->scheme = PyString_FromStringAndSize(cfg->scheme.ptr, cfg->scheme.slen);
253 Py_XDECREF(obj->username);
254 obj->username = PyString_FromStringAndSize(cfg->username.ptr, cfg->username.slen);
255 obj->data_type = cfg->data_type;
256 Py_XDECREF(obj->data);
257 obj->data = PyString_FromStringAndSize(cfg->data.ptr, cfg->data.slen);
258}
259
260static void PyObj_pjsip_cred_info_export(pjsip_cred_info *cfg,
261 PyObj_pjsip_cred_info *obj)
262{
263 cfg->realm = PyString_to_pj_str(obj->realm);
264 cfg->scheme = PyString_to_pj_str(obj->scheme);
265 cfg->username = PyString_to_pj_str(obj->username);
266 cfg->data_type = obj->data_type;
267 cfg->data = PyString_to_pj_str(obj->data);
268}
269
270
271/*
272 * cred_info_new
273 * constructor for cred_info object
274 */
275static PyObject * PyObj_pjsip_cred_info_new(PyTypeObject *type,
276 PyObject *args,
277 PyObject *kwds)
278{
279 PyObj_pjsip_cred_info *self;
280
281 PJ_UNUSED_ARG(args);
282 PJ_UNUSED_ARG(kwds);
283
284 self = (PyObj_pjsip_cred_info *)type->tp_alloc(type, 0);
285 if (self != NULL)
286 {
287 self->realm = PyString_FromString("");
288 if (self->realm == NULL)
289 {
290 Py_DECREF(self);
291 return NULL;
292 }
293 self->scheme = PyString_FromString("");
294 if (self->scheme == NULL)
295 {
296 Py_DECREF(self);
297 return NULL;
298 }
299 self->username = PyString_FromString("");
300 if (self->username == NULL)
301 {
302 Py_DECREF(self);
303 return NULL;
304 }
305 self->data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
306 self->data = PyString_FromString("");
307 if (self->data == NULL)
308 {
309 Py_DECREF(self);
310 return NULL;
311 }
312 }
313
314 return (PyObject *)self;
315}
316
317
318/*
319 * PyObj_pjsip_cred_info_members
320 */
321static PyMemberDef PyObj_pjsip_cred_info_members[] =
322{
323 {
324 "realm", T_OBJECT_EX,
325 offsetof(PyObj_pjsip_cred_info, realm), 0,
326 "Realm"
327 },
328 {
329 "scheme", T_OBJECT_EX,
330 offsetof(PyObj_pjsip_cred_info, scheme), 0,
331 "Scheme"
332 },
333 {
334 "username", T_OBJECT_EX,
335 offsetof(PyObj_pjsip_cred_info, username), 0,
336 "User name"
337 },
338 {
339 "data", T_OBJECT_EX,
340 offsetof(PyObj_pjsip_cred_info, data), 0,
341 "The data, which can be a plaintext password or a hashed digest, "
342 "depending on the value of data_type"
343 },
344 {
345 "data_type", T_INT,
346 offsetof(PyObj_pjsip_cred_info, data_type), 0,
347 "Type of data"
348 },
349
350 {NULL} /* Sentinel */
351};
352
353/*
354 * PyTyp_pjsip_cred_info
355 */
356static PyTypeObject PyTyp_pjsip_cred_info =
357{
358 PyObject_HEAD_INIT(NULL)
359 0, /*ob_size*/
360 "py_pjsua.Pjsip_Cred_Info", /*tp_name*/
361 sizeof(PyObj_pjsip_cred_info), /*tp_basicsize*/
362 0, /*tp_itemsize*/
363 (destructor)PyObj_pjsip_cred_info_delete,/*tp_dealloc*/
364 0, /*tp_print*/
365 0, /*tp_getattr*/
366 0, /*tp_setattr*/
367 0, /*tp_compare*/
368 0, /*tp_repr*/
369 0, /*tp_as_number*/
370 0, /*tp_as_sequence*/
371 0, /*tp_as_mapping*/
372 0, /*tp_hash */
373 0, /*tp_call*/
374 0, /*tp_str*/
375 0, /*tp_getattro*/
376 0, /*tp_setattro*/
377 0, /*tp_as_buffer*/
378 Py_TPFLAGS_DEFAULT, /*tp_flags*/
379 "PJSIP credential information", /* tp_doc */
380 0, /* tp_traverse */
381 0, /* tp_clear */
382 0, /* tp_richcompare */
383 0, /* tp_weaklistoffset */
384 0, /* tp_iter */
385 0, /* tp_iternext */
386 0, /* tp_methods */
387 PyObj_pjsip_cred_info_members, /* tp_members */
388 0, /* tp_getset */
389 0, /* tp_base */
390 0, /* tp_dict */
391 0, /* tp_descr_get */
392 0, /* tp_descr_set */
393 0, /* tp_dictoffset */
394 0, /* tp_init */
395 0, /* tp_alloc */
396 PyObj_pjsip_cred_info_new, /* tp_new */
397
398};
399
400
401//////////////////////////////////////////////////////////////////////////////
402/*
403 * PyObj_pjsip_event
404 * C/python typewrapper for event struct
405 */
406typedef struct
407{
408 PyObject_HEAD
409 /* Type-specific fields go here. */
410 pjsip_event * event;
411} PyObj_pjsip_event;
412
413
414
415/*
416 * PyTyp_pjsip_event
417 * event struct signatures
418 */
419static PyTypeObject PyTyp_pjsip_event =
420{
421 PyObject_HEAD_INIT(NULL)
422 0, /*ob_size*/
423 "py_pjsua.Pjsip_Event", /*tp_name*/
424 sizeof(PyObj_pjsip_event), /*tp_basicsize*/
425 0, /*tp_itemsize*/
426 0, /*tp_dealloc*/
427 0, /*tp_print*/
428 0, /*tp_getattr*/
429 0, /*tp_setattr*/
430 0, /*tp_compare*/
431 0, /*tp_repr*/
432 0, /*tp_as_number*/
433 0, /*tp_as_sequence*/
434 0, /*tp_as_mapping*/
435 0, /*tp_hash */
436 0, /*tp_call*/
437 0, /*tp_str*/
438 0, /*tp_getattro*/
439 0, /*tp_setattro*/
440 0, /*tp_as_buffer*/
441 Py_TPFLAGS_DEFAULT, /*tp_flags*/
442 "pjsip_event object", /*tp_doc */
443};
444
445
446//////////////////////////////////////////////////////////////////////////////
447/*
448 * PyObj_pjsip_rx_data
449 * C/python typewrapper for pjsip_rx_data struct
450 */
451typedef struct
452{
453 PyObject_HEAD
454 /* Type-specific fields go here. */
455 pjsip_rx_data * rdata;
456} PyObj_pjsip_rx_data;
457
458
459/*
460 * PyTyp_pjsip_rx_data
461 */
462static PyTypeObject PyTyp_pjsip_rx_data =
463{
464 PyObject_HEAD_INIT(NULL)
465 0, /*ob_size*/
466 "py_pjsua.Pjsip_Rx_Data", /*tp_name*/
467 sizeof(PyObj_pjsip_rx_data), /*tp_basicsize*/
468 0, /*tp_itemsize*/
469 0, /*tp_dealloc*/
470 0, /*tp_print*/
471 0, /*tp_getattr*/
472 0, /*tp_setattr*/
473 0, /*tp_compare*/
474 0, /*tp_repr*/
475 0, /*tp_as_number*/
476 0, /*tp_as_sequence*/
477 0, /*tp_as_mapping*/
478 0, /*tp_hash */
479 0, /*tp_call*/
480 0, /*tp_str*/
481 0, /*tp_getattro*/
482 0, /*tp_setattro*/
483 0, /*tp_as_buffer*/
484 Py_TPFLAGS_DEFAULT, /*tp_flags*/
485 "pjsip_rx_data object", /*tp_doc*/
486};
487
488
489
490//////////////////////////////////////////////////////////////////////////////
491/*
492 * PyObj_pjsua_callback
493 * C/python typewrapper for callback struct
494 */
495typedef struct PyObj_pjsua_callback
496{
497 PyObject_HEAD
498 /* Type-specific fields go here. */
499 PyObject * on_call_state;
500 PyObject * on_incoming_call;
501 PyObject * on_call_media_state;
502 PyObject * on_dtmf_digit;
503 PyObject * on_call_transfer_request;
504 PyObject * on_call_transfer_status;
505 PyObject * on_call_replace_request;
506 PyObject * on_call_replaced;
507 PyObject * on_reg_state;
508 PyObject * on_buddy_state;
509 PyObject * on_pager;
510 PyObject * on_pager_status;
511 PyObject * on_typing;
512} PyObj_pjsua_callback;
513
514
515/*
516 * PyObj_pjsua_callback_delete
517 * destructor function for callback struct
518 */
519static void PyObj_pjsua_callback_delete(PyObj_pjsua_callback* self)
520{
521 Py_XDECREF(self->on_call_state);
522 Py_XDECREF(self->on_incoming_call);
523 Py_XDECREF(self->on_call_media_state);
524 Py_XDECREF(self->on_dtmf_digit);
525 Py_XDECREF(self->on_call_transfer_request);
526 Py_XDECREF(self->on_call_transfer_status);
527 Py_XDECREF(self->on_call_replace_request);
528 Py_XDECREF(self->on_call_replaced);
529 Py_XDECREF(self->on_reg_state);
530 Py_XDECREF(self->on_buddy_state);
531 Py_XDECREF(self->on_pager);
532 Py_XDECREF(self->on_pager_status);
533 Py_XDECREF(self->on_typing);
534 self->ob_type->tp_free((PyObject*)self);
535}
536
537
538/*
539 * PyObj_pjsua_callback_new
540 * * declares constructor for callback struct
541 */
542static PyObject * PyObj_pjsua_callback_new(PyTypeObject *type,
543 PyObject *args,
544 PyObject *kwds)
545{
546 PyObj_pjsua_callback *self;
547
548 PJ_UNUSED_ARG(args);
549 PJ_UNUSED_ARG(kwds);
550
551 self = (PyObj_pjsua_callback *)type->tp_alloc(type, 0);
552 if (self != NULL)
553 {
554 Py_INCREF(Py_None);
555 self->on_call_state = Py_None;
556 if (self->on_call_state == NULL)
557 {
558 Py_DECREF(Py_None);
559 return NULL;
560 }
561 Py_INCREF(Py_None);
562 self->on_incoming_call = Py_None;
563 if (self->on_incoming_call == NULL)
564 {
565 Py_DECREF(Py_None);
566 return NULL;
567 }
568 Py_INCREF(Py_None);
569 self->on_call_media_state = Py_None;
570 if (self->on_call_media_state == NULL)
571 {
572 Py_DECREF(Py_None);
573 return NULL;
574 }
575 Py_INCREF(Py_None);
576 self->on_dtmf_digit = Py_None;
577 if (self->on_dtmf_digit == NULL)
578 {
579 Py_DECREF(Py_None);
580 return NULL;
581 }
582 Py_INCREF(Py_None);
583 self->on_call_transfer_request = Py_None;
584 if (self->on_call_transfer_request == NULL)
585 {
586 Py_DECREF(Py_None);
587 return NULL;
588 }
589 Py_INCREF(Py_None);
590 self->on_call_transfer_status = Py_None;
591 if (self->on_call_transfer_status == NULL)
592 {
593 Py_DECREF(Py_None);
594 return NULL;
595 }
596 Py_INCREF(Py_None);
597 self->on_call_replace_request = Py_None;
598 if (self->on_call_replace_request == NULL)
599 {
600 Py_DECREF(Py_None);
601 return NULL;
602 }
603 Py_INCREF(Py_None);
604 self->on_call_replaced = Py_None;
605 if (self->on_call_replaced == NULL)
606 {
607 Py_DECREF(Py_None);
608 return NULL;
609 }
610 Py_INCREF(Py_None);
611 self->on_reg_state = Py_None;
612 if (self->on_reg_state == NULL)
613 {
614 Py_DECREF(Py_None);
615 return NULL;
616 }
617 Py_INCREF(Py_None);
618 self->on_buddy_state = Py_None;
619 if (self->on_buddy_state == NULL)
620 {
621 Py_DECREF(Py_None);
622 return NULL;
623 }
624 Py_INCREF(Py_None);
625 self->on_pager = Py_None;
626 if (self->on_pager == NULL)
627 {
628 Py_DECREF(Py_None);
629 return NULL;
630 }
631 Py_INCREF(Py_None);
632 self->on_pager_status = Py_None;
633 if (self->on_pager_status == NULL)
634 {
635 Py_DECREF(Py_None);
636 return NULL;
637 }
638 Py_INCREF(Py_None);
639 self->on_typing = Py_None;
640 if (self->on_typing == NULL)
641 {
642 Py_DECREF(Py_None);
643 return NULL;
644 }
645 }
646
647 return (PyObject *)self;
648}
649
650
651/*
652 * PyObj_pjsua_callback_members
653 * declares available functions for callback object
654 */
655static PyMemberDef PyObj_pjsua_callback_members[] =
656{
657 {
658 "on_call_state", T_OBJECT_EX,
659 offsetof(PyObj_pjsua_callback, on_call_state), 0,
660 "Notify application when invite state has changed. Application may "
661 "then query the call info to get the detail call states."
662 },
663 {
664 "on_incoming_call", T_OBJECT_EX,
665 offsetof(PyObj_pjsua_callback, on_incoming_call), 0,
666 "Notify application on incoming call."
667 },
668 {
669 "on_call_media_state", T_OBJECT_EX,
670 offsetof(PyObj_pjsua_callback, on_call_media_state), 0,
671 "Notify application when media state in the call has changed. Normal "
672 "application would need to implement this callback, e.g. to connect "
673 "the call's media to sound device."
674 },
675 {
676 "on_dtmf_digit", T_OBJECT_EX,
677 offsetof(PyObj_pjsua_callback, on_dtmf_digit), 0,
678 "Notify application upon receiving incoming DTMF digit."
679 },
680 {
681 "on_call_transfer_request", T_OBJECT_EX,
682 offsetof(PyObj_pjsua_callback, on_call_transfer_request), 0,
683 "Notify application on call being transfered. "
684 "Application can decide to accept/reject transfer request "
685 "by setting the code (default is 200). When this callback "
686 "is not defined, the default behavior is to accept the "
687 "transfer."
688 },
689 {
690 "on_call_transfer_status", T_OBJECT_EX,
691 offsetof(PyObj_pjsua_callback, on_call_transfer_status), 0,
692 "Notify application of the status of previously sent call "
693 "transfer request. Application can monitor the status of the "
694 "call transfer request, for example to decide whether to "
695 "terminate existing call."
696 },
697 {
698 "on_call_replace_request", T_OBJECT_EX,
699 offsetof(PyObj_pjsua_callback, on_call_replace_request), 0,
700 "Notify application about incoming INVITE with Replaces header. "
701 "Application may reject the request by setting non-2xx code."
702 },
703 {
704 "on_call_replaced", T_OBJECT_EX,
705 offsetof(PyObj_pjsua_callback, on_call_replaced), 0,
706 "Notify application that an existing call has been replaced with "
707 "a new call. This happens when PJSUA-API receives incoming INVITE "
708 "request with Replaces header."
709 " "
710 "After this callback is called, normally PJSUA-API will disconnect "
711 "old_call_id and establish new_call_id."
712 },
713 {
714 "on_reg_state", T_OBJECT_EX,
715 offsetof(PyObj_pjsua_callback, on_reg_state), 0,
716 "Notify application when registration status has changed. Application "
717 "may then query the account info to get the registration details."
718 },
719 {
720 "on_buddy_state", T_OBJECT_EX,
721 offsetof(PyObj_pjsua_callback, on_buddy_state), 0,
722 "Notify application when the buddy state has changed. Application may "
723 "then query the buddy into to get the details."
724 },
725 {
726 "on_pager", T_OBJECT_EX,
727 offsetof(PyObj_pjsua_callback, on_pager), 0,
728 "Notify application on incoming pager (i.e. MESSAGE request). "
729 "Argument call_id will be -1 if MESSAGE request is not related to an "
730 "existing call."
731 },
732 {
733 "on_pager_status", T_OBJECT_EX,
734 offsetof(PyObj_pjsua_callback, on_pager_status), 0,
735 "Notify application about the delivery status of outgoing pager "
736 "request."
737 },
738 {
739 "on_typing", T_OBJECT_EX,
740 offsetof(PyObj_pjsua_callback, on_typing), 0,
741 "Notify application about typing indication."
742 },
743 {NULL} /* Sentinel */
744};
745
746
747/*
748 * PyTyp_pjsua_callback
749 * callback class definition
750 */
751static PyTypeObject PyTyp_pjsua_callback =
752{
753 PyObject_HEAD_INIT(NULL)
754 0, /*ob_size*/
755 "py_pjsua.Callback", /*tp_name*/
756 sizeof(PyObj_pjsua_callback), /*tp_basicsize*/
757 0, /*tp_itemsize*/
758 (destructor)PyObj_pjsua_callback_delete, /*tp_dealloc*/
759 0, /*tp_print*/
760 0, /*tp_getattr*/
761 0, /*tp_setattr*/
762 0, /*tp_compare*/
763 0, /*tp_repr*/
764 0, /*tp_as_number*/
765 0, /*tp_as_sequence*/
766 0, /*tp_as_mapping*/
767 0, /*tp_hash */
768 0, /*tp_call*/
769 0, /*tp_str*/
770 0, /*tp_getattro*/
771 0, /*tp_setattro*/
772 0, /*tp_as_buffer*/
773 Py_TPFLAGS_DEFAULT, /*tp_flags*/
774 "This structure describes application callback "
775 "to receive various event notifications from "
776 "PJSUA-API", /* tp_doc */
777 0, /* tp_traverse */
778 0, /* tp_clear */
779 0, /* tp_richcompare */
780 0, /* tp_weaklistoffset */
781 0, /* tp_iter */
782 0, /* tp_iternext */
783 0, /* tp_methods */
784 PyObj_pjsua_callback_members, /* tp_members */
785 0, /* tp_getset */
786 0, /* tp_base */
787 0, /* tp_dict */
788 0, /* tp_descr_get */
789 0, /* tp_descr_set */
790 0, /* tp_dictoffset */
791 0, /* tp_init */
792 0, /* tp_alloc */
793 PyObj_pjsua_callback_new, /* tp_new */
794
795};
796
797
798//////////////////////////////////////////////////////////////////////////////
799/*
800 * PyObj_pjsua_media_config
801 * C/Python wrapper for pjsua_media_config object
802 */
803typedef struct
804{
805 PyObject_HEAD
806 /* Type-specific fields go here. */
807 unsigned clock_rate;
808 unsigned max_media_ports;
809 int has_ioqueue;
810 unsigned thread_cnt;
811 unsigned quality;
812 unsigned ptime;
813 int no_vad;
814 unsigned ilbc_mode;
815 unsigned tx_drop_pct;
816 unsigned rx_drop_pct;
817 unsigned ec_options;
818 unsigned ec_tail_len;
819} PyObj_pjsua_media_config;
820
821
822/*
823 * PyObj_pjsua_media_config_members
824 * declares attributes accessible from both C and Python for media_config file
825 */
826static PyMemberDef PyObj_pjsua_media_config_members[] =
827{
828 {
829 "clock_rate", T_INT,
830 offsetof(PyObj_pjsua_media_config, clock_rate), 0,
831 "Clock rate to be applied to the conference bridge. If value is zero, "
832 "default clock rate will be used (16KHz)."
833 },
834 {
835 "max_media_ports", T_INT,
836 offsetof(PyObj_pjsua_media_config, max_media_ports), 0,
837 "Specify maximum number of media ports to be created in the "
838 "conference bridge. Since all media terminate in the bridge (calls, "
839 "file player, file recorder, etc), the value must be large enough to "
840 "support all of them. However, the larger the value, the more "
841 "computations are performed."
842 },
843 {
844 "has_ioqueue", T_INT,
845 offsetof(PyObj_pjsua_media_config, has_ioqueue), 0,
846 "Specify whether the media manager should manage its own ioqueue for "
847 "the RTP/RTCP sockets. If yes, ioqueue will be created and at least "
848 "one worker thread will be created too. If no, the RTP/RTCP sockets "
849 "will share the same ioqueue as SIP sockets, and no worker thread is "
850 "needed."
851 },
852 {
853 "thread_cnt", T_INT,
854 offsetof(PyObj_pjsua_media_config, thread_cnt), 0,
855 "Specify the number of worker threads to handle incoming RTP packets. "
856 "A value of one is recommended for most applications."
857 },
858 {
859 "quality", T_INT,
860 offsetof(PyObj_pjsua_media_config, quality), 0,
861 "The media quality also sets speex codec quality/complexity to the "
862 "number."
863 },
864 {
865 "ptime", T_INT,
866 offsetof(PyObj_pjsua_media_config, ptime), 0,
867 "Specify default ptime."
868 },
869 {
870 "no_vad", T_INT,
871 offsetof(PyObj_pjsua_media_config, no_vad), 0,
872 "Disable VAD?"
873 },
874 {
875 "ilbc_mode", T_INT,
876 offsetof(PyObj_pjsua_media_config, ilbc_mode), 0,
877 "iLBC mode (20 or 30)."
878 },
879 {
880 "tx_drop_pct", T_INT,
881 offsetof(PyObj_pjsua_media_config, tx_drop_pct), 0,
882 "Percentage of RTP packet to drop in TX direction (to simulate packet "
883 "lost)."
884 },
885 {
886 "rx_drop_pct", T_INT,
887 offsetof(PyObj_pjsua_media_config, rx_drop_pct), 0,
888 "Percentage of RTP packet to drop in RX direction (to simulate packet "
889 "lost)."},
890 {
891 "ec_options", T_INT,
892 offsetof(PyObj_pjsua_media_config, ec_options), 0,
893 "Echo canceller options (see pjmedia_echo_create())"
894 },
895 {
896 "ec_tail_len", T_INT,
897 offsetof(PyObj_pjsua_media_config, ec_tail_len), 0,
898 "Echo canceller tail length, in miliseconds."
899 },
900 {NULL} /* Sentinel */
901};
902
903
904/*
905 * PyTyp_pjsua_media_config
906 */
907static PyTypeObject PyTyp_pjsua_media_config =
908{
909 PyObject_HEAD_INIT(NULL)
910 0, /*ob_size*/
911 "py_pjsua.Media_Config", /*tp_name*/
912 sizeof(PyObj_pjsua_media_config),/*tp_basicsize*/
913 0, /*tp_itemsize*/
914 0, /*tp_dealloc*/
915 0, /*tp_print*/
916 0, /*tp_getattr*/
917 0, /*tp_setattr*/
918 0, /*tp_compare*/
919 0, /*tp_repr*/
920 0, /*tp_as_number*/
921 0, /*tp_as_sequence*/
922 0, /*tp_as_mapping*/
923 0, /*tp_hash */
924 0, /*tp_call*/
925 0, /*tp_str*/
926 0, /*tp_getattro*/
927 0, /*tp_setattro*/
928 0, /*tp_as_buffer*/
929 Py_TPFLAGS_DEFAULT, /*tp_flags*/
930 "Media Config objects", /*tp_doc*/
931 0, /*tp_traverse*/
932 0, /*tp_clear*/
933 0, /*tp_richcompare*/
934 0, /* tp_weaklistoffset */
935 0, /* tp_iter */
936 0, /* tp_iternext */
937 0, /* tp_methods */
938 PyObj_pjsua_media_config_members, /* tp_members */
939
940};
941
942
943static void PyObj_pjsua_media_config_import(PyObj_pjsua_media_config *obj,
944 const pjsua_media_config *cfg)
945{
946 obj->clock_rate = cfg->clock_rate;
947 obj->max_media_ports = cfg->max_media_ports;
948 obj->has_ioqueue = cfg->has_ioqueue;
949 obj->thread_cnt = cfg->thread_cnt;
950 obj->quality = cfg->quality;
951 obj->ptime = cfg->ptime;
952 obj->no_vad = cfg->no_vad;
953 obj->ilbc_mode = cfg->ilbc_mode;
954 obj->tx_drop_pct = cfg->tx_drop_pct;
955 obj->rx_drop_pct = cfg->rx_drop_pct;
956 obj->ec_options = cfg->ec_options;
957 obj->ec_tail_len = cfg->ec_tail_len;
958}
959
960static void PyObj_pjsua_media_config_export(pjsua_media_config *cfg,
961 const PyObj_pjsua_media_config *obj)
962{
963 cfg->clock_rate = obj->clock_rate;
964 cfg->max_media_ports = obj->max_media_ports;
965 cfg->has_ioqueue = obj->has_ioqueue;
966 cfg->thread_cnt = obj->thread_cnt;
967 cfg->quality = obj->quality;
968 cfg->ptime = obj->ptime;
969 cfg->no_vad = obj->no_vad;
970 cfg->ilbc_mode = obj->ilbc_mode;
971 cfg->tx_drop_pct = obj->tx_drop_pct;
972 cfg->rx_drop_pct = obj->rx_drop_pct;
973 cfg->ec_options = obj->ec_options;
974 cfg->ec_tail_len = obj->ec_tail_len;
975}
976
977//////////////////////////////////////////////////////////////////////////////
978/*
979 * PyObj_pjsua_config
980 * attribute list for config object
981 */
982typedef struct
983{
984 PyObject_HEAD
985 /* Type-specific fields go here. */
986 unsigned max_calls;
987 unsigned thread_cnt;
988 PyObject *outbound_proxy;
989 PyObject *stun_domain;
990 PyObject *stun_host;
991 PyObject *stun_relay_host;
992 PyObj_pjsua_callback *cb;
993 PyObject *user_agent;
994} PyObj_pjsua_config;
995
996
997static void PyObj_pjsua_config_delete(PyObj_pjsua_config* self)
998{
999 Py_XDECREF(self->outbound_proxy);
1000 Py_XDECREF(self->stun_domain);
1001 Py_XDECREF(self->stun_host);
1002 Py_XDECREF(self->stun_relay_host);
1003 Py_XDECREF(self->cb);
1004 Py_XDECREF(self->user_agent);
1005 self->ob_type->tp_free((PyObject*)self);
1006}
1007
1008
1009static void PyObj_pjsua_config_import(PyObj_pjsua_config *obj,
1010 const pjsua_config *cfg)
1011{
1012 obj->max_calls = cfg->max_calls;
1013 obj->thread_cnt = cfg->thread_cnt;
1014 Py_XDECREF(obj->outbound_proxy);
1015 obj->outbound_proxy = PyString_FromStringAndSize(cfg->outbound_proxy[0].ptr,
1016 cfg->outbound_proxy[0].slen);
1017 Py_XDECREF(obj->stun_domain);
1018 obj->stun_domain = PyString_FromStringAndSize(cfg->stun_domain.ptr,
1019 cfg->stun_domain.slen);
1020 Py_XDECREF(obj->stun_host);
1021 obj->stun_host = PyString_FromStringAndSize(cfg->stun_host.ptr,
1022 cfg->stun_host.slen);
1023 Py_XDECREF(obj->stun_relay_host);
1024 obj->stun_relay_host= PyString_FromStringAndSize(cfg->stun_relay_host.ptr,
1025 cfg->stun_relay_host.slen);
1026 Py_XDECREF(obj->user_agent);
1027 obj->user_agent = PyString_FromStringAndSize(cfg->user_agent.ptr,
1028 cfg->user_agent.slen);
1029}
1030
1031
1032static void PyObj_pjsua_config_export(pjsua_config *cfg,
1033 PyObj_pjsua_config *obj)
1034{
1035 cfg->max_calls = obj->max_calls;
1036 cfg->thread_cnt = obj->thread_cnt;
1037 if (PyString_Size(obj->outbound_proxy) > 0) {
1038 cfg->outbound_proxy_cnt = 1;
1039 cfg->outbound_proxy[0] = PyString_to_pj_str(obj->outbound_proxy);
1040 } else {
1041 cfg->outbound_proxy_cnt = 0;
1042 }
1043 cfg->stun_domain = PyString_to_pj_str(obj->stun_domain);
1044 cfg->stun_host = PyString_to_pj_str(obj->stun_host);
1045 cfg->stun_relay_host= PyString_to_pj_str(obj->stun_host);
1046 cfg->user_agent = PyString_to_pj_str(obj->user_agent);
1047
1048}
1049
1050
1051static PyObject *PyObj_pjsua_config_new(PyTypeObject *type,
1052 PyObject *args,
1053 PyObject *kwds)
1054{
1055 PyObj_pjsua_config *self;
1056
1057 PJ_UNUSED_ARG(args);
1058 PJ_UNUSED_ARG(kwds);
1059
1060 self = (PyObj_pjsua_config *)type->tp_alloc(type, 0);
1061 if (self != NULL)
1062 {
1063 self->user_agent = PyString_FromString("");
1064 if (self->user_agent == NULL)
1065 {
1066 Py_DECREF(self);
1067 return NULL;
1068 }
1069 self->outbound_proxy = PyString_FromString("");
1070 if (self->outbound_proxy == NULL)
1071 {
1072 Py_DECREF(self);
1073 return NULL;
1074 }
1075 self->cb = (PyObj_pjsua_callback *)
1076 PyType_GenericNew(&PyTyp_pjsua_callback, NULL, NULL);
1077 if (self->cb == NULL)
1078 {
1079 Py_DECREF(Py_None);
1080 return NULL;
1081 }
1082 }
1083 return (PyObject *)self;
1084}
1085
1086
1087/*
1088 * PyObj_pjsua_config_members
1089 * attribute list accessible from Python/C
1090 */
1091static PyMemberDef PyObj_pjsua_config_members[] =
1092{
1093 {
1094 "max_calls", T_INT,
1095 offsetof(PyObj_pjsua_config, max_calls), 0,
1096 "Maximum calls to support (default: 4) "
1097 },
1098 {
1099 "thread_cnt", T_INT,
1100 offsetof(PyObj_pjsua_config, thread_cnt), 0,
1101 "Number of worker threads. Normally application will want to have at "
1102 "least one worker thread, unless when it wants to poll the library "
1103 "periodically, which in this case the worker thread can be set to "
1104 "zero."
1105 },
1106 {
1107 "outbound_proxy", T_OBJECT_EX,
1108 offsetof(PyObj_pjsua_config, outbound_proxy), 0,
1109 "SIP URL of the outbound proxy (optional)"
1110 },
1111 {
1112 "stun_domain", T_OBJECT_EX,
1113 offsetof(PyObj_pjsua_config, stun_domain), 0,
1114 "Domain of the STUN server (optional). STUN server will be resolved "
1115 "using DNS SRV resolution only when nameserver is configured. "
1116 "Alternatively, if DNS SRV resolution for STUN is not desired, "
1117 "application can specify the STUN server hostname or IP address "
1118 "in stun_host attribute."
1119 },
1120 {
1121 "stun_host", T_OBJECT_EX,
1122 offsetof(PyObj_pjsua_config, stun_host), 0,
1123 "Hostname or IP address of the STUN server (optional)."
1124 },
1125 {
1126 "stun_relay_host", T_OBJECT_EX,
1127 offsetof(PyObj_pjsua_config, stun_relay_host), 0,
1128 "Hostname or IP address of the TURN server (optional)."
1129 },
1130 {
1131 "cb", T_OBJECT_EX, offsetof(PyObj_pjsua_config, cb), 0,
1132 "Application callback."
1133 },
1134 {
1135 "user_agent", T_OBJECT_EX, offsetof(PyObj_pjsua_config, user_agent), 0,
1136 "User agent string (default empty)"
1137 },
1138 {NULL} /* Sentinel */
1139};
1140
1141
1142/*
1143 * PyTyp_pjsua_config
1144 * type wrapper for config class
1145 */
1146static PyTypeObject PyTyp_pjsua_config =
1147{
1148 PyObject_HEAD_INIT(NULL)
1149 0, /*ob_size*/
1150 "py_pjsua.Config", /*tp_name*/
1151 sizeof(PyObj_pjsua_config),/*tp_basicsize*/
1152 0, /*tp_itemsize*/
1153 (destructor)PyObj_pjsua_config_delete,/*tp_dealloc*/
1154 0, /*tp_print*/
1155 0, /*tp_getattr*/
1156 0, /*tp_setattr*/
1157 0, /*tp_compare*/
1158 0, /*tp_repr*/
1159 0, /*tp_as_number*/
1160 0, /*tp_as_sequence*/
1161 0, /*tp_as_mapping*/
1162 0, /*tp_hash */
1163 0, /*tp_call*/
1164 0, /*tp_str*/
1165 0, /*tp_getattro*/
1166 0, /*tp_setattro*/
1167 0, /*tp_as_buffer*/
1168 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1169 "Config object", /* tp_doc */
1170 0, /* tp_traverse */
1171 0, /* tp_clear */
1172 0, /* tp_richcompare */
1173 0, /* tp_weaklistoffset */
1174 0, /* tp_iter */
1175 0, /* tp_iternext */
1176 0, /* tp_methods */
1177 PyObj_pjsua_config_members,/* tp_members */
1178 0, /* tp_getset */
1179 0, /* tp_base */
1180 0, /* tp_dict */
1181 0, /* tp_descr_get */
1182 0, /* tp_descr_set */
1183 0, /* tp_dictoffset */
1184 0, /* tp_init */
1185 0, /* tp_alloc */
1186 PyObj_pjsua_config_new, /* tp_new */
1187
1188};
1189
1190//////////////////////////////////////////////////////////////////////////////
1191/*
1192 * PyObj_pjsua_logging_config
1193 * configuration class for logging_config object
1194 */
1195typedef struct
1196{
1197 PyObject_HEAD
1198 /* Type-specific fields go here. */
1199 int msg_logging;
1200 unsigned level;
1201 unsigned console_level;
1202 unsigned decor;
1203 PyObject *log_filename;
1204 PyObject *cb;
1205} PyObj_pjsua_logging_config;
1206
1207
1208/*
1209 * PyObj_pjsua_logging_config_delete
1210 * deletes a logging config from memory
1211 */
1212static void PyObj_pjsua_logging_config_delete(PyObj_pjsua_logging_config* self)
1213{
1214 Py_XDECREF(self->log_filename);
1215 Py_XDECREF(self->cb);
1216 self->ob_type->tp_free((PyObject*)self);
1217}
1218
1219
1220static void PyObj_pjsua_logging_config_import(PyObj_pjsua_logging_config *obj,
1221 const pjsua_logging_config *cfg)
1222{
1223 obj->msg_logging = cfg->msg_logging;
1224 obj->level = cfg->level;
1225 obj->console_level = cfg->console_level;
1226 obj->decor = cfg->decor;
1227}
1228
1229static void PyObj_pjsua_logging_config_export(pjsua_logging_config *cfg,
1230 PyObj_pjsua_logging_config *obj)
1231{
1232 cfg->msg_logging = obj->msg_logging;
1233 cfg->level = obj->level;
1234 cfg->console_level = obj->console_level;
1235 cfg->decor = obj->decor;
1236 cfg->log_filename = PyString_to_pj_str(obj->log_filename);
1237}
1238
1239
1240/*
1241 * PyObj_pjsua_logging_config_new
1242 * constructor for logging_config object
1243 */
1244static PyObject * PyObj_pjsua_logging_config_new(PyTypeObject *type,
1245 PyObject *args,
1246 PyObject *kwds)
1247{
1248 PyObj_pjsua_logging_config *self;
1249
1250 PJ_UNUSED_ARG(args);
1251 PJ_UNUSED_ARG(kwds);
1252
1253 self = (PyObj_pjsua_logging_config *)type->tp_alloc(type, 0);
1254 if (self != NULL)
1255 {
1256 self->log_filename = PyString_FromString("");
1257 if (self->log_filename == NULL)
1258 {
1259 Py_DECREF(self);
1260 return NULL;
1261 }
1262 Py_INCREF(Py_None);
1263 self->cb = Py_None;
1264 if (self->cb == NULL)
1265 {
1266 Py_DECREF(Py_None);
1267 return NULL;
1268 }
1269 }
1270
1271 return (PyObject *)self;
1272}
1273
1274
1275/*
1276 * PyObj_pjsua_logging_config_members
1277 */
1278static PyMemberDef PyObj_pjsua_logging_config_members[] =
1279{
1280 {
1281 "msg_logging", T_INT,
1282 offsetof(PyObj_pjsua_logging_config, msg_logging), 0,
1283 "Log incoming and outgoing SIP message? Yes!"
1284 },
1285 {
1286 "level", T_INT,
1287 offsetof(PyObj_pjsua_logging_config, level), 0,
1288 "Input verbosity level. Value 5 is reasonable."
1289 },
1290 {
1291 "console_level", T_INT,
1292 offsetof(PyObj_pjsua_logging_config, console_level),
1293 0, "Verbosity level for console. Value 4 is reasonable."
1294 },
1295 {
1296 "decor", T_INT,
1297 offsetof(PyObj_pjsua_logging_config, decor), 0,
1298 "Log decoration"
1299 },
1300 {
1301 "log_filename", T_OBJECT_EX,
1302 offsetof(PyObj_pjsua_logging_config, log_filename), 0,
1303 "Optional log filename"
1304 },
1305 {
1306 "cb", T_OBJECT_EX,
1307 offsetof(PyObj_pjsua_logging_config, cb), 0,
1308 "Optional callback function to be called to write log to application "
1309 "specific device. This function will be called forlog messages on "
1310 "input verbosity level."
1311 },
1312 {NULL} /* Sentinel */
1313};
1314
1315
1316
1317
1318/*
1319 * PyTyp_pjsua_logging_config
1320 */
1321static PyTypeObject PyTyp_pjsua_logging_config =
1322{
1323 PyObject_HEAD_INIT(NULL)
1324 0, /*ob_size*/
1325 "py_pjsua.Logging_Config", /*tp_name*/
1326 sizeof(PyObj_pjsua_logging_config), /*tp_basicsize*/
1327 0, /*tp_itemsize*/
1328 (destructor)PyObj_pjsua_logging_config_delete,/*tp_dealloc*/
1329 0, /*tp_print*/
1330 0, /*tp_getattr*/
1331 0, /*tp_setattr*/
1332 0, /*tp_compare*/
1333 0, /*tp_repr*/
1334 0, /*tp_as_number*/
1335 0, /*tp_as_sequence*/
1336 0, /*tp_as_mapping*/
1337 0, /*tp_hash */
1338 0, /*tp_call*/
1339 0, /*tp_str*/
1340 0, /*tp_getattro*/
1341 0, /*tp_setattro*/
1342 0, /*tp_as_buffer*/
1343 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1344 "Logging Config objects", /* tp_doc */
1345 0, /* tp_traverse */
1346 0, /* tp_clear */
1347 0, /* tp_richcompare */
1348 0, /* tp_weaklistoffset */
1349 0, /* tp_iter */
1350 0, /* tp_iternext */
1351 0, /* tp_methods */
1352 PyObj_pjsua_logging_config_members,/* tp_members */
1353 0, /* tp_getset */
1354 0, /* tp_base */
1355 0, /* tp_dict */
1356 0, /* tp_descr_get */
1357 0, /* tp_descr_set */
1358 0, /* tp_dictoffset */
1359 0, /* tp_init */
1360 0, /* tp_alloc */
1361 PyObj_pjsua_logging_config_new, /* tp_new */
1362
1363};
1364
1365
1366//////////////////////////////////////////////////////////////////////////////
1367/*
1368 * PyObj_pjsua_msg_data
1369 * typewrapper for MessageData class
1370 * !modified @ 061206
1371 */
1372typedef struct
1373{
1374 PyObject_HEAD
1375 /* Type-specific fields go here. */
1376 PyObject * hdr_list;
1377 PyObject * content_type;
1378 PyObject * msg_body;
1379} PyObj_pjsua_msg_data;
1380
1381
1382/*
1383 * PyObj_pjsua_msg_data_delete
1384 * deletes a msg_data
1385 * !modified @ 061206
1386 */
1387static void PyObj_pjsua_msg_data_delete(PyObj_pjsua_msg_data* self)
1388{
1389 Py_XDECREF(self->hdr_list);
1390 Py_XDECREF(self->content_type);
1391 Py_XDECREF(self->msg_body);
1392 self->ob_type->tp_free((PyObject*)self);
1393}
1394
1395
1396/*
1397 * PyObj_pjsua_msg_data_new
1398 * constructor for msg_data object
1399 * !modified @ 061206
1400 */
1401static PyObject * PyObj_pjsua_msg_data_new(PyTypeObject *type,
1402 PyObject *args,
1403 PyObject *kwds)
1404{
1405 PyObj_pjsua_msg_data *self;
1406
1407 PJ_UNUSED_ARG(args);
1408 PJ_UNUSED_ARG(kwds);
1409
1410 self = (PyObj_pjsua_msg_data *)type->tp_alloc(type, 0);
1411 if (self != NULL)
1412 {
1413 Py_INCREF(Py_None);
1414 self->hdr_list = Py_None;
1415 if (self->hdr_list == NULL) {
1416 Py_DECREF(self);
1417 return NULL;
1418 }
1419 self->content_type = PyString_FromString("");
1420 if (self->content_type == NULL) {
1421 Py_DECREF(self);
1422 return NULL;
1423 }
1424 self->msg_body = PyString_FromString("");
1425 if (self->msg_body == NULL) {
1426 Py_DECREF(self);
1427 return NULL;
1428 }
1429 }
1430
1431 return (PyObject *)self;
1432}
1433
1434
1435/*
1436 * PyObj_pjsua_msg_data_members
1437 * !modified @ 061206
1438 */
1439static PyMemberDef PyObj_pjsua_msg_data_members[] =
1440{
1441 {
1442 "hdr_list", T_OBJECT_EX,
1443 offsetof(PyObj_pjsua_msg_data, hdr_list), 0,
1444 "Additional message headers as linked list of strings."
1445 },
1446 {
1447 "content_type", T_OBJECT_EX,
1448 offsetof(PyObj_pjsua_msg_data, content_type), 0,
1449 "MIME type of optional message body."
1450 },
1451 {
1452 "msg_body", T_OBJECT_EX,
1453 offsetof(PyObj_pjsua_msg_data, msg_body), 0,
1454 "Optional message body."
1455 },
1456 {NULL} /* Sentinel */
1457};
1458
1459
1460/*
1461 * PyTyp_pjsua_msg_data
1462 */
1463static PyTypeObject PyTyp_pjsua_msg_data =
1464{
1465 PyObject_HEAD_INIT(NULL)
1466 0, /*ob_size*/
1467 "py_pjsua.Msg_Data", /*tp_name*/
1468 sizeof(PyObj_pjsua_msg_data), /*tp_basicsize*/
1469 0, /*tp_itemsize*/
1470 (destructor)PyObj_pjsua_msg_data_delete,/*tp_dealloc*/
1471 0, /*tp_print*/
1472 0, /*tp_getattr*/
1473 0, /*tp_setattr*/
1474 0, /*tp_compare*/
1475 0, /*tp_repr*/
1476 0, /*tp_as_number*/
1477 0, /*tp_as_sequence*/
1478 0, /*tp_as_mapping*/
1479 0, /*tp_hash */
1480 0, /*tp_call*/
1481 0, /*tp_str*/
1482 0, /*tp_getattro*/
1483 0, /*tp_setattro*/
1484 0, /*tp_as_buffer*/
1485 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1486 "msg_data objects", /* tp_doc */
1487 0, /* tp_traverse */
1488 0, /* tp_clear */
1489 0, /* tp_richcompare */
1490 0, /* tp_weaklistoffset */
1491 0, /* tp_iter */
1492 0, /* tp_iternext */
1493 0, /* tp_methods */
1494 PyObj_pjsua_msg_data_members, /* tp_members */
1495 0, /* tp_getset */
1496 0, /* tp_base */
1497 0, /* tp_dict */
1498 0, /* tp_descr_get */
1499 0, /* tp_descr_set */
1500 0, /* tp_dictoffset */
1501 0, /* tp_init */
1502 0, /* tp_alloc */
1503 PyObj_pjsua_msg_data_new, /* tp_new */
1504
1505};
1506
1507
1508//////////////////////////////////////////////////////////////////////////////
1509/*
1510 * PyObj_pjsua_transport_config
1511 * Transport configuration for creating UDP transports for both SIP
1512 * and media.
1513 */
1514typedef struct
1515{
1516 PyObject_HEAD
1517 /* Type-specific fields go here. */
1518 unsigned port;
1519 PyObject *public_addr;
1520 PyObject *bound_addr;
1521} PyObj_pjsua_transport_config;
1522
1523
1524/*
1525 * PyObj_pjsua_transport_config_delete
1526 * deletes a transport config from memory
1527 */
1528static void PyObj_pjsua_transport_config_delete(PyObj_pjsua_transport_config* self)
1529{
1530 Py_XDECREF(self->public_addr);
1531 Py_XDECREF(self->bound_addr);
1532 self->ob_type->tp_free((PyObject*)self);
1533}
1534
1535
1536static void PyObj_pjsua_transport_config_export(pjsua_transport_config *cfg,
1537 PyObj_pjsua_transport_config *obj)
1538{
1539 cfg->public_addr = PyString_to_pj_str(obj->public_addr);
1540 cfg->bound_addr = PyString_to_pj_str(obj->bound_addr);
1541 cfg->port = obj->port;
1542
1543}
1544
1545static void PyObj_pjsua_transport_config_import(PyObj_pjsua_transport_config *obj,
1546 const pjsua_transport_config *cfg)
1547{
1548 Py_XDECREF(obj->public_addr);
1549 obj->public_addr = PyString_FromStringAndSize(cfg->public_addr.ptr,
1550 cfg->public_addr.slen);
1551
1552 Py_XDECREF(obj->bound_addr);
1553 obj->bound_addr = PyString_FromStringAndSize(cfg->bound_addr.ptr,
1554 cfg->bound_addr.slen);
1555
1556 obj->port = cfg->port;
1557}
1558
1559
1560/*
1561 * PyObj_pjsua_transport_config_new
1562 * constructor for transport_config object
1563 */
1564static PyObject * PyObj_pjsua_transport_config_new(PyTypeObject *type,
1565 PyObject *args,
1566 PyObject *kwds)
1567{
1568 PyObj_pjsua_transport_config *self;
1569
1570 PJ_UNUSED_ARG(args);
1571 PJ_UNUSED_ARG(kwds);
1572
1573 self = (PyObj_pjsua_transport_config *)type->tp_alloc(type, 0);
1574 if (self != NULL) {
1575 self->public_addr = PyString_FromString("");
1576 if (self->public_addr == NULL) {
1577 Py_DECREF(self);
1578 return NULL;
1579 }
1580 self->bound_addr = PyString_FromString("");
1581 if (self->bound_addr == NULL) {
1582 Py_DECREF(self);
1583 return NULL;
1584 }
1585 }
1586
1587 return (PyObject *)self;
1588}
1589
1590
1591/*
1592 * PyObj_pjsua_transport_config_members
1593 */
1594static PyMemberDef PyObj_pjsua_transport_config_members[] =
1595{
1596 {
1597 "port", T_INT,
1598 offsetof(PyObj_pjsua_transport_config, port), 0,
1599 "UDP port number to bind locally. This setting MUST be specified "
1600 "even when default port is desired. If the value is zero, the "
1601 "transport will be bound to any available port, and application "
1602 "can query the port by querying the transport info."
1603 },
1604 {
1605 "public_addr", T_OBJECT_EX,
1606 offsetof(PyObj_pjsua_transport_config, public_addr), 0,
1607 "Optional address to advertise as the address of this transport. "
1608 "Application can specify any address or hostname for this field, "
1609 "for example it can point to one of the interface address in the "
1610 "system, or it can point to the public address of a NAT router "
1611 "where port mappings have been configured for the application."
1612 },
1613 {
1614 "bound_addr", T_OBJECT_EX,
1615 offsetof(PyObj_pjsua_transport_config, bound_addr), 0,
1616 "Optional address where the socket should be bound to. This option "
1617 "SHOULD only be used to selectively bind the socket to particular "
1618 "interface (instead of 0.0.0.0), and SHOULD NOT be used to set the "
1619 "published address of a transport (the public_addr field should be "
1620 "used for that purpose)."
1621 },
1622 {NULL} /* Sentinel */
1623};
1624
1625
1626
1627
1628/*
1629 * PyTyp_pjsua_transport_config
1630 */
1631static PyTypeObject PyTyp_pjsua_transport_config =
1632{
1633 PyObject_HEAD_INIT(NULL)
1634 0, /*ob_size*/
1635 "py_pjsua.Transport_Config", /*tp_name*/
1636 sizeof(PyObj_pjsua_transport_config), /*tp_basicsize*/
1637 0, /*tp_itemsize*/
1638 (destructor)PyObj_pjsua_transport_config_delete,/*tp_dealloc*/
1639 0, /*tp_print*/
1640 0, /*tp_getattr*/
1641 0, /*tp_setattr*/
1642 0, /*tp_compare*/
1643 0, /*tp_repr*/
1644 0, /*tp_as_number*/
1645 0, /*tp_as_sequence*/
1646 0, /*tp_as_mapping*/
1647 0, /*tp_hash */
1648 0, /*tp_call*/
1649 0, /*tp_str*/
1650 0, /*tp_getattro*/
1651 0, /*tp_setattro*/
1652 0, /*tp_as_buffer*/
1653 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1654 "Transport setting", /* tp_doc */
1655 0, /* tp_traverse */
1656 0, /* tp_clear */
1657 0, /* tp_richcompare */
1658 0, /* tp_weaklistoffset */
1659 0, /* tp_iter */
1660 0, /* tp_iternext */
1661 0, /* tp_methods */
1662 PyObj_pjsua_transport_config_members,/* tp_members */
1663 0, /* tp_getset */
1664 0, /* tp_base */
1665 0, /* tp_dict */
1666 0, /* tp_descr_get */
1667 0, /* tp_descr_set */
1668 0, /* tp_dictoffset */
1669 0, /* tp_init */
1670 0, /* tp_alloc */
1671 PyObj_pjsua_transport_config_new,/* tp_new */
1672};
1673
1674
1675//////////////////////////////////////////////////////////////////////////////
1676/*
1677 * PyObj_pjsua_transport_info
1678 * Transport info
1679 */
1680typedef struct
1681{
1682 PyObject_HEAD
1683 /* Type-specific fields go here. */
1684 int id;
1685 int type;
1686 PyObject *type_name;
1687 PyObject *info;
1688 unsigned flag;
1689 PyObject *addr;
1690 unsigned port;
1691 unsigned usage_count;
1692} PyObj_pjsua_transport_info;
1693
1694
1695/*
1696 * PyObj_pjsua_transport_info_delete
1697 * deletes a transport info from memory
1698 */
1699static void PyObj_pjsua_transport_info_delete(PyObj_pjsua_transport_info* self)
1700{
1701 Py_XDECREF(self->type_name);
1702 Py_XDECREF(self->info);
1703 Py_XDECREF(self->addr);
1704 self->ob_type->tp_free((PyObject*)self);
1705}
1706
1707
1708static void PyObj_pjsua_transport_info_import(PyObj_pjsua_transport_info *obj,
1709 const pjsua_transport_info *info)
1710{
1711 obj->id = info->id;
1712 obj->type = info->type;
1713 obj->type_name = PyString_FromStringAndSize(info->type_name.ptr,
1714 info->type_name.slen);
1715 obj->info = PyString_FromStringAndSize(info->info.ptr,
1716 info->info.slen);
1717 obj->flag = info->flag;
1718 obj->addr = PyString_FromStringAndSize(info->local_name.host.ptr,
1719 info->local_name.host.slen);
1720 obj->port = info->local_name.port;
1721 obj->usage_count= info->usage_count;
1722}
1723
1724/*
1725 * PyObj_pjsua_transport_info_new
1726 * constructor for transport_info object
1727 */
1728static PyObject * PyObj_pjsua_transport_info_new(PyTypeObject *type,
1729 PyObject *args,
1730 PyObject *kwds)
1731{
1732 PyObj_pjsua_transport_info *self;
1733
1734 PJ_UNUSED_ARG(args);
1735 PJ_UNUSED_ARG(kwds);
1736
1737 self = (PyObj_pjsua_transport_info *)type->tp_alloc(type, 0);
1738 if (self != NULL)
1739 {
1740 self->type_name = PyString_FromString("");
1741 if (self->type_name == NULL) {
1742 Py_DECREF(self);
1743 return NULL;
1744 }
1745 self->info = PyString_FromString("");
1746 if (self->info == NULL) {
1747 Py_DECREF(self);
1748 return NULL;
1749 }
1750 self->addr = PyString_FromString("");
1751 if (self->addr == NULL) {
1752 Py_DECREF(self);
1753 return NULL;
1754 }
1755 }
1756
1757 return (PyObject *)self;
1758}
1759
1760
1761/*
1762 * PyObj_pjsua_transport_info_members
1763 */
1764static PyMemberDef PyObj_pjsua_transport_info_members[] =
1765{
1766 {
1767 "id", T_INT,
1768 offsetof(PyObj_pjsua_transport_info, id), 0,
1769 "PJSUA transport identification."
1770 },
1771 {
1772 "type", T_INT,
1773 offsetof(PyObj_pjsua_transport_info, id), 0,
1774 "Transport type."
1775 },
1776 {
1777 "type_name", T_OBJECT_EX,
1778 offsetof(PyObj_pjsua_transport_info, type_name), 0,
1779 "Transport type name."
1780 },
1781 {
1782 "info", T_OBJECT_EX,
1783 offsetof(PyObj_pjsua_transport_info, info), 0,
1784 "Transport string info/description."
1785 },
1786 {
1787 "flag", T_INT,
1788 offsetof(PyObj_pjsua_transport_info, flag), 0,
1789 "Transport flag (see ##pjsip_transport_flags_e)."
1790 },
1791 {
1792 "addr", T_OBJECT_EX,
1793 offsetof(PyObj_pjsua_transport_info, addr), 0,
1794 "Published address (or transport address name)."
1795 },
1796 {
1797 "port", T_INT,
1798 offsetof(PyObj_pjsua_transport_info, port), 0,
1799 "Published port number."
1800 },
1801 {
1802 "usage_count", T_INT,
1803 offsetof(PyObj_pjsua_transport_info, usage_count), 0,
1804 "Current number of objects currently referencing this transport."
1805 },
1806 {NULL} /* Sentinel */
1807};
1808
1809
1810/*
1811 * PyTyp_pjsua_transport_info
1812 */
1813static PyTypeObject PyTyp_pjsua_transport_info =
1814{
1815 PyObject_HEAD_INIT(NULL)
1816 0, /*ob_size*/
1817 "py_pjsua.Transport_Info", /*tp_name*/
1818 sizeof(PyObj_pjsua_transport_info), /*tp_basicsize*/
1819 0, /*tp_itemsize*/
1820 (destructor)PyObj_pjsua_transport_info_delete,/*tp_dealloc*/
1821 0, /*tp_print*/
1822 0, /*tp_getattr*/
1823 0, /*tp_setattr*/
1824 0, /*tp_compare*/
1825 0, /*tp_repr*/
1826 0, /*tp_as_number*/
1827 0, /*tp_as_sequence*/
1828 0, /*tp_as_mapping*/
1829 0, /*tp_hash */
1830 0, /*tp_call*/
1831 0, /*tp_str*/
1832 0, /*tp_getattro*/
1833 0, /*tp_setattro*/
1834 0, /*tp_as_buffer*/
1835 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1836 "Transport Info objects", /* tp_doc */
1837 0, /* tp_traverse */
1838 0, /* tp_clear */
1839 0, /* tp_richcompare */
1840 0, /* tp_weaklistoffset */
1841 0, /* tp_iter */
1842 0, /* tp_iternext */
1843 0, /* tp_methods */
1844 PyObj_pjsua_transport_info_members, /* tp_members */
1845 0, /* tp_getset */
1846 0, /* tp_base */
1847 0, /* tp_dict */
1848 0, /* tp_descr_get */
1849 0, /* tp_descr_set */
1850 0, /* tp_dictoffset */
1851 0, /* tp_init */
1852 0, /* tp_alloc */
1853 PyObj_pjsua_transport_info_new, /* tp_new */
1854
1855};
1856
1857
1858//////////////////////////////////////////////////////////////////////////////
1859
1860/*
1861 * PyObj_pjsua_acc_config
1862 * Acc Config
1863 */
1864typedef struct
1865{
1866 PyObject_HEAD
1867 /* Type-specific fields go here. */
1868 int priority;
1869 PyObject *id;
1870 PyObject *reg_uri;
1871 int publish_enabled;
1872 PyObject *force_contact;
1873 /*pj_str_t proxy[8];*/
1874 PyListObject *proxy;
1875 unsigned reg_timeout;
1876 /*pjsip_cred_info cred_info[8];*/
1877 PyListObject *cred_info;
1878 int transport_id;
1879} PyObj_pjsua_acc_config;
1880
1881
1882/*
1883 * PyObj_pjsua_acc_config_delete
1884 * deletes a acc_config from memory
1885 */
1886static void PyObj_pjsua_acc_config_delete(PyObj_pjsua_acc_config* self)
1887{
1888 Py_XDECREF(self->id);
1889 Py_XDECREF(self->reg_uri);
1890 Py_XDECREF(self->force_contact);
1891 Py_XDECREF(self->proxy);
1892 Py_XDECREF(self->cred_info);
1893 self->ob_type->tp_free((PyObject*)self);
1894}
1895
1896
1897static void PyObj_pjsua_acc_config_import(PyObj_pjsua_acc_config *obj,
1898 const pjsua_acc_config *cfg)
1899{
1900 unsigned i;
1901
1902 obj->priority = cfg->priority;
1903 Py_XDECREF(obj->id);
1904 obj->id = PyString_FromStringAndSize(cfg->id.ptr, cfg->id.slen);
1905 Py_XDECREF(obj->reg_uri);
1906 obj->reg_uri = PyString_FromStringAndSize(cfg->reg_uri.ptr,
1907 cfg->reg_uri.slen);
1908 obj->publish_enabled = cfg->publish_enabled;
1909 Py_XDECREF(obj->force_contact);
1910 obj->force_contact = PyString_FromStringAndSize(cfg->force_contact.ptr,
1911 cfg->force_contact.slen);
1912 Py_XDECREF(obj->proxy);
Benny Prijonod7ea6052007-09-17 15:44:47 +00001913 obj->proxy = (PyListObject *)PyList_New(0);
Benny Prijono1f63cc42007-09-10 16:54:22 +00001914 for (i=0; i<cfg->proxy_cnt; ++i) {
1915 PyObject * str;
1916 str = PyString_FromStringAndSize(cfg->proxy[i].ptr,
1917 cfg->proxy[i].slen);
Benny Prijonod7ea6052007-09-17 15:44:47 +00001918 PyList_Append((PyObject *)obj->proxy, str);
Benny Prijono1f63cc42007-09-10 16:54:22 +00001919 }
1920
1921 obj->reg_timeout = cfg->reg_timeout;
1922
1923 Py_XDECREF(obj->cred_info);
Benny Prijonod7ea6052007-09-17 15:44:47 +00001924 obj->cred_info = (PyListObject *)PyList_New(0);
Benny Prijono1f63cc42007-09-10 16:54:22 +00001925 for (i=0; i<cfg->cred_count; ++i) {
1926 PyObj_pjsip_cred_info * ci;
1927
1928 ci = (PyObj_pjsip_cred_info *)
1929 PyObj_pjsip_cred_info_new(&PyTyp_pjsip_cred_info,NULL,NULL);
1930 PyObj_pjsip_cred_info_import(ci, &cfg->cred_info[i]);
Benny Prijonod7ea6052007-09-17 15:44:47 +00001931 PyList_Append((PyObject *)obj->cred_info, (PyObject *)ci);
Benny Prijono1f63cc42007-09-10 16:54:22 +00001932 }
1933
1934 obj->transport_id = cfg->transport_id;
1935}
1936
1937static void PyObj_pjsua_acc_config_export(pjsua_acc_config *cfg,
1938 PyObj_pjsua_acc_config *obj)
1939{
1940 unsigned i;
1941
1942 cfg->priority = obj->priority;
1943 cfg->id = PyString_to_pj_str(obj->id);
1944 cfg->reg_uri = PyString_to_pj_str(obj->reg_uri);
1945 cfg->publish_enabled = obj->publish_enabled;
1946 cfg->force_contact = PyString_to_pj_str(obj->force_contact);
1947
1948 cfg->proxy_cnt = PyList_Size((PyObject*)obj->proxy);
1949 for (i = 0; i < cfg->proxy_cnt; i++) {
1950 /*cfg.proxy[i] = ac->proxy[i];*/
1951 cfg->proxy[i] = PyString_to_pj_str(PyList_GetItem((PyObject *)obj->proxy,i));
1952 }
1953
1954 cfg->reg_timeout = obj->reg_timeout;
1955
1956 cfg->cred_count = PyList_Size((PyObject*)obj->cred_info);
1957 for (i = 0; i < cfg->cred_count; i++) {
1958 /*cfg.cred_info[i] = ac->cred_info[i];*/
1959 PyObj_pjsip_cred_info *ci;
1960 ci = (PyObj_pjsip_cred_info*)
1961 PyList_GetItem((PyObject *)obj->cred_info,i);
1962 PyObj_pjsip_cred_info_export(&cfg->cred_info[i], ci);
1963 }
1964
1965 cfg->transport_id = obj->transport_id;
1966}
1967
1968
1969/*
1970 * PyObj_pjsua_acc_config_new
1971 * constructor for acc_config object
1972 */
1973static PyObject * PyObj_pjsua_acc_config_new(PyTypeObject *type,
1974 PyObject *args,
1975 PyObject *kwds)
1976{
1977 PyObj_pjsua_acc_config *self;
1978
1979 PJ_UNUSED_ARG(args);
1980 PJ_UNUSED_ARG(kwds);
1981
1982 self = (PyObj_pjsua_acc_config *)type->tp_alloc(type, 0);
1983 if (self != NULL) {
1984 self->id = PyString_FromString("");
1985 if (self->id == NULL) {
1986 Py_DECREF(self);
1987 return NULL;
1988 }
1989 self->reg_uri = PyString_FromString("");
1990 if (self->reg_uri == NULL) {
1991 Py_DECREF(self);
1992 return NULL;
1993 }
1994 self->force_contact = PyString_FromString("");
1995 if (self->force_contact == NULL) {
1996 Py_DECREF(self);
1997 return NULL;
1998 }
Benny Prijonod7ea6052007-09-17 15:44:47 +00001999 self->proxy = (PyListObject *)PyList_New(0);
Benny Prijono1f63cc42007-09-10 16:54:22 +00002000 if (self->proxy == NULL) {
2001 Py_DECREF(self);
2002 return NULL;
2003 }
Benny Prijonod7ea6052007-09-17 15:44:47 +00002004 self->cred_info = (PyListObject *)PyList_New(0);
Benny Prijono1f63cc42007-09-10 16:54:22 +00002005 if (self->cred_info == NULL) {
2006 Py_DECREF(self);
2007 return NULL;
2008 }
2009 }
2010
2011 return (PyObject *)self;
2012}
2013
2014
2015
2016/*
2017 * PyObj_pjsua_acc_config_members
2018 */
2019static PyMemberDef PyObj_pjsua_acc_config_members[] =
2020{
2021 {
2022 "priority", T_INT, offsetof(PyObj_pjsua_acc_config, priority), 0,
2023 "Account priority, which is used to control the order of matching "
2024 "incoming/outgoing requests. The higher the number means the higher "
2025 "the priority is, and the account will be matched first. "
2026 },
2027 {
2028 "id", T_OBJECT_EX,
2029 offsetof(PyObj_pjsua_acc_config, id), 0,
2030 "The full SIP URL for the account. "
2031 "The value can take name address or URL format, "
2032 "and will look something like 'sip:account@serviceprovider'. "
2033 "This field is mandatory."
2034 },
2035 {
2036 "reg_uri", T_OBJECT_EX,
2037 offsetof(PyObj_pjsua_acc_config, reg_uri), 0,
2038 "This is the URL to be put in the request URI for the registration, "
2039 "and will look something like 'sip:serviceprovider'. "
2040 "This field should be specified if registration is desired. "
2041 "If the value is empty, no account registration will be performed. "
2042 },
2043 {
2044 "publish_enabled", T_INT,
2045 offsetof(PyObj_pjsua_acc_config, publish_enabled), 0,
2046 "Publish presence? "
2047 },
2048 {
2049 "force_contact", T_OBJECT_EX,
2050 offsetof(PyObj_pjsua_acc_config, force_contact), 0,
2051 "Optional URI to be put as Contact for this account. "
2052 "It is recommended that this field is left empty, "
2053 "so that the value will be calculated automatically "
2054 "based on the transport address. "
2055 },
2056 {
2057 "proxy", T_OBJECT_EX,
2058 offsetof(PyObj_pjsua_acc_config, proxy), 0,
2059 "Optional URI of the proxies to be visited for all outgoing requests "
2060 "that are using this account (REGISTER, INVITE, etc). Application need "
2061 "to specify these proxies if the service provider requires "
2062 "that requests destined towards its network should go through certain "
2063 "proxies first (for example, border controllers)."
2064 },
2065 {
2066 "reg_timeout", T_INT, offsetof(PyObj_pjsua_acc_config, reg_timeout), 0,
2067 "Optional interval for registration, in seconds. "
2068 "If the value is zero, default interval will be used "
2069 "(PJSUA_REG_INTERVAL, 55 seconds). "
2070 },
2071 {
2072 "cred_info", T_OBJECT_EX,
2073 offsetof(PyObj_pjsua_acc_config, cred_info), 0,
2074 "Array of credentials. If registration is desired, normally there "
2075 "should be at least one credential specified, to successfully "
2076 "authenticate against the service provider. More credentials can "
2077 "be specified, for example when the requests are expected to be "
2078 "challenged by the proxies in the route set."
2079 },
2080 {
2081 "transport_id", T_INT,
2082 offsetof(PyObj_pjsua_acc_config, transport_id), 0,
2083 "Optionally bind this account to specific transport. This normally is"
2084 " not a good idea, as account should be able to send requests using"
2085 " any available transports according to the destination. But some"
2086 " application may want to have explicit control over the transport to"
2087 " use, so in that case it can set this field."
2088 },
2089 {NULL} /* Sentinel */
2090};
2091
2092
2093
2094
2095/*
2096 * PyTyp_pjsua_acc_config
2097 */
2098static PyTypeObject PyTyp_pjsua_acc_config =
2099{
2100 PyObject_HEAD_INIT(NULL)
2101 0, /*ob_size*/
2102 "py_pjsua.Acc_Config", /*tp_name*/
2103 sizeof(PyObj_pjsua_acc_config), /*tp_basicsize*/
2104 0, /*tp_itemsize*/
2105 (destructor)PyObj_pjsua_acc_config_delete,/*tp_dealloc*/
2106 0, /*tp_print*/
2107 0, /*tp_getattr*/
2108 0, /*tp_setattr*/
2109 0, /*tp_compare*/
2110 0, /*tp_repr*/
2111 0, /*tp_as_number*/
2112 0, /*tp_as_sequence*/
2113 0, /*tp_as_mapping*/
2114 0, /*tp_hash */
2115 0, /*tp_call*/
2116 0, /*tp_str*/
2117 0, /*tp_getattro*/
2118 0, /*tp_setattro*/
2119 0, /*tp_as_buffer*/
2120 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2121 "Acc Config objects", /* tp_doc */
2122 0, /* tp_traverse */
2123 0, /* tp_clear */
2124 0, /* tp_richcompare */
2125 0, /* tp_weaklistoffset */
2126 0, /* tp_iter */
2127 0, /* tp_iternext */
2128 0/*acc_config_methods*/, /* tp_methods */
2129 PyObj_pjsua_acc_config_members, /* tp_members */
2130 0, /* tp_getset */
2131 0, /* tp_base */
2132 0, /* tp_dict */
2133 0, /* tp_descr_get */
2134 0, /* tp_descr_set */
2135 0, /* tp_dictoffset */
2136 0, /* tp_init */
2137 0, /* tp_alloc */
2138 PyObj_pjsua_acc_config_new, /* tp_new */
2139
2140};
2141
2142
2143//////////////////////////////////////////////////////////////////////////////
2144/*
2145 * PyObj_pjsua_acc_info
2146 * Acc Info
2147 */
2148typedef struct
2149{
2150 PyObject_HEAD
2151 /* Type-specific fields go here. */
2152 int id;
2153 int is_default;
2154 PyObject *acc_uri;
2155 int has_registration;
2156 int expires;
2157 int status;
2158 PyObject *status_text;
2159 int online_status;
2160 PyObject *online_status_text;
2161} PyObj_pjsua_acc_info;
2162
2163
2164/*
2165 * PyObj_pjsua_acc_info_delete
2166 * deletes a acc_info from memory
2167 */
2168static void PyObj_pjsua_acc_info_delete(PyObj_pjsua_acc_info* self)
2169{
2170 Py_XDECREF(self->acc_uri);
2171 Py_XDECREF(self->status_text);
2172 Py_XDECREF(self->online_status_text);
2173 self->ob_type->tp_free((PyObject*)self);
2174}
2175
2176
2177static void PyObj_pjsua_acc_info_import(PyObj_pjsua_acc_info *obj,
2178 const pjsua_acc_info *info)
2179{
2180 obj->id = info->id;
2181 obj->is_default = info->is_default;
2182 obj->acc_uri = PyString_FromStringAndSize(info->acc_uri.ptr,
2183 info->acc_uri.slen);
2184 obj->has_registration = info->has_registration;
2185 obj->expires = info->expires;
2186 obj->status = info->status;
2187 obj->status_text= PyString_FromStringAndSize(info->status_text.ptr,
2188 info->status_text.slen);
2189 obj->online_status = info->online_status;
2190 obj->online_status_text = PyString_FromStringAndSize(info->online_status_text.ptr,
2191 info->online_status_text.slen);
2192}
2193
2194
2195/*
2196 * PyObj_pjsua_acc_info_new
2197 * constructor for acc_info object
2198 */
2199static PyObject * PyObj_pjsua_acc_info_new(PyTypeObject *type,
2200 PyObject *args,
2201 PyObject *kwds)
2202{
2203 PyObj_pjsua_acc_info *self;
2204
2205 PJ_UNUSED_ARG(args);
2206 PJ_UNUSED_ARG(kwds);
2207
2208 self = (PyObj_pjsua_acc_info *)type->tp_alloc(type, 0);
2209 if (self != NULL) {
2210 self->acc_uri = PyString_FromString("");
2211 if (self->acc_uri == NULL) {
2212 Py_DECREF(self);
2213 return NULL;
2214 }
2215 self->status_text = PyString_FromString("");
2216 if (self->status_text == NULL) {
2217 Py_DECREF(self);
2218 return NULL;
2219 }
2220 self->online_status_text = PyString_FromString("");
2221 if (self->online_status_text == NULL) {
2222 Py_DECREF(self);
2223 return NULL;
2224 }
2225 }
2226
2227 return (PyObject *)self;
2228}
2229
2230/*
2231 * acc_info_members
2232 */
2233static PyMemberDef acc_info_members[] =
2234{
2235 {
2236 "id", T_INT,
2237 offsetof(PyObj_pjsua_acc_info, id), 0,
2238 "The account ID."
2239 },
2240 {
2241 "is_default", T_INT,
2242 offsetof(PyObj_pjsua_acc_info, is_default), 0,
2243 "Flag to indicate whether this is the default account. "
2244 },
2245 {
2246 "acc_uri", T_OBJECT_EX,
2247 offsetof(PyObj_pjsua_acc_info, acc_uri), 0,
2248 "Account URI"
2249 },
2250 {
2251 "has_registration", T_INT,
2252 offsetof(PyObj_pjsua_acc_info, has_registration), 0,
2253 "Flag to tell whether this account has registration setting "
2254 "(reg_uri is not empty)."
2255 },
2256 {
2257 "expires", T_INT,
2258 offsetof(PyObj_pjsua_acc_info, expires), 0,
2259 "An up to date expiration interval for account registration session."
2260 },
2261 {
2262 "status", T_INT,
2263 offsetof(PyObj_pjsua_acc_info, status), 0,
2264 "Last registration status code. If status code is zero, "
2265 "the account is currently not registered. Any other value indicates "
2266 "the SIP status code of the registration. "
2267 },
2268 {
2269 "status_text", T_OBJECT_EX,
2270 offsetof(PyObj_pjsua_acc_info, status_text), 0,
2271 "String describing the registration status."
2272 },
2273 {
2274 "online_status", T_INT,
2275 offsetof(PyObj_pjsua_acc_info, online_status), 0,
2276 "Presence online status for this account. "
2277 },
2278 {
2279 "online_status_text", T_OBJECT_EX,
2280 offsetof(PyObj_pjsua_acc_info, online_status_text), 0,
2281 "Presence online status text."
2282 },
2283 {NULL} /* Sentinel */
2284};
2285
2286
2287
2288
2289/*
2290 * PyTyp_pjsua_acc_info
2291 */
2292static PyTypeObject PyTyp_pjsua_acc_info =
2293{
2294 PyObject_HEAD_INIT(NULL)
2295 0, /*ob_size*/
2296 "py_pjsua.Acc_Info", /*tp_name*/
2297 sizeof(PyObj_pjsua_acc_info), /*tp_basicsize*/
2298 0, /*tp_itemsize*/
2299 (destructor)PyObj_pjsua_acc_info_delete,/*tp_dealloc*/
2300 0, /*tp_print*/
2301 0, /*tp_getattr*/
2302 0, /*tp_setattr*/
2303 0, /*tp_compare*/
2304 0, /*tp_repr*/
2305 0, /*tp_as_number*/
2306 0, /*tp_as_sequence*/
2307 0, /*tp_as_mapping*/
2308 0, /*tp_hash */
2309 0, /*tp_call*/
2310 0, /*tp_str*/
2311 0, /*tp_getattro*/
2312 0, /*tp_setattro*/
2313 0, /*tp_as_buffer*/
2314 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2315 "Acc Info objects", /* tp_doc */
2316 0, /* tp_traverse */
2317 0, /* tp_clear */
2318 0, /* tp_richcompare */
2319 0, /* tp_weaklistoffset */
2320 0, /* tp_iter */
2321 0, /* tp_iternext */
2322 NULL, /* tp_methods */
2323 acc_info_members, /* tp_members */
2324 0, /* tp_getset */
2325 0, /* tp_base */
2326 0, /* tp_dict */
2327 0, /* tp_descr_get */
2328 0, /* tp_descr_set */
2329 0, /* tp_dictoffset */
2330 0, /* tp_init */
2331 0, /* tp_alloc */
2332 PyObj_pjsua_acc_info_new, /* tp_new */
2333
2334};
2335
2336
2337//////////////////////////////////////////////////////////////////////////////
2338
2339/*
2340 * PyObj_pjsua_buddy_config
2341 * Buddy Config
2342 */
2343typedef struct
2344{
2345 PyObject_HEAD
2346 /* Type-specific fields go here. */
2347 PyObject *uri;
2348 int subscribe;
2349} PyObj_pjsua_buddy_config;
2350
2351
2352/*
2353 * PyObj_pjsua_buddy_config_delete
2354 * deletes a buddy_config from memory
2355 */
2356static void PyObj_pjsua_buddy_config_delete(PyObj_pjsua_buddy_config* self)
2357{
2358 Py_XDECREF(self->uri);
2359 self->ob_type->tp_free((PyObject*)self);
2360}
2361
2362
2363static void PyObj_pjsua_buddy_config_import(PyObj_pjsua_buddy_config *obj,
2364 const pjsua_buddy_config *cfg)
2365{
2366 Py_XDECREF(obj->uri);
2367 obj->uri = PyString_FromStringAndSize(cfg->uri.ptr, cfg->uri.slen);
2368 obj->subscribe = cfg->subscribe;
2369}
2370
2371
2372static void PyObj_pjsua_buddy_config_export(pjsua_buddy_config *cfg,
2373 PyObj_pjsua_buddy_config *obj)
2374{
2375 cfg->uri = PyString_to_pj_str(obj->uri);
2376 cfg->subscribe = obj->subscribe;
2377}
2378
2379
2380
2381/*
2382 * PyObj_pjsua_buddy_config_new
2383 * constructor for buddy_config object
2384 */
2385static PyObject *PyObj_pjsua_buddy_config_new(PyTypeObject *type,
2386 PyObject *args,
2387 PyObject *kwds)
2388{
2389 PyObj_pjsua_buddy_config *self;
2390
2391 PJ_UNUSED_ARG(args);
2392 PJ_UNUSED_ARG(kwds);
2393
2394 self = (PyObj_pjsua_buddy_config *)type->tp_alloc(type, 0);
2395 if (self != NULL) {
2396 self->uri = PyString_FromString("");
2397 if (self->uri == NULL) {
2398 Py_DECREF(self);
2399 return NULL;
2400 }
2401 }
2402 return (PyObject *)self;
2403}
2404
2405/*
2406 * PyObj_pjsua_buddy_config_members
2407 */
2408static PyMemberDef PyObj_pjsua_buddy_config_members[] =
2409{
2410
2411 {
2412 "uri", T_OBJECT_EX,
2413 offsetof(PyObj_pjsua_buddy_config, uri), 0,
2414 "TBuddy URL or name address."
2415 },
2416
2417 {
2418 "subscribe", T_INT,
2419 offsetof(PyObj_pjsua_buddy_config, subscribe), 0,
2420 "Specify whether presence subscription should start immediately. "
2421 },
2422
2423 {NULL} /* Sentinel */
2424};
2425
2426
2427
2428
2429/*
2430 * PyTyp_pjsua_buddy_config
2431 */
2432static PyTypeObject PyTyp_pjsua_buddy_config =
2433{
2434 PyObject_HEAD_INIT(NULL)
2435 0, /*ob_size*/
2436 "py_pjsua.Buddy_Config", /*tp_name*/
2437 sizeof(PyObj_pjsua_buddy_config),/*tp_basicsize*/
2438 0, /*tp_itemsize*/
2439 (destructor)PyObj_pjsua_buddy_config_delete,/*tp_dealloc*/
2440 0, /*tp_print*/
2441 0, /*tp_getattr*/
2442 0, /*tp_setattr*/
2443 0, /*tp_compare*/
2444 0, /*tp_repr*/
2445 0, /*tp_as_number*/
2446 0, /*tp_as_sequence*/
2447 0, /*tp_as_mapping*/
2448 0, /*tp_hash */
2449 0, /*tp_call*/
2450 0, /*tp_str*/
2451 0, /*tp_getattro*/
2452 0, /*tp_setattro*/
2453 0, /*tp_as_buffer*/
2454 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2455 "Buddy Config objects", /* tp_doc */
2456 0, /* tp_traverse */
2457 0, /* tp_clear */
2458 0, /* tp_richcompare */
2459 0, /* tp_weaklistoffset */
2460 0, /* tp_iter */
2461 0, /* tp_iternext */
2462 0, /* tp_methods */
2463 PyObj_pjsua_buddy_config_members, /* tp_members */
2464 0, /* tp_getset */
2465 0, /* tp_base */
2466 0, /* tp_dict */
2467 0, /* tp_descr_get */
2468 0, /* tp_descr_set */
2469 0, /* tp_dictoffset */
2470 0, /* tp_init */
2471 0, /* tp_alloc */
2472 PyObj_pjsua_buddy_config_new, /* tp_new */
2473
2474};
2475
2476//////////////////////////////////////////////////////////////////////////////
2477/*
2478 * PyObj_pjsua_buddy_info
2479 * Buddy Info
2480 */
2481typedef struct
2482{
2483 PyObject_HEAD
2484 /* Type-specific fields go here. */
2485 int id;
2486 PyObject *uri;
2487 PyObject *contact;
2488 int status;
2489 PyObject *status_text;
2490 int monitor_pres;
2491} PyObj_pjsua_buddy_info;
2492
2493
2494/*
2495 * PyObj_pjsua_buddy_info_delete
2496 * deletes a buddy_info from memory
2497 * !modified @ 071206
2498 */
2499static void PyObj_pjsua_buddy_info_delete(PyObj_pjsua_buddy_info* self)
2500{
2501 Py_XDECREF(self->uri);
2502 Py_XDECREF(self->contact);
2503 Py_XDECREF(self->status_text);
2504
2505 self->ob_type->tp_free((PyObject*)self);
2506}
2507
2508
2509static void PyObj_pjsua_buddy_info_import(PyObj_pjsua_buddy_info *obj,
2510 const pjsua_buddy_info *info)
2511{
2512 obj->id = info->id;
2513 Py_XDECREF(obj->uri);
2514 obj->uri = PyString_FromStringAndSize(info->uri.ptr, info->uri.slen);
2515 Py_XDECREF(obj->contact);
2516 obj->contact = PyString_FromStringAndSize(info->contact.ptr, info->contact.slen);
2517 obj->status = info->status;
2518 Py_XDECREF(obj->status_text);
2519 obj->status_text = PyString_FromStringAndSize(info->status_text.ptr,
2520 info->status_text.slen);
2521 obj->monitor_pres = info->monitor_pres;
2522}
2523
2524
2525/*
2526 * PyObj_pjsua_buddy_info_new
2527 * constructor for buddy_info object
2528 * !modified @ 071206
2529 */
2530static PyObject * PyObj_pjsua_buddy_info_new(PyTypeObject *type,
2531 PyObject *args,
2532 PyObject *kwds)
2533{
2534 PyObj_pjsua_buddy_info *self;
2535
2536 PJ_UNUSED_ARG(args);
2537 PJ_UNUSED_ARG(kwds);
2538
2539 self = (PyObj_pjsua_buddy_info *)type->tp_alloc(type, 0);
2540 if (self != NULL) {
2541 self->uri = PyString_FromString("");
2542 if (self->uri == NULL) {
2543 Py_DECREF(self);
2544 return NULL;
2545 }
2546 self->contact = PyString_FromString("");
2547 if (self->contact == NULL) {
2548 Py_DECREF(self);
2549 return NULL;
2550 }
2551 self->status_text = PyString_FromString("");
2552 if (self->status_text == NULL) {
2553 Py_DECREF(self);
2554 return NULL;
2555 }
2556
2557 }
2558 return (PyObject *)self;
2559}
2560
2561/*
2562 * PyObj_pjsua_buddy_info_members
2563 * !modified @ 071206
2564 */
2565static PyMemberDef PyObj_pjsua_buddy_info_members[] =
2566{
2567 {
2568 "id", T_INT,
2569 offsetof(PyObj_pjsua_buddy_info, id), 0,
2570 "The buddy ID."
2571 },
2572 {
2573 "uri", T_OBJECT_EX,
2574 offsetof(PyObj_pjsua_buddy_info, uri), 0,
2575 "The full URI of the buddy, as specified in the configuration. "
2576 },
2577 {
2578 "contact", T_OBJECT_EX,
2579 offsetof(PyObj_pjsua_buddy_info, contact), 0,
2580 "Buddy's Contact, only available when presence subscription "
2581 "has been established to the buddy."
2582 },
2583 {
2584 "status", T_INT,
2585 offsetof(PyObj_pjsua_buddy_info, status), 0,
2586 "Buddy's online status. "
2587 },
2588 {
2589 "status_text", T_OBJECT_EX,
2590 offsetof(PyObj_pjsua_buddy_info, status_text), 0,
2591 "Text to describe buddy's online status."
2592 },
2593 {
2594 "monitor_pres", T_INT,
2595 offsetof(PyObj_pjsua_buddy_info, monitor_pres), 0,
2596 "Flag to indicate that we should monitor the presence information "
2597 "for this buddy (normally yes, unless explicitly disabled). "
2598 },
2599
2600
2601 {NULL} /* Sentinel */
2602};
2603
2604
2605
2606
2607/*
2608 * PyTyp_pjsua_buddy_info
2609 */
2610static PyTypeObject PyTyp_pjsua_buddy_info =
2611{
2612 PyObject_HEAD_INIT(NULL)
2613 0, /*ob_size*/
2614 "py_pjsua.Buddy_Info", /*tp_name*/
2615 sizeof(PyObj_pjsua_buddy_info), /*tp_basicsize*/
2616 0, /*tp_itemsize*/
2617 (destructor)PyObj_pjsua_buddy_info_delete,/*tp_dealloc*/
2618 0, /*tp_print*/
2619 0, /*tp_getattr*/
2620 0, /*tp_setattr*/
2621 0, /*tp_compare*/
2622 0, /*tp_repr*/
2623 0, /*tp_as_number*/
2624 0, /*tp_as_sequence*/
2625 0, /*tp_as_mapping*/
2626 0, /*tp_hash */
2627 0, /*tp_call*/
2628 0, /*tp_str*/
2629 0, /*tp_getattro*/
2630 0, /*tp_setattro*/
2631 0, /*tp_as_buffer*/
2632 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2633 "Buddy Info objects", /* tp_doc */
2634 0, /* tp_traverse */
2635 0, /* tp_clear */
2636 0, /* tp_richcompare */
2637 0, /* tp_weaklistoffset */
2638 0, /* tp_iter */
2639 0, /* tp_iternext */
2640 0, /* tp_methods */
2641 PyObj_pjsua_buddy_info_members, /* tp_members */
2642 0, /* tp_getset */
2643 0, /* tp_base */
2644 0, /* tp_dict */
2645 0, /* tp_descr_get */
2646 0, /* tp_descr_set */
2647 0, /* tp_dictoffset */
2648 0, /* tp_init */
2649 0, /* tp_alloc */
2650 PyObj_pjsua_buddy_info_new, /* tp_new */
2651
2652};
2653
2654
2655
2656
2657
2658#endif /* __PY_PJSUA_H__ */
2659