[asterisk-commits] mmichelson: branch mmichelson/pool_shark r380288 - /team/mmichelson/pool_shar...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Jan 28 15:40:22 CST 2013
Author: mmichelson
Date: Mon Jan 28 15:40:18 2013
New Revision: 380288
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=380288
Log:
Progress towards having chan_gulp use the threadpool.
This takes careful consideration. The channel-related stuff needs
to occur in the PBX thread and the PJSIP stuff needs to happen in
the threadpool. This commit takes care of gulp_answer, gulp_indicate,
and gulp_call.
Next will be gulp_hangup and gulp_request.
Modified:
team/mmichelson/pool_shark/channels/chan_gulp.c
Modified: team/mmichelson/pool_shark/channels/chan_gulp.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark/channels/chan_gulp.c?view=diff&rev=380288&r1=380287&r2=380288
==============================================================================
--- team/mmichelson/pool_shark/channels/chan_gulp.c (original)
+++ team/mmichelson/pool_shark/channels/chan_gulp.c Mon Jan 28 15:40:18 2013
@@ -186,12 +186,24 @@
return chan;
}
+static int answer(void *data)
+{
+ pj_status_t status;
+ pjsip_tx_data *packet;
+ struct ast_sip_session *session = data;
+
+ if ((status = pjsip_inv_answer(session->inv_session, 200, NULL, NULL, &packet)) == PJ_SUCCESS) {
+ ast_sip_session_send_response(session, packet);
+ }
+
+ ao2_ref(session, -1);
+ return (status == PJ_SUCCESS) ? 0 : -1;
+}
+
/*! \brief Function called by core when we should answer a Gulp session */
static int gulp_answer(struct ast_channel *ast)
{
struct ast_sip_session *session = ast_channel_tech_pvt(ast);
- pj_status_t status;
- pjsip_tx_data *packet;
if (ast_channel_state(ast) == AST_STATE_UP) {
return 0;
@@ -199,13 +211,8 @@
ast_setstate(ast, AST_STATE_UP);
- pj_thread_register_check();
-
- if ((status = pjsip_inv_answer(session->inv_session, 200, NULL, NULL, &packet)) == PJ_SUCCESS) {
- ast_sip_session_send_response(session, packet);
- }
-
- return (status == PJ_SUCCESS) ? 0 : -1;
+ ao2_ref(session, +1);
+ return ast_sip_push_task(session->work, answer, session);
}
/*! \brief Function called by core to read any waiting frames */
@@ -282,55 +289,100 @@
return 0;
}
+struct indicate_data {
+ struct ast_sip_session *session;
+ int condition;
+ int response_code;
+ void *frame_data;
+ size_t datalen;
+};
+
+static void indicate_data_destroy(void *obj)
+{
+ struct indicate_data *ind_data = obj;
+ ast_free(ind_data->frame_data);
+}
+
+static struct indicate_data *indicate_data_alloc(struct ast_sip_session *session,
+ int condition, int response_code, const void *frame_data, size_t datalen)
+{
+ struct indicate_data *ind_data = ao2_alloc(sizeof(*ind_data), indicate_data_destroy);
+ if (!ind_data) {
+ return NULL;
+ }
+ ind_data->frame_data = ast_malloc(datalen);
+ if (!ind_data->frame_data) {
+ ao2_ref(ind_data, -1);
+ return NULL;
+ }
+ memcpy(ind_data->frame_data, frame_data, datalen);
+ ind_data->datalen = datalen;
+ ind_data->condition = condition;
+ ind_data->response_code = response_code;
+ return ind_data;
+}
+
+static int indicate(void *data)
+{
+ struct indicate_data *ind_data = data;
+ struct ast_sip_session *session = ind_data->session;
+ int response_code = ind_data->response_code;
+ pjsip_tx_data *packet = NULL;
+
+ if (pjsip_inv_answer(session->inv_session, response_code, NULL, NULL, &packet) == PJ_SUCCESS) {
+ ast_sip_session_send_response(session, packet);
+ }
+
+ ao2_ref(ind_data, -1);
+ return 0;
+}
+
/*! \brief Function called by core to ask the channel to indicate some sort of condition */
static int gulp_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
{
int res = 0;
struct ast_sip_session *session = ast_channel_tech_pvt(ast);
- pj_status_t status = -1;
- pjsip_tx_data *packet = NULL;
-
- pj_thread_register_check();
+ int response_code = 0;
switch (condition) {
case AST_CONTROL_RINGING:
if (ast_channel_state(ast) == AST_STATE_RING) {
- status = pjsip_inv_answer(session->inv_session, 180, NULL, NULL, &packet);
+ response_code = 180;
} else {
res = -1;
}
break;
case AST_CONTROL_BUSY:
if (ast_channel_state(ast) != AST_STATE_UP) {
- status = pjsip_inv_answer(session->inv_session, 486, NULL, NULL, &packet);
+ response_code = 486;
} else {
res = -1;
}
break;
case AST_CONTROL_CONGESTION:
if (ast_channel_state(ast) != AST_STATE_UP) {
- status = pjsip_inv_answer(session->inv_session, 503, NULL, NULL, &packet);
+ response_code = 503;
} else {
res = -1;
}
break;
case AST_CONTROL_INCOMPLETE:
if (ast_channel_state(ast) != AST_STATE_UP) {
- status = pjsip_inv_answer(session->inv_session, 484, NULL, NULL, &packet);
+ response_code = 484;
} else {
res = -1;
}
break;
case AST_CONTROL_PROCEEDING:
if (ast_channel_state(ast) != AST_STATE_UP) {
- status = pjsip_inv_answer(session->inv_session, 100, NULL, NULL, &packet);
+ response_code = 100;
} else {
res = -1;
}
break;
case AST_CONTROL_PROGRESS:
if (ast_channel_state(ast) != AST_STATE_UP) {
- status = pjsip_inv_answer(session->inv_session, 183, NULL, NULL, &packet);
+ response_code = 183;
} else {
res = -1;
}
@@ -358,8 +410,13 @@
break;
}
- if (packet && (status == PJ_SUCCESS)) {
- ast_sip_session_send_response(session, packet);
+ if (!res) {
+ struct indicate_data *ind_data = indicate_data_alloc(session, condition, response_code, data, datalen);
+ if (!ind_data) {
+ res = -1;
+ } else {
+ ast_sip_push_task(session->work, indicate, ind_data);
+ }
}
return res;
@@ -408,21 +465,28 @@
return res;
}
+static int call(void *data)
+{
+ struct ast_sip_session *session = data;
+ pjsip_tx_data *packet;
+
+ if (pjsip_inv_invite(session->inv_session, &packet) != PJ_SUCCESS) {
+ return -1;
+ }
+
+ ast_sip_session_send_request(session, packet);
+
+ ao2_ref(session, -1);
+ return 0;
+}
+
/*! \brief Function called by core to actually start calling a remote party */
static int gulp_call(struct ast_channel *ast, const char *dest, int timeout)
{
struct ast_sip_session *session = ast_channel_tech_pvt(ast);
- pjsip_tx_data *packet;
-
- pj_thread_register_check();
-
- if (pjsip_inv_invite(session->inv_session, &packet) != PJ_SUCCESS) {
- return -1;
- }
-
- ast_sip_session_send_request(session, packet);
-
- return 0;
+
+ ao2_ref(session, +1);
+ return ast_sip_push_task(session->work, call, session);
}
/*! \brief Internal function which translates from Asterisk cause codes to SIP response codes */
More information about the asterisk-commits
mailing list