Author: anthm Date: Sat Oct 21 00:58:15 2006 New Revision: 3134 Modified: freeswitch/trunk/src/include/switch_channel.h freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c freeswitch/trunk/src/switch_channel.c freeswitch/trunk/src/switch_core.c Log: add some more nifty stuff and fix a bug or 2 Modified: freeswitch/trunk/src/include/switch_channel.h ============================================================================== --- freeswitch/trunk/src/include/switch_channel.h (original) +++ freeswitch/trunk/src/include/switch_channel.h Sat Oct 21 00:58:15 2006 @@ -137,6 +137,14 @@ uint32_t flags); /*! + \brief Fire A presence event for the channel + \param channel the channel to initilize + \param rpid the rpid if for the icon to use + \param status the status message +*/ +SWITCH_DECLARE(void) switch_channel_presence(switch_channel_t *channel, char *rpid, char *status); + +/*! \brief Uninitalize a channel \param channel the channel to uninit */ Modified: freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c ============================================================================== --- freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c (original) +++ freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c Sat Oct 21 00:58:15 2006 @@ -60,6 +60,11 @@ } } +static void eval_function(switch_core_session_t *session, char *data) +{ + return; +} + static void answer_function(switch_core_session_t *session, char *data) { switch_channel_t *channel; @@ -165,14 +170,89 @@ return SWITCH_STATUS_SUCCESS; } +static switch_status_t presence_api_function(char *fmt, switch_core_session_t *session, switch_stream_handle_t *stream) +{ + switch_event_t *event; + char *lbuf, *argv[4]; + int argc = 0; + switch_event_types_t type = SWITCH_EVENT_PRESENCE_IN; + + if ((lbuf = strdup(fmt)) && (argc = switch_separate_string(lbuf, '|', argv, (sizeof(argv) / sizeof(argv[0])))) > 0) { + if (!strcasecmp(argv[0], "out")) { + type = SWITCH_EVENT_PRESENCE_OUT; + } else if (argc != 4) { + stream->write_function(stream, "Invalid"); + return SWITCH_STATUS_SUCCESS; + } + + if (switch_event_create(&event, type) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "dp"); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", __FILE__); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", argv[1]); + if (type == SWITCH_EVENT_PRESENCE_IN) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "%s", argv[2]); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", argv[3]); + } + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence"); + switch_event_fire(&event); + } + stream->write_function(stream, "Event Sent"); + switch_safe_free(lbuf); + } else { + stream->write_function(stream, "Invalid"); + } + + return SWITCH_STATUS_SUCCESS; +} + + +static switch_status_t chat_api_function(char *fmt, switch_core_session_t *session, switch_stream_handle_t *stream) +{ + char *lbuf, *argv[4]; + int argc = 0; + + if ((lbuf = strdup(fmt)) && (argc = switch_separate_string(lbuf, '|', argv, (sizeof(argv) / sizeof(argv[0])))) == 4) { + switch_chat_interface_t *ci; + + if ((ci = switch_loadable_module_get_chat_interface(argv[0]))) { + ci->chat_send("dp", argv[1], argv[2], "", argv[3], ""); + stream->write_function(stream, "Sent"); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invaid Chat Interface [%s]!\n", argv[0]); + } + } else { + stream->write_function(stream, "Invalid"); + } + + return SWITCH_STATUS_SUCCESS; +} + + +static switch_api_interface_t chat_api_interface = { + /*.interface_name */ "chat", + /*.desc */ "chat", + /*.function */ chat_api_function, + /*.syntax */ "<proto>|<from>|<to>|<message>", + /*.next */ NULL +}; + static switch_api_interface_t dptools_api_interface = { /*.interface_name */ "strftime", /*.desc */ "strftime", /*.function */ strftime_api_function, /*.syntax */ "<format_string>", - /*.next */ NULL + /*.next */ &chat_api_interface }; + +static switch_api_interface_t presence_api_interface = { + /*.interface_name */ "presence", + /*.desc */ "presence", + /*.function */ presence_api_function, + /*.syntax */ "<user> <rpid> <message>", + /*.next */ &dptools_api_interface +}; + static const switch_application_interface_t set_application_interface = { /*.interface_name */ "set", /*.application_function */ set_function, @@ -192,13 +272,23 @@ }; +static const switch_application_interface_t eval_application_interface = { + /*.interface_name */ "eval", + /*.application_function */ eval_function, + /* long_desc */ "Do Nothing", + /* short_desc */ "Do Nothing", + /* syntax */ "", + /*.next */ &answer_application_interface + +}; + static const switch_application_interface_t strftime_application_interface = { /*.interface_name */ "strftime", /*.application_function */ strftime_function, /* long_desc */ NULL, /* short_desc */ NULL, /* syntax */ NULL, - /*.next */ &answer_application_interface + /*.next */ &eval_application_interface }; @@ -236,7 +326,7 @@ /*.dialplan_interface = */ NULL, /*.codec_interface = */ NULL, /*.application_interface */ &privacy_application_interface, - /*.api_interface */ &dptools_api_interface + /*.api_interface */ &presence_api_interface }; SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename) Modified: freeswitch/trunk/src/switch_channel.c ============================================================================== --- freeswitch/trunk/src/switch_channel.c (original) +++ freeswitch/trunk/src/switch_channel.c Sat Oct 21 00:58:15 2006 @@ -305,6 +305,38 @@ return SWITCH_STATUS_SUCCESS; } +SWITCH_DECLARE(void) switch_channel_presence(switch_channel_t *channel, char *rpid, char *status) +{ + char *id = switch_channel_get_variable(channel, "presence_id"); + switch_event_t *event; + switch_event_types_t type = SWITCH_EVENT_PRESENCE_IN; + + if (!status) { + type = SWITCH_EVENT_PRESENCE_OUT; + } + + if (!id) { + return; + } + + if (switch_event_create(&event, type) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", __FILE__); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", __FILE__); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", id); + if (type == SWITCH_EVENT_PRESENCE_IN) { + if (!rpid) { + rpid = "unknown"; + } + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "%s", rpid); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", status); + } + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence"); + switch_event_fire(&event); + } + +} + + SWITCH_DECLARE(char *) switch_channel_get_variable(switch_channel_t *channel, char *varname) { char *v; @@ -589,7 +621,9 @@ if (ok) { - + if (state > CS_RING) { + switch_channel_presence(channel, "unknown", (char*)state_names[state]); + } switch_log_printf(SWITCH_CHANNEL_ID_LOG, (char *) file, func, line, SWITCH_LOG_DEBUG, "%s State Change %s -> %s\n", channel->name, state_names[last_state], @@ -928,6 +962,8 @@ switch_channel_event_set_data(channel, event); switch_event_fire(&event); } + + switch_channel_presence(channel, "unavailable", switch_channel_cause2str(channel->hangup_cause)); switch_core_session_kill_channel(channel->session, SWITCH_SIG_KILL); switch_core_session_signal_state_change(channel->session); Modified: freeswitch/trunk/src/switch_core.c ============================================================================== --- freeswitch/trunk/src/switch_core.c (original) +++ freeswitch/trunk/src/switch_core.c Sat Oct 21 00:58:15 2006 @@ -2536,6 +2536,16 @@ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Application-Data", "%s", expanded); switch_event_fire(&event); } + + + if (switch_channel_get_variable(session->channel, "presence_id")) { + char *arg = switch_mprintf("%s(%s)", extension->current_application->application_name, expanded); + if (arg) { + switch_channel_presence(session->channel, "unknown", arg); + switch_safe_free(arg); + } + } + application_interface->application_function(session, expanded); if (expanded != extension->current_application->application_data) {