📄 py_pjsua.c
字号:
/* $Id: py_pjsua.c 972 2007-02-18 23:49:14Z bennylp $ */
/*
* Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <Python.h>
#include "structmember.h"
#include <pjsua-lib/pjsua.h>
#define THIS_FILE "main.c"
#define POOL_SIZE 4000
#define SND_DEV_NUM 64
#define SND_NAME_LEN 64
/* LIB BASE */
static PyObject* obj_log_cb;
static long thread_id;
#define ENTER_PYTHON() PyGILState_STATE state = PyGILState_Ensure()
#define LEAVE_PYTHON() PyGILState_Release(state)
/*
* cb_log_cb
* declares method for reconfiguring logging process for callback struct
*/
static void cb_log_cb(int level, const char *data, pj_size_t len)
{
/* Ignore if this callback is called from alien thread context,
* or otherwise it will crash Python.
*/
if (pj_thread_local_get(thread_id) == 0)
return;
if (PyCallable_Check(obj_log_cb))
{
ENTER_PYTHON();
PyObject_CallFunctionObjArgs(
obj_log_cb, Py_BuildValue("i",level),
PyString_FromString(data), Py_BuildValue("i",len), NULL
);
LEAVE_PYTHON();
}
}
/*
* pjsip_event_Object
* C/python typewrapper for event struct
*/
typedef struct
{
PyObject_HEAD
/* Type-specific fields go here. */
pjsip_event * event;
} pjsip_event_Object;
/*
* pjsip_event_Type
* event struct signatures
*/
static PyTypeObject pjsip_event_Type =
{
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"py_pjsua.PJSIP_Event", /*tp_name*/
sizeof(pjsip_event_Object), /*tp_basicsize*/
0, /*tp_itemsize*/
0, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"pjsip_event objects", /*tp_doc */
};
/*
* pjsip_rx_data_Object
* C/python typewrapper for RX data struct
*/
typedef struct
{
PyObject_HEAD
/* Type-specific fields go here. */
pjsip_rx_data * rdata;
} pjsip_rx_data_Object;
/*
* pjsip_rx_data_Type
*/
static PyTypeObject pjsip_rx_data_Type =
{
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"py_pjsua.PJSIP_RX_Data", /*tp_name*/
sizeof(pjsip_rx_data_Object), /*tp_basicsize*/
0, /*tp_itemsize*/
0, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
"pjsip_rx_data objects", /*tp_doc*/
};
/*
* callback_Object
* C/python typewrapper for callback struct
*/
typedef struct
{
PyObject_HEAD
/* Type-specific fields go here. */
PyObject * on_call_state;
PyObject * on_incoming_call;
PyObject * on_call_media_state;
PyObject * on_call_transfer_request;
PyObject * on_call_transfer_status;
PyObject * on_call_replace_request;
PyObject * on_call_replaced;
PyObject * on_reg_state;
PyObject * on_buddy_state;
PyObject * on_pager;
PyObject * on_pager_status;
PyObject * on_typing;
} callback_Object;
/*
* The global callback object.
*/
static callback_Object * g_obj_callback;
/*
* cb_on_call_state
* declares method on_call_state for callback struct
*/
static void cb_on_call_state(pjsua_call_id call_id, pjsip_event *e)
{
if (PyCallable_Check(g_obj_callback->on_call_state))
{
pjsip_event_Object * obj;
ENTER_PYTHON();
obj = (pjsip_event_Object *)PyType_GenericNew(&pjsip_event_Type,
NULL, NULL);
obj->event = e;
PyObject_CallFunctionObjArgs(
g_obj_callback->on_call_state,Py_BuildValue("i",call_id),obj,NULL
);
LEAVE_PYTHON();
}
}
/*
* cb_on_incoming_call
* declares method on_incoming_call for callback struct
*/
static void cb_on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
pjsip_rx_data *rdata)
{
if (PyCallable_Check(g_obj_callback->on_incoming_call))
{
pjsip_rx_data_Object * obj;
ENTER_PYTHON();
obj = (pjsip_rx_data_Object *)PyType_GenericNew(&pjsip_rx_data_Type,
NULL, NULL);
obj->rdata = rdata;
PyObject_CallFunctionObjArgs(
g_obj_callback->on_incoming_call,
Py_BuildValue("i",acc_id),
Py_BuildValue("i",call_id),
obj,
NULL
);
LEAVE_PYTHON();
}
}
/*
* cb_on_call_media_state
* declares method on_call_media_state for callback struct
*/
static void cb_on_call_media_state(pjsua_call_id call_id)
{
if (PyCallable_Check(g_obj_callback->on_call_media_state))
{
ENTER_PYTHON();
PyObject_CallFunction(g_obj_callback->on_call_media_state,"i",call_id);
LEAVE_PYTHON();
}
}
/*
* Notify application on call being transfered.
* !modified @061206
*/
static void cb_on_call_transfer_request(pjsua_call_id call_id,
const pj_str_t *dst,
pjsip_status_code *code)
{
if (PyCallable_Check(g_obj_callback->on_call_transfer_request))
{
PyObject * ret;
int cd;
ENTER_PYTHON();
ret = PyObject_CallFunctionObjArgs(
g_obj_callback->on_call_transfer_request,
Py_BuildValue("i",call_id),
PyString_FromStringAndSize(dst->ptr, dst->slen),
Py_BuildValue("i",*code),
NULL
);
if (ret != NULL) {
if (ret != Py_None) {
if (PyArg_Parse(ret,"i",&cd)) {
*code = cd;
}
}
}
LEAVE_PYTHON();
}
}
/*
* Notify application of the status of previously sent call
* transfer request. Application can monitor the status of the
* call transfer request, for example to decide whether to
* terminate existing call.
* !modified @061206
*/
static void cb_on_call_transfer_status( pjsua_call_id call_id,
int status_code,
const pj_str_t *status_text,
pj_bool_t final,
pj_bool_t *p_cont)
{
if (PyCallable_Check(g_obj_callback->on_call_transfer_status))
{
PyObject * ret;
int cnt;
ENTER_PYTHON();
ret = PyObject_CallFunctionObjArgs(
g_obj_callback->on_call_transfer_status,
Py_BuildValue("i",call_id),
Py_BuildValue("i",status_code),
PyString_FromStringAndSize(status_text->ptr, status_text->slen),
Py_BuildValue("i",final),
Py_BuildValue("i",*p_cont),
NULL
);
if (ret != NULL) {
if (ret != Py_None) {
if (PyArg_Parse(ret,"i",&cnt)) {
*p_cont = cnt;
}
}
}
LEAVE_PYTHON();
}
}
/*
* Notify application about incoming INVITE with Replaces header.
* Application may reject the request by setting non-2xx code.
* !modified @061206
*/
static void cb_on_call_replace_request( pjsua_call_id call_id,
pjsip_rx_data *rdata,
int *st_code,
pj_str_t *st_text)
{
if (PyCallable_Check(g_obj_callback->on_call_replace_request))
{
PyObject * ret;
PyObject * txt;
int cd;
pjsip_rx_data_Object * obj;
ENTER_PYTHON();
obj = (pjsip_rx_data_Object *)PyType_GenericNew(&pjsip_rx_data_Type,
NULL, NULL);
obj->rdata = rdata;
ret = PyObject_CallFunctionObjArgs(
g_obj_callback->on_call_replace_request,
Py_BuildValue("i",call_id),
obj,
Py_BuildValue("i",*st_code),
PyString_FromStringAndSize(st_text->ptr, st_text->slen),
NULL
);
if (ret != NULL) {
if (ret != Py_None) {
if (PyArg_ParseTuple(ret,"iO",&cd, &txt)) {
*st_code = cd;
st_text->ptr = PyString_AsString(txt);
st_text->slen = strlen(PyString_AsString(txt));
}
}
}
LEAVE_PYTHON();
}
}
/*
* Notify application that an existing call has been replaced with
* a new call. This happens when PJSUA-API receives incoming INVITE
* request with Replaces header.
*/
static void cb_on_call_replaced(pjsua_call_id old_call_id,
pjsua_call_id new_call_id)
{
if (PyCallable_Check(g_obj_callback->on_call_replaced))
{
ENTER_PYTHON();
PyObject_CallFunctionObjArgs(
g_obj_callback->on_call_replaced,
Py_BuildValue("i",old_call_id),
Py_BuildValue("i",old_call_id),
NULL
);
LEAVE_PYTHON();
}
}
/*
* cb_on_reg_state
* declares method on_reg_state for callback struct
*/
static void cb_on_reg_state(pjsua_acc_id acc_id)
{
if (PyCallable_Check(g_obj_callback->on_reg_state))
{
ENTER_PYTHON();
PyObject_CallFunction(g_obj_callback->on_reg_state,"i",acc_id);
LEAVE_PYTHON();
}
}
/*
* cb_on_buddy_state
* declares method on_buddy state for callback struct
*/
static void cb_on_buddy_state(pjsua_buddy_id buddy_id)
{
if (PyCallable_Check(g_obj_callback->on_buddy_state))
{
ENTER_PYTHON();
PyObject_CallFunction(g_obj_callback->on_buddy_state,"i",buddy_id);
LEAVE_PYTHON();
}
}
/*
* cb_on_pager
* declares method on_pager for callback struct
*/
static void cb_on_pager(pjsua_call_id call_id, const pj_str_t *from,
const pj_str_t *to, const pj_str_t *contact,
const pj_str_t *mime_type, const pj_str_t *body)
{
if (PyCallable_Check(g_obj_callback->on_pager))
{
ENTER_PYTHON();
PyObject_CallFunctionObjArgs(
g_obj_callback->on_pager,Py_BuildValue("i",call_id),
PyString_FromStringAndSize(from->ptr, from->slen),
PyString_FromStringAndSize(to->ptr, to->slen),
PyString_FromStringAndSize(contact->ptr, contact->slen),
PyString_FromStringAndSize(mime_type->ptr, mime_type->slen),
PyString_FromStringAndSize(body->ptr, body->slen), NULL
);
LEAVE_PYTHON();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -