📄 py_pjsua.c
字号:
}
}
/*
* cb_on_pager_status
* declares method on_pager_status for callback struct
*/
static void cb_on_pager_status(pjsua_call_id call_id, const pj_str_t *to,
const pj_str_t *body, void *user_data,
pjsip_status_code status,
const pj_str_t *reason)
{
if (PyCallable_Check(g_obj_callback->on_pager))
{
PyObject * obj_user_data;
ENTER_PYTHON();
obj_user_data = Py_BuildValue("i", user_data);
PyObject_CallFunctionObjArgs(
g_obj_callback->on_pager_status,
Py_BuildValue("i",call_id),
PyString_FromStringAndSize(to->ptr, to->slen),
PyString_FromStringAndSize(body->ptr, body->slen),
obj_user_data,
Py_BuildValue("i",status),
PyString_FromStringAndSize(reason->ptr,reason->slen),
NULL
);
LEAVE_PYTHON();
}
}
/*
* cb_on_typing
* declares method on_typing for callback struct
*/
static void cb_on_typing(pjsua_call_id call_id, const pj_str_t *from,
const pj_str_t *to, const pj_str_t *contact,
pj_bool_t is_typing)
{
if (PyCallable_Check(g_obj_callback->on_typing))
{
ENTER_PYTHON();
PyObject_CallFunctionObjArgs(
g_obj_callback->on_typing,Py_BuildValue("i",call_id),
PyString_FromStringAndSize(from->ptr, from->slen),
PyString_FromStringAndSize(to->ptr, to->slen),
PyString_FromStringAndSize(contact->ptr, contact->slen),
Py_BuildValue("i",is_typing),NULL
);
LEAVE_PYTHON();
}
}
/*
* callback_dealloc
* destructor function for callback struct
*/
static void callback_dealloc(callback_Object* self)
{
Py_XDECREF(self->on_call_state);
Py_XDECREF(self->on_incoming_call);
Py_XDECREF(self->on_call_media_state);
Py_XDECREF(self->on_call_transfer_request);
Py_XDECREF(self->on_call_transfer_status);
Py_XDECREF(self->on_call_replace_request);
Py_XDECREF(self->on_call_replaced);
Py_XDECREF(self->on_reg_state);
Py_XDECREF(self->on_buddy_state);
Py_XDECREF(self->on_pager);
Py_XDECREF(self->on_pager_status);
Py_XDECREF(self->on_typing);
self->ob_type->tp_free((PyObject*)self);
}
/*
* callback_new
* * declares constructor for callback struct
*/
static PyObject * callback_new(PyTypeObject *type, PyObject *args,
PyObject *kwds)
{
callback_Object *self;
self = (callback_Object *)type->tp_alloc(type, 0);
if (self != NULL)
{
Py_INCREF(Py_None);
self->on_call_state = Py_None;
if (self->on_call_state == NULL)
{
Py_DECREF(Py_None);
return NULL;
}
Py_INCREF(Py_None);
self->on_incoming_call = Py_None;
if (self->on_incoming_call == NULL)
{
Py_DECREF(Py_None);
return NULL;
}
Py_INCREF(Py_None);
self->on_call_media_state = Py_None;
if (self->on_call_media_state == NULL)
{
Py_DECREF(Py_None);
return NULL;
}
Py_INCREF(Py_None);
self->on_call_transfer_request = Py_None;
if (self->on_call_transfer_request == NULL)
{
Py_DECREF(Py_None);
return NULL;
}
Py_INCREF(Py_None);
self->on_call_transfer_status = Py_None;
if (self->on_call_transfer_status == NULL)
{
Py_DECREF(Py_None);
return NULL;
}
Py_INCREF(Py_None);
self->on_call_replace_request = Py_None;
if (self->on_call_replace_request == NULL)
{
Py_DECREF(Py_None);
return NULL;
}
Py_INCREF(Py_None);
self->on_call_replaced = Py_None;
if (self->on_call_replaced == NULL)
{
Py_DECREF(Py_None);
return NULL;
}
Py_INCREF(Py_None);
self->on_reg_state = Py_None;
if (self->on_reg_state == NULL)
{
Py_DECREF(Py_None);
return NULL;
}
Py_INCREF(Py_None);
self->on_buddy_state = Py_None;
if (self->on_buddy_state == NULL)
{
Py_DECREF(Py_None);
return NULL;
}
Py_INCREF(Py_None);
self->on_pager = Py_None;
if (self->on_pager == NULL)
{
Py_DECREF(Py_None);
return NULL;
}
Py_INCREF(Py_None);
self->on_pager_status = Py_None;
if (self->on_pager_status == NULL)
{
Py_DECREF(Py_None);
return NULL;
}
Py_INCREF(Py_None);
self->on_typing = Py_None;
if (self->on_typing == NULL)
{
Py_DECREF(Py_None);
return NULL;
}
}
return (PyObject *)self;
}
/*
* callback_members
* declares available functions for callback object
*/
static PyMemberDef callback_members[] =
{
{
"on_call_state", T_OBJECT_EX, offsetof(callback_Object, on_call_state),
0, "Notify application when invite state has changed. Application may "
"then query the call info to get the detail call states."
},
{
"on_incoming_call", T_OBJECT_EX,
offsetof(callback_Object, on_incoming_call), 0,
"Notify application on incoming call."
},
{
"on_call_media_state", T_OBJECT_EX,
offsetof(callback_Object, on_call_media_state), 0,
"Notify application when media state in the call has changed. Normal "
"application would need to implement this callback, e.g. to connect "
"the call's media to sound device."
},
{
"on_call_transfer_request", T_OBJECT_EX,
offsetof(callback_Object, on_call_transfer_request), 0,
"Notify application on call being transfered. "
"Application can decide to accept/reject transfer request "
"by setting the code (default is 200). When this callback "
"is not defined, the default behavior is to accept the "
"transfer."
},
{
"on_call_transfer_status", T_OBJECT_EX,
offsetof(callback_Object, on_call_transfer_status), 0,
"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."
},
{
"on_call_replace_request", T_OBJECT_EX,
offsetof(callback_Object, on_call_replace_request), 0,
"Notify application about incoming INVITE with Replaces header. "
"Application may reject the request by setting non-2xx code."
},
{
"on_call_replaced", T_OBJECT_EX,
offsetof(callback_Object, on_call_replaced), 0,
"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."
" "
"After this callback is called, normally PJSUA-API will disconnect "
"old_call_id and establish new_call_id."
},
{
"on_reg_state", T_OBJECT_EX,
offsetof(callback_Object, on_reg_state), 0,
"Notify application when registration status has changed. Application "
"may then query the account info to get the registration details."
},
{
"on_buddy_state", T_OBJECT_EX,
offsetof(callback_Object, on_buddy_state), 0,
"Notify application when the buddy state has changed. Application may "
"then query the buddy into to get the details."
},
{
"on_pager", T_OBJECT_EX, offsetof(callback_Object, on_pager), 0,
"Notify application on incoming pager (i.e. MESSAGE request). "
"Argument call_id will be -1 if MESSAGE request is not related to an "
"existing call."
},
{
"on_pager_status", T_OBJECT_EX,
offsetof(callback_Object, on_pager_status), 0,
"Notify application about the delivery status of outgoing pager "
"request."
},
{
"on_typing", T_OBJECT_EX, offsetof(callback_Object, on_typing), 0,
"Notify application about typing indication."
},
{NULL} /* Sentinel */
};
/*
* callback_Type
* callback class definition
*/
static PyTypeObject callback_Type =
{
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"py_pjsua.Callback", /*tp_name*/
sizeof(callback_Object), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)callback_dealloc, /*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*/
"Callback objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
callback_members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
callback_new, /* tp_new */
};
/*
* media_config_Object
* C/Python wrapper for media_config object
*/
typedef struct
{
PyObject_HEAD
/* Type-specific fields go here. */
unsigned clock_rate;
unsigned max_media_ports;
int has_ioqueue;
unsigned thread_cnt;
unsigned quality;
unsigned ptime;
int no_vad;
unsigned ilbc_mode;
unsigned tx_drop_pct;
unsigned rx_drop_pct;
unsigned ec_options;
unsigned ec_tail_len;
} media_config_Object;
/*
* media_config_members
* declares attributes accessible from both C and Python for media_config file
*/
static PyMemberDef media_config_members[] =
{
{
"clock_rate", T_INT, offsetof(media_config_Object, clock_rate), 0,
"Clock rate to be applied to the conference bridge. If value is zero, "
"default clock rate will be used (16KHz)."
},
{
"max_media_ports", T_INT,
offsetof(media_config_Object, max_media_ports), 0,
"Specify maximum number of media ports to be created in the "
"conference bridge. Since all media terminate in the bridge (calls, "
"file player, file recorder, etc), the value must be large enough to "
"support all of them. However, the larger the value, the more "
"computations are performed."
},
{
"has_ioqueue", T_INT, offsetof(media_config_Object, has_ioqueue), 0,
"Specify whether the media manager should manage its own ioqueue for "
"the RTP/RTCP sockets. If yes, ioqueue will be created and at least "
"one worker thread will be created too. If no, the RTP/RTCP sockets "
"will share the same ioqueue as SIP sockets, and no worker thread is "
"needed."
},
{
"thread_cnt", T_INT, offsetof(media_config_Object, thread_cnt), 0,
"Specify the number of worker threads to handle incoming RTP packets. "
"A value of one is recommended for most applications."
},
{
"quality", T_INT, offsetof(media_config_Object, quality), 0,
"The media quality also sets speex codec quality/complexity to the "
"number."
},
{
"ptime", T_INT, offsetof(media_config_Object, ptime), 0,
"Specify default ptime."
},
{
"no_vad", T_INT, offsetof(media_config_Object, no_vad), 0,
"Disable VAD?"
},
{
"ilbc_mode", T_INT, offsetof(media_config_Object, ilbc_mode), 0,
"iLBC mode (20 or 30)."
},
{
"tx_drop_pct", T_INT, offsetof(media_config_Object, tx_drop_pct), 0,
"Percentage of RTP packet to drop in TX direction (to simulate packet "
"lost)."
},
{
"rx_drop_pct", T_INT, offsetof(media_config_Object, rx_drop_pct), 0,
"Percentage of RTP packet to drop in RX direction (to simulate packet "
"lost)."},
{
"ec_options", T_INT, offsetof(media_config_Object, ec_options), 0,
"Echo canceller options (see #pjmedia_echo_create())"
},
{
"ec_tail_len", T_INT, offsetof(media_config_Object, ec_tail_len), 0,
"Echo canceller tail length, in miliseconds."
},
{NULL} /* Sentinel */
};
/*
* media_config_Type
*/
static PyTypeObject media_config_Type =
{
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"py_pjsua.Media_Config", /*tp_name*/
sizeof(media_config_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*/
"Media Config objects", /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
0, /*tp_richcompare*/
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
media_config_members, /* tp_members */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -