diff --git a/libs/libdingaling/src/libdingaling.c b/libs/libdingaling/src/libdingaling.c index 2ec6b5ad4c..ed83486cca 100644 --- a/libs/libdingaling/src/libdingaling.c +++ b/libs/libdingaling/src/libdingaling.c @@ -386,7 +386,7 @@ static ldl_status parse_session_code(ldl_handle_t *handle, char *id, char *from, } if (handle->session_callback && signal) { - handle->session_callback(handle, session, signal, msg); + handle->session_callback(handle, session, signal, from, id, msg); } return LDL_STATUS_SUCCESS; @@ -549,8 +549,14 @@ static int on_stream(ldl_handle_t *handle, int type, iks * node) } } else if (strcmp("failure", iks_name(node)) == 0) { globals.logger(DL_LOG_DEBUG, "sasl authentication failed\n"); + if (handle->session_callback) { + handle->session_callback(handle, NULL, LDL_SIGNAL_LOGIN_FAILURE, "core", "Login Failure", handle->login); + } } else if (strcmp("success", iks_name(node)) == 0) { globals.logger(DL_LOG_DEBUG, "XMPP server connected\n"); + if (handle->session_callback) { + handle->session_callback(handle, NULL, LDL_SIGNAL_LOGIN_SUCCESS, "core", "Login Success", handle->login); + } iks_send_header(handle->parser, handle->acc->server); ldl_set_flag(handle, LDL_FLAG_AUTHORIZED); } else { @@ -583,19 +589,18 @@ static int on_msg(void *user_data, ikspak *pak) { char *cmd = iks_find_cdata(pak->x, "body"); char *from = iks_find_attrib(pak->x, "from"); + char *subject = iks_find_attrib(pak->x, "subject"); ldl_handle_t *handle = user_data; ldl_session_t *session = NULL; - if (from && (session = apr_hash_get(handle->sessions, from, APR_HASH_KEY_STRING))) { - if (handle->session_callback) { - handle->session_callback(handle, session, LDL_SIGNAL_MSG, cmd); - } + if (from) { + session = apr_hash_get(handle->sessions, from, APR_HASH_KEY_STRING); + } + + if (handle->session_callback) { + handle->session_callback(handle, session, LDL_SIGNAL_MSG, from, subject ? subject : "N/A", cmd); } - - //printf("%s %s\n", handle->login, cmd); - - return 0; } @@ -870,12 +875,28 @@ void *ldl_session_get_private(ldl_session_t *session) return session->private_data; } - void *ldl_handle_get_private(ldl_handle_t *handle) { return handle->private_info; } +void ldl_handle_send_msg(ldl_handle_t *handle, char *to, char *subject, char *body) +{ + iks *msg; + + assert(handle != NULL); + assert(body != NULL); + + msg = iks_make_msg(IKS_TYPE_NONE, to, body); + + if (subject) { + iks_insert_attrib(msg, "subject", subject); + } + + apr_queue_push(handle->queue, msg); + +} + void ldl_global_set_logger(ldl_logger_t logger) { globals.logger = logger; diff --git a/libs/libdingaling/src/libdingaling.h b/libs/libdingaling/src/libdingaling.h index 7503d7c864..687e1841cc 100644 --- a/libs/libdingaling/src/libdingaling.h +++ b/libs/libdingaling/src/libdingaling.h @@ -108,7 +108,9 @@ typedef enum { LDL_SIGNAL_CANDIDATES, LDL_SIGNAL_MSG, LDL_SIGNAL_TERMINATE, - LDL_SIGNAL_ERROR + LDL_SIGNAL_ERROR, + LDL_SIGNAL_LOGIN_SUCCESS, + LDL_SIGNAL_LOGIN_FAILURE, } ldl_signal_t; typedef enum { @@ -138,7 +140,7 @@ typedef enum { #define DL_LOG_EMERG DL_PRE, 0 typedef ldl_status (*ldl_loop_callback_t)(ldl_handle_t *); -typedef ldl_status (*ldl_session_callback_t)(ldl_handle_t *, ldl_session_t *, ldl_signal_t, char *); +typedef ldl_status (*ldl_session_callback_t)(ldl_handle_t *, ldl_session_t *, ldl_signal_t, char *, char *, char *); typedef ldl_status (*ldl_response_callback_t)(ldl_handle_t *, char *); typedef void (*ldl_logger_t)(char *file, const char *func, int line, int level, char *fmt, ...); @@ -272,6 +274,16 @@ unsigned int ldl_session_terminate(ldl_session_t *session); */ void *ldl_handle_get_private(ldl_handle_t *handle); + +/*! + \brief Send a message + \param handle the conection handle + \param to the message recipiant + \param subject optional subject + \param body body of the message +*/ +void ldl_handle_send_msg(ldl_handle_t *handle, char *to, char *subject, char *body); + /*! \brief Offer candidates to a potential session \param session the session to send candidates on diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 056a813d15..1b95b64bf4 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -35,6 +35,11 @@ #define DL_CAND_WAIT 10000000 #define DL_CAND_INITIAL_WAIT 2000000 + +#define DL_EVENT_LOGIN_SUCCESS "dingaling::login_success" +#define DL_EVENT_LOGIN_FAILURE "dingaling::login_failure" +#define DL_EVENT_MESSAGE "dingaling::message" + static const char modname[] = "mod_dingaling"; static switch_memory_pool_t *module_pool = NULL; @@ -161,7 +166,7 @@ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan) static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id); static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig); - static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsession, ldl_signal_t signal, char *msg); + static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsession, ldl_signal_t signal, char *from, char *subject, char *msg); static ldl_status handle_response(ldl_handle_t *handle, char *id); static switch_status_t load_config(void); @@ -1115,6 +1120,21 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod load_config(); + if (switch_event_reserve_subclass(DL_EVENT_LOGIN_SUCCESS) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!", DL_EVENT_LOGIN_SUCCESS); + return SWITCH_STATUS_GENERR; + } + + if (switch_event_reserve_subclass(DL_EVENT_LOGIN_FAILURE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!", DL_EVENT_LOGIN_FAILURE); + return SWITCH_STATUS_GENERR; + } + + if (switch_event_reserve_subclass(DL_EVENT_MESSAGE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!", DL_EVENT_MESSAGE); + return SWITCH_STATUS_GENERR; + } + /* connect my internal structure to the blank pointer passed to me */ *module_interface = &channel_module_interface; @@ -1279,14 +1299,14 @@ static switch_status_t load_config(void) -static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsession, ldl_signal_t signal, char *msg) +static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsession, ldl_signal_t signal, char *from, char *subject, char *msg) { struct mdl_profile *profile = NULL; switch_core_session_t *session = NULL; switch_channel_t *channel = NULL; struct private_object *tech_pvt = NULL; + switch_event_t *event; - assert(dlsession != NULL); assert(handle != NULL); if (!(profile = ldl_handle_get_private(handle))) { @@ -1294,6 +1314,43 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi return LDL_STATUS_FALSE; } + + //#define DL_EVENT_LOGIN_SUCCESS "dingaling::login_success" + //#define DL_EVENT_LOGIN_FAILURE "dingaling::login_failure" + //#define DL_EVENT_MESSAGE "dingaling::message" + + if (!dlsession) { + switch(signal) { + case LDL_SIGNAL_MSG: + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, DL_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", profile->login); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", from); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "subject", subject); + switch_event_add_body(event, msg); + switch_event_fire(&event); + } + break; + case LDL_SIGNAL_LOGIN_SUCCESS: + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, DL_EVENT_LOGIN_SUCCESS) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", profile->login); + switch_event_fire(&event); + } + break; + case LDL_SIGNAL_LOGIN_FAILURE: + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, DL_EVENT_LOGIN_FAILURE) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", profile->login); + switch_event_fire(&event); + } + break; + default: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR\n"); + break; + + } + return LDL_STATUS_SUCCESS; + } + + if ((session = ldl_session_get_private(dlsession))) { tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); @@ -1361,9 +1418,6 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi } switch(signal) { - case LDL_SIGNAL_NONE: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR\n"); - break; case LDL_SIGNAL_MSG: if (msg) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "MSG [%s]\n", msg); @@ -1372,6 +1426,15 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi } } + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, DL_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", profile->login); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", from); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "subject", subject); + switch_event_add_body(event, msg); + switch_event_fire(&event); + } + break; + break; case LDL_SIGNAL_INITIATE: if (signal) { @@ -1521,6 +1584,10 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi } break; + + default: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR\n"); + break; } return LDL_STATUS_SUCCESS;