### Eclipse Workspace Patch 1.0
#P gateway-cvs-head
Index: gw/smscconn_p.h
===================================================================
RCS file: /home/cvs/gateway/gw/smscconn_p.h,v
retrieving revision 1.54
diff -u -r1.54 smscconn_p.h
--- gw/smscconn_p.h	6 May 2009 18:47:34 -0000	1.54
+++ gw/smscconn_p.h	1 Jul 2009 16:39:53 -0000
@@ -284,6 +284,9 @@
 /* Responsible file: smsc/smsc_oisd.c */
 int smsc_oisd_create(SMSCConn *conn, CfgGroup *cfg);
 
+/* Responsible file: smsc/smsc_loopback.c */
+int smsc_loopback_create(SMSCConn *conn, CfgGroup *cfg);
+
 /* ADD NEW CREATE FUNCTIONS HERE
  *
  * int smsc_xxx_create(SMSCConn *conn, CfgGroup *cfg);
Index: gw/smscconn.c
===================================================================
RCS file: /home/cvs/gateway/gw/smscconn.c,v
retrieving revision 1.60
diff -u -r1.60 smscconn.c
--- gw/smscconn.c	6 May 2009 18:47:34 -0000	1.60
+++ gw/smscconn.c	1 Jul 2009 16:39:52 -0000
@@ -280,6 +280,8 @@
         ret = smsc_smasi_create(conn, grp);
     else if (octstr_compare(smsc_type, octstr_imm("oisd")) == 0)
         ret = smsc_oisd_create(conn, grp);
+    else if (octstr_compare(smsc_type, octstr_imm("loopback")) == 0)
+        ret = smsc_loopback_create(conn, grp);
     else
         ret = smsc_wrapper_create(conn, grp);
 
Index: gw/smsc/smsc_loopback.c
===================================================================
RCS file: gw/smsc/smsc_loopback.c
diff -N gw/smsc/smsc_loopback.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gw/smsc/smsc_loopback.c	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,169 @@
+/* ==================================================================== 
+ * The Kannel Software License, Version 1.0 
+ * 
+ * Copyright (c) 2001-2009 Kannel Group  
+ * Copyright (c) 1998-2001 WapIT Ltd.   
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in 
+ *    the documentation and/or other materials provided with the 
+ *    distribution. 
+ * 
+ * 3. The end-user documentation included with the redistribution, 
+ *    if any, must include the following acknowledgment: 
+ *       "This product includes software developed by the 
+ *        Kannel Group (http://www.kannel.org/)." 
+ *    Alternately, this acknowledgment may appear in the software itself, 
+ *    if and wherever such third-party acknowledgments normally appear. 
+ * 
+ * 4. The names "Kannel" and "Kannel Group" must not be used to 
+ *    endorse or promote products derived from this software without 
+ *    prior written permission. For written permission, please  
+ *    contact org@kannel.org. 
+ * 
+ * 5. Products derived from this software may not be called "Kannel", 
+ *    nor may "Kannel" appear in their name, without prior written 
+ *    permission of the Kannel Group. 
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS 
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,  
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR  
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ * ==================================================================== 
+ * 
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Kannel Group.  For more information on  
+ * the Kannel Group, please see <http://www.kannel.org/>. 
+ * 
+ * Portions of this software are based upon software originally written at  
+ * WapIT Ltd., Helsinki, Finland for the Kannel project.  
+ */ 
+
+/*
+ * smsc_loopback.c - loopback SMSC interface
+ * 
+ * This SMSC type is the MT wise counterpart of the 'reroute' functionality
+ * of the smsc group when MOs are re-routed as MT. This SMSC type re-routes
+ * therefore MTs as MOs back again.
+ *
+ * Stipe Tolj <stolj at kannel dot org>
+ */
+
+#include "gwlib/gwlib.h"
+#include "smscconn.h"
+#include "smscconn_p.h"
+#include "bb_smscconn_cb.h"
+#include "dlr.h"
+
+
+static int msg_cb(SMSCConn *conn, Msg *msg)
+{
+    Msg *sms;
+    
+    /* create duplicates first */
+    sms = msg_duplicate(msg);
+    
+    /* store temporary DLR data for SMSC ACK */
+    if (DLR_IS_ENABLED_DEVICE(msg->sms.dlr_mask) && !uuid_is_null(sms->sms.id)) {
+        Octstr *mid;
+        char id[UUID_STR_LEN + 1];
+
+        uuid_unparse(sms->sms.id, id);
+        mid = octstr_create(id);
+
+        dlr_add(conn->id, mid, sms);
+        
+        octstr_destroy(mid);
+    }
+
+	/* 
+	 * Inform abstraction layer of sent event,
+	 * it will also take care of DLR SMSC events.
+	 */
+    bb_smscconn_sent(conn, sms, NULL);
+
+    /* now change msg type to reflect flow type */
+    sms = msg_duplicate(msg);
+    sms->sms.sms_type = mo;
+    
+    /* 
+     * If there is a reroute-smsc-id in the config group,
+     * then let's use that value, otherwise assign the
+     * smsc-id canonical name for the MO. 
+     * This re-assignment of the smsc-id provides some
+     * MO routing capabilities, i.e. via smsbox-route group.
+     */
+    octstr_destroy(sms->sms.smsc_id);
+    
+    if (conn->reroute_to_smsc) {
+        sms->sms.smsc_id = octstr_duplicate(conn->reroute_to_smsc);
+    } else {
+        sms->sms.smsc_id = octstr_duplicate(conn->id);
+    }
+    
+    /* now pass back again as MO to the abstraction layer */
+    bb_smscconn_receive(conn, sms);
+
+    return 0;
+}
+
+
+static int shutdown_cb(SMSCConn *conn, int finish_sending)
+{
+    debug("smsc.loopback", 0, "Shutting down SMSCConn %s", 
+          octstr_get_cstr(conn->name));
+
+    conn->why_killed = SMSCCONN_KILLED_SHUTDOWN;
+    conn->status = SMSCCONN_DEAD;
+    bb_smscconn_killed();
+        
+    return 0;
+}
+
+
+static void start_cb(SMSCConn *conn)
+{
+    conn->status = SMSCCONN_ACTIVE;
+    conn->connect_time = time(NULL);
+}
+
+
+static long queued_cb(SMSCConn *conn)
+{
+    long ret = 0;
+
+    conn->load = ret;
+    return ret;
+}
+
+
+int smsc_loopback_create(SMSCConn *conn, CfgGroup *cfg)
+{
+    conn->data = NULL;
+    conn->name = octstr_format("LOOPBACK:%S", conn->id);
+  
+    conn->status = SMSCCONN_CONNECTING;
+    conn->connect_time = time(NULL);
+
+    conn->shutdown = shutdown_cb;
+    conn->queued = queued_cb;
+    conn->start_conn = start_cb;
+    conn->send_msg = msg_cb;
+
+    return 0;
+}
