⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 py_pjsua.c

📁 一个开源SIP协议栈
💻 C
📖 第 1 页 / 共 5 页
字号:
/* $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 + -