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