blob: 6590dd5c59e53c5a87188cfa5429f1103f87eafb [file] [log] [blame]
Benny Prijono9c461142008-07-10 22:41:20 +00001/* $Id$ */
2/*
3 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include "_pjsua.h"
20
21#define THIS_FILE "main.c"
22#define POOL_SIZE 4000
23#define SND_DEV_NUM 64
24#define SND_NAME_LEN 64
25
26/* LIB BASE */
27
28static PyObject* obj_log_cb;
29static long thread_id;
30
31#define ENTER_PYTHON() PyGILState_STATE state = PyGILState_Ensure()
32#define LEAVE_PYTHON() PyGILState_Release(state)
33
34/*
35 * cb_log_cb
36 * declares method for reconfiguring logging process for callback struct
37 */
38static void cb_log_cb(int level, const char *data, int len)
39{
40
41 /* Ignore if this callback is called from alien thread context,
42 * or otherwise it will crash Python.
43 */
44 if (pj_thread_local_get(thread_id) == 0)
45 return;
46
47 if (PyCallable_Check(obj_log_cb))
48 {
49 ENTER_PYTHON();
50
51 PyObject_CallFunctionObjArgs(
52 obj_log_cb, Py_BuildValue("i",level),
53 PyString_FromString(data), Py_BuildValue("i",len), NULL
54 );
55
56 LEAVE_PYTHON();
57 }
58}
59
60
61
62/*
63 * The global callback object.
64 */
65static PyObj_pjsua_callback * g_obj_callback;
66
67
68/*
69 * cb_on_call_state
70 * declares method on_call_state for callback struct
71 */
72static void cb_on_call_state(pjsua_call_id call_id, pjsip_event *e)
73{
74 if (PyCallable_Check(g_obj_callback->on_call_state))
75 {
76 PyObj_pjsip_event * obj;
77
78 ENTER_PYTHON();
79
80 obj = (PyObj_pjsip_event *)PyType_GenericNew(&PyTyp_pjsip_event,
81 NULL, NULL);
82
83 obj->event = e;
84
85 PyObject_CallFunctionObjArgs(
86 g_obj_callback->on_call_state,
87 Py_BuildValue("i",call_id),
88 obj,
89 NULL
90 );
91
92 LEAVE_PYTHON();
93 }
94}
95
96
97/*
98 * cb_on_incoming_call
99 * declares method on_incoming_call for callback struct
100 */
101static void cb_on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
102 pjsip_rx_data *rdata)
103{
104 if (PyCallable_Check(g_obj_callback->on_incoming_call))
105 {
106 PyObj_pjsip_rx_data * obj;
107
108 ENTER_PYTHON();
109
110 obj = (PyObj_pjsip_rx_data *)PyType_GenericNew(&PyTyp_pjsip_rx_data,
111 NULL, NULL);
112 obj->rdata = rdata;
113
114 PyObject_CallFunctionObjArgs(
115 g_obj_callback->on_incoming_call,
116 Py_BuildValue("i",acc_id),
117 Py_BuildValue("i",call_id),
118 obj,
119 NULL
120 );
121
122 LEAVE_PYTHON();
123 }
124}
125
126
127/*
128 * cb_on_call_media_state
129 * declares method on_call_media_state for callback struct
130 */
131static void cb_on_call_media_state(pjsua_call_id call_id)
132{
133 if (PyCallable_Check(g_obj_callback->on_call_media_state))
134 {
135 ENTER_PYTHON();
136
137 PyObject_CallFunction(
138 g_obj_callback->on_call_media_state,
139 "i",
140 call_id,
141 NULL
142 );
143
144 LEAVE_PYTHON();
145 }
146}
147
148
149/*
150 * cb_on_dtmf_digit()
151 * Callback from PJSUA-LIB on receiving DTMF digit
152 */
153static void cb_on_dtmf_digit(pjsua_call_id call_id, int digit)
154{
155 if (PyCallable_Check(g_obj_callback->on_dtmf_digit))
156 {
157 char digit_str[10];
158
159 ENTER_PYTHON();
160
161 pj_ansi_snprintf(digit_str, sizeof(digit_str), "%c", digit);
162
163 PyObject_CallFunctionObjArgs(
164 g_obj_callback->on_dtmf_digit,
165 Py_BuildValue("i",call_id),
166 PyString_FromString(digit_str),
167 NULL
168 );
169
170 LEAVE_PYTHON();
171 }
172}
173
174
175/*
176 * Notify application on call being transfered.
177 * !modified @061206
178 */
179static void cb_on_call_transfer_request(pjsua_call_id call_id,
180 const pj_str_t *dst,
181 pjsip_status_code *code)
182{
183 if (PyCallable_Check(g_obj_callback->on_call_transfer_request))
184 {
185 PyObject * ret;
186 int cd;
187
188 ENTER_PYTHON();
189
190 ret = PyObject_CallFunctionObjArgs(
191 g_obj_callback->on_call_transfer_request,
192 Py_BuildValue("i",call_id),
193 PyString_FromStringAndSize(dst->ptr, dst->slen),
194 Py_BuildValue("i",*code),
195 NULL
196 );
197 if (ret != NULL) {
198 if (ret != Py_None) {
199 if (PyArg_Parse(ret,"i",&cd)) {
200 *code = cd;
201 }
202 }
203 }
204
205 LEAVE_PYTHON();
206 }
207}
208
209
210/*
211 * Notify application of the status of previously sent call
212 * transfer request. Application can monitor the status of the
213 * call transfer request, for example to decide whether to
214 * terminate existing call.
215 * !modified @061206
216 */
217static void cb_on_call_transfer_status( pjsua_call_id call_id,
218 int status_code,
219 const pj_str_t *status_text,
220 pj_bool_t final,
221 pj_bool_t *p_cont)
222{
223 if (PyCallable_Check(g_obj_callback->on_call_transfer_status))
224 {
225 PyObject * ret;
226 int cnt;
227
228 ENTER_PYTHON();
229
230 ret = PyObject_CallFunctionObjArgs(
231 g_obj_callback->on_call_transfer_status,
232 Py_BuildValue("i",call_id),
233 Py_BuildValue("i",status_code),
234 PyString_FromStringAndSize(status_text->ptr, status_text->slen),
235 Py_BuildValue("i",final),
236 Py_BuildValue("i",*p_cont),
237 NULL
238 );
239 if (ret != NULL) {
240 if (ret != Py_None) {
241 if (PyArg_Parse(ret,"i",&cnt)) {
242 *p_cont = cnt;
243 }
244 }
245 }
246
247 LEAVE_PYTHON();
248 }
249}
250
251
252/*
253 * Notify application about incoming INVITE with Replaces header.
254 * Application may reject the request by setting non-2xx code.
255 * !modified @061206
256 */
257static void cb_on_call_replace_request( pjsua_call_id call_id,
258 pjsip_rx_data *rdata,
259 int *st_code,
260 pj_str_t *st_text)
261{
262 if (PyCallable_Check(g_obj_callback->on_call_replace_request))
263 {
264 PyObject * ret;
265 PyObject * txt;
266 int cd;
267 PyObj_pjsip_rx_data * obj;
268
269 ENTER_PYTHON();
270
271 obj = (PyObj_pjsip_rx_data *)PyType_GenericNew(&PyTyp_pjsip_rx_data,
272 NULL, NULL);
273 obj->rdata = rdata;
274
275 ret = PyObject_CallFunctionObjArgs(
276 g_obj_callback->on_call_replace_request,
277 Py_BuildValue("i",call_id),
278 obj,
279 Py_BuildValue("i",*st_code),
280 PyString_FromStringAndSize(st_text->ptr, st_text->slen),
281 NULL
282 );
283 if (ret != NULL) {
284 if (ret != Py_None) {
285 if (PyArg_ParseTuple(ret,"iO",&cd, &txt)) {
286 *st_code = cd;
287 st_text->ptr = PyString_AsString(txt);
288 st_text->slen = strlen(PyString_AsString(txt));
289 }
290 }
291 }
292
293 LEAVE_PYTHON();
294 }
295}
296
297
298/*
299 * Notify application that an existing call has been replaced with
300 * a new call. This happens when PJSUA-API receives incoming INVITE
301 * request with Replaces header.
302 */
303static void cb_on_call_replaced(pjsua_call_id old_call_id,
304 pjsua_call_id new_call_id)
305{
306 if (PyCallable_Check(g_obj_callback->on_call_replaced))
307 {
308 ENTER_PYTHON();
309
310 PyObject_CallFunctionObjArgs(
311 g_obj_callback->on_call_replaced,
312 Py_BuildValue("i",old_call_id),
313 Py_BuildValue("i",new_call_id),
314 NULL
315 );
316
317 LEAVE_PYTHON();
318 }
319}
320
321
322/*
323 * cb_on_reg_state
324 * declares method on_reg_state for callback struct
325 */
326static void cb_on_reg_state(pjsua_acc_id acc_id)
327{
328 if (PyCallable_Check(g_obj_callback->on_reg_state))
329 {
330 ENTER_PYTHON();
331
332 PyObject_CallFunction(
333 g_obj_callback->on_reg_state,
334 "i",
335 acc_id,
336 NULL
337 );
338
339 LEAVE_PYTHON();
340 }
341}
342
Benny Prijonoe6787ec2008-07-18 23:00:56 +0000343/*
344 * cb_on_incoming_subscribe
345 */
346static void cb_on_incoming_subscribe( pjsua_acc_id acc_id,
347 pjsua_srv_pres *srv_pres,
348 pjsua_buddy_id buddy_id,
349 const pj_str_t *from,
350 pjsip_rx_data *rdata,
351 pjsip_status_code *code,
352 pj_str_t *reason,
353 pjsua_msg_data *msg_data)
354{
355 static char reason_buf[64];
356
357 PJ_UNUSED_ARG(rdata);
358 PJ_UNUSED_ARG(msg_data);
359
360 if (PyCallable_Check(g_obj_callback->on_incoming_subscribe))
361 {
362 PyObject *ret;
363
364 ENTER_PYTHON();
365
366 ret = PyObject_CallFunctionObjArgs(
367 g_obj_callback->on_incoming_subscribe,
368 Py_BuildValue("i", acc_id),
369 Py_BuildValue("i", buddy_id),
370 PyString_FromStringAndSize(from->ptr, from->slen),
371 PyLong_FromLong((long)srv_pres),
372 NULL
373 );
374
375 if (ret && PyTuple_Check(ret)) {
376 if (PyTuple_Size(ret) >= 1)
377 *code = (int)PyInt_AsLong(PyTuple_GetItem(ret, 0));
378 if (PyTuple_Size(ret) >= 2) {
379 if (PyTuple_GetItem(ret, 1) != Py_None) {
380 pj_str_t tmp;
381 tmp = PyString_to_pj_str(PyTuple_GetItem(ret, 1));
382 reason->ptr = reason_buf;
383 pj_strncpy(reason, &tmp, sizeof(reason_buf));
384 } else {
385 }
386 }
387
388 } else if (ret) {
389 Py_XDECREF(ret);
390 }
391
392 LEAVE_PYTHON();
393 }
394}
Benny Prijono9c461142008-07-10 22:41:20 +0000395
396/*
397 * cb_on_buddy_state
398 * declares method on_buddy state for callback struct
399 */
400static void cb_on_buddy_state(pjsua_buddy_id buddy_id)
401{
402 if (PyCallable_Check(g_obj_callback->on_buddy_state))
403 {
404 ENTER_PYTHON();
405
406 PyObject_CallFunction(
407 g_obj_callback->on_buddy_state,
408 "i",
409 buddy_id,
410 NULL
411 );
412
413 LEAVE_PYTHON();
414 }
415}
416
417/*
418 * cb_on_pager
419 * declares method on_pager for callback struct
420 */
421static void cb_on_pager(pjsua_call_id call_id, const pj_str_t *from,
422 const pj_str_t *to, const pj_str_t *contact,
423 const pj_str_t *mime_type, const pj_str_t *body,
424 pjsip_rx_data *rdata, pjsua_acc_id acc_id)
425{
Benny Prijonoe6787ec2008-07-18 23:00:56 +0000426 PJ_UNUSED_ARG(rdata);
427
Benny Prijono9c461142008-07-10 22:41:20 +0000428 if (PyCallable_Check(g_obj_callback->on_pager))
429 {
430 ENTER_PYTHON();
431
432 PyObject_CallFunctionObjArgs(
433 g_obj_callback->on_pager,
434 Py_BuildValue("i",call_id),
435 PyString_FromStringAndSize(from->ptr, from->slen),
436 PyString_FromStringAndSize(to->ptr, to->slen),
437 PyString_FromStringAndSize(contact->ptr, contact->slen),
438 PyString_FromStringAndSize(mime_type->ptr, mime_type->slen),
439 PyString_FromStringAndSize(body->ptr, body->slen),
440 Py_BuildValue("i",acc_id),
441 NULL
442 );
443
444 LEAVE_PYTHON();
445 }
446}
447
448
449/*
450 * cb_on_pager_status
451 * declares method on_pager_status for callback struct
452 */
453static void cb_on_pager_status(pjsua_call_id call_id, const pj_str_t *to,
454 const pj_str_t *body, void *user_data,
455 pjsip_status_code status,
456 const pj_str_t *reason,
457 pjsip_tx_data *tdata,
458 pjsip_rx_data *rdata,
459 pjsua_acc_id acc_id)
460{
461 if (PyCallable_Check(g_obj_callback->on_pager))
462 {
463 PyObject * obj_user_data;
464
465 ENTER_PYTHON();
466
467 PJ_UNUSED_ARG(tdata);
468 PJ_UNUSED_ARG(rdata);
469
470 obj_user_data = Py_BuildValue("i", user_data);
471
472 PyObject_CallFunctionObjArgs(
473 g_obj_callback->on_pager_status,
474 Py_BuildValue("i",call_id),
475 PyString_FromStringAndSize(to->ptr, to->slen),
476 PyString_FromStringAndSize(body->ptr, body->slen),
477 obj_user_data,
478 Py_BuildValue("i",status),
479 PyString_FromStringAndSize(reason->ptr,reason->slen),
480 Py_BuildValue("i",acc_id),
481 NULL
482 );
483
484 LEAVE_PYTHON();
485 }
486}
487
488
489/*
490 * cb_on_typing
491 * declares method on_typing for callback struct
492 */
493static void cb_on_typing(pjsua_call_id call_id, const pj_str_t *from,
494 const pj_str_t *to, const pj_str_t *contact,
495 pj_bool_t is_typing, pjsip_rx_data *rdata,
496 pjsua_acc_id acc_id)
497{
498 if (PyCallable_Check(g_obj_callback->on_typing))
499 {
500 ENTER_PYTHON();
501
502 PJ_UNUSED_ARG(rdata);
503
504 PyObject_CallFunctionObjArgs(
505 g_obj_callback->on_typing,Py_BuildValue("i",call_id),
506 PyString_FromStringAndSize(from->ptr, from->slen),
507 PyString_FromStringAndSize(to->ptr, to->slen),
508 PyString_FromStringAndSize(contact->ptr, contact->slen),
509 Py_BuildValue("i",is_typing),
510 Py_BuildValue("i",acc_id),
511 NULL
512 );
513
514 LEAVE_PYTHON();
515 }
516}
517
518
519
520/*
521 * translate_hdr
522 * internal function
523 * translate from hdr_list to pjsip_generic_string_hdr
524 */
525void translate_hdr(pj_pool_t *pool, pjsip_hdr *hdr, PyObject *py_hdr_list)
526{
527 pj_list_init(hdr);
528
529 if (PyList_Check(py_hdr_list)) {
530 int i;
531
532 for (i = 0; i < PyList_Size(py_hdr_list); i++)
533 {
534 pj_str_t hname, hvalue;
535 pjsip_generic_string_hdr * new_hdr;
536 PyObject * tuple = PyList_GetItem(py_hdr_list, i);
537
538 if (PyTuple_Check(tuple))
539 {
540 hname.ptr = PyString_AsString(PyTuple_GetItem(tuple,0));
541 hname.slen = strlen(PyString_AsString
542 (PyTuple_GetItem(tuple,0)));
543 hvalue.ptr = PyString_AsString(PyTuple_GetItem(tuple,1));
544 hvalue.slen = strlen(PyString_AsString
545 (PyTuple_GetItem(tuple,1)));
546 } else {
547 hname.ptr = "";
548 hname.slen = 0;
549 hvalue.ptr = "";
550 hvalue.slen = 0;
551 }
552 new_hdr = pjsip_generic_string_hdr_create(pool, &hname, &hvalue);
553 pj_list_push_back((pj_list_type *)hdr, (pj_list_type *)new_hdr);
554 }
555 }
556}
557
558/*
559 * translate_hdr_rev
560 * internal function
561 * translate from pjsip_generic_string_hdr to hdr_list
562 */
563
564void translate_hdr_rev(pjsip_generic_string_hdr *hdr, PyObject *py_hdr_list)
565{
566 int i;
567 int len;
568 pjsip_generic_string_hdr * p_hdr;
569
570 len = pj_list_size(hdr);
571
572 if (len > 0)
573 {
574 p_hdr = hdr;
575 Py_XDECREF(py_hdr_list);
576 py_hdr_list = PyList_New(len);
577
578 for (i = 0; i < len && p_hdr != NULL; i++)
579 {
580 PyObject * tuple;
581 PyObject * str;
582
583 tuple = PyTuple_New(2);
584
585 str = PyString_FromStringAndSize(p_hdr->name.ptr, p_hdr->name.slen);
586 PyTuple_SetItem(tuple, 0, str);
587 str = PyString_FromStringAndSize
588 (hdr->hvalue.ptr, p_hdr->hvalue.slen);
589 PyTuple_SetItem(tuple, 1, str);
590 PyList_SetItem(py_hdr_list, i, tuple);
591 p_hdr = p_hdr->next;
592 }
593 }
594
595
596}
597
598/*
599 * py_pjsua_thread_register
600 * !added @ 061206
601 */
602static PyObject *py_pjsua_thread_register(PyObject *pSelf, PyObject *pArgs)
603{
604
605 pj_status_t status;
606 const char *name;
607 PyObject *py_desc;
608 pj_thread_t *thread;
609 void *thread_desc;
610#if 0
611 int size;
612 int i;
613 int *td;
614#endif
615
616 PJ_UNUSED_ARG(pSelf);
617
618 if (!PyArg_ParseTuple(pArgs, "sO", &name, &py_desc))
619 {
620 return NULL;
621 }
622#if 0
623 size = PyList_Size(py_desc);
624 td = (int *)malloc(size * sizeof(int));
625 for (i = 0; i < size; i++)
626 {
627 if (!PyArg_Parse(PyList_GetItem(py_desc,i),"i", td[i]))
628 {
629 return NULL;
630 }
631 }
632 thread_desc = td;
633#else
634 thread_desc = malloc(sizeof(pj_thread_desc));
635#endif
636 status = pj_thread_register(name, thread_desc, &thread);
637
638 if (status == PJ_SUCCESS)
639 status = pj_thread_local_set(thread_id, (void*)1);
640 return Py_BuildValue("i",status);
641}
642
643/*
644 * py_pjsua_logging_config_default
645 * !modified @ 051206
646 */
647static PyObject *py_pjsua_logging_config_default(PyObject *pSelf,
648 PyObject *pArgs)
649{
650 PyObj_pjsua_logging_config *obj;
651 pjsua_logging_config cfg;
652
653 PJ_UNUSED_ARG(pSelf);
654
655 if (!PyArg_ParseTuple(pArgs, ""))
656 {
657 return NULL;
658 }
659
660 pjsua_logging_config_default(&cfg);
661 obj = (PyObj_pjsua_logging_config *) PyObj_pjsua_logging_config_new
662 (&PyTyp_pjsua_logging_config,NULL,NULL);
663 PyObj_pjsua_logging_config_import(obj, &cfg);
664
665 return (PyObject *)obj;
666}
667
668
669/*
670 * py_pjsua_config_default
671 * !modified @ 051206
672 */
673static PyObject *py_pjsua_config_default(PyObject *pSelf, PyObject *pArgs)
674{
675 PyObj_pjsua_config *obj;
676 pjsua_config cfg;
677
678 PJ_UNUSED_ARG(pSelf);
679
680 if (!PyArg_ParseTuple(pArgs, ""))
681 {
682 return NULL;
683 }
684 pjsua_config_default(&cfg);
685 obj = (PyObj_pjsua_config *) PyObj_pjsua_config_new(&PyTyp_pjsua_config, NULL, NULL);
686 PyObj_pjsua_config_import(obj, &cfg);
687
688 return (PyObject *)obj;
689}
690
691
692/*
693 * py_pjsua_media_config_default
694 * !modified @ 051206
695 */
696static PyObject * py_pjsua_media_config_default(PyObject *pSelf,
697 PyObject *pArgs)
698{
699 PyObj_pjsua_media_config *obj;
700 pjsua_media_config cfg;
701
702 PJ_UNUSED_ARG(pSelf);
703
704 if (!PyArg_ParseTuple(pArgs, ""))
705 {
706 return NULL;
707 }
708 pjsua_media_config_default(&cfg);
709 obj = (PyObj_pjsua_media_config *)
710 PyType_GenericNew(&PyTyp_pjsua_media_config, NULL, NULL);
711 PyObj_pjsua_media_config_import(obj, &cfg);
712 return (PyObject *)obj;
713}
714
715
716/*
717 * py_pjsua_msg_data_init
718 * !modified @ 051206
719 */
720static PyObject *py_pjsua_msg_data_init(PyObject *pSelf, PyObject *pArgs)
721{
722 PyObj_pjsua_msg_data *obj;
723 pjsua_msg_data msg;
724
725 PJ_UNUSED_ARG(pSelf);
726
727 if (!PyArg_ParseTuple(pArgs, ""))
728 {
729 return NULL;
730 }
731 pjsua_msg_data_init(&msg);
732 obj = (PyObj_pjsua_msg_data *)PyObj_pjsua_msg_data_new(&PyTyp_pjsua_msg_data, NULL, NULL);
733 Py_XDECREF(obj->content_type);
734 obj->content_type = PyString_FromStringAndSize(
735 msg.content_type.ptr, msg.content_type.slen
736 );
737 Py_XDECREF(obj->msg_body);
738 obj->msg_body = PyString_FromStringAndSize(
739 msg.msg_body.ptr, msg.msg_body.slen
740 );
741
742 translate_hdr_rev((pjsip_generic_string_hdr *)&msg.hdr_list,obj->hdr_list);
743
744 return (PyObject *)obj;
745}
746
747
748/*
749 * py_pjsua_reconfigure_logging
750 */
751static PyObject *py_pjsua_reconfigure_logging(PyObject *pSelf, PyObject *pArgs)
752{
753 PyObject * logObj;
754 PyObj_pjsua_logging_config *log;
755 pjsua_logging_config cfg;
756 pj_status_t status;
757
758 PJ_UNUSED_ARG(pSelf);
759
760 if (!PyArg_ParseTuple(pArgs, "O", &logObj))
761 {
762 return NULL;
763 }
764 if (logObj != Py_None)
765 {
766 log = (PyObj_pjsua_logging_config *)logObj;
767 cfg.msg_logging = log->msg_logging;
768 cfg.level = log->level;
769 cfg.console_level = log->console_level;
770 cfg.decor = log->decor;
771 cfg.log_filename.ptr = PyString_AsString(log->log_filename);
772 cfg.log_filename.slen = strlen(cfg.log_filename.ptr);
773 Py_XDECREF(obj_log_cb);
774 obj_log_cb = log->cb;
775 Py_INCREF(obj_log_cb);
776 cfg.cb = &cb_log_cb;
777 status = pjsua_reconfigure_logging(&cfg);
778 } else {
779 status = pjsua_reconfigure_logging(NULL);
780 }
781 return Py_BuildValue("i",status);
782}
783
784
785/*
786 * py_pjsua_pool_create
787 */
788static PyObject *py_pjsua_pool_create(PyObject *pSelf, PyObject *pArgs)
789{
790 pj_size_t init_size;
791 pj_size_t increment;
792 const char * name;
793 pj_pool_t *p;
794 PyObj_pj_pool *pool;
795
796 PJ_UNUSED_ARG(pSelf);
797
798 if (!PyArg_ParseTuple(pArgs, "sII", &name, &init_size, &increment))
799 {
800 return NULL;
801 }
802
803 p = pjsua_pool_create(name, init_size, increment);
804 pool = (PyObj_pj_pool *)PyType_GenericNew(&PyTyp_pj_pool_t, NULL, NULL);
805 pool->pool = p;
806 return (PyObject *)pool;
807
808}
809
810
811/*
812 * py_pjsua_get_pjsip_endpt
813 */
814static PyObject *py_pjsua_get_pjsip_endpt(PyObject *pSelf, PyObject *pArgs)
815{
816 PyObj_pjsip_endpoint *endpt;
817 pjsip_endpoint *e;
818
819 PJ_UNUSED_ARG(pSelf);
820
821 if (!PyArg_ParseTuple(pArgs, ""))
822 {
823 return NULL;
824 }
825 e = pjsua_get_pjsip_endpt();
826 endpt = (PyObj_pjsip_endpoint *)PyType_GenericNew(
827 &PyTyp_pjsip_endpoint, NULL, NULL
828 );
829 endpt->endpt = e;
830 return (PyObject *)endpt;
831}
832
833
834/*
835 * py_pjsua_get_pjmedia_endpt
836 */
837static PyObject *py_pjsua_get_pjmedia_endpt(PyObject *pSelf, PyObject *pArgs)
838{
839 PyObj_pjmedia_endpt *endpt;
840 pjmedia_endpt *e;
841
842 PJ_UNUSED_ARG(pSelf);
843
844 if (!PyArg_ParseTuple(pArgs, ""))
845 {
846 return NULL;
847 }
848 e = pjsua_get_pjmedia_endpt();
849 endpt = (PyObj_pjmedia_endpt *)PyType_GenericNew(
850 &PyTyp_pjmedia_endpt, NULL, NULL
851 );
852 endpt->endpt = e;
853 return (PyObject *)endpt;
854}
855
856
857/*
858 * py_pjsua_get_pool_factory
859 */
860static PyObject *py_pjsua_get_pool_factory(PyObject *pSelf, PyObject *pArgs)
861{
862 PyObj_pj_pool_factory *pool;
863 pj_pool_factory *p;
864
865 PJ_UNUSED_ARG(pSelf);
866
867 if (!PyArg_ParseTuple(pArgs, ""))
868 {
869 return NULL;
870 }
871 p = pjsua_get_pool_factory();
872 pool = (PyObj_pj_pool_factory *)PyType_GenericNew(
873 &PyTyp_pj_pool_factory, NULL, NULL
874 );
875 pool->pool_fact = p;
876 return (PyObject *)pool;
877}
878
879
880/*
881 * py_pjsua_perror
882 */
883static PyObject *py_pjsua_perror(PyObject *pSelf, PyObject *pArgs)
884{
885 const char *sender;
886 const char *title;
887 pj_status_t status;
888
889 PJ_UNUSED_ARG(pSelf);
890
891 if (!PyArg_ParseTuple(pArgs, "ssi", &sender, &title, &status))
892 {
893 return NULL;
894 }
895
896 pjsua_perror(sender, title, status);
897 Py_INCREF(Py_None);
898 return Py_None;
899}
900
901
902/*
903 * py_pjsua_create
904 */
905static PyObject *py_pjsua_create(PyObject *pSelf, PyObject *pArgs)
906{
907 pj_status_t status;
908
909 PJ_UNUSED_ARG(pSelf);
910
911 if (!PyArg_ParseTuple(pArgs, ""))
912 {
913 return NULL;
914 }
915 status = pjsua_create();
916
917 if (status == PJ_SUCCESS)
918 {
919 status = pj_thread_local_alloc(&thread_id);
920 if (status == PJ_SUCCESS)
921 status = pj_thread_local_set(thread_id, (void*)1);
922 }
923
924 return Py_BuildValue("i",status);
925}
926
927
928/*
929 * py_pjsua_init
930 */
931static PyObject *py_pjsua_init(PyObject *pSelf, PyObject *pArgs)
932{
933 pj_status_t status;
934 PyObject *o_ua_cfg, *o_log_cfg, *o_media_cfg;
935 pjsua_config cfg_ua, *p_cfg_ua;
936 pjsua_logging_config cfg_log, *p_cfg_log;
937 pjsua_media_config cfg_media, *p_cfg_media;
938
939 PJ_UNUSED_ARG(pSelf);
940
941 if (!PyArg_ParseTuple(pArgs, "OOO", &o_ua_cfg, &o_log_cfg, &o_media_cfg))
942 {
943 return NULL;
944 }
945
946 pjsua_config_default(&cfg_ua);
947 pjsua_logging_config_default(&cfg_log);
948 pjsua_media_config_default(&cfg_media);
949
950 if (o_ua_cfg != Py_None)
951 {
952 PyObj_pjsua_config *obj_ua_cfg = (PyObj_pjsua_config*)o_ua_cfg;
953
954 PyObj_pjsua_config_export(&cfg_ua, obj_ua_cfg);
955
956 g_obj_callback = obj_ua_cfg->cb;
957 Py_INCREF(g_obj_callback);
958
959 cfg_ua.cb.on_call_state = &cb_on_call_state;
960 cfg_ua.cb.on_incoming_call = &cb_on_incoming_call;
961 cfg_ua.cb.on_call_media_state = &cb_on_call_media_state;
962 cfg_ua.cb.on_dtmf_digit = &cb_on_dtmf_digit;
963 cfg_ua.cb.on_call_transfer_request = &cb_on_call_transfer_request;
964 cfg_ua.cb.on_call_transfer_status = &cb_on_call_transfer_status;
965 cfg_ua.cb.on_call_replace_request = &cb_on_call_replace_request;
966 cfg_ua.cb.on_call_replaced = &cb_on_call_replaced;
967 cfg_ua.cb.on_reg_state = &cb_on_reg_state;
Benny Prijonoe6787ec2008-07-18 23:00:56 +0000968 cfg_ua.cb.on_incoming_subscribe = &cb_on_incoming_subscribe;
Benny Prijono9c461142008-07-10 22:41:20 +0000969 cfg_ua.cb.on_buddy_state = &cb_on_buddy_state;
970 cfg_ua.cb.on_pager2 = &cb_on_pager;
971 cfg_ua.cb.on_pager_status2 = &cb_on_pager_status;
972 cfg_ua.cb.on_typing2 = &cb_on_typing;
973
974 p_cfg_ua = &cfg_ua;
975
976 } else {
977 p_cfg_ua = NULL;
978 }
979
980 if (o_log_cfg != Py_None)
981 {
982 PyObj_pjsua_logging_config * obj_log;
983
984 obj_log = (PyObj_pjsua_logging_config *)o_log_cfg;
985
986 PyObj_pjsua_logging_config_export(&cfg_log, obj_log);
987
988 Py_XDECREF(obj_log_cb);
989 obj_log_cb = obj_log->cb;
990 Py_INCREF(obj_log_cb);
991
992 cfg_log.cb = &cb_log_cb;
993 p_cfg_log = &cfg_log;
994
995 } else {
996 p_cfg_log = NULL;
997 }
998
999 if (o_media_cfg != Py_None)
1000 {
1001 PyObj_pjsua_media_config_export(&cfg_media,
1002 (PyObj_pjsua_media_config*)o_media_cfg);
1003 p_cfg_media = &cfg_media;
1004
1005 } else {
1006 p_cfg_media = NULL;
1007 }
1008
1009 status = pjsua_init(p_cfg_ua, p_cfg_log, p_cfg_media);
1010 return Py_BuildValue("i",status);
1011}
1012
1013
1014/*
1015 * py_pjsua_start
1016 */
1017static PyObject *py_pjsua_start(PyObject *pSelf, PyObject *pArgs)
1018{
1019 pj_status_t status;
1020
1021 PJ_UNUSED_ARG(pSelf);
1022
1023 if (!PyArg_ParseTuple(pArgs, ""))
1024 {
1025 return NULL;
1026 }
1027 status = pjsua_start();
1028
1029 return Py_BuildValue("i",status);
1030}
1031
1032
1033/*
1034 * py_pjsua_destroy
1035 */
1036static PyObject *py_pjsua_destroy(PyObject *pSelf, PyObject *pArgs)
1037{
1038 pj_status_t status;
1039
1040 PJ_UNUSED_ARG(pSelf);
1041
1042 if (!PyArg_ParseTuple(pArgs, ""))
1043 {
1044 return NULL;
1045 }
1046 status = pjsua_destroy();
1047
1048 return Py_BuildValue("i",status);
1049}
1050
1051
1052/*
1053 * py_pjsua_handle_events
1054 */
1055static PyObject *py_pjsua_handle_events(PyObject *pSelf, PyObject *pArgs)
1056{
1057 int ret;
1058 unsigned msec;
1059
1060 PJ_UNUSED_ARG(pSelf);
1061
1062 if (!PyArg_ParseTuple(pArgs, "i", &msec))
1063 {
1064 return NULL;
1065 }
1066
1067 /* Since handle_events() will block, we must wrap it with ALLOW_THREADS
1068 * construct, or otherwise many Python blocking functions (such as
1069 * time.sleep(), readline(), etc.) may hang/block indefinitely.
1070 * See http://www.python.org/doc/current/api/threads.html for more info.
1071 */
1072 Py_BEGIN_ALLOW_THREADS
1073 ret = pjsua_handle_events(msec);
1074 Py_END_ALLOW_THREADS
1075
1076 return Py_BuildValue("i",ret);
1077}
1078
1079
1080/*
1081 * py_pjsua_verify_sip_url
1082 */
1083static PyObject *py_pjsua_verify_sip_url(PyObject *pSelf, PyObject *pArgs)
1084{
1085 pj_status_t status;
1086 const char *url;
1087
1088 PJ_UNUSED_ARG(pSelf);
1089
1090 if (!PyArg_ParseTuple(pArgs, "s", &url))
1091 {
1092 return NULL;
1093 }
1094 status = pjsua_verify_sip_url(url);
1095
1096 return Py_BuildValue("i",status);
1097}
1098
1099
1100/*
1101 * function doc
1102 */
1103
1104static char pjsua_thread_register_doc[] =
1105 "int _pjsua.thread_register(string name, int[] desc)";
1106static char pjsua_perror_doc[] =
1107 "void _pjsua.perror (string sender, string title, int status) "
1108 "Display error message for the specified error code. Parameters: "
1109 "sender: The log sender field; "
1110 "title: Message title for the error; "
1111 "status: Status code.";
1112
1113static char pjsua_create_doc[] =
1114 "int _pjsua.create (void) "
1115 "Instantiate pjsua application. Application "
1116 "must call this function before calling any other functions, to make sure "
1117 "that the underlying libraries are properly initialized. Once this "
1118 "function has returned success, application must call pjsua_destroy() "
1119 "before quitting.";
1120
1121static char pjsua_init_doc[] =
1122 "int _pjsua.init (_pjsua.Config obj_ua_cfg, "
1123 "_pjsua.Logging_Config log_cfg, _pjsua.Media_Config media_cfg) "
1124 "Initialize pjsua with the specified settings. All the settings are "
1125 "optional, and the default values will be used when the config is not "
1126 "specified. Parameters: "
1127 "obj_ua_cfg : User agent configuration; "
1128 "log_cfg : Optional logging configuration; "
1129 "media_cfg : Optional media configuration.";
1130
1131static char pjsua_start_doc[] =
1132 "int _pjsua.start (void) "
1133 "Application is recommended to call this function after all "
1134 "initialization is done, so that the library can do additional checking "
1135 "set up additional";
1136
1137static char pjsua_destroy_doc[] =
1138 "int _pjsua.destroy (void) "
1139 "Destroy pjsua This function must be called once PJSUA is created. To "
1140 "make it easier for application, application may call this function "
1141 "several times with no danger.";
1142
1143static char pjsua_handle_events_doc[] =
1144 "int _pjsua.handle_events (int msec_timeout) "
1145 "Poll pjsua for events, and if necessary block the caller thread for the "
1146 "specified maximum interval (in miliseconds) Parameters: "
1147 "msec_timeout: Maximum time to wait, in miliseconds. "
1148 "Returns: The number of events that have been handled during the poll. "
1149 "Negative value indicates error, and application can retrieve the error "
1150 "as (err = -return_value).";
1151
1152static char pjsua_verify_sip_url_doc[] =
1153 "int _pjsua.verify_sip_url (string c_url) "
1154 "Verify that valid SIP url is given Parameters: "
1155 "c_url: The URL, as NULL terminated string.";
1156
1157static char pjsua_pool_create_doc[] =
1158 "_pjsua.Pj_Pool _pjsua.pool_create (string name, int init_size, "
1159 "int increment) "
1160 "Create memory pool Parameters: "
1161 "name: Optional pool name; "
1162 "init_size: Initial size of the pool; "
1163 "increment: Increment size.";
1164
1165static char pjsua_get_pjsip_endpt_doc[] =
1166 "_pjsua.Pjsip_Endpoint _pjsua.get_pjsip_endpt (void) "
1167 "Internal function to get SIP endpoint instance of pjsua, which is needed "
1168 "for example to register module, create transports, etc. Probably is only "
1169 "valid after pjsua_init() is called.";
1170
1171static char pjsua_get_pjmedia_endpt_doc[] =
1172 "_pjsua.Pjmedia_Endpt _pjsua.get_pjmedia_endpt (void) "
1173 "Internal function to get media endpoint instance. Only valid after "
1174 "pjsua_init() is called.";
1175
1176static char pjsua_get_pool_factory_doc[] =
1177 "_pjsua.Pj_Pool_Factory _pjsua.get_pool_factory (void) "
1178 "Internal function to get PJSUA pool factory. Only valid after "
1179 "pjsua_init() is called.";
1180
1181static char pjsua_reconfigure_logging_doc[] =
1182 "int _pjsua.reconfigure_logging (_pjsua.Logging_Config c) "
1183 "Application can call this function at any time (after pjsua_create(), of "
1184 "course) to change logging settings. Parameters: "
1185 "c: Logging configuration.";
1186
1187static char pjsua_logging_config_default_doc[] =
1188 "_pjsua.Logging_Config _pjsua.logging_config_default () "
1189 "Use this function to initialize logging config.";
1190
1191static char pjsua_config_default_doc[] =
1192 "_pjsua.Config _pjsua.config_default (). Use this function to "
1193 "initialize pjsua config. ";
1194
1195static char pjsua_media_config_default_doc[] =
1196 "_pjsua.Media_Config _pjsua.media_config_default (). "
1197 "Use this function to initialize media config.";
1198
1199static char pjsua_msg_data_init_doc[] =
1200 "_pjsua.Msg_Data void _pjsua.msg_data_init () "
1201 "Initialize message data ";
1202
1203
1204/* END OF LIB BASE */
1205
1206/* LIB TRANSPORT */
1207
1208/*
1209 * py_pjsua_transport_config_default
1210 * !modified @ 051206
1211 */
1212static PyObject *py_pjsua_transport_config_default(PyObject *pSelf,
1213 PyObject *pArgs)
1214{
1215 PyObj_pjsua_transport_config *obj;
1216 pjsua_transport_config cfg;
1217
1218 PJ_UNUSED_ARG(pSelf);
1219
1220 if (!PyArg_ParseTuple(pArgs, "")) {
1221 return NULL;
1222 }
1223
1224 pjsua_transport_config_default(&cfg);
1225 obj = (PyObj_pjsua_transport_config*)
1226 PyObj_pjsua_transport_config_new(&PyTyp_pjsua_transport_config,
1227 NULL, NULL);
1228 PyObj_pjsua_transport_config_import(obj, &cfg);
1229
1230 return (PyObject *)obj;
1231}
1232
1233/*
1234 * py_pjsua_transport_create
1235 * !modified @ 051206
1236 */
1237static PyObject *py_pjsua_transport_create(PyObject *pSelf, PyObject *pArgs)
1238{
1239 pj_status_t status;
1240 int type;
1241 PyObject * tmpObj;
1242 pjsua_transport_config cfg;
1243 pjsua_transport_id id;
1244
1245 PJ_UNUSED_ARG(pSelf);
1246
1247 if (!PyArg_ParseTuple(pArgs, "iO", &type, &tmpObj)) {
1248 return NULL;
1249 }
1250
1251 if (tmpObj != Py_None) {
1252 PyObj_pjsua_transport_config *obj;
1253 obj = (PyObj_pjsua_transport_config*)tmpObj;
1254 PyObj_pjsua_transport_config_export(&cfg, obj);
1255 status = pjsua_transport_create(type, &cfg, &id);
1256 } else {
1257 status = pjsua_transport_create(type, NULL, &id);
1258 }
1259
1260
1261 return Py_BuildValue("ii", status, id);
1262}
1263
1264/*
1265 * py_pjsua_enum_transports
1266 * !modified @ 261206
1267 */
1268static PyObject *py_pjsua_enum_transports(PyObject *pSelf, PyObject *pArgs)
1269{
1270 pj_status_t status;
1271 PyObject *list;
1272
1273 pjsua_transport_id id[PJSIP_MAX_TRANSPORTS];
1274 unsigned c, i;
1275
1276 PJ_UNUSED_ARG(pSelf);
1277
1278 if (!PyArg_ParseTuple(pArgs, ""))
1279 {
1280 return NULL;
1281 }
1282
1283 c = PJ_ARRAY_SIZE(id);
1284 status = pjsua_enum_transports(id, &c);
1285
1286 list = PyList_New(c);
1287 for (i = 0; i < c; i++)
1288 {
1289 int ret = PyList_SetItem(list, i, Py_BuildValue("i", id[i]));
1290 if (ret == -1)
1291 {
1292 return NULL;
1293 }
1294 }
1295
1296 return Py_BuildValue("O",list);
1297}
1298
1299/*
1300 * py_pjsua_transport_get_info
1301 * !modified @ 051206
1302 */
1303static PyObject *py_pjsua_transport_get_info(PyObject *pSelf, PyObject *pArgs)
1304{
1305 pj_status_t status;
1306 int id;
1307 pjsua_transport_info info;
1308
1309 PJ_UNUSED_ARG(pSelf);
1310
1311 if (!PyArg_ParseTuple(pArgs, "i", &id)) {
1312 return NULL;
1313 }
1314
1315 status = pjsua_transport_get_info(id, &info);
1316 if (status == PJ_SUCCESS) {
1317 PyObj_pjsua_transport_info *obj;
1318 obj = (PyObj_pjsua_transport_info *)
1319 PyObj_pjsua_transport_info_new(&PyTyp_pjsua_transport_info,
1320 NULL, NULL);
1321 PyObj_pjsua_transport_info_import(obj, &info);
1322 return Py_BuildValue("O", obj);
1323 } else {
1324 Py_INCREF(Py_None);
1325 return Py_None;
1326 }
1327}
1328
1329/*
1330 * py_pjsua_transport_set_enable
1331 */
1332static PyObject *py_pjsua_transport_set_enable
1333(PyObject *pSelf, PyObject *pArgs)
1334{
1335 pj_status_t status;
1336 int id;
1337 int enabled;
1338
1339 PJ_UNUSED_ARG(pSelf);
1340
1341 if (!PyArg_ParseTuple(pArgs, "ii", &id, &enabled))
1342 {
1343 return NULL;
1344 }
1345 status = pjsua_transport_set_enable(id, enabled);
1346
1347 return Py_BuildValue("i",status);
1348}
1349
1350/*
1351 * py_pjsua_transport_close
1352 */
1353static PyObject *py_pjsua_transport_close(PyObject *pSelf, PyObject *pArgs)
1354{
1355 pj_status_t status;
1356 int id;
1357 int force;
1358
1359 PJ_UNUSED_ARG(pSelf);
1360
1361 if (!PyArg_ParseTuple(pArgs, "ii", &id, &force))
1362 {
1363 return NULL;
1364 }
1365 status = pjsua_transport_close(id, force);
1366
1367 return Py_BuildValue("i",status);
1368}
1369
1370static char pjsua_transport_config_default_doc[] =
1371 "_pjsua.Transport_Config _pjsua.transport_config_default () "
1372 "Call this function to initialize UDP config with default values.";
1373static char pjsua_transport_create_doc[] =
1374 "int, int _pjsua.transport_create (int type, "
1375 "_pjsua.Transport_Config cfg) "
1376 "Create SIP transport.";
1377static char pjsua_enum_transports_doc[] =
1378 "int[] _pjsua.enum_transports () "
1379 "Enumerate all transports currently created in the system.";
1380static char pjsua_transport_get_info_doc[] =
1381 "void _pjsua.transport_get_info "
1382 "(_pjsua.Transport_ID id, _pjsua.Transport_Info info) "
1383 "Get information about transports.";
1384static char pjsua_transport_set_enable_doc[] =
1385 "void _pjsua.transport_set_enable "
1386 "(_pjsua.Transport_ID id, int enabled) "
1387 "Disable a transport or re-enable it. "
1388 "By default transport is always enabled after it is created. "
1389 "Disabling a transport does not necessarily close the socket, "
1390 "it will only discard incoming messages and prevent the transport "
1391 "from being used to send outgoing messages.";
1392static char pjsua_transport_close_doc[] =
1393 "void _pjsua.transport_close (_pjsua.Transport_ID id, int force) "
1394 "Close the transport. If transport is forcefully closed, "
1395 "it will be immediately closed, and any pending transactions "
1396 "that are using the transport may not terminate properly. "
1397 "Otherwise, the system will wait until all transactions are closed "
1398 "while preventing new users from using the transport, and will close "
1399 "the transport when it is safe to do so.";
1400
1401/* END OF LIB TRANSPORT */
1402
1403/* LIB ACCOUNT */
1404
1405
1406/*
1407 * py_pjsua_acc_config_default
1408 * !modified @ 051206
1409 */
1410static PyObject *py_pjsua_acc_config_default(PyObject *pSelf, PyObject *pArgs)
1411{
1412 PyObj_pjsua_acc_config *obj;
1413 pjsua_acc_config cfg;
1414
1415 PJ_UNUSED_ARG(pSelf);
1416
1417 if (!PyArg_ParseTuple(pArgs, "")) {
1418 return NULL;
1419 }
1420
1421 pjsua_acc_config_default(&cfg);
1422 obj = (PyObj_pjsua_acc_config *)
1423 PyObj_pjsua_acc_config_new(&PyTyp_pjsua_acc_config,
1424 NULL, NULL);
1425 PyObj_pjsua_acc_config_import(obj, &cfg);
1426 return (PyObject *)obj;
1427}
1428
1429/*
1430 * py_pjsua_acc_get_count
1431 */
1432static PyObject *py_pjsua_acc_get_count(PyObject *pSelf, PyObject *pArgs)
1433{
1434 int count;
1435
1436 PJ_UNUSED_ARG(pSelf);
1437
1438 if (!PyArg_ParseTuple(pArgs, "")) {
1439 return NULL;
1440 }
1441
1442 count = pjsua_acc_get_count();
1443 return Py_BuildValue("i",count);
1444}
1445
1446/*
1447 * py_pjsua_acc_is_valid
1448 */
1449static PyObject *py_pjsua_acc_is_valid(PyObject *pSelf, PyObject *pArgs)
1450{
1451 int id;
1452 int is_valid;
1453
1454 PJ_UNUSED_ARG(pSelf);
1455
1456 if (!PyArg_ParseTuple(pArgs, "i", &id)) {
1457 return NULL;
1458 }
1459
1460 is_valid = pjsua_acc_is_valid(id);
1461 return Py_BuildValue("i", is_valid);
1462}
1463
1464/*
1465 * py_pjsua_acc_set_default
1466 */
1467static PyObject *py_pjsua_acc_set_default(PyObject *pSelf, PyObject *pArgs)
1468{
1469 int id;
1470 int status;
1471
1472 PJ_UNUSED_ARG(pSelf);
1473
1474 if (!PyArg_ParseTuple(pArgs, "i", &id)) {
1475 return NULL;
1476 }
1477 status = pjsua_acc_set_default(id);
1478
1479 return Py_BuildValue("i", status);
1480}
1481
1482/*
1483 * py_pjsua_acc_get_default
1484 */
1485static PyObject *py_pjsua_acc_get_default(PyObject *pSelf, PyObject *pArgs)
1486{
1487 int id;
1488
1489 PJ_UNUSED_ARG(pSelf);
1490
1491 if (!PyArg_ParseTuple(pArgs, "")) {
1492 return NULL;
1493 }
1494
1495 id = pjsua_acc_get_default();
1496
1497 return Py_BuildValue("i", id);
1498}
1499
1500/*
1501 * py_pjsua_acc_add
1502 * !modified @ 051206
1503 */
1504static PyObject *py_pjsua_acc_add(PyObject *pSelf, PyObject *pArgs)
1505{
1506 int is_default;
1507 PyObject * acObj;
1508 PyObj_pjsua_acc_config * ac;
1509 int acc_id;
1510 int status;
1511
1512 PJ_UNUSED_ARG(pSelf);
1513
1514 if (!PyArg_ParseTuple(pArgs, "Oi", &acObj, &is_default)) {
1515 return NULL;
1516 }
1517
1518 if (acObj != Py_None) {
1519 pjsua_acc_config cfg;
1520
1521 pjsua_acc_config_default(&cfg);
1522 ac = (PyObj_pjsua_acc_config *)acObj;
1523 PyObj_pjsua_acc_config_export(&cfg, ac);
1524 status = pjsua_acc_add(&cfg, is_default, &acc_id);
1525 } else {
1526 status = PJ_EINVAL;
1527 acc_id = PJSUA_INVALID_ID;
1528 }
1529
1530 return Py_BuildValue("ii", status, acc_id);
1531}
1532
1533/*
1534 * py_pjsua_acc_add_local
1535 * !modified @ 051206
1536 */
1537static PyObject *py_pjsua_acc_add_local(PyObject *pSelf, PyObject *pArgs)
1538{
1539 int is_default;
1540 int tid;
1541 int p_acc_id;
1542 int status;
1543
1544 PJ_UNUSED_ARG(pSelf);
1545
1546 if (!PyArg_ParseTuple(pArgs, "ii", &tid, &is_default)) {
1547 return NULL;
1548 }
1549
1550
1551 status = pjsua_acc_add_local(tid, is_default, &p_acc_id);
1552
1553 return Py_BuildValue("ii", status, p_acc_id);
1554}
1555
1556/*
1557 * py_pjsua_acc_del
1558 */
1559static PyObject *py_pjsua_acc_del(PyObject *pSelf, PyObject *pArgs)
1560{
1561 int acc_id;
1562 int status;
1563
1564 PJ_UNUSED_ARG(pSelf);
1565
1566 if (!PyArg_ParseTuple(pArgs, "i", &acc_id))
1567 {
1568 return NULL;
1569 }
1570
1571
1572 status = pjsua_acc_del(acc_id);
1573 return Py_BuildValue("i", status);
1574}
1575
1576/*
1577 * py_pjsua_acc_modify
1578 */
1579static PyObject *py_pjsua_acc_modify(PyObject *pSelf, PyObject *pArgs)
1580{
1581 PyObject * acObj;
1582 PyObj_pjsua_acc_config * ac;
1583 int acc_id;
1584 int status;
1585
1586 PJ_UNUSED_ARG(pSelf);
1587
1588 if (!PyArg_ParseTuple(pArgs, "iO", &acc_id, &acObj)) {
1589 return NULL;
1590 }
1591
1592 if (acObj != Py_None) {
1593 pjsua_acc_config cfg;
1594
1595 pjsua_acc_config_default(&cfg);
1596 ac = (PyObj_pjsua_acc_config *)acObj;
1597 PyObj_pjsua_acc_config_export(&cfg, ac);
1598
1599 status = pjsua_acc_modify(acc_id, &cfg);
1600 } else {
1601 status = PJ_EINVAL;
1602 }
1603 return Py_BuildValue("i", status);
1604}
1605
1606/*
1607 * py_pjsua_acc_set_online_status
1608 */
1609static PyObject *py_pjsua_acc_set_online_status(PyObject *pSelf,
1610 PyObject *pArgs)
1611{
1612 int is_online;
1613 int acc_id;
1614 int status;
1615
1616 PJ_UNUSED_ARG(pSelf);
1617
1618 if (!PyArg_ParseTuple(pArgs, "ii", &acc_id, &is_online)) {
1619 return NULL;
1620 }
1621
1622 status = pjsua_acc_set_online_status(acc_id, is_online);
1623
1624 return Py_BuildValue("i", status);
1625}
1626
1627/*
1628 * py_pjsua_acc_set_online_status2
1629 */
1630static PyObject *py_pjsua_acc_set_online_status2(PyObject *pSelf,
1631 PyObject *pArgs)
1632{
1633 int is_online;
1634 int acc_id;
1635 int activity_id;
1636 const char *activity_text;
1637 const char *rpid_id;
1638 pjrpid_element rpid;
1639 pj_status_t status;
1640
1641 PJ_UNUSED_ARG(pSelf);
1642
1643 if (!PyArg_ParseTuple(pArgs, "iiiss", &acc_id, &is_online,
1644 &activity_id, &activity_text, &rpid_id)) {
1645 return NULL;
1646 }
1647
1648 pj_bzero(&rpid, sizeof(rpid));
1649 rpid.type = PJRPID_ELEMENT_TYPE_PERSON;
1650 rpid.activity = activity_id;
1651 rpid.note = pj_str((char*)activity_text);
1652
1653 if (rpid_id)
1654 rpid.id = pj_str((char*)rpid_id);
1655
1656 status = pjsua_acc_set_online_status2(acc_id, is_online, &rpid);
1657
1658 return Py_BuildValue("i", status);
1659}
1660
1661/*
1662 * py_pjsua_acc_set_registration
1663 */
1664static PyObject *py_pjsua_acc_set_registration(PyObject *pSelf,
1665 PyObject *pArgs)
1666{
1667 int renew;
1668 int acc_id;
1669 int status;
1670
1671 PJ_UNUSED_ARG(pSelf);
1672
1673 if (!PyArg_ParseTuple(pArgs, "ii", &acc_id, &renew)) {
1674 return NULL;
1675 }
1676
1677 status = pjsua_acc_set_registration(acc_id, renew);
1678
1679 return Py_BuildValue("i", status);
1680}
1681
1682/*
1683 * py_pjsua_acc_get_info
1684 * !modified @ 051206
1685 */
1686static PyObject *py_pjsua_acc_get_info(PyObject *pSelf, PyObject *pArgs)
1687{
1688 int acc_id;
1689 PyObj_pjsua_acc_info * obj;
1690 pjsua_acc_info info;
1691 int status;
1692
1693 PJ_UNUSED_ARG(pSelf);
1694
1695 if (!PyArg_ParseTuple(pArgs, "i", &acc_id)) {
1696 return NULL;
1697 }
1698
1699 status = pjsua_acc_get_info(acc_id, &info);
1700 if (status == PJ_SUCCESS) {
1701 obj = (PyObj_pjsua_acc_info *)
1702 PyObj_pjsua_acc_info_new(&PyTyp_pjsua_acc_info,NULL, NULL);
1703 PyObj_pjsua_acc_info_import(obj, &info);
1704 return Py_BuildValue("O", obj);
1705 } else {
1706 Py_INCREF(Py_None);
1707 return Py_None;
1708 }
1709}
1710
1711/*
1712 * py_pjsua_enum_accs
1713 * !modified @ 241206
1714 */
1715static PyObject *py_pjsua_enum_accs(PyObject *pSelf, PyObject *pArgs)
1716{
1717 pj_status_t status;
1718 PyObject *list;
1719
1720 pjsua_acc_id id[PJSUA_MAX_ACC];
1721 unsigned c, i;
1722
1723 PJ_UNUSED_ARG(pSelf);
1724
1725 if (!PyArg_ParseTuple(pArgs, ""))
1726 {
1727 return NULL;
1728 }
1729 c = PJ_ARRAY_SIZE(id);
1730
1731 status = pjsua_enum_accs(id, &c);
1732
1733 list = PyList_New(c);
1734 for (i = 0; i < c; i++)
1735 {
1736 int ret = PyList_SetItem(list, i, Py_BuildValue("i", id[i]));
1737 if (ret == -1)
1738 {
1739 return NULL;
1740 }
1741 }
1742
1743 return Py_BuildValue("O",list);
1744}
1745
1746/*
1747 * py_pjsua_acc_enum_info
1748 * !modified @ 241206
1749 */
1750static PyObject *py_pjsua_acc_enum_info(PyObject *pSelf, PyObject *pArgs)
1751{
1752 pj_status_t status;
1753 PyObject *list;
1754 pjsua_acc_info info[PJSUA_MAX_ACC];
1755 unsigned c, i;
1756
1757 PJ_UNUSED_ARG(pSelf);
1758
1759 if (!PyArg_ParseTuple(pArgs, "")) {
1760 return NULL;
1761 }
1762
1763 c = PJ_ARRAY_SIZE(info);
1764 status = pjsua_acc_enum_info(info, &c);
1765
1766 list = PyList_New(c);
1767 for (i = 0; i < c; i++) {
1768 PyObj_pjsua_acc_info *obj;
1769 obj = (PyObj_pjsua_acc_info *)
1770 PyObj_pjsua_acc_info_new(&PyTyp_pjsua_acc_info, NULL, NULL);
1771
1772 PyObj_pjsua_acc_info_import(obj, &info[i]);
1773
1774 PyList_SetItem(list, i, (PyObject *)obj);
1775 }
1776
1777 return Py_BuildValue("O",list);
1778}
1779
1780/*
1781 * py_pjsua_acc_find_for_outgoing
1782 */
1783static PyObject *py_pjsua_acc_find_for_outgoing(PyObject *pSelf,
1784 PyObject *pArgs)
1785{
1786 int acc_id;
1787 PyObject * url;
1788 pj_str_t str;
1789
1790 PJ_UNUSED_ARG(pSelf);
1791
1792 if (!PyArg_ParseTuple(pArgs, "O", &url))
1793 {
1794 return NULL;
1795 }
1796 str.ptr = PyString_AsString(url);
1797 str.slen = strlen(PyString_AsString(url));
1798
1799 acc_id = pjsua_acc_find_for_outgoing(&str);
1800
1801 return Py_BuildValue("i", acc_id);
1802}
1803
1804/*
1805 * py_pjsua_acc_find_for_incoming
1806 */
1807static PyObject *py_pjsua_acc_find_for_incoming(PyObject *pSelf,
1808 PyObject *pArgs)
1809{
1810 int acc_id;
1811 PyObject * tmpObj;
1812 PyObj_pjsip_rx_data * obj;
1813 pjsip_rx_data * rdata;
1814
1815 PJ_UNUSED_ARG(pSelf);
1816
1817 if (!PyArg_ParseTuple(pArgs, "O", &tmpObj))
1818 {
1819 return NULL;
1820 }
1821 if (tmpObj != Py_None)
1822 {
1823 obj = (PyObj_pjsip_rx_data *)tmpObj;
1824 rdata = obj->rdata;
1825 acc_id = pjsua_acc_find_for_incoming(rdata);
1826 } else {
1827 acc_id = pjsua_acc_find_for_incoming(NULL);
1828 }
1829 return Py_BuildValue("i", acc_id);
1830}
1831
1832/*
1833 * py_pjsua_acc_create_uac_contact
1834 * !modified @ 061206
1835 */
1836static PyObject *py_pjsua_acc_create_uac_contact(PyObject *pSelf,
1837 PyObject *pArgs)
1838{
1839 int status;
1840 int acc_id;
1841 PyObject * pObj;
1842 PyObj_pj_pool * p;
1843 pj_pool_t * pool;
1844 PyObject * strc;
1845 pj_str_t contact;
1846 PyObject * stru;
1847 pj_str_t uri;
1848
1849 PJ_UNUSED_ARG(pSelf);
1850
1851 if (!PyArg_ParseTuple(pArgs, "OiO", &pObj, &acc_id, &stru))
1852 {
1853 return NULL;
1854 }
1855 if (pObj != Py_None)
1856 {
1857 p = (PyObj_pj_pool *)pObj;
1858 pool = p->pool;
1859 uri.ptr = PyString_AsString(stru);
1860 uri.slen = strlen(PyString_AsString(stru));
1861 status = pjsua_acc_create_uac_contact(pool, &contact, acc_id, &uri);
1862 } else {
1863 status = pjsua_acc_create_uac_contact(NULL, &contact, acc_id, &uri);
1864 }
1865 strc = PyString_FromStringAndSize(contact.ptr, contact.slen);
1866
1867 return Py_BuildValue("O", strc);
1868}
1869
1870/*
1871 * py_pjsua_acc_create_uas_contact
1872 * !modified @ 061206
1873 */
1874static PyObject *py_pjsua_acc_create_uas_contact(PyObject *pSelf,
1875 PyObject *pArgs)
1876{
1877 int status;
1878 int acc_id;
1879 PyObject * pObj;
1880 PyObj_pj_pool * p;
1881 pj_pool_t * pool;
1882 PyObject * strc;
1883 pj_str_t contact;
1884 PyObject * rObj;
1885 PyObj_pjsip_rx_data * objr;
1886 pjsip_rx_data * rdata;
1887
1888 PJ_UNUSED_ARG(pSelf);
1889
1890 if (!PyArg_ParseTuple(pArgs, "OiO", &pObj, &acc_id, &rObj))
1891 {
1892 return NULL;
1893 }
1894 if (pObj != Py_None)
1895 {
1896 p = (PyObj_pj_pool *)pObj;
1897 pool = p->pool;
1898 } else {
1899 pool = NULL;
1900 }
1901 if (rObj != Py_None)
1902 {
1903 objr = (PyObj_pjsip_rx_data *)rObj;
1904 rdata = objr->rdata;
1905 } else {
1906 rdata = NULL;
1907 }
1908 status = pjsua_acc_create_uas_contact(pool, &contact, acc_id, rdata);
1909 strc = PyString_FromStringAndSize(contact.ptr, contact.slen);
1910
1911 return Py_BuildValue("O", strc);
1912}
1913
1914/*
1915 * py_pjsua_acc_set_transport
1916 */
1917static PyObject *py_pjsua_acc_set_transport
1918(PyObject *pSelf, PyObject *pArgs)
1919{
1920 int acc_id, transport_id;
1921 int status;
1922
1923 PJ_UNUSED_ARG(pSelf);
1924
1925 if (!PyArg_ParseTuple(pArgs, "ii", &acc_id, &transport_id))
1926 {
1927 return NULL;
1928 }
1929
1930 status = pjsua_acc_set_transport(acc_id, transport_id);
1931
1932
1933 return Py_BuildValue("i", status);
1934}
1935
1936
Benny Prijonoe6787ec2008-07-18 23:00:56 +00001937/*
1938 * py_pjsua_acc_pres_notify
1939 */
1940static PyObject *py_pjsua_acc_pres_notify
1941(PyObject *pSelf, PyObject *pArgs)
1942{
1943 static char reason_buf[64];
1944 int acc_id, state;
1945 PyObject *arg_pres, *arg_msg_data;
1946 void *srv_pres;
1947 pjsua_msg_data msg_data;
1948 const char *arg_reason;
1949 pj_str_t reason;
1950 pj_bool_t with_body;
1951 pj_pool_t *pool = NULL;
1952 int status;
1953
1954 PJ_UNUSED_ARG(pSelf);
1955
1956 if (!PyArg_ParseTuple(pArgs, "iOisO", &acc_id, &arg_pres,
1957 &state, &arg_reason, &arg_msg_data))
1958 {
1959 return NULL;
1960 }
1961
1962 srv_pres = (void*) PyLong_AsLong(arg_pres);
1963 pjsua_msg_data_init(&msg_data);
1964 with_body = (state != PJSIP_EVSUB_STATE_TERMINATED);
1965
1966 if (arg_reason) {
1967 strncpy(reason_buf, arg_reason, sizeof(reason_buf));
1968 reason.ptr = reason_buf;
1969 reason.slen = strlen(arg_reason);
1970 } else {
1971 reason = pj_str("");
1972 }
1973
1974 if (arg_msg_data && arg_msg_data != Py_None) {
1975 PyObj_pjsua_msg_data *omd = (PyObj_pjsua_msg_data *)arg_msg_data;
1976 msg_data.content_type.ptr = PyString_AsString(omd->content_type);
1977 msg_data.content_type.slen = PyString_Size(omd->content_type);
1978 msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
1979 msg_data.msg_body.slen = PyString_Size(omd->msg_body);
1980 pool = pjsua_pool_create("pytmp", POOL_SIZE, POOL_SIZE);
1981 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
1982 } else if (arg_msg_data) {
1983 Py_XDECREF(arg_msg_data);
1984 }
1985
1986 status = pjsua_pres_notify(acc_id, (pjsua_srv_pres*)srv_pres,
1987 (pjsip_evsub_state)state, NULL,
1988 &reason, with_body, &msg_data);
1989
1990 if (pool) {
1991 pj_pool_release(pool);
1992 }
1993
1994 return Py_BuildValue("i", status);
1995}
1996
Benny Prijono9c461142008-07-10 22:41:20 +00001997static char pjsua_acc_config_default_doc[] =
1998 "_pjsua.Acc_Config _pjsua.acc_config_default () "
1999 "Call this function to initialize account config with default values.";
2000static char pjsua_acc_get_count_doc[] =
2001 "int _pjsua.acc_get_count () "
2002 "Get number of current accounts.";
2003static char pjsua_acc_is_valid_doc[] =
2004 "int _pjsua.acc_is_valid (int acc_id) "
2005 "Check if the specified account ID is valid.";
2006static char pjsua_acc_set_default_doc[] =
2007 "int _pjsua.acc_set_default (int acc_id) "
2008 "Set default account to be used when incoming "
2009 "and outgoing requests doesn't match any accounts.";
2010static char pjsua_acc_get_default_doc[] =
2011 "int _pjsua.acc_get_default () "
2012 "Get default account.";
2013static char pjsua_acc_add_doc[] =
2014 "int, int _pjsua.acc_add (_pjsua.Acc_Config cfg, "
2015 "int is_default) "
2016 "Add a new account to pjsua. PJSUA must have been initialized "
2017 "(with pjsua_init()) before calling this function.";
2018static char pjsua_acc_add_local_doc[] =
2019 "int,int _pjsua.acc_add_local (int tid, "
2020 "int is_default) "
2021 "Add a local account. A local account is used to identify "
2022 "local endpoint instead of a specific user, and for this reason, "
2023 "a transport ID is needed to obtain the local address information.";
2024static char pjsua_acc_del_doc[] =
2025 "int _pjsua.acc_del (int acc_id) "
2026 "Delete account.";
2027static char pjsua_acc_modify_doc[] =
2028 "int _pjsua.acc_modify (int acc_id, _pjsua.Acc_Config cfg) "
2029 "Modify account information.";
2030static char pjsua_acc_set_online_status_doc[] =
2031 "int _pjsua.acc_set_online_status2(int acc_id, int is_online) "
2032 "Modify account's presence status to be advertised "
2033 "to remote/presence subscribers.";
2034static char pjsua_acc_set_online_status2_doc[] =
2035 "int _pjsua.acc_set_online_status (int acc_id, int is_online, "
2036 "int activity_id, string activity_text) "
2037 "Modify account's presence status to be advertised "
2038 "to remote/presence subscribers.";
2039static char pjsua_acc_set_registration_doc[] =
2040 "int _pjsua.acc_set_registration (int acc_id, int renew) "
2041 "Update registration or perform unregistration.";
2042static char pjsua_acc_get_info_doc[] =
2043 "_pjsua.Acc_Info _pjsua.acc_get_info (int acc_id) "
2044 "Get account information.";
2045static char pjsua_enum_accs_doc[] =
2046 "int[] _pjsua.enum_accs () "
2047 "Enum accounts all account ids.";
2048static char pjsua_acc_enum_info_doc[] =
2049 "_pjsua.Acc_Info[] _pjsua.acc_enum_info () "
2050 "Enum accounts info.";
2051static char pjsua_acc_find_for_outgoing_doc[] =
2052 "int _pjsua.acc_find_for_outgoing (string url) "
2053 "This is an internal function to find the most appropriate account "
2054 "to used to reach to the specified URL.";
2055static char pjsua_acc_find_for_incoming_doc[] =
2056 "int _pjsua.acc_find_for_incoming (PyObj_pjsip_rx_data rdata) "
2057 "This is an internal function to find the most appropriate account "
2058 "to be used to handle incoming calls.";
2059static char pjsua_acc_create_uac_contact_doc[] =
2060 "string _pjsua.acc_create_uac_contact (PyObj_pj_pool pool, "
2061 "int acc_id, string uri) "
2062 "Create a suitable URI to be put as Contact based on the specified "
2063 "target URI for the specified account.";
2064static char pjsua_acc_create_uas_contact_doc[] =
2065 "string _pjsua.acc_create_uas_contact (PyObj_pj_pool pool, "
2066 "int acc_id, PyObj_pjsip_rx_data rdata) "
2067 "Create a suitable URI to be put as Contact based on the information "
2068 "in the incoming request.";
2069
2070/* END OF LIB ACCOUNT */
2071
2072/* LIB BUDDY */
2073
2074
2075
2076/*
2077 * py_pjsua_buddy_config_default
2078 */
2079static PyObject *py_pjsua_buddy_config_default(PyObject *pSelf,
2080 PyObject *pArgs)
2081{
2082 PyObj_pjsua_buddy_config *obj;
2083 pjsua_buddy_config cfg;
2084
2085 PJ_UNUSED_ARG(pSelf);
2086
2087 if (!PyArg_ParseTuple(pArgs, "")) {
2088 return NULL;
2089 }
2090
2091 pjsua_buddy_config_default(&cfg);
2092 obj = (PyObj_pjsua_buddy_config *)
2093 PyObj_pjsua_buddy_config_new(&PyTyp_pjsua_buddy_config, NULL, NULL);
2094 PyObj_pjsua_buddy_config_import(obj, &cfg);
2095
2096 return (PyObject *)obj;
2097}
2098
2099/*
2100 * py_pjsua_get_buddy_count
2101 */
2102static PyObject *py_pjsua_get_buddy_count(PyObject *pSelf, PyObject *pArgs)
2103{
2104 int ret;
2105
2106 PJ_UNUSED_ARG(pSelf);
2107
2108 if (!PyArg_ParseTuple(pArgs, "")) {
2109 return NULL;
2110 }
2111 ret = pjsua_get_buddy_count();
2112
2113 return Py_BuildValue("i", ret);
2114}
2115
2116/*
2117 * py_pjsua_buddy_is_valid
2118 */
2119static PyObject *py_pjsua_buddy_is_valid(PyObject *pSelf, PyObject *pArgs)
2120{
2121 int id;
2122 int is_valid;
2123
2124 PJ_UNUSED_ARG(pSelf);
2125
2126 if (!PyArg_ParseTuple(pArgs, "i", &id)) {
2127 return NULL;
2128 }
2129 is_valid = pjsua_buddy_is_valid(id);
2130
2131 return Py_BuildValue("i", is_valid);
2132}
2133
2134/*
2135 * py_pjsua_enum_buddies
2136 * !modified @ 241206
2137 */
2138static PyObject *py_pjsua_enum_buddies(PyObject *pSelf, PyObject *pArgs)
2139{
2140 pj_status_t status;
2141 PyObject *list;
2142
2143 pjsua_buddy_id id[PJSUA_MAX_BUDDIES];
2144 unsigned c, i;
2145
2146 PJ_UNUSED_ARG(pSelf);
2147
2148 if (!PyArg_ParseTuple(pArgs, "")) {
2149 return NULL;
2150 }
2151 c = PJ_ARRAY_SIZE(id);
2152 status = pjsua_enum_buddies(id, &c);
2153 list = PyList_New(c);
2154 for (i = 0; i < c; i++) {
2155 PyList_SetItem(list, i, Py_BuildValue("i", id[i]));
2156 }
2157
2158 return Py_BuildValue("O",list);
2159}
2160
2161/*
2162 * py_pjsua_buddy_get_info
2163 * !modified @ 071206
2164 */
2165static PyObject *py_pjsua_buddy_get_info(PyObject *pSelf, PyObject *pArgs)
2166{
2167 int buddy_id;
2168 PyObj_pjsua_buddy_info * obj;
2169 pjsua_buddy_info info;
2170 int status;
2171
2172 PJ_UNUSED_ARG(pSelf);
2173
2174 if (!PyArg_ParseTuple(pArgs, "i", &buddy_id)) {
2175 return NULL;
2176 }
2177
2178 status = pjsua_buddy_get_info(buddy_id, &info);
2179 if (status == PJ_SUCCESS) {
2180 obj = (PyObj_pjsua_buddy_info *)
2181 PyObj_pjsua_buddy_config_new(&PyTyp_pjsua_buddy_info,NULL,NULL);
2182 PyObj_pjsua_buddy_info_import(obj, &info);
2183 return Py_BuildValue("O", obj);
2184 } else {
2185 Py_INCREF(Py_None);
2186 return Py_None;
2187 }
2188}
2189
2190/*
2191 * py_pjsua_buddy_add
2192 * !modified @ 061206
2193 */
2194static PyObject *py_pjsua_buddy_add(PyObject *pSelf, PyObject *pArgs)
2195{
2196 PyObject * bcObj;
2197 int buddy_id;
2198 int status;
2199
2200 PJ_UNUSED_ARG(pSelf);
2201
2202 if (!PyArg_ParseTuple(pArgs, "O", &bcObj)) {
2203 return NULL;
2204 }
2205
2206 if (bcObj != Py_None) {
2207 pjsua_buddy_config cfg;
2208 PyObj_pjsua_buddy_config * bc;
2209
2210 bc = (PyObj_pjsua_buddy_config *)bcObj;
2211
2212 pjsua_buddy_config_default(&cfg);
2213 PyObj_pjsua_buddy_config_export(&cfg, bc);
2214
2215 status = pjsua_buddy_add(&cfg, &buddy_id);
2216 } else {
2217 status = PJ_EINVAL;
2218 buddy_id = PJSUA_INVALID_ID;
2219 }
2220 return Py_BuildValue("ii", status, buddy_id);
2221}
2222
2223/*
2224 * py_pjsua_buddy_del
2225 */
2226static PyObject *py_pjsua_buddy_del(PyObject *pSelf, PyObject *pArgs)
2227{
2228 int buddy_id;
2229 int status;
2230
2231 PJ_UNUSED_ARG(pSelf);
2232
2233 if (!PyArg_ParseTuple(pArgs, "i", &buddy_id)) {
2234 return NULL;
2235 }
2236
2237
2238 status = pjsua_buddy_del(buddy_id);
2239 return Py_BuildValue("i", status);
2240}
2241
2242/*
2243 * py_pjsua_buddy_subscribe_pres
2244 */
2245static PyObject *py_pjsua_buddy_subscribe_pres(PyObject *pSelf, PyObject *pArgs)
2246{
2247 int buddy_id;
2248 int status;
2249 int subscribe;
2250
2251 PJ_UNUSED_ARG(pSelf);
2252
2253 if (!PyArg_ParseTuple(pArgs, "ii", &buddy_id, &subscribe)) {
2254 return NULL;
2255 }
2256
2257
2258 status = pjsua_buddy_subscribe_pres(buddy_id, subscribe);
2259 return Py_BuildValue("i", status);
2260}
2261
2262/*
2263 * py_pjsua_pres_dump
2264 */
2265static PyObject *py_pjsua_pres_dump(PyObject *pSelf, PyObject *pArgs)
2266{
2267 int verbose;
2268
2269 PJ_UNUSED_ARG(pSelf);
2270
2271 if (!PyArg_ParseTuple(pArgs, "i", &verbose)) {
2272 return NULL;
2273 }
2274
2275
2276 pjsua_pres_dump(verbose);
2277 Py_INCREF(Py_None);
2278 return Py_None;
2279}
2280
2281/*
2282 * py_pjsua_im_send
2283 * !modified @ 071206
2284 */
2285static PyObject *py_pjsua_im_send(PyObject *pSelf, PyObject *pArgs)
2286{
2287 int status;
2288 int acc_id;
2289 pj_str_t * mime_type, tmp_mime_type;
2290 pj_str_t to, content;
2291 PyObject * st;
2292 PyObject * smt;
2293 PyObject * sc;
2294 pjsua_msg_data msg_data;
2295 PyObject * omdObj;
2296 PyObj_pjsua_msg_data * omd;
2297
2298 int user_data;
2299 pj_pool_t *pool;
2300
2301 PJ_UNUSED_ARG(pSelf);
2302
2303 if (!PyArg_ParseTuple(pArgs, "iOOOOi", &acc_id,
2304 &st, &smt, &sc, &omdObj, &user_data))
2305 {
2306 return NULL;
2307 }
2308 if (smt != Py_None) {
2309 mime_type = &tmp_mime_type;
2310 tmp_mime_type = PyString_to_pj_str(smt);
2311 } else {
2312 mime_type = NULL;
2313 }
2314 to = PyString_to_pj_str(st);
2315 content = PyString_to_pj_str(sc);
2316
2317 if (omdObj != Py_None) {
2318
2319 omd = (PyObj_pjsua_msg_data *)omdObj;
2320 msg_data.content_type = PyString_to_pj_str(omd->content_type);
2321 msg_data.msg_body = PyString_to_pj_str(omd->msg_body);
2322 pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
2323
2324 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
2325 status = pjsua_im_send(acc_id, &to, mime_type,
2326 &content, &msg_data, (void *)user_data);
2327 pj_pool_release(pool);
2328 } else {
2329
2330 status = pjsua_im_send(acc_id, &to, mime_type,
2331 &content, NULL, NULL);
2332 }
2333
2334 return Py_BuildValue("i",status);
2335}
2336
2337/*
2338 * py_pjsua_im_typing
2339 */
2340static PyObject *py_pjsua_im_typing(PyObject *pSelf, PyObject *pArgs)
2341{
2342 int status;
2343 int acc_id;
2344 pj_str_t to;
2345 PyObject * st;
2346 int is_typing;
2347 pjsua_msg_data msg_data;
2348 PyObject * omdObj;
2349 PyObj_pjsua_msg_data * omd;
2350 pj_pool_t * pool;
2351
2352 PJ_UNUSED_ARG(pSelf);
2353
2354 if (!PyArg_ParseTuple(pArgs, "iOiO", &acc_id, &st, &is_typing, &omdObj)) {
2355 return NULL;
2356 }
2357
2358 to = PyString_to_pj_str(st);
2359
2360 if (omdObj != Py_None) {
2361 omd = (PyObj_pjsua_msg_data *)omdObj;
2362 msg_data.content_type = PyString_to_pj_str(omd->content_type);
2363 msg_data.msg_body = PyString_to_pj_str(omd->msg_body);
2364 pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
2365
2366 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
2367 status = pjsua_im_typing(acc_id, &to, is_typing, &msg_data);
2368 pj_pool_release(pool);
2369 } else {
2370 status = pjsua_im_typing(acc_id, &to, is_typing, NULL);
2371 }
2372 return Py_BuildValue("i",status);
2373}
2374
2375static char pjsua_buddy_config_default_doc[] =
2376 "_pjsua.Buddy_Config _pjsua.buddy_config_default () "
2377 "Set default values to the buddy config.";
2378static char pjsua_get_buddy_count_doc[] =
2379 "int _pjsua.get_buddy_count () "
2380 "Get total number of buddies.";
2381static char pjsua_buddy_is_valid_doc[] =
2382 "int _pjsua.buddy_is_valid (int buddy_id) "
2383 "Check if buddy ID is valid.";
2384static char pjsua_enum_buddies_doc[] =
2385 "int[] _pjsua.enum_buddies () "
2386 "Enum buddy IDs.";
2387static char pjsua_buddy_get_info_doc[] =
2388 "_pjsua.Buddy_Info _pjsua.buddy_get_info (int buddy_id) "
2389 "Get detailed buddy info.";
2390static char pjsua_buddy_add_doc[] =
2391 "int,int _pjsua.buddy_add (_pjsua.Buddy_Config cfg) "
2392 "Add new buddy.";
2393static char pjsua_buddy_del_doc[] =
2394 "int _pjsua.buddy_del (int buddy_id) "
2395 "Delete buddy.";
2396static char pjsua_buddy_subscribe_pres_doc[] =
2397 "int _pjsua.buddy_subscribe_pres (int buddy_id, int subscribe) "
2398 "Enable/disable buddy's presence monitoring.";
2399static char pjsua_pres_dump_doc[] =
2400 "void _pjsua.pres_dump (int verbose) "
2401 "Dump presence subscriptions to log file.";
2402static char pjsua_im_send_doc[] =
2403 "int _pjsua.im_send (int acc_id, string to, string mime_type, "
2404 "string content, _pjsua.Msg_Data msg_data, int user_data) "
2405 "Send instant messaging outside dialog, using the specified account "
2406 "for route set and authentication.";
2407static char pjsua_im_typing_doc[] =
2408 "int _pjsua.im_typing (int acc_id, string to, int is_typing, "
2409 "_pjsua.Msg_Data msg_data) "
2410 "Send typing indication outside dialog.";
2411
2412/* END OF LIB BUDDY */
2413
2414/* LIB MEDIA */
2415
2416
2417
2418/*
2419 * PyObj_pjsua_codec_info
2420 * Codec Info
2421 * !modified @ 071206
2422 */
2423typedef struct
2424{
2425 PyObject_HEAD
2426 /* Type-specific fields go here. */
2427
2428 PyObject * codec_id;
2429 pj_uint8_t priority;
2430 char buf_[32];
2431} PyObj_pjsua_codec_info;
2432
2433
2434/*
2435 * codec_info_dealloc
2436 * deletes a codec_info from memory
2437 * !modified @ 071206
2438 */
2439static void codec_info_dealloc(PyObj_pjsua_codec_info* self)
2440{
2441 Py_XDECREF(self->codec_id);
2442
2443 self->ob_type->tp_free((PyObject*)self);
2444}
2445
2446
2447/*
2448 * codec_info_new
2449 * constructor for codec_info object
2450 * !modified @ 071206
2451 */
2452static PyObject * codec_info_new(PyTypeObject *type, PyObject *args,
2453 PyObject *kwds)
2454{
2455 PyObj_pjsua_codec_info *self;
2456
2457 PJ_UNUSED_ARG(args);
2458 PJ_UNUSED_ARG(kwds);
2459
2460 self = (PyObj_pjsua_codec_info *)type->tp_alloc(type, 0);
2461 if (self != NULL)
2462 {
2463 self->codec_id = PyString_FromString("");
2464 if (self->codec_id == NULL)
2465 {
2466 Py_DECREF(self);
2467 return NULL;
2468 }
2469
2470
2471 }
2472 return (PyObject *)self;
2473}
2474
2475/*
2476 * codec_info_members
2477 * !modified @ 071206
2478 */
2479static PyMemberDef codec_info_members[] =
2480{
2481 {
2482 "codec_id", T_OBJECT_EX,
2483 offsetof(PyObj_pjsua_codec_info, codec_id), 0,
2484 "Codec unique identification."
2485 },
2486
2487 {
2488 "priority", T_INT,
2489 offsetof(PyObj_pjsua_codec_info, priority), 0,
2490 "Codec priority (integer 0-255)."
2491 },
2492
2493
2494
2495 {NULL} /* Sentinel */
2496};
2497
2498
2499
2500
2501/*
2502 * PyTyp_pjsua_codec_info
2503 */
2504static PyTypeObject PyTyp_pjsua_codec_info =
2505{
2506 PyObject_HEAD_INIT(NULL)
2507 0, /*ob_size*/
2508 "_pjsua.Codec_Info", /*tp_name*/
2509 sizeof(PyObj_pjsua_codec_info), /*tp_basicsize*/
2510 0, /*tp_itemsize*/
2511 (destructor)codec_info_dealloc,/*tp_dealloc*/
2512 0, /*tp_print*/
2513 0, /*tp_getattr*/
2514 0, /*tp_setattr*/
2515 0, /*tp_compare*/
2516 0, /*tp_repr*/
2517 0, /*tp_as_number*/
2518 0, /*tp_as_sequence*/
2519 0, /*tp_as_mapping*/
2520 0, /*tp_hash */
2521 0, /*tp_call*/
2522 0, /*tp_str*/
2523 0, /*tp_getattro*/
2524 0, /*tp_setattro*/
2525 0, /*tp_as_buffer*/
2526 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2527 "Codec Info objects", /* tp_doc */
2528 0, /* tp_traverse */
2529 0, /* tp_clear */
2530 0, /* tp_richcompare */
2531 0, /* tp_weaklistoffset */
2532 0, /* tp_iter */
2533 0, /* tp_iternext */
2534 0, /* tp_methods */
2535 codec_info_members, /* tp_members */
2536 0, /* tp_getset */
2537 0, /* tp_base */
2538 0, /* tp_dict */
2539 0, /* tp_descr_get */
2540 0, /* tp_descr_set */
2541 0, /* tp_dictoffset */
2542 0, /* tp_init */
2543 0, /* tp_alloc */
2544 codec_info_new, /* tp_new */
2545
2546};
2547
2548/*
2549 * PyObj_pjsua_conf_port_info
2550 * Conf Port Info
2551 */
2552typedef struct
2553{
2554 PyObject_HEAD
2555 /* Type-specific fields go here. */
2556
2557 int slot_id;
2558 PyObject * name;
2559 unsigned clock_rate;
2560 unsigned channel_count;
2561 unsigned samples_per_frame;
2562 unsigned bits_per_sample;
2563 PyListObject * listeners;
2564
2565} PyObj_pjsua_conf_port_info;
2566
2567
2568/*
2569 * conf_port_info_dealloc
2570 * deletes a conf_port_info from memory
2571 */
2572static void conf_port_info_dealloc(PyObj_pjsua_conf_port_info* self)
2573{
2574 Py_XDECREF(self->name);
2575 Py_XDECREF(self->listeners);
2576 self->ob_type->tp_free((PyObject*)self);
2577}
2578
2579
2580/*
2581 * conf_port_info_new
2582 * constructor for conf_port_info object
2583 */
2584static PyObject * conf_port_info_new(PyTypeObject *type, PyObject *args,
2585 PyObject *kwds)
2586{
2587 PyObj_pjsua_conf_port_info *self;
2588
2589 PJ_UNUSED_ARG(args);
2590 PJ_UNUSED_ARG(kwds);
2591
2592 self = (PyObj_pjsua_conf_port_info *)type->tp_alloc(type, 0);
2593 if (self != NULL)
2594 {
2595 self->name = PyString_FromString("");
2596 if (self->name == NULL)
2597 {
2598 Py_DECREF(self);
2599 return NULL;
2600 }
2601
2602 self->listeners = (PyListObject *)PyList_New(0);
2603 if (self->listeners == NULL)
2604 {
2605 Py_DECREF(self);
2606 return NULL;
2607 }
2608 }
2609 return (PyObject *)self;
2610}
2611
2612/*
2613 * conf_port_info_members
2614 */
2615static PyMemberDef conf_port_info_members[] =
2616{
2617 {
2618 "slot_id", T_INT,
2619 offsetof(PyObj_pjsua_conf_port_info, slot_id), 0,
2620 "Conference port number."
2621 },
2622 {
2623 "name", T_OBJECT_EX,
2624 offsetof(PyObj_pjsua_conf_port_info, name), 0,
2625 "Port name"
2626 },
2627 {
2628 "clock_rate", T_INT,
2629 offsetof(PyObj_pjsua_conf_port_info, clock_rate), 0,
2630 "Clock rate"
2631 },
2632 {
2633 "channel_count", T_INT,
2634 offsetof(PyObj_pjsua_conf_port_info, channel_count), 0,
2635 "Number of channels."
2636 },
2637 {
2638 "samples_per_frame", T_INT,
2639 offsetof(PyObj_pjsua_conf_port_info, samples_per_frame), 0,
2640 "Samples per frame "
2641 },
2642 {
2643 "bits_per_sample", T_INT,
2644 offsetof(PyObj_pjsua_conf_port_info, bits_per_sample), 0,
2645 "Bits per sample"
2646 },
2647 {
2648 "listeners", T_OBJECT_EX,
2649 offsetof(PyObj_pjsua_conf_port_info, listeners), 0,
2650 "Array of listeners (in other words, ports where this port "
2651 "is transmitting to"
2652 },
2653
2654 {NULL} /* Sentinel */
2655};
2656
2657
2658
2659
2660/*
2661 * PyTyp_pjsua_conf_port_info
2662 */
2663static PyTypeObject PyTyp_pjsua_conf_port_info =
2664{
2665 PyObject_HEAD_INIT(NULL)
2666 0, /*ob_size*/
2667 "_pjsua.Conf_Port_Info", /*tp_name*/
2668 sizeof(PyObj_pjsua_conf_port_info), /*tp_basicsize*/
2669 0, /*tp_itemsize*/
2670 (destructor)conf_port_info_dealloc,/*tp_dealloc*/
2671 0, /*tp_print*/
2672 0, /*tp_getattr*/
2673 0, /*tp_setattr*/
2674 0, /*tp_compare*/
2675 0, /*tp_repr*/
2676 0, /*tp_as_number*/
2677 0, /*tp_as_sequence*/
2678 0, /*tp_as_mapping*/
2679 0, /*tp_hash */
2680 0, /*tp_call*/
2681 0, /*tp_str*/
2682 0, /*tp_getattro*/
2683 0, /*tp_setattro*/
2684 0, /*tp_as_buffer*/
2685 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2686 "Conf Port Info objects", /* tp_doc */
2687 0, /* tp_traverse */
2688 0, /* tp_clear */
2689 0, /* tp_richcompare */
2690 0, /* tp_weaklistoffset */
2691 0, /* tp_iter */
2692 0, /* tp_iternext */
2693 0, /* tp_methods */
2694 conf_port_info_members, /* tp_members */
2695 0, /* tp_getset */
2696 0, /* tp_base */
2697 0, /* tp_dict */
2698 0, /* tp_descr_get */
2699 0, /* tp_descr_set */
2700 0, /* tp_dictoffset */
2701 0, /* tp_init */
2702 0, /* tp_alloc */
2703 conf_port_info_new, /* tp_new */
2704
2705};
2706
2707/*
2708 * PyObj_pjmedia_port
2709 */
2710typedef struct
2711{
2712 PyObject_HEAD
2713 /* Type-specific fields go here. */
2714 pjmedia_port * port;
2715} PyObj_pjmedia_port;
2716
2717
2718/*
2719 * PyTyp_pjmedia_port
2720 */
2721static PyTypeObject PyTyp_pjmedia_port =
2722{
2723 PyObject_HEAD_INIT(NULL)
2724 0, /*ob_size*/
2725 "_pjsua.PJMedia_Port", /*tp_name*/
2726 sizeof(PyObj_pjmedia_port), /*tp_basicsize*/
2727 0, /*tp_itemsize*/
2728 0, /*tp_dealloc*/
2729 0, /*tp_print*/
2730 0, /*tp_getattr*/
2731 0, /*tp_setattr*/
2732 0, /*tp_compare*/
2733 0, /*tp_repr*/
2734 0, /*tp_as_number*/
2735 0, /*tp_as_sequence*/
2736 0, /*tp_as_mapping*/
2737 0, /*tp_hash */
2738 0, /*tp_call*/
2739 0, /*tp_str*/
2740 0, /*tp_getattro*/
2741 0, /*tp_setattro*/
2742 0, /*tp_as_buffer*/
2743 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2744 "pjmedia_port objects", /* tp_doc */
2745
2746};
2747
2748/*
2749 * PyObj_pjmedia_snd_dev_info
2750 * PJMedia Snd Dev Info
2751 */
2752typedef struct
2753{
2754 PyObject_HEAD
2755 /* Type-specific fields go here. */
2756
2757
2758 unsigned input_count;
2759 unsigned output_count;
2760 unsigned default_samples_per_sec;
2761 PyObject * name;
2762
2763} PyObj_pjmedia_snd_dev_info;
2764
2765
2766/*
2767 * pjmedia_snd_dev_info_dealloc
2768 * deletes a pjmedia_snd_dev_info from memory
2769 */
2770static void pjmedia_snd_dev_info_dealloc(PyObj_pjmedia_snd_dev_info* self)
2771{
2772 Py_XDECREF(self->name);
2773 self->ob_type->tp_free((PyObject*)self);
2774}
2775
2776
2777/*
2778 * pjmedia_snd_dev_info_new
2779 * constructor for pjmedia_snd_dev_info object
2780 */
2781static PyObject * pjmedia_snd_dev_info_new(PyTypeObject *type, PyObject *args,
2782 PyObject *kwds)
2783{
2784 PyObj_pjmedia_snd_dev_info *self;
2785
2786 PJ_UNUSED_ARG(args);
2787 PJ_UNUSED_ARG(kwds);
2788
2789 self = (PyObj_pjmedia_snd_dev_info *)type->tp_alloc(type, 0);
2790 if (self != NULL)
2791 {
2792 self->name = PyString_FromString("");
2793 if (self->name == NULL)
2794 {
2795 Py_DECREF(self);
2796 return NULL;
2797 }
2798
2799 }
2800 return (PyObject *)self;
2801}
2802
2803/*
2804 * pjmedia_snd_dev_info_members
2805 */
2806static PyMemberDef pjmedia_snd_dev_info_members[] =
2807{
2808
2809 {
2810 "name", T_OBJECT_EX,
2811 offsetof(PyObj_pjmedia_snd_dev_info, name), 0,
2812 "Device name"
2813 },
2814 {
2815 "input_count", T_INT,
2816 offsetof(PyObj_pjmedia_snd_dev_info, input_count), 0,
2817 "Max number of input channels"
2818 },
2819 {
2820 "output_count", T_INT,
2821 offsetof(PyObj_pjmedia_snd_dev_info, output_count), 0,
2822 "Max number of output channels"
2823 },
2824 {
2825 "default_samples_per_sec", T_INT,
2826 offsetof(PyObj_pjmedia_snd_dev_info, default_samples_per_sec), 0,
2827 "Default sampling rate."
2828 },
2829
2830
2831 {NULL} /* Sentinel */
2832};
2833
2834
2835
2836
2837/*
2838 * PyTyp_pjmedia_snd_dev_info
2839 */
2840static PyTypeObject PyTyp_pjmedia_snd_dev_info =
2841{
2842 PyObject_HEAD_INIT(NULL)
2843 0, /*ob_size*/
2844 "_pjsua.PJMedia_Snd_Dev_Info", /*tp_name*/
2845 sizeof(PyObj_pjmedia_snd_dev_info), /*tp_basicsize*/
2846 0, /*tp_itemsize*/
2847 (destructor)pjmedia_snd_dev_info_dealloc,/*tp_dealloc*/
2848 0, /*tp_print*/
2849 0, /*tp_getattr*/
2850 0, /*tp_setattr*/
2851 0, /*tp_compare*/
2852 0, /*tp_repr*/
2853 0, /*tp_as_number*/
2854 0, /*tp_as_sequence*/
2855 0, /*tp_as_mapping*/
2856 0, /*tp_hash */
2857 0, /*tp_call*/
2858 0, /*tp_str*/
2859 0, /*tp_getattro*/
2860 0, /*tp_setattro*/
2861 0, /*tp_as_buffer*/
2862 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2863 "PJMedia Snd Dev Info objects", /* tp_doc */
2864 0, /* tp_traverse */
2865 0, /* tp_clear */
2866 0, /* tp_richcompare */
2867 0, /* tp_weaklistoffset */
2868 0, /* tp_iter */
2869 0, /* tp_iternext */
2870 0, /* tp_methods */
2871 pjmedia_snd_dev_info_members, /* tp_members */
2872 0, /* tp_getset */
2873 0, /* tp_base */
2874 0, /* tp_dict */
2875 0, /* tp_descr_get */
2876 0, /* tp_descr_set */
2877 0, /* tp_dictoffset */
2878 0, /* tp_init */
2879 0, /* tp_alloc */
2880 pjmedia_snd_dev_info_new, /* tp_new */
2881
2882};
2883
2884/*
2885 * PyObj_pjmedia_codec_param_info
2886 * PJMedia Codec Param Info
2887 */
2888typedef struct
2889{
2890 PyObject_HEAD
2891 /* Type-specific fields go here. */
2892
2893 unsigned clock_rate;
2894 unsigned channel_cnt;
2895 pj_uint32_t avg_bps;
2896 pj_uint16_t frm_ptime;
2897 pj_uint8_t pcm_bits_per_sample;
2898 pj_uint8_t pt;
2899
2900} PyObj_pjmedia_codec_param_info;
2901
2902
2903
2904/*
2905 * pjmedia_codec_param_info_members
2906 */
2907static PyMemberDef pjmedia_codec_param_info_members[] =
2908{
2909
2910 {
2911 "clock_rate", T_INT,
2912 offsetof(PyObj_pjmedia_codec_param_info, clock_rate), 0,
2913 "Sampling rate in Hz"
2914 },
2915 {
2916 "channel_cnt", T_INT,
2917 offsetof(PyObj_pjmedia_codec_param_info, channel_cnt), 0,
2918 "Channel count"
2919 },
2920 {
2921 "avg_bps", T_INT,
2922 offsetof(PyObj_pjmedia_codec_param_info, avg_bps), 0,
2923 "Average bandwidth in bits/sec"
2924 },
2925 {
2926 "frm_ptime", T_INT,
2927 offsetof(PyObj_pjmedia_codec_param_info, frm_ptime), 0,
2928 "Base frame ptime in msec."
2929 },
2930 {
2931 "pcm_bits_per_sample", T_INT,
2932 offsetof(PyObj_pjmedia_codec_param_info, pcm_bits_per_sample), 0,
2933 "Bits/sample in the PCM side"
2934 },
2935 {
2936 "pt", T_INT,
2937 offsetof(PyObj_pjmedia_codec_param_info, pt), 0,
2938 "Payload type"
2939 },
2940
2941 {NULL} /* Sentinel */
2942};
2943
2944
2945
2946
2947/*
2948 * PyTyp_pjmedia_codec_param_info
2949 */
2950static PyTypeObject PyTyp_pjmedia_codec_param_info =
2951{
2952 PyObject_HEAD_INIT(NULL)
2953 0, /*ob_size*/
2954 "_pjsua.PJMedia_Codec_Param_Info", /*tp_name*/
2955 sizeof(PyObj_pjmedia_codec_param_info), /*tp_basicsize*/
2956 0, /*tp_itemsize*/
2957 0,/*tp_dealloc*/
2958 0, /*tp_print*/
2959 0, /*tp_getattr*/
2960 0, /*tp_setattr*/
2961 0, /*tp_compare*/
2962 0, /*tp_repr*/
2963 0, /*tp_as_number*/
2964 0, /*tp_as_sequence*/
2965 0, /*tp_as_mapping*/
2966 0, /*tp_hash */
2967 0, /*tp_call*/
2968 0, /*tp_str*/
2969 0, /*tp_getattro*/
2970 0, /*tp_setattro*/
2971 0, /*tp_as_buffer*/
2972 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2973 "PJMedia Codec Param Info objects", /* tp_doc */
2974 0, /* tp_traverse */
2975 0, /* tp_clear */
2976 0, /* tp_richcompare */
2977 0, /* tp_weaklistoffset */
2978 0, /* tp_iter */
2979 0, /* tp_iternext */
2980 0, /* tp_methods */
2981 pjmedia_codec_param_info_members, /* tp_members */
2982
2983
2984};
2985
2986/*
2987 * PyObj_pjmedia_codec_param_setting
2988 * PJMedia Codec Param Setting
2989 */
2990typedef struct
2991{
2992 PyObject_HEAD
2993 /* Type-specific fields go here. */
2994 pj_uint8_t frm_per_pkt;
2995 unsigned vad;
2996 unsigned cng;
2997 unsigned penh;
2998 unsigned plc;
2999 unsigned reserved;
3000 pj_uint8_t enc_fmtp_mode;
3001 pj_uint8_t dec_fmtp_mode;
3002
3003} PyObj_pjmedia_codec_param_setting;
3004
3005
3006
3007/*
3008 * pjmedia_codec_param_setting_members
3009 */
3010static PyMemberDef pjmedia_codec_param_setting_members[] =
3011{
3012
3013 {
3014 "frm_per_pkt", T_INT,
3015 offsetof(PyObj_pjmedia_codec_param_setting, frm_per_pkt), 0,
3016 "Number of frames per packet"
3017 },
3018 {
3019 "vad", T_INT,
3020 offsetof(PyObj_pjmedia_codec_param_setting, vad), 0,
3021 "Voice Activity Detector"
3022 },
3023 {
3024 "penh", T_INT,
3025 offsetof(PyObj_pjmedia_codec_param_setting, penh), 0,
3026 "Perceptual Enhancement"
3027 },
3028 {
3029 "plc", T_INT,
3030 offsetof(PyObj_pjmedia_codec_param_setting, plc), 0,
3031 "Packet loss concealment"
3032 },
3033 {
3034 "reserved", T_INT,
3035 offsetof(PyObj_pjmedia_codec_param_setting, reserved), 0,
3036 "Reserved, must be zero"
3037 },
3038 {
3039 "cng", T_INT,
3040 offsetof(PyObj_pjmedia_codec_param_setting, cng), 0,
3041 "Comfort Noise Generator"
3042 },
3043 {
3044 "enc_fmtp_mode", T_INT,
3045 offsetof(PyObj_pjmedia_codec_param_setting, enc_fmtp_mode), 0,
3046 "Mode param in fmtp (def:0)"
3047 },
3048 {
3049 "dec_fmtp_mode", T_INT,
3050 offsetof(PyObj_pjmedia_codec_param_setting, dec_fmtp_mode), 0,
3051 "Mode param in fmtp (def:0)"
3052 },
3053
3054 {NULL} /* Sentinel */
3055};
3056
3057
3058
3059
3060/*
3061 * PyTyp_pjmedia_codec_param_setting
3062 */
3063static PyTypeObject PyTyp_pjmedia_codec_param_setting =
3064{
3065 PyObject_HEAD_INIT(NULL)
3066 0, /*ob_size*/
3067 "_pjsua.PJMedia_Codec_Param_Setting", /*tp_name*/
3068 sizeof(PyObj_pjmedia_codec_param_setting), /*tp_basicsize*/
3069 0, /*tp_itemsize*/
3070 0,/*tp_dealloc*/
3071 0, /*tp_print*/
3072 0, /*tp_getattr*/
3073 0, /*tp_setattr*/
3074 0, /*tp_compare*/
3075 0, /*tp_repr*/
3076 0, /*tp_as_number*/
3077 0, /*tp_as_sequence*/
3078 0, /*tp_as_mapping*/
3079 0, /*tp_hash */
3080 0, /*tp_call*/
3081 0, /*tp_str*/
3082 0, /*tp_getattro*/
3083 0, /*tp_setattro*/
3084 0, /*tp_as_buffer*/
3085 Py_TPFLAGS_DEFAULT, /*tp_flags*/
3086 "PJMedia Codec Param Setting objects", /* tp_doc */
3087 0, /* tp_traverse */
3088 0, /* tp_clear */
3089 0, /* tp_richcompare */
3090 0, /* tp_weaklistoffset */
3091 0, /* tp_iter */
3092 0, /* tp_iternext */
3093 0, /* tp_methods */
3094 pjmedia_codec_param_setting_members, /* tp_members */
3095
3096
3097};
3098
3099/*
3100 * PyObj_pjmedia_codec_param
3101 * PJMedia Codec Param
3102 */
3103typedef struct
3104{
3105 PyObject_HEAD
3106 /* Type-specific fields go here. */
3107
3108 PyObj_pjmedia_codec_param_info * info;
3109 PyObj_pjmedia_codec_param_setting * setting;
3110
3111} PyObj_pjmedia_codec_param;
3112
3113
3114/*
3115 * pjmedia_codec_param_dealloc
3116 * deletes a pjmedia_codec_param from memory
3117 */
3118static void pjmedia_codec_param_dealloc(PyObj_pjmedia_codec_param* self)
3119{
3120 Py_XDECREF(self->info);
3121 Py_XDECREF(self->setting);
3122 self->ob_type->tp_free((PyObject*)self);
3123}
3124
3125
3126/*
3127 * pjmedia_codec_param_new
3128 * constructor for pjmedia_codec_param object
3129 */
3130static PyObject * pjmedia_codec_param_new(PyTypeObject *type, PyObject *args,
3131 PyObject *kwds)
3132{
3133 PyObj_pjmedia_codec_param *self;
3134
3135 PJ_UNUSED_ARG(args);
3136 PJ_UNUSED_ARG(kwds);
3137
3138 self = (PyObj_pjmedia_codec_param *)type->tp_alloc(type, 0);
3139 if (self != NULL)
3140 {
3141 self->info = (PyObj_pjmedia_codec_param_info *)
3142 PyType_GenericNew(&PyTyp_pjmedia_codec_param_info, NULL, NULL);
3143 if (self->info == NULL)
3144 {
3145 Py_DECREF(self);
3146 return NULL;
3147 }
3148 self->setting = (PyObj_pjmedia_codec_param_setting *)
3149 PyType_GenericNew(&PyTyp_pjmedia_codec_param_setting, NULL, NULL);
3150 if (self->setting == NULL)
3151 {
3152 Py_DECREF(self);
3153 return NULL;
3154 }
3155 }
3156 return (PyObject *)self;
3157}
3158
3159/*
3160 * pjmedia_codec_param_members
3161 */
3162static PyMemberDef pjmedia_codec_param_members[] =
3163{
3164
3165 {
3166 "info", T_OBJECT_EX,
3167 offsetof(PyObj_pjmedia_codec_param, info), 0,
3168 "The 'info' part of codec param describes the capability of the codec,"
3169 " and the value should NOT be changed by application."
3170 },
3171 {
3172 "setting", T_OBJECT_EX,
3173 offsetof(PyObj_pjmedia_codec_param, setting), 0,
3174 "The 'setting' part of codec param describes various settings to be "
3175 "applied to the codec. When the codec param is retrieved from the "
3176 "codec or codec factory, the values of these will be filled by "
3177 "the capability of the codec. Any features that are supported by "
3178 "the codec (e.g. vad or plc) will be turned on, so that application "
3179 "can query which capabilities are supported by the codec. "
3180 "Application may change the settings here before instantiating "
3181 "the codec/stream."
3182 },
3183
3184 {NULL} /* Sentinel */
3185};
3186
3187
3188
3189
3190/*
3191 * PyTyp_pjmedia_codec_param
3192 */
3193static PyTypeObject PyTyp_pjmedia_codec_param =
3194{
3195 PyObject_HEAD_INIT(NULL)
3196 0, /*ob_size*/
3197 "_pjsua.PJMedia_Codec_Param", /*tp_name*/
3198 sizeof(PyObj_pjmedia_codec_param), /*tp_basicsize*/
3199 0, /*tp_itemsize*/
3200 (destructor)pjmedia_codec_param_dealloc,/*tp_dealloc*/
3201 0, /*tp_print*/
3202 0, /*tp_getattr*/
3203 0, /*tp_setattr*/
3204 0, /*tp_compare*/
3205 0, /*tp_repr*/
3206 0, /*tp_as_number*/
3207 0, /*tp_as_sequence*/
3208 0, /*tp_as_mapping*/
3209 0, /*tp_hash */
3210 0, /*tp_call*/
3211 0, /*tp_str*/
3212 0, /*tp_getattro*/
3213 0, /*tp_setattro*/
3214 0, /*tp_as_buffer*/
3215 Py_TPFLAGS_DEFAULT, /*tp_flags*/
3216 "PJMedia Codec Param objects", /* tp_doc */
3217 0, /* tp_traverse */
3218 0, /* tp_clear */
3219 0, /* tp_richcompare */
3220 0, /* tp_weaklistoffset */
3221 0, /* tp_iter */
3222 0, /* tp_iternext */
3223 0, /* tp_methods */
3224 pjmedia_codec_param_members, /* tp_members */
3225 0, /* tp_getset */
3226 0, /* tp_base */
3227 0, /* tp_dict */
3228 0, /* tp_descr_get */
3229 0, /* tp_descr_set */
3230 0, /* tp_dictoffset */
3231 0, /* tp_init */
3232 0, /* tp_alloc */
3233 pjmedia_codec_param_new, /* tp_new */
3234
3235};
3236
3237/*
3238 * py_pjsua_conf_get_max_ports
3239 */
3240static PyObject *py_pjsua_conf_get_max_ports
3241(PyObject *pSelf, PyObject *pArgs)
3242{
3243 int ret;
3244
3245 PJ_UNUSED_ARG(pSelf);
3246
3247 if (!PyArg_ParseTuple(pArgs, ""))
3248 {
3249 return NULL;
3250 }
3251 ret = pjsua_conf_get_max_ports();
3252
3253 return Py_BuildValue("i", ret);
3254}
3255
3256/*
3257 * py_pjsua_conf_get_active_ports
3258 */
3259static PyObject *py_pjsua_conf_get_active_ports
3260(PyObject *pSelf, PyObject *pArgs)
3261{
3262 int ret;
3263
3264 PJ_UNUSED_ARG(pSelf);
3265
3266 if (!PyArg_ParseTuple(pArgs, ""))
3267 {
3268 return NULL;
3269 }
3270 ret = pjsua_conf_get_active_ports();
3271
3272 return Py_BuildValue("i", ret);
3273}
3274
3275/*
3276 * py_pjsua_enum_conf_ports
3277 * !modified @ 241206
3278 */
3279static PyObject *py_pjsua_enum_conf_ports(PyObject *pSelf, PyObject *pArgs)
3280{
3281 pj_status_t status;
3282 PyObject *list;
3283
3284 pjsua_conf_port_id id[PJSUA_MAX_CONF_PORTS];
3285 unsigned c, i;
3286
3287 PJ_UNUSED_ARG(pSelf);
3288
3289 if (!PyArg_ParseTuple(pArgs, ""))
3290 {
3291 return NULL;
3292 }
3293
3294 c = PJ_ARRAY_SIZE(id);
3295 status = pjsua_enum_conf_ports(id, &c);
3296
3297 list = PyList_New(c);
3298 for (i = 0; i < c; i++)
3299 {
3300 int ret = PyList_SetItem(list, i, Py_BuildValue("i", id[i]));
3301 if (ret == -1)
3302 {
3303 return NULL;
3304 }
3305 }
3306
3307 return Py_BuildValue("O",list);
3308}
3309
3310/*
3311 * py_pjsua_conf_get_port_info
3312 */
3313static PyObject *py_pjsua_conf_get_port_info
3314(PyObject *pSelf, PyObject *pArgs)
3315{
3316 int id;
3317 PyObj_pjsua_conf_port_info * obj;
3318 pjsua_conf_port_info info;
3319 int status;
3320 unsigned i;
3321
3322 PJ_UNUSED_ARG(pSelf);
3323
3324 if (!PyArg_ParseTuple(pArgs, "i", &id))
3325 {
3326 return NULL;
3327 }
3328
3329
3330 status = pjsua_conf_get_port_info(id, &info);
3331 obj = (PyObj_pjsua_conf_port_info *)conf_port_info_new
3332 (&PyTyp_pjsua_conf_port_info,NULL,NULL);
3333 obj->bits_per_sample = info.bits_per_sample;
3334 obj->channel_count = info.bits_per_sample;
3335 obj->clock_rate = info.clock_rate;
3336 obj->name = PyString_FromStringAndSize(info.name.ptr, info.name.slen);
3337 obj->samples_per_frame = info.samples_per_frame;
3338 obj->slot_id = info.slot_id;
3339
3340 obj->listeners = (PyListObject *)PyList_New(info.listener_cnt);
3341 for (i = 0; i < info.listener_cnt; i++) {
3342 PyObject * item = Py_BuildValue("i",info.listeners[i]);
3343 PyList_SetItem((PyObject *)obj->listeners, i, item);
3344 }
3345 return Py_BuildValue("O", obj);
3346}
3347
3348/*
3349 * py_pjsua_conf_add_port
3350 */
3351static PyObject *py_pjsua_conf_add_port
3352(PyObject *pSelf, PyObject *pArgs)
3353{
3354 int p_id;
3355 PyObject * oportObj;
3356 PyObj_pjmedia_port * oport;
3357 pjmedia_port * port;
3358 PyObject * opoolObj;
3359 PyObj_pj_pool * opool;
3360 pj_pool_t * pool;
3361
3362 int status;
3363
3364 PJ_UNUSED_ARG(pSelf);
3365
3366 if (!PyArg_ParseTuple(pArgs, "OO", &opoolObj, &oportObj))
3367 {
3368 return NULL;
3369 }
3370 if (opoolObj != Py_None)
3371 {
3372 opool = (PyObj_pj_pool *)opoolObj;
3373 pool = opool->pool;
3374 } else {
3375 opool = NULL;
3376 pool = NULL;
3377 }
3378 if (oportObj != Py_None)
3379 {
3380 oport = (PyObj_pjmedia_port *)oportObj;
3381 port = oport->port;
3382 } else {
3383 oport = NULL;
3384 port = NULL;
3385 }
3386
3387 status = pjsua_conf_add_port(pool, port, &p_id);
3388
3389
3390 return Py_BuildValue("ii", status, p_id);
3391}
3392
3393/*
3394 * py_pjsua_conf_remove_port
3395 */
3396static PyObject *py_pjsua_conf_remove_port
3397(PyObject *pSelf, PyObject *pArgs)
3398{
3399 int id;
3400 int status;
3401
3402 PJ_UNUSED_ARG(pSelf);
3403
3404 if (!PyArg_ParseTuple(pArgs, "i", &id))
3405 {
3406 return NULL;
3407 }
3408
3409 status = pjsua_conf_remove_port(id);
3410
3411
3412 return Py_BuildValue("i", status);
3413}
3414
3415/*
3416 * py_pjsua_conf_connect
3417 */
3418static PyObject *py_pjsua_conf_connect
3419(PyObject *pSelf, PyObject *pArgs)
3420{
3421 int source, sink;
3422 int status;
3423
3424 PJ_UNUSED_ARG(pSelf);
3425
3426 if (!PyArg_ParseTuple(pArgs, "ii", &source, &sink))
3427 {
3428 return NULL;
3429 }
3430
3431 status = pjsua_conf_connect(source, sink);
3432
3433
3434 return Py_BuildValue("i", status);
3435}
3436
3437/*
3438 * py_pjsua_conf_disconnect
3439 */
3440static PyObject *py_pjsua_conf_disconnect
3441(PyObject *pSelf, PyObject *pArgs)
3442{
3443 int source, sink;
3444 int status;
3445
3446 PJ_UNUSED_ARG(pSelf);
3447
3448 if (!PyArg_ParseTuple(pArgs, "ii", &source, &sink))
3449 {
3450 return NULL;
3451 }
3452
3453 status = pjsua_conf_disconnect(source, sink);
3454
3455
3456 return Py_BuildValue("i", status);
3457}
3458
3459/*
3460 * py_pjsua_player_create
3461 */
3462static PyObject *py_pjsua_player_create
3463(PyObject *pSelf, PyObject *pArgs)
3464{
3465 int id;
3466 int options;
3467 PyObject * filename;
3468 pj_str_t str;
3469 int status;
3470
3471 PJ_UNUSED_ARG(pSelf);
3472
3473 if (!PyArg_ParseTuple(pArgs, "Oi", &filename, &options))
3474 {
3475 return NULL;
3476 }
3477 str.ptr = PyString_AsString(filename);
3478 str.slen = strlen(PyString_AsString(filename));
3479 status = pjsua_player_create(&str, options, &id);
3480
3481 return Py_BuildValue("ii", status, id);
3482}
3483
3484/*
3485 * py_pjsua_player_get_conf_port
3486 */
3487static PyObject *py_pjsua_player_get_conf_port
3488(PyObject *pSelf, PyObject *pArgs)
3489{
3490
3491 int id, port_id;
3492
3493 PJ_UNUSED_ARG(pSelf);
3494
3495 if (!PyArg_ParseTuple(pArgs, "i", &id))
3496 {
3497 return NULL;
3498 }
3499
3500 port_id = pjsua_player_get_conf_port(id);
3501
3502
3503 return Py_BuildValue("i", port_id);
3504}
3505
3506/*
3507 * py_pjsua_player_set_pos
3508 */
3509static PyObject *py_pjsua_player_set_pos
3510(PyObject *pSelf, PyObject *pArgs)
3511{
3512 int id;
3513 pj_uint32_t samples;
3514 int status;
3515
3516 PJ_UNUSED_ARG(pSelf);
3517
3518 if (!PyArg_ParseTuple(pArgs, "iI", &id, &samples))
3519 {
3520 return NULL;
3521 }
3522
3523 status = pjsua_player_set_pos(id, samples);
3524
3525
3526 return Py_BuildValue("i", status);
3527}
3528
3529/*
3530 * py_pjsua_player_destroy
3531 */
3532static PyObject *py_pjsua_player_destroy
3533(PyObject *pSelf, PyObject *pArgs)
3534{
3535 int id;
3536 int status;
3537
3538 PJ_UNUSED_ARG(pSelf);
3539
3540 if (!PyArg_ParseTuple(pArgs, "i", &id))
3541 {
3542 return NULL;
3543 }
3544
3545 status = pjsua_player_destroy(id);
3546
3547
3548 return Py_BuildValue("i", status);
3549}
3550
3551/*
3552 * py_pjsua_recorder_create
3553 * !modified @ 261206
3554 */
3555static PyObject *py_pjsua_recorder_create
3556(PyObject *pSelf, PyObject *pArgs)
3557{
3558 int p_id;
3559 int options;
3560 int max_size;
3561 PyObject * filename;
3562 pj_str_t str;
3563 PyObject * enc_param;
3564 pj_str_t strparam;
3565 int enc_type;
3566
3567 int status;
3568
3569 PJ_UNUSED_ARG(pSelf);
3570
3571 if (!PyArg_ParseTuple(pArgs, "OiOii", &filename,
3572 &enc_type, &enc_param, &max_size, &options))
3573 {
3574 return NULL;
3575 }
3576 str.ptr = PyString_AsString(filename);
3577 str.slen = strlen(PyString_AsString(filename));
3578 if (enc_param != Py_None)
3579 {
3580 strparam.ptr = PyString_AsString(enc_param);
3581 strparam.slen = strlen(PyString_AsString(enc_param));
3582 status = pjsua_recorder_create
3583 (&str, enc_type, NULL, max_size, options, &p_id);
3584 } else {
3585 status = pjsua_recorder_create
3586 (&str, enc_type, NULL, max_size, options, &p_id);
3587 }
3588 return Py_BuildValue("ii", status, p_id);
3589}
3590
3591/*
3592 * py_pjsua_recorder_get_conf_port
3593 */
3594static PyObject *py_pjsua_recorder_get_conf_port
3595(PyObject *pSelf, PyObject *pArgs)
3596{
3597
3598 int id, port_id;
3599
3600 PJ_UNUSED_ARG(pSelf);
3601
3602 if (!PyArg_ParseTuple(pArgs, "i", &id))
3603 {
3604 return NULL;
3605 }
3606
3607 port_id = pjsua_recorder_get_conf_port(id);
3608
3609
3610 return Py_BuildValue("i", port_id);
3611}
3612
3613/*
3614 * py_pjsua_recorder_destroy
3615 */
3616static PyObject *py_pjsua_recorder_destroy
3617(PyObject *pSelf, PyObject *pArgs)
3618{
3619 int id;
3620 int status;
3621
3622 PJ_UNUSED_ARG(pSelf);
3623
3624 if (!PyArg_ParseTuple(pArgs, "i", &id))
3625 {
3626 return NULL;
3627 }
3628
3629 status = pjsua_recorder_destroy(id);
3630
3631
3632 return Py_BuildValue("i", status);
3633}
3634
3635/*
3636 * py_pjsua_enum_snd_devs
3637 */
3638static PyObject *py_pjsua_enum_snd_devs(PyObject *pSelf, PyObject *pArgs)
3639{
3640 pj_status_t status;
3641 PyObject *list;
3642
3643 pjmedia_snd_dev_info info[SND_DEV_NUM];
3644 unsigned c, i;
3645
3646 PJ_UNUSED_ARG(pSelf);
3647
3648 if (!PyArg_ParseTuple(pArgs, ""))
3649 {
3650 return NULL;
3651 }
3652
3653 c = PJ_ARRAY_SIZE(info);
3654 status = pjsua_enum_snd_devs(info, &c);
3655
3656 list = PyList_New(c);
3657 for (i = 0; i < c; i++)
3658 {
3659 int ret;
3660 int j;
3661 char * str;
3662
3663 PyObj_pjmedia_snd_dev_info * obj;
3664 obj = (PyObj_pjmedia_snd_dev_info *)pjmedia_snd_dev_info_new
3665 (&PyTyp_pjmedia_snd_dev_info, NULL, NULL);
3666 obj->default_samples_per_sec = info[i].default_samples_per_sec;
3667 obj->input_count = info[i].input_count;
3668 obj->output_count = info[i].output_count;
3669 str = (char *)malloc(SND_NAME_LEN * sizeof(char));
3670 memset(str, 0, SND_NAME_LEN);
3671 for (j = 0; j < SND_NAME_LEN; j++)
3672 {
3673 str[j] = info[i].name[j];
3674 }
3675 obj->name = PyString_FromStringAndSize(str, SND_NAME_LEN);
3676 free(str);
3677 ret = PyList_SetItem(list, i, (PyObject *)obj);
3678 if (ret == -1)
3679 {
3680 return NULL;
3681 }
3682 }
3683
3684 return Py_BuildValue("O",list);
3685}
3686
3687/*
3688 * py_pjsua_get_snd_dev
3689 */
3690static PyObject *py_pjsua_get_snd_dev
3691(PyObject *pSelf, PyObject *pArgs)
3692{
3693 int capture_dev, playback_dev;
3694 int status;
3695
3696 PJ_UNUSED_ARG(pSelf);
3697
3698 if (!PyArg_ParseTuple(pArgs, ""))
3699 {
3700 return NULL;
3701 }
3702
3703 status = pjsua_get_snd_dev(&capture_dev, &playback_dev);
3704
3705
3706 return Py_BuildValue("ii", capture_dev, playback_dev);
3707}
3708
3709/*
3710 * py_pjsua_set_snd_dev
3711 */
3712static PyObject *py_pjsua_set_snd_dev
3713(PyObject *pSelf, PyObject *pArgs)
3714{
3715 int capture_dev, playback_dev;
3716 int status;
3717
3718 PJ_UNUSED_ARG(pSelf);
3719
3720 if (!PyArg_ParseTuple(pArgs, "ii", &capture_dev, &playback_dev))
3721 {
3722 return NULL;
3723 }
3724
3725 status = pjsua_set_snd_dev(capture_dev, playback_dev);
3726
3727
3728 return Py_BuildValue("i", status);
3729}
3730
3731/*
3732 * py_pjsua_set_null_snd_dev
3733 */
3734static PyObject *py_pjsua_set_null_snd_dev
3735(PyObject *pSelf, PyObject *pArgs)
3736{
3737
3738 int status;
3739
3740 PJ_UNUSED_ARG(pSelf);
3741
3742 if (!PyArg_ParseTuple(pArgs, ""))
3743 {
3744 return NULL;
3745 }
3746
3747 status = pjsua_set_null_snd_dev();
3748
3749
3750 return Py_BuildValue("i", status);
3751}
3752
3753/*
3754 * py_pjsua_set_no_snd_dev
3755 */
3756static PyObject *py_pjsua_set_no_snd_dev
3757(PyObject *pSelf, PyObject *pArgs)
3758{
3759
3760 PyObj_pjmedia_port * obj;
3761
3762 PJ_UNUSED_ARG(pSelf);
3763
3764 if (!PyArg_ParseTuple(pArgs, ""))
3765 {
3766 return NULL;
3767 }
3768
3769 obj = (PyObj_pjmedia_port *)PyType_GenericNew
3770 (&PyTyp_pjmedia_port, NULL, NULL);
3771 obj->port = pjsua_set_no_snd_dev();
3772 return Py_BuildValue("O", obj);
3773}
3774
3775/*
3776 * py_pjsua_set_ec
3777 */
3778static PyObject *py_pjsua_set_ec
3779(PyObject *pSelf, PyObject *pArgs)
3780{
3781 int options;
3782 int tail_ms;
3783 int status;
3784
3785 PJ_UNUSED_ARG(pSelf);
3786
3787 if (!PyArg_ParseTuple(pArgs, "ii", &tail_ms, &options))
3788 {
3789 return NULL;
3790 }
3791
3792 status = pjsua_set_ec(tail_ms, options);
3793
3794
3795 return Py_BuildValue("i", status);
3796}
3797
3798/*
3799 * py_pjsua_get_ec_tail
3800 */
3801static PyObject *py_pjsua_get_ec_tail
3802(PyObject *pSelf, PyObject *pArgs)
3803{
3804
3805 int status;
3806 unsigned p_tail_ms;
3807
3808 PJ_UNUSED_ARG(pSelf);
3809
3810 if (!PyArg_ParseTuple(pArgs, ""))
3811 {
3812 return NULL;
3813 }
3814
3815 status = pjsua_get_ec_tail(&p_tail_ms);
3816
3817
3818 return Py_BuildValue("i", p_tail_ms);
3819}
3820
3821/*
3822 * py_pjsua_enum_codecs
3823 * !modified @ 261206
3824 */
3825static PyObject *py_pjsua_enum_codecs(PyObject *pSelf, PyObject *pArgs)
3826{
3827 pj_status_t status;
3828 PyObject *list;
3829
3830 pjsua_codec_info info[PJMEDIA_CODEC_MGR_MAX_CODECS];
3831 unsigned c, i;
3832
3833 PJ_UNUSED_ARG(pSelf);
3834
3835 if (!PyArg_ParseTuple(pArgs, ""))
3836 {
3837 return NULL;
3838 }
3839
3840 c = PJ_ARRAY_SIZE(info);
3841 status = pjsua_enum_codecs(info, &c);
3842
3843 list = PyList_New(c);
3844 for (i = 0; i < c; i++)
3845 {
3846 int ret;
3847 int j;
3848 PyObj_pjsua_codec_info * obj;
3849 obj = (PyObj_pjsua_codec_info *)codec_info_new
3850 (&PyTyp_pjsua_codec_info, NULL, NULL);
3851 obj->codec_id = PyString_FromStringAndSize
3852 (info[i].codec_id.ptr, info[i].codec_id.slen);
3853 obj->priority = info[i].priority;
3854 for (j = 0; j < 32; j++)
3855 {
3856 obj->buf_[j] = info[i].buf_[j];
3857 }
3858 ret = PyList_SetItem(list, i, (PyObject *)obj);
3859 if (ret == -1) {
3860 return NULL;
3861 }
3862 }
3863
3864
3865 return Py_BuildValue("O",list);
3866}
3867
3868/*
3869 * py_pjsua_codec_set_priority
3870 */
3871static PyObject *py_pjsua_codec_set_priority
3872(PyObject *pSelf, PyObject *pArgs)
3873{
3874
3875 int status;
3876 PyObject * id;
3877 pj_str_t str;
3878 pj_uint8_t priority;
3879
3880 PJ_UNUSED_ARG(pSelf);
3881
3882 if (!PyArg_ParseTuple(pArgs, "OB", &id, &priority))
3883 {
3884 return NULL;
3885 }
3886 str.ptr = PyString_AsString(id);
3887 str.slen = strlen(PyString_AsString(id));
3888 status = pjsua_codec_set_priority(&str, priority);
3889
3890
3891 return Py_BuildValue("i", status);
3892}
3893
3894/*
3895 * py_pjsua_codec_get_param
3896 */
3897static PyObject *py_pjsua_codec_get_param
3898(PyObject *pSelf, PyObject *pArgs)
3899{
3900
3901 int status;
3902 PyObject * id;
3903 pj_str_t str;
3904 pjmedia_codec_param param;
3905 PyObj_pjmedia_codec_param *obj;
3906
3907 PJ_UNUSED_ARG(pSelf);
3908
3909 if (!PyArg_ParseTuple(pArgs, "O", &id))
3910 {
3911 return NULL;
3912 }
3913 str.ptr = PyString_AsString(id);
3914 str.slen = strlen(PyString_AsString(id));
3915 status = pjsua_codec_get_param(&str, &param);
3916 obj = (PyObj_pjmedia_codec_param *)pjmedia_codec_param_new
3917 (&PyTyp_pjmedia_codec_param, NULL, NULL);
3918 obj->info->avg_bps = param.info.avg_bps;
3919 obj->info->channel_cnt = param.info.channel_cnt;
3920 obj->info->clock_rate = param.info.clock_rate;
3921 obj->info->frm_ptime = param.info.frm_ptime;
3922 obj->info->pcm_bits_per_sample = param.info.pcm_bits_per_sample;
3923 obj->info->pt = param.info.pt;
3924 obj->setting->cng = param.setting.cng;
3925 obj->setting->dec_fmtp_mode = param.setting.dec_fmtp_mode;
3926 obj->setting->enc_fmtp_mode = param.setting.enc_fmtp_mode;
3927 obj->setting->frm_per_pkt = param.setting.frm_per_pkt;
3928 obj->setting->penh = param.setting.penh;
3929 obj->setting->plc = param.setting.plc;
3930 obj->setting->reserved = param.setting.reserved;
3931 obj->setting->vad = param.setting.vad;
3932
3933 return Py_BuildValue("O", obj);
3934}
3935/*
3936 * py_pjsua_codec_set_param
3937 */
3938static PyObject *py_pjsua_codec_set_param
3939(PyObject *pSelf, PyObject *pArgs)
3940{
3941
3942 int status;
3943 PyObject * id;
3944 pj_str_t str;
3945 pjmedia_codec_param param;
3946 PyObject * tmpObj;
3947 PyObj_pjmedia_codec_param *obj;
3948
3949 PJ_UNUSED_ARG(pSelf);
3950
3951 if (!PyArg_ParseTuple(pArgs, "OO", &id, &tmpObj))
3952 {
3953 return NULL;
3954 }
3955
3956 str.ptr = PyString_AsString(id);
3957 str.slen = strlen(PyString_AsString(id));
3958 if (tmpObj != Py_None)
3959 {
3960 obj = (PyObj_pjmedia_codec_param *)tmpObj;
3961 param.info.avg_bps = obj->info->avg_bps;
3962 param.info.channel_cnt = obj->info->channel_cnt;
3963 param.info.clock_rate = obj->info->clock_rate;
3964 param.info.frm_ptime = obj->info->frm_ptime;
3965 param.info.pcm_bits_per_sample = obj->info->pcm_bits_per_sample;
3966 param.info.pt = obj->info->pt;
3967 param.setting.cng = obj->setting->cng;
3968 param.setting.dec_fmtp_mode = obj->setting->dec_fmtp_mode;
3969 param.setting.enc_fmtp_mode = obj->setting->enc_fmtp_mode;
3970 param.setting.frm_per_pkt = obj->setting->frm_per_pkt;
3971 param.setting.penh = obj->setting->penh;
3972 param.setting.plc = obj->setting->plc;
3973 param.setting.reserved = obj->setting->reserved;
3974 param.setting.vad = obj->setting->vad;
3975 status = pjsua_codec_set_param(&str, &param);
3976 } else {
3977 status = pjsua_codec_set_param(&str, NULL);
3978 }
3979 return Py_BuildValue("i", status);
3980}
3981
3982static char pjsua_conf_get_max_ports_doc[] =
3983 "int _pjsua.conf_get_max_ports () "
3984 "Get maxinum number of conference ports.";
3985static char pjsua_conf_get_active_ports_doc[] =
3986 "int _pjsua.conf_get_active_ports () "
3987 "Get current number of active ports in the bridge.";
3988static char pjsua_enum_conf_ports_doc[] =
3989 "int[] _pjsua.enum_conf_ports () "
3990 "Enumerate all conference ports.";
3991static char pjsua_conf_get_port_info_doc[] =
3992 "_pjsua.Conf_Port_Info _pjsua.conf_get_port_info (int id) "
3993 "Get information about the specified conference port";
3994static char pjsua_conf_add_port_doc[] =
3995 "int, int _pjsua.conf_add_port "
3996 "(_pjsua.Pj_Pool pool, _pjsua.PJMedia_Port port) "
3997 "Add arbitrary media port to PJSUA's conference bridge. "
3998 "Application can use this function to add the media port "
3999 "that it creates. For media ports that are created by PJSUA-LIB "
4000 "(such as calls, file player, or file recorder), PJSUA-LIB will "
4001 "automatically add the port to the bridge.";
4002static char pjsua_conf_remove_port_doc[] =
4003 "int _pjsua.conf_remove_port (int id) "
4004 "Remove arbitrary slot from the conference bridge. "
4005 "Application should only call this function "
4006 "if it registered the port manually.";
4007static char pjsua_conf_connect_doc[] =
4008 "int _pjsua.conf_connect (int source, int sink) "
4009 "Establish unidirectional media flow from souce to sink. "
4010 "One source may transmit to multiple destinations/sink. "
4011 "And if multiple sources are transmitting to the same sink, "
4012 "the media will be mixed together. Source and sink may refer "
4013 "to the same ID, effectively looping the media. "
4014 "If bidirectional media flow is desired, application "
4015 "needs to call this function twice, with the second "
4016 "one having the arguments reversed.";
4017static char pjsua_conf_disconnect_doc[] =
4018 "int _pjsua.conf_disconnect (int source, int sink) "
4019 "Disconnect media flow from the source to destination port.";
4020static char pjsua_player_create_doc[] =
4021 "int, int _pjsua.player_create (string filename, int options) "
4022 "Create a file player, and automatically connect "
4023 "this player to the conference bridge.";
4024static char pjsua_player_get_conf_port_doc[] =
4025 "int _pjsua.player_get_conf_port (int) "
4026 "Get conference port ID associated with player.";
4027static char pjsua_player_set_pos_doc[] =
4028 "int _pjsua.player_set_pos (int id, int samples) "
4029 "Set playback position.";
4030static char pjsua_player_destroy_doc[] =
4031 "int _pjsua.player_destroy (int id) "
4032 "Close the file, remove the player from the bridge, "
4033 "and free resources associated with the file player.";
4034static char pjsua_recorder_create_doc[] =
4035 "int, int _pjsua.recorder_create (string filename, "
4036 "int enc_type, int enc_param, int max_size, int options) "
4037 "Create a file recorder, and automatically connect this recorder "
4038 "to the conference bridge. The recorder currently supports recording "
4039 "WAV file, and on Windows, MP3 file. The type of the recorder to use "
4040 "is determined by the extension of the file (e.g. '.wav' or '.mp3').";
4041static char pjsua_recorder_get_conf_port_doc[] =
4042 "int _pjsua.recorder_get_conf_port (int id) "
4043 "Get conference port associated with recorder.";
4044static char pjsua_recorder_destroy_doc[] =
4045 "int _pjsua.recorder_destroy (int id) "
4046 "Destroy recorder (this will complete recording).";
4047static char pjsua_enum_snd_devs_doc[] =
4048 "_pjsua.PJMedia_Snd_Dev_Info[] _pjsua.enum_snd_devs (int count) "
4049 "Enum sound devices.";
4050static char pjsua_get_snd_dev_doc[] =
4051 "int, int _pjsua.get_snd_dev () "
4052 "Get currently active sound devices. "
4053 "If sound devices has not been created "
4054 "(for example when pjsua_start() is not called), "
4055 "it is possible that the function returns "
4056 "PJ_SUCCESS with -1 as device IDs.";
4057static char pjsua_set_snd_dev_doc[] =
4058 "int _pjsua.set_snd_dev (int capture_dev, int playback_dev) "
4059 "Select or change sound device. Application may call this function "
4060 "at any time to replace current sound device.";
4061static char pjsua_set_null_snd_dev_doc[] =
4062 "int _pjsua.set_null_snd_dev () "
4063 "Set pjsua to use null sound device. The null sound device only "
4064 "provides the timing needed by the conference bridge, and will not "
4065 "interract with any hardware.";
4066static char pjsua_set_no_snd_dev_doc[] =
4067 "_pjsua.PJMedia_Port _pjsua.set_no_snd_dev () "
4068 "Disconnect the main conference bridge from any sound devices, "
4069 "and let application connect the bridge to it's "
4070 "own sound device/master port.";
4071static char pjsua_set_ec_doc[] =
4072 "int _pjsua.set_ec (int tail_ms, int options) "
4073 "Configure the echo canceller tail length of the sound port.";
4074static char pjsua_get_ec_tail_doc[] =
4075 "int _pjsua.get_ec_tail () "
4076 "Get current echo canceller tail length.";
4077static char pjsua_enum_codecs_doc[] =
4078 "_pjsua.Codec_Info[] _pjsua.enum_codecs () "
4079 "Enum all supported codecs in the system.";
4080static char pjsua_codec_set_priority_doc[] =
4081 "int _pjsua.codec_set_priority (string id, int priority) "
4082 "Change codec priority.";
4083static char pjsua_codec_get_param_doc[] =
4084 "_pjsua.PJMedia_Codec_Param _pjsua.codec_get_param (string id) "
4085 "Get codec parameters";
4086static char pjsua_codec_set_param_doc[] =
4087 "int _pjsua.codec_set_param (string id, "
4088 "_pjsua.PJMedia_Codec_Param param) "
4089 "Set codec parameters.";
4090
4091/* END OF LIB MEDIA */
4092
4093/* LIB CALL */
4094
4095/*
4096 * PyObj_pj_time_val
4097 * PJ Time Val
4098 */
4099typedef struct
4100{
4101 PyObject_HEAD
4102 /* Type-specific fields go here. */
4103 long sec;
4104 long msec;
4105
4106} PyObj_pj_time_val;
4107
4108
4109
4110/*
4111 * pj_time_val_members
4112 */
4113static PyMemberDef pj_time_val_members[] =
4114{
4115
4116 {
4117 "sec", T_INT,
4118 offsetof(PyObj_pj_time_val, sec), 0,
4119 "The seconds part of the time"
4120 },
4121 {
4122 "msec", T_INT,
4123 offsetof(PyObj_pj_time_val, sec), 0,
4124 "The milliseconds fraction of the time"
4125 },
4126
4127
4128 {NULL} /* Sentinel */
4129};
4130
4131
4132
4133
4134/*
4135 * PyTyp_pj_time_val
4136 */
4137static PyTypeObject PyTyp_pj_time_val =
4138{
4139 PyObject_HEAD_INIT(NULL)
4140 0, /*ob_size*/
4141 "_pjsua.PJ_Time_Val", /*tp_name*/
4142 sizeof(PyObj_pj_time_val), /*tp_basicsize*/
4143 0, /*tp_itemsize*/
4144 0,/*tp_dealloc*/
4145 0, /*tp_print*/
4146 0, /*tp_getattr*/
4147 0, /*tp_setattr*/
4148 0, /*tp_compare*/
4149 0, /*tp_repr*/
4150 0, /*tp_as_number*/
4151 0, /*tp_as_sequence*/
4152 0, /*tp_as_mapping*/
4153 0, /*tp_hash */
4154 0, /*tp_call*/
4155 0, /*tp_str*/
4156 0, /*tp_getattro*/
4157 0, /*tp_setattro*/
4158 0, /*tp_as_buffer*/
4159 Py_TPFLAGS_DEFAULT, /*tp_flags*/
4160 "PJ Time Val objects", /* tp_doc */
4161 0, /* tp_traverse */
4162 0, /* tp_clear */
4163 0, /* tp_richcompare */
4164 0, /* tp_weaklistoffset */
4165 0, /* tp_iter */
4166 0, /* tp_iternext */
4167 0, /* tp_methods */
4168 pj_time_val_members, /* tp_members */
4169
4170
4171};
4172
4173/*
4174 * PyObj_pjsua_call_info
4175 * Call Info
4176 */
4177typedef struct
4178{
4179 PyObject_HEAD
4180 /* Type-specific fields go here. */
4181
4182 int id;
4183 int role;
4184 int acc_id;
4185 PyObject * local_info;
4186 PyObject * local_contact;
4187 PyObject * remote_info;
4188 PyObject * remote_contact;
4189 PyObject * call_id;
4190 int state;
4191 PyObject * state_text;
4192 int last_status;
4193 PyObject * last_status_text;
4194 int media_status;
4195 int media_dir;
4196 int conf_slot;
4197 PyObj_pj_time_val * connect_duration;
4198 PyObj_pj_time_val * total_duration;
4199 struct {
4200 char local_info[128];
4201 char local_contact[128];
4202 char remote_info[128];
4203 char remote_contact[128];
4204 char call_id[128];
4205 char last_status_text[128];
4206 } buf_;
4207
4208} PyObj_pjsua_call_info;
4209
4210
4211/*
4212 * call_info_dealloc
4213 * deletes a call_info from memory
4214 */
4215static void call_info_dealloc(PyObj_pjsua_call_info* self)
4216{
4217 Py_XDECREF(self->local_info);
4218 Py_XDECREF(self->local_contact);
4219 Py_XDECREF(self->remote_info);
4220 Py_XDECREF(self->remote_contact);
4221 Py_XDECREF(self->call_id);
4222 Py_XDECREF(self->state_text);
4223 Py_XDECREF(self->last_status_text);
4224 Py_XDECREF(self->connect_duration);
4225 Py_XDECREF(self->total_duration);
4226 self->ob_type->tp_free((PyObject*)self);
4227}
4228
4229
4230/*
4231 * call_info_new
4232 * constructor for call_info object
4233 */
4234static PyObject * call_info_new(PyTypeObject *type, PyObject *args,
4235 PyObject *kwds)
4236{
4237 PyObj_pjsua_call_info *self;
4238
4239 PJ_UNUSED_ARG(args);
4240 PJ_UNUSED_ARG(kwds);
4241
4242 self = (PyObj_pjsua_call_info *)type->tp_alloc(type, 0);
4243 if (self != NULL)
4244 {
4245 self->local_info = PyString_FromString("");
4246 if (self->local_info == NULL)
4247 {
4248 Py_DECREF(self);
4249 return NULL;
4250 }
4251 self->local_contact = PyString_FromString("");
4252 if (self->local_contact == NULL)
4253 {
4254 Py_DECREF(self);
4255 return NULL;
4256 }
4257 self->remote_info = PyString_FromString("");
4258 if (self->remote_info == NULL)
4259 {
4260 Py_DECREF(self);
4261 return NULL;
4262 }
4263 self->remote_contact = PyString_FromString("");
4264 if (self->remote_contact == NULL)
4265 {
4266 Py_DECREF(self);
4267 return NULL;
4268 }
4269 self->call_id = PyString_FromString("");
4270 if (self->call_id == NULL)
4271 {
4272 Py_DECREF(self);
4273 return NULL;
4274 }
4275 self->state_text = PyString_FromString("");
4276 if (self->state_text == NULL)
4277 {
4278 Py_DECREF(self);
4279 return NULL;
4280 }
4281 self->last_status_text = PyString_FromString("");
4282 if (self->last_status_text == NULL)
4283 {
4284 Py_DECREF(self);
4285 return NULL;
4286 }
4287 self->connect_duration = (PyObj_pj_time_val *)PyType_GenericNew
4288 (&PyTyp_pj_time_val,NULL,NULL);
4289 if (self->connect_duration == NULL)
4290 {
4291 Py_DECREF(self);
4292 return NULL;
4293 }
4294 self->total_duration = (PyObj_pj_time_val *)PyType_GenericNew
4295 (&PyTyp_pj_time_val,NULL,NULL);
4296 if (self->total_duration == NULL)
4297 {
4298 Py_DECREF(self);
4299 return NULL;
4300 }
4301 }
4302 return (PyObject *)self;
4303}
4304
4305/*
4306 * call_info_members
4307 */
4308static PyMemberDef call_info_members[] =
4309{
4310 {
4311 "id", T_INT,
4312 offsetof(PyObj_pjsua_call_info, id), 0,
4313 "Call identification"
4314 },
4315 {
4316 "role", T_INT,
4317 offsetof(PyObj_pjsua_call_info, role), 0,
4318 "Initial call role (UAC == caller)"
4319 },
4320 {
4321 "acc_id", T_INT,
4322 offsetof(PyObj_pjsua_call_info, acc_id), 0,
4323 "The account ID where this call belongs."
4324 },
4325 {
4326 "local_info", T_OBJECT_EX,
4327 offsetof(PyObj_pjsua_call_info, local_info), 0,
4328 "Local URI"
4329 },
4330 {
4331 "local_contact", T_OBJECT_EX,
4332 offsetof(PyObj_pjsua_call_info, local_contact), 0,
4333 "Local Contact"
4334 },
4335 {
4336 "remote_info", T_OBJECT_EX,
4337 offsetof(PyObj_pjsua_call_info, remote_info), 0,
4338 "Remote URI"
4339 },
4340 {
4341 "remote_contact", T_OBJECT_EX,
4342 offsetof(PyObj_pjsua_call_info, remote_contact), 0,
4343 "Remote Contact"
4344 },
4345 {
4346 "call_id", T_OBJECT_EX,
4347 offsetof(PyObj_pjsua_call_info, call_id), 0,
4348 "Dialog Call-ID string"
4349 },
4350 {
4351 "state", T_INT,
4352 offsetof(PyObj_pjsua_call_info, state), 0,
4353 "Call state"
4354 },
4355 {
4356 "state_text", T_OBJECT_EX,
4357 offsetof(PyObj_pjsua_call_info, state_text), 0,
4358 "Text describing the state "
4359 },
4360 {
4361 "last_status", T_INT,
4362 offsetof(PyObj_pjsua_call_info, last_status), 0,
4363 "Last status code heard, which can be used as cause code"
4364 },
4365 {
4366 "last_status_text", T_OBJECT_EX,
4367 offsetof(PyObj_pjsua_call_info, last_status_text), 0,
4368 "The reason phrase describing the status."
4369 },
4370 {
4371 "media_status", T_INT,
4372 offsetof(PyObj_pjsua_call_info, media_status), 0,
4373 "Call media status."
4374 },
4375 {
4376 "media_dir", T_INT,
4377 offsetof(PyObj_pjsua_call_info, media_dir), 0,
4378 "Media direction"
4379 },
4380 {
4381 "conf_slot", T_INT,
4382 offsetof(PyObj_pjsua_call_info, conf_slot), 0,
4383 "The conference port number for the call"
4384 },
4385 {
4386 "connect_duration", T_OBJECT_EX,
4387 offsetof(PyObj_pjsua_call_info, connect_duration), 0,
4388 "Up-to-date call connected duration(zero when call is not established)"
4389 },
4390 {
4391 "total_duration", T_OBJECT_EX,
4392 offsetof(PyObj_pjsua_call_info, total_duration), 0,
4393 "Total call duration, including set-up time"
4394 },
4395
4396 {NULL} /* Sentinel */
4397};
4398
4399
4400
4401
4402/*
4403 * PyTyp_pjsua_call_info
4404 */
4405static PyTypeObject PyTyp_pjsua_call_info =
4406{
4407 PyObject_HEAD_INIT(NULL)
4408 0, /*ob_size*/
4409 "_pjsua.Call_Info", /*tp_name*/
4410 sizeof(PyObj_pjsua_call_info), /*tp_basicsize*/
4411 0, /*tp_itemsize*/
4412 (destructor)call_info_dealloc,/*tp_dealloc*/
4413 0, /*tp_print*/
4414 0, /*tp_getattr*/
4415 0, /*tp_setattr*/
4416 0, /*tp_compare*/
4417 0, /*tp_repr*/
4418 0, /*tp_as_number*/
4419 0, /*tp_as_sequence*/
4420 0, /*tp_as_mapping*/
4421 0, /*tp_hash */
4422 0, /*tp_call*/
4423 0, /*tp_str*/
4424 0, /*tp_getattro*/
4425 0, /*tp_setattro*/
4426 0, /*tp_as_buffer*/
4427 Py_TPFLAGS_DEFAULT, /*tp_flags*/
4428 "Call Info objects", /* tp_doc */
4429 0, /* tp_traverse */
4430 0, /* tp_clear */
4431 0, /* tp_richcompare */
4432 0, /* tp_weaklistoffset */
4433 0, /* tp_iter */
4434 0, /* tp_iternext */
4435 0, /* tp_methods */
4436 call_info_members, /* tp_members */
4437 0, /* tp_getset */
4438 0, /* tp_base */
4439 0, /* tp_dict */
4440 0, /* tp_descr_get */
4441 0, /* tp_descr_set */
4442 0, /* tp_dictoffset */
4443 0, /* tp_init */
4444 0, /* tp_alloc */
4445 call_info_new, /* tp_new */
4446
4447};
4448
4449/*
4450 * py_pjsua_call_get_max_count
4451 */
4452static PyObject *py_pjsua_call_get_max_count
4453(PyObject *pSelf, PyObject *pArgs)
4454{
4455 int count;
4456
4457 PJ_UNUSED_ARG(pSelf);
4458
4459 if (!PyArg_ParseTuple(pArgs, ""))
4460 {
4461 return NULL;
4462 }
4463
4464 count = pjsua_call_get_max_count();
4465
4466
4467 return Py_BuildValue("i", count);
4468}
4469
4470/*
4471 * py_pjsua_call_get_count
4472 */
4473static PyObject *py_pjsua_call_get_count
4474(PyObject *pSelf, PyObject *pArgs)
4475{
4476
4477 int count;
4478
4479 PJ_UNUSED_ARG(pSelf);
4480
4481 if (!PyArg_ParseTuple(pArgs, ""))
4482 {
4483 return NULL;
4484 }
4485
4486 count = pjsua_call_get_count();
4487
4488
4489 return Py_BuildValue("i", count);
4490}
4491
4492/*
4493 * py_pjsua_enum_calls
4494 */
4495static PyObject *py_pjsua_enum_calls(PyObject *pSelf, PyObject *pArgs)
4496{
4497 pj_status_t status;
4498 PyObject *list;
4499
4500 pjsua_transport_id id[PJSUA_MAX_CALLS];
4501 unsigned c, i;
4502
4503 PJ_UNUSED_ARG(pSelf);
4504
4505 if (!PyArg_ParseTuple(pArgs, ""))
4506 {
4507 return NULL;
4508 }
4509
4510 c = PJ_ARRAY_SIZE(id);
4511 status = pjsua_enum_calls(id, &c);
4512
4513 list = PyList_New(c);
4514 for (i = 0; i < c; i++)
4515 {
4516 int ret = PyList_SetItem(list, i, Py_BuildValue("i", id[i]));
4517 if (ret == -1)
4518 {
4519 return NULL;
4520 }
4521 }
4522
4523 return Py_BuildValue("O",list);
4524}
4525
4526/*
4527 * py_pjsua_call_make_call
4528 */
4529static PyObject *py_pjsua_call_make_call
4530(PyObject *pSelf, PyObject *pArgs)
4531{
4532 int status;
4533 int acc_id;
4534 pj_str_t dst_uri;
4535 PyObject * sd;
4536 unsigned options;
4537 pjsua_msg_data msg_data;
4538 PyObject * omdObj;
4539 PyObj_pjsua_msg_data * omd;
4540 int user_data;
4541 int call_id;
4542 pj_pool_t * pool;
4543
4544 PJ_UNUSED_ARG(pSelf);
4545
4546 if (!PyArg_ParseTuple
4547 (pArgs, "iOIiO", &acc_id, &sd, &options, &user_data, &omdObj))
4548 {
4549 return NULL;
4550 }
4551
4552 dst_uri.ptr = PyString_AsString(sd);
4553 dst_uri.slen = strlen(PyString_AsString(sd));
4554 if (omdObj != Py_None)
4555 {
4556 omd = (PyObj_pjsua_msg_data *)omdObj;
4557 msg_data.content_type.ptr = PyString_AsString(omd->content_type);
4558 msg_data.content_type.slen = strlen
4559 (PyString_AsString(omd->content_type));
4560 msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
4561 msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
4562 pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
4563 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
4564 status = pjsua_call_make_call(acc_id, &dst_uri,
4565 options, (void*)user_data, &msg_data, &call_id);
4566 pj_pool_release(pool);
4567 } else {
4568
4569 status = pjsua_call_make_call(acc_id, &dst_uri,
4570 options, (void*)user_data, NULL, &call_id);
4571 }
4572
4573 return Py_BuildValue("ii",status, call_id);
4574
4575}
4576
4577/*
4578 * py_pjsua_call_is_active
4579 */
4580static PyObject *py_pjsua_call_is_active
4581(PyObject *pSelf, PyObject *pArgs)
4582{
4583 int call_id;
4584 int isActive;
4585
4586 PJ_UNUSED_ARG(pSelf);
4587
4588 if (!PyArg_ParseTuple(pArgs, "i", &call_id))
4589 {
4590 return NULL;
4591 }
4592
4593 isActive = pjsua_call_is_active(call_id);
4594
4595
4596 return Py_BuildValue("i", isActive);
4597}
4598
4599/*
4600 * py_pjsua_call_has_media
4601 */
4602static PyObject *py_pjsua_call_has_media
4603(PyObject *pSelf, PyObject *pArgs)
4604{
4605 int call_id;
4606 int hasMedia;
4607
4608 PJ_UNUSED_ARG(pSelf);
4609
4610 if (!PyArg_ParseTuple(pArgs, "i", &call_id))
4611 {
4612 return NULL;
4613 }
4614
4615 hasMedia = pjsua_call_has_media(call_id);
4616
4617
4618 return Py_BuildValue("i", hasMedia);
4619}
4620
4621/*
4622 * py_pjsua_call_get_conf_port
4623 */
4624static PyObject *py_pjsua_call_get_conf_port
4625(PyObject *pSelf, PyObject *pArgs)
4626{
4627 int call_id;
4628 int port_id;
4629
4630 PJ_UNUSED_ARG(pSelf);
4631
4632 if (!PyArg_ParseTuple(pArgs, "i", &call_id))
4633 {
4634 return NULL;
4635 }
4636
4637 port_id = pjsua_call_get_conf_port(call_id);
4638
4639
4640 return Py_BuildValue("i", port_id);
4641}
4642
4643/*
4644 * py_pjsua_call_get_info
4645 */
4646static PyObject *py_pjsua_call_get_info
4647(PyObject *pSelf, PyObject *pArgs)
4648{
4649 int call_id;
4650 int status;
4651 PyObj_pjsua_call_info * oi;
4652 pjsua_call_info info;
4653
4654 PJ_UNUSED_ARG(pSelf);
4655
4656 if (!PyArg_ParseTuple(pArgs, "i", &call_id))
4657 {
4658 return NULL;
4659 }
4660
4661
4662 status = pjsua_call_get_info(call_id, &info);
4663 if (status == PJ_SUCCESS)
4664 {
4665 oi = (PyObj_pjsua_call_info *)call_info_new(&PyTyp_pjsua_call_info, NULL, NULL);
4666 oi->acc_id = info.acc_id;
4667 pj_ansi_snprintf(oi->buf_.call_id, sizeof(oi->buf_.call_id),
4668 "%.*s", (int)info.call_id.slen, info.call_id.ptr);
4669 pj_ansi_snprintf(oi->buf_.last_status_text,
4670 sizeof(oi->buf_.last_status_text),
4671 "%.*s", (int)info.last_status_text.slen, info.last_status_text.ptr);
4672 pj_ansi_snprintf(oi->buf_.local_contact, sizeof(oi->buf_.local_contact),
4673 "%.*s", (int)info.local_contact.slen, info.local_contact.ptr);
4674 pj_ansi_snprintf(oi->buf_.local_info, sizeof(oi->buf_.local_info),
4675 "%.*s", (int)info.local_info.slen, info.local_info.ptr);
4676 pj_ansi_snprintf(oi->buf_.remote_contact,
4677 sizeof(oi->buf_.remote_contact),
4678 "%.*s", (int)info.remote_contact.slen, info.remote_contact.ptr);
4679 pj_ansi_snprintf(oi->buf_.remote_info, sizeof(oi->buf_.remote_info),
4680 "%.*s", (int)info.remote_info.slen, info.remote_info.ptr);
4681
4682 oi->call_id = PyString_FromStringAndSize(info.call_id.ptr,
4683 info.call_id.slen);
4684 oi->conf_slot = info.conf_slot;
4685 oi->connect_duration->sec = info.connect_duration.sec;
4686 oi->connect_duration->msec = info.connect_duration.msec;
4687 oi->total_duration->sec = info.total_duration.sec;
4688 oi->total_duration->msec = info.total_duration.msec;
4689 oi->id = info.id;
4690 oi->last_status = info.last_status;
4691 oi->last_status_text = PyString_FromStringAndSize(
4692 info.last_status_text.ptr, info.last_status_text.slen);
4693 oi->local_contact = PyString_FromStringAndSize(
4694 info.local_contact.ptr, info.local_contact.slen);
4695 oi->local_info = PyString_FromStringAndSize(
4696 info.local_info.ptr, info.local_info.slen);
4697 oi->remote_contact = PyString_FromStringAndSize(
4698 info.remote_contact.ptr, info.remote_contact.slen);
4699 oi->remote_info = PyString_FromStringAndSize(
4700 info.remote_info.ptr, info.remote_info.slen);
4701 oi->media_dir = info.media_dir;
4702 oi->media_status = info.media_status;
4703 oi->role = info.role;
4704 oi->state = info.state;
4705 oi->state_text = PyString_FromStringAndSize(
4706 info.state_text.ptr, info.state_text.slen);
4707
4708 return Py_BuildValue("O", oi);
4709 } else {
4710 Py_INCREF(Py_None);
4711 return Py_None;
4712 }
4713}
4714
4715/*
4716 * py_pjsua_call_set_user_data
4717 */
4718static PyObject *py_pjsua_call_set_user_data
4719(PyObject *pSelf, PyObject *pArgs)
4720{
4721 int call_id;
4722 int user_data;
4723 int status;
4724
4725 PJ_UNUSED_ARG(pSelf);
4726
4727 if (!PyArg_ParseTuple(pArgs, "ii", &call_id, &user_data))
4728 {
4729 return NULL;
4730 }
4731
4732 status = pjsua_call_set_user_data(call_id, (void*)user_data);
4733
4734
4735 return Py_BuildValue("i", status);
4736}
4737
4738/*
4739 * py_pjsua_call_get_user_data
4740 */
4741static PyObject *py_pjsua_call_get_user_data
4742(PyObject *pSelf, PyObject *pArgs)
4743{
4744 int call_id;
4745 void * user_data;
4746
4747 PJ_UNUSED_ARG(pSelf);
4748
4749 if (!PyArg_ParseTuple(pArgs, "i", &call_id))
4750 {
4751 return NULL;
4752 }
4753
4754 user_data = pjsua_call_get_user_data(call_id);
4755
4756
4757 return Py_BuildValue("i", (int)user_data);
4758}
4759
4760/*
4761 * py_pjsua_call_answer
4762 */
4763static PyObject *py_pjsua_call_answer
4764(PyObject *pSelf, PyObject *pArgs)
4765{
4766 int status;
4767 int call_id;
4768 pj_str_t * reason, tmp_reason;
4769 PyObject * sr;
4770 unsigned code;
4771 pjsua_msg_data msg_data;
4772 PyObject * omdObj;
4773 PyObj_pjsua_msg_data * omd;
4774 pj_pool_t * pool;
4775
4776 PJ_UNUSED_ARG(pSelf);
4777
4778 if (!PyArg_ParseTuple(pArgs, "iIOO", &call_id, &code, &sr, &omdObj))
4779 {
4780 return NULL;
4781 }
4782 if (sr == Py_None)
4783 {
4784 reason = NULL;
4785 } else {
4786 reason = &tmp_reason;
4787 tmp_reason.ptr = PyString_AsString(sr);
4788 tmp_reason.slen = strlen(PyString_AsString(sr));
4789 }
4790 if (omdObj != Py_None)
4791 {
4792 omd = (PyObj_pjsua_msg_data *)omdObj;
4793 msg_data.content_type.ptr = PyString_AsString(omd->content_type);
4794 msg_data.content_type.slen = strlen
4795 (PyString_AsString(omd->content_type));
4796 msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
4797 msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
4798 pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
4799 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
4800
4801 status = pjsua_call_answer(call_id, code, reason, &msg_data);
4802
4803 pj_pool_release(pool);
4804 } else {
4805
4806 status = pjsua_call_answer(call_id, code, reason, NULL);
4807
4808 }
4809
4810 return Py_BuildValue("i",status);
4811}
4812
4813/*
4814 * py_pjsua_call_hangup
4815 */
4816static PyObject *py_pjsua_call_hangup
4817(PyObject *pSelf, PyObject *pArgs)
4818{
4819 int status;
4820 int call_id;
4821 pj_str_t * reason, tmp_reason;
4822 PyObject * sr;
4823 unsigned code;
4824 pjsua_msg_data msg_data;
4825 PyObject * omdObj;
4826 PyObj_pjsua_msg_data * omd;
4827 pj_pool_t * pool = NULL;
4828
4829 PJ_UNUSED_ARG(pSelf);
4830
4831 if (!PyArg_ParseTuple(pArgs, "iIOO", &call_id, &code, &sr, &omdObj))
4832 {
4833 return NULL;
4834 }
4835 if (sr == Py_None)
4836 {
4837 reason = NULL;
4838 } else {
4839 reason = &tmp_reason;
4840 tmp_reason.ptr = PyString_AsString(sr);
4841 tmp_reason.slen = strlen(PyString_AsString(sr));
4842 }
4843 if (omdObj != Py_None)
4844 {
4845 omd = (PyObj_pjsua_msg_data *)omdObj;
4846 msg_data.content_type.ptr = PyString_AsString(omd->content_type);
4847 msg_data.content_type.slen = strlen
4848 (PyString_AsString(omd->content_type));
4849 msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
4850 msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
4851 pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
4852 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
4853 status = pjsua_call_hangup(call_id, code, reason, &msg_data);
4854 pj_pool_release(pool);
4855 } else {
4856 status = pjsua_call_hangup(call_id, code, reason, NULL);
4857 }
4858
4859 return Py_BuildValue("i",status);
4860}
4861
4862/*
4863 * py_pjsua_call_set_hold
4864 */
4865static PyObject *py_pjsua_call_set_hold
4866(PyObject *pSelf, PyObject *pArgs)
4867{
4868 int status;
4869 int call_id;
4870 pjsua_msg_data msg_data;
4871 PyObject * omdObj;
4872 PyObj_pjsua_msg_data * omd;
4873 pj_pool_t * pool;
4874
4875 PJ_UNUSED_ARG(pSelf);
4876
4877 if (!PyArg_ParseTuple(pArgs, "iO", &call_id, &omdObj))
4878 {
4879 return NULL;
4880 }
4881
4882 if (omdObj != Py_None)
4883 {
4884 omd = (PyObj_pjsua_msg_data *)omdObj;
4885 msg_data.content_type.ptr = PyString_AsString(omd->content_type);
4886 msg_data.content_type.slen = strlen
4887 (PyString_AsString(omd->content_type));
4888 msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
4889 msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
4890 pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
4891 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
4892 status = pjsua_call_set_hold(call_id, &msg_data);
4893 pj_pool_release(pool);
4894 } else {
4895 status = pjsua_call_set_hold(call_id, NULL);
4896 }
4897 return Py_BuildValue("i",status);
4898}
4899
4900/*
4901 * py_pjsua_call_reinvite
4902 */
4903static PyObject *py_pjsua_call_reinvite
4904(PyObject *pSelf, PyObject *pArgs)
4905{
4906 int status;
4907 int call_id;
4908 int unhold;
4909 pjsua_msg_data msg_data;
4910 PyObject * omdObj;
4911 PyObj_pjsua_msg_data * omd;
4912 pj_pool_t * pool;
4913
4914 PJ_UNUSED_ARG(pSelf);
4915
4916 if (!PyArg_ParseTuple(pArgs, "iiO", &call_id, &unhold, &omdObj))
4917 {
4918 return NULL;
4919 }
4920
4921 if (omdObj != Py_None)
4922 {
4923 omd = (PyObj_pjsua_msg_data *)omdObj;
4924 msg_data.content_type.ptr = PyString_AsString(omd->content_type);
4925 msg_data.content_type.slen = strlen
4926 (PyString_AsString(omd->content_type));
4927 msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
4928 msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
4929 pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
4930 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
4931 status = pjsua_call_reinvite(call_id, unhold, &msg_data);
4932 pj_pool_release(pool);
4933 } else {
4934 status = pjsua_call_reinvite(call_id, unhold, NULL);
4935 }
4936 return Py_BuildValue("i",status);
4937}
4938
4939/*
4940 * py_pjsua_call_update
4941 */
4942static PyObject *py_pjsua_call_update
4943(PyObject *pSelf, PyObject *pArgs)
4944{
4945 int status;
4946 int call_id;
4947 int option;
4948 pjsua_msg_data msg_data;
4949 PyObject * omdObj;
4950 PyObj_pjsua_msg_data * omd;
4951 pj_pool_t * pool;
4952
4953 PJ_UNUSED_ARG(pSelf);
4954
4955 if (!PyArg_ParseTuple(pArgs, "iiO", &call_id, &option, &omdObj))
4956 {
4957 return NULL;
4958 }
4959
4960 if (omdObj != Py_None)
4961 {
4962 omd = (PyObj_pjsua_msg_data *)omdObj;
4963 msg_data.content_type.ptr = PyString_AsString(omd->content_type);
4964 msg_data.content_type.slen = strlen
4965 (PyString_AsString(omd->content_type));
4966 msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
4967 msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
4968 pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
4969 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
4970 status = pjsua_call_update(call_id, option, &msg_data);
4971 pj_pool_release(pool);
4972 } else {
4973 status = pjsua_call_update(call_id, option, NULL);
4974 }
4975 return Py_BuildValue("i",status);
4976}
4977
4978/*
4979 * py_pjsua_call_send_request
4980 */
4981static PyObject *py_pjsua_call_send_request
4982(PyObject *pSelf, PyObject *pArgs)
4983{
4984 int status;
4985 int call_id;
4986 PyObject *method_obj;
4987 pj_str_t method;
4988 pjsua_msg_data msg_data;
4989 PyObject * omdObj;
4990 PyObj_pjsua_msg_data * omd;
4991 pj_pool_t * pool;
4992
4993 PJ_UNUSED_ARG(pSelf);
4994
4995 if (!PyArg_ParseTuple(pArgs, "iOO", &call_id, &method_obj, &omdObj))
4996 {
4997 return NULL;
4998 }
4999
5000 if (!PyString_Check(method_obj)) {
5001 return NULL;
5002 }
5003
5004 method.ptr = PyString_AsString(method_obj);
5005 method.slen = PyString_Size(method_obj);
5006
5007 if (omdObj != Py_None)
5008 {
5009 omd = (PyObj_pjsua_msg_data *)omdObj;
5010 msg_data.content_type.ptr = PyString_AsString(omd->content_type);
5011 msg_data.content_type.slen = strlen
5012 (PyString_AsString(omd->content_type));
5013 msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
5014 msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
5015 pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
5016 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
5017 status = pjsua_call_send_request(call_id, &method, &msg_data);
5018 pj_pool_release(pool);
5019 } else {
5020 status = pjsua_call_send_request(call_id, &method, NULL);
5021 }
5022 return Py_BuildValue("i",status);
5023}
5024
5025/*
5026 * py_pjsua_call_xfer
5027 */
5028static PyObject *py_pjsua_call_xfer
5029(PyObject *pSelf, PyObject *pArgs)
5030{
5031 int status;
5032 int call_id;
5033 pj_str_t dest;
5034 PyObject * sd;
5035 pjsua_msg_data msg_data;
5036 PyObject * omdObj;
5037 PyObj_pjsua_msg_data * omd;
5038 pj_pool_t * pool;
5039
5040 PJ_UNUSED_ARG(pSelf);
5041
5042 if (!PyArg_ParseTuple(pArgs, "iOO", &call_id, &sd, &omdObj))
5043 {
5044 return NULL;
5045 }
5046
5047 dest.ptr = PyString_AsString(sd);
5048 dest.slen = strlen(PyString_AsString(sd));
5049
5050 if (omdObj != Py_None)
5051 {
5052 omd = (PyObj_pjsua_msg_data *)omdObj;
5053 msg_data.content_type.ptr = PyString_AsString(omd->content_type);
5054 msg_data.content_type.slen = strlen
5055 (PyString_AsString(omd->content_type));
5056 msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
5057 msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
5058 pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
5059 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
5060 status = pjsua_call_xfer(call_id, &dest, &msg_data);
5061 pj_pool_release(pool);
5062 } else {
5063 status = pjsua_call_xfer(call_id, &dest, NULL);
5064 }
5065 return Py_BuildValue("i",status);
5066}
5067
5068/*
5069 * py_pjsua_call_xfer_replaces
5070 */
5071static PyObject *py_pjsua_call_xfer_replaces
5072(PyObject *pSelf, PyObject *pArgs)
5073{
5074 int status;
5075 int call_id;
5076 int dest_call_id;
5077 unsigned options;
5078 pjsua_msg_data msg_data;
5079 PyObject * omdObj;
5080 PyObj_pjsua_msg_data * omd;
5081 pj_pool_t * pool;
5082
5083 PJ_UNUSED_ARG(pSelf);
5084
5085 if (!PyArg_ParseTuple
5086 (pArgs, "iiIO", &call_id, &dest_call_id, &options, &omdObj))
5087 {
5088 return NULL;
5089 }
5090
5091 if (omdObj != Py_None)
5092 {
5093 omd = (PyObj_pjsua_msg_data *)omdObj;
5094 msg_data.content_type.ptr = PyString_AsString(omd->content_type);
5095 msg_data.content_type.slen = strlen
5096 (PyString_AsString(omd->content_type));
5097 msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
5098 msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
5099 pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
5100 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
5101 status = pjsua_call_xfer_replaces
5102 (call_id, dest_call_id, options, &msg_data);
5103 pj_pool_release(pool);
5104 } else {
5105 status = pjsua_call_xfer_replaces(call_id, dest_call_id,options, NULL);
5106 }
5107 return Py_BuildValue("i",status);
5108}
5109
5110/*
5111 * py_pjsua_call_dial_dtmf
5112 */
5113static PyObject *py_pjsua_call_dial_dtmf
5114(PyObject *pSelf, PyObject *pArgs)
5115{
5116 int call_id;
5117 PyObject * sd;
5118 pj_str_t digits;
5119 int status;
5120
5121 PJ_UNUSED_ARG(pSelf);
5122
5123 if (!PyArg_ParseTuple(pArgs, "iO", &call_id, &sd))
5124 {
5125 return NULL;
5126 }
5127 digits.ptr = PyString_AsString(sd);
5128 digits.slen = strlen(PyString_AsString(sd));
5129 status = pjsua_call_dial_dtmf(call_id, &digits);
5130
5131 return Py_BuildValue("i", status);
5132}
5133
5134/*
5135 * py_pjsua_call_send_im
5136 */
5137static PyObject *py_pjsua_call_send_im
5138(PyObject *pSelf, PyObject *pArgs)
5139{
5140 int status;
5141 int call_id;
5142 pj_str_t content;
5143 pj_str_t * mime_type, tmp_mime_type;
5144 PyObject * sm;
5145 PyObject * sc;
5146 pjsua_msg_data msg_data;
5147 PyObject * omdObj;
5148 PyObj_pjsua_msg_data * omd;
5149 int user_data;
5150 pj_pool_t * pool;
5151
5152 PJ_UNUSED_ARG(pSelf);
5153
5154 if (!PyArg_ParseTuple
5155 (pArgs, "iOOOi", &call_id, &sm, &sc, &omdObj, &user_data))
5156 {
5157 return NULL;
5158 }
5159 if (sm == Py_None)
5160 {
5161 mime_type = NULL;
5162 } else {
5163 mime_type = &tmp_mime_type;
5164 tmp_mime_type.ptr = PyString_AsString(sm);
5165 tmp_mime_type.slen = strlen(PyString_AsString(sm));
5166 }
5167 content.ptr = PyString_AsString(sc);
5168 content.slen = strlen(PyString_AsString(sc));
5169
5170 if (omdObj != Py_None)
5171 {
5172 omd = (PyObj_pjsua_msg_data *)omdObj;
5173 msg_data.content_type.ptr = PyString_AsString(omd->content_type);
5174 msg_data.content_type.slen = strlen
5175 (PyString_AsString(omd->content_type));
5176 msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
5177 msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
5178 pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
5179 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
5180 status = pjsua_call_send_im
5181 (call_id, mime_type, &content, &msg_data, (void *)user_data);
5182 pj_pool_release(pool);
5183 } else {
5184 status = pjsua_call_send_im
5185 (call_id, mime_type, &content, NULL, (void *)user_data);
5186 }
5187
5188 return Py_BuildValue("i",status);
5189}
5190
5191/*
5192 * py_pjsua_call_send_typing_ind
5193 */
5194static PyObject *py_pjsua_call_send_typing_ind
5195(PyObject *pSelf, PyObject *pArgs)
5196{
5197 int status;
5198 int call_id;
5199 int is_typing;
5200 pjsua_msg_data msg_data;
5201 PyObject * omdObj;
5202 PyObj_pjsua_msg_data * omd;
5203 pj_pool_t * pool;
5204
5205 PJ_UNUSED_ARG(pSelf);
5206
5207 if (!PyArg_ParseTuple(pArgs, "iiO", &call_id, &is_typing, &omdObj))
5208 {
5209 return NULL;
5210 }
5211
5212 if (omdObj != Py_None)
5213 {
5214 omd = (PyObj_pjsua_msg_data *)omdObj;
5215 msg_data.content_type.ptr = PyString_AsString(omd->content_type);
5216 msg_data.content_type.slen = strlen
5217 (PyString_AsString(omd->content_type));
5218 msg_data.msg_body.ptr = PyString_AsString(omd->msg_body);
5219 msg_data.msg_body.slen = strlen(PyString_AsString(omd->msg_body));
5220 pool = pjsua_pool_create("pjsua", POOL_SIZE, POOL_SIZE);
5221 translate_hdr(pool, &msg_data.hdr_list, omd->hdr_list);
5222 status = pjsua_call_send_typing_ind(call_id, is_typing, &msg_data);
5223 pj_pool_release(pool);
5224 } else {
5225 status = pjsua_call_send_typing_ind(call_id, is_typing, NULL);
5226 }
5227 return Py_BuildValue("i",status);
5228}
5229
5230/*
5231 * py_pjsua_call_hangup_all
5232 */
5233static PyObject *py_pjsua_call_hangup_all
5234(PyObject *pSelf, PyObject *pArgs)
5235{
5236
5237 PJ_UNUSED_ARG(pSelf);
5238
5239 if (!PyArg_ParseTuple(pArgs, ""))
5240 {
5241 return NULL;
5242 }
5243
5244 pjsua_call_hangup_all();
5245
5246 Py_INCREF(Py_None);
5247 return Py_None;
5248}
5249
5250/*
5251 * py_pjsua_call_dump
5252 */
5253static PyObject *py_pjsua_call_dump
5254(PyObject *pSelf, PyObject *pArgs)
5255{
5256 int call_id;
5257 int with_media;
5258 PyObject * sb;
5259 PyObject * si;
5260 char * buffer;
5261 char * indent;
5262 unsigned maxlen;
5263 int status;
5264
5265 PJ_UNUSED_ARG(pSelf);
5266
5267 if (!PyArg_ParseTuple(pArgs, "iiIO", &call_id, &with_media, &maxlen, &si))
5268 {
5269 return NULL;
5270 }
5271 buffer = (char *) malloc (maxlen * sizeof(char));
5272 indent = PyString_AsString(si);
5273
5274 status = pjsua_call_dump(call_id, with_media, buffer, maxlen, indent);
5275 sb = PyString_FromStringAndSize(buffer, maxlen);
5276 free(buffer);
5277 return Py_BuildValue("O", sb);
5278}
5279
5280
5281/*
5282 * py_pjsua_dump
5283 * Dump application states.
5284 */
5285static PyObject *py_pjsua_dump(PyObject *pSelf, PyObject *pArgs)
5286{
5287 unsigned old_decor;
5288 char buf[1024];
5289 int detail;
5290
5291 PJ_UNUSED_ARG(pSelf);
5292
5293 if (!PyArg_ParseTuple(pArgs, "i", &detail))
5294 {
5295 return NULL;
5296 }
5297
5298 PJ_LOG(3,(THIS_FILE, "Start dumping application states:"));
5299
5300 old_decor = pj_log_get_decor();
5301 pj_log_set_decor(old_decor & (PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_CR));
5302
5303 if (detail)
5304 pj_dump_config();
5305
5306 pjsip_endpt_dump(pjsua_get_pjsip_endpt(), detail);
5307 pjmedia_endpt_dump(pjsua_get_pjmedia_endpt());
5308 pjsip_tsx_layer_dump(detail);
5309 pjsip_ua_dump(detail);
5310
5311
5312 /* Dump all invite sessions: */
5313 PJ_LOG(3,(THIS_FILE, "Dumping invite sessions:"));
5314
5315 if (pjsua_call_get_count() == 0) {
5316
5317 PJ_LOG(3,(THIS_FILE, " - no sessions -"));
5318
5319 } else {
5320 unsigned i, max;
5321
5322 max = pjsua_call_get_max_count();
5323 for (i=0; i<max; ++i) {
5324 if (pjsua_call_is_active(i)) {
5325 pjsua_call_dump(i, detail, buf, sizeof(buf), " ");
5326 PJ_LOG(3,(THIS_FILE, "%s", buf));
5327 }
5328 }
5329 }
5330
5331 /* Dump presence status */
5332 pjsua_pres_dump(detail);
5333
5334 pj_log_set_decor(old_decor);
5335 PJ_LOG(3,(THIS_FILE, "Dump complete"));
5336
5337 Py_INCREF(Py_None);
5338 return Py_None;
5339}
5340
5341
5342/*
5343 * py_pj_strerror
5344 */
5345static PyObject *py_pj_strerror(PyObject *pSelf, PyObject *pArgs)
5346{
5347 int err;
5348 char err_msg[PJ_ERR_MSG_SIZE];
5349
5350 PJ_UNUSED_ARG(pSelf);
5351
5352 if (!PyArg_ParseTuple(pArgs, "i", &err))
5353 {
5354 return NULL;
5355 }
5356
5357 pj_strerror(err, err_msg, sizeof(err_msg));
5358
5359 return PyString_FromString(err_msg);
5360}
5361
5362
5363/*
5364 * py_pj_parse_simple_sip
5365 */
5366static PyObject *py_pj_parse_simple_sip(PyObject *pSelf, PyObject *pArgs)
5367{
5368 const char *uri_param;
5369 pj_pool_t *pool;
5370 char tmp[PJSIP_MAX_URL_SIZE];
5371 pjsip_uri *uri;
5372 pjsip_sip_uri *sip_uri;
5373 PyObject *ret, *item;
5374
5375 PJ_UNUSED_ARG(pSelf);
5376
5377 if (!PyArg_ParseTuple(pArgs, "s", &uri_param))
5378 {
5379 return NULL;
5380 }
5381
5382 strncpy(tmp, uri_param, sizeof(tmp));
5383 tmp[sizeof(tmp)-1] = '\0';
5384
5385 pool = pjsua_pool_create("py_pj_parse_simple_sip", 512, 512);
5386 uri = pjsip_parse_uri(pool, tmp, strlen(tmp), 0);
5387
5388 if (uri == NULL || (!PJSIP_URI_SCHEME_IS_SIP(uri) &&
5389 !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
5390 pj_pool_release(pool);
5391 Py_INCREF(Py_None);
5392 return Py_None;
5393 }
5394
5395 ret = PyTuple_New(5);
5396 sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(uri);
5397
5398 /* Scheme */
5399 item = PyString_FromStringAndSize(pjsip_uri_get_scheme(uri)->ptr,
5400 pjsip_uri_get_scheme(uri)->slen);
5401 PyTuple_SetItem(ret, 0, item);
5402
5403 /* Username */
5404 item = PyString_FromStringAndSize(sip_uri->user.ptr, sip_uri->user.slen);
5405 PyTuple_SetItem(ret, 1, item);
5406
5407 /* Host */
5408 item = PyString_FromStringAndSize(sip_uri->host.ptr, sip_uri->host.slen);
5409 PyTuple_SetItem(ret, 2, item);
5410
5411 /* Port */
5412 if (sip_uri->port == 5060) {
5413 sip_uri->port = 0;
5414 }
5415 item = Py_BuildValue("i", sip_uri->port);
5416 PyTuple_SetItem(ret, 3, item);
5417
5418 /* Transport */
5419 if (pj_stricmp2(&sip_uri->transport_param, "udp")) {
5420 sip_uri->transport_param.ptr = "";
5421 sip_uri->transport_param.slen = 0;
5422 }
5423 item = PyString_FromStringAndSize(sip_uri->transport_param.ptr,
5424 sip_uri->transport_param.slen);
5425 PyTuple_SetItem(ret, 4, item);
5426
5427 return ret;
5428}
5429
5430
5431static char pjsua_call_get_max_count_doc[] =
5432 "int _pjsua.call_get_max_count () "
5433 "Get maximum number of calls configured in pjsua.";
5434static char pjsua_call_get_count_doc[] =
5435 "int _pjsua.call_get_count () "
5436 "Get number of currently active calls.";
5437static char pjsua_enum_calls_doc[] =
5438 "int[] _pjsua.enum_calls () "
5439 "Get maximum number of calls configured in pjsua.";
5440static char pjsua_call_make_call_doc[] =
5441 "int,int _pjsua.call_make_call (int acc_id, string dst_uri, int options,"
5442 "int user_data, _pjsua.Msg_Data msg_data) "
5443 "Make outgoing call to the specified URI using the specified account.";
5444static char pjsua_call_is_active_doc[] =
5445 "int _pjsua.call_is_active (int call_id) "
5446 "Check if the specified call has active INVITE session and the INVITE "
5447 "session has not been disconnected.";
5448static char pjsua_call_has_media_doc[] =
5449 "int _pjsua.call_has_media (int call_id) "
5450 "Check if call has an active media session.";
5451static char pjsua_call_get_conf_port_doc[] =
5452 "int _pjsua.call_get_conf_port (int call_id) "
5453 "Get the conference port identification associated with the call.";
5454static char pjsua_call_get_info_doc[] =
5455 "_pjsua.Call_Info _pjsua.call_get_info (int call_id) "
5456 "Obtain detail information about the specified call.";
5457static char pjsua_call_set_user_data_doc[] =
5458 "int _pjsua.call_set_user_data (int call_id, int user_data) "
5459 "Attach application specific data to the call.";
5460static char pjsua_call_get_user_data_doc[] =
5461 "int _pjsua.call_get_user_data (int call_id) "
5462 "Get user data attached to the call.";
5463static char pjsua_call_answer_doc[] =
5464 "int _pjsua.call_answer (int call_id, int code, string reason, "
5465 "_pjsua.Msg_Data msg_data) "
5466 "Send response to incoming INVITE request.";
5467static char pjsua_call_hangup_doc[] =
5468 "int _pjsua.call_hangup (int call_id, int code, string reason, "
5469 "_pjsua.Msg_Data msg_data) "
5470 "Hangup call by using method that is appropriate according "
5471 "to the call state.";
5472static char pjsua_call_set_hold_doc[] =
5473 "int _pjsua.call_set_hold (int call_id, _pjsua.Msg_Data msg_data) "
5474 "Put the specified call on hold.";
5475static char pjsua_call_reinvite_doc[] =
5476 "int _pjsua.call_reinvite (int call_id, int unhold, "
5477 "_pjsua.Msg_Data msg_data) "
5478 "Send re-INVITE (to release hold).";
5479static char pjsua_call_xfer_doc[] =
5480 "int _pjsua.call_xfer (int call_id, string dest, "
5481 "_pjsua.Msg_Data msg_data) "
5482 "Initiate call transfer to the specified address. "
5483 "This function will send REFER request to instruct remote call party "
5484 "to initiate a new INVITE session to the specified destination/target.";
5485static char pjsua_call_xfer_replaces_doc[] =
5486 "int _pjsua.call_xfer_replaces (int call_id, int dest_call_id, "
5487 "int options, _pjsua.Msg_Data msg_data) "
5488 "Initiate attended call transfer. This function will send REFER request "
5489 "to instruct remote call party to initiate new INVITE session to the URL "
5490 "of dest_call_id. The party at dest_call_id then should 'replace' the call"
5491 "with us with the new call from the REFER recipient.";
5492static char pjsua_call_dial_dtmf_doc[] =
5493 "int _pjsua.call_dial_dtmf (int call_id, string digits) "
5494 "Send DTMF digits to remote using RFC 2833 payload formats.";
5495static char pjsua_call_send_im_doc[] =
5496 "int _pjsua.call_send_im (int call_id, string mime_type, string content,"
5497 "_pjsua.Msg_Data msg_data, int user_data) "
5498 "Send instant messaging inside INVITE session.";
5499static char pjsua_call_send_typing_ind_doc[] =
5500 "int _pjsua.call_send_typing_ind (int call_id, int is_typing, "
5501 "_pjsua.Msg_Data msg_data) "
5502 "Send IM typing indication inside INVITE session.";
5503static char pjsua_call_hangup_all_doc[] =
5504 "void _pjsua.call_hangup_all () "
5505 "Terminate all calls.";
5506static char pjsua_call_dump_doc[] =
5507 "int _pjsua.call_dump (int call_id, int with_media, int maxlen, "
5508 "string indent) "
5509 "Dump call and media statistics to string.";
5510
5511/* END OF LIB CALL */
5512
5513/*
5514 * Map of function names to functions
5515 */
5516static PyMethodDef py_pjsua_methods[] =
5517{
5518 {
5519 "thread_register", py_pjsua_thread_register, METH_VARARGS,
5520 pjsua_thread_register_doc
5521 },
5522 {
5523 "perror", py_pjsua_perror, METH_VARARGS, pjsua_perror_doc
5524 },
5525 {
5526 "create", py_pjsua_create, METH_VARARGS, pjsua_create_doc
5527 },
5528 {
5529 "init", py_pjsua_init, METH_VARARGS, pjsua_init_doc
5530 },
5531 {
5532 "start", py_pjsua_start, METH_VARARGS, pjsua_start_doc
5533 },
5534 {
5535 "destroy", py_pjsua_destroy, METH_VARARGS, pjsua_destroy_doc
5536 },
5537 {
5538 "handle_events", py_pjsua_handle_events, METH_VARARGS,
5539 pjsua_handle_events_doc
5540 },
5541 {
5542 "verify_sip_url", py_pjsua_verify_sip_url, METH_VARARGS,
5543 pjsua_verify_sip_url_doc
5544 },
5545 {
5546 "pool_create", py_pjsua_pool_create, METH_VARARGS,
5547 pjsua_pool_create_doc
5548 },
5549 {
5550 "get_pjsip_endpt", py_pjsua_get_pjsip_endpt, METH_VARARGS,
5551 pjsua_get_pjsip_endpt_doc
5552 },
5553 {
5554 "get_pjmedia_endpt", py_pjsua_get_pjmedia_endpt, METH_VARARGS,
5555 pjsua_get_pjmedia_endpt_doc
5556 },
5557 {
5558 "get_pool_factory", py_pjsua_get_pool_factory, METH_VARARGS,
5559 pjsua_get_pool_factory_doc
5560 },
5561 {
5562 "reconfigure_logging", py_pjsua_reconfigure_logging, METH_VARARGS,
5563 pjsua_reconfigure_logging_doc
5564 },
5565 {
5566 "logging_config_default", py_pjsua_logging_config_default,
5567 METH_VARARGS, pjsua_logging_config_default_doc
5568 },
5569 {
5570 "config_default", py_pjsua_config_default, METH_VARARGS,
5571 pjsua_config_default_doc
5572 },
5573 {
5574 "media_config_default", py_pjsua_media_config_default, METH_VARARGS,
5575 pjsua_media_config_default_doc
5576 },
5577
5578
5579 {
5580 "msg_data_init", py_pjsua_msg_data_init, METH_VARARGS,
5581 pjsua_msg_data_init_doc
5582 },
5583 {
5584 "transport_config_default", py_pjsua_transport_config_default,
5585 METH_VARARGS,pjsua_transport_config_default_doc
5586 },
5587 {
5588 "transport_create", py_pjsua_transport_create, METH_VARARGS,
5589 pjsua_transport_create_doc
5590 },
5591 {
5592 "transport_enum_transports", py_pjsua_enum_transports, METH_VARARGS,
5593 pjsua_enum_transports_doc
5594 },
5595 {
5596 "transport_get_info", py_pjsua_transport_get_info, METH_VARARGS,
5597 pjsua_transport_get_info_doc
5598 },
5599 {
5600 "transport_set_enable", py_pjsua_transport_set_enable, METH_VARARGS,
5601 pjsua_transport_set_enable_doc
5602 },
5603 {
5604 "transport_close", py_pjsua_transport_close, METH_VARARGS,
5605 pjsua_transport_close_doc
5606 },
5607 {
5608 "acc_config_default", py_pjsua_acc_config_default, METH_VARARGS,
5609 pjsua_acc_config_default_doc
5610 },
5611 {
5612 "acc_get_count", py_pjsua_acc_get_count, METH_VARARGS,
5613 pjsua_acc_get_count_doc
5614 },
5615 {
5616 "acc_is_valid", py_pjsua_acc_is_valid, METH_VARARGS,
5617 pjsua_acc_is_valid_doc
5618 },
5619 {
5620 "acc_set_default", py_pjsua_acc_set_default, METH_VARARGS,
5621 pjsua_acc_set_default_doc
5622 },
5623 {
5624 "acc_get_default", py_pjsua_acc_get_default, METH_VARARGS,
5625 pjsua_acc_get_default_doc
5626 },
5627 {
5628 "acc_add", py_pjsua_acc_add, METH_VARARGS,
5629 pjsua_acc_add_doc
5630 },
5631 {
5632 "acc_add_local", py_pjsua_acc_add_local, METH_VARARGS,
5633 pjsua_acc_add_local_doc
5634 },
5635 {
5636 "acc_del", py_pjsua_acc_del, METH_VARARGS,
5637 pjsua_acc_del_doc
5638 },
5639 {
5640 "acc_modify", py_pjsua_acc_modify, METH_VARARGS,
5641 pjsua_acc_modify_doc
5642 },
5643 {
5644 "acc_set_online_status", py_pjsua_acc_set_online_status, METH_VARARGS,
5645 pjsua_acc_set_online_status_doc
5646 },
5647 {
5648 "acc_set_online_status2", py_pjsua_acc_set_online_status2, METH_VARARGS,
5649 pjsua_acc_set_online_status2_doc
5650 },
5651 {
5652 "acc_set_registration", py_pjsua_acc_set_registration, METH_VARARGS,
5653 pjsua_acc_set_registration_doc
5654 },
5655 {
5656 "acc_get_info", py_pjsua_acc_get_info, METH_VARARGS,
5657 pjsua_acc_get_info_doc
5658 },
5659 {
Benny Prijonoe6787ec2008-07-18 23:00:56 +00005660 "acc_pres_notify", py_pjsua_acc_pres_notify, METH_VARARGS,
5661 "Accept or reject subscription request"
5662 },
5663 {
Benny Prijono9c461142008-07-10 22:41:20 +00005664 "enum_accs", py_pjsua_enum_accs, METH_VARARGS,
5665 pjsua_enum_accs_doc
5666 },
5667 {
5668 "acc_enum_info", py_pjsua_acc_enum_info, METH_VARARGS,
5669 pjsua_acc_enum_info_doc
5670 },
5671 {
5672 "acc_find_for_outgoing", py_pjsua_acc_find_for_outgoing, METH_VARARGS,
5673 pjsua_acc_find_for_outgoing_doc
5674 },
5675 {
5676 "acc_find_for_incoming", py_pjsua_acc_find_for_incoming, METH_VARARGS,
5677 pjsua_acc_find_for_incoming_doc
5678 },
5679 {
5680 "acc_create_uac_contact", py_pjsua_acc_create_uac_contact, METH_VARARGS,
5681 pjsua_acc_create_uac_contact_doc
5682 },
5683 {
5684 "acc_create_uas_contact", py_pjsua_acc_create_uas_contact, METH_VARARGS,
5685 pjsua_acc_create_uas_contact_doc
5686 },
5687 {
5688 "acc_set_transport", py_pjsua_acc_set_transport, METH_VARARGS,
5689 "Lock transport to use the specified transport"
5690 },
5691 {
5692 "buddy_config_default", py_pjsua_buddy_config_default, METH_VARARGS,
5693 pjsua_buddy_config_default_doc
5694 },
5695 {
5696 "get_buddy_count", py_pjsua_get_buddy_count, METH_VARARGS,
5697 pjsua_get_buddy_count_doc
5698 },
5699 {
5700 "buddy_is_valid", py_pjsua_buddy_is_valid, METH_VARARGS,
5701 pjsua_buddy_is_valid_doc
5702 },
5703 {
5704 "enum_buddies", py_pjsua_enum_buddies, METH_VARARGS,
5705 pjsua_enum_buddies_doc
5706 },
5707 {
5708 "buddy_get_info", py_pjsua_buddy_get_info, METH_VARARGS,
5709 pjsua_buddy_get_info_doc
5710 },
5711 {
5712 "buddy_add", py_pjsua_buddy_add, METH_VARARGS,
5713 pjsua_buddy_add_doc
5714 },
5715 {
5716 "buddy_del", py_pjsua_buddy_del, METH_VARARGS,
5717 pjsua_buddy_del_doc
5718 },
5719 {
5720 "buddy_subscribe_pres", py_pjsua_buddy_subscribe_pres, METH_VARARGS,
5721 pjsua_buddy_subscribe_pres_doc
5722 },
5723 {
5724 "pres_dump", py_pjsua_pres_dump, METH_VARARGS,
5725 pjsua_pres_dump_doc
5726 },
5727 {
5728 "im_send", py_pjsua_im_send, METH_VARARGS,
5729 pjsua_im_send_doc
5730 },
5731 {
5732 "im_typing", py_pjsua_im_typing, METH_VARARGS,
5733 pjsua_im_typing_doc
5734 },
5735 {
5736 "conf_get_max_ports", py_pjsua_conf_get_max_ports, METH_VARARGS,
5737 pjsua_conf_get_max_ports_doc
5738 },
5739 {
5740 "conf_get_active_ports", py_pjsua_conf_get_active_ports, METH_VARARGS,
5741 pjsua_conf_get_active_ports_doc
5742 },
5743 {
5744 "enum_conf_ports", py_pjsua_enum_conf_ports, METH_VARARGS,
5745 pjsua_enum_conf_ports_doc
5746 },
5747 {
5748 "conf_get_port_info", py_pjsua_conf_get_port_info, METH_VARARGS,
5749 pjsua_conf_get_port_info_doc
5750 },
5751 {
5752 "conf_add_port", py_pjsua_conf_add_port, METH_VARARGS,
5753 pjsua_conf_add_port_doc
5754 },
5755 {
5756 "conf_remove_port", py_pjsua_conf_remove_port, METH_VARARGS,
5757 pjsua_conf_remove_port_doc
5758 },
5759 {
5760 "conf_connect", py_pjsua_conf_connect, METH_VARARGS,
5761 pjsua_conf_connect_doc
5762 },
5763 {
5764 "conf_disconnect", py_pjsua_conf_disconnect, METH_VARARGS,
5765 pjsua_conf_disconnect_doc
5766 },
5767 {
5768 "player_create", py_pjsua_player_create, METH_VARARGS,
5769 pjsua_player_create_doc
5770 },
5771 {
5772 "player_get_conf_port", py_pjsua_player_get_conf_port, METH_VARARGS,
5773 pjsua_player_get_conf_port_doc
5774 },
5775 {
5776 "player_set_pos", py_pjsua_player_set_pos, METH_VARARGS,
5777 pjsua_player_set_pos_doc
5778 },
5779 {
5780 "player_destroy", py_pjsua_player_destroy, METH_VARARGS,
5781 pjsua_player_destroy_doc
5782 },
5783 {
5784 "recorder_create", py_pjsua_recorder_create, METH_VARARGS,
5785 pjsua_recorder_create_doc
5786 },
5787 {
5788 "recorder_get_conf_port", py_pjsua_recorder_get_conf_port, METH_VARARGS,
5789 pjsua_recorder_get_conf_port_doc
5790 },
5791 {
5792 "recorder_destroy", py_pjsua_recorder_destroy, METH_VARARGS,
5793 pjsua_recorder_destroy_doc
5794 },
5795 {
5796 "enum_snd_devs", py_pjsua_enum_snd_devs, METH_VARARGS,
5797 pjsua_enum_snd_devs_doc
5798 },
5799 {
5800 "get_snd_dev", py_pjsua_get_snd_dev, METH_VARARGS,
5801 pjsua_get_snd_dev_doc
5802 },
5803 {
5804 "set_snd_dev", py_pjsua_set_snd_dev, METH_VARARGS,
5805 pjsua_set_snd_dev_doc
5806 },
5807 {
5808 "set_null_snd_dev", py_pjsua_set_null_snd_dev, METH_VARARGS,
5809 pjsua_set_null_snd_dev_doc
5810 },
5811 {
5812 "set_no_snd_dev", py_pjsua_set_no_snd_dev, METH_VARARGS,
5813 pjsua_set_no_snd_dev_doc
5814 },
5815 {
5816 "set_ec", py_pjsua_set_ec, METH_VARARGS,
5817 pjsua_set_ec_doc
5818 },
5819 {
5820 "get_ec_tail", py_pjsua_get_ec_tail, METH_VARARGS,
5821 pjsua_get_ec_tail_doc
5822 },
5823 {
5824 "enum_codecs", py_pjsua_enum_codecs, METH_VARARGS,
5825 pjsua_enum_codecs_doc
5826 },
5827 {
5828 "codec_set_priority", py_pjsua_codec_set_priority, METH_VARARGS,
5829 pjsua_codec_set_priority_doc
5830 },
5831 {
5832 "codec_get_param", py_pjsua_codec_get_param, METH_VARARGS,
5833 pjsua_codec_get_param_doc
5834 },
5835 {
5836 "codec_set_param", py_pjsua_codec_set_param, METH_VARARGS,
5837 pjsua_codec_set_param_doc
5838 },
5839 {
5840 "call_get_max_count", py_pjsua_call_get_max_count, METH_VARARGS,
5841 pjsua_call_get_max_count_doc
5842 },
5843 {
5844 "call_get_count", py_pjsua_call_get_count, METH_VARARGS,
5845 pjsua_call_get_count_doc
5846 },
5847 {
5848 "enum_calls", py_pjsua_enum_calls, METH_VARARGS,
5849 pjsua_enum_calls_doc
5850 },
5851 {
5852 "call_make_call", py_pjsua_call_make_call, METH_VARARGS,
5853 pjsua_call_make_call_doc
5854 },
5855 {
5856 "call_is_active", py_pjsua_call_is_active, METH_VARARGS,
5857 pjsua_call_is_active_doc
5858 },
5859 {
5860 "call_has_media", py_pjsua_call_has_media, METH_VARARGS,
5861 pjsua_call_has_media_doc
5862 },
5863 {
5864 "call_get_conf_port", py_pjsua_call_get_conf_port, METH_VARARGS,
5865 pjsua_call_get_conf_port_doc
5866 },
5867 {
5868 "call_get_info", py_pjsua_call_get_info, METH_VARARGS,
5869 pjsua_call_get_info_doc
5870 },
5871 {
5872 "call_set_user_data", py_pjsua_call_set_user_data, METH_VARARGS,
5873 pjsua_call_set_user_data_doc
5874 },
5875 {
5876 "call_get_user_data", py_pjsua_call_get_user_data, METH_VARARGS,
5877 pjsua_call_get_user_data_doc
5878 },
5879 {
5880 "call_answer", py_pjsua_call_answer, METH_VARARGS,
5881 pjsua_call_answer_doc
5882 },
5883 {
5884 "call_hangup", py_pjsua_call_hangup, METH_VARARGS,
5885 pjsua_call_hangup_doc
5886 },
5887 {
5888 "call_set_hold", py_pjsua_call_set_hold, METH_VARARGS,
5889 pjsua_call_set_hold_doc
5890 },
5891 {
5892 "call_reinvite", py_pjsua_call_reinvite, METH_VARARGS,
5893 pjsua_call_reinvite_doc
5894 },
5895 {
5896 "call_update", py_pjsua_call_update, METH_VARARGS,
5897 "Send UPDATE"
5898 },
5899 {
5900 "call_xfer", py_pjsua_call_xfer, METH_VARARGS,
5901 pjsua_call_xfer_doc
5902 },
5903 {
5904 "call_xfer_replaces", py_pjsua_call_xfer_replaces, METH_VARARGS,
5905 pjsua_call_xfer_replaces_doc
5906 },
5907 {
5908 "call_dial_dtmf", py_pjsua_call_dial_dtmf, METH_VARARGS,
5909 pjsua_call_dial_dtmf_doc
5910 },
5911 {
5912 "call_send_im", py_pjsua_call_send_im, METH_VARARGS,
5913 pjsua_call_send_im_doc
5914 },
5915 {
5916 "call_send_typing_ind", py_pjsua_call_send_typing_ind, METH_VARARGS,
5917 pjsua_call_send_typing_ind_doc
5918 },
5919 {
5920 "call_hangup_all", py_pjsua_call_hangup_all, METH_VARARGS,
5921 pjsua_call_hangup_all_doc
5922 },
5923 {
5924 "call_dump", py_pjsua_call_dump, METH_VARARGS,
5925 pjsua_call_dump_doc
5926 },
5927 {
5928 "call_send_request", py_pjsua_call_send_request, METH_VARARGS,
5929 "Send arbitrary request"
5930 },
5931 {
5932 "dump", py_pjsua_dump, METH_VARARGS, "Dump application state"
5933 },
5934 {
5935 "strerror", py_pj_strerror, METH_VARARGS, "Get error message"
5936 },
5937 {
5938 "parse_simple_uri", py_pj_parse_simple_sip, METH_VARARGS, "Parse URI"
5939 },
5940
5941
5942 {NULL, NULL} /* end of function list */
5943};
5944
5945
5946
5947/*
5948 * Mapping C structs from and to Python objects & initializing object
5949 */
5950DL_EXPORT(void)
5951init_pjsua(void)
5952{
5953 PyObject* m = NULL;
5954#define ADD_CONSTANT(mod,name) PyModule_AddIntConstant(mod,#name,name)
5955
5956
5957 PyEval_InitThreads();
5958
5959 if (PyType_Ready(&PyTyp_pjsua_callback) < 0)
5960 return;
5961 if (PyType_Ready(&PyTyp_pjsua_config) < 0)
5962 return;
5963 if (PyType_Ready(&PyTyp_pjsua_logging_config) < 0)
5964 return;
5965 if (PyType_Ready(&PyTyp_pjsua_msg_data) < 0)
5966 return;
5967 PyTyp_pjsua_media_config.tp_new = PyType_GenericNew;
5968 if (PyType_Ready(&PyTyp_pjsua_media_config) < 0)
5969 return;
5970 PyTyp_pjsip_event.tp_new = PyType_GenericNew;
5971 if (PyType_Ready(&PyTyp_pjsip_event) < 0)
5972 return;
5973 PyTyp_pjsip_rx_data.tp_new = PyType_GenericNew;
5974 if (PyType_Ready(&PyTyp_pjsip_rx_data) < 0)
5975 return;
5976 PyTyp_pj_pool_t.tp_new = PyType_GenericNew;
5977 if (PyType_Ready(&PyTyp_pj_pool_t) < 0)
5978 return;
5979 PyTyp_pjsip_endpoint.tp_new = PyType_GenericNew;
5980 if (PyType_Ready(&PyTyp_pjsip_endpoint) < 0)
5981 return;
5982 PyTyp_pjmedia_endpt.tp_new = PyType_GenericNew;
5983 if (PyType_Ready(&PyTyp_pjmedia_endpt) < 0)
5984 return;
5985 PyTyp_pj_pool_factory.tp_new = PyType_GenericNew;
5986 if (PyType_Ready(&PyTyp_pj_pool_factory) < 0)
5987 return;
5988 PyTyp_pjsip_cred_info.tp_new = PyType_GenericNew;
5989 if (PyType_Ready(&PyTyp_pjsip_cred_info) < 0)
5990 return;
5991
5992 /* LIB TRANSPORT */
5993
5994 if (PyType_Ready(&PyTyp_pjsua_transport_config) < 0)
5995 return;
5996
5997 if (PyType_Ready(&PyTyp_pjsua_transport_info) < 0)
5998 return;
5999
6000 /* END OF LIB TRANSPORT */
6001
6002 /* LIB ACCOUNT */
6003
6004
6005 if (PyType_Ready(&PyTyp_pjsua_acc_config) < 0)
6006 return;
6007 if (PyType_Ready(&PyTyp_pjsua_acc_info) < 0)
6008 return;
6009
6010 /* END OF LIB ACCOUNT */
6011
6012 /* LIB BUDDY */
6013
6014 if (PyType_Ready(&PyTyp_pjsua_buddy_config) < 0)
6015 return;
6016 if (PyType_Ready(&PyTyp_pjsua_buddy_info) < 0)
6017 return;
6018
6019 /* END OF LIB BUDDY */
6020
6021 /* LIB MEDIA */
6022
6023 if (PyType_Ready(&PyTyp_pjsua_codec_info) < 0)
6024 return;
6025
6026 if (PyType_Ready(&PyTyp_pjsua_conf_port_info) < 0)
6027 return;
6028
6029 PyTyp_pjmedia_port.tp_new = PyType_GenericNew;
6030 if (PyType_Ready(&PyTyp_pjmedia_port) < 0)
6031 return;
6032
6033 if (PyType_Ready(&PyTyp_pjmedia_snd_dev_info) < 0)
6034 return;
6035
6036 PyTyp_pjmedia_codec_param_info.tp_new = PyType_GenericNew;
6037 if (PyType_Ready(&PyTyp_pjmedia_codec_param_info) < 0)
6038 return;
6039 PyTyp_pjmedia_codec_param_setting.tp_new = PyType_GenericNew;
6040 if (PyType_Ready(&PyTyp_pjmedia_codec_param_setting) < 0)
6041 return;
6042
6043 if (PyType_Ready(&PyTyp_pjmedia_codec_param) < 0)
6044 return;
6045
6046 /* END OF LIB MEDIA */
6047
6048 /* LIB CALL */
6049
6050 PyTyp_pj_time_val.tp_new = PyType_GenericNew;
6051 if (PyType_Ready(&PyTyp_pj_time_val) < 0)
6052 return;
6053
6054 if (PyType_Ready(&PyTyp_pjsua_call_info) < 0)
6055 return;
6056
6057 /* END OF LIB CALL */
6058
6059 m = Py_InitModule3(
6060 "_pjsua", py_pjsua_methods,"PJSUA-lib module for python"
6061 );
6062
6063 Py_INCREF(&PyTyp_pjsua_callback);
6064 PyModule_AddObject(m, "Callback", (PyObject *)&PyTyp_pjsua_callback);
6065
6066 Py_INCREF(&PyTyp_pjsua_config);
6067 PyModule_AddObject(m, "Config", (PyObject *)&PyTyp_pjsua_config);
6068
6069 Py_INCREF(&PyTyp_pjsua_media_config);
6070 PyModule_AddObject(m, "Media_Config", (PyObject *)&PyTyp_pjsua_media_config);
6071
6072 Py_INCREF(&PyTyp_pjsua_logging_config);
6073 PyModule_AddObject(m, "Logging_Config", (PyObject *)&PyTyp_pjsua_logging_config);
6074
6075 Py_INCREF(&PyTyp_pjsua_msg_data);
6076 PyModule_AddObject(m, "Msg_Data", (PyObject *)&PyTyp_pjsua_msg_data);
6077
6078 Py_INCREF(&PyTyp_pjsip_event);
6079 PyModule_AddObject(m, "Pjsip_Event", (PyObject *)&PyTyp_pjsip_event);
6080
6081 Py_INCREF(&PyTyp_pjsip_rx_data);
6082 PyModule_AddObject(m, "Pjsip_Rx_Data", (PyObject *)&PyTyp_pjsip_rx_data);
6083
6084 Py_INCREF(&PyTyp_pj_pool_t);
6085 PyModule_AddObject(m, "Pj_Pool", (PyObject *)&PyTyp_pj_pool_t);
6086
6087 Py_INCREF(&PyTyp_pjsip_endpoint);
6088 PyModule_AddObject(m, "Pjsip_Endpoint", (PyObject *)&PyTyp_pjsip_endpoint);
6089
6090 Py_INCREF(&PyTyp_pjmedia_endpt);
6091 PyModule_AddObject(m, "Pjmedia_Endpt", (PyObject *)&PyTyp_pjmedia_endpt);
6092
6093 Py_INCREF(&PyTyp_pj_pool_factory);
6094 PyModule_AddObject(
6095 m, "Pj_Pool_Factory", (PyObject *)&PyTyp_pj_pool_factory
6096 );
6097
6098 Py_INCREF(&PyTyp_pjsip_cred_info);
6099 PyModule_AddObject(m, "Pjsip_Cred_Info",
6100 (PyObject *)&PyTyp_pjsip_cred_info
6101 );
6102
6103 /* LIB TRANSPORT */
6104
6105 Py_INCREF(&PyTyp_pjsua_transport_config);
6106 PyModule_AddObject
6107 (m, "Transport_Config", (PyObject *)&PyTyp_pjsua_transport_config);
6108
6109 Py_INCREF(&PyTyp_pjsua_transport_info);
6110 PyModule_AddObject(m, "Transport_Info", (PyObject *)&PyTyp_pjsua_transport_info);
6111
6112
6113 /* END OF LIB TRANSPORT */
6114
6115 /* LIB ACCOUNT */
6116
6117
6118 Py_INCREF(&PyTyp_pjsua_acc_config);
6119 PyModule_AddObject(m, "Acc_Config", (PyObject *)&PyTyp_pjsua_acc_config);
6120 Py_INCREF(&PyTyp_pjsua_acc_info);
6121 PyModule_AddObject(m, "Acc_Info", (PyObject *)&PyTyp_pjsua_acc_info);
6122
6123 /* END OF LIB ACCOUNT */
6124
6125 /* LIB BUDDY */
6126
6127 Py_INCREF(&PyTyp_pjsua_buddy_config);
6128 PyModule_AddObject(m, "Buddy_Config", (PyObject *)&PyTyp_pjsua_buddy_config);
6129 Py_INCREF(&PyTyp_pjsua_buddy_info);
6130 PyModule_AddObject(m, "Buddy_Info", (PyObject *)&PyTyp_pjsua_buddy_info);
6131
6132 /* END OF LIB BUDDY */
6133
6134 /* LIB MEDIA */
6135
6136 Py_INCREF(&PyTyp_pjsua_codec_info);
6137 PyModule_AddObject(m, "Codec_Info", (PyObject *)&PyTyp_pjsua_codec_info);
6138 Py_INCREF(&PyTyp_pjsua_conf_port_info);
6139 PyModule_AddObject(m, "Conf_Port_Info", (PyObject *)&PyTyp_pjsua_conf_port_info);
6140 Py_INCREF(&PyTyp_pjmedia_port);
6141 PyModule_AddObject(m, "PJMedia_Port", (PyObject *)&PyTyp_pjmedia_port);
6142 Py_INCREF(&PyTyp_pjmedia_snd_dev_info);
6143 PyModule_AddObject(m, "PJMedia_Snd_Dev_Info",
6144 (PyObject *)&PyTyp_pjmedia_snd_dev_info);
6145 Py_INCREF(&PyTyp_pjmedia_codec_param_info);
6146 PyModule_AddObject(m, "PJMedia_Codec_Param_Info",
6147 (PyObject *)&PyTyp_pjmedia_codec_param_info);
6148 Py_INCREF(&PyTyp_pjmedia_codec_param_setting);
6149 PyModule_AddObject(m, "PJMedia_Codec_Param_Setting",
6150 (PyObject *)&PyTyp_pjmedia_codec_param_setting);
6151 Py_INCREF(&PyTyp_pjmedia_codec_param);
6152 PyModule_AddObject(m, "PJMedia_Codec_Param",
6153 (PyObject *)&PyTyp_pjmedia_codec_param);
6154
6155 /* END OF LIB MEDIA */
6156
6157 /* LIB CALL */
6158
6159 Py_INCREF(&PyTyp_pj_time_val);
6160 PyModule_AddObject(m, "PJ_Time_Val", (PyObject *)&PyTyp_pj_time_val);
6161
6162 Py_INCREF(&PyTyp_pjsua_call_info);
6163 PyModule_AddObject(m, "Call_Info", (PyObject *)&PyTyp_pjsua_call_info);
6164
6165 /* END OF LIB CALL */
6166
6167
6168 /*
6169 * Add various constants.
6170 */
6171
6172 /* Call states */
6173 ADD_CONSTANT(m, PJSIP_INV_STATE_NULL);
6174 ADD_CONSTANT(m, PJSIP_INV_STATE_CALLING);
6175 ADD_CONSTANT(m, PJSIP_INV_STATE_INCOMING);
6176 ADD_CONSTANT(m, PJSIP_INV_STATE_EARLY);
6177 ADD_CONSTANT(m, PJSIP_INV_STATE_CONNECTING);
6178 ADD_CONSTANT(m, PJSIP_INV_STATE_CONFIRMED);
6179 ADD_CONSTANT(m, PJSIP_INV_STATE_DISCONNECTED);
6180
6181 /* Call media status (enum pjsua_call_media_status) */
6182 ADD_CONSTANT(m, PJSUA_CALL_MEDIA_NONE);
6183 ADD_CONSTANT(m, PJSUA_CALL_MEDIA_ACTIVE);
6184 ADD_CONSTANT(m, PJSUA_CALL_MEDIA_LOCAL_HOLD);
6185 ADD_CONSTANT(m, PJSUA_CALL_MEDIA_REMOTE_HOLD);
6186
6187 /* Buddy status */
6188 ADD_CONSTANT(m, PJSUA_BUDDY_STATUS_UNKNOWN);
6189 ADD_CONSTANT(m, PJSUA_BUDDY_STATUS_ONLINE);
6190 ADD_CONSTANT(m, PJSUA_BUDDY_STATUS_OFFLINE);
6191
6192 /* PJSIP transport types (enum pjsip_transport_type_e) */
6193 ADD_CONSTANT(m, PJSIP_TRANSPORT_UNSPECIFIED);
6194 ADD_CONSTANT(m, PJSIP_TRANSPORT_UDP);
6195 ADD_CONSTANT(m, PJSIP_TRANSPORT_TCP);
6196 ADD_CONSTANT(m, PJSIP_TRANSPORT_TLS);
6197 ADD_CONSTANT(m, PJSIP_TRANSPORT_SCTP);
6198 ADD_CONSTANT(m, PJSIP_TRANSPORT_LOOP);
6199 ADD_CONSTANT(m, PJSIP_TRANSPORT_LOOP_DGRAM);
6200
6201
6202 /* Invalid IDs */
6203 ADD_CONSTANT(m, PJSUA_INVALID_ID);
6204
6205
6206 /* Various compile time constants */
6207 ADD_CONSTANT(m, PJSUA_ACC_MAX_PROXIES);
6208 ADD_CONSTANT(m, PJSUA_MAX_ACC);
6209 ADD_CONSTANT(m, PJSUA_REG_INTERVAL);
6210 ADD_CONSTANT(m, PJSUA_PUBLISH_EXPIRATION);
6211 ADD_CONSTANT(m, PJSUA_DEFAULT_ACC_PRIORITY);
6212 ADD_CONSTANT(m, PJSUA_MAX_BUDDIES);
6213 ADD_CONSTANT(m, PJSUA_MAX_CONF_PORTS);
6214 ADD_CONSTANT(m, PJSUA_DEFAULT_CLOCK_RATE);
6215 ADD_CONSTANT(m, PJSUA_DEFAULT_CODEC_QUALITY);
6216 ADD_CONSTANT(m, PJSUA_DEFAULT_ILBC_MODE);
6217 ADD_CONSTANT(m, PJSUA_DEFAULT_EC_TAIL_LEN);
6218 ADD_CONSTANT(m, PJSUA_MAX_CALLS);
6219 ADD_CONSTANT(m, PJSUA_XFER_NO_REQUIRE_REPLACES);
6220
6221
6222#undef ADD_CONSTANT
6223}