blob: dffd3b86b7a3d0e7a028e11a5d94b244617dee33 [file] [log] [blame]
Alexandre Lision8af73cb2013-12-10 14:11:20 -05001/* $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#include "_pjsua.h"
21
22#define THIS_FILE "main.c"
23#define POOL_SIZE 512
24#define SND_DEV_NUM 64
25#define SND_NAME_LEN 64
26
27/* LIB BASE */
28
29static PyObject* g_obj_log_cb;
30static long g_thread_id;
31static struct py_thread_desc
32{
33 struct py_thread_desc *next;
34 pj_thread_desc desc;
35} *py_thread_desc;
36
37/*
38 * The global callback object.
39 */
40static PyObj_pjsua_callback * g_obj_callback;
41
42/* Set this to 1 if all threads are created by Python */
43#define NO_PJSIP_THREAD 1
44
45#if NO_PJSIP_THREAD
46# define ENTER_PYTHON()
47# define LEAVE_PYTHON()
48#else
49# define ENTER_PYTHON() PyGILState_STATE state = PyGILState_Ensure()
50# define LEAVE_PYTHON() PyGILState_Release(state)
51#endif
52
53
54static void clear_py_thread_desc(void)
55{
56 while (py_thread_desc) {
57 struct py_thread_desc *next = py_thread_desc->next;
58 free(py_thread_desc);
59 py_thread_desc = next;
60 }
61}
62
63
64/*
65 * cb_log_cb
66 * declares method for reconfiguring logging process for callback struct
67 */
68static void cb_log_cb(int level, const char *data, int len)
69{
70
71 /* Ignore if this callback is called from alien thread context,
72 * or otherwise it will crash Python.
73 */
74 if (pj_thread_local_get(g_thread_id) == 0)
75 return;
76
77 if (PyCallable_Check(g_obj_log_cb)) {
78 PyObject *param_data;
79
80 ENTER_PYTHON();
81
82 param_data = PyString_FromStringAndSize(data, len);
83
84 PyObject_CallFunction(
85 g_obj_log_cb,
86 "iOi",
87 level,
88 param_data,
89 len,
90 NULL
91 );
92
93 Py_DECREF(param_data);
94
95 LEAVE_PYTHON();
96 }
97}
98
99/*
100 * cb_on_call_state
101 * declares method on_call_state for callback struct
102 */
103static void cb_on_call_state(pjsua_call_id call_id, pjsip_event *e)
104{
105 PJ_UNUSED_ARG(e);
106
107 if (PyCallable_Check(g_obj_callback->on_call_state)) {
108 PyObject * obj;
109
110 ENTER_PYTHON();
111
112 obj = Py_BuildValue("");
113
114 PyObject_CallFunction(
115 g_obj_callback->on_call_state,
116 "iO",
117 call_id,
118 obj,
119 NULL
120 );
121
122 Py_DECREF(obj);
123
124 LEAVE_PYTHON();
125 }
126}
127
128
129/*
130 * cb_on_incoming_call
131 * declares method on_incoming_call for callback struct
132 */
133static void cb_on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
134 pjsip_rx_data *rdata)
135{
136 if (PyCallable_Check(g_obj_callback->on_incoming_call)) {
137 PyObj_pjsip_rx_data *obj;
138
139 ENTER_PYTHON();
140
141 obj = (PyObj_pjsip_rx_data*)
142 PyObj_pjsip_rx_data_new(&PyTyp_pjsip_rx_data,
143 NULL, NULL);
144 PyObj_pjsip_rx_data_import(obj, rdata);
145
146 PyObject_CallFunction(
147 g_obj_callback->on_incoming_call,
148 "iiO",
149 acc_id,
150 call_id,
151 obj,
152 NULL
153 );
154
155 Py_DECREF(obj);
156
157 LEAVE_PYTHON();
158 }
159}
160
161
162/*
163 * cb_on_call_media_state
164 * declares method on_call_media_state for callback struct
165 */
166static void cb_on_call_media_state(pjsua_call_id call_id)
167{
168 if (PyCallable_Check(g_obj_callback->on_call_media_state)) {
169
170 ENTER_PYTHON();
171
172 PyObject_CallFunction(
173 g_obj_callback->on_call_media_state,
174 "i",
175 call_id,
176 NULL
177 );
178
179 LEAVE_PYTHON();
180 }
181}
182
183
184/*
185 * cb_on_dtmf_digit()
186 * Callback from PJSUA-LIB on receiving DTMF digit
187 */
188static void cb_on_dtmf_digit(pjsua_call_id call_id, int digit)
189{
190 if (PyCallable_Check(g_obj_callback->on_dtmf_digit)) {
191 char digit_str[10];
192
193 PyGILState_STATE state = PyGILState_Ensure();
194
195 pj_ansi_snprintf(digit_str, sizeof(digit_str), "%c", digit);
196
197 PyObject_CallFunction(
198 g_obj_callback->on_dtmf_digit,
199 "is",
200 call_id,
201 digit_str,
202 NULL
203 );
204
205 PyGILState_Release(state);
206 }
207}
208
209
210/*
211 * Notify application on call being transfered.
212 * !modified @061206
213 */
214static void cb_on_call_transfer_request(pjsua_call_id call_id,
215 const pj_str_t *dst,
216 pjsip_status_code *code)
217{
218 if (PyCallable_Check(g_obj_callback->on_call_transfer_request)) {
219 PyObject *ret, *param_dst;
220 int cd;
221
222 ENTER_PYTHON();
223
224 param_dst = PyString_FromPJ(dst);
225
226 ret = PyObject_CallFunction(
227 g_obj_callback->on_call_transfer_request,
228 "iOi",
229 call_id,
230 param_dst,
231 *code,
232 NULL
233 );
234
235 Py_DECREF(param_dst);
236
237 if (ret != NULL) {
238 if (ret != Py_None) {
239 if (PyArg_Parse(ret,"i",&cd)) {
240 *code = cd;
241 }
242 }
243 Py_DECREF(ret);
244 }
245
246 LEAVE_PYTHON();
247 }
248}
249
250
251/*
252 * Notify application of the status of previously sent call
253 * transfer request. Application can monitor the status of the
254 * call transfer request, for example to decide whether to
255 * terminate existing call.
256 * !modified @061206
257 */
258static void cb_on_call_transfer_status( pjsua_call_id call_id,
259 int status_code,
260 const pj_str_t *status_text,
261 pj_bool_t final,
262 pj_bool_t *p_cont)
263{
264 if (PyCallable_Check(g_obj_callback->on_call_transfer_status)) {
265 PyObject *ret, *param_reason;
266
267 ENTER_PYTHON();
268
269 param_reason = PyString_FromPJ(status_text);
270
271 ret = PyObject_CallFunction(
272 g_obj_callback->on_call_transfer_status,
273 "iiOii",
274 call_id,
275 status_code,
276 param_reason,
277 final,
278 *p_cont,
279 NULL
280 );
281
282 Py_DECREF(param_reason);
283
284 if (ret != NULL) {
285 if (ret != Py_None) {
286 int cnt;
287 if (PyArg_Parse(ret,"i",&cnt)) {
288 *p_cont = cnt;
289 }
290 }
291 Py_DECREF(ret);
292 }
293
294 LEAVE_PYTHON();
295 }
296}
297
298
299/*
300 * Notify application about incoming INVITE with Replaces header.
301 * Application may reject the request by setting non-2xx code.
302 * !modified @061206
303 */
304static void cb_on_call_replace_request( pjsua_call_id call_id,
305 pjsip_rx_data *rdata,
306 int *st_code,
307 pj_str_t *st_text)
308{
309 PJ_UNUSED_ARG(rdata);
310
311 if (PyCallable_Check(g_obj_callback->on_call_replace_request)) {
312 PyObject *ret, *param_reason, *param_rdata;
313 int cd;
314
315 ENTER_PYTHON();
316
317 param_reason = PyString_FromPJ(st_text);
318 param_rdata = Py_BuildValue("");
319
320 ret = PyObject_CallFunction(
321 g_obj_callback->on_call_replace_request,
322 "iOiO",
323 call_id,
324 param_rdata,
325 *st_code,
326 param_reason,
327 NULL
328 );
329
330 Py_DECREF(param_rdata);
331 Py_DECREF(param_reason);
332
333 if (ret != NULL) {
334 if (ret != Py_None) {
335 PyObject * txt;
336 if (PyArg_ParseTuple(ret,"iO",&cd, &txt)) {
337 *st_code = cd;
338 *st_text = PyString_ToPJ(txt);
339 }
340 }
341 Py_DECREF(ret);
342 }
343
344 LEAVE_PYTHON();
345 }
346}
347
348
349/*
350 * Notify application that an existing call has been replaced with
351 * a new call. This happens when PJSUA-API receives incoming INVITE
352 * request with Replaces header.
353 */
354static void cb_on_call_replaced(pjsua_call_id old_call_id,
355 pjsua_call_id new_call_id)
356{
357 if (PyCallable_Check(g_obj_callback->on_call_replaced)) {
358 ENTER_PYTHON();
359
360 PyObject_CallFunction(
361 g_obj_callback->on_call_replaced,
362 "ii",
363 old_call_id,
364 new_call_id,
365 NULL
366 );
367
368 LEAVE_PYTHON();
369 }
370}
371
372
373/*
374 * cb_on_reg_state
375 * declares method on_reg_state for callback struct
376 */
377static void cb_on_reg_state(pjsua_acc_id acc_id)
378{
379 if (PyCallable_Check(g_obj_callback->on_reg_state)) {
380 ENTER_PYTHON();
381
382 PyObject_CallFunction(
383 g_obj_callback->on_reg_state,
384 "i",
385 acc_id,
386 NULL
387 );
388
389 LEAVE_PYTHON();
390 }
391}
392
393/*
394 * cb_on_incoming_subscribe
395 */
396static void cb_on_incoming_subscribe( pjsua_acc_id acc_id,
397 pjsua_srv_pres *srv_pres,
398 pjsua_buddy_id buddy_id,
399 const pj_str_t *from,
400 pjsip_rx_data *rdata,
401 pjsip_status_code *code,
402 pj_str_t *reason,
403 pjsua_msg_data *msg_data)
404{
405 static char reason_buf[64];
406
407 PJ_UNUSED_ARG(rdata);
408 PJ_UNUSED_ARG(msg_data);
409
410 if (PyCallable_Check(g_obj_callback->on_incoming_subscribe)) {
411 PyObject *ret, *param_from, *param_contact, *param_srv_pres;
412 pjsip_contact_hdr *contact_hdr;
413 pj_pool_t *pool = NULL;
414
415 ENTER_PYTHON();
416
417 param_from = PyString_FromPJ(from);
418 param_srv_pres = PyLong_FromLong((long)srv_pres);
419
420 contact_hdr = (pjsip_contact_hdr*)
421 pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
422 NULL);
423 if (contact_hdr) {
424 char *contact;
425 int len;
426
427 pool = pjsua_pool_create("pytmp", 512, 512);
428 contact = (char*) pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE+1);
429 len = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, contact_hdr->uri,
430 contact, PJSIP_MAX_URL_SIZE);
431 if (len < 1)
432 len = 0;
433 contact[len] = '\0';
434
435 param_contact = PyString_FromStringAndSize(contact, len);
436 } else {
437 param_contact = Py_BuildValue("");
438 }
439
440 ret = PyObject_CallFunction(
441 g_obj_callback->on_incoming_subscribe,
442 "iiOOO",
443 acc_id,
444 buddy_id,
445 param_from,
446 param_contact,
447 param_srv_pres,
448 NULL
449 );
450
451 if (pool)
452 pj_pool_release(pool);
453
454 Py_DECREF(param_from);
455 Py_DECREF(param_contact);
456 Py_DECREF(param_srv_pres);
457
458 if (ret && PyTuple_Check(ret)) {
459 if (PyTuple_Size(ret) >= 1)
460 *code = (int)PyInt_AsLong(PyTuple_GetItem(ret, 0));
461 if (PyTuple_Size(ret) >= 2) {
462 if (PyTuple_GetItem(ret, 1) != Py_None) {
463 pj_str_t tmp;
464 tmp = PyString_ToPJ(PyTuple_GetItem(ret, 1));
465 reason->ptr = reason_buf;
466 pj_strncpy(reason, &tmp, sizeof(reason_buf));
467 } else {
468 reason->slen = 0;
469 }
470 }
471 Py_XDECREF(ret);
472 } else if (ret) {
473 Py_XDECREF(ret);
474 }
475
476 LEAVE_PYTHON();
477 }
478}
479
480/*
481 * cb_on_buddy_state
482 * declares method on_buddy state for callback struct
483 */
484static void cb_on_buddy_state(pjsua_buddy_id buddy_id)
485{
486 if (PyCallable_Check(g_obj_callback->on_buddy_state)) {
487 ENTER_PYTHON();
488
489 PyObject_CallFunction(
490 g_obj_callback->on_buddy_state,
491 "i",
492 buddy_id,
493 NULL
494 );
495
496 LEAVE_PYTHON();
497 }
498}
499
500/*
501 * cb_on_pager
502 * declares method on_pager for callback struct
503 */
504static void cb_on_pager(pjsua_call_id call_id, const pj_str_t *from,
505 const pj_str_t *to, const pj_str_t *contact,
506 const pj_str_t *mime_type, const pj_str_t *body,
507 pjsip_rx_data *rdata, pjsua_acc_id acc_id)
508{
509 PJ_UNUSED_ARG(rdata);
510
511 if (PyCallable_Check(g_obj_callback->on_pager)) {
512 PyObject *param_from, *param_to, *param_contact, *param_mime_type,
513 *param_body;
514
515 ENTER_PYTHON();
516
517 param_from = PyString_FromPJ(from);
518 param_to = PyString_FromPJ(to);
519 param_contact = PyString_FromPJ(contact);
520 param_mime_type = PyString_FromPJ(mime_type);
521 param_body = PyString_FromPJ(body);
522
523 PyObject_CallFunction(
524 g_obj_callback->on_pager,
525 "iOOOOOi",
526 call_id,
527 param_from,
528 param_to,
529 param_contact,
530 param_mime_type,
531 param_body,
532 acc_id,
533 NULL
534 );
535
536 Py_DECREF(param_body);
537 Py_DECREF(param_mime_type);
538 Py_DECREF(param_contact);
539 Py_DECREF(param_to);
540 Py_DECREF(param_from);
541
542 LEAVE_PYTHON();
543 }
544}
545
546
547/*
548 * cb_on_pager_status
549 * declares method on_pager_status for callback struct
550 */
551static void cb_on_pager_status(pjsua_call_id call_id, const pj_str_t *to,
552 const pj_str_t *body, void *user_data,
553 pjsip_status_code status,
554 const pj_str_t *reason,
555 pjsip_tx_data *tdata,
556 pjsip_rx_data *rdata,
557 pjsua_acc_id acc_id)
558{
559 if (PyCallable_Check(g_obj_callback->on_pager)) {
560 PyObject *param_call_id, *param_to, *param_body,
561 *param_user_data, *param_status, *param_reason,
562 *param_acc_id;
563
564 ENTER_PYTHON();
565
566 PJ_UNUSED_ARG(tdata);
567 PJ_UNUSED_ARG(rdata);
568
569 PyObject_CallFunctionObjArgs(
570 g_obj_callback->on_pager_status,
571 param_call_id = Py_BuildValue("i",call_id),
572 param_to = PyString_FromPJ(to),
573 param_body = PyString_FromPJ(body),
574 param_user_data = Py_BuildValue("i", user_data),
575 param_status = Py_BuildValue("i",status),
576 param_reason = PyString_FromPJ(reason),
577 param_acc_id = Py_BuildValue("i",acc_id),
578 NULL
579 );
580
581 Py_DECREF(param_call_id);
582 Py_DECREF(param_to);
583 Py_DECREF(param_body);
584 Py_DECREF(param_user_data);
585 Py_DECREF(param_status);
586 Py_DECREF(param_reason);
587 Py_DECREF(param_acc_id);
588
589 LEAVE_PYTHON();
590 }
591}
592
593
594/*
595 * cb_on_typing
596 * declares method on_typing for callback struct
597 */
598static void cb_on_typing(pjsua_call_id call_id, const pj_str_t *from,
599 const pj_str_t *to, const pj_str_t *contact,
600 pj_bool_t is_typing, pjsip_rx_data *rdata,
601 pjsua_acc_id acc_id)
602{
603 if (PyCallable_Check(g_obj_callback->on_typing)) {
604 PyObject *param_call_id, *param_from, *param_to, *param_contact,
605 *param_is_typing, *param_acc_id;
606
607 ENTER_PYTHON();
608
609 PJ_UNUSED_ARG(rdata);
610
611 PyObject_CallFunctionObjArgs(
612 g_obj_callback->on_typing,
613 param_call_id = Py_BuildValue("i",call_id),
614 param_from = PyString_FromPJ(from),
615 param_to = PyString_FromPJ(to),
616 param_contact = PyString_FromPJ(contact),
617 param_is_typing = Py_BuildValue("i",is_typing),
618 param_acc_id = Py_BuildValue("i",acc_id),
619 NULL
620 );
621
622 Py_DECREF(param_call_id);
623 Py_DECREF(param_from);
624 Py_DECREF(param_to);
625 Py_DECREF(param_contact);
626 Py_DECREF(param_is_typing);
627 Py_DECREF(param_acc_id);
628
629 LEAVE_PYTHON();
630 }
631}
632
633
634/*
635 * on_mwi_info
636 */
637static void cb_on_mwi_info(pjsua_acc_id acc_id, pjsua_mwi_info *mwi_info)
638{
639 if (PyCallable_Check(g_obj_callback->on_mwi_info)) {
640 PyObject *param_acc_id, *param_body;
641 pj_str_t body;
642
643 ENTER_PYTHON();
644
645 body.ptr = mwi_info->rdata->msg_info.msg->body->data;
646 body.slen = mwi_info->rdata->msg_info.msg->body->len;
647
648 PyObject_CallFunctionObjArgs(
649 g_obj_callback->on_mwi_info,
650 param_acc_id = Py_BuildValue("i",acc_id),
651 param_body = PyString_FromPJ(&body),
652 NULL
653 );
654
655 Py_DECREF(param_acc_id);
656 Py_DECREF(param_body);
657
658 LEAVE_PYTHON();
659 }
660}
661
662/*
663 * translate_hdr
664 * internal function
665 * translate from hdr_list to pjsip_generic_string_hdr
666 */
667void translate_hdr(pj_pool_t *pool, pjsip_hdr *hdr, PyObject *py_hdr_list)
668{
669 pj_list_init(hdr);
670
671 if (PyList_Check(py_hdr_list)) {
672 int i;
673
674 for (i=0; i<PyList_Size(py_hdr_list); ++i) {
675 pj_str_t hname, hvalue;
676 pjsip_generic_string_hdr * new_hdr;
677 PyObject * tuple = PyList_GetItem(py_hdr_list, i);
678
679 if (PyTuple_Check(tuple)) {
680 if (PyTuple_Size(tuple) >= 1)
681 hname = PyString_ToPJ(PyTuple_GetItem(tuple,0));
682 else
683 hname.slen = 0;
684 if (PyTuple_Size(tuple) >= 2)
685 hvalue = PyString_ToPJ(PyTuple_GetItem(tuple,1));
686 else
687 hvalue.slen = 0;
688 } else {
689 hname.ptr = "";
690 hname.slen = 0;
691 hvalue.ptr = "";
692 hvalue.slen = 0;
693 }
694 new_hdr = pjsip_generic_string_hdr_create(pool, &hname, &hvalue);
695 pj_list_push_back((pj_list_type *)hdr, (pj_list_type *)new_hdr);
696 }
697 }
698}
699
700/*
701 * py_pjsua_thread_register
702 */
703static PyObject *py_pjsua_thread_register(PyObject *pSelf, PyObject *pArgs)
704{
705 pj_status_t status;
706 const char *name;
707 PyObject *py_desc;
708 pj_thread_t *thread;
709 struct py_thread_desc *thread_desc;
710
711 PJ_UNUSED_ARG(pSelf);
712
713 if (!PyArg_ParseTuple(pArgs, "sO", &name, &py_desc)) {
714 return NULL;
715 }
716 thread_desc = (struct py_thread_desc*)
717 malloc(sizeof(struct py_thread_desc));
718 thread_desc->next = py_thread_desc;
719 py_thread_desc = thread_desc;
720
721 status = pj_thread_register(name, thread_desc->desc, &thread);
722
723 if (status == PJ_SUCCESS)
724 status = pj_thread_local_set(g_thread_id, (void*)1);
725
726 return Py_BuildValue("i",status);
727}
728
729/*
730 * py_pjsua_logging_config_default
731 */
732static PyObject *py_pjsua_logging_config_default(PyObject *pSelf,
733 PyObject *pArgs)
734{
735 PyObj_pjsua_logging_config *obj;
736 pjsua_logging_config cfg;
737
738 PJ_UNUSED_ARG(pSelf);
739 PJ_UNUSED_ARG(pArgs);
740
741 pjsua_logging_config_default(&cfg);
742 obj = (PyObj_pjsua_logging_config*)
743 PyObj_pjsua_logging_config_new(&PyTyp_pjsua_logging_config,
744 NULL, NULL);
745 PyObj_pjsua_logging_config_import(obj, &cfg);
746
747 return (PyObject*)obj;
748}
749
750
751/*
752 * py_pjsua_config_default
753 */
754static PyObject *py_pjsua_config_default(PyObject *pSelf, PyObject *pArgs)
755{
756 PyObj_pjsua_config *obj;
757 pjsua_config cfg;
758
759 PJ_UNUSED_ARG(pSelf);
760 PJ_UNUSED_ARG(pArgs);
761
762 pjsua_config_default(&cfg);
763 obj = (PyObj_pjsua_config *) PyObj_pjsua_config_new(&PyTyp_pjsua_config,
764 NULL, NULL);
765 PyObj_pjsua_config_import(obj, &cfg);
766
767 return (PyObject*)obj;
768}
769
770
771/*
772 * py_pjsua_media_config_default
773 */
774static PyObject * py_pjsua_media_config_default(PyObject *pSelf,
775 PyObject *pArgs)
776{
777 PyObj_pjsua_media_config *obj;
778 pjsua_media_config cfg;
779
780 PJ_UNUSED_ARG(pSelf);
781 PJ_UNUSED_ARG(pArgs);
782
783 pjsua_media_config_default(&cfg);
784 obj = (PyObj_pjsua_media_config *)
785 PyType_GenericNew(&PyTyp_pjsua_media_config, NULL, NULL);
786 PyObj_pjsua_media_config_import(obj, &cfg);
787
788 return (PyObject *)obj;
789}
790
791
792/*
793 * py_pjsua_msg_data_init
794 */
795static PyObject *py_pjsua_msg_data_init(PyObject *pSelf, PyObject *pArgs)
796{
797 PJ_UNUSED_ARG(pSelf);
798 PJ_UNUSED_ARG(pArgs);
799
800 return (PyObject *)PyObj_pjsua_msg_data_new(&PyTyp_pjsua_msg_data,
801 NULL, NULL);
802}
803
804
805/*
806 * py_pjsua_reconfigure_logging
807 */
808static PyObject *py_pjsua_reconfigure_logging(PyObject *pSelf,
809 PyObject *pArgs)
810{
811 PyObject *logObj;
812 pj_status_t status;
813
814 PJ_UNUSED_ARG(pSelf);
815
816 if (!PyArg_ParseTuple(pArgs, "O", &logObj)) {
817 return NULL;
818 }
819
820 if (logObj != Py_None) {
821 PyObj_pjsua_logging_config *log;
822 pjsua_logging_config cfg;
823
824 log = (PyObj_pjsua_logging_config*)logObj;
825 cfg.msg_logging = log->msg_logging;
826 cfg.level = log->level;
827 cfg.console_level = log->console_level;
828 cfg.decor = log->decor;
829 cfg.log_filename = PyString_ToPJ(log->log_filename);
830 Py_XDECREF(g_obj_log_cb);
831 g_obj_log_cb = log->cb;
832 Py_INCREF(g_obj_log_cb);
833 cfg.cb = &cb_log_cb;
834 status = pjsua_reconfigure_logging(&cfg);
835 } else {
836 status = pjsua_reconfigure_logging(NULL);
837 }
838
839 return Py_BuildValue("i",status);
840}
841
842
843/*
844 * py_pjsua_perror
845 */
846static PyObject *py_pjsua_perror(PyObject *pSelf, PyObject *pArgs)
847{
848 const char *sender;
849 const char *title;
850 pj_status_t status;
851
852 PJ_UNUSED_ARG(pSelf);
853
854 if (!PyArg_ParseTuple(pArgs, "ssi", &sender, &title, &status)) {
855 return NULL;
856 }
857
858 pjsua_perror(sender, title, status);
859
860 return Py_BuildValue("");
861}
862
863
864/*
865 * py_pjsua_create
866 */
867static PyObject *py_pjsua_create(PyObject *pSelf, PyObject *pArgs)
868{
869 pj_status_t status;
870
871 PJ_UNUSED_ARG(pSelf);
872 PJ_UNUSED_ARG(pArgs);
873
874 status = pjsua_create();
875
876 if (status == PJ_SUCCESS) {
877 status = pj_thread_local_alloc(&g_thread_id);
878 if (status == PJ_SUCCESS)
879 status = pj_thread_local_set(g_thread_id, (void*)1);
880
881 pj_atexit(&clear_py_thread_desc);
882 }
883
884 return Py_BuildValue("i",status);
885}
886
887
888/*
889 * py_pjsua_init
890 */
891static PyObject *py_pjsua_init(PyObject *pSelf, PyObject *pArgs)
892{
893 pj_status_t status;
894 PyObject *o_ua_cfg, *o_log_cfg, *o_media_cfg;
895 pjsua_config cfg_ua, *p_cfg_ua;
896 pjsua_logging_config cfg_log, *p_cfg_log;
897 pjsua_media_config cfg_media, *p_cfg_media;
898
899 PJ_UNUSED_ARG(pSelf);
900
901 if (!PyArg_ParseTuple(pArgs, "OOO", &o_ua_cfg, &o_log_cfg, &o_media_cfg)) {
902 return NULL;
903 }
904
905 pjsua_config_default(&cfg_ua);
906 pjsua_logging_config_default(&cfg_log);
907 pjsua_media_config_default(&cfg_media);
908
909 if (o_ua_cfg != Py_None) {
910 PyObj_pjsua_config *obj_ua_cfg = (PyObj_pjsua_config*)o_ua_cfg;
911
912 PyObj_pjsua_config_export(&cfg_ua, obj_ua_cfg);
913
914 Py_XDECREF(g_obj_callback);
915 g_obj_callback = obj_ua_cfg->cb;
916 Py_INCREF(g_obj_callback);
917
918 cfg_ua.cb.on_call_state = &cb_on_call_state;
919 cfg_ua.cb.on_incoming_call = &cb_on_incoming_call;
920 cfg_ua.cb.on_call_media_state = &cb_on_call_media_state;
921 cfg_ua.cb.on_dtmf_digit = &cb_on_dtmf_digit;
922 cfg_ua.cb.on_call_transfer_request = &cb_on_call_transfer_request;
923 cfg_ua.cb.on_call_transfer_status = &cb_on_call_transfer_status;
924 cfg_ua.cb.on_call_replace_request = &cb_on_call_replace_request;
925 cfg_ua.cb.on_call_replaced = &cb_on_call_replaced;
926 cfg_ua.cb.on_reg_state = &cb_on_reg_state;
927 cfg_ua.cb.on_incoming_subscribe = &cb_on_incoming_subscribe;
928 cfg_ua.cb.on_buddy_state = &cb_on_buddy_state;
929 cfg_ua.cb.on_pager2 = &cb_on_pager;
930 cfg_ua.cb.on_pager_status2 = &cb_on_pager_status;
931 cfg_ua.cb.on_typing2 = &cb_on_typing;
932 cfg_ua.cb.on_mwi_info = &cb_on_mwi_info;
933
934 p_cfg_ua = &cfg_ua;
935
936 } else {
937 p_cfg_ua = NULL;
938 }
939
940 if (o_log_cfg != Py_None) {
941 PyObj_pjsua_logging_config * obj_log;
942
943 obj_log = (PyObj_pjsua_logging_config *)o_log_cfg;
944
945 PyObj_pjsua_logging_config_export(&cfg_log, obj_log);
946
947 Py_XDECREF(g_obj_log_cb);
948 g_obj_log_cb = obj_log->cb;
949 Py_INCREF(g_obj_log_cb);
950
951 cfg_log.cb = &cb_log_cb;
952 p_cfg_log = &cfg_log;
953
954 } else {
955 p_cfg_log = NULL;
956 }
957
958 if (o_media_cfg != Py_None) {
959 PyObj_pjsua_media_config_export(&cfg_media,
960 (PyObj_pjsua_media_config*)o_media_cfg);
961 p_cfg_media = &cfg_media;
962
963 } else {
964 p_cfg_media = NULL;
965 }
966
967 status = pjsua_init(p_cfg_ua, p_cfg_log, p_cfg_media);
968
969 return Py_BuildValue("i", status);
970}
971
972
973/*
974 * py_pjsua_start
975 */
976static PyObject *py_pjsua_start(PyObject *pSelf, PyObject *pArgs)
977{
978 pj_status_t status;
979
980 PJ_UNUSED_ARG(pSelf);
981 PJ_UNUSED_ARG(pArgs);
982
983 status = pjsua_start();
984
985 return Py_BuildValue("i", status);
986}
987
988
989/*
990 * py_pjsua_destroy
991 */
992static PyObject *py_pjsua_destroy(PyObject *pSelf, PyObject *pArgs)
993{
994 pj_status_t status;
995
996 PJ_UNUSED_ARG(pSelf);
997 PJ_UNUSED_ARG(pArgs);
998
999 status = pjsua_destroy();
1000
1001 return Py_BuildValue("i", status);
1002}
1003
1004
1005/*
1006 * py_pjsua_handle_events
1007 */
1008static PyObject *py_pjsua_handle_events(PyObject *pSelf, PyObject *pArgs)
1009{
1010 int ret;
1011 int msec;
1012
1013 PJ_UNUSED_ARG(pSelf);
1014
1015 if (!PyArg_ParseTuple(pArgs, "i", &msec)) {
1016 return NULL;
1017 }
1018
1019 if (msec < 0)
1020 msec = 0;
1021
1022#if !NO_PJSIP_THREAD
1023 /* Since handle_events() will block, we must wrap it with ALLOW_THREADS
1024 * construct, or otherwise many Python blocking functions (such as
1025 * time.sleep(), readline(), etc.) may hang/block indefinitely.
1026 * See http://www.python.org/doc/current/api/threads.html for more info.
1027 */
1028 Py_BEGIN_ALLOW_THREADS
1029#endif
1030
1031 ret = pjsua_handle_events(msec);
1032
1033#if !NO_PJSIP_THREAD
1034 Py_END_ALLOW_THREADS
1035#endif
1036
1037 return Py_BuildValue("i", ret);
1038}
1039
1040
1041/*
1042 * py_pjsua_verify_sip_url
1043 */
1044static PyObject *py_pjsua_verify_sip_url(PyObject *pSelf, PyObject *pArgs)
1045{
1046 pj_status_t status;
1047 const char *url;
1048
1049 PJ_UNUSED_ARG(pSelf);
1050
1051 if (!PyArg_ParseTuple(pArgs, "s", &url)) {
1052 return NULL;
1053 }
1054
1055 status = pjsua_verify_sip_url(url);
1056
1057 return Py_BuildValue("i", status);
1058}
1059
1060
1061/*
1062 * function doc
1063 */
1064
1065static char pjsua_thread_register_doc[] =
1066 "int _pjsua.thread_register(string name, int[] desc)";
1067static char pjsua_perror_doc[] =
1068 "void _pjsua.perror (string sender, string title, int status) "
1069 "Display error message for the specified error code. Parameters: "
1070 "sender: The log sender field; "
1071 "title: Message title for the error; "
1072 "status: Status code.";
1073
1074static char pjsua_create_doc[] =
1075 "int _pjsua.create (void) "
1076 "Instantiate pjsua application. Application "
1077 "must call this function before calling any other functions, to make sure "
1078 "that the underlying libraries are properly initialized. Once this "
1079 "function has returned success, application must call pjsua_destroy() "
1080 "before quitting.";
1081
1082static char pjsua_init_doc[] =
1083 "int _pjsua.init (_pjsua.Config obj_ua_cfg, "
1084 "_pjsua.Logging_Config log_cfg, _pjsua.Media_Config media_cfg) "
1085 "Initialize pjsua with the specified settings. All the settings are "
1086 "optional, and the default values will be used when the config is not "
1087 "specified. Parameters: "
1088 "obj_ua_cfg : User agent configuration; "
1089 "log_cfg : Optional logging configuration; "
1090 "media_cfg : Optional media configuration.";
1091
1092static char pjsua_start_doc[] =
1093 "int _pjsua.start (void) "
1094 "Application is recommended to call this function after all "
1095 "initialization is done, so that the library can do additional checking "
1096 "set up additional";
1097
1098static char pjsua_destroy_doc[] =
1099 "int _pjsua.destroy (void) "
1100 "Destroy pjsua This function must be called once PJSUA is created. To "
1101 "make it easier for application, application may call this function "
1102 "several times with no danger.";
1103
1104static char pjsua_handle_events_doc[] =
1105 "int _pjsua.handle_events (int msec_timeout) "
1106 "Poll pjsua for events, and if necessary block the caller thread for the "
1107 "specified maximum interval (in miliseconds) Parameters: "
1108 "msec_timeout: Maximum time to wait, in miliseconds. "
1109 "Returns: The number of events that have been handled during the poll. "
1110 "Negative value indicates error, and application can retrieve the error "
1111 "as (err = -return_value).";
1112
1113static char pjsua_verify_sip_url_doc[] =
1114 "int _pjsua.verify_sip_url (string c_url) "
1115 "Verify that valid SIP url is given Parameters: "
1116 "c_url: The URL, as NULL terminated string.";
1117
1118static char pjsua_reconfigure_logging_doc[] =
1119 "int _pjsua.reconfigure_logging (_pjsua.Logging_Config c) "
1120 "Application can call this function at any time (after pjsua_create(), of "
1121 "course) to change logging settings. Parameters: "
1122 "c: Logging configuration.";
1123
1124static char pjsua_logging_config_default_doc[] =
1125 "_pjsua.Logging_Config _pjsua.logging_config_default () "
1126 "Use this function to initialize logging config.";
1127
1128static char pjsua_config_default_doc[] =
1129 "_pjsua.Config _pjsua.config_default (). Use this function to "
1130 "initialize pjsua config. ";
1131
1132static char pjsua_media_config_default_doc[] =
1133 "_pjsua.Media_Config _pjsua.media_config_default (). "
1134 "Use this function to initialize media config.";
1135
1136static char pjsua_msg_data_init_doc[] =
1137 "_pjsua.Msg_Data void _pjsua.msg_data_init () "
1138 "Initialize message data ";
1139
1140
1141/* END OF LIB BASE */
1142
1143/* LIB TRANSPORT */
1144
1145/*
1146 * py_pjsua_transport_config_default
1147 */
1148static PyObject *py_pjsua_transport_config_default(PyObject *pSelf,
1149 PyObject *pArgs)
1150{
1151 PyObj_pjsua_transport_config *obj;
1152 pjsua_transport_config cfg;
1153
1154 PJ_UNUSED_ARG(pSelf);
1155 PJ_UNUSED_ARG(pArgs);
1156
1157 pjsua_transport_config_default(&cfg);
1158 obj = (PyObj_pjsua_transport_config*)
1159 PyObj_pjsua_transport_config_new(&PyTyp_pjsua_transport_config,
1160 NULL, NULL);
1161 PyObj_pjsua_transport_config_import(obj, &cfg);
1162
1163 return (PyObject *)obj;
1164}
1165
1166/*
1167 * py_pjsua_transport_create
1168 */
1169static PyObject *py_pjsua_transport_create(PyObject *pSelf, PyObject *pArgs)
1170{
1171 pj_status_t status;
1172 int type;
1173 PyObject *pCfg;
1174 pjsua_transport_config cfg;
1175 pjsua_transport_id id;
1176
1177 PJ_UNUSED_ARG(pSelf);
1178
1179 if (!PyArg_ParseTuple(pArgs, "iO", &type, &pCfg)) {
1180 return NULL;
1181 }
1182
1183 if (pCfg != Py_None) {
1184 PyObj_pjsua_transport_config *obj;
1185
1186 obj = (PyObj_pjsua_transport_config*)pCfg;
1187 PyObj_pjsua_transport_config_export(&cfg, obj);
1188 status = pjsua_transport_create(type, &cfg, &id);
1189 } else {
1190 status = pjsua_transport_create(type, NULL, &id);
1191 }
1192
1193
1194 return Py_BuildValue("ii", status, id);
1195}
1196
1197/*
1198 * py_pjsua_enum_transports
1199 */
1200static PyObject *py_pjsua_enum_transports(PyObject *pSelf, PyObject *pArgs)
1201{
1202 pj_status_t status;
1203 PyObject *list;
1204 pjsua_transport_id id[PJSIP_MAX_TRANSPORTS];
1205 unsigned c, i;
1206
1207 PJ_UNUSED_ARG(pSelf);
1208 PJ_UNUSED_ARG(pArgs);
1209
1210 c = PJ_ARRAY_SIZE(id);
1211 status = pjsua_enum_transports(id, &c);
1212
1213 list = PyList_New(c);
1214 for (i = 0; i < c; i++) {
1215 PyList_SetItem(list, i, Py_BuildValue("i", id[i]));
1216 }
1217
1218 return (PyObject*)list;
1219}
1220
1221/*
1222 * py_pjsua_transport_get_info
1223 * !modified @ 051206
1224 */
1225static PyObject *py_pjsua_transport_get_info(PyObject *pSelf, PyObject *pArgs)
1226{
1227 pj_status_t status;
1228 int id;
1229 pjsua_transport_info info;
1230
1231 PJ_UNUSED_ARG(pSelf);
1232
1233 if (!PyArg_ParseTuple(pArgs, "i", &id)) {
1234 return NULL;
1235 }
1236
1237 status = pjsua_transport_get_info(id, &info);
1238 if (status == PJ_SUCCESS) {
1239 PyObj_pjsua_transport_info *obj;
1240 obj = (PyObj_pjsua_transport_info *)
1241 PyObj_pjsua_transport_info_new(&PyTyp_pjsua_transport_info,
1242 NULL, NULL);
1243 PyObj_pjsua_transport_info_import(obj, &info);
1244 return (PyObject*)obj;
1245 } else {
1246 return Py_BuildValue("");
1247 }
1248}
1249
1250/*
1251 * py_pjsua_transport_set_enable
1252 */
1253static PyObject *py_pjsua_transport_set_enable(PyObject *pSelf,
1254 PyObject *pArgs)
1255{
1256 pj_status_t status;
1257 int id;
1258 int enabled;
1259
1260 PJ_UNUSED_ARG(pSelf);
1261
1262 if (!PyArg_ParseTuple(pArgs, "ii", &id, &enabled)) {
1263 return NULL;
1264 }
1265 status = pjsua_transport_set_enable(id, enabled);
1266
1267 return Py_BuildValue("i", status);
1268}
1269
1270/*
1271 * py_pjsua_transport_close
1272 */
1273static PyObject *py_pjsua_transport_close(PyObject *pSelf, PyObject *pArgs)
1274{
1275 pj_status_t status;
1276 int id;
1277 int force;
1278
1279 PJ_UNUSED_ARG(pSelf);
1280
1281 if (!PyArg_ParseTuple(pArgs, "ii", &id, &force)) {
1282 return NULL;
1283 }
1284 status = pjsua_transport_close(id, force);
1285
1286 return Py_BuildValue("i", status);
1287}
1288
1289static char pjsua_transport_config_default_doc[] =
1290 "_pjsua.Transport_Config _pjsua.transport_config_default () "
1291 "Call this function to initialize UDP config with default values.";
1292static char pjsua_transport_create_doc[] =
1293 "int, int _pjsua.transport_create (int type, "
1294 "_pjsua.Transport_Config cfg) "
1295 "Create SIP transport.";
1296static char pjsua_enum_transports_doc[] =
1297 "int[] _pjsua.enum_transports () "
1298 "Enumerate all transports currently created in the system.";
1299static char pjsua_transport_get_info_doc[] =
1300 "void _pjsua.transport_get_info "
1301 "(_pjsua.Transport_ID id, _pjsua.Transport_Info info) "
1302 "Get information about transports.";
1303static char pjsua_transport_set_enable_doc[] =
1304 "void _pjsua.transport_set_enable "
1305 "(_pjsua.Transport_ID id, int enabled) "
1306 "Disable a transport or re-enable it. "
1307 "By default transport is always enabled after it is created. "
1308 "Disabling a transport does not necessarily close the socket, "
1309 "it will only discard incoming messages and prevent the transport "
1310 "from being used to send outgoing messages.";
1311static char pjsua_transport_close_doc[] =
1312 "void _pjsua.transport_close (_pjsua.Transport_ID id, int force) "
1313 "Close the transport. If transport is forcefully closed, "
1314 "it will be immediately closed, and any pending transactions "
1315 "that are using the transport may not terminate properly. "
1316 "Otherwise, the system will wait until all transactions are closed "
1317 "while preventing new users from using the transport, and will close "
1318 "the transport when it is safe to do so.";
1319
1320/* END OF LIB TRANSPORT */
1321
1322/* LIB ACCOUNT */
1323
1324
1325/*
1326 * py_pjsua_acc_config_default
1327 */
1328static PyObject *py_pjsua_acc_config_default(PyObject *pSelf, PyObject *pArgs)
1329{
1330 PyObj_pjsua_acc_config *obj;
1331 pjsua_acc_config cfg;
1332
1333 PJ_UNUSED_ARG(pSelf);
1334 PJ_UNUSED_ARG(pArgs);
1335
1336 if (!PyArg_ParseTuple(pArgs, "")) {
1337 return NULL;
1338 }
1339
1340 pjsua_acc_config_default(&cfg);
1341 obj = (PyObj_pjsua_acc_config *)
1342 PyObj_pjsua_acc_config_new(&PyTyp_pjsua_acc_config,
1343 NULL, NULL);
1344 PyObj_pjsua_acc_config_import(obj, &cfg);
1345 return (PyObject *)obj;
1346}
1347
1348/*
1349 * py_pjsua_acc_get_count
1350 */
1351static PyObject *py_pjsua_acc_get_count(PyObject *pSelf, PyObject *pArgs)
1352{
1353 int count;
1354
1355 PJ_UNUSED_ARG(pSelf);
1356 PJ_UNUSED_ARG(pArgs);
1357
1358 count = pjsua_acc_get_count();
1359 return Py_BuildValue("i", count);
1360}
1361
1362/*
1363 * py_pjsua_acc_is_valid
1364 */
1365static PyObject *py_pjsua_acc_is_valid(PyObject *pSelf, PyObject *pArgs)
1366{
1367 int id;
1368 int is_valid;
1369
1370 PJ_UNUSED_ARG(pSelf);
1371
1372 if (!PyArg_ParseTuple(pArgs, "i", &id)) {
1373 return NULL;
1374 }
1375
1376 is_valid = pjsua_acc_is_valid(id);
1377 return Py_BuildValue("i", is_valid);
1378}
1379
1380/*
1381 * py_pjsua_acc_set_default
1382 */
1383static PyObject *py_pjsua_acc_set_default(PyObject *pSelf, PyObject *pArgs)
1384{
1385 int id;
1386 int status;
1387
1388 PJ_UNUSED_ARG(pSelf);
1389
1390 if (!PyArg_ParseTuple(pArgs, "i", &id)) {
1391 return NULL;
1392 }
1393 status = pjsua_acc_set_default(id);
1394
1395 return Py_BuildValue("i", status);
1396}
1397
1398/*
1399 * py_pjsua_acc_get_default
1400 */
1401static PyObject *py_pjsua_acc_get_default(PyObject *pSelf, PyObject *pArgs)
1402{
1403 int id;
1404
1405 PJ_UNUSED_ARG(pSelf);
1406 PJ_UNUSED_ARG(pArgs);
1407
1408 id = pjsua_acc_get_default();
1409
1410 return Py_BuildValue("i", id);
1411}
1412
1413/*
1414 * py_pjsua_acc_add
1415 */
1416static PyObject *py_pjsua_acc_add(PyObject *pSelf, PyObject *pArgs)
1417{
1418 int is_default;
1419 PyObject *pCfg;
1420 int acc_id;
1421 int status;
1422
1423 PJ_UNUSED_ARG(pSelf);
1424
1425 if (!PyArg_ParseTuple(pArgs, "Oi", &pCfg, &is_default)) {
1426 return NULL;
1427 }
1428
1429 if (pCfg != Py_None) {
1430 pjsua_acc_config cfg;
1431 PyObj_pjsua_acc_config *ac;
1432
1433 pjsua_acc_config_default(&cfg);
1434 ac = (PyObj_pjsua_acc_config *)pCfg;
1435 PyObj_pjsua_acc_config_export(&cfg, ac);
1436 status = pjsua_acc_add(&cfg, is_default, &acc_id);
1437 } else {
1438 status = PJ_EINVAL;
1439 acc_id = PJSUA_INVALID_ID;
1440 }
1441
1442 return Py_BuildValue("ii", status, acc_id);
1443}
1444
1445/*
1446 * py_pjsua_acc_add_local
1447 */
1448static PyObject *py_pjsua_acc_add_local(PyObject *pSelf, PyObject *pArgs)
1449{
1450 int is_default;
1451 int tid;
1452 int acc_id;
1453 int status;
1454
1455 PJ_UNUSED_ARG(pSelf);
1456
1457 if (!PyArg_ParseTuple(pArgs, "ii", &tid, &is_default)) {
1458 return NULL;
1459 }
1460
1461 status = pjsua_acc_add_local(tid, is_default, &acc_id);
1462
1463 return Py_BuildValue("ii", status, acc_id);
1464}
1465
1466/*
1467 * py_pjsua_acc_set_user_data
1468 */
1469static PyObject *py_pjsua_acc_set_user_data(PyObject *pSelf, PyObject *pArgs)
1470{
1471 int acc_id;
1472 PyObject *pUserData, *old_user_data;
1473 int status;
1474
1475 PJ_UNUSED_ARG(pSelf);
1476
1477 if (!PyArg_ParseTuple(pArgs, "iO", &acc_id, &pUserData)) {
1478 return NULL;
1479 }
1480
1481 old_user_data = (PyObject*) pjsua_acc_get_user_data(acc_id);
1482
1483 status = pjsua_acc_set_user_data(acc_id, (void*)pUserData);
1484
1485 if (status == PJ_SUCCESS) {
1486 Py_XINCREF(pUserData);
1487 Py_XDECREF(old_user_data);
1488 }
1489
1490 return Py_BuildValue("i", status);
1491}
1492
1493/*
1494 * py_pjsua_acc_get_user_data
1495 */
1496static PyObject *py_pjsua_acc_get_user_data(PyObject *pSelf, PyObject *pArgs)
1497{
1498 int acc_id;
1499 PyObject *user_data;
1500
1501 PJ_UNUSED_ARG(pSelf);
1502
1503 if (!PyArg_ParseTuple(pArgs, "i", &acc_id)) {
1504 return NULL;
1505 }
1506
1507 user_data = (PyObject*) pjsua_acc_get_user_data(acc_id);
1508
1509 return user_data ? Py_BuildValue("O", user_data) : Py_BuildValue("");
1510}
1511
1512/*
1513 * py_pjsua_acc_del
1514 */
1515static PyObject *py_pjsua_acc_del(PyObject *pSelf, PyObject *pArgs)
1516{
1517 int acc_id;
1518 PyObject *user_data;
1519 int status;
1520
1521 PJ_UNUSED_ARG(pSelf);
1522
1523 if (!PyArg_ParseTuple(pArgs, "i", &acc_id)) {
1524 return NULL;
1525 }
1526
1527 user_data = (PyObject*) pjsua_acc_get_user_data(acc_id);
1528 Py_XDECREF(user_data);
1529
1530 status = pjsua_acc_del(acc_id);
1531
1532 return Py_BuildValue("i", status);
1533}
1534
1535/*
1536 * py_pjsua_acc_modify
1537 */
1538static PyObject *py_pjsua_acc_modify(PyObject *pSelf, PyObject *pArgs)
1539{
1540 PyObject *pCfg;
1541 PyObj_pjsua_acc_config * ac;
1542 int acc_id;
1543 int status;
1544
1545 PJ_UNUSED_ARG(pSelf);
1546
1547 if (!PyArg_ParseTuple(pArgs, "iO", &acc_id, &pCfg)) {
1548 return NULL;
1549 }
1550
1551 if (pCfg != Py_None) {
1552 pjsua_acc_config cfg;
1553
1554 pjsua_acc_config_default(&cfg);
1555 ac = (PyObj_pjsua_acc_config*)pCfg;
1556 PyObj_pjsua_acc_config_export(&cfg, ac);
1557
1558 status = pjsua_acc_modify(acc_id, &cfg);
1559 } else {
1560 status = PJ_EINVAL;
1561 }
1562 return Py_BuildValue("i", status);
1563}
1564
1565/*
1566 * py_pjsua_acc_set_online_status
1567 */
1568static PyObject *py_pjsua_acc_set_online_status(PyObject *pSelf,
1569 PyObject *pArgs)
1570{
1571 int is_online;
1572 int acc_id;
1573 int status;
1574
1575 PJ_UNUSED_ARG(pSelf);
1576
1577 if (!PyArg_ParseTuple(pArgs, "ii", &acc_id, &is_online)) {
1578 return NULL;
1579 }
1580
1581 status = pjsua_acc_set_online_status(acc_id, is_online);
1582
1583 return Py_BuildValue("i", status);
1584}
1585
1586/*
1587 * py_pjsua_acc_set_online_status2
1588 */
1589static PyObject *py_pjsua_acc_set_online_status2(PyObject *pSelf,
1590 PyObject *pArgs)
1591{
1592 int is_online;
1593 int acc_id;
1594 int activity_id;
1595 const char *activity_text = NULL;
1596 const char *rpid_id = NULL;
1597 pjrpid_element rpid;
1598 pj_status_t status;
1599
1600 PJ_UNUSED_ARG(pSelf);
1601
1602 if (!PyArg_ParseTuple(pArgs, "iiiss", &acc_id, &is_online,
1603 &activity_id, &activity_text, &rpid_id))
1604 {
1605 return NULL;
1606 }
1607
1608 pj_bzero(&rpid, sizeof(rpid));
1609 rpid.type = PJRPID_ELEMENT_TYPE_PERSON;
1610 rpid.activity = activity_id;
1611 if (activity_text)
1612 rpid.note = pj_str((char*)activity_text);
1613
1614 if (rpid_id)
1615 rpid.id = pj_str((char*)rpid_id);
1616
1617 status = pjsua_acc_set_online_status2(acc_id, is_online, &rpid);
1618
1619 return Py_BuildValue("i", status);
1620}
1621
1622/*
1623 * py_pjsua_acc_set_registration
1624 */
1625static PyObject *py_pjsua_acc_set_registration(PyObject *pSelf,
1626 PyObject *pArgs)
1627{
1628 int renew;
1629 int acc_id;
1630 int status;
1631
1632 PJ_UNUSED_ARG(pSelf);
1633
1634 if (!PyArg_ParseTuple(pArgs, "ii", &acc_id, &renew)) {
1635 return NULL;
1636 }
1637
1638 status = pjsua_acc_set_registration(acc_id, renew);
1639
1640 return Py_BuildValue("i", status);
1641}
1642
1643/*
1644 * py_pjsua_acc_get_info
1645 */
1646static PyObject *py_pjsua_acc_get_info(PyObject *pSelf, PyObject *pArgs)
1647{
1648 int acc_id;
1649 PyObj_pjsua_acc_info * obj;
1650 pjsua_acc_info info;
1651 int status;
1652
1653 PJ_UNUSED_ARG(pSelf);
1654
1655 if (!PyArg_ParseTuple(pArgs, "i", &acc_id)) {
1656 return NULL;
1657 }
1658
1659 status = pjsua_acc_get_info(acc_id, &info);
1660 if (status == PJ_SUCCESS) {
1661 obj = (PyObj_pjsua_acc_info*)
1662 PyObj_pjsua_acc_info_new(&PyTyp_pjsua_acc_info, NULL, NULL);
1663 PyObj_pjsua_acc_info_import(obj, &info);
1664 return (PyObject*)obj;
1665 } else {
1666 return Py_BuildValue("");
1667 }
1668}
1669
1670/*
1671 * py_pjsua_enum_accs
1672 */
1673static PyObject *py_pjsua_enum_accs(PyObject *pSelf, PyObject *pArgs)
1674{
1675 pj_status_t status;
1676 PyObject *list;
1677 pjsua_acc_id id[PJSUA_MAX_ACC];
1678 unsigned c, i;
1679
1680 PJ_UNUSED_ARG(pSelf);
1681 PJ_UNUSED_ARG(pArgs);
1682
1683 c = PJ_ARRAY_SIZE(id);
1684 status = pjsua_enum_accs(id, &c);
1685 if (status != PJ_SUCCESS)
1686 c = 0;
1687
1688 list = PyList_New(c);
1689 for (i = 0; i < c; i++) {
1690 PyList_SetItem(list, i, Py_BuildValue("i", id[i]));
1691 }
1692
1693 return (PyObject*)list;
1694}
1695
1696/*
1697 * py_pjsua_acc_enum_info
1698 */
1699static PyObject *py_pjsua_acc_enum_info(PyObject *pSelf, PyObject *pArgs)
1700{
1701 pj_status_t status;
1702 PyObject *list;
1703 pjsua_acc_info info[PJSUA_MAX_ACC];
1704 unsigned c, i;
1705
1706 PJ_UNUSED_ARG(pSelf);
1707 PJ_UNUSED_ARG(pArgs);
1708
1709 if (!PyArg_ParseTuple(pArgs, "")) {
1710 return NULL;
1711 }
1712
1713 c = PJ_ARRAY_SIZE(info);
1714 status = pjsua_acc_enum_info(info, &c);
1715 if (status != PJ_SUCCESS)
1716 c = 0;
1717
1718 list = PyList_New(c);
1719 for (i = 0; i < c; i++) {
1720 PyObj_pjsua_acc_info *obj;
1721 obj = (PyObj_pjsua_acc_info *)
1722 PyObj_pjsua_acc_info_new(&PyTyp_pjsua_acc_info, NULL, NULL);
1723
1724 PyObj_pjsua_acc_info_import(obj, &info[i]);
1725
1726 PyList_SetItem(list, i, (PyObject*)obj);
1727 }
1728
1729 return (PyObject*)list;
1730}
1731
1732/*
1733 * py_pjsua_acc_set_transport
1734 */
1735static PyObject *py_pjsua_acc_set_transport(PyObject *pSelf, PyObject *pArgs)
1736{
1737 int acc_id, transport_id;
1738 int status;
1739
1740 PJ_UNUSED_ARG(pSelf);
1741
1742 if (!PyArg_ParseTuple(pArgs, "ii", &acc_id, &transport_id)) {
1743 return NULL;
1744 }
1745
1746 status = pjsua_acc_set_transport(acc_id, transport_id);
1747
1748
1749 return Py_BuildValue("i", status);
1750}
1751
1752
1753/*
1754 * py_pjsua_acc_pres_notify
1755 */
1756static PyObject *py_pjsua_acc_pres_notify(PyObject *pSelf,
1757 PyObject *pArgs)
1758{
1759 int acc_id, state;
1760 PyObject *arg_pres, *arg_msg_data, *arg_reason;
1761 void *srv_pres;
1762 pjsua_msg_data msg_data;
1763 pj_str_t reason;
1764 pj_bool_t with_body;
1765 pj_pool_t *pool = NULL;
1766 int status;
1767
1768 PJ_UNUSED_ARG(pSelf);
1769
1770 if (!PyArg_ParseTuple(pArgs, "iOiOO", &acc_id, &arg_pres,
1771 &state, &arg_reason, &arg_msg_data))
1772 {
1773 return NULL;
1774 }
1775
1776 srv_pres = (void*) PyLong_AsLong(arg_pres);
1777 with_body = (state != PJSIP_EVSUB_STATE_TERMINATED);
1778
1779 if (arg_reason && PyString_Check(arg_reason)) {
1780 reason = PyString_ToPJ(arg_reason);
1781 } else {
1782 reason = pj_str("");
1783 }
1784
1785 pjsua_msg_data_init(&msg_data);
1786 if (arg_msg_data && arg_msg_data != Py_None) {
1787 PyObj_pjsua_msg_data *omd = (PyObj_pjsua_msg_data *)arg_msg_data;
1788 msg_data.content_type = PyString_ToPJ(omd->content_type);
1789 msg_data.msg_body = PyString_ToPJ(omd->msg_body);
1790 pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
1791 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
1792 }
1793
1794 status = pjsua_pres_notify(acc_id, (pjsua_srv_pres*)srv_pres,
1795 (pjsip_evsub_state)state, NULL,
1796 &reason, with_body, &msg_data);
1797
1798 if (pool) {
1799 pj_pool_release(pool);
1800 }
1801
1802 return Py_BuildValue("i", status);
1803}
1804
1805static char pjsua_acc_config_default_doc[] =
1806 "_pjsua.Acc_Config _pjsua.acc_config_default () "
1807 "Call this function to initialize account config with default values.";
1808static char pjsua_acc_get_count_doc[] =
1809 "int _pjsua.acc_get_count () "
1810 "Get number of current accounts.";
1811static char pjsua_acc_is_valid_doc[] =
1812 "int _pjsua.acc_is_valid (int acc_id) "
1813 "Check if the specified account ID is valid.";
1814static char pjsua_acc_set_default_doc[] =
1815 "int _pjsua.acc_set_default (int acc_id) "
1816 "Set default account to be used when incoming "
1817 "and outgoing requests doesn't match any accounts.";
1818static char pjsua_acc_get_default_doc[] =
1819 "int _pjsua.acc_get_default () "
1820 "Get default account.";
1821static char pjsua_acc_add_doc[] =
1822 "int, int _pjsua.acc_add (_pjsua.Acc_Config cfg, "
1823 "int is_default) "
1824 "Add a new account to pjsua. PJSUA must have been initialized "
1825 "(with pjsua_init()) before calling this function.";
1826static char pjsua_acc_add_local_doc[] =
1827 "int,int _pjsua.acc_add_local (int tid, "
1828 "int is_default) "
1829 "Add a local account. A local account is used to identify "
1830 "local endpoint instead of a specific user, and for this reason, "
1831 "a transport ID is needed to obtain the local address information.";
1832static char pjsua_acc_del_doc[] =
1833 "int _pjsua.acc_del (int acc_id) "
1834 "Delete account.";
1835static char pjsua_acc_modify_doc[] =
1836 "int _pjsua.acc_modify (int acc_id, _pjsua.Acc_Config cfg) "
1837 "Modify account information.";
1838static char pjsua_acc_set_online_status_doc[] =
1839 "int _pjsua.acc_set_online_status2(int acc_id, int is_online) "
1840 "Modify account's presence status to be advertised "
1841 "to remote/presence subscribers.";
1842static char pjsua_acc_set_online_status2_doc[] =
1843 "int _pjsua.acc_set_online_status (int acc_id, int is_online, "
1844 "int activity_id, string activity_text) "
1845 "Modify account's presence status to be advertised "
1846 "to remote/presence subscribers.";
1847static char pjsua_acc_set_registration_doc[] =
1848 "int _pjsua.acc_set_registration (int acc_id, int renew) "
1849 "Update registration or perform unregistration.";
1850static char pjsua_acc_get_info_doc[] =
1851 "_pjsua.Acc_Info _pjsua.acc_get_info (int acc_id) "
1852 "Get account information.";
1853static char pjsua_enum_accs_doc[] =
1854 "int[] _pjsua.enum_accs () "
1855 "Enum accounts all account ids.";
1856static char pjsua_acc_enum_info_doc[] =
1857 "_pjsua.Acc_Info[] _pjsua.acc_enum_info () "
1858 "Enum accounts info.";
1859
1860/* END OF LIB ACCOUNT */
1861
1862/* LIB BUDDY */
1863
1864
1865
1866/*
1867 * py_pjsua_buddy_config_default
1868 */
1869static PyObject *py_pjsua_buddy_config_default(PyObject *pSelf,
1870 PyObject *pArgs)
1871{
1872 PyObj_pjsua_buddy_config *obj;
1873 pjsua_buddy_config cfg;
1874
1875 PJ_UNUSED_ARG(pSelf);
1876 PJ_UNUSED_ARG(pArgs);
1877
1878 pjsua_buddy_config_default(&cfg);
1879 obj = (PyObj_pjsua_buddy_config *)
1880 PyObj_pjsua_buddy_config_new(&PyTyp_pjsua_buddy_config, NULL, NULL);
1881 PyObj_pjsua_buddy_config_import(obj, &cfg);
1882
1883 return (PyObject *)obj;
1884}
1885
1886/*
1887 * py_pjsua_get_buddy_count
1888 */
1889static PyObject *py_pjsua_get_buddy_count(PyObject *pSelf, PyObject *pArgs)
1890{
1891 PJ_UNUSED_ARG(pSelf);
1892 PJ_UNUSED_ARG(pArgs);
1893
1894 return Py_BuildValue("i", pjsua_get_buddy_count());
1895}
1896
1897/*
1898 * py_pjsua_buddy_is_valid
1899 */
1900static PyObject *py_pjsua_buddy_is_valid(PyObject *pSelf, PyObject *pArgs)
1901{
1902 int id;
1903 int is_valid;
1904
1905 PJ_UNUSED_ARG(pSelf);
1906
1907 if (!PyArg_ParseTuple(pArgs, "i", &id)) {
1908 return NULL;
1909 }
1910 is_valid = pjsua_buddy_is_valid(id);
1911
1912 return Py_BuildValue("i", is_valid);
1913}
1914
1915/*
1916 * py_pjsua_enum_buddies
1917 */
1918static PyObject *py_pjsua_enum_buddies(PyObject *pSelf, PyObject *pArgs)
1919{
1920 pj_status_t status;
1921 PyObject *list;
1922 pjsua_buddy_id id[PJSUA_MAX_BUDDIES];
1923 unsigned c, i;
1924
1925 PJ_UNUSED_ARG(pSelf);
1926 PJ_UNUSED_ARG(pArgs);
1927
1928 c = PJ_ARRAY_SIZE(id);
1929 status = pjsua_enum_buddies(id, &c);
1930 if (status != PJ_SUCCESS)
1931 c = 0;
1932
1933 list = PyList_New(c);
1934 for (i = 0; i < c; i++) {
1935 PyList_SetItem(list, i, Py_BuildValue("i", id[i]));
1936 }
1937
1938 return (PyObject*)list;
1939}
1940
1941/*
1942 * py_pjsua_buddy_find
1943 */
1944static PyObject *py_pjsua_buddy_find(PyObject *pSelf, PyObject *pArgs)
1945{
1946 PyObject *pURI;
1947 pj_str_t uri;
1948 pjsua_buddy_id buddy_id;
1949
1950 PJ_UNUSED_ARG(pSelf);
1951
1952 if (!PyArg_ParseTuple(pArgs, "O", &pURI)) {
1953 return NULL;
1954 }
1955
1956 if (!PyString_Check(pURI))
1957 return Py_BuildValue("i", PJSUA_INVALID_ID);
1958
1959 uri = PyString_ToPJ(pURI);
1960 buddy_id = pjsua_buddy_find(&uri);
1961
1962 return Py_BuildValue("i", buddy_id);
1963}
1964
1965/*
1966 * py_pjsua_buddy_get_info
1967 */
1968static PyObject *py_pjsua_buddy_get_info(PyObject *pSelf, PyObject *pArgs)
1969{
1970 int buddy_id;
1971 pjsua_buddy_info info;
1972 int status;
1973
1974 PJ_UNUSED_ARG(pSelf);
1975
1976 if (!PyArg_ParseTuple(pArgs, "i", &buddy_id)) {
1977 return NULL;
1978 }
1979
1980 status = pjsua_buddy_get_info(buddy_id, &info);
1981 if (status == PJ_SUCCESS) {
1982 PyObj_pjsua_buddy_info *obj;
1983
1984 obj = (PyObj_pjsua_buddy_info *)
1985 PyObj_pjsua_buddy_config_new(&PyTyp_pjsua_buddy_info,
1986 NULL, NULL);
1987 PyObj_pjsua_buddy_info_import(obj, &info);
1988 return (PyObject*)obj;
1989 } else {
1990 return Py_BuildValue("");
1991 }
1992}
1993
1994/*
1995 * py_pjsua_buddy_add
1996 */
1997static PyObject *py_pjsua_buddy_add(PyObject *pSelf, PyObject *pArgs)
1998{
1999 PyObject *pCfg;
2000 int buddy_id;
2001 int status;
2002
2003 PJ_UNUSED_ARG(pSelf);
2004
2005 if (!PyArg_ParseTuple(pArgs, "O", &pCfg)) {
2006 return NULL;
2007 }
2008
2009 if (pCfg != Py_None) {
2010 pjsua_buddy_config cfg;
2011 PyObj_pjsua_buddy_config *bc;
2012
2013 bc = (PyObj_pjsua_buddy_config *)pCfg;
2014
2015 pjsua_buddy_config_default(&cfg);
2016 PyObj_pjsua_buddy_config_export(&cfg, bc);
2017
2018 status = pjsua_buddy_add(&cfg, &buddy_id);
2019
2020 } else {
2021 status = PJ_EINVAL;
2022 buddy_id = PJSUA_INVALID_ID;
2023 }
2024 return Py_BuildValue("ii", status, buddy_id);
2025}
2026
2027/*
2028 * py_pjsua_buddy_del
2029 */
2030static PyObject *py_pjsua_buddy_del(PyObject *pSelf, PyObject *pArgs)
2031{
2032 int buddy_id;
2033 int status;
2034 PyObject *user_data;
2035
2036 PJ_UNUSED_ARG(pSelf);
2037
2038 if (!PyArg_ParseTuple(pArgs, "i", &buddy_id)) {
2039 return NULL;
2040 }
2041
2042 user_data = (PyObject*) pjsua_buddy_get_user_data(buddy_id);
2043 Py_XDECREF(user_data);
2044
2045 status = pjsua_buddy_del(buddy_id);
2046
2047 return Py_BuildValue("i", status);
2048}
2049
2050/*
2051 * py_pjsua_buddy_set_user_data
2052 */
2053static PyObject *py_pjsua_buddy_set_user_data(PyObject *pSelf, PyObject *pArgs)
2054{
2055 int buddy_id;
2056 int status;
2057 PyObject *user_data, *old_user_data;
2058
2059 PJ_UNUSED_ARG(pSelf);
2060
2061 if (!PyArg_ParseTuple(pArgs, "iO", &buddy_id, &user_data)) {
2062 return NULL;
2063 }
2064
2065 if (!pjsua_buddy_is_valid(buddy_id)) {
2066 return Py_BuildValue("i", 0);
2067 }
2068
2069 old_user_data = (PyObject*) pjsua_buddy_get_user_data(buddy_id);
2070
2071 status = pjsua_buddy_set_user_data(buddy_id, (void*)user_data);
2072
2073 if (status == PJ_SUCCESS) {
2074 Py_XINCREF(user_data);
2075 Py_XDECREF(old_user_data);
2076 }
2077
2078 return Py_BuildValue("i", status);
2079}
2080
2081/*
2082 * py_pjsua_buddy_get_user_data
2083 */
2084static PyObject *py_pjsua_buddy_get_user_data(PyObject *pSelf, PyObject *pArgs)
2085{
2086 int buddy_id;
2087 PyObject *user_data;
2088
2089 PJ_UNUSED_ARG(pSelf);
2090
2091 if (!PyArg_ParseTuple(pArgs, "i", &buddy_id)) {
2092 return NULL;
2093 }
2094
2095 user_data = (PyObject*) pjsua_buddy_get_user_data(buddy_id);
2096
2097 return user_data? Py_BuildValue("O", user_data) : Py_BuildValue("");
2098}
2099
2100/*
2101 * py_pjsua_buddy_subscribe_pres
2102 */
2103static PyObject *py_pjsua_buddy_subscribe_pres(PyObject *pSelf,
2104 PyObject *pArgs)
2105{
2106 int buddy_id;
2107 int status;
2108 int subscribe;
2109
2110 PJ_UNUSED_ARG(pSelf);
2111
2112 if (!PyArg_ParseTuple(pArgs, "ii", &buddy_id, &subscribe)) {
2113 return NULL;
2114 }
2115
2116 status = pjsua_buddy_subscribe_pres(buddy_id, subscribe);
2117
2118 return Py_BuildValue("i", status);
2119}
2120
2121/*
2122 * py_pjsua_pres_dump
2123 */
2124static PyObject *py_pjsua_pres_dump(PyObject *pSelf, PyObject *pArgs)
2125{
2126 int verbose;
2127
2128 PJ_UNUSED_ARG(pSelf);
2129
2130 if (!PyArg_ParseTuple(pArgs, "i", &verbose)) {
2131 return NULL;
2132 }
2133
2134 pjsua_pres_dump(verbose);
2135
2136 return Py_BuildValue("");
2137}
2138
2139/*
2140 * py_pjsua_im_send
2141 */
2142static PyObject *py_pjsua_im_send(PyObject *pSelf, PyObject *pArgs)
2143{
2144 int status;
2145 int acc_id;
2146 pj_str_t *mime_type, tmp_mime_type;
2147 pj_str_t to, content;
2148 PyObject *pTo;
2149 PyObject *pMimeType;
2150 PyObject *pContent;
2151 pjsua_msg_data msg_data;
2152 PyObject *pMsgData;
2153 int user_data;
2154 pj_pool_t *pool = NULL;
2155
2156 PJ_UNUSED_ARG(pSelf);
2157
2158 if (!PyArg_ParseTuple(pArgs, "iOOOOi", &acc_id,
2159 &pTo, &pMimeType, &pContent, &pMsgData, &user_data))
2160 {
2161 return NULL;
2162 }
2163
2164 if (pMimeType != Py_None) {
2165 mime_type = &tmp_mime_type;
2166 tmp_mime_type = PyString_ToPJ(pMimeType);
2167 } else {
2168 mime_type = NULL;
2169 }
2170
2171 to = PyString_ToPJ(pTo);
2172 content = PyString_ToPJ(pContent);
2173
2174 pjsua_msg_data_init(&msg_data);
2175
2176 if (pMsgData != Py_None) {
2177 PyObj_pjsua_msg_data *omd;
2178
2179 omd = (PyObj_pjsua_msg_data *)pMsgData;
2180 msg_data.content_type = PyString_ToPJ(omd->content_type);
2181 msg_data.msg_body = PyString_ToPJ(omd->msg_body);
2182 pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
2183 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
2184 }
2185
2186 status = pjsua_im_send(acc_id, &to, mime_type, &content,
2187 &msg_data, (void*)(long)user_data);
2188 if (pool)
2189 pj_pool_release(pool);
2190
2191 return Py_BuildValue("i",status);
2192}
2193
2194/*
2195 * py_pjsua_im_typing
2196 */
2197static PyObject *py_pjsua_im_typing(PyObject *pSelf, PyObject *pArgs)
2198{
2199 int status;
2200 int acc_id;
2201 pj_str_t to;
2202 PyObject *pTo;
2203 int is_typing;
2204 pjsua_msg_data msg_data;
2205 PyObject *pMsgData;
2206 pj_pool_t *pool = NULL;
2207
2208 PJ_UNUSED_ARG(pSelf);
2209
2210 if (!PyArg_ParseTuple(pArgs, "iOiO", &acc_id, &pTo, &is_typing,
2211 &pMsgData))
2212 {
2213 return NULL;
2214 }
2215
2216 to = PyString_ToPJ(pTo);
2217
2218 pjsua_msg_data_init(&msg_data);
2219
2220 if (pMsgData != Py_None) {
2221 PyObj_pjsua_msg_data *omd;
2222
2223 omd = (PyObj_pjsua_msg_data *)pMsgData;
2224 msg_data.content_type = PyString_ToPJ(omd->content_type);
2225 msg_data.msg_body = PyString_ToPJ(omd->msg_body);
2226 pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
2227
2228 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
2229 }
2230
2231 status = pjsua_im_typing(acc_id, &to, is_typing, &msg_data);
2232
2233 if (pool)
2234 pj_pool_release(pool);
2235
2236 return Py_BuildValue("i", status);
2237}
2238
2239static char pjsua_buddy_config_default_doc[] =
2240 "_pjsua.Buddy_Config _pjsua.buddy_config_default () "
2241 "Set default values to the buddy config.";
2242static char pjsua_get_buddy_count_doc[] =
2243 "int _pjsua.get_buddy_count () "
2244 "Get total number of buddies.";
2245static char pjsua_buddy_is_valid_doc[] =
2246 "int _pjsua.buddy_is_valid (int buddy_id) "
2247 "Check if buddy ID is valid.";
2248static char pjsua_enum_buddies_doc[] =
2249 "int[] _pjsua.enum_buddies () "
2250 "Enum buddy IDs.";
2251static char pjsua_buddy_get_info_doc[] =
2252 "_pjsua.Buddy_Info _pjsua.buddy_get_info (int buddy_id) "
2253 "Get detailed buddy info.";
2254static char pjsua_buddy_add_doc[] =
2255 "int,int _pjsua.buddy_add (_pjsua.Buddy_Config cfg) "
2256 "Add new buddy.";
2257static char pjsua_buddy_del_doc[] =
2258 "int _pjsua.buddy_del (int buddy_id) "
2259 "Delete buddy.";
2260static char pjsua_buddy_subscribe_pres_doc[] =
2261 "int _pjsua.buddy_subscribe_pres (int buddy_id, int subscribe) "
2262 "Enable/disable buddy's presence monitoring.";
2263static char pjsua_pres_dump_doc[] =
2264 "void _pjsua.pres_dump (int verbose) "
2265 "Dump presence subscriptions to log file.";
2266static char pjsua_im_send_doc[] =
2267 "int _pjsua.im_send (int acc_id, string to, string mime_type, "
2268 "string content, _pjsua.Msg_Data msg_data, int user_data) "
2269 "Send instant messaging outside dialog, using the specified account "
2270 "for route set and authentication.";
2271static char pjsua_im_typing_doc[] =
2272 "int _pjsua.im_typing (int acc_id, string to, int is_typing, "
2273 "_pjsua.Msg_Data msg_data) "
2274 "Send typing indication outside dialog.";
2275
2276/* END OF LIB BUDDY */
2277
2278/* LIB MEDIA */
2279
2280
2281/*
2282 * py_pjsua_conf_get_max_ports
2283 */
2284static PyObject *py_pjsua_conf_get_max_ports(PyObject *pSelf, PyObject *pArgs)
2285{
2286 PJ_UNUSED_ARG(pSelf);
2287 PJ_UNUSED_ARG(pArgs);
2288
2289 return Py_BuildValue("i", pjsua_conf_get_max_ports());
2290}
2291
2292/*
2293 * py_pjsua_conf_get_active_ports
2294 */
2295static PyObject *py_pjsua_conf_get_active_ports(PyObject *pSelf,
2296 PyObject *pArgs)
2297{
2298 PJ_UNUSED_ARG(pSelf);
2299 PJ_UNUSED_ARG(pArgs);
2300
2301 return Py_BuildValue("i", pjsua_conf_get_active_ports());
2302}
2303
2304/*
2305 * py_pjsua_enum_conf_ports
2306 */
2307static PyObject *py_pjsua_enum_conf_ports(PyObject *pSelf, PyObject *pArgs)
2308{
2309 pj_status_t status;
2310 PyObject *list;
2311 pjsua_conf_port_id id[PJSUA_MAX_CONF_PORTS];
2312 unsigned c, i;
2313
2314 PJ_UNUSED_ARG(pSelf);
2315 PJ_UNUSED_ARG(pArgs);
2316
2317 c = PJ_ARRAY_SIZE(id);
2318 status = pjsua_enum_conf_ports(id, &c);
2319 if (status != PJ_SUCCESS)
2320 c = 0;
2321
2322 list = PyList_New(c);
2323 for (i = 0; i < c; i++) {
2324 PyList_SetItem(list, i, Py_BuildValue("i", id[i]));
2325 }
2326
2327 return (PyObject*)list;
2328}
2329
2330/*
2331 * py_pjsua_conf_get_port_info
2332 */
2333static PyObject *py_pjsua_conf_get_port_info(PyObject *pSelf, PyObject *pArgs)
2334{
2335 int id;
2336 PyObj_pjsua_conf_port_info *ret;
2337 pjsua_conf_port_info info;
2338 int status;
2339 unsigned i;
2340
2341 PJ_UNUSED_ARG(pSelf);
2342
2343 if (!PyArg_ParseTuple(pArgs, "i", &id)) {
2344 return NULL;
2345 }
2346
2347 status = pjsua_conf_get_port_info(id, &info);
2348 ret = (PyObj_pjsua_conf_port_info *)
2349 conf_port_info_new(&PyTyp_pjsua_conf_port_info, NULL, NULL);
2350 ret->bits_per_sample = info.bits_per_sample;
2351 ret->channel_count = info.channel_count;
2352 ret->clock_rate = info.clock_rate;
2353 ret->name = PyString_FromPJ(&info.name);
2354 ret->samples_per_frame = info.samples_per_frame;
2355 ret->slot_id = info.slot_id;
2356 Py_XDECREF(ret->listeners);
2357 ret->listeners = PyList_New(info.listener_cnt);
2358 for (i = 0; i < info.listener_cnt; i++) {
2359 PyObject *item = Py_BuildValue("i",info.listeners[i]);
2360 PyList_SetItem(ret->listeners, i, item);
2361 }
2362 return (PyObject*)ret;
2363}
2364
2365/*
2366 * py_pjsua_conf_remove_port
2367 */
2368static PyObject *py_pjsua_conf_remove_port(PyObject *pSelf, PyObject *pArgs)
2369{
2370 int id;
2371 int status;
2372
2373 PJ_UNUSED_ARG(pSelf);
2374
2375 if (!PyArg_ParseTuple(pArgs, "i", &id)) {
2376 return NULL;
2377 }
2378
2379 status = pjsua_conf_remove_port(id);
2380
2381 return Py_BuildValue("i", status);
2382}
2383
2384/*
2385 * py_pjsua_conf_connect
2386 */
2387static PyObject *py_pjsua_conf_connect(PyObject *pSelf, PyObject *pArgs)
2388{
2389 int source, sink;
2390 int status;
2391
2392 PJ_UNUSED_ARG(pSelf);
2393
2394 if (!PyArg_ParseTuple(pArgs, "ii", &source, &sink)) {
2395 return NULL;
2396 }
2397
2398 status = pjsua_conf_connect(source, sink);
2399
2400 return Py_BuildValue("i", status);
2401}
2402
2403/*
2404 * py_pjsua_conf_disconnect
2405 */
2406static PyObject *py_pjsua_conf_disconnect(PyObject *pSelf, PyObject *pArgs)
2407{
2408 int source, sink;
2409 int status;
2410
2411 PJ_UNUSED_ARG(pSelf);
2412
2413 if (!PyArg_ParseTuple(pArgs, "ii", &source, &sink)) {
2414 return NULL;
2415 }
2416
2417 status = pjsua_conf_disconnect(source, sink);
2418
2419 return Py_BuildValue("i", status);
2420}
2421
2422/*
2423 * py_pjsua_conf_set_tx_level
2424 */
2425static PyObject *py_pjsua_conf_set_tx_level(PyObject *pSelf, PyObject *pArgs)
2426{
2427 int slot;
2428 float level;
2429 int status;
2430
2431 PJ_UNUSED_ARG(pSelf);
2432
2433 if (!PyArg_ParseTuple(pArgs, "if", &slot, &level)) {
2434 return NULL;
2435 }
2436
2437 status = pjsua_conf_adjust_tx_level(slot, level);
2438
2439 return Py_BuildValue("i", status);
2440}
2441
2442/*
2443 * py_pjsua_conf_set_rx_level
2444 */
2445static PyObject *py_pjsua_conf_set_rx_level(PyObject *pSelf, PyObject *pArgs)
2446{
2447 int slot;
2448 float level;
2449 int status;
2450
2451 PJ_UNUSED_ARG(pSelf);
2452
2453 if (!PyArg_ParseTuple(pArgs, "if", &slot, &level)) {
2454 return NULL;
2455 }
2456
2457 status = pjsua_conf_adjust_rx_level(slot, level);
2458
2459 return Py_BuildValue("i", status);
2460}
2461
2462/*
2463 * py_pjsua_conf_get_signal_level
2464 */
2465static PyObject *py_pjsua_conf_get_signal_level(PyObject *pSelf,
2466 PyObject *pArgs)
2467{
2468 int slot;
2469 unsigned tx_level, rx_level;
2470 int status;
2471
2472 PJ_UNUSED_ARG(pSelf);
2473
2474 if (!PyArg_ParseTuple(pArgs, "i", &slot)) {
2475 return NULL;
2476 }
2477
2478 status = pjsua_conf_get_signal_level(slot, &tx_level, &rx_level);
2479
2480 return Py_BuildValue("iff", status, (float)(tx_level/255.0),
2481 (float)(rx_level/255.0));
2482}
2483
2484/*
2485 * py_pjsua_player_create
2486 */
2487static PyObject *py_pjsua_player_create(PyObject *pSelf, PyObject *pArgs)
2488{
2489 int id;
2490 int options;
2491 PyObject *pFilename;
2492 pj_str_t filename;
2493 int status;
2494
2495 PJ_UNUSED_ARG(pSelf);
2496
2497 if (!PyArg_ParseTuple(pArgs, "Oi", &pFilename, &options)) {
2498 return NULL;
2499 }
2500
2501 filename = PyString_ToPJ(pFilename);
2502 status = pjsua_player_create(&filename, options, &id);
2503
2504 return Py_BuildValue("ii", status, id);
2505}
2506
2507/*
2508 * py_pjsua_playlist_create
2509 */
2510static PyObject *py_pjsua_playlist_create(PyObject *pSelf, PyObject *pArgs)
2511{
2512 int id;
2513 int options;
2514 PyObject *pLabel, *pFileList;
2515 pj_str_t label;
2516 int count;
2517 pj_str_t files[64];
2518 int status;
2519
2520 PJ_UNUSED_ARG(pSelf);
2521
2522 if (!PyArg_ParseTuple(pArgs, "OOi", &pLabel, &pFileList, &options)) {
2523 return NULL;
2524 }
2525
2526 label = PyString_ToPJ(pLabel);
2527 if (!PyList_Check(pFileList))
2528 return Py_BuildValue("ii", PJ_EINVAL, PJSUA_INVALID_ID);
2529
2530 count = 0;
2531 for (count=0; count<PyList_Size(pFileList) &&
2532 count<PJ_ARRAY_SIZE(files); ++count)
2533 {
2534 files[count] = PyString_ToPJ(PyList_GetItem(pFileList, count));
2535 }
2536
2537 status = pjsua_playlist_create(files, count, &label, options, &id);
2538
2539 return Py_BuildValue("ii", status, id);
2540}
2541
2542/*
2543 * py_pjsua_player_get_conf_port
2544 */
2545static PyObject *py_pjsua_player_get_conf_port(PyObject *pSelf,
2546 PyObject *pArgs)
2547{
2548
2549 int id, port_id;
2550
2551 PJ_UNUSED_ARG(pSelf);
2552
2553 if (!PyArg_ParseTuple(pArgs, "i", &id)) {
2554 return NULL;
2555 }
2556
2557 port_id = pjsua_player_get_conf_port(id);
2558
2559 return Py_BuildValue("i", port_id);
2560}
2561
2562/*
2563 * py_pjsua_player_set_pos
2564 */
2565static PyObject *py_pjsua_player_set_pos(PyObject *pSelf, PyObject *pArgs)
2566{
2567 int id;
2568 int samples;
2569 int status;
2570
2571 PJ_UNUSED_ARG(pSelf);
2572
2573 if (!PyArg_ParseTuple(pArgs, "ii", &id, &samples)) {
2574 return NULL;
2575 }
2576
2577 if (samples < 0)
2578 samples = 0;
2579
2580 status = pjsua_player_set_pos(id, samples);
2581
2582 return Py_BuildValue("i", status);
2583}
2584
2585/*
2586 * py_pjsua_player_destroy
2587 */
2588static PyObject *py_pjsua_player_destroy(PyObject *pSelf, PyObject *pArgs)
2589{
2590 int id;
2591 int status;
2592
2593 PJ_UNUSED_ARG(pSelf);
2594
2595 if (!PyArg_ParseTuple(pArgs, "i", &id)) {
2596 return NULL;
2597 }
2598
2599 status = pjsua_player_destroy(id);
2600
2601 return Py_BuildValue("i", status);
2602}
2603
2604/*
2605 * py_pjsua_recorder_create
2606 */
2607static PyObject *py_pjsua_recorder_create(PyObject *pSelf, PyObject *pArgs)
2608{
2609 int id, options;
2610 int max_size;
2611 PyObject *pFilename, *pEncParam;
2612 pj_str_t filename;
2613 int enc_type;
2614
2615 int status;
2616
2617 PJ_UNUSED_ARG(pSelf);
2618
2619 if (!PyArg_ParseTuple(pArgs, "OiOii", &pFilename, &enc_type, &pEncParam,
2620 &max_size, &options))
2621 {
2622 return NULL;
2623 }
2624
2625 filename = PyString_ToPJ(pFilename);
2626
2627 status = pjsua_recorder_create(&filename, enc_type, NULL, max_size,
2628 options, &id);
2629
2630 return Py_BuildValue("ii", status, id);
2631}
2632
2633/*
2634 * py_pjsua_recorder_get_conf_port
2635 */
2636static PyObject *py_pjsua_recorder_get_conf_port(PyObject *pSelf,
2637 PyObject *pArgs)
2638{
2639
2640 int id, port_id;
2641
2642 PJ_UNUSED_ARG(pSelf);
2643
2644 if (!PyArg_ParseTuple(pArgs, "i", &id)) {
2645 return NULL;
2646 }
2647
2648 port_id = pjsua_recorder_get_conf_port(id);
2649
2650 return Py_BuildValue("i", port_id);
2651}
2652
2653/*
2654 * py_pjsua_recorder_destroy
2655 */
2656static PyObject *py_pjsua_recorder_destroy(PyObject *pSelf, PyObject *pArgs)
2657{
2658 int id;
2659 int status;
2660
2661 PJ_UNUSED_ARG(pSelf);
2662
2663 if (!PyArg_ParseTuple(pArgs, "i", &id)) {
2664 return NULL;
2665 }
2666
2667 status = pjsua_recorder_destroy(id);
2668
2669 return Py_BuildValue("i", status);
2670}
2671
2672/*
2673 * py_pjsua_enum_snd_devs
2674 */
2675static PyObject *py_pjsua_enum_snd_devs(PyObject *pSelf, PyObject *pArgs)
2676{
2677 pj_status_t status;
2678 PyObject *ret;
2679 pjmedia_snd_dev_info info[SND_DEV_NUM];
2680 unsigned c, i;
2681
2682 PJ_UNUSED_ARG(pSelf);
2683 PJ_UNUSED_ARG(pArgs);
2684
2685 c = PJ_ARRAY_SIZE(info);
2686 status = pjsua_enum_snd_devs(info, &c);
2687 if (status != PJ_SUCCESS)
2688 c = 0;
2689
2690 ret = PyList_New(c);
2691 for (i = 0; i < c; i++) {
2692 PyObj_pjmedia_snd_dev_info * obj;
2693
2694 obj = (PyObj_pjmedia_snd_dev_info *)
2695 pjmedia_snd_dev_info_new(&PyTyp_pjmedia_snd_dev_info,
2696 NULL, NULL);
2697 obj->default_samples_per_sec = info[i].default_samples_per_sec;
2698 obj->input_count = info[i].input_count;
2699 obj->output_count = info[i].output_count;
2700 obj->name = PyString_FromString(info[i].name);
2701
2702 PyList_SetItem(ret, i, (PyObject *)obj);
2703 }
2704
2705 return (PyObject*)ret;
2706}
2707
2708/*
2709 * py_pjsua_get_snd_dev
2710 */
2711static PyObject *py_pjsua_get_snd_dev(PyObject *pSelf, PyObject *pArgs)
2712{
2713 int capture_dev, playback_dev;
2714 int status;
2715
2716 PJ_UNUSED_ARG(pSelf);
2717 PJ_UNUSED_ARG(pArgs);
2718
2719 status = pjsua_get_snd_dev(&capture_dev, &playback_dev);
2720
2721 return Py_BuildValue("ii", capture_dev, playback_dev);
2722}
2723
2724/*
2725 * py_pjsua_set_snd_dev
2726 */
2727static PyObject *py_pjsua_set_snd_dev(PyObject *pSelf, PyObject *pArgs)
2728{
2729 int capture_dev, playback_dev;
2730 int status;
2731
2732 PJ_UNUSED_ARG(pSelf);
2733
2734 if (!PyArg_ParseTuple(pArgs, "ii", &capture_dev, &playback_dev)) {
2735 return NULL;
2736 }
2737
2738 status = pjsua_set_snd_dev(capture_dev, playback_dev);
2739
2740 return Py_BuildValue("i", status);
2741}
2742
2743/*
2744 * py_pjsua_set_null_snd_dev
2745 */
2746static PyObject *py_pjsua_set_null_snd_dev(PyObject *pSelf, PyObject *pArgs)
2747{
2748 int status;
2749
2750 PJ_UNUSED_ARG(pSelf);
2751 PJ_UNUSED_ARG(pArgs);
2752
2753 status = pjsua_set_null_snd_dev();
2754
2755 return Py_BuildValue("i", status);
2756}
2757
2758/*
2759 * py_pjsua_set_ec
2760 */
2761static PyObject *py_pjsua_set_ec(PyObject *pSelf, PyObject *pArgs)
2762{
2763 int options;
2764 int tail_ms;
2765 int status;
2766
2767 PJ_UNUSED_ARG(pSelf);
2768
2769 if (!PyArg_ParseTuple(pArgs, "ii", &tail_ms, &options)) {
2770 return NULL;
2771 }
2772
2773 status = pjsua_set_ec(tail_ms, options);
2774
2775 return Py_BuildValue("i", status);
2776}
2777
2778/*
2779 * py_pjsua_get_ec_tail
2780 */
2781static PyObject *py_pjsua_get_ec_tail(PyObject *pSelf, PyObject *pArgs)
2782{
2783 int status;
2784 unsigned tail_ms;
2785
2786 PJ_UNUSED_ARG(pSelf);
2787 PJ_UNUSED_ARG(pArgs);
2788
2789 status = pjsua_get_ec_tail(&tail_ms);
2790 if (status != PJ_SUCCESS)
2791 tail_ms = 0;
2792
2793 return Py_BuildValue("i", tail_ms);
2794}
2795
2796/*
2797 * py_pjsua_enum_codecs
2798 */
2799static PyObject *py_pjsua_enum_codecs(PyObject *pSelf, PyObject *pArgs)
2800{
2801 pj_status_t status;
2802 PyObject *ret;
2803 pjsua_codec_info info[PJMEDIA_CODEC_MGR_MAX_CODECS];
2804 unsigned c, i;
2805
2806 PJ_UNUSED_ARG(pSelf);
2807 PJ_UNUSED_ARG(pArgs);
2808
2809 c = PJ_ARRAY_SIZE(info);
2810 status = pjsua_enum_codecs(info, &c);
2811 if (status != PJ_SUCCESS)
2812 c = 0;
2813
2814 ret = PyList_New(c);
2815 for (i = 0; i < c; i++) {
2816 PyObj_pjsua_codec_info * obj;
2817 obj = (PyObj_pjsua_codec_info *)
2818 codec_info_new(&PyTyp_pjsua_codec_info, NULL, NULL);
2819 obj->codec_id = PyString_FromPJ(&info[i].codec_id);
2820 obj->priority = info[i].priority;
2821
2822 PyList_SetItem(ret, i, (PyObject *)obj);
2823 }
2824
2825 return (PyObject*)ret;
2826}
2827
2828/*
2829 * py_pjsua_codec_set_priority
2830 */
2831static PyObject *py_pjsua_codec_set_priority(PyObject *pSelf, PyObject *pArgs)
2832{
2833 int status;
2834 PyObject *pCodecId;
2835 pj_str_t codec_id;
2836 int priority;
2837
2838 PJ_UNUSED_ARG(pSelf);
2839
2840 if (!PyArg_ParseTuple(pArgs, "Oi", &pCodecId, &priority)) {
2841 return NULL;
2842 }
2843
2844 codec_id = PyString_ToPJ(pCodecId);
2845 if (priority < 0)
2846 priority = 0;
2847 if (priority > 255)
2848 priority = 255;
2849
2850 status = pjsua_codec_set_priority(&codec_id, (pj_uint8_t)priority);
2851
2852 return Py_BuildValue("i", status);
2853}
2854
2855/*
2856 * py_pjsua_codec_get_param
2857 */
2858static PyObject *py_pjsua_codec_get_param(PyObject *pSelf, PyObject *pArgs)
2859{
2860 int status;
2861 PyObject *pCodecId;
2862 pj_str_t codec_id;
2863 pjmedia_codec_param param;
2864 PyObj_pjmedia_codec_param *ret;
2865
2866 PJ_UNUSED_ARG(pSelf);
2867
2868 if (!PyArg_ParseTuple(pArgs, "O", &pCodecId)) {
2869 return NULL;
2870 }
2871
2872 codec_id = PyString_ToPJ(pCodecId);
2873
2874 status = pjsua_codec_get_param(&codec_id, &param);
2875 if (status != PJ_SUCCESS)
2876 return Py_BuildValue("");
2877
2878 ret = (PyObj_pjmedia_codec_param *)
2879 pjmedia_codec_param_new(&PyTyp_pjmedia_codec_param, NULL, NULL);
2880
2881 ret->info->avg_bps = param.info.avg_bps;
2882 ret->info->channel_cnt = param.info.channel_cnt;
2883 ret->info->clock_rate = param.info.clock_rate;
2884 ret->info->frm_ptime = param.info.frm_ptime;
2885 ret->info->pcm_bits_per_sample = param.info.pcm_bits_per_sample;
2886 ret->info->pt = param.info.pt;
2887 ret->setting->cng = param.setting.cng;
2888 //ret->setting->dec_fmtp_mode = param.setting.dec_fmtp_mode;
2889 //ret->setting->enc_fmtp_mode = param.setting.enc_fmtp_mode;
2890 ret->setting->frm_per_pkt = param.setting.frm_per_pkt;
2891 ret->setting->penh = param.setting.penh;
2892 ret->setting->plc = param.setting.plc;
2893 ret->setting->vad = param.setting.vad;
2894
2895 return (PyObject*)ret;
2896}
2897
2898
2899/*
2900 * py_pjsua_codec_set_param
2901 */
2902static PyObject *py_pjsua_codec_set_param(PyObject *pSelf, PyObject *pArgs)
2903{
2904 int status;
2905 PyObject *pCodecId, *pCodecParam;
2906 pj_str_t codec_id;
2907 pjmedia_codec_param param;
2908
2909 PJ_UNUSED_ARG(pSelf);
2910
2911 if (!PyArg_ParseTuple(pArgs, "OO", &pCodecId, &pCodecParam)) {
2912 return NULL;
2913 }
2914
2915 codec_id = PyString_ToPJ(pCodecId);
2916
2917 if (pCodecParam != Py_None) {
2918 PyObj_pjmedia_codec_param *obj;
2919
2920 obj = (PyObj_pjmedia_codec_param *)pCodecParam;
2921
2922 param.info.avg_bps = obj->info->avg_bps;
2923 param.info.channel_cnt = obj->info->channel_cnt;
2924 param.info.clock_rate = obj->info->clock_rate;
2925 param.info.frm_ptime = obj->info->frm_ptime;
2926 param.info.pcm_bits_per_sample = obj->info->pcm_bits_per_sample;
2927 param.info.pt = obj->info->pt;
2928 param.setting.cng = obj->setting->cng;
2929 //param.setting.dec_fmtp_mode = obj->setting->dec_fmtp_mode;
2930 //param.setting.enc_fmtp_mode = obj->setting->enc_fmtp_mode;
2931 param.setting.frm_per_pkt = obj->setting->frm_per_pkt;
2932 param.setting.penh = obj->setting->penh;
2933 param.setting.plc = obj->setting->plc;
2934 param.setting.vad = obj->setting->vad;
2935 status = pjsua_codec_set_param(&codec_id, &param);
2936
2937 } else {
2938 status = pjsua_codec_set_param(&codec_id, NULL);
2939 }
2940
2941 return Py_BuildValue("i", status);
2942}
2943
2944static char pjsua_conf_get_max_ports_doc[] =
2945 "int _pjsua.conf_get_max_ports () "
2946 "Get maxinum number of conference ports.";
2947static char pjsua_conf_get_active_ports_doc[] =
2948 "int _pjsua.conf_get_active_ports () "
2949 "Get current number of active ports in the bridge.";
2950static char pjsua_enum_conf_ports_doc[] =
2951 "int[] _pjsua.enum_conf_ports () "
2952 "Enumerate all conference ports.";
2953static char pjsua_conf_get_port_info_doc[] =
2954 "_pjsua.Conf_Port_Info _pjsua.conf_get_port_info (int id) "
2955 "Get information about the specified conference port";
2956static char pjsua_conf_remove_port_doc[] =
2957 "int _pjsua.conf_remove_port (int id) "
2958 "Remove arbitrary slot from the conference bridge. "
2959 "Application should only call this function "
2960 "if it registered the port manually.";
2961static char pjsua_conf_connect_doc[] =
2962 "int _pjsua.conf_connect (int source, int sink) "
2963 "Establish unidirectional media flow from souce to sink. "
2964 "One source may transmit to multiple destinations/sink. "
2965 "And if multiple sources are transmitting to the same sink, "
2966 "the media will be mixed together. Source and sink may refer "
2967 "to the same ID, effectively looping the media. "
2968 "If bidirectional media flow is desired, application "
2969 "needs to call this function twice, with the second "
2970 "one having the arguments reversed.";
2971static char pjsua_conf_disconnect_doc[] =
2972 "int _pjsua.conf_disconnect (int source, int sink) "
2973 "Disconnect media flow from the source to destination port.";
2974static char pjsua_player_create_doc[] =
2975 "int, int _pjsua.player_create (string filename, int options) "
2976 "Create a file player, and automatically connect "
2977 "this player to the conference bridge.";
2978static char pjsua_player_get_conf_port_doc[] =
2979 "int _pjsua.player_get_conf_port (int) "
2980 "Get conference port ID associated with player.";
2981static char pjsua_player_set_pos_doc[] =
2982 "int _pjsua.player_set_pos (int id, int samples) "
2983 "Set playback position.";
2984static char pjsua_player_destroy_doc[] =
2985 "int _pjsua.player_destroy (int id) "
2986 "Close the file, remove the player from the bridge, "
2987 "and free resources associated with the file player.";
2988static char pjsua_recorder_create_doc[] =
2989 "int, int _pjsua.recorder_create (string filename, "
2990 "int enc_type, int enc_param, int max_size, int options) "
2991 "Create a file recorder, and automatically connect this recorder "
2992 "to the conference bridge. The recorder currently supports recording "
2993 "WAV file, and on Windows, MP3 file. The type of the recorder to use "
2994 "is determined by the extension of the file (e.g. '.wav' or '.mp3').";
2995static char pjsua_recorder_get_conf_port_doc[] =
2996 "int _pjsua.recorder_get_conf_port (int id) "
2997 "Get conference port associated with recorder.";
2998static char pjsua_recorder_destroy_doc[] =
2999 "int _pjsua.recorder_destroy (int id) "
3000 "Destroy recorder (this will complete recording).";
3001static char pjsua_enum_snd_devs_doc[] =
3002 "_pjsua.PJMedia_Snd_Dev_Info[] _pjsua.enum_snd_devs (int count) "
3003 "Enum sound devices.";
3004static char pjsua_get_snd_dev_doc[] =
3005 "int, int _pjsua.get_snd_dev () "
3006 "Get currently active sound devices. "
3007 "If sound devices has not been created "
3008 "(for example when pjsua_start() is not called), "
3009 "it is possible that the function returns "
3010 "PJ_SUCCESS with -1 as device IDs.";
3011static char pjsua_set_snd_dev_doc[] =
3012 "int _pjsua.set_snd_dev (int capture_dev, int playback_dev) "
3013 "Select or change sound device. Application may call this function "
3014 "at any time to replace current sound device.";
3015static char pjsua_set_null_snd_dev_doc[] =
3016 "int _pjsua.set_null_snd_dev () "
3017 "Set pjsua to use null sound device. The null sound device only "
3018 "provides the timing needed by the conference bridge, and will not "
3019 "interract with any hardware.";
3020static char pjsua_set_ec_doc[] =
3021 "int _pjsua.set_ec (int tail_ms, int options) "
3022 "Configure the echo canceller tail length of the sound port.";
3023static char pjsua_get_ec_tail_doc[] =
3024 "int _pjsua.get_ec_tail () "
3025 "Get current echo canceller tail length.";
3026static char pjsua_enum_codecs_doc[] =
3027 "_pjsua.Codec_Info[] _pjsua.enum_codecs () "
3028 "Enum all supported codecs in the system.";
3029static char pjsua_codec_set_priority_doc[] =
3030 "int _pjsua.codec_set_priority (string id, int priority) "
3031 "Change codec priority.";
3032static char pjsua_codec_get_param_doc[] =
3033 "_pjsua.PJMedia_Codec_Param _pjsua.codec_get_param (string id) "
3034 "Get codec parameters";
3035static char pjsua_codec_set_param_doc[] =
3036 "int _pjsua.codec_set_param (string id, "
3037 "_pjsua.PJMedia_Codec_Param param) "
3038 "Set codec parameters.";
3039
3040/* END OF LIB MEDIA */
3041
3042/* LIB CALL */
3043
3044/*
3045 * py_pjsua_call_get_max_count
3046 */
3047static PyObject *py_pjsua_call_get_max_count(PyObject *pSelf, PyObject *pArgs)
3048{
3049 int count;
3050
3051 PJ_UNUSED_ARG(pSelf);
3052 PJ_UNUSED_ARG(pArgs);
3053
3054 count = pjsua_call_get_max_count();
3055
3056 return Py_BuildValue("i", count);
3057}
3058
3059/*
3060 * py_pjsua_call_get_count
3061 */
3062static PyObject *py_pjsua_call_get_count(PyObject *pSelf, PyObject *pArgs)
3063{
3064 int count;
3065
3066 PJ_UNUSED_ARG(pSelf);
3067 PJ_UNUSED_ARG(pArgs);
3068
3069 count = pjsua_call_get_count();
3070
3071 return Py_BuildValue("i", count);
3072}
3073
3074/*
3075 * py_pjsua_enum_calls
3076 */
3077static PyObject *py_pjsua_enum_calls(PyObject *pSelf, PyObject *pArgs)
3078{
3079 pj_status_t status;
3080 PyObject *ret;
3081 pjsua_transport_id id[PJSUA_MAX_CALLS];
3082 unsigned c, i;
3083
3084 PJ_UNUSED_ARG(pSelf);
3085 PJ_UNUSED_ARG(pArgs);
3086
3087 c = PJ_ARRAY_SIZE(id);
3088 status = pjsua_enum_calls(id, &c);
3089 if (status != PJ_SUCCESS)
3090 c = 0;
3091
3092 ret = PyList_New(c);
3093 for (i = 0; i < c; i++) {
3094 PyList_SetItem(ret, i, Py_BuildValue("i", id[i]));
3095 }
3096
3097 return (PyObject*)ret;
3098}
3099
3100/*
3101 * py_pjsua_call_make_call
3102 */
3103static PyObject *py_pjsua_call_make_call(PyObject *pSelf, PyObject *pArgs)
3104{
3105 int status;
3106 int acc_id;
3107 pj_str_t dst_uri;
3108 PyObject *pDstUri, *pMsgData, *pUserData;
3109 pjsua_call_setting option;
3110 pjsua_msg_data msg_data;
3111 int call_id;
3112 pj_pool_t *pool = NULL;
3113
3114 PJ_UNUSED_ARG(pSelf);
3115
3116 pjsua_call_setting_default(&option);
3117 if (!PyArg_ParseTuple(pArgs, "iOIOO", &acc_id, &pDstUri, &option.flag,
3118 &pUserData, &pMsgData))
3119 {
3120 return NULL;
3121 }
3122
3123 dst_uri = PyString_ToPJ(pDstUri);
3124 pjsua_msg_data_init(&msg_data);
3125
3126 if (pMsgData != Py_None) {
3127 PyObj_pjsua_msg_data * omd;
3128
3129 omd = (PyObj_pjsua_msg_data *)pMsgData;
3130
3131 msg_data.content_type = PyString_ToPJ(omd->content_type);
3132 msg_data.msg_body = PyString_ToPJ(omd->msg_body);
3133 pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
3134 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
3135 }
3136
3137 Py_XINCREF(pUserData);
3138
3139 status = pjsua_call_make_call(acc_id, &dst_uri,
3140 &option, (void*)pUserData,
3141 &msg_data, &call_id);
3142 if (pool != NULL)
3143 pj_pool_release(pool);
3144
3145 if (status != PJ_SUCCESS) {
3146 Py_XDECREF(pUserData);
3147 }
3148
3149 return Py_BuildValue("ii", status, call_id);
3150}
3151
3152/*
3153 * py_pjsua_call_is_active
3154 */
3155static PyObject *py_pjsua_call_is_active(PyObject *pSelf, PyObject *pArgs)
3156{
3157 int call_id;
3158 int is_active;
3159
3160 PJ_UNUSED_ARG(pSelf);
3161
3162 if (!PyArg_ParseTuple(pArgs, "i", &call_id)) {
3163 return NULL;
3164 }
3165
3166 is_active = pjsua_call_is_active(call_id);
3167
3168 return Py_BuildValue("i", is_active);
3169}
3170
3171/*
3172 * py_pjsua_call_has_media
3173 */
3174static PyObject *py_pjsua_call_has_media(PyObject *pSelf, PyObject *pArgs)
3175{
3176 int call_id;
3177 int has_media;
3178
3179 PJ_UNUSED_ARG(pSelf);
3180
3181 if (!PyArg_ParseTuple(pArgs, "i", &call_id)) {
3182 return NULL;
3183 }
3184
3185 has_media = pjsua_call_has_media(call_id);
3186
3187 return Py_BuildValue("i", has_media);
3188}
3189
3190/*
3191 * py_pjsua_call_get_conf_port
3192 */
3193static PyObject* py_pjsua_call_get_conf_port(PyObject *pSelf, PyObject *pArgs)
3194{
3195 int call_id;
3196 int port_id;
3197
3198 PJ_UNUSED_ARG(pSelf);
3199
3200 if (!PyArg_ParseTuple(pArgs, "i", &call_id)) {
3201 return NULL;
3202 }
3203
3204 port_id = pjsua_call_get_conf_port(call_id);
3205
3206 return Py_BuildValue("i", port_id);
3207}
3208
3209/*
3210 * py_pjsua_call_get_info
3211 */
3212static PyObject* py_pjsua_call_get_info(PyObject *pSelf, PyObject *pArgs)
3213{
3214 int call_id;
3215 int status;
3216 PyObj_pjsua_call_info *ret;
3217 pjsua_call_info info;
3218
3219 PJ_UNUSED_ARG(pSelf);
3220
3221 if (!PyArg_ParseTuple(pArgs, "i", &call_id)) {
3222 return NULL;
3223 }
3224
3225 status = pjsua_call_get_info(call_id, &info);
3226 if (status != PJ_SUCCESS)
3227 return Py_BuildValue("");
3228
3229 ret = (PyObj_pjsua_call_info *)call_info_new(&PyTyp_pjsua_call_info,
3230 NULL, NULL);
3231 ret->acc_id = info.acc_id;
3232 Py_XDECREF(ret->call_id);
3233 ret->call_id = PyString_FromPJ(&info.call_id);
3234 ret->conf_slot = info.conf_slot;
3235 ret->connect_duration = info.connect_duration.sec * 1000 +
3236 info.connect_duration.msec;
3237 ret->total_duration = info.total_duration.sec * 1000 +
3238 info.total_duration.msec;
3239 ret->id = info.id;
3240 ret->last_status = info.last_status;
3241 Py_XDECREF(ret->last_status_text);
3242 ret->last_status_text = PyString_FromPJ(&info.last_status_text);
3243 Py_XDECREF(ret->local_contact);
3244 ret->local_contact = PyString_FromPJ(&info.local_contact);
3245 Py_XDECREF(ret->local_info);
3246 ret->local_info = PyString_FromPJ(&info.local_info);
3247 Py_XDECREF(ret->remote_contact);
3248 ret->remote_contact = PyString_FromPJ(&info.remote_contact);
3249 Py_XDECREF(ret->remote_info);
3250 ret->remote_info = PyString_FromPJ(&info.remote_info);
3251 ret->media_dir = info.media_dir;
3252 ret->media_status = info.media_status;
3253 ret->role = info.role;
3254 ret->state = info.state;
3255 Py_XDECREF(ret->state_text);
3256 ret->state_text = PyString_FromPJ(&info.state_text);
3257
3258 return (PyObject*)ret;
3259}
3260
3261/*
3262 * py_pjsua_call_set_user_data
3263 */
3264static PyObject *py_pjsua_call_set_user_data(PyObject *pSelf, PyObject *pArgs)
3265{
3266 int call_id;
3267 PyObject *pUserData, *old_user_data;
3268 int status;
3269
3270 PJ_UNUSED_ARG(pSelf);
3271
3272 if (!PyArg_ParseTuple(pArgs, "iO", &call_id, &pUserData)) {
3273 return NULL;
3274 }
3275
3276 old_user_data = (PyObject*) pjsua_call_get_user_data(call_id);
3277
3278 if (old_user_data == pUserData) {
3279 return Py_BuildValue("i", PJ_SUCCESS);
3280 }
3281
3282 Py_XINCREF(pUserData);
3283 Py_XDECREF(old_user_data);
3284
3285 status = pjsua_call_set_user_data(call_id, (void*)pUserData);
3286
3287 if (status != PJ_SUCCESS) {
3288 Py_XDECREF(pUserData);
3289 }
3290
3291 return Py_BuildValue("i", status);
3292}
3293
3294/*
3295 * py_pjsua_call_get_user_data
3296 */
3297static PyObject *py_pjsua_call_get_user_data(PyObject *pSelf, PyObject *pArgs)
3298{
3299 int call_id;
3300 PyObject *user_data;
3301
3302 PJ_UNUSED_ARG(pSelf);
3303
3304 if (!PyArg_ParseTuple(pArgs, "i", &call_id)) {
3305 return NULL;
3306 }
3307
3308 user_data = (PyObject*)pjsua_call_get_user_data(call_id);
3309 return user_data ? Py_BuildValue("O", user_data) : Py_BuildValue("");
3310}
3311
3312/*
3313 * py_pjsua_call_answer
3314 */
3315static PyObject *py_pjsua_call_answer(PyObject *pSelf, PyObject *pArgs)
3316{
3317 int status;
3318 int call_id;
3319 pj_str_t * reason, tmp_reason;
3320 PyObject *pReason;
3321 unsigned code;
3322 pjsua_msg_data msg_data;
3323 PyObject * omdObj;
3324 pj_pool_t * pool = NULL;
3325
3326 PJ_UNUSED_ARG(pSelf);
3327
3328 if (!PyArg_ParseTuple(pArgs, "iIOO", &call_id, &code, &pReason, &omdObj)) {
3329 return NULL;
3330 }
3331
3332 if (pReason == Py_None) {
3333 reason = NULL;
3334 } else {
3335 reason = &tmp_reason;
3336 tmp_reason = PyString_ToPJ(pReason);
3337 }
3338
3339 pjsua_msg_data_init(&msg_data);
3340 if (omdObj != Py_None) {
3341 PyObj_pjsua_msg_data *omd;
3342
3343 omd = (PyObj_pjsua_msg_data *)omdObj;
3344 msg_data.content_type = PyString_ToPJ(omd->content_type);
3345 msg_data.msg_body = PyString_ToPJ(omd->msg_body);
3346 pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
3347 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
3348 }
3349
3350 status = pjsua_call_answer(call_id, code, reason, &msg_data);
3351
3352 if (pool)
3353 pj_pool_release(pool);
3354
3355 return Py_BuildValue("i", status);
3356}
3357
3358/*
3359 * py_pjsua_call_hangup
3360 */
3361static PyObject *py_pjsua_call_hangup(PyObject *pSelf, PyObject *pArgs)
3362{
3363 int status;
3364 int call_id;
3365 pj_str_t *reason, tmp_reason;
3366 PyObject *pReason;
3367 unsigned code;
3368 pjsua_msg_data msg_data;
3369 PyObject *omdObj;
3370 pj_pool_t *pool = NULL;
3371
3372 PJ_UNUSED_ARG(pSelf);
3373
3374 if (!PyArg_ParseTuple(pArgs, "iIOO", &call_id, &code, &pReason,
3375 &omdObj))
3376 {
3377 return NULL;
3378 }
3379
3380 if (pReason == Py_None) {
3381 reason = NULL;
3382 } else {
3383 reason = &tmp_reason;
3384 tmp_reason = PyString_ToPJ(pReason);
3385 }
3386
3387 pjsua_msg_data_init(&msg_data);
3388 if (omdObj != Py_None) {
3389 PyObj_pjsua_msg_data *omd;
3390
3391 omd = (PyObj_pjsua_msg_data *)omdObj;
3392 msg_data.content_type = PyString_ToPJ(omd->content_type);
3393 msg_data.msg_body = PyString_ToPJ(omd->msg_body);
3394 pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
3395 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
3396 }
3397
3398 status = pjsua_call_hangup(call_id, code, reason, &msg_data);
3399 if (pool)
3400 pj_pool_release(pool);
3401
3402 return Py_BuildValue("i", status);
3403}
3404
3405/*
3406 * py_pjsua_call_set_hold
3407 */
3408static PyObject *py_pjsua_call_set_hold(PyObject *pSelf, PyObject *pArgs)
3409{
3410 int status;
3411 int call_id;
3412 pjsua_msg_data msg_data;
3413 PyObject *omdObj;
3414 pj_pool_t *pool = NULL;
3415
3416 PJ_UNUSED_ARG(pSelf);
3417
3418 if (!PyArg_ParseTuple(pArgs, "iO", &call_id, &omdObj)) {
3419 return NULL;
3420 }
3421
3422 pjsua_msg_data_init(&msg_data);
3423 if (omdObj != Py_None) {
3424 PyObj_pjsua_msg_data *omd;
3425
3426 omd = (PyObj_pjsua_msg_data *)omdObj;
3427 msg_data.content_type = PyString_ToPJ(omd->content_type);
3428 msg_data.msg_body = PyString_ToPJ(omd->msg_body);
3429 pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
3430 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
3431 }
3432
3433 status = pjsua_call_set_hold(call_id, &msg_data);
3434
3435 if (pool)
3436 pj_pool_release(pool);
3437
3438 return Py_BuildValue("i",status);
3439}
3440
3441/*
3442 * py_pjsua_call_reinvite
3443 */
3444static PyObject *py_pjsua_call_reinvite(PyObject *pSelf, PyObject *pArgs)
3445{
3446 int status;
3447 int call_id;
3448 int unhold;
3449 pjsua_msg_data msg_data;
3450 PyObject *omdObj;
3451 pj_pool_t *pool = NULL;
3452
3453 PJ_UNUSED_ARG(pSelf);
3454
3455 if (!PyArg_ParseTuple(pArgs, "iiO", &call_id, &unhold, &omdObj)) {
3456 return NULL;
3457 }
3458
3459 pjsua_msg_data_init(&msg_data);
3460 if (omdObj != Py_None) {
3461 PyObj_pjsua_msg_data *omd;
3462
3463 omd = (PyObj_pjsua_msg_data *)omdObj;
3464 msg_data.content_type = PyString_ToPJ(omd->content_type);
3465 msg_data.msg_body = PyString_ToPJ(omd->msg_body);
3466 pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
3467 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
3468 }
3469
3470 status = pjsua_call_reinvite(call_id, unhold, &msg_data);
3471
3472 if (pool)
3473 pj_pool_release(pool);
3474
3475 return Py_BuildValue("i", status);
3476}
3477
3478/*
3479 * py_pjsua_call_update
3480 */
3481static PyObject *py_pjsua_call_update(PyObject *pSelf, PyObject *pArgs)
3482{
3483 int status;
3484 int call_id;
3485 int option;
3486 pjsua_msg_data msg_data;
3487 PyObject *omdObj;
3488 pj_pool_t *pool = NULL;
3489
3490 PJ_UNUSED_ARG(pSelf);
3491
3492 if (!PyArg_ParseTuple(pArgs, "iiO", &call_id, &option, &omdObj)) {
3493 return NULL;
3494 }
3495
3496 pjsua_msg_data_init(&msg_data);
3497 if (omdObj != Py_None) {
3498 PyObj_pjsua_msg_data *omd;
3499
3500 omd = (PyObj_pjsua_msg_data *)omdObj;
3501 msg_data.content_type = PyString_ToPJ(omd->content_type);
3502 msg_data.msg_body = PyString_ToPJ(omd->msg_body);
3503 pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
3504 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
3505 }
3506
3507 status = pjsua_call_update(call_id, option, &msg_data);
3508
3509 if (pool)
3510 pj_pool_release(pool);
3511
3512 return Py_BuildValue("i", status);
3513}
3514
3515/*
3516 * py_pjsua_call_send_request
3517 */
3518static PyObject *py_pjsua_call_send_request(PyObject *pSelf, PyObject *pArgs)
3519{
3520 int status;
3521 int call_id;
3522 PyObject *pMethod;
3523 pj_str_t method;
3524 pjsua_msg_data msg_data;
3525 PyObject *omdObj;
3526 pj_pool_t *pool = NULL;
3527
3528 PJ_UNUSED_ARG(pSelf);
3529
3530 if (!PyArg_ParseTuple(pArgs, "iOO", &call_id, &pMethod, &omdObj)) {
3531 return NULL;
3532 }
3533
3534 if (!PyString_Check(pMethod)) {
3535 return NULL;
3536 }
3537
3538 method = PyString_ToPJ(pMethod);
3539 pjsua_msg_data_init(&msg_data);
3540
3541 if (omdObj != Py_None) {
3542 PyObj_pjsua_msg_data *omd;
3543
3544 omd = (PyObj_pjsua_msg_data *)omdObj;
3545 msg_data.content_type = PyString_ToPJ(omd->content_type);
3546 msg_data.msg_body = PyString_ToPJ(omd->msg_body);
3547 pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
3548 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
3549 }
3550
3551 status = pjsua_call_send_request(call_id, &method, &msg_data);
3552
3553 if (pool)
3554 pj_pool_release(pool);
3555
3556 return Py_BuildValue("i", status);
3557}
3558
3559/*
3560 * py_pjsua_call_xfer
3561 */
3562static PyObject *py_pjsua_call_xfer(PyObject *pSelf, PyObject *pArgs)
3563{
3564 int status;
3565 int call_id;
3566 pj_str_t dest;
3567 PyObject *pDstUri;
3568 pjsua_msg_data msg_data;
3569 PyObject *omdObj;
3570 pj_pool_t *pool = NULL;
3571
3572 PJ_UNUSED_ARG(pSelf);
3573
3574 if (!PyArg_ParseTuple(pArgs, "iOO", &call_id, &pDstUri, &omdObj)) {
3575 return NULL;
3576 }
3577
3578 if (!PyString_Check(pDstUri))
3579 return NULL;
3580
3581 dest = PyString_ToPJ(pDstUri);
3582 pjsua_msg_data_init(&msg_data);
3583
3584 if (omdObj != Py_None) {
3585 PyObj_pjsua_msg_data *omd;
3586
3587 omd = (PyObj_pjsua_msg_data *)omdObj;
3588 msg_data.content_type = PyString_ToPJ(omd->content_type);
3589 msg_data.msg_body = PyString_ToPJ(omd->msg_body);
3590 pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
3591 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
3592 }
3593
3594 status = pjsua_call_xfer(call_id, &dest, &msg_data);
3595
3596 if (pool)
3597 pj_pool_release(pool);
3598
3599 return Py_BuildValue("i", status);
3600}
3601
3602/*
3603 * py_pjsua_call_xfer_replaces
3604 */
3605static PyObject *py_pjsua_call_xfer_replaces(PyObject *pSelf, PyObject *pArgs)
3606{
3607 int status;
3608 int call_id;
3609 int dest_call_id;
3610 unsigned options;
3611 pjsua_msg_data msg_data;
3612 PyObject *omdObj;
3613 pj_pool_t *pool = NULL;
3614
3615 PJ_UNUSED_ARG(pSelf);
3616
3617 if (!PyArg_ParseTuple(pArgs, "iiIO", &call_id, &dest_call_id,
3618 &options, &omdObj))
3619 {
3620 return NULL;
3621 }
3622
3623 pjsua_msg_data_init(&msg_data);
3624
3625 if (omdObj != Py_None) {
3626 PyObj_pjsua_msg_data *omd;
3627
3628 omd = (PyObj_pjsua_msg_data *)omdObj;
3629 msg_data.content_type = PyString_ToPJ(omd->content_type);
3630 msg_data.msg_body = PyString_ToPJ(omd->msg_body);
3631 pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
3632 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
3633 }
3634
3635 status = pjsua_call_xfer_replaces(call_id, dest_call_id, options,
3636 &msg_data);
3637
3638 if (pool)
3639 pj_pool_release(pool);
3640
3641 return Py_BuildValue("i", status);
3642}
3643
3644/*
3645 * py_pjsua_call_dial_dtmf
3646 */
3647static PyObject *py_pjsua_call_dial_dtmf(PyObject *pSelf, PyObject *pArgs)
3648{
3649 int call_id;
3650 PyObject *pDigits;
3651 pj_str_t digits;
3652 int status;
3653
3654 PJ_UNUSED_ARG(pSelf);
3655
3656 if (!PyArg_ParseTuple(pArgs, "iO", &call_id, &pDigits)) {
3657 return NULL;
3658 }
3659
3660 if (!PyString_Check(pDigits))
3661 return Py_BuildValue("i", PJ_EINVAL);
3662
3663 digits = PyString_ToPJ(pDigits);
3664 status = pjsua_call_dial_dtmf(call_id, &digits);
3665
3666 return Py_BuildValue("i", status);
3667}
3668
3669/*
3670 * py_pjsua_call_send_im
3671 */
3672static PyObject *py_pjsua_call_send_im(PyObject *pSelf, PyObject *pArgs)
3673{
3674 int status;
3675 int call_id;
3676 pj_str_t content;
3677 pj_str_t * mime_type, tmp_mime_type;
3678 PyObject *pMimeType, *pContent, *omdObj;
3679 pjsua_msg_data msg_data;
3680 int user_data;
3681 pj_pool_t *pool = NULL;
3682
3683 PJ_UNUSED_ARG(pSelf);
3684
3685 if (!PyArg_ParseTuple(pArgs, "iOOOi", &call_id, &pMimeType, &pContent,
3686 &omdObj, &user_data))
3687 {
3688 return NULL;
3689 }
3690
3691 if (!PyString_Check(pContent))
3692 return Py_BuildValue("i", PJ_EINVAL);
3693
3694 content = PyString_ToPJ(pContent);
3695
3696 if (PyString_Check(pMimeType)) {
3697 mime_type = &tmp_mime_type;
3698 tmp_mime_type = PyString_ToPJ(pMimeType);
3699 } else {
3700 mime_type = NULL;
3701 }
3702
3703 pjsua_msg_data_init(&msg_data);
3704 if (omdObj != Py_None) {
3705 PyObj_pjsua_msg_data * omd;
3706
3707 omd = (PyObj_pjsua_msg_data *)omdObj;
3708 msg_data.content_type = PyString_ToPJ(omd->content_type);
3709 msg_data.msg_body = PyString_ToPJ(omd->msg_body);
3710 pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
3711 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
3712 }
3713
3714 status = pjsua_call_send_im(call_id, mime_type, &content,
3715 &msg_data, (void*)(long)user_data);
3716
3717 if (pool)
3718 pj_pool_release(pool);
3719
3720 return Py_BuildValue("i", status);
3721}
3722
3723/*
3724 * py_pjsua_call_send_typing_ind
3725 */
3726static PyObject *py_pjsua_call_send_typing_ind(PyObject *pSelf,
3727 PyObject *pArgs)
3728{
3729 int status;
3730 int call_id;
3731 int is_typing;
3732 pjsua_msg_data msg_data;
3733 PyObject *omdObj;
3734 pj_pool_t *pool = NULL;
3735
3736 PJ_UNUSED_ARG(pSelf);
3737
3738 if (!PyArg_ParseTuple(pArgs, "iiO", &call_id, &is_typing, &omdObj)) {
3739 return NULL;
3740 }
3741
3742 pjsua_msg_data_init(&msg_data);
3743 if (omdObj != Py_None) {
3744 PyObj_pjsua_msg_data *omd;
3745
3746 omd = (PyObj_pjsua_msg_data *)omdObj;
3747 msg_data.content_type = PyString_ToPJ(omd->content_type);
3748 msg_data.msg_body = PyString_ToPJ(omd->msg_body);
3749 pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
3750 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
3751 }
3752
3753 status = pjsua_call_send_typing_ind(call_id, is_typing, &msg_data);
3754
3755 if (pool)
3756 pj_pool_release(pool);
3757
3758 return Py_BuildValue("i", status);
3759}
3760
3761/*
3762 * py_pjsua_call_hangup_all
3763 */
3764static PyObject *py_pjsua_call_hangup_all(PyObject *pSelf, PyObject *pArgs)
3765{
3766 PJ_UNUSED_ARG(pSelf);
3767 PJ_UNUSED_ARG(pArgs);
3768
3769 pjsua_call_hangup_all();
3770
3771 return Py_BuildValue("");
3772}
3773
3774/*
3775 * py_pjsua_call_dump
3776 */
3777static PyObject *py_pjsua_call_dump(PyObject *pSelf, PyObject *pArgs)
3778{
3779 int call_id;
3780 int with_media;
3781 PyObject *ret;
3782 PyObject *pIndent;
3783 char *buffer;
3784 char *indent;
3785 unsigned maxlen;
3786 int status;
3787
3788 PJ_UNUSED_ARG(pSelf);
3789
3790 if (!PyArg_ParseTuple(pArgs, "iiIO", &call_id, &with_media,
3791 &maxlen, &pIndent))
3792 {
3793 return NULL;
3794 }
3795
3796 buffer = (char*) malloc(maxlen * sizeof(char));
3797 indent = PyString_AsString(pIndent);
3798
3799 status = pjsua_call_dump(call_id, with_media, buffer, maxlen, indent);
3800 if (status != PJ_SUCCESS) {
3801 free(buffer);
3802 return PyString_FromString("");
3803 }
3804
3805 ret = PyString_FromString(buffer);
3806 free(buffer);
3807 return (PyObject*)ret;
3808}
3809
3810
3811/*
3812 * py_pjsua_dump
3813 * Dump application states.
3814 */
3815static PyObject *py_pjsua_dump(PyObject *pSelf, PyObject *pArgs)
3816{
3817 int detail;
3818
3819 PJ_UNUSED_ARG(pSelf);
3820
3821 if (!PyArg_ParseTuple(pArgs, "i", &detail)) {
3822 return NULL;
3823 }
3824
3825 pjsua_dump(detail);
3826
3827 return Py_BuildValue("");
3828}
3829
3830
3831/*
3832 * py_pj_strerror
3833 */
3834static PyObject *py_pj_strerror(PyObject *pSelf, PyObject *pArgs)
3835{
3836 int err;
3837 char err_msg[PJ_ERR_MSG_SIZE];
3838 pj_str_t ret;
3839
3840 PJ_UNUSED_ARG(pSelf);
3841
3842 if (!PyArg_ParseTuple(pArgs, "i", &err)) {
3843 return NULL;
3844 }
3845
3846 ret = pj_strerror(err, err_msg, sizeof(err_msg));
3847
3848 return PyString_FromStringAndSize(err_msg, ret.slen);
3849}
3850
3851
3852/*
3853 * py_pj_parse_simple_sip
3854 */
3855static PyObject *py_pj_parse_simple_sip(PyObject *pSelf, PyObject *pArgs)
3856{
3857 const char *arg_uri;
3858 pj_pool_t *pool;
3859 char tmp[PJSIP_MAX_URL_SIZE];
3860 pjsip_uri *uri;
3861 pjsip_sip_uri *sip_uri;
3862 PyObject *ret, *item;
3863
3864 PJ_UNUSED_ARG(pSelf);
3865
3866 if (!PyArg_ParseTuple(pArgs, "s", &arg_uri)) {
3867 return NULL;
3868 }
3869
3870 strncpy(tmp, arg_uri, sizeof(tmp));
3871 tmp[sizeof(tmp)-1] = '\0';
3872
3873 pool = pjsua_pool_create("py_pj_parse_simple_sip", 512, 512);
3874 uri = pjsip_parse_uri(pool, tmp, strlen(tmp), 0);
3875
3876 if (uri == NULL || (!PJSIP_URI_SCHEME_IS_SIP(uri) &&
3877 !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
3878 pj_pool_release(pool);
3879 return Py_BuildValue("");
3880 }
3881
3882 ret = PyTuple_New(5);
3883 sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(uri);
3884
3885 /* Scheme */
3886 item = PyString_FromPJ(pjsip_uri_get_scheme(uri));
3887 PyTuple_SetItem(ret, 0, item);
3888
3889 /* Username */
3890 item = PyString_FromPJ(&sip_uri->user);
3891 PyTuple_SetItem(ret, 1, item);
3892
3893 /* Host */
3894 item = PyString_FromPJ(&sip_uri->host);
3895 PyTuple_SetItem(ret, 2, item);
3896
3897 /* Port */
3898 if (sip_uri->port == 5060) {
3899 sip_uri->port = 0;
3900 }
3901 item = Py_BuildValue("i", sip_uri->port);
3902 PyTuple_SetItem(ret, 3, item);
3903
3904 /* Transport */
3905 if (pj_stricmp2(&sip_uri->transport_param, "udp")) {
3906 sip_uri->transport_param.ptr = "";
3907 sip_uri->transport_param.slen = 0;
3908 }
3909 item = PyString_FromPJ(&sip_uri->transport_param);
3910 PyTuple_SetItem(ret, 4, item);
3911
3912 pj_pool_release(pool);
3913 return ret;
3914}
3915
3916
3917static char pjsua_call_get_max_count_doc[] =
3918 "int _pjsua.call_get_max_count () "
3919 "Get maximum number of calls configured in pjsua.";
3920static char pjsua_call_get_count_doc[] =
3921 "int _pjsua.call_get_count () "
3922 "Get number of currently active calls.";
3923static char pjsua_enum_calls_doc[] =
3924 "int[] _pjsua.enum_calls () "
3925 "Get maximum number of calls configured in pjsua.";
3926static char pjsua_call_make_call_doc[] =
3927 "int,int _pjsua.call_make_call (int acc_id, string dst_uri, int options,"
3928 "int user_data, _pjsua.Msg_Data msg_data) "
3929 "Make outgoing call to the specified URI using the specified account.";
3930static char pjsua_call_is_active_doc[] =
3931 "int _pjsua.call_is_active (int call_id) "
3932 "Check if the specified call has active INVITE session and the INVITE "
3933 "session has not been disconnected.";
3934static char pjsua_call_has_media_doc[] =
3935 "int _pjsua.call_has_media (int call_id) "
3936 "Check if call has an active media session.";
3937static char pjsua_call_get_conf_port_doc[] =
3938 "int _pjsua.call_get_conf_port (int call_id) "
3939 "Get the conference port identification associated with the call.";
3940static char pjsua_call_get_info_doc[] =
3941 "_pjsua.Call_Info _pjsua.call_get_info (int call_id) "
3942 "Obtain detail information about the specified call.";
3943static char pjsua_call_set_user_data_doc[] =
3944 "int _pjsua.call_set_user_data (int call_id, int user_data) "
3945 "Attach application specific data to the call.";
3946static char pjsua_call_get_user_data_doc[] =
3947 "int _pjsua.call_get_user_data (int call_id) "
3948 "Get user data attached to the call.";
3949static char pjsua_call_answer_doc[] =
3950 "int _pjsua.call_answer (int call_id, int code, string reason, "
3951 "_pjsua.Msg_Data msg_data) "
3952 "Send response to incoming INVITE request.";
3953static char pjsua_call_hangup_doc[] =
3954 "int _pjsua.call_hangup (int call_id, int code, string reason, "
3955 "_pjsua.Msg_Data msg_data) "
3956 "Hangup call by using method that is appropriate according "
3957 "to the call state.";
3958static char pjsua_call_set_hold_doc[] =
3959 "int _pjsua.call_set_hold (int call_id, _pjsua.Msg_Data msg_data) "
3960 "Put the specified call on hold.";
3961static char pjsua_call_reinvite_doc[] =
3962 "int _pjsua.call_reinvite (int call_id, int unhold, "
3963 "_pjsua.Msg_Data msg_data) "
3964 "Send re-INVITE (to release hold).";
3965static char pjsua_call_xfer_doc[] =
3966 "int _pjsua.call_xfer (int call_id, string dest, "
3967 "_pjsua.Msg_Data msg_data) "
3968 "Initiate call transfer to the specified address. "
3969 "This function will send REFER request to instruct remote call party "
3970 "to initiate a new INVITE session to the specified destination/target.";
3971static char pjsua_call_xfer_replaces_doc[] =
3972 "int _pjsua.call_xfer_replaces (int call_id, int dest_call_id, "
3973 "int options, _pjsua.Msg_Data msg_data) "
3974 "Initiate attended call transfer. This function will send REFER request "
3975 "to instruct remote call party to initiate new INVITE session to the URL "
3976 "of dest_call_id. The party at dest_call_id then should 'replace' the call"
3977 "with us with the new call from the REFER recipient.";
3978static char pjsua_call_dial_dtmf_doc[] =
3979 "int _pjsua.call_dial_dtmf (int call_id, string digits) "
3980 "Send DTMF digits to remote using RFC 2833 payload formats.";
3981static char pjsua_call_send_im_doc[] =
3982 "int _pjsua.call_send_im (int call_id, string mime_type, string content,"
3983 "_pjsua.Msg_Data msg_data, int user_data) "
3984 "Send instant messaging inside INVITE session.";
3985static char pjsua_call_send_typing_ind_doc[] =
3986 "int _pjsua.call_send_typing_ind (int call_id, int is_typing, "
3987 "_pjsua.Msg_Data msg_data) "
3988 "Send IM typing indication inside INVITE session.";
3989static char pjsua_call_hangup_all_doc[] =
3990 "void _pjsua.call_hangup_all () "
3991 "Terminate all calls.";
3992static char pjsua_call_dump_doc[] =
3993 "int _pjsua.call_dump (int call_id, int with_media, int maxlen, "
3994 "string indent) "
3995 "Dump call and media statistics to string.";
3996
3997/* END OF LIB CALL */
3998
3999/*
4000 * Map of function names to functions
4001 */
4002static PyMethodDef py_pjsua_methods[] =
4003{
4004 {
4005 "thread_register", py_pjsua_thread_register, METH_VARARGS,
4006 pjsua_thread_register_doc
4007 },
4008 {
4009 "perror", py_pjsua_perror, METH_VARARGS, pjsua_perror_doc
4010 },
4011 {
4012 "create", py_pjsua_create, METH_VARARGS, pjsua_create_doc
4013 },
4014 {
4015 "init", py_pjsua_init, METH_VARARGS, pjsua_init_doc
4016 },
4017 {
4018 "start", py_pjsua_start, METH_VARARGS, pjsua_start_doc
4019 },
4020 {
4021 "destroy", py_pjsua_destroy, METH_VARARGS, pjsua_destroy_doc
4022 },
4023 {
4024 "handle_events", py_pjsua_handle_events, METH_VARARGS,
4025 pjsua_handle_events_doc
4026 },
4027 {
4028 "verify_sip_url", py_pjsua_verify_sip_url, METH_VARARGS,
4029 pjsua_verify_sip_url_doc
4030 },
4031 {
4032 "reconfigure_logging", py_pjsua_reconfigure_logging, METH_VARARGS,
4033 pjsua_reconfigure_logging_doc
4034 },
4035 {
4036 "logging_config_default", py_pjsua_logging_config_default,
4037 METH_VARARGS, pjsua_logging_config_default_doc
4038 },
4039 {
4040 "config_default", py_pjsua_config_default, METH_VARARGS,
4041 pjsua_config_default_doc
4042 },
4043 {
4044 "media_config_default", py_pjsua_media_config_default, METH_VARARGS,
4045 pjsua_media_config_default_doc
4046 },
4047
4048
4049 {
4050 "msg_data_init", py_pjsua_msg_data_init, METH_VARARGS,
4051 pjsua_msg_data_init_doc
4052 },
4053 {
4054 "transport_config_default", py_pjsua_transport_config_default,
4055 METH_VARARGS,pjsua_transport_config_default_doc
4056 },
4057 {
4058 "transport_create", py_pjsua_transport_create, METH_VARARGS,
4059 pjsua_transport_create_doc
4060 },
4061 {
4062 "transport_enum_transports", py_pjsua_enum_transports, METH_VARARGS,
4063 pjsua_enum_transports_doc
4064 },
4065 {
4066 "transport_get_info", py_pjsua_transport_get_info, METH_VARARGS,
4067 pjsua_transport_get_info_doc
4068 },
4069 {
4070 "transport_set_enable", py_pjsua_transport_set_enable, METH_VARARGS,
4071 pjsua_transport_set_enable_doc
4072 },
4073 {
4074 "transport_close", py_pjsua_transport_close, METH_VARARGS,
4075 pjsua_transport_close_doc
4076 },
4077 {
4078 "acc_config_default", py_pjsua_acc_config_default, METH_VARARGS,
4079 pjsua_acc_config_default_doc
4080 },
4081 {
4082 "acc_get_count", py_pjsua_acc_get_count, METH_VARARGS,
4083 pjsua_acc_get_count_doc
4084 },
4085 {
4086 "acc_is_valid", py_pjsua_acc_is_valid, METH_VARARGS,
4087 pjsua_acc_is_valid_doc
4088 },
4089 {
4090 "acc_set_default", py_pjsua_acc_set_default, METH_VARARGS,
4091 pjsua_acc_set_default_doc
4092 },
4093 {
4094 "acc_get_default", py_pjsua_acc_get_default, METH_VARARGS,
4095 pjsua_acc_get_default_doc
4096 },
4097 {
4098 "acc_add", py_pjsua_acc_add, METH_VARARGS,
4099 pjsua_acc_add_doc
4100 },
4101 {
4102 "acc_add_local", py_pjsua_acc_add_local, METH_VARARGS,
4103 pjsua_acc_add_local_doc
4104 },
4105 {
4106 "acc_del", py_pjsua_acc_del, METH_VARARGS,
4107 pjsua_acc_del_doc
4108 },
4109 {
4110 "acc_set_user_data", py_pjsua_acc_set_user_data, METH_VARARGS,
4111 "Accociate user data with the account"
4112 },
4113 {
4114 "acc_get_user_data", py_pjsua_acc_get_user_data, METH_VARARGS,
4115 "Get account's user data"
4116 },
4117 {
4118 "acc_modify", py_pjsua_acc_modify, METH_VARARGS,
4119 pjsua_acc_modify_doc
4120 },
4121 {
4122 "acc_set_online_status", py_pjsua_acc_set_online_status, METH_VARARGS,
4123 pjsua_acc_set_online_status_doc
4124 },
4125 {
4126 "acc_set_online_status2", py_pjsua_acc_set_online_status2, METH_VARARGS,
4127 pjsua_acc_set_online_status2_doc
4128 },
4129 {
4130 "acc_set_registration", py_pjsua_acc_set_registration, METH_VARARGS,
4131 pjsua_acc_set_registration_doc
4132 },
4133 {
4134 "acc_get_info", py_pjsua_acc_get_info, METH_VARARGS,
4135 pjsua_acc_get_info_doc
4136 },
4137 {
4138 "acc_pres_notify", py_pjsua_acc_pres_notify, METH_VARARGS,
4139 "Accept or reject subscription request"
4140 },
4141 {
4142 "enum_accs", py_pjsua_enum_accs, METH_VARARGS,
4143 pjsua_enum_accs_doc
4144 },
4145 {
4146 "acc_enum_info", py_pjsua_acc_enum_info, METH_VARARGS,
4147 pjsua_acc_enum_info_doc
4148 },
4149 {
4150 "acc_set_transport", py_pjsua_acc_set_transport, METH_VARARGS,
4151 "Lock transport to use the specified transport"
4152 },
4153 {
4154 "buddy_config_default", py_pjsua_buddy_config_default, METH_VARARGS,
4155 pjsua_buddy_config_default_doc
4156 },
4157 {
4158 "get_buddy_count", py_pjsua_get_buddy_count, METH_VARARGS,
4159 pjsua_get_buddy_count_doc
4160 },
4161 {
4162 "buddy_is_valid", py_pjsua_buddy_is_valid, METH_VARARGS,
4163 pjsua_buddy_is_valid_doc
4164 },
4165 {
4166 "enum_buddies", py_pjsua_enum_buddies, METH_VARARGS,
4167 pjsua_enum_buddies_doc
4168 },
4169 {
4170 "buddy_find", py_pjsua_buddy_find, METH_VARARGS,
4171 "Find buddy with the specified URI"
4172 },
4173 {
4174 "buddy_get_info", py_pjsua_buddy_get_info, METH_VARARGS,
4175 pjsua_buddy_get_info_doc
4176 },
4177 {
4178 "buddy_add", py_pjsua_buddy_add, METH_VARARGS,
4179 pjsua_buddy_add_doc
4180 },
4181 {
4182 "buddy_del", py_pjsua_buddy_del, METH_VARARGS,
4183 pjsua_buddy_del_doc
4184 },
4185 {
4186 "buddy_set_user_data", py_pjsua_buddy_set_user_data, METH_VARARGS,
4187 "Associate user data to the buddy object"
4188 },
4189 {
4190 "buddy_get_user_data", py_pjsua_buddy_get_user_data, METH_VARARGS,
4191 "Get buddy user data"
4192 },
4193 {
4194 "buddy_subscribe_pres", py_pjsua_buddy_subscribe_pres, METH_VARARGS,
4195 pjsua_buddy_subscribe_pres_doc
4196 },
4197 {
4198 "pres_dump", py_pjsua_pres_dump, METH_VARARGS,
4199 pjsua_pres_dump_doc
4200 },
4201 {
4202 "im_send", py_pjsua_im_send, METH_VARARGS,
4203 pjsua_im_send_doc
4204 },
4205 {
4206 "im_typing", py_pjsua_im_typing, METH_VARARGS,
4207 pjsua_im_typing_doc
4208 },
4209 {
4210 "conf_get_max_ports", py_pjsua_conf_get_max_ports, METH_VARARGS,
4211 pjsua_conf_get_max_ports_doc
4212 },
4213 {
4214 "conf_get_active_ports", py_pjsua_conf_get_active_ports, METH_VARARGS,
4215 pjsua_conf_get_active_ports_doc
4216 },
4217 {
4218 "enum_conf_ports", py_pjsua_enum_conf_ports, METH_VARARGS,
4219 pjsua_enum_conf_ports_doc
4220 },
4221 {
4222 "conf_get_port_info", py_pjsua_conf_get_port_info, METH_VARARGS,
4223 pjsua_conf_get_port_info_doc
4224 },
4225 {
4226 "conf_remove_port", py_pjsua_conf_remove_port, METH_VARARGS,
4227 pjsua_conf_remove_port_doc
4228 },
4229 {
4230 "conf_connect", py_pjsua_conf_connect, METH_VARARGS,
4231 pjsua_conf_connect_doc
4232 },
4233 {
4234 "conf_disconnect", py_pjsua_conf_disconnect, METH_VARARGS,
4235 pjsua_conf_disconnect_doc
4236 },
4237 {
4238 "conf_set_tx_level", py_pjsua_conf_set_tx_level, METH_VARARGS,
4239 "Adjust the signal level to be transmitted from the bridge to the"
4240 " specified port by making it louder or quieter"
4241 },
4242 {
4243 "conf_set_rx_level", py_pjsua_conf_set_rx_level, METH_VARARGS,
4244 "Adjust the signal level to be received from the specified port (to"
4245 " the bridge) by making it louder or quieter"
4246 },
4247 {
4248 "conf_get_signal_level", py_pjsua_conf_get_signal_level, METH_VARARGS,
4249 "Get last signal level transmitted to or received from the specified port"
4250 },
4251 {
4252 "player_create", py_pjsua_player_create, METH_VARARGS,
4253 pjsua_player_create_doc
4254 },
4255 {
4256 "playlist_create", py_pjsua_playlist_create, METH_VARARGS,
4257 "Create WAV playlist"
4258 },
4259 {
4260 "player_get_conf_port", py_pjsua_player_get_conf_port, METH_VARARGS,
4261 pjsua_player_get_conf_port_doc
4262 },
4263 {
4264 "player_set_pos", py_pjsua_player_set_pos, METH_VARARGS,
4265 pjsua_player_set_pos_doc
4266 },
4267 {
4268 "player_destroy", py_pjsua_player_destroy, METH_VARARGS,
4269 pjsua_player_destroy_doc
4270 },
4271 {
4272 "recorder_create", py_pjsua_recorder_create, METH_VARARGS,
4273 pjsua_recorder_create_doc
4274 },
4275 {
4276 "recorder_get_conf_port", py_pjsua_recorder_get_conf_port, METH_VARARGS,
4277 pjsua_recorder_get_conf_port_doc
4278 },
4279 {
4280 "recorder_destroy", py_pjsua_recorder_destroy, METH_VARARGS,
4281 pjsua_recorder_destroy_doc
4282 },
4283 {
4284 "enum_snd_devs", py_pjsua_enum_snd_devs, METH_VARARGS,
4285 pjsua_enum_snd_devs_doc
4286 },
4287 {
4288 "get_snd_dev", py_pjsua_get_snd_dev, METH_VARARGS,
4289 pjsua_get_snd_dev_doc
4290 },
4291 {
4292 "set_snd_dev", py_pjsua_set_snd_dev, METH_VARARGS,
4293 pjsua_set_snd_dev_doc
4294 },
4295 {
4296 "set_null_snd_dev", py_pjsua_set_null_snd_dev, METH_VARARGS,
4297 pjsua_set_null_snd_dev_doc
4298 },
4299 {
4300 "set_ec", py_pjsua_set_ec, METH_VARARGS,
4301 pjsua_set_ec_doc
4302 },
4303 {
4304 "get_ec_tail", py_pjsua_get_ec_tail, METH_VARARGS,
4305 pjsua_get_ec_tail_doc
4306 },
4307 {
4308 "enum_codecs", py_pjsua_enum_codecs, METH_VARARGS,
4309 pjsua_enum_codecs_doc
4310 },
4311 {
4312 "codec_set_priority", py_pjsua_codec_set_priority, METH_VARARGS,
4313 pjsua_codec_set_priority_doc
4314 },
4315 {
4316 "codec_get_param", py_pjsua_codec_get_param, METH_VARARGS,
4317 pjsua_codec_get_param_doc
4318 },
4319 {
4320 "codec_set_param", py_pjsua_codec_set_param, METH_VARARGS,
4321 pjsua_codec_set_param_doc
4322 },
4323 {
4324 "call_get_max_count", py_pjsua_call_get_max_count, METH_VARARGS,
4325 pjsua_call_get_max_count_doc
4326 },
4327 {
4328 "call_get_count", py_pjsua_call_get_count, METH_VARARGS,
4329 pjsua_call_get_count_doc
4330 },
4331 {
4332 "enum_calls", py_pjsua_enum_calls, METH_VARARGS,
4333 pjsua_enum_calls_doc
4334 },
4335 {
4336 "call_make_call", py_pjsua_call_make_call, METH_VARARGS,
4337 pjsua_call_make_call_doc
4338 },
4339 {
4340 "call_is_active", py_pjsua_call_is_active, METH_VARARGS,
4341 pjsua_call_is_active_doc
4342 },
4343 {
4344 "call_has_media", py_pjsua_call_has_media, METH_VARARGS,
4345 pjsua_call_has_media_doc
4346 },
4347 {
4348 "call_get_conf_port", py_pjsua_call_get_conf_port, METH_VARARGS,
4349 pjsua_call_get_conf_port_doc
4350 },
4351 {
4352 "call_get_info", py_pjsua_call_get_info, METH_VARARGS,
4353 pjsua_call_get_info_doc
4354 },
4355 {
4356 "call_set_user_data", py_pjsua_call_set_user_data, METH_VARARGS,
4357 pjsua_call_set_user_data_doc
4358 },
4359 {
4360 "call_get_user_data", py_pjsua_call_get_user_data, METH_VARARGS,
4361 pjsua_call_get_user_data_doc
4362 },
4363 {
4364 "call_answer", py_pjsua_call_answer, METH_VARARGS,
4365 pjsua_call_answer_doc
4366 },
4367 {
4368 "call_hangup", py_pjsua_call_hangup, METH_VARARGS,
4369 pjsua_call_hangup_doc
4370 },
4371 {
4372 "call_set_hold", py_pjsua_call_set_hold, METH_VARARGS,
4373 pjsua_call_set_hold_doc
4374 },
4375 {
4376 "call_reinvite", py_pjsua_call_reinvite, METH_VARARGS,
4377 pjsua_call_reinvite_doc
4378 },
4379 {
4380 "call_update", py_pjsua_call_update, METH_VARARGS,
4381 "Send UPDATE"
4382 },
4383 {
4384 "call_xfer", py_pjsua_call_xfer, METH_VARARGS,
4385 pjsua_call_xfer_doc
4386 },
4387 {
4388 "call_xfer_replaces", py_pjsua_call_xfer_replaces, METH_VARARGS,
4389 pjsua_call_xfer_replaces_doc
4390 },
4391 {
4392 "call_dial_dtmf", py_pjsua_call_dial_dtmf, METH_VARARGS,
4393 pjsua_call_dial_dtmf_doc
4394 },
4395 {
4396 "call_send_im", py_pjsua_call_send_im, METH_VARARGS,
4397 pjsua_call_send_im_doc
4398 },
4399 {
4400 "call_send_typing_ind", py_pjsua_call_send_typing_ind, METH_VARARGS,
4401 pjsua_call_send_typing_ind_doc
4402 },
4403 {
4404 "call_hangup_all", py_pjsua_call_hangup_all, METH_VARARGS,
4405 pjsua_call_hangup_all_doc
4406 },
4407 {
4408 "call_dump", py_pjsua_call_dump, METH_VARARGS,
4409 pjsua_call_dump_doc
4410 },
4411 {
4412 "call_send_request", py_pjsua_call_send_request, METH_VARARGS,
4413 "Send arbitrary request"
4414 },
4415 {
4416 "dump", py_pjsua_dump, METH_VARARGS, "Dump application state"
4417 },
4418 {
4419 "strerror", py_pj_strerror, METH_VARARGS, "Get error message"
4420 },
4421 {
4422 "parse_simple_uri", py_pj_parse_simple_sip, METH_VARARGS, "Parse URI"
4423 },
4424
4425
4426 {NULL, NULL} /* end of function list */
4427};
4428
4429
4430
4431/*
4432 * Mapping C structs from and to Python objects & initializing object
4433 */
4434DL_EXPORT(void)
4435init_pjsua(void)
4436{
4437 PyObject* m = NULL;
4438#define ADD_CONSTANT(mod,name) PyModule_AddIntConstant(mod,#name,name)
4439
4440
4441 PyEval_InitThreads();
4442
4443 if (PyType_Ready(&PyTyp_pjsua_callback) < 0)
4444 return;
4445 if (PyType_Ready(&PyTyp_pjsua_config) < 0)
4446 return;
4447 if (PyType_Ready(&PyTyp_pjsua_logging_config) < 0)
4448 return;
4449 if (PyType_Ready(&PyTyp_pjsua_msg_data) < 0)
4450 return;
4451 PyTyp_pjsua_media_config.tp_new = PyType_GenericNew;
4452 if (PyType_Ready(&PyTyp_pjsua_media_config) < 0)
4453 return;
4454 PyTyp_pjsip_cred_info.tp_new = PyType_GenericNew;
4455 if (PyType_Ready(&PyTyp_pjsip_cred_info) < 0)
4456 return;
4457 PyTyp_pjsip_rx_data.tp_new = PyType_GenericNew;
4458 if (PyType_Ready(&PyTyp_pjsip_rx_data) < 0)
4459 return;
4460
4461 /* LIB TRANSPORT */
4462
4463 if (PyType_Ready(&PyTyp_pjsua_transport_config) < 0)
4464 return;
4465
4466 if (PyType_Ready(&PyTyp_pjsua_transport_info) < 0)
4467 return;
4468
4469 /* END OF LIB TRANSPORT */
4470
4471 /* LIB ACCOUNT */
4472
4473
4474 if (PyType_Ready(&PyTyp_pjsua_acc_config) < 0)
4475 return;
4476 if (PyType_Ready(&PyTyp_pjsua_acc_info) < 0)
4477 return;
4478
4479 /* END OF LIB ACCOUNT */
4480
4481 /* LIB BUDDY */
4482
4483 if (PyType_Ready(&PyTyp_pjsua_buddy_config) < 0)
4484 return;
4485 if (PyType_Ready(&PyTyp_pjsua_buddy_info) < 0)
4486 return;
4487
4488 /* END OF LIB BUDDY */
4489
4490 /* LIB MEDIA */
4491
4492 if (PyType_Ready(&PyTyp_pjsua_codec_info) < 0)
4493 return;
4494
4495 if (PyType_Ready(&PyTyp_pjsua_conf_port_info) < 0)
4496 return;
4497
4498 if (PyType_Ready(&PyTyp_pjmedia_snd_dev_info) < 0)
4499 return;
4500
4501 PyTyp_pjmedia_codec_param_info.tp_new = PyType_GenericNew;
4502 if (PyType_Ready(&PyTyp_pjmedia_codec_param_info) < 0)
4503 return;
4504 PyTyp_pjmedia_codec_param_setting.tp_new = PyType_GenericNew;
4505 if (PyType_Ready(&PyTyp_pjmedia_codec_param_setting) < 0)
4506 return;
4507
4508 if (PyType_Ready(&PyTyp_pjmedia_codec_param) < 0)
4509 return;
4510
4511 /* END OF LIB MEDIA */
4512
4513 /* LIB CALL */
4514
4515 if (PyType_Ready(&PyTyp_pjsua_call_info) < 0)
4516 return;
4517
4518 /* END OF LIB CALL */
4519
4520 m = Py_InitModule3(
4521 "_pjsua", py_pjsua_methods, "PJSUA-lib module for python"
4522 );
4523
4524 Py_INCREF(&PyTyp_pjsua_callback);
4525 PyModule_AddObject(m, "Callback", (PyObject *)&PyTyp_pjsua_callback);
4526
4527 Py_INCREF(&PyTyp_pjsua_config);
4528 PyModule_AddObject(m, "Config", (PyObject *)&PyTyp_pjsua_config);
4529
4530 Py_INCREF(&PyTyp_pjsua_media_config);
4531 PyModule_AddObject(m, "Media_Config", (PyObject *)&PyTyp_pjsua_media_config);
4532
4533 Py_INCREF(&PyTyp_pjsua_logging_config);
4534 PyModule_AddObject(m, "Logging_Config", (PyObject *)&PyTyp_pjsua_logging_config);
4535
4536 Py_INCREF(&PyTyp_pjsua_msg_data);
4537 PyModule_AddObject(m, "Msg_Data", (PyObject *)&PyTyp_pjsua_msg_data);
4538
4539 Py_INCREF(&PyTyp_pjsip_cred_info);
4540 PyModule_AddObject(m, "Pjsip_Cred_Info",
4541 (PyObject *)&PyTyp_pjsip_cred_info
4542 );
4543
4544 Py_INCREF(&PyTyp_pjsip_rx_data);
4545 PyModule_AddObject(m, "Pjsip_Rx_Data",
4546 (PyObject *)&PyTyp_pjsip_rx_data
4547 );
4548
4549 /* LIB TRANSPORT */
4550
4551 Py_INCREF(&PyTyp_pjsua_transport_config);
4552 PyModule_AddObject
4553 (m, "Transport_Config", (PyObject *)&PyTyp_pjsua_transport_config);
4554
4555 Py_INCREF(&PyTyp_pjsua_transport_info);
4556 PyModule_AddObject(m, "Transport_Info", (PyObject *)&PyTyp_pjsua_transport_info);
4557
4558
4559 /* END OF LIB TRANSPORT */
4560
4561 /* LIB ACCOUNT */
4562
4563
4564 Py_INCREF(&PyTyp_pjsua_acc_config);
4565 PyModule_AddObject(m, "Acc_Config", (PyObject *)&PyTyp_pjsua_acc_config);
4566 Py_INCREF(&PyTyp_pjsua_acc_info);
4567 PyModule_AddObject(m, "Acc_Info", (PyObject *)&PyTyp_pjsua_acc_info);
4568
4569 /* END OF LIB ACCOUNT */
4570
4571 /* LIB BUDDY */
4572
4573 Py_INCREF(&PyTyp_pjsua_buddy_config);
4574 PyModule_AddObject(m, "Buddy_Config", (PyObject *)&PyTyp_pjsua_buddy_config);
4575 Py_INCREF(&PyTyp_pjsua_buddy_info);
4576 PyModule_AddObject(m, "Buddy_Info", (PyObject *)&PyTyp_pjsua_buddy_info);
4577
4578 /* END OF LIB BUDDY */
4579
4580 /* LIB MEDIA */
4581
4582 Py_INCREF(&PyTyp_pjsua_codec_info);
4583 PyModule_AddObject(m, "Codec_Info", (PyObject *)&PyTyp_pjsua_codec_info);
4584 Py_INCREF(&PyTyp_pjsua_conf_port_info);
4585 PyModule_AddObject(m, "Conf_Port_Info", (PyObject *)&PyTyp_pjsua_conf_port_info);
4586 Py_INCREF(&PyTyp_pjmedia_snd_dev_info);
4587 PyModule_AddObject(m, "PJMedia_Snd_Dev_Info",
4588 (PyObject *)&PyTyp_pjmedia_snd_dev_info);
4589 Py_INCREF(&PyTyp_pjmedia_codec_param_info);
4590 PyModule_AddObject(m, "PJMedia_Codec_Param_Info",
4591 (PyObject *)&PyTyp_pjmedia_codec_param_info);
4592 Py_INCREF(&PyTyp_pjmedia_codec_param_setting);
4593 PyModule_AddObject(m, "PJMedia_Codec_Param_Setting",
4594 (PyObject *)&PyTyp_pjmedia_codec_param_setting);
4595 Py_INCREF(&PyTyp_pjmedia_codec_param);
4596 PyModule_AddObject(m, "PJMedia_Codec_Param",
4597 (PyObject *)&PyTyp_pjmedia_codec_param);
4598
4599 /* END OF LIB MEDIA */
4600
4601 /* LIB CALL */
4602
4603 Py_INCREF(&PyTyp_pjsua_call_info);
4604 PyModule_AddObject(m, "Call_Info", (PyObject *)&PyTyp_pjsua_call_info);
4605
4606 /* END OF LIB CALL */
4607
4608
4609 /*
4610 * Add various constants.
4611 */
4612 /* Skip it.. */
4613
4614#undef ADD_CONSTANT
4615}