diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 1b08cbe5a8..14e144b5f8 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -692,7 +692,9 @@ typedef enum { SWITCH_EVENT_MODULE_LOAD - Module was loaded SWITCH_EVENT_DTMF - DTMF was sent SWITCH_EVENT_MESSAGE - A Basic Message - SWITCH_EVENT_PRESENCE - Presence Info + SWITCH_EVENT_PRESENCE_IN - Presence in + SWITCH_EVENT_PRESENCE_OUT - Presence out + SWITCH_EVENT_PRESENCE_PROBE - Presence probe SWITCH_EVENT_CODEC - Codec Change SWITCH_EVENT_BACKGROUND_JOB - Background Job SWITCH_EVENT_DETECTED_SPEECH - Detected Speech @@ -730,6 +732,7 @@ typedef enum { SWITCH_EVENT_MESSAGE, SWITCH_EVENT_PRESENCE_IN, SWITCH_EVENT_PRESENCE_OUT, + SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_ROSTER, SWITCH_EVENT_CODEC, SWITCH_EVENT_BACKGROUND_JOB, diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index b3db423b8b..d9a6f65cbb 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -3682,6 +3682,86 @@ static conference_obj_t *conference_new(char *name, switch_xml_t profile, switch return conference; } +static void pres_event_handler(switch_event_t *event) +{ + char *to = switch_event_get_header(event, "to"); + char *dup_to = NULL, *conf_name, *e; + conference_obj_t *conference; + + if (!to || strncasecmp(to, "conf+", 5)) { + return; + } + + if (!(dup_to = strdup(to))) { + return; + } + + conf_name = dup_to + 5; + + if ((e = strchr(conf_name, '@'))) { + *e = '\0'; + } + + if ((conference = (conference_obj_t *) switch_core_hash_find(globals.conference_hash, conf_name))) { + switch_event_t *event; + + if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", CONF_CHAT_PROTO); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", conference->name); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", conference->name, conference->domain); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Active (%d caller%s)", conference->count, conference->count == 1 ? "" : "s"); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence"); + switch_event_fire(&event); + } + } else if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", CONF_CHAT_PROTO); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", conf_name); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", to); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Idle"); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "idle"); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence"); + switch_event_fire(&event); + } + + switch_safe_free(dup_to); +} + +static void send_presence(switch_event_types_t id) +{ + switch_xml_t cxml, cfg, advertise, room; + + /* Open the config from the xml registry */ + if (!(cxml = switch_xml_open_cfg(global_cf_name, &cfg, NULL))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", global_cf_name); + goto done; + } + + if ((advertise = switch_xml_child(cfg, "advertise"))) { + for (room = switch_xml_child(advertise, "room"); room; room = room->next) { + char *name = (char *) switch_xml_attr_soft(room, "name"); + char *status = (char *) switch_xml_attr_soft(room, "status"); + switch_event_t *event; + + if (name && switch_event_create(&event, id) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", CONF_CHAT_PROTO); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", name); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", name); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", status ? status : "Available"); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "idle"); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence"); + switch_event_fire(&event); + } + } + } + + done: + /* Release the config registry handle */ + if (cxml) { + switch_xml_free(cxml); + cxml = NULL; + } +} + /* Called by FreeSWITCH when the module loads */ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename) { @@ -3710,6 +3790,14 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod switch_mutex_init(&globals.id_mutex, SWITCH_MUTEX_NESTED, globals.conference_pool); switch_mutex_init(&globals.hash_mutex, SWITCH_MUTEX_NESTED, globals.conference_pool); + /* Get presence request events */ + if (switch_event_bind((char *) modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); + return SWITCH_STATUS_GENERR; + + } + send_presence(SWITCH_EVENT_PRESENCE_IN); + globals.running = 1; /* indicate that the module should continue to be loaded */ return status; diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 2b2958a286..da363b7d13 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -191,7 +191,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi static ldl_status handle_response(ldl_handle_t *handle, char *id); static switch_status_t load_config(void); -#define is_special(s) (s && (strstr(s, "ext+") || strstr(s, "user+") || strstr(s, "conf+"))) +#define is_special(s) (s && (strstr(s, "ext+") || strstr(s, "user+"))) static char *translate_rpid(char *in, char *ext) { @@ -2133,6 +2133,14 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi case LDL_SIGNAL_PRESENCE_PROBE: if (is_special(to)) { ldl_handle_send_presence(profile->handle, to, from, NULL, NULL, "Click To Call"); + } else { + if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_PROTO); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s", to); + switch_event_fire(&event); + } } break; case LDL_SIGNAL_PRESENCE_IN: diff --git a/src/switch_event.c b/src/switch_event.c index 89b43706c2..36b535a6be 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -125,6 +125,7 @@ static char *EVENT_NAMES[] = { "MESSAGE", "PRESENCE_IN", "PRESENCE_OUT", + "PRESENCE_PROBE", "ROSTER", "CODEC", "BACKGROUND_JOB",