Changeset 824
- Timestamp:
- Nov 23, 2006 9:50:02 PM (18 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip-apps/build/py_pjsua.dsp
r803 r824 54 54 LINK32=link.exe 55 55 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 56 # ADD LINK32 python24.lib pjlib-i386-win32-vc6-release.lib pjlib-util-i386-win32-vc6-release.lib pjmedia-codec-i386-win32-vc6-release.lib pjmedia-i386-win32-vc6-release.lib pjsip-core-i386-win32-vc6-release.lib pjsip-simple-i386-win32-vc6-release.lib pjsip-ua-i386-win32-vc6-release.lib pjsua-lib-i386-win32-vc6-release.libkernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib /nologo /dll /map /machine:I386 /nodefaultlib:"libcmt.lib" /out:"..\lib\py_pjsua.pyd" /libpath:"../../pjlib/lib" /libpath:"../../pjlib-util/lib" /libpath:"../../pjmedia/lib" /libpath:"../../pjsip/lib"56 # ADD LINK32 python24.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib /nologo /dll /map /machine:I386 /nodefaultlib:"libcmt.lib" /out:"..\lib\py_pjsua.pyd" /libpath:"../../pjlib/lib" /libpath:"../../pjlib-util/lib" /libpath:"../../pjmedia/lib" /libpath:"../../pjsip/lib" 57 57 # SUBTRACT LINK32 /nodefaultlib 58 58 … … 81 81 LINK32=link.exe 82 82 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept 83 # ADD LINK32 python24 _d.lib pjlib-i386-win32-vc6-debug.lib pjlib-util-i386-win32-vc6-debug.lib pjmedia-codec-i386-win32-vc6-debug.lib pjmedia-i386-win32-vc6-debug.lib pjsip-core-i386-win32-vc6-debug.lib pjsip-simple-i386-win32-vc6-debug.lib pjsip-ua-i386-win32-vc6-debug.lib pjsua-lib-i386-win32-vc6-debug.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib /nologo /dll /debug /machine:I386 /out:"..\lib\py_pjsua_d.pyd" /pdbtype:sept /libpath:"../../pjlib/lib" /libpath:"../../pjlib-util/lib" /libpath:"../../pjmedia/lib" /libpath:"../../pjsip/lib" /libpath:"F:\incoming\projects\divusi\Python-2.4\Python-2.4\PCbuild" /libpath:"F:\incoming\projects\divusi\Python-2.4\Python-2.4\PC\VC6"83 # ADD LINK32 python24.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib dxguid.lib netapi32.lib mswsock.lib ws2_32.lib /nologo /dll /debug /machine:I386 /out:"..\lib\py_pjsua_d.pyd" /pdbtype:sept /libpath:"../../pjlib/lib" /libpath:"../../pjlib-util/lib" /libpath:"../../pjmedia/lib" /libpath:"../../pjsip/lib" /libpath:"F:\incoming\projects\divusi\Python-2.4\Python-2.4\PCbuild" /libpath:"F:\incoming\projects\divusi\Python-2.4\Python-2.4\PC\VC6" 84 84 85 85 !ENDIF … … 92 92 93 93 # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 94 # Begin Source File 95 96 SOURCE=..\src\py_pjsua\pjsua.py 97 # PROP Exclude_From_Build 1 98 # End Source File 94 99 # Begin Source File 95 100 -
pjproject/trunk/pjsip-apps/src/py_pjsua/pjsua.py
r803 r824 1 # import module py_pjsua2 1 import py_pjsua 3 2 4 print '''Testing py_pjsua.create : '''5 3 status = py_pjsua.create() 6 4 print "py status " + `status` 7 5 8 # perror9 print '''Testing error code 70006 : '''10 py_pjsua.perror("py_pjsua","hello",70006)11 6 12 # test py_pjsua.destroy 13 print '''Testing py_pjsua.destroy : ''' 7 # 8 # Create configuration objects 9 # 10 ua_cfg = py_pjsua.Config() 11 log_cfg = py_pjsua.Logging_Config() 12 media_cfg = py_pjsua.Media_Config() 13 14 # 15 # Logging callback. 16 # 17 def logging_cb1(level, str, len): 18 print str, 19 20 21 # 22 # Initialize configs with default values. 23 # 24 py_pjsua.config_default(ua_cfg) 25 py_pjsua.logging_config_default(log_cfg) 26 py_pjsua.media_config_default(media_cfg) 27 28 # 29 # Configure logging 30 # 31 log_cfg.cb = logging_cb1 32 log_cfg.console_level = 4 33 34 # 35 # Initialize pjsua! 36 # 37 status = py_pjsua.init(ua_cfg, log_cfg, media_cfg); 38 print "py status after initialization :" + `status` 39 40 41 # 42 # Start pjsua! 43 # 44 status = py_pjsua.start() 45 if status != 0: 46 exit(1) 47 48 49 message = py_pjsua.Msg_Data() 50 py_pjsua.msg_data_init(message) 51 print "identitas object message data :" + `message` 52 53 sipaddr = 'sip:167.205.34.99' 54 print "checking sip address [%s] : %d" % (sipaddr, py_pjsua.verify_sip_url(sipaddr)) 55 56 sipaddr = '167.205.34.99' 57 print "checking invalid sip address [%s] : %d" % (sipaddr, py_pjsua.verify_sip_url(sipaddr)) 58 59 object = py_pjsua.get_pjsip_endpt() 60 print "identitas Endpoint :" + `object` + "" 61 62 mediaend = py_pjsua.get_pjmedia_endpt() 63 print "identitas Media Endpoint :" + `mediaend` + "" 64 65 pool = py_pjsua.get_pool_factory() 66 print "identitas pool factory :" + `pool` + "" 67 68 status = py_pjsua.handle_events(3000) 69 print "py status after 3 second of blocking wait :" + `status` 70 71 72 73 # end of new testrun 74 75 # 76 77 py_pjsua.perror("saya","hallo",70006) 78 14 79 status = py_pjsua.destroy() 15 80 print "py status " + `status` 16 81 17 print '''End Of py_pjsua''' 82 -
pjproject/trunk/pjsip-apps/src/py_pjsua/py_pjsua.c
r803 r824 1 /* $Id$ */ 2 /* 3 * Copyright (C) 2003-2006 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 */ 1 19 #include <Python.h> 20 #include "structmember.h" 2 21 #include <pjsua-lib/pjsua.h> 3 22 4 5 static PyObject *py_pjsua_perror(PyObject *pSelf, PyObject *pArgs) { 6 const char *sender; 7 const char *title; 8 pj_status_t status; 9 if (!PyArg_ParseTuple(pArgs, "ssi", &sender, &title, &status)) { 10 return NULL; 11 } 12 pjsua_perror(sender, title, status); 13 Py_INCREF(Py_None); 14 return Py_None; 15 } 16 static PyObject *py_pjsua_create(PyObject *pSelf, PyObject *pArgs) { 17 pj_status_t status; 18 if (!PyArg_ParseTuple(pArgs, "")) { 19 return NULL; 20 } 21 status = pjsua_create(); 22 printf("status %d\n",status); 23 return Py_BuildValue("i",status); 24 } 25 static PyObject *py_pjsua_start(PyObject *pSelf, PyObject *pArgs) { 26 pj_status_t status; 27 if (!PyArg_ParseTuple(pArgs, "")) { 28 return NULL; 29 } 30 status = pjsua_start(); 31 printf("status %d\n",status); 32 return Py_BuildValue("i",status); 33 } 34 35 static PyObject *py_pjsua_destroy(PyObject *pSelf, PyObject *pArgs) { 36 pj_status_t status; 37 if (!PyArg_ParseTuple(pArgs, "")) { 38 return NULL; 39 } 40 status = pjsua_destroy(); 41 printf("status %d\n",status); 42 return Py_BuildValue("i",status); 43 } 44 static PyObject *py_pjsua_handle_events(PyObject *pSelf, PyObject *pArgs) { 45 int ret; 46 unsigned msec; 47 if (!PyArg_ParseTuple(pArgs, "i", &msec)) { 48 return NULL; 49 } 50 ret = pjsua_handle_events(msec); 51 printf("return %d\n",ret); 52 return Py_BuildValue("i",ret); 53 } 54 static PyObject *py_pjsua_verify_sip_url(PyObject *pSelf, PyObject *pArgs) { 55 pj_status_t status; 56 const char *url; 57 if (!PyArg_ParseTuple(pArgs, "s", &url)) { 58 return NULL; 59 } 60 status = pjsua_verify_sip_url(url); 61 printf("status %d\n",status); 62 return Py_BuildValue("i",status); 63 } 64 /* doc string */ 65 static char pjsua_perror_doc[] = "Display error message for the specified error code"; 66 static char pjsua_create_doc[] = "Instantiate pjsua application"; 67 static char pjsua_start_doc[] = "Application is recommended to call this function after all initialization is done, so that the library can do additional checking set up additional"; 68 static char pjsua_destroy_doc[] = "Destroy pjsua"; 69 static char pjsua_handle_events_doc[] = "Poll pjsua for events, and if necessary block the caller thread for the specified maximum interval (in miliseconds)"; 70 static char pjsua_verify_sip_url_doc[] = "Verify that valid SIP url is given"; 71 72 /* Map of function names to functions */ 73 static PyMethodDef py_pjsua_methods[] = { 74 {"perror", py_pjsua_perror, METH_VARARGS, pjsua_perror_doc}, 75 {"create", py_pjsua_create, METH_VARARGS, pjsua_create_doc}, 76 {"start", py_pjsua_start, METH_VARARGS, pjsua_start_doc}, 77 {"destroy", py_pjsua_destroy, METH_VARARGS, pjsua_destroy_doc}, 78 {"handle_events", py_pjsua_handle_events, METH_VARARGS, pjsua_handle_events_doc}, 79 {"verify_sip_url", py_pjsua_verify_sip_url, METH_VARARGS, pjsua_verify_sip_url_doc}, 80 {NULL, NULL} /* End of functions */ 23 #define THIS_FILE "main.c" 24 25 static PyObject* obj_reconfigure_logging; 26 static PyObject* obj_logging_init; 27 28 /* 29 * cb_reconfigure_logging 30 * declares method for reconfiguring logging process for callback struct 31 */ 32 static void cb_reconfigure_logging(int level, const char *data, pj_size_t len) 33 { 34 if (PyCallable_Check(obj_reconfigure_logging)) 35 { 36 PyObject_CallFunctionObjArgs( 37 obj_reconfigure_logging, Py_BuildValue("i",level), 38 PyString_FromString(data), Py_BuildValue("i",len), NULL 39 ); 40 } 41 } 42 43 44 /* 45 * cb_logging_init 46 * declares method logging_init for callback struct 47 */ 48 static void cb_logging_init(int level, const char *data, pj_size_t len) 49 { 50 if (PyCallable_Check(obj_logging_init)) 51 { 52 //PyObject_CallFunction(obj_logging_init,"iSi",level,data,len); 53 //printf("level : %d data : %s len : %d\n",level, data, len); 54 PyObject_CallFunctionObjArgs( 55 obj_logging_init, Py_BuildValue("i",level), 56 PyString_FromString(data), Py_BuildValue("i",len), NULL 57 ); 58 } 59 } 60 61 62 /* 63 * pjsip_event_Object 64 * C/python typewrapper for event struct 65 */ 66 typedef struct 67 { 68 PyObject_HEAD 69 /* Type-specific fields go here. */ 70 pjsip_event * event; 71 } pjsip_event_Object; 72 73 74 /* 75 * pjsip_event_Type 76 * event struct signatures 77 */ 78 static PyTypeObject pjsip_event_Type = 79 { 80 PyObject_HEAD_INIT(NULL) 81 0, /*ob_size*/ 82 "py_pjsua.PJSIP_Event", /*tp_name*/ 83 sizeof(pjsip_event_Object), /*tp_basicsize*/ 84 0, /*tp_itemsize*/ 85 0, /*tp_dealloc*/ 86 0, /*tp_print*/ 87 0, /*tp_getattr*/ 88 0, /*tp_setattr*/ 89 0, /*tp_compare*/ 90 0, /*tp_repr*/ 91 0, /*tp_as_number*/ 92 0, /*tp_as_sequence*/ 93 0, /*tp_as_mapping*/ 94 0, /*tp_hash */ 95 0, /*tp_call*/ 96 0, /*tp_str*/ 97 0, /*tp_getattro*/ 98 0, /*tp_setattro*/ 99 0, /*tp_as_buffer*/ 100 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 101 "pjsip_event objects", /*tp_doc */ 81 102 }; 82 103 83 104 84 PyMODINIT_FUNC 105 /* 106 * pjsip_rx_data_Object 107 * C/python typewrapper for RX data struct 108 */ 109 typedef struct 110 { 111 PyObject_HEAD 112 /* Type-specific fields go here. */ 113 pjsip_rx_data * rdata; 114 } pjsip_rx_data_Object; 115 116 117 /* 118 * pjsip_rx_data_Type 119 */ 120 static PyTypeObject pjsip_rx_data_Type = 121 { 122 PyObject_HEAD_INIT(NULL) 123 0, /*ob_size*/ 124 "py_pjsua.PJSIP_RX_Data", /*tp_name*/ 125 sizeof(pjsip_rx_data_Object), /*tp_basicsize*/ 126 0, /*tp_itemsize*/ 127 0, /*tp_dealloc*/ 128 0, /*tp_print*/ 129 0, /*tp_getattr*/ 130 0, /*tp_setattr*/ 131 0, /*tp_compare*/ 132 0, /*tp_repr*/ 133 0, /*tp_as_number*/ 134 0, /*tp_as_sequence*/ 135 0, /*tp_as_mapping*/ 136 0, /*tp_hash */ 137 0, /*tp_call*/ 138 0, /*tp_str*/ 139 0, /*tp_getattro*/ 140 0, /*tp_setattro*/ 141 0, /*tp_as_buffer*/ 142 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 143 "pjsip_rx_data objects", /*tp_doc*/ 144 }; 145 146 147 /* 148 * callback_Object 149 * C/python typewrapper for callback struct 150 */ 151 typedef struct 152 { 153 PyObject_HEAD 154 /* Type-specific fields go here. */ 155 PyObject * on_call_state; 156 PyObject * on_incoming_call; 157 PyObject * on_call_media_state; 158 PyObject * on_call_transfer_request; 159 PyObject * on_call_transfer_status; 160 PyObject * on_call_replace_request; 161 PyObject * on_call_replaced; 162 PyObject * on_reg_state; 163 PyObject * on_buddy_state; 164 PyObject * on_pager; 165 PyObject * on_pager_status; 166 PyObject * on_typing; 167 168 } callback_Object; 169 170 171 /* 172 * The global callback object. 173 */ 174 static callback_Object * obj_callback; 175 176 177 /* 178 * cb_on_call_state 179 * declares method on_call_state for callback struct 180 */ 181 static void cb_on_call_state(pjsua_call_id call_id, pjsip_event *e) 182 { 183 if (PyCallable_Check(obj_callback->on_call_state)) 184 { 185 pjsip_event_Object * obj = 186 (pjsip_event_Object *)PyType_GenericNew(&pjsip_event_Type, 187 NULL, NULL); 188 obj->event = e; 189 190 PyObject_CallFunctionObjArgs( 191 obj_callback->on_call_state,Py_BuildValue("i",call_id),obj,NULL 192 ); 193 } 194 } 195 196 197 /* 198 * cb_on_incoming_call 199 * declares method on_incoming_call for callback struct 200 */ 201 static void cb_on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id, 202 pjsip_rx_data *rdata) 203 { 204 if (PyCallable_Check(obj_callback->on_incoming_call)) 205 { 206 pjsip_rx_data_Object * obj = (pjsip_rx_data_Object *) 207 PyType_GenericNew(&pjsip_rx_data_Type, 208 NULL, NULL); 209 obj->rdata = rdata; 210 211 PyObject_CallFunctionObjArgs( 212 obj_callback->on_incoming_call, 213 Py_BuildValue("i",acc_id), 214 Py_BuildValue("i",call_id), 215 obj, 216 NULL 217 ); 218 } 219 } 220 221 222 /* 223 * cb_on_call_media_state 224 * declares method on_call_media_state for callback struct 225 */ 226 static void cb_on_call_media_state(pjsua_call_id call_id) 227 { 228 if (PyCallable_Check(obj_callback->on_call_media_state)) 229 { 230 PyObject_CallFunction(obj_callback->on_call_media_state,"i",call_id); 231 } 232 } 233 234 235 /* 236 * Notify application on call being transfered. 237 */ 238 static void cb_on_call_transfer_request(pjsua_call_id call_id, 239 const pj_str_t *dst, 240 pjsip_status_code *code) 241 { 242 if (PyCallable_Check(obj_callback->on_call_transfer_request)) 243 { 244 PyObject_CallFunctionObjArgs( 245 obj_callback->on_call_transfer_request, 246 Py_BuildValue("i",call_id), 247 PyString_FromStringAndSize(dst->ptr, dst->slen), 248 Py_BuildValue("i",*code), 249 NULL 250 ); 251 } 252 } 253 254 255 /* 256 * Notify application of the status of previously sent call 257 * transfer request. Application can monitor the status of the 258 * call transfer request, for example to decide whether to 259 * terminate existing call. 260 */ 261 static void cb_on_call_transfer_status( pjsua_call_id call_id, 262 int status_code, 263 const pj_str_t *status_text, 264 pj_bool_t final, 265 pj_bool_t *p_cont) 266 { 267 if (PyCallable_Check(obj_callback->on_call_transfer_status)) 268 { 269 PyObject_CallFunctionObjArgs( 270 obj_callback->on_call_transfer_status, 271 Py_BuildValue("i",call_id), 272 Py_BuildValue("i",status_code), 273 PyString_FromStringAndSize(status_text->ptr, status_text->slen), 274 Py_BuildValue("i",final), 275 Py_BuildValue("i",*p_cont), 276 NULL 277 ); 278 } 279 } 280 281 282 /* 283 * Notify application about incoming INVITE with Replaces header. 284 * Application may reject the request by setting non-2xx code. 285 */ 286 static void cb_on_call_replace_request( pjsua_call_id call_id, 287 pjsip_rx_data *rdata, 288 int *st_code, 289 pj_str_t *st_text) 290 { 291 if (PyCallable_Check(obj_callback->on_call_replace_request)) 292 { 293 pjsip_rx_data_Object * obj = (pjsip_rx_data_Object *) 294 PyType_GenericNew(&pjsip_rx_data_Type, 295 NULL, NULL); 296 obj->rdata = rdata; 297 298 PyObject_CallFunctionObjArgs( 299 obj_callback->on_call_replace_request, 300 Py_BuildValue("i",call_id), 301 obj, 302 Py_BuildValue("i",*st_code), 303 PyString_FromStringAndSize(st_text->ptr, st_text->slen), 304 NULL 305 ); 306 } 307 } 308 309 310 /* 311 * Notify application that an existing call has been replaced with 312 * a new call. This happens when PJSUA-API receives incoming INVITE 313 * request with Replaces header. 314 */ 315 static void cb_on_call_replaced(pjsua_call_id old_call_id, 316 pjsua_call_id new_call_id) 317 { 318 if (PyCallable_Check(obj_callback->on_call_replaced)) 319 { 320 PyObject_CallFunctionObjArgs( 321 obj_callback->on_call_replaced, 322 Py_BuildValue("i",old_call_id), 323 Py_BuildValue("i",old_call_id), 324 NULL 325 ); 326 } 327 } 328 329 330 /* 331 * cb_on_reg_state 332 * declares method on_reg_state for callback struct 333 */ 334 static void cb_on_reg_state(pjsua_acc_id acc_id) 335 { 336 if (PyCallable_Check(obj_callback->on_reg_state)) 337 { 338 PyObject_CallFunction(obj_callback->on_reg_state,"i",acc_id); 339 } 340 } 341 342 343 /* 344 * cb_on_buddy_state 345 * declares method on_buddy state for callback struct 346 */ 347 static void cb_on_buddy_state(pjsua_buddy_id buddy_id) 348 { 349 if (PyCallable_Check(obj_callback->on_buddy_state)) 350 { 351 PyObject_CallFunction(obj_callback->on_buddy_state,"i",buddy_id); 352 } 353 } 354 355 /* 356 * cb_on_pager 357 * * declares method on_pager for callback struct 358 */ 359 static void cb_on_pager(pjsua_call_id call_id, const pj_str_t *from, 360 const pj_str_t *to, const pj_str_t *contact, 361 const pj_str_t *mime_type, const pj_str_t *body) 362 { 363 if (PyCallable_Check(obj_callback->on_pager)) 364 { 365 PyObject_CallFunctionObjArgs( 366 obj_callback->on_pager,Py_BuildValue("i",call_id), 367 PyString_FromStringAndSize(from->ptr, from->slen), 368 PyString_FromStringAndSize(to->ptr, to->slen), 369 PyString_FromStringAndSize(contact->ptr, contact->slen), 370 PyString_FromStringAndSize(mime_type->ptr, mime_type->slen), 371 PyString_FromStringAndSize(body->ptr, body->slen), NULL 372 ); 373 } 374 } 375 376 377 /* 378 * cb_on_pager_status 379 * declares method on_pager_status for callback struct 380 */ 381 static void cb_on_pager_status(pjsua_call_id call_id, const pj_str_t *to, 382 const pj_str_t *body, void *user_data, 383 pjsip_status_code status, 384 const pj_str_t *reason) 385 { 386 PyObject * obj = PyType_GenericNew(user_data, NULL, NULL); 387 if (PyCallable_Check(obj_callback->on_pager)) 388 { 389 PyObject_CallFunctionObjArgs( 390 obj_callback->on_pager,Py_BuildValue("i",call_id), 391 PyString_FromStringAndSize(to->ptr, to->slen), 392 PyString_FromStringAndSize(body->ptr, body->slen),obj, 393 Py_BuildValue("i",status),PyString_FromStringAndSize(reason->ptr, 394 reason->slen),NULL 395 ); 396 } 397 } 398 399 400 /* 401 * cb_on_typing 402 * declares method on_typing for callback struct 403 */ 404 static void cb_on_typing(pjsua_call_id call_id, const pj_str_t *from, 405 const pj_str_t *to, const pj_str_t *contact, 406 pj_bool_t is_typing) 407 { 408 if (PyCallable_Check(obj_callback->on_typing)) 409 { 410 PyObject_CallFunctionObjArgs( 411 obj_callback->on_typing,Py_BuildValue("i",call_id), 412 PyString_FromStringAndSize(from->ptr, from->slen), 413 PyString_FromStringAndSize(to->ptr, to->slen), 414 PyString_FromStringAndSize(contact->ptr, contact->slen), 415 Py_BuildValue("i",is_typing),NULL 416 ); 417 } 418 } 419 420 421 /* 422 * callback_dealloc 423 * destructor function for callback struct 424 */ 425 static void callback_dealloc(callback_Object* self) 426 { 427 Py_XDECREF(self->on_call_state); 428 Py_XDECREF(self->on_incoming_call); 429 Py_XDECREF(self->on_call_media_state); 430 Py_XDECREF(self->on_call_transfer_request); 431 Py_XDECREF(self->on_call_transfer_status); 432 Py_XDECREF(self->on_call_replace_request); 433 Py_XDECREF(self->on_call_replaced); 434 Py_XDECREF(self->on_reg_state); 435 Py_XDECREF(self->on_buddy_state); 436 Py_XDECREF(self->on_pager); 437 Py_XDECREF(self->on_pager_status); 438 Py_XDECREF(self->on_typing); 439 self->ob_type->tp_free((PyObject*)self); 440 } 441 442 443 /* 444 * callback_new 445 * * declares constructor for callback struct 446 */ 447 static PyObject * callback_new(PyTypeObject *type, PyObject *args, 448 PyObject *kwds) 449 { 450 callback_Object *self; 451 452 self = (callback_Object *)type->tp_alloc(type, 0); 453 if (self != NULL) 454 { 455 Py_INCREF(Py_None); 456 self->on_call_state = Py_None; 457 if (self->on_call_state == NULL) 458 { 459 Py_DECREF(Py_None); 460 return NULL; 461 } 462 Py_INCREF(Py_None); 463 self->on_incoming_call = Py_None; 464 if (self->on_incoming_call == NULL) 465 { 466 Py_DECREF(Py_None); 467 return NULL; 468 } 469 Py_INCREF(Py_None); 470 self->on_call_media_state = Py_None; 471 if (self->on_call_media_state == NULL) 472 { 473 Py_DECREF(Py_None); 474 return NULL; 475 } 476 Py_INCREF(Py_None); 477 self->on_call_transfer_request = Py_None; 478 if (self->on_call_transfer_request == NULL) 479 { 480 Py_DECREF(Py_None); 481 return NULL; 482 } 483 Py_INCREF(Py_None); 484 self->on_call_transfer_status = Py_None; 485 if (self->on_call_transfer_status == NULL) 486 { 487 Py_DECREF(Py_None); 488 return NULL; 489 } 490 Py_INCREF(Py_None); 491 self->on_call_replace_request = Py_None; 492 if (self->on_call_replace_request == NULL) 493 { 494 Py_DECREF(Py_None); 495 return NULL; 496 } 497 Py_INCREF(Py_None); 498 self->on_call_replaced = Py_None; 499 if (self->on_call_replaced == NULL) 500 { 501 Py_DECREF(Py_None); 502 return NULL; 503 } 504 Py_INCREF(Py_None); 505 self->on_reg_state = Py_None; 506 if (self->on_reg_state == NULL) 507 { 508 Py_DECREF(Py_None); 509 return NULL; 510 } 511 Py_INCREF(Py_None); 512 self->on_buddy_state = Py_None; 513 if (self->on_buddy_state == NULL) 514 { 515 Py_DECREF(Py_None); 516 return NULL; 517 } 518 Py_INCREF(Py_None); 519 self->on_pager = Py_None; 520 if (self->on_pager == NULL) 521 { 522 Py_DECREF(Py_None); 523 return NULL; 524 } 525 Py_INCREF(Py_None); 526 self->on_pager_status = Py_None; 527 if (self->on_pager_status == NULL) 528 { 529 Py_DECREF(Py_None); 530 return NULL; 531 } 532 Py_INCREF(Py_None); 533 self->on_typing = Py_None; 534 if (self->on_typing == NULL) 535 { 536 Py_DECREF(Py_None); 537 return NULL; 538 } 539 } 540 541 return (PyObject *)self; 542 } 543 544 545 /* 546 * callback_members 547 * declares available functions for callback object 548 */ 549 static PyMemberDef callback_members[] = 550 { 551 { 552 "on_call_state", T_OBJECT_EX, offsetof(callback_Object, on_call_state), 553 0, "Notify application when invite state has changed. Application may " 554 "then query the call info to get the detail call states." 555 }, 556 { 557 "on_incoming_call", T_OBJECT_EX, 558 offsetof(callback_Object, on_incoming_call), 0, 559 "Notify application on incoming call." 560 }, 561 { 562 "on_call_media__state", T_OBJECT_EX, 563 offsetof(callback_Object, on_call_media_state), 0, 564 "Notify application when media state in the call has changed. Normal " 565 "application would need to implement this callback, e.g. to connect " 566 "the call's media to sound device." 567 }, 568 { 569 "on_call_transfer_request", T_OBJECT_EX, 570 offsetof(callback_Object, on_call_transfer_request), 0, 571 "Notify application on call being transfered. " 572 "Application can decide to accept/reject transfer request " 573 "by setting the code (default is 200). When this callback " 574 "is not defined, the default behavior is to accept the " 575 "transfer." 576 }, 577 { 578 "on_call_transfer_status", T_OBJECT_EX, 579 offsetof(callback_Object, on_call_transfer_status), 0, 580 "Notify application of the status of previously sent call " 581 "transfer request. Application can monitor the status of the " 582 "call transfer request, for example to decide whether to " 583 "terminate existing call." 584 }, 585 { 586 "on_call_replace_request", T_OBJECT_EX, 587 offsetof(callback_Object, on_call_replace_request), 0, 588 "Notify application about incoming INVITE with Replaces header. " 589 "Application may reject the request by setting non-2xx code." 590 }, 591 { 592 "on_call_replaced", T_OBJECT_EX, 593 offsetof(callback_Object, on_call_replaced), 0, 594 "Notify application that an existing call has been replaced with " 595 "a new call. This happens when PJSUA-API receives incoming INVITE " 596 "request with Replaces header." 597 " " 598 "After this callback is called, normally PJSUA-API will disconnect " 599 "old_call_id and establish new_call_id." 600 }, 601 { 602 "on_reg_state", T_OBJECT_EX, 603 offsetof(callback_Object, on_reg_state), 0, 604 "Notify application when registration status has changed. Application " 605 "may then query the account info to get the registration details." 606 }, 607 { 608 "on_buddy_state", T_OBJECT_EX, 609 offsetof(callback_Object, on_buddy_state), 0, 610 "Notify application when the buddy state has changed. Application may " 611 "then query the buddy into to get the details." 612 }, 613 { 614 "on_pager", T_OBJECT_EX, offsetof(callback_Object, on_pager), 0, 615 "Notify application on incoming pager (i.e. MESSAGE request). " 616 "Argument call_id will be -1 if MESSAGE request is not related to an " 617 "existing call." 618 }, 619 { 620 "on_pager_status", T_OBJECT_EX, 621 offsetof(callback_Object, on_pager_status), 0, 622 "Notify application about the delivery status of outgoing pager " 623 "request." 624 }, 625 { 626 "on_typing", T_OBJECT_EX, offsetof(callback_Object, on_typing), 0, 627 "Notify application about typing indication." 628 }, 629 {NULL} /* Sentinel */ 630 }; 631 632 633 /* 634 * callback_Type 635 * callback class definition 636 */ 637 static PyTypeObject callback_Type = 638 { 639 PyObject_HEAD_INIT(NULL) 640 0, /*ob_size*/ 641 "py_pjsua.Callback", /*tp_name*/ 642 sizeof(callback_Object), /*tp_basicsize*/ 643 0, /*tp_itemsize*/ 644 (destructor)callback_dealloc, /*tp_dealloc*/ 645 0, /*tp_print*/ 646 0, /*tp_getattr*/ 647 0, /*tp_setattr*/ 648 0, /*tp_compare*/ 649 0, /*tp_repr*/ 650 0, /*tp_as_number*/ 651 0, /*tp_as_sequence*/ 652 0, /*tp_as_mapping*/ 653 0, /*tp_hash */ 654 0, /*tp_call*/ 655 0, /*tp_str*/ 656 0, /*tp_getattro*/ 657 0, /*tp_setattro*/ 658 0, /*tp_as_buffer*/ 659 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 660 "Callback objects", /* tp_doc */ 661 0, /* tp_traverse */ 662 0, /* tp_clear */ 663 0, /* tp_richcompare */ 664 0, /* tp_weaklistoffset */ 665 0, /* tp_iter */ 666 0, /* tp_iternext */ 667 0, /* tp_methods */ 668 callback_members, /* tp_members */ 669 0, /* tp_getset */ 670 0, /* tp_base */ 671 0, /* tp_dict */ 672 0, /* tp_descr_get */ 673 0, /* tp_descr_set */ 674 0, /* tp_dictoffset */ 675 0, /* tp_init */ 676 0, /* tp_alloc */ 677 callback_new, /* tp_new */ 678 679 }; 680 681 682 /* 683 * media_config_Object 684 * C/Python wrapper for media_config object 685 */ 686 typedef struct 687 { 688 PyObject_HEAD 689 /* Type-specific fields go here. */ 690 unsigned clock_rate; 691 unsigned max_media_ports; 692 int has_ioqueue; 693 unsigned thread_cnt; 694 unsigned quality; 695 unsigned ptime; 696 int no_vad; 697 unsigned ilbc_mode; 698 unsigned tx_drop_pct; 699 unsigned rx_drop_pct; 700 unsigned ec_options; 701 unsigned ec_tail_len; 702 } media_config_Object; 703 704 705 /* 706 * media_config_members 707 * declares attributes accessible from both C and Python for media_config file 708 */ 709 static PyMemberDef media_config_members[] = 710 { 711 { 712 "clock_rate", T_INT, offsetof(media_config_Object, clock_rate), 0, 713 "Clock rate to be applied to the conference bridge. If value is zero, " 714 "default clock rate will be used (16KHz)." 715 }, 716 { 717 "max_media_ports", T_INT, 718 offsetof(media_config_Object, max_media_ports), 0, 719 "Specify maximum number of media ports to be created in the " 720 "conference bridge. Since all media terminate in the bridge (calls, " 721 "file player, file recorder, etc), the value must be large enough to " 722 "support all of them. However, the larger the value, the more " 723 "computations are performed." 724 }, 725 { 726 "has_ioqueue", T_INT, offsetof(media_config_Object, has_ioqueue), 0, 727 "Specify whether the media manager should manage its own ioqueue for " 728 "the RTP/RTCP sockets. If yes, ioqueue will be created and at least " 729 "one worker thread will be created too. If no, the RTP/RTCP sockets " 730 "will share the same ioqueue as SIP sockets, and no worker thread is " 731 "needed." 732 }, 733 { 734 "thread_cnt", T_INT, offsetof(media_config_Object, thread_cnt), 0, 735 "Specify the number of worker threads to handle incoming RTP packets. " 736 "A value of one is recommended for most applications." 737 }, 738 { 739 "quality", T_INT, offsetof(media_config_Object, quality), 0, 740 "The media quality also sets speex codec quality/complexity to the " 741 "number." 742 }, 743 { 744 "ptime", T_INT, offsetof(media_config_Object, ptime), 0, 745 "Specify default ptime." 746 }, 747 { 748 "no_vad", T_INT, offsetof(media_config_Object, no_vad), 0, 749 "Disable VAD?" 750 }, 751 { 752 "ilbc_mode", T_INT, offsetof(media_config_Object, ilbc_mode), 0, 753 "iLBC mode (20 or 30)." 754 }, 755 { 756 "tx_drop_pct", T_INT, offsetof(media_config_Object, tx_drop_pct), 0, 757 "Percentage of RTP packet to drop in TX direction (to simulate packet " 758 "lost)." 759 }, 760 { 761 "rx_drop_pct", T_INT, offsetof(media_config_Object, rx_drop_pct), 0, 762 "Percentage of RTP packet to drop in RX direction (to simulate packet " 763 "lost)."}, 764 { 765 "ec_options", T_INT, offsetof(media_config_Object, ec_options), 0, 766 "Echo canceller options (see #pjmedia_echo_create())" 767 }, 768 { 769 "ec_tail_len", T_INT, offsetof(media_config_Object, ec_tail_len), 0, 770 "Echo canceller tail length, in miliseconds." 771 }, 772 {NULL} /* Sentinel */ 773 }; 774 775 776 /* 777 * media_config_Type 778 */ 779 static PyTypeObject media_config_Type = 780 { 781 PyObject_HEAD_INIT(NULL) 782 0, /*ob_size*/ 783 "py_pjsua.Media_Config", /*tp_name*/ 784 sizeof(media_config_Object), /*tp_basicsize*/ 785 0, /*tp_itemsize*/ 786 0, /*tp_dealloc*/ 787 0, /*tp_print*/ 788 0, /*tp_getattr*/ 789 0, /*tp_setattr*/ 790 0, /*tp_compare*/ 791 0, /*tp_repr*/ 792 0, /*tp_as_number*/ 793 0, /*tp_as_sequence*/ 794 0, /*tp_as_mapping*/ 795 0, /*tp_hash */ 796 0, /*tp_call*/ 797 0, /*tp_str*/ 798 0, /*tp_getattro*/ 799 0, /*tp_setattro*/ 800 0, /*tp_as_buffer*/ 801 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 802 "Media Config objects", /*tp_doc*/ 803 0, /*tp_traverse*/ 804 0, /*tp_clear*/ 805 0, /*tp_richcompare*/ 806 0, /* tp_weaklistoffset */ 807 0, /* tp_iter */ 808 0, /* tp_iternext */ 809 0, /* tp_methods */ 810 media_config_members, /* tp_members */ 811 812 }; 813 814 815 /* 816 * config_Object 817 * attribute list for config object 818 */ 819 typedef struct 820 { 821 PyObject_HEAD 822 /* Type-specific fields go here. */ 823 unsigned max_calls; 824 unsigned thread_cnt; 825 unsigned outbound_proxy_cnt; 826 pj_str_t outbound_proxy[4]; 827 unsigned cred_count; 828 pjsip_cred_info cred_info[PJSUA_ACC_MAX_PROXIES]; 829 callback_Object * cb; 830 PyObject * user_agent; 831 } config_Object; 832 833 834 /* 835 * config_dealloc 836 * deallocates a config object 837 */ 838 static void config_dealloc(config_Object* self) 839 { 840 Py_XDECREF(self->cb); 841 Py_XDECREF(self->user_agent); 842 self->ob_type->tp_free((PyObject*)self); 843 } 844 845 /* 846 * config_new 847 * config object constructor 848 */ 849 static PyObject *config_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 850 { 851 config_Object *self; 852 853 self = (config_Object *)type->tp_alloc(type, 0); 854 if (self != NULL) 855 { 856 self->user_agent = PyString_FromString(""); 857 if (self->user_agent == NULL) 858 { 859 Py_DECREF(self); 860 return NULL; 861 } 862 self->cb = (callback_Object *)PyType_GenericNew( 863 &callback_Type, NULL, NULL 864 ); 865 if (self->cb == NULL) 866 { 867 Py_DECREF(Py_None); 868 return NULL; 869 } 870 } 871 return (PyObject *)self; 872 } 873 874 875 /* 876 * config_members 877 * attribute list accessible from Python/C 878 */ 879 static PyMemberDef config_members[] = 880 { 881 { 882 "max_calls", T_INT, offsetof(config_Object, max_calls), 0, 883 "Maximum calls to support (default: 4) " 884 }, 885 { 886 "thread_cnt", T_INT, offsetof(config_Object, thread_cnt), 0, 887 "Number of worker threads. Normally application will want to have at " 888 "least one worker thread, unless when it wants to poll the library " 889 "periodically, which in this case the worker thread can be set to " 890 "zero." 891 }, 892 { 893 "outbound_proxy_cnt", T_INT, 894 offsetof(config_Object, outbound_proxy_cnt), 0, 895 "Number of outbound proxies in the array." 896 }, 897 { 898 "cred_count", T_INT, offsetof(config_Object, cred_count), 0, 899 "Number of credentials in the credential array." 900 }, 901 { 902 "user_agent", T_OBJECT_EX, offsetof(config_Object, user_agent), 0, 903 "User agent string (default empty)" 904 }, 905 { 906 "cb", T_OBJECT_EX, offsetof(config_Object, cb), 0, 907 "Application callback." 908 }, 909 {NULL} /* Sentinel */ 910 }; 911 912 913 /* 914 * config_Type 915 * type wrapper for config class 916 */ 917 static PyTypeObject config_Type = 918 { 919 PyObject_HEAD_INIT(NULL) 920 0, /*ob_size*/ 921 "py_pjsua.Config", /*tp_name*/ 922 sizeof(config_Object), /*tp_basicsize*/ 923 0, /*tp_itemsize*/ 924 (destructor)config_dealloc,/*tp_dealloc*/ 925 0, /*tp_print*/ 926 0, /*tp_getattr*/ 927 0, /*tp_setattr*/ 928 0, /*tp_compare*/ 929 0, /*tp_repr*/ 930 0, /*tp_as_number*/ 931 0, /*tp_as_sequence*/ 932 0, /*tp_as_mapping*/ 933 0, /*tp_hash */ 934 0, /*tp_call*/ 935 0, /*tp_str*/ 936 0, /*tp_getattro*/ 937 0, /*tp_setattro*/ 938 0, /*tp_as_buffer*/ 939 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 940 "Config objects", /* tp_doc */ 941 0, /* tp_traverse */ 942 0, /* tp_clear */ 943 0, /* tp_richcompare */ 944 0, /* tp_weaklistoffset */ 945 0, /* tp_iter */ 946 0, /* tp_iternext */ 947 0, /* tp_methods */ 948 config_members, /* tp_members */ 949 0, /* tp_getset */ 950 0, /* tp_base */ 951 0, /* tp_dict */ 952 0, /* tp_descr_get */ 953 0, /* tp_descr_set */ 954 0, /* tp_dictoffset */ 955 0, /* tp_init */ 956 0, /* tp_alloc */ 957 config_new, /* tp_new */ 958 959 }; 960 961 962 /* 963 * logging_config_Object 964 * configuration class for logging_config object 965 */ 966 typedef struct 967 { 968 PyObject_HEAD 969 /* Type-specific fields go here. */ 970 int msg_logging; 971 unsigned level; 972 unsigned console_level; 973 unsigned decor; 974 PyObject * log_filename; 975 PyObject * cb; 976 } logging_config_Object; 977 978 979 /* 980 * logging_config_dealloc 981 * deletes a logging config from memory 982 */ 983 static void logging_config_dealloc(logging_config_Object* self) 984 { 985 Py_XDECREF(self->log_filename); 986 Py_XDECREF(self->cb); 987 self->ob_type->tp_free((PyObject*)self); 988 } 989 990 991 /* 992 * logging_config_new 993 * constructor for logging_config object 994 */ 995 static PyObject * logging_config_new(PyTypeObject *type, PyObject *args, 996 PyObject *kwds) 997 { 998 logging_config_Object *self; 999 1000 self = (logging_config_Object *)type->tp_alloc(type, 0); 1001 if (self != NULL) 1002 { 1003 self->log_filename = PyString_FromString(""); 1004 if (self->log_filename == NULL) 1005 { 1006 Py_DECREF(self); 1007 return NULL; 1008 } 1009 Py_INCREF(Py_None); 1010 self->cb = Py_None; 1011 if (self->cb == NULL) 1012 { 1013 Py_DECREF(Py_None); 1014 return NULL; 1015 } 1016 } 1017 1018 return (PyObject *)self; 1019 } 1020 1021 1022 /* 1023 * logging_config_members 1024 */ 1025 static PyMemberDef logging_config_members[] = 1026 { 1027 { 1028 "msg_logging", T_INT, offsetof(logging_config_Object, msg_logging), 0, 1029 "Log incoming and outgoing SIP message? Yes!" 1030 }, 1031 { 1032 "level", T_INT, offsetof(logging_config_Object, level), 0, 1033 "Input verbosity level. Value 5 is reasonable." 1034 }, 1035 { 1036 "console_level", T_INT, offsetof(logging_config_Object, console_level), 1037 0, "Verbosity level for console. Value 4 is reasonable." 1038 }, 1039 { 1040 "decor", T_INT, offsetof(logging_config_Object, decor), 0, 1041 "Log decoration" 1042 }, 1043 { 1044 "log_filename", T_OBJECT_EX, 1045 offsetof(logging_config_Object, log_filename), 0, 1046 "Optional log filename" 1047 }, 1048 { 1049 "cb", T_OBJECT_EX, offsetof(logging_config_Object, cb), 0, 1050 "Optional callback function to be called to write log to application " 1051 "specific device. This function will be called forlog messages on " 1052 "input verbosity level." 1053 }, 1054 {NULL} /* Sentinel */ 1055 }; 1056 1057 1058 1059 1060 /* 1061 * logging_config_Type 1062 */ 1063 static PyTypeObject logging_config_Type = 1064 { 1065 PyObject_HEAD_INIT(NULL) 1066 0, /*ob_size*/ 1067 "py_pjsua.Logging_Config", /*tp_name*/ 1068 sizeof(logging_config_Object), /*tp_basicsize*/ 1069 0, /*tp_itemsize*/ 1070 (destructor)logging_config_dealloc,/*tp_dealloc*/ 1071 0, /*tp_print*/ 1072 0, /*tp_getattr*/ 1073 0, /*tp_setattr*/ 1074 0, /*tp_compare*/ 1075 0, /*tp_repr*/ 1076 0, /*tp_as_number*/ 1077 0, /*tp_as_sequence*/ 1078 0, /*tp_as_mapping*/ 1079 0, /*tp_hash */ 1080 0, /*tp_call*/ 1081 0, /*tp_str*/ 1082 0, /*tp_getattro*/ 1083 0, /*tp_setattro*/ 1084 0, /*tp_as_buffer*/ 1085 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 1086 "Logging Config objects", /* tp_doc */ 1087 0, /* tp_traverse */ 1088 0, /* tp_clear */ 1089 0, /* tp_richcompare */ 1090 0, /* tp_weaklistoffset */ 1091 0, /* tp_iter */ 1092 0, /* tp_iternext */ 1093 0, /* tp_methods */ 1094 logging_config_members, /* tp_members */ 1095 0, /* tp_getset */ 1096 0, /* tp_base */ 1097 0, /* tp_dict */ 1098 0, /* tp_descr_get */ 1099 0, /* tp_descr_set */ 1100 0, /* tp_dictoffset */ 1101 0, /* tp_init */ 1102 0, /* tp_alloc */ 1103 logging_config_new, /* tp_new */ 1104 1105 }; 1106 1107 1108 /* 1109 * msg_data_Object 1110 * typewrapper for MessageData class 1111 */ 1112 typedef struct 1113 { 1114 PyObject_HEAD 1115 /* Type-specific fields go here. */ 1116 pjsip_hdr hdr_list; 1117 PyObject * content_type; 1118 PyObject * msg_body; 1119 } msg_data_Object; 1120 1121 1122 /* 1123 * msg_data_dealloc 1124 * deletes a msg_data 1125 */ 1126 static void msg_data_dealloc(msg_data_Object* self) 1127 { 1128 Py_XDECREF(self->content_type); 1129 Py_XDECREF(self->msg_body); 1130 self->ob_type->tp_free((PyObject*)self); 1131 } 1132 1133 1134 /* 1135 * msg_data_new 1136 * constructor for msg_data object 1137 */ 1138 static PyObject * msg_data_new(PyTypeObject *type, PyObject *args, 1139 PyObject *kwds) 1140 { 1141 msg_data_Object *self; 1142 1143 self = (msg_data_Object *)type->tp_alloc(type, 0); 1144 if (self != NULL) 1145 { 1146 self->content_type = PyString_FromString(""); 1147 if (self->content_type == NULL) 1148 { 1149 Py_DECREF(self); 1150 return NULL; 1151 } 1152 self->msg_body = PyString_FromString(""); 1153 if (self->msg_body == NULL) 1154 { 1155 Py_DECREF(self); 1156 return NULL; 1157 } 1158 } 1159 1160 return (PyObject *)self; 1161 } 1162 1163 1164 /* 1165 * msg_data_members 1166 */ 1167 static PyMemberDef msg_data_members[] = 1168 { 1169 { 1170 "content_type", T_OBJECT_EX, offsetof(msg_data_Object, content_type), 1171 0, "MIME type of optional message body." 1172 }, 1173 { 1174 "msg_body", T_OBJECT_EX, offsetof(msg_data_Object, msg_body), 0, 1175 "Optional message body." 1176 }, 1177 {NULL} /* Sentinel */ 1178 }; 1179 1180 1181 /* 1182 * msg_data_Type 1183 */ 1184 static PyTypeObject msg_data_Type = 1185 { 1186 PyObject_HEAD_INIT(NULL) 1187 0, /*ob_size*/ 1188 "py_pjsua.Msg_Data", /*tp_name*/ 1189 sizeof(msg_data_Object), /*tp_basicsize*/ 1190 0, /*tp_itemsize*/ 1191 (destructor)msg_data_dealloc,/*tp_dealloc*/ 1192 0, /*tp_print*/ 1193 0, /*tp_getattr*/ 1194 0, /*tp_setattr*/ 1195 0, /*tp_compare*/ 1196 0, /*tp_repr*/ 1197 0, /*tp_as_number*/ 1198 0, /*tp_as_sequence*/ 1199 0, /*tp_as_mapping*/ 1200 0, /*tp_hash */ 1201 0, /*tp_call*/ 1202 0, /*tp_str*/ 1203 0, /*tp_getattro*/ 1204 0, /*tp_setattro*/ 1205 0, /*tp_as_buffer*/ 1206 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 1207 "msg_data objects", /* tp_doc */ 1208 0, /* tp_traverse */ 1209 0, /* tp_clear */ 1210 0, /* tp_richcompare */ 1211 0, /* tp_weaklistoffset */ 1212 0, /* tp_iter */ 1213 0, /* tp_iternext */ 1214 0, /* tp_methods */ 1215 msg_data_members, /* tp_members */ 1216 0, /* tp_getset */ 1217 0, /* tp_base */ 1218 0, /* tp_dict */ 1219 0, /* tp_descr_get */ 1220 0, /* tp_descr_set */ 1221 0, /* tp_dictoffset */ 1222 0, /* tp_init */ 1223 0, /* tp_alloc */ 1224 msg_data_new, /* tp_new */ 1225 1226 }; 1227 1228 1229 /* 1230 * pj_pool_Object 1231 */ 1232 typedef struct 1233 { 1234 PyObject_HEAD 1235 /* Type-specific fields go here. */ 1236 pj_pool_t * pool; 1237 } pj_pool_Object; 1238 1239 1240 /* 1241 * pj_pool_Type 1242 */ 1243 static PyTypeObject pj_pool_Type = 1244 { 1245 PyObject_HEAD_INIT(NULL) 1246 0, /*ob_size*/ 1247 "py_pjsua.PJ_Pool", /*tp_name*/ 1248 sizeof(pj_pool_Object), /*tp_basicsize*/ 1249 0, /*tp_itemsize*/ 1250 0, /*tp_dealloc*/ 1251 0, /*tp_print*/ 1252 0, /*tp_getattr*/ 1253 0, /*tp_setattr*/ 1254 0, /*tp_compare*/ 1255 0, /*tp_repr*/ 1256 0, /*tp_as_number*/ 1257 0, /*tp_as_sequence*/ 1258 0, /*tp_as_mapping*/ 1259 0, /*tp_hash */ 1260 0, /*tp_call*/ 1261 0, /*tp_str*/ 1262 0, /*tp_getattro*/ 1263 0, /*tp_setattro*/ 1264 0, /*tp_as_buffer*/ 1265 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 1266 "pj_pool_t objects", /* tp_doc */ 1267 1268 }; 1269 1270 1271 /* 1272 * pjsip_endpoint_Object 1273 */ 1274 typedef struct 1275 { 1276 PyObject_HEAD 1277 /* Type-specific fields go here. */ 1278 pjsip_endpoint * endpt; 1279 } pjsip_endpoint_Object; 1280 1281 1282 /* 1283 * pjsip_endpoint_Type 1284 */ 1285 static PyTypeObject pjsip_endpoint_Type = 1286 { 1287 PyObject_HEAD_INIT(NULL) 1288 0, /*ob_size*/ 1289 "py_pjsua.PJSIP_Endpoint", /*tp_name*/ 1290 sizeof(pjsip_endpoint_Object),/*tp_basicsize*/ 1291 0, /*tp_itemsize*/ 1292 0, /*tp_dealloc*/ 1293 0, /*tp_print*/ 1294 0, /*tp_getattr*/ 1295 0, /*tp_setattr*/ 1296 0, /*tp_compare*/ 1297 0, /*tp_repr*/ 1298 0, /*tp_as_number*/ 1299 0, /*tp_as_sequence*/ 1300 0, /*tp_as_mapping*/ 1301 0, /*tp_hash */ 1302 0, /*tp_call*/ 1303 0, /*tp_str*/ 1304 0, /*tp_getattro*/ 1305 0, /*tp_setattro*/ 1306 0, /*tp_as_buffer*/ 1307 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 1308 "pjsip_endpoint objects", /* tp_doc */ 1309 }; 1310 1311 1312 /* 1313 * pjmedia_endpt_Object 1314 */ 1315 typedef struct 1316 { 1317 PyObject_HEAD 1318 /* Type-specific fields go here. */ 1319 pjmedia_endpt * endpt; 1320 } pjmedia_endpt_Object; 1321 1322 1323 /* 1324 * pjmedia_endpt_Type 1325 */ 1326 static PyTypeObject pjmedia_endpt_Type = 1327 { 1328 PyObject_HEAD_INIT(NULL) 1329 0, /*ob_size*/ 1330 "py_pjsua.PJMedia_Endpt", /*tp_name*/ 1331 sizeof(pjmedia_endpt_Object), /*tp_basicsize*/ 1332 0, /*tp_itemsize*/ 1333 0, /*tp_dealloc*/ 1334 0, /*tp_print*/ 1335 0, /*tp_getattr*/ 1336 0, /*tp_setattr*/ 1337 0, /*tp_compare*/ 1338 0, /*tp_repr*/ 1339 0, /*tp_as_number*/ 1340 0, /*tp_as_sequence*/ 1341 0, /*tp_as_mapping*/ 1342 0, /*tp_hash */ 1343 0, /*tp_call*/ 1344 0, /*tp_str*/ 1345 0, /*tp_getattro*/ 1346 0, /*tp_setattro*/ 1347 0, /*tp_as_buffer*/ 1348 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 1349 "pjmedia_endpt objects", /* tp_doc */ 1350 1351 }; 1352 1353 1354 /* 1355 * pj_pool_factory_Object 1356 */ 1357 typedef struct 1358 { 1359 PyObject_HEAD 1360 /* Type-specific fields go here. */ 1361 pj_pool_factory * pool_fact; 1362 } pj_pool_factory_Object; 1363 1364 1365 1366 /* 1367 * pj_pool_factory_Type 1368 */ 1369 static PyTypeObject pj_pool_factory_Type = 1370 { 1371 PyObject_HEAD_INIT(NULL) 1372 0, /*ob_size*/ 1373 "py_pjsua.PJ_Pool_Factory",/*tp_name*/ 1374 sizeof(pj_pool_factory_Object), /*tp_basicsize*/ 1375 0, /*tp_itemsize*/ 1376 0, /*tp_dealloc*/ 1377 0, /*tp_print*/ 1378 0, /*tp_getattr*/ 1379 0, /*tp_setattr*/ 1380 0, /*tp_compare*/ 1381 0, /*tp_repr*/ 1382 0, /*tp_as_number*/ 1383 0, /*tp_as_sequence*/ 1384 0, /*tp_as_mapping*/ 1385 0, /*tp_hash */ 1386 0, /*tp_call*/ 1387 0, /*tp_str*/ 1388 0, /*tp_getattro*/ 1389 0, /*tp_setattro*/ 1390 0, /*tp_as_buffer*/ 1391 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 1392 "pj_pool_factory objects", /* tp_doc */ 1393 1394 }; 1395 1396 1397 /* 1398 * pjsip_cred_info_Object 1399 */ 1400 typedef struct 1401 { 1402 PyObject_HEAD 1403 /* Type-specific fields go here. */ 1404 pjsip_cred_info * cred; 1405 } pjsip_cred_info_Object; 1406 1407 1408 /* 1409 * pjsip_cred_info_Type 1410 */ 1411 static PyTypeObject pjsip_cred_info_Type = 1412 { 1413 PyObject_HEAD_INIT(NULL) 1414 0, /*ob_size*/ 1415 "py_pjsua.PJSIP_Cred_Info",/*tp_name*/ 1416 sizeof(pjsip_cred_info_Object), /*tp_basicsize*/ 1417 0, /*tp_itemsize*/ 1418 0, /*tp_dealloc*/ 1419 0, /*tp_print*/ 1420 0, /*tp_getattr*/ 1421 0, /*tp_setattr*/ 1422 0, /*tp_compare*/ 1423 0, /*tp_repr*/ 1424 0, /*tp_as_number*/ 1425 0, /*tp_as_sequence*/ 1426 0, /*tp_as_mapping*/ 1427 0, /*tp_hash */ 1428 0, /*tp_call*/ 1429 0, /*tp_str*/ 1430 0, /*tp_getattro*/ 1431 0, /*tp_setattro*/ 1432 0, /*tp_as_buffer*/ 1433 Py_TPFLAGS_DEFAULT, /*tp_flags*/ 1434 "pjsip_cred_info objects", /* tp_doc */ 1435 1436 }; 1437 1438 1439 /* 1440 * py_pjsua_logging_config_default 1441 */ 1442 static PyObject *py_pjsua_logging_config_default(PyObject *pSelf, 1443 PyObject *pArgs) 1444 { 1445 logging_config_Object *obj; 1446 pjsua_logging_config cfg; 1447 1448 if (!PyArg_ParseTuple(pArgs, "O", &obj)) 1449 { 1450 return NULL; 1451 } 1452 /*pj_bzero(cfg, sizeof(*cfg)); 1453 1454 cfg->msg_logging = obj->msg_logging; 1455 cfg->level = obj->level; 1456 cfg->console_level = obj->console_level; 1457 cfg->decor = obj->decor;*/ 1458 pjsua_logging_config_default(&cfg); 1459 obj->msg_logging = cfg.msg_logging; 1460 obj->level = cfg.level; 1461 obj->console_level = cfg.console_level; 1462 obj->decor = cfg.decor; 1463 /*printf("msg logging : %d\n",obj->msg_logging); 1464 printf("level : %d\n",obj->level); 1465 printf("console level : %d\n",obj->console_level); 1466 printf("decor : %d\n",obj->decor); 1467 printf("str sebelum "); 1468 printf(PyString_AsString(obj->log_filename)); 1469 1470 Py_XDECREF(obj->log_filename); 1471 obj->log_filename = PyString_FromString("oke"); 1472 printf("\nstr sesudah "); 1473 printf(PyString_AsString(obj->log_filename));*/ 1474 Py_INCREF(Py_None); 1475 return Py_None; 1476 } 1477 1478 1479 /* 1480 * py_pjsua_config_default 1481 */ 1482 static PyObject *py_pjsua_config_default(PyObject *pSelf, PyObject *pArgs) 1483 { 1484 config_Object *obj; 1485 pjsua_config cfg; 1486 1487 if (!PyArg_ParseTuple(pArgs, "O", &obj)) 1488 { 1489 return NULL; 1490 } 1491 pjsua_config_default(&cfg); 1492 obj->max_calls = cfg.max_calls; 1493 obj->thread_cnt = cfg.thread_cnt; 1494 Py_INCREF(Py_None); 1495 return Py_None; 1496 } 1497 1498 1499 /* 1500 * py_pjsua_media_config_default 1501 */ 1502 static PyObject * py_pjsua_media_config_default(PyObject *pSelf, 1503 PyObject *pArgs) 1504 { 1505 media_config_Object *obj; 1506 pjsua_media_config cfg; 1507 if (!PyArg_ParseTuple(pArgs, "O", &obj)) 1508 { 1509 return NULL; 1510 } 1511 pjsua_media_config_default(&cfg); 1512 obj->clock_rate = cfg.clock_rate; 1513 obj->ec_options = cfg.ec_options; 1514 obj->ec_tail_len = cfg.ec_tail_len; 1515 obj->has_ioqueue = cfg.has_ioqueue; 1516 obj->ilbc_mode = cfg.ilbc_mode; 1517 obj->max_media_ports = cfg.max_media_ports; 1518 obj->no_vad = cfg.no_vad; 1519 obj->ptime = cfg.ptime; 1520 obj->quality = cfg.quality; 1521 obj->rx_drop_pct = cfg.rx_drop_pct; 1522 obj->thread_cnt = cfg.thread_cnt; 1523 obj->tx_drop_pct = cfg.tx_drop_pct; 1524 Py_INCREF(Py_None); 1525 return Py_None; 1526 } 1527 1528 1529 /* 1530 * py_pjsua_msg_data_init 1531 */ 1532 static PyObject *py_pjsua_msg_data_init(PyObject *pSelf, PyObject *pArgs) 1533 { 1534 msg_data_Object *obj; 1535 pjsua_msg_data msg; 1536 if (!PyArg_ParseTuple(pArgs, "O", &obj)) 1537 { 1538 return NULL; 1539 } 1540 pjsua_msg_data_init(&msg); 1541 Py_XDECREF(obj->content_type); 1542 obj->content_type = PyString_FromStringAndSize( 1543 msg.content_type.ptr, msg.content_type.slen 1544 ); 1545 Py_XDECREF(obj->msg_body); 1546 obj->msg_body = PyString_FromStringAndSize( 1547 msg.msg_body.ptr, msg.msg_body.slen 1548 ); 1549 obj->hdr_list = msg.hdr_list; 1550 Py_INCREF(Py_None); 1551 return Py_None; 1552 } 1553 1554 1555 /* 1556 * py_pjsua_logging_config_dup 1557 */ 1558 static PyObject *py_pjsua_logging_config_dup(PyObject *pSelf, PyObject *pArgs) 1559 { 1560 pj_pool_Object *pool; 1561 logging_config_Object *src; 1562 logging_config_Object *dest; 1563 pj_str_t strdest; 1564 pj_str_t strsrc; 1565 int len; 1566 1567 if (!PyArg_ParseTuple(pArgs, "OOO", &pool, &dest, &src)) 1568 { 1569 return NULL; 1570 } 1571 pj_memcpy(dest, src, sizeof(*src)); 1572 len = strlen(PyString_AsString(src->log_filename)); 1573 strsrc.ptr = PyString_AsString(src->log_filename); 1574 strsrc.slen = len; 1575 pj_strdup_with_null(pool->pool, &strdest, &strsrc); 1576 Py_XDECREF(dest->log_filename); 1577 dest->log_filename = PyString_FromStringAndSize(strdest.ptr, strdest.slen); 1578 Py_INCREF(Py_None); 1579 return Py_None; 1580 } 1581 1582 1583 /* 1584 * py_pjsua_config_dup 1585 */ 1586 static PyObject *py_pjsua_config_dup(PyObject *pSelf, PyObject *pArgs) 1587 { 1588 pj_pool_Object *pool; 1589 config_Object *src; 1590 config_Object *dest; 1591 pj_str_t strdest; 1592 pj_str_t strsrc; 1593 int len; 1594 unsigned i; 1595 1596 if (!PyArg_ParseTuple(pArgs, "OOO", &pool, &dest, &src)) 1597 { 1598 return NULL; 1599 } 1600 pj_memcpy(dest, src, sizeof(*src)); 1601 1602 for (i=0; i<src->outbound_proxy_cnt; ++i) 1603 { 1604 pj_strdup_with_null( 1605 pool->pool, &dest->outbound_proxy[i], &src->outbound_proxy[i] 1606 ); 1607 } 1608 1609 for (i=0; i<src->cred_count; ++i) 1610 { 1611 pjsip_cred_dup(pool->pool, &dest->cred_info[i], &src->cred_info[i]); 1612 } 1613 len = strlen(PyString_AsString(src->user_agent)); 1614 strsrc.ptr = PyString_AsString(src->user_agent); 1615 strsrc.slen = len; 1616 pj_strdup_with_null(pool->pool, &strdest, &strsrc); 1617 Py_XDECREF(dest->user_agent); 1618 dest->user_agent = PyString_FromStringAndSize(strdest.ptr, strdest.slen); 1619 Py_INCREF(Py_None); 1620 return Py_None; 1621 } 1622 1623 1624 /* 1625 * py_pjsip_cred_dup 1626 */ 1627 static PyObject *py_pjsip_cred_dup(PyObject *pSelf, PyObject *pArgs) 1628 { 1629 pj_pool_Object *pool; 1630 pjsip_cred_info_Object *src; 1631 pjsip_cred_info_Object *dest; 1632 if (!PyArg_ParseTuple(pArgs, "OOO", &pool, &dest, &src)) 1633 { 1634 return NULL; 1635 } 1636 pjsip_cred_dup(pool->pool, dest->cred, src->cred); 1637 Py_INCREF(Py_None); 1638 return Py_None; 1639 } 1640 1641 1642 /* 1643 * py_pjsua_reconfigure_logging 1644 */ 1645 static PyObject *py_pjsua_reconfigure_logging(PyObject *pSelf, PyObject *pArgs) 1646 { 1647 logging_config_Object *log; 1648 pjsua_logging_config cfg; 1649 pj_status_t status; 1650 1651 if (!PyArg_ParseTuple(pArgs, "O", &log)) 1652 { 1653 return NULL; 1654 } 1655 cfg.msg_logging = log->msg_logging; 1656 cfg.level = log->level; 1657 cfg.console_level = log->console_level; 1658 cfg.decor = log->decor; 1659 cfg.log_filename.ptr = PyString_AsString(log->log_filename); 1660 cfg.log_filename.slen = strlen(cfg.log_filename.ptr); 1661 Py_XDECREF(obj_reconfigure_logging); 1662 obj_reconfigure_logging = log->cb; 1663 Py_INCREF(obj_reconfigure_logging); 1664 cfg.cb = &cb_reconfigure_logging; 1665 status = pjsua_reconfigure_logging(&cfg); 1666 return Py_BuildValue("i",status); 1667 } 1668 1669 1670 /* 1671 * py_pjsua_pool_create 1672 */ 1673 static PyObject *py_pjsua_pool_create(PyObject *pSelf, PyObject *pArgs) 1674 { 1675 pj_size_t init_size; 1676 pj_size_t increment; 1677 const char * name; 1678 pj_pool_t *p; 1679 pj_pool_Object *pool; 1680 1681 if (!PyArg_ParseTuple(pArgs, "sII", &name, &init_size, &increment)) 1682 { 1683 return NULL; 1684 } 1685 /*printf("name : %s\n",name); 1686 printf("init : %d\n", init_size); 1687 printf("increment : %d\n", increment);*/ 1688 p = pjsua_pool_create(name, init_size, increment); 1689 pool = (pj_pool_Object *)PyType_GenericNew(&pj_pool_Type, NULL, NULL); 1690 pool->pool = p; 1691 return (PyObject *)pool; 1692 1693 } 1694 1695 1696 /* 1697 * py_pjsua_get_pjsip_endpt 1698 */ 1699 static PyObject *py_pjsua_get_pjsip_endpt(PyObject *pSelf, PyObject *pArgs) 1700 { 1701 pjsip_endpoint_Object *endpt; 1702 pjsip_endpoint *e; 1703 1704 if (!PyArg_ParseTuple(pArgs, "")) 1705 { 1706 return NULL; 1707 } 1708 e = pjsua_get_pjsip_endpt(); 1709 endpt = (pjsip_endpoint_Object *)PyType_GenericNew( 1710 &pjsip_endpoint_Type, NULL, NULL 1711 ); 1712 endpt->endpt = e; 1713 return (PyObject *)endpt; 1714 } 1715 1716 1717 /* 1718 * py_pjsua_get_pjmedia_endpt 1719 */ 1720 static PyObject *py_pjsua_get_pjmedia_endpt(PyObject *pSelf, PyObject *pArgs) 1721 { 1722 pjmedia_endpt_Object *endpt; 1723 pjmedia_endpt *e; 1724 1725 if (!PyArg_ParseTuple(pArgs, "")) 1726 { 1727 return NULL; 1728 } 1729 e = pjsua_get_pjmedia_endpt(); 1730 endpt = (pjmedia_endpt_Object *)PyType_GenericNew( 1731 &pjmedia_endpt_Type, NULL, NULL 1732 ); 1733 endpt->endpt = e; 1734 return (PyObject *)endpt; 1735 } 1736 1737 1738 /* 1739 * py_pjsua_get_pool_factory 1740 */ 1741 static PyObject *py_pjsua_get_pool_factory(PyObject *pSelf, PyObject *pArgs) 1742 { 1743 pj_pool_factory_Object *pool; 1744 pj_pool_factory *p; 1745 1746 if (!PyArg_ParseTuple(pArgs, "")) 1747 { 1748 return NULL; 1749 } 1750 p = pjsua_get_pool_factory(); 1751 pool = (pj_pool_factory_Object *)PyType_GenericNew( 1752 &pj_pool_factory_Type, NULL, NULL 1753 ); 1754 pool->pool_fact = p; 1755 return (PyObject *)pool; 1756 } 1757 1758 1759 /* 1760 * py_pjsua_perror 1761 */ 1762 static PyObject *py_pjsua_perror(PyObject *pSelf, PyObject *pArgs) 1763 { 1764 const char *sender; 1765 const char *title; 1766 pj_status_t status; 1767 if (!PyArg_ParseTuple(pArgs, "ssi", &sender, &title, &status)) 1768 { 1769 return NULL; 1770 } 1771 pjsua_perror(sender, title, status); 1772 Py_INCREF(Py_None); 1773 return Py_None; 1774 } 1775 1776 1777 /* 1778 * py_pjsua_create 1779 */ 1780 static PyObject *py_pjsua_create(PyObject *pSelf, PyObject *pArgs) 1781 { 1782 pj_status_t status; 1783 if (!PyArg_ParseTuple(pArgs, "")) 1784 { 1785 return NULL; 1786 } 1787 status = pjsua_create(); 1788 printf("status %d\n",status); 1789 return Py_BuildValue("i",status); 1790 } 1791 1792 1793 /* 1794 * py_pjsua_init 1795 */ 1796 static PyObject *py_pjsua_init(PyObject *pSelf, PyObject *pArgs) 1797 { 1798 pj_status_t status; 1799 config_Object * ua_cfg; 1800 logging_config_Object * log_cfg; 1801 media_config_Object * media_cfg; 1802 pjsua_config cfg_ua; 1803 pjsua_logging_config cfg_log; 1804 pjsua_media_config cfg_media; 1805 unsigned i; 1806 1807 if (!PyArg_ParseTuple(pArgs, "OOO", &ua_cfg, &log_cfg, &media_cfg)) 1808 { 1809 return NULL; 1810 } 1811 1812 pjsua_config_default(&cfg_ua); 1813 pjsua_logging_config_default(&cfg_log); 1814 pjsua_media_config_default(&cfg_media); 1815 cfg_ua.cred_count = ua_cfg->cred_count; 1816 for (i = 0; i < 4; i++) 1817 { 1818 cfg_ua.cred_info[i] = ua_cfg->cred_info[i]; 1819 } 1820 cfg_ua.max_calls = ua_cfg->max_calls; 1821 for (i = 0; i < PJSUA_ACC_MAX_PROXIES; i++) 1822 { 1823 cfg_ua.outbound_proxy[i] = ua_cfg->outbound_proxy[i]; 1824 } 1825 1826 cfg_ua.outbound_proxy_cnt = ua_cfg->outbound_proxy_cnt; 1827 cfg_ua.thread_cnt = ua_cfg->thread_cnt; 1828 cfg_ua.user_agent.ptr = PyString_AsString(ua_cfg->user_agent); 1829 cfg_ua.user_agent.slen = strlen(cfg_ua.user_agent.ptr); 1830 1831 obj_callback = ua_cfg->cb; 1832 cfg_ua.cb.on_call_state = &cb_on_call_state; 1833 cfg_ua.cb.on_incoming_call = &cb_on_incoming_call; 1834 cfg_ua.cb.on_call_media_state = &cb_on_call_media_state; 1835 cfg_ua.cb.on_call_transfer_request = &cb_on_call_transfer_request; 1836 cfg_ua.cb.on_call_transfer_status = &cb_on_call_transfer_status; 1837 cfg_ua.cb.on_call_replace_request = &cb_on_call_replace_request; 1838 cfg_ua.cb.on_call_replaced = &cb_on_call_replaced; 1839 cfg_ua.cb.on_reg_state = &cb_on_reg_state; 1840 cfg_ua.cb.on_buddy_state = &cb_on_buddy_state; 1841 cfg_ua.cb.on_pager = &cb_on_pager; 1842 cfg_ua.cb.on_pager_status = &cb_on_pager_status; 1843 cfg_ua.cb.on_typing = &cb_on_typing; 1844 1845 cfg_log.msg_logging = log_cfg->msg_logging; 1846 cfg_log.level = log_cfg->level; 1847 cfg_log.console_level = log_cfg->console_level; 1848 cfg_log.decor = log_cfg->decor; 1849 cfg_log.log_filename.ptr = PyString_AsString(log_cfg->log_filename); 1850 cfg_log.log_filename.slen = strlen(cfg_log.log_filename.ptr); 1851 Py_XDECREF(obj_logging_init); 1852 obj_logging_init = log_cfg->cb; 1853 Py_INCREF(obj_logging_init); 1854 cfg_log.cb = &cb_logging_init; 1855 1856 1857 cfg_media.clock_rate = media_cfg->clock_rate; 1858 cfg_media.ec_options = media_cfg->ec_options; 1859 cfg_media.ec_tail_len = media_cfg->ec_tail_len; 1860 cfg_media.has_ioqueue = media_cfg->has_ioqueue; 1861 cfg_media.ilbc_mode = media_cfg->ilbc_mode; 1862 cfg_media.max_media_ports = media_cfg->max_media_ports; 1863 cfg_media.no_vad = media_cfg->no_vad; 1864 cfg_media.ptime = media_cfg->ptime; 1865 cfg_media.quality = media_cfg->quality; 1866 cfg_media.rx_drop_pct = media_cfg->rx_drop_pct; 1867 cfg_media.thread_cnt = media_cfg->thread_cnt; 1868 cfg_media.tx_drop_pct = media_cfg->tx_drop_pct; 1869 1870 status = pjsua_init(&cfg_ua, &cfg_log, &cfg_media); 1871 return Py_BuildValue("i",status); 1872 } 1873 1874 1875 /* 1876 * py_pjsua_start 1877 */ 1878 static PyObject *py_pjsua_start(PyObject *pSelf, PyObject *pArgs) 1879 { 1880 pj_status_t status; 1881 if (!PyArg_ParseTuple(pArgs, "")) 1882 { 1883 return NULL; 1884 } 1885 status = pjsua_start(); 1886 printf("status %d\n",status); 1887 return Py_BuildValue("i",status); 1888 } 1889 1890 1891 /* 1892 * py_pjsua_destroy 1893 */ 1894 static PyObject *py_pjsua_destroy(PyObject *pSelf, PyObject *pArgs) 1895 { 1896 pj_status_t status; 1897 if (!PyArg_ParseTuple(pArgs, "")) 1898 { 1899 return NULL; 1900 } 1901 status = pjsua_destroy(); 1902 printf("status %d\n",status); 1903 return Py_BuildValue("i",status); 1904 } 1905 1906 1907 /* 1908 * py_pjsua_handle_events 1909 */ 1910 static PyObject *py_pjsua_handle_events(PyObject *pSelf, PyObject *pArgs) 1911 { 1912 int ret; 1913 unsigned msec; 1914 if (!PyArg_ParseTuple(pArgs, "i", &msec)) 1915 { 1916 return NULL; 1917 } 1918 ret = pjsua_handle_events(msec); 1919 printf("return %d\n",ret); 1920 return Py_BuildValue("i",ret); 1921 } 1922 1923 1924 /* 1925 * py_pjsua_verify_sip_url 1926 */ 1927 static PyObject *py_pjsua_verify_sip_url(PyObject *pSelf, PyObject *pArgs) 1928 { 1929 pj_status_t status; 1930 const char *url; 1931 if (!PyArg_ParseTuple(pArgs, "s", &url)) 1932 { 1933 return NULL; 1934 } 1935 status = pjsua_verify_sip_url(url); 1936 printf("status %d\n",status); 1937 return Py_BuildValue("i",status); 1938 } 1939 1940 1941 1942 1943 1944 1945 /* 1946 * error messages 1947 */ 1948 1949 static char pjsua_perror_doc[] = 1950 "void py_pjsua.perror (string sender, string title, int status) " 1951 "Display error message for the specified error code. Parameters: " 1952 "sender: The log sender field; " 1953 "title: Message title for the error; " 1954 "status: Status code."; 1955 1956 static char pjsua_create_doc[] = 1957 "int py_pjsua.create (void) " 1958 "Instantiate pjsua application. Application " 1959 "must call this function before calling any other functions, to make sure " 1960 "that the underlying libraries are properly initialized. Once this " 1961 "function has returned success, application must call pjsua_destroy() " 1962 "before quitting."; 1963 1964 static char pjsua_init_doc[] = 1965 "int py_pjsua.init (py_pjsua.Config ua_cfg, " 1966 "py_pjsua.Logging_Config log_cfg, py_pjsua.Media_Config media_cfg) " 1967 "Initialize pjsua with the specified settings. All the settings are " 1968 "optional, and the default values will be used when the config is not " 1969 "specified. Parameters: " 1970 "ua_cfg : User agent configuration; " 1971 "log_cfg : Optional logging configuration; " 1972 "media_cfg : Optional media configuration."; 1973 1974 static char pjsua_start_doc[] = 1975 "int py_pjsua.start (void) " 1976 "Application is recommended to call this function after all " 1977 "initialization is done, so that the library can do additional checking " 1978 "set up additional"; 1979 1980 static char pjsua_destroy_doc[] = 1981 "int py_pjsua.destroy (void) " 1982 "Destroy pjsua This function must be called once PJSUA is created. To " 1983 "make it easier for application, application may call this function " 1984 "several times with no danger."; 1985 1986 static char pjsua_handle_events_doc[] = 1987 "int py_pjsua.handle_events (int msec_timeout) " 1988 "Poll pjsua for events, and if necessary block the caller thread for the " 1989 "specified maximum interval (in miliseconds) Parameters: " 1990 "msec_timeout: Maximum time to wait, in miliseconds. " 1991 "Returns: The number of events that have been handled during the poll. " 1992 "Negative value indicates error, and application can retrieve the error " 1993 "as (err = -return_value)."; 1994 1995 static char pjsua_verify_sip_url_doc[] = 1996 "int py_pjsua.verify_sip_url (string c_url) " 1997 "Verify that valid SIP url is given Parameters: " 1998 "c_url: The URL, as NULL terminated string."; 1999 2000 static char pjsua_pool_create_doc[] = 2001 "py_pjsua.PJ_Pool py_pjsua.pool_create (string name, int init_size, " 2002 "int increment) " 2003 "Create memory pool Parameters: " 2004 "name: Optional pool name; " 2005 "init_size: Initial size of the pool; " 2006 "increment: Increment size."; 2007 2008 static char pjsua_get_pjsip_endpt_doc[] = 2009 "py_pjsua.PJSIP_Endpoint py_pjsua.get_pjsip_endpt (void) " 2010 "Internal function to get SIP endpoint instance of pjsua, which is needed " 2011 "for example to register module, create transports, etc. Probably is only " 2012 "valid after pjsua_init() is called."; 2013 2014 static char pjsua_get_pjmedia_endpt_doc[] = 2015 "py_pjsua.PJMedia_Endpt py_pjsua.get_pjmedia_endpt (void) " 2016 "Internal function to get media endpoint instance. Only valid after " 2017 "pjsua_init() is called."; 2018 2019 static char pjsua_get_pool_factory_doc[] = 2020 "py_pjsua.PJ_Pool_Factory py_pjsua.get_pool_factory (void) " 2021 "Internal function to get PJSUA pool factory. Only valid after " 2022 "pjsua_init() is called."; 2023 2024 static char pjsua_reconfigure_logging_doc[] = 2025 "int py_pjsua.reconfigure_logging (py_pjsua.Logging_Config c) " 2026 "Application can call this function at any time (after pjsua_create(), of " 2027 "course) to change logging settings. Parameters: " 2028 "c: Logging configuration."; 2029 2030 static char pjsua_logging_config_default_doc[] = 2031 "void py_pjsua.logging_config_default (py_pjsua.Logging_Config cfg) " 2032 "Use this function to initialize logging config."; 2033 2034 static char pjsua_config_default_doc[] = 2035 "void py_pjsua.config_default (py_pjsua.Config cfg). Use this function to " 2036 "initialize pjsua config. Parameters: " 2037 "cfg: pjsua config to be initialized."; 2038 2039 static char pjsua_media_config_default_doc[] = 2040 "Use this function to initialize media config."; 2041 2042 static char pjsua_logging_config_dup_doc[] = 2043 "void py_pjsua.logging_config_dup (py_pjsua.PJ_Pool pool, " 2044 "py_pjsua.Logging_Config dst, py_pjsua.Logging_Config src) " 2045 "Use this function to duplicate logging config. Parameters: " 2046 "pool: Pool to use; " 2047 "dst: Destination config; " 2048 "src: Source config."; 2049 2050 static char pjsua_config_dup_doc[] = 2051 "void py_pjsua.config_dup (py_pjsua.PJ_Pool pool, py_pjsua.Config dst, " 2052 "py_pjsua.Config src) " 2053 "Duplicate pjsua_config. "; 2054 2055 static char pjsip_cred_dup_doc[] = 2056 "void py_pjsua.pjsip_cred_dup (py_pjsua.PJ_Pool pool, " 2057 "py_pjsua.PJSIP_Cred_Info dst, " 2058 "py_pjsua.PJSIP_Cred_Info src) " 2059 "Duplicate credential."; 2060 2061 static char pjsua_msg_data_init_doc[] = 2062 "void py_pjsua.msg_data_init (py_pjsua.Msg_Data msg_data) " 2063 "Initialize message data Parameters: " 2064 "msg_data: Message data to be initialized."; 2065 2066 2067 /* 2068 * Map of function names to functions 2069 */ 2070 static PyMethodDef py_pjsua_methods[] = 2071 { 2072 { 2073 "perror", py_pjsua_perror, METH_VARARGS, pjsua_perror_doc 2074 }, 2075 { 2076 "create", py_pjsua_create, METH_VARARGS, pjsua_create_doc 2077 }, 2078 { 2079 "init", py_pjsua_init, METH_VARARGS, pjsua_init_doc 2080 }, 2081 { 2082 "start", py_pjsua_start, METH_VARARGS, pjsua_start_doc 2083 }, 2084 { 2085 "destroy", py_pjsua_destroy, METH_VARARGS, pjsua_destroy_doc 2086 }, 2087 { 2088 "handle_events", py_pjsua_handle_events, METH_VARARGS, 2089 pjsua_handle_events_doc 2090 }, 2091 { 2092 "verify_sip_url", py_pjsua_verify_sip_url, METH_VARARGS, 2093 pjsua_verify_sip_url_doc 2094 }, 2095 { 2096 "pool_create", py_pjsua_pool_create, METH_VARARGS, 2097 pjsua_pool_create_doc 2098 }, 2099 { 2100 "get_pjsip_endpt", py_pjsua_get_pjsip_endpt, METH_VARARGS, 2101 pjsua_get_pjsip_endpt_doc 2102 }, 2103 { 2104 "get_pjmedia_endpt", py_pjsua_get_pjmedia_endpt, METH_VARARGS, 2105 pjsua_get_pjmedia_endpt_doc 2106 }, 2107 { 2108 "get_pool_factory", py_pjsua_get_pool_factory, METH_VARARGS, 2109 pjsua_get_pool_factory_doc 2110 }, 2111 { 2112 "reconfigure_logging", py_pjsua_reconfigure_logging, METH_VARARGS, 2113 pjsua_reconfigure_logging_doc 2114 }, 2115 { 2116 "logging_config_default", py_pjsua_logging_config_default, 2117 METH_VARARGS, pjsua_logging_config_default_doc 2118 }, 2119 { 2120 "config_default", py_pjsua_config_default, METH_VARARGS, 2121 pjsua_config_default_doc 2122 }, 2123 { 2124 "media_config_default", py_pjsua_media_config_default, METH_VARARGS, 2125 pjsua_media_config_default_doc 2126 }, 2127 { 2128 "logging_config_dup", py_pjsua_logging_config_dup, METH_VARARGS, 2129 pjsua_logging_config_dup_doc 2130 }, 2131 { 2132 "config_dup", py_pjsua_config_dup, METH_VARARGS, pjsua_config_dup_doc 2133 }, 2134 { 2135 "pjsip_cred_dup", py_pjsip_cred_dup, METH_VARARGS, pjsip_cred_dup_doc 2136 }, 2137 { 2138 "msg_data_init", py_pjsua_msg_data_init, METH_VARARGS, 2139 pjsua_msg_data_init_doc 2140 }, 2141 {NULL, NULL} /* end of function list */ 2142 }; 2143 2144 2145 2146 /* 2147 * Mapping C structs from and to Python objects & initializing object 2148 */ 2149 DL_EXPORT(void) 85 2150 initpy_pjsua(void) 86 2151 { 87 Py_InitModule("py_pjsua", py_pjsua_methods); 88 } 2152 PyObject* m = NULL; 2153 2154 if (PyType_Ready(&callback_Type) < 0) 2155 return; 2156 if (PyType_Ready(&config_Type) < 0) 2157 return; 2158 if (PyType_Ready(&logging_config_Type) < 0) 2159 return; 2160 if (PyType_Ready(&msg_data_Type) < 0) 2161 return; 2162 media_config_Type.tp_new = PyType_GenericNew; 2163 if (PyType_Ready(&media_config_Type) < 0) 2164 return; 2165 pjsip_event_Type.tp_new = PyType_GenericNew; 2166 if (PyType_Ready(&pjsip_event_Type) < 0) 2167 return; 2168 pjsip_rx_data_Type.tp_new = PyType_GenericNew; 2169 if (PyType_Ready(&pjsip_rx_data_Type) < 0) 2170 return; 2171 pj_pool_Type.tp_new = PyType_GenericNew; 2172 if (PyType_Ready(&pj_pool_Type) < 0) 2173 return; 2174 pjsip_endpoint_Type.tp_new = PyType_GenericNew; 2175 if (PyType_Ready(&pjsip_endpoint_Type) < 0) 2176 return; 2177 pjmedia_endpt_Type.tp_new = PyType_GenericNew; 2178 if (PyType_Ready(&pjmedia_endpt_Type) < 0) 2179 return; 2180 pj_pool_factory_Type.tp_new = PyType_GenericNew; 2181 if (PyType_Ready(&pj_pool_factory_Type) < 0) 2182 return; 2183 pjsip_cred_info_Type.tp_new = PyType_GenericNew; 2184 if (PyType_Ready(&pjsip_cred_info_Type) < 0) 2185 return; 2186 2187 m = Py_InitModule3( 2188 "py_pjsua", py_pjsua_methods,"PJSUA-lib module for python" 2189 ); 2190 2191 Py_INCREF(&callback_Type); 2192 PyModule_AddObject(m, "Callback", (PyObject *)&callback_Type); 2193 2194 Py_INCREF(&config_Type); 2195 PyModule_AddObject(m, "Config", (PyObject *)&config_Type); 2196 2197 Py_INCREF(&media_config_Type); 2198 PyModule_AddObject(m, "Media_Config", (PyObject *)&media_config_Type); 2199 2200 Py_INCREF(&logging_config_Type); 2201 PyModule_AddObject(m, "Logging_Config", (PyObject *)&logging_config_Type); 2202 2203 Py_INCREF(&msg_data_Type); 2204 PyModule_AddObject(m, "Msg_Data", (PyObject *)&msg_data_Type); 2205 2206 Py_INCREF(&pjsip_event_Type); 2207 PyModule_AddObject(m, "PJSIP_Event", (PyObject *)&pjsip_event_Type); 2208 2209 Py_INCREF(&pjsip_rx_data_Type); 2210 PyModule_AddObject(m, "PJSIP_RX_Data", (PyObject *)&pjsip_rx_data_Type); 2211 2212 Py_INCREF(&pj_pool_Type); 2213 PyModule_AddObject(m, "PJ_Pool", (PyObject *)&pj_pool_Type); 2214 2215 Py_INCREF(&pjsip_endpoint_Type); 2216 PyModule_AddObject(m, "PJSIP_Endpoint", (PyObject *)&pjsip_endpoint_Type); 2217 2218 Py_INCREF(&pjmedia_endpt_Type); 2219 PyModule_AddObject(m, "PJMedia_Endpt", (PyObject *)&pjmedia_endpt_Type); 2220 2221 Py_INCREF(&pj_pool_factory_Type); 2222 PyModule_AddObject( 2223 m, "PJ_Pool_Factory", (PyObject *)&pj_pool_factory_Type 2224 ); 2225 2226 Py_INCREF(&pjsip_cred_info_Type); 2227 PyModule_AddObject(m, "PJSIP_Cred_Info", 2228 (PyObject *)&pjsip_cred_info_Type 2229 ); 2230 2231 2232 #ifdef PJSUA_INVALID_ID 2233 /* 2234 * Constant to identify invalid ID for all sorts of IDs. 2235 */ 2236 PyModule_AddIntConstant(m, "PJSUA_INVALID_ID", PJSUA_INVALID_ID); 2237 #endif 2238 2239 #ifdef PJSUA_ACC_MAX_PROXIES 2240 /* 2241 * Maximum proxies in account. 2242 */ 2243 PyModule_AddIntConstant( 2244 m, "PJSUA_ACC_MAX_PROXIES ", PJSUA_ACC_MAX_PROXIES 2245 ); 2246 #endif 2247 } -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
r815 r824 286 286 static void log_writer(int level, const char *buffer, int len) 287 287 { 288 /* Write to stdout, file, and application callback. */ 289 290 if (level <= (int)pjsua_var.log_cfg.console_level) 291 pj_log_write(level, buffer, len); 288 /* Write to file, stdout or application callback. */ 292 289 293 290 if (pjsua_var.log_file) { … … 296 293 } 297 294 298 if (pjsua_var.log_cfg.cb) 299 (*pjsua_var.log_cfg.cb)(level, buffer, len); 295 if (level <= (int)pjsua_var.log_cfg.console_level) { 296 if (pjsua_var.log_cfg.cb) 297 (*pjsua_var.log_cfg.cb)(level, buffer, len); 298 else 299 pj_log_write(level, buffer, len); 300 } 300 301 } 301 302
Note: See TracChangeset
for help on using the changeset viewer.