Index: gw/smppbox.c
===================================================================
--- gw/smppbox.c	(revision 46)
+++ gw/smppbox.c	(working copy)
@@ -142,9 +142,9 @@
     time_t	connect_time;
     Counter	*smpp_pdu_counter;
     Octstr	*client_ip;
-    List	*incoming;
+    List	*incoming;	/* from esme to smppbox */
+    List	*outgoing;	/* from bearerbox to smppbox */
     List	*retry;   	/* If sending fails */
-    List	*outgoing;
     Dict	*sent;
     Semaphore	*pending;
     volatile sig_atomic_t alive;
@@ -418,6 +418,16 @@
     return msg;
 }
 
+void smpp_incoming(void *arg)
+{
+	Boxc *box = (Boxc *)arg;
+	Msg *msg;
+
+	while (box->alive && (msg = read_from_box(box->bearerbox_connection, box)) != NULL) {
+		gwlist_produce(box->outgoing, msg);
+	}
+}
+
 Msg *catenate_msg(List *list, int total)
 {
 	int current = 1, partno = 1, thismsg, max = 0;
@@ -1615,6 +1625,11 @@
     boxc->dest_addr_ton = smpp_dest_addr_ton;
     boxc->dest_addr_npi = smpp_dest_addr_npi;
 
+    boxc->incoming = gwlist_create();
+    gwlist_add_producer(boxc->incoming);
+    boxc->outgoing = gwlist_create();
+    gwlist_add_producer(boxc->outgoing);
+
     boxc->alt_dcs = 0;
     boxc->validityperiod = -1;	
     boxc->priority = 0;
@@ -1646,6 +1661,10 @@
 	    octstr_destroy(boxc->client_ip);
     dict_destroy(boxc->msg_acks);
     dict_destroy(boxc->deliver_acks);
+    gwlist_remove_producer(boxc->incoming);
+    gwlist_destroy(boxc->incoming, NULL);
+    gwlist_remove_producer(boxc->outgoing);
+    gwlist_destroy(boxc->outgoing, NULL);
     if (boxc->boxc_id)
 	octstr_destroy(boxc->boxc_id);
     gw_free(boxc);
@@ -1696,6 +1715,17 @@
 static void smpp_to_bearerbox(void *arg)
 {
     Boxc *box = arg;
+    SMPP_PDU *pdu;
+
+    while (box->alive && (pdu = gwlist_consume(box->incoming)) != NULL) {
+	handle_pdu(box->smpp_connection, box, pdu);
+    }
+
+}
+
+void smpp_outgoing(void *arg)
+{
+    Boxc *box = (Boxc *)arg;
     Connection *conn = box->smpp_connection;
     SMPP_PDU *pdu;
     long len;
@@ -1717,13 +1747,10 @@
 			break;
 		case 1:
 			box->last_pdu_received = time(NULL);
-			handle_pdu(conn, box, pdu);
+			gwlist_produce(box->incoming, pdu);
 			break;
 		}
     }
-#ifdef HAVE_SHUTDOWN_CONNECTION
-    shutdown_connection(box->bearerbox_connection);
-#endif
 }
 
 /* if this login was made as a transmitter, then find the corresponding receiver connection */
@@ -1757,7 +1784,7 @@
 
     while (smppbox_status == SMPP_RUNNING && box->alive) {
 
-	msg = read_from_box(box->bearerbox_connection, box);
+	msg = gwlist_consume(box->outgoing);
         if (msg == NULL) {
 	    if ((!box->alive) || conn_eof(box->bearerbox_connection)) {
             	/* tell smppbox to die */
@@ -1924,7 +1951,7 @@
 {
     int fd;
     Boxc *newconn;
-    long sender;
+    long sender, inthread, outthread;
     Msg *msg;
 
     fd = (int)arg;
@@ -1952,6 +1979,8 @@
     }
 #endif
 
+    inthread = gwthread_create(smpp_incoming, newconn);
+    outthread = gwthread_create(smpp_outgoing, newconn);
     sender = gwthread_create(smpp_to_bearerbox, newconn);
     if (sender == -1) {
 	    error(0, "Failed to start a new thread, disconnecting client <%s>",
@@ -1961,6 +1990,8 @@
     }
     bearerbox_to_smpp(newconn);
     gwthread_join(sender);
+    gwthread_join(inthread);
+    gwthread_join(outthread);
     gwlist_delete_equal(all_boxes, newconn);
     boxc_destroy(newconn);
 }
