--- kannel-dev/gateway/gw/smsc_smpp.c	2002-06-02 14:35:57.000000000 +0300
+++ gateway/gw/smsc_smpp.c	2002-06-02 14:35:21.000000000 +0300
@@ -50,6 +51,12 @@
 #define SMPP_MAX_PENDING_SUBMITS    10 
 #define SMPP_RECONNECT_DELAY	    10.0 
 #define SMPP_DEFAULT_VERSION        0x34
+#define SMPP_THROTTLING_SLEEP_TIME  15
+
+enum {
+        SMPP_ESME_RMSGQFUL   = 0x00000014,
+        SMPP_ESME_RTHROTTLED = 0x00000058
+} SMPP_ERROR_MESSAGES;
  
  
 /*********************************************************************** 
@@ -84,6 +91,7 @@
     long max_pending_submits;
     long reconnect_delay;
     int version;
+    time_t throttling_err_time;
     SMSCConn *conn; 
 } SMPP; 
  
@@ -127,8 +135,8 @@
     smpp->reconnect_delay = reconnect_delay;
     smpp->quitting = 0; 
     smpp->version = version;
+    smpp->throttling_err_time = 0; 
     smpp->conn = conn; 
-     
     return smpp; 
 } 
  
@@ -223,21 +231,21 @@
  
 static long smpp_status_to_smscconn_failure_reason(long status) 
 { 
-    enum { 
-        ESME_RMSGQFUL = 0x00000014 
-    }; 
- 
-    if (status == ESME_RMSGQFUL) 
+    switch(status) {
+        case SMPP_ESME_RMSGQFUL:
+                return SMSCCONN_FAILED_TEMPORARILY;
+        case SMPP_ESME_RTHROTTLED:
         return SMSCCONN_FAILED_TEMPORARILY;
- 
+        default:
     return SMSCCONN_FAILED_REJECTED; 
+    }
 } 
  
  
 static SMPP_PDU *msg_to_pdu(SMPP *smpp, Msg *msg) 
 { 
     SMPP_PDU *pdu; 
-    char buffer[16];
+    Octstr* buffer;
     Octstr *relation_UTC_time = NULL;
     struct tm gmtime, localtime, tm;
     int gwqdiff;
@@ -327,30 +335,32 @@
         /* work out 1/4 hour difference between local time and UTC/GMT */
         gmtime = gw_gmtime(time(NULL));
         localtime = gw_localtime(time(NULL));
-        if (localtime.tm_hour >= gmtime.tm_hour) {
+        gwqdiff = ((localtime.tm_hour - gmtime.tm_hour) * 4)
+                  + ((localtime.tm_min - gmtime.tm_min) / 15);
+        if (gwqdiff >= 0)
             relation_UTC_time = octstr_create("+");
-            gwqdiff = (localtime.tm_hour - gmtime.tm_hour) * 4;
-        } else {
+	else
             relation_UTC_time = octstr_create("-");
-            gwqdiff = (gmtime.tm_hour - localtime.tm_hour) * 4;
-        }
+			  
 
         if (msg->sms.validity) {
-            tm = gw_localtime(time(NULL) + msg->sms.validity * 60);
-            sprintf(buffer, "%02d%02d%02d%02d%02d%02d0%01d%02d%1s",
+            tm = gw_localtime(time(NULL) + msg->sms.validity);
+            buffer = octstr_format("%02d%02d%02d%02d%02d%02d0%01d%02d%1s",
                     tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
                     tm.tm_hour, tm.tm_min, tm.tm_sec,
                     0, gwqdiff, octstr_get_cstr(relation_UTC_time));
-            pdu->u.submit_sm.validity_period = octstr_create(buffer);
+            pdu->u.submit_sm.validity_period = octstr_copy(buffer,0,16);
+            octstr_destroy(buffer);
         }
 
         if (msg->sms.deferred) {
-            tm = gw_localtime(time(NULL) + msg->sms.deferred * 60);
-            sprintf(buffer, "%02d%02d%02d%02d%02d%02d0%01d%02d%1s",
+            tm = gw_localtime(time(NULL) + msg->sms.deferred);
+            buffer = octstr_format("%02d%02d%02d%02d%02d%02d0%01d%02d%1s",
                     tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
                     tm.tm_hour, tm.tm_min, tm.tm_sec,
                     0, gwqdiff, octstr_get_cstr(relation_UTC_time));
-            pdu->u.submit_sm.schedule_delivery_time = octstr_create(buffer);
+            pdu->u.submit_sm.schedule_delivery_time = octstr_copy(buffer,0,16);
+            octstr_destroy(buffer);
         }
     }
 
@@ -376,6 +386,7 @@
     pdu = smpp_pdu_create(enquire_link, counter_increase(smpp->message_id_counter)); 
     dump_pdu("Sending enquire link:", smpp->conn->id, pdu); 
     os = smpp_pdu_pack(pdu); 
+    if (os)
     conn_write(conn, os); /* Write errors checked by caller. */ 
     octstr_destroy(os); 
     smpp_pdu_destroy(pdu); 
@@ -389,7 +400,10 @@
      
     dump_pdu("Sending PDU:", id, pdu); 
     os = smpp_pdu_pack(pdu); 
+    if (os)
     ret = conn_write(conn, os);   /* Caller checks for write errors later */ 
+    else
+        ret = -1;
     octstr_destroy(os); 
     return ret; 
 } 
