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