]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add roughed in xmpp logger (NEEDS WORK)
authorAnthony Minessale <anthony.minessale@gmail.com>
Thu, 22 Dec 2005 23:59:33 +0000 (23:59 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Thu, 22 Dec 2005 23:59:33 +0000 (23:59 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@194 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/mod_xmpp_event/Makefile [new file with mode: 0644]
src/mod/mod_xmpp_event/mod_xmpp_event.c [new file with mode: 0644]
src/switch.c

diff --git a/src/mod/mod_xmpp_event/Makefile b/src/mod/mod_xmpp_event/Makefile
new file mode 100644 (file)
index 0000000..21bc939
--- /dev/null
@@ -0,0 +1,14 @@
+LDFLAGS += -liksemel -L/usr/local/lib
+
+all:   depends $(MOD).so
+
+depends:
+       $(BASE)/buildlib.sh $(BASE) install iksemel-1.2.tar.gz
+
+$(MOD).so: $(MOD).c
+       $(CC) $(CFLAGS) -fPIC -c $(MOD).c -o $(MOD).o 
+       $(CC) $(SOLINK) -o $(MOD).so  $(MOD).o $(LDFLAGS)
+
+clean:
+       rm -fr *.so *.o *~
+
diff --git a/src/mod/mod_xmpp_event/mod_xmpp_event.c b/src/mod/mod_xmpp_event/mod_xmpp_event.c
new file mode 100644 (file)
index 0000000..e0339ac
--- /dev/null
@@ -0,0 +1,330 @@
+/* 
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II <anthmct@yahoo.com>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Anthony Minessale II <anthmct@yahoo.com>
+ *
+ *
+ * mod_xmpp_event.c -- XMPP Event Logger
+ *
+ */
+#include <switch.h>
+#include <iksemel.h>
+
+static const char modname[] = "mod_xmpp_event";
+
+static int RUNNING = 0;
+static iksfilter *my_filter;
+static int opt_timeout = 30;
+static int opt_use_tls = 0;
+
+/* stuff we keep per session */
+struct session {
+       iksparser *parser;
+       iksid *acc;
+       char *pass;
+       int features;
+       int authorized;
+       int counter;
+       int job_done;
+};
+
+static struct {
+       char *jid;
+       char *passwd;
+       char *target_jid;
+       int debug;
+       struct session session;
+} globals;
+
+static void event_handler (switch_event *event)
+{
+       char buf[1024];
+       iks *msg;
+
+       if (!globals.session.authorized) {
+               return;
+       }
+
+       switch(event->event_id) {
+       default:
+               switch_event_serialize(event, buf, sizeof(buf), NULL);
+               //switch_console_printf(SWITCH_CHANNEL_CONSOLE, "\nEVENT\n--------------------------------\n%s\n", buf);
+               msg = iks_make_msg(IKS_TYPE_NONE, globals.target_jid, buf);
+               iks_send(globals.session.parser, msg);
+               break;
+       }
+}
+
+
+
+SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_jid, globals.jid)
+        SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_target_jid, globals.target_jid)
+        SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_passwd, globals.passwd)
+
+
+        static switch_status load_config(void)
+{
+       switch_config cfg;
+       switch_status status = SWITCH_STATUS_FALSE;
+       char *var, *val;
+       char *cf = "xmpp_event.conf";
+       int count = 0;
+
+       memset(&globals, 0, sizeof(globals));   
+
+       if (!switch_config_open_file(&cfg, cf)) {
+               switch_console_printf(SWITCH_CHANNEL_CONSOLE, "open of %s failed\n", cf);
+               return SWITCH_STATUS_TERM;
+       }
+       
+       while (switch_config_next_pair(&cfg, &var, &val)) {
+               if (!strcasecmp(cfg.category, "settings")) {
+                       if (!strcmp(var, "jid")) {
+                               set_global_jid(val);
+                               count++;
+                       } else if (!strcmp(var, "target_jid")) {
+                               set_global_target_jid(val);
+                               count++;
+                       } else if (!strcmp(var, "passwd")) {
+                               set_global_passwd(val);
+                               count++;
+                       } else if (!strcmp(var, "debug")) {
+                               globals.debug = atoi(val);
+                       }
+               }
+       }
+
+       switch_config_close_file(&cfg);
+       
+       /* TBD use config to pick what events to bind to */
+       if (switch_event_bind((char *)modname, SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY, event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
+               switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Couldn't bind!\n");
+               return SWITCH_STATUS_GENERR;
+       }
+       
+       if (count == 3) {
+               status = SWITCH_STATUS_SUCCESS;
+       }
+
+       return status;
+       
+}
+
+int
+on_result (struct session *sess, ikspak *pak)
+{
+
+       return IKS_FILTER_EAT;
+}
+
+int
+on_stream (struct session *sess, int type, iks *node)
+{
+       sess->counter = opt_timeout;
+       //iks *x;
+
+       switch (type) {
+       case IKS_NODE_START:
+               if (opt_use_tls && !iks_is_secure (sess->parser)) {
+                       iks_start_tls (sess->parser);
+               }
+               break;
+       case IKS_NODE_NORMAL:
+               if (strcmp ("stream:features", iks_name (node)) == 0) {
+                       sess->features = iks_stream_features (node);
+                       if (opt_use_tls && !iks_is_secure (sess->parser)) break;
+                       if (sess->authorized) {
+                               iks *t;
+                               if (sess->features & IKS_STREAM_BIND) {
+                                       t = iks_make_resource_bind (sess->acc);
+                                       iks_send (sess->parser, t);
+                                       iks_delete (t);
+                               }
+                               if (sess->features & IKS_STREAM_SESSION) {
+                                       t = iks_make_session ();
+                                       iks_insert_attrib (t, "id", "auth");
+                                       iks_send (sess->parser, t);
+                                       iks_delete (t);
+                               }
+                       } else {
+                               if (sess->features & IKS_STREAM_SASL_MD5)
+                                       iks_start_sasl (sess->parser, IKS_SASL_DIGEST_MD5, sess->acc->user, sess->pass);
+                               else if (sess->features & IKS_STREAM_SASL_PLAIN)
+                                       iks_start_sasl (sess->parser, IKS_SASL_PLAIN, sess->acc->user, sess->pass);
+                       }
+               } else if (strcmp ("failure", iks_name (node)) == 0) {
+                       switch_console_printf(SWITCH_CHANNEL_CONSOLE, "sasl authentication failed\n");
+               } else if (strcmp ("success", iks_name (node)) == 0) {
+                       sess->authorized = 1;
+                       iks_send_header (sess->parser, sess->acc->server);
+               } else {
+                       ikspak *pak;
+
+                       pak = iks_packet (node);
+                       iks_filter_packet (my_filter, pak);
+                       if (sess->job_done == 1) return IKS_HOOK;
+               }
+               break;
+#if 0
+       case IKS_NODE_STOP:
+               switch_console_printf(SWITCH_CHANNEL_CONSOLE, "server disconnected\n");
+               break;
+               
+       case IKS_NODE_ERROR:
+               switch_console_printf(SWITCH_CHANNEL_CONSOLE, "stream error\n");
+               break;
+#endif
+
+       }
+
+       if (node) iks_delete (node);
+       return IKS_OK;
+}
+
+int
+on_error (void *user_data, ikspak *pak)
+{
+       switch_console_printf(SWITCH_CHANNEL_CONSOLE, "authorization failed\n");
+       return IKS_FILTER_EAT;
+}
+
+void
+on_log (struct session *sess, const char *data, size_t size, int is_incoming)
+{
+       if (iks_is_secure (sess->parser)) fprintf (stderr, "Sec");
+       if (is_incoming) fprintf (stderr, "RECV"); else fprintf (stderr, "SEND");
+       fprintf (stderr, "[%s]\n", data);
+}
+
+void
+j_setup_filter (struct session *sess)
+{
+       if (my_filter) iks_filter_delete (my_filter);
+       my_filter = iks_filter_new ();
+       iks_filter_add_rule (my_filter, (iksFilterHook *) on_result, sess,
+                                                IKS_RULE_TYPE, IKS_PAK_IQ,
+                                                IKS_RULE_SUBTYPE, IKS_TYPE_RESULT,
+                                                IKS_RULE_ID, "auth",
+                                                IKS_RULE_DONE);
+       iks_filter_add_rule (my_filter, on_error, sess,
+                                                IKS_RULE_TYPE, IKS_PAK_IQ,
+                                                IKS_RULE_SUBTYPE, IKS_TYPE_ERROR,
+                                                IKS_RULE_ID, "auth",
+                                                IKS_RULE_DONE);
+}
+
+static void j_connect (char *jabber_id, char *pass)
+{
+
+       int e;
+
+       memset (&globals.session, 0, sizeof (globals.session));
+       globals.session.parser = iks_stream_new (IKS_NS_CLIENT, &globals.session, (iksStreamHook *) on_stream);
+       if (globals.debug) iks_set_log_hook (globals.session.parser, (iksLogHook *) on_log);
+       globals.session.acc = iks_id_new (iks_parser_stack (globals.session.parser), jabber_id);
+       if (NULL == globals.session.acc->resource) {
+               /* user gave no resource name, use the default */
+               char *tmp;
+               tmp = iks_malloc (strlen (globals.session.acc->user) + strlen (globals.session.acc->server) + 9 + 3);
+               sprintf (tmp, "%s@%s/%s", globals.session.acc->user, globals.session.acc->server, modname);
+               globals.session.acc = iks_id_new (iks_parser_stack (globals.session.parser), tmp);
+               iks_free (tmp);
+       }
+       globals.session.pass = pass;
+
+       j_setup_filter (&globals.session);
+
+       e = iks_connect_tcp (globals.session.parser, globals.session.acc->server, IKS_JABBER_PORT);
+       switch (e) {
+       case IKS_OK:
+               break;
+       case IKS_NET_NODNS:
+               switch_console_printf(SWITCH_CHANNEL_CONSOLE, "hostname lookup failed\n");
+       case IKS_NET_NOCONN:
+               switch_console_printf(SWITCH_CHANNEL_CONSOLE, "connection failed\n");
+       default:
+               switch_console_printf(SWITCH_CHANNEL_CONSOLE, "io error\n");
+       }
+
+       globals.session.counter = opt_timeout;
+       while (RUNNING == 1) {
+               e = iks_recv (globals.session.parser, 1);
+               if(globals.session.job_done) break;
+               if (IKS_HOOK == e) break;
+               if (!globals.session.authorized) {
+                       if (IKS_NET_TLSFAIL == e) switch_console_printf(SWITCH_CHANNEL_CONSOLE, "tls handshake failed\n");
+                       if (IKS_OK != e) switch_console_printf(SWITCH_CHANNEL_CONSOLE, "io error\n");
+                       globals.session.counter--;
+                       if (globals.session.counter == 0) switch_console_printf(SWITCH_CHANNEL_CONSOLE, "network timeout\n");
+               }
+       }
+       iks_disconnect(globals.session.parser);
+       iks_parser_delete (globals.session.parser);
+       globals.session.authorized = 0;
+       RUNNING = 0;
+       
+}
+                                                 
+static switch_loadable_module_interface xmpp_event_module_interface = {
+       /*.module_name*/                        modname,
+       /*.endpoint_interface*/         NULL,
+       /*.timer_interface*/            NULL,
+       /*.dialplan_interface*/         NULL,
+       /*.codec_interface*/            NULL,
+       /*.application_interface*/      NULL
+};
+
+SWITCH_MOD_DECLARE(switch_status) switch_module_load(switch_loadable_module_interface **interface, char *filename) {
+       /* connect my internal structure to the blank pointer passed to me */
+       *interface = &xmpp_event_module_interface;
+
+       if (load_config() != SWITCH_STATUS_SUCCESS) {
+               return SWITCH_STATUS_FALSE;
+       }
+
+
+
+       /* indicate that the module should continue to be loaded */
+       return SWITCH_STATUS_SUCCESS;
+}
+
+
+SWITCH_MOD_DECLARE(switch_status) switch_module_shutdown(void)
+{
+       RUNNING = -1;
+
+       while (RUNNING) {
+               switch_yield(1000);
+       }
+       return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_MOD_DECLARE(switch_status) switch_module_runtime(void)
+{
+       RUNNING = 1;
+       j_connect(globals.jid, globals.passwd);
+       switch_console_printf(SWITCH_CHANNEL_CONSOLE, "disconnecting client\n");
+       return SWITCH_STATUS_TERM;
+}
index de66d12d1c83ddee6cfc228fbfa8d1d18462837a..868484f139857d2755d719817f52c87529e9488c 100644 (file)
@@ -62,6 +62,11 @@ int main(int argc, char *argv[]) {
        /* wait for console input */
        switch_console_loop();
 
+       if (switch_event_create(&event, SWITCH_EVENT_SHUTDOWN) == SWITCH_STATUS_SUCCESS) {
+               switch_event_add_header(event, "event_info", "System Shutting Down");
+               switch_event_fire(&event);
+       }
+
        switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Clean up modules.\n");
        loadable_module_shutdown();
        switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Tearing down environment.\n");