@@ -667,8 +681,16 @@
                 reason = smpp_status_to_smscconn_failure_reason( 
                             pdu->u.submit_sm.command_status); 
  
+                /* check to see if we got a "throttling error", in which case we'll just
+                 * sleep for a while */
+				if (pdu->u.submit_sm.command_status == SMPP_ESME_RTHROTTLED)
+					time(&(smpp->throttling_err_time));
+				else
+					smpp->throttling_err_time = 0;
+
                 /* gen DLR_SMSC_FAIL */		 
-                if (msg->sms.dlr_mask & (DLR_SMSC_FAIL|DLR_FAIL)) { 
+                if (reason == SMSCCONN_FAILED_REJECTED &&
+                       (msg->sms.dlr_mask & (DLR_SMSC_FAIL|DLR_FAIL))) {
                     Octstr *reply; 
  		 
                     reply = octstr_format("0x%08lx", 
@@ -693,9 +715,9 @@
                     info(0,"SMPP[%s]: DLR = %s", octstr_get_cstr(smpp->conn->id),
                          octstr_get_cstr(dlrmsg->sms.msgdata)); 
                     bb_smscconn_receive(smpp->conn, dlrmsg); 
-                } else { 
-                    bb_smscconn_send_failed(smpp->conn, msg, reason); 
                 } 
+
+                bb_smscconn_send_failed(smpp->conn, msg, reason);
                 --(*pending_submits); 
             } else {  
                 Octstr *tmp; 
@@ -871,8 +893,13 @@
                 send_enquire_link(smpp, conn, &last_enquire_sent); 
  
                 /* Make sure we send even if we read a lot */ 
-                if (transmitter) 
+				if (transmitter &&
+					(!smpp->throttling_err_time || 
+					((time(NULL) - smpp->throttling_err_time) > SMPP_THROTTLING_SLEEP_TIME 
+						&& !(smpp->throttling_err_time = NULL)))
+					)
                     send_messages(smpp, conn, &pending_submits); 
+
             } 
 	     
             if (ret == -1) { 
@@ -881,7 +908,11 @@
                 break; 
             } 
 	     
-            if (transmitter) 
+			if (transmitter &&
+				(!smpp->throttling_err_time || 
+				((time(NULL) - smpp->throttling_err_time) > SMPP_THROTTLING_SLEEP_TIME 
+					&& !(smpp->throttling_err_time = NULL)))
+				)
                 send_messages(smpp, conn, &pending_submits); 
         } 
 	 
