Re: [PATCH] preliminary confirmed sendsms

Kalle Marjola <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Organization Enpocket
Message-ID <[email protected]>
And here is the patch itself =]

-- 
 &Kalle Marjola ::: Development ::: Helsinki ::: Enpocket
confirmpatch.txt (text/plain, 6.6 KB)
? gwlib/gw_uuid_types.h
? test/test_boxc
? test/test_mime_multipart
? test/test_pcre
? test/test_prioqueue
? test/test_regex
? test/test_uuid
Index: gw/smsbox.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsbox.c,v
retrieving revision 1.252
diff -u -r1.252 smsbox.c
--- gw/smsbox.c	3 Sep 2004 12:42:33 -0000	1.252
+++ gw/smsbox.c	6 Oct 2004 12:34:55 -0000
@@ -130,6 +130,15 @@
 int charset_processing (Octstr *charset, Octstr *text, int coding);
 static long get_tag(Octstr *body, Octstr *tag, Octstr **value, long pos, int nostrip);
 
+/* for delayed HTTP answers.
+ * Dict key is uuid, value is HTTPClient pointer
+ * of open transaction
+ */
+
+static Dict *client_dict = NULL;
+static Octstr *stored_uuid_os = NULL;  // horrible kludge!
+static List *sendsms_reply_hdrs = NULL;
+
 /***********************************************************************
  * Communication with the bearerbox.
  */
@@ -150,6 +159,60 @@
     write_to_bearerbox(msg);
 }
 
+/*
+ * Handle delayed reply to HTTP sendsms client, if any
+ */
+static void delayed_http_reply(Msg *msg)
+{
+    HTTPClient *client;
+    Octstr *os, *answer;
+    char id[UUID_STR_LEN + 1];
+    int status;
+	  
+    uuid_unparse(msg->ack.id, id);
+    os = octstr_create(id);
+    debug("sms.http", 0, "Got ACK (%d) of %s", msg->ack.nack, octstr_get_cstr(os));
+    client = dict_remove(client_dict, os);
+    if (client == NULL) {
+        warning(0, "No client? (multi-send?)");
+        octstr_destroy(os);
+        return;
+    }
+    /* XXX  this should be fixed so that we really wait for DLR
+     *      SMSC accept/deny before doing this - but that is far
+     *      more slower, a bit more complex, and is done later on
+     */
+
+    switch (msg->ack.nack) {
+      case ack_success:
+        status = HTTP_ACCEPTED;
+        answer = octstr_create("0: Accepted for delivery");
+        break;
+      case ack_buffered:
+        status = HTTP_ACCEPTED;
+        answer = octstr_create("3: Queued for later delivery");
+        break;
+      case ack_failed:
+        status = HTTP_FORBIDDEN;
+        answer = octstr_create("Not routable. Do not try again.");
+        break;
+      case ack_failed_tmp:
+        status = HTTP_SERVICE_UNAVAILABLE;
+        answer = octstr_create("Temporal failure, try again later.");
+        break;
+      default:
+	error(0, "Strange reply from bearerbox!");
+        status = HTTP_SERVICE_UNAVAILABLE;
+        answer = octstr_create("Temporal failure, try again later.");
+        break;
+    }
+
+    http_send_reply(client, status, sendsms_reply_hdrs, answer);
+
+    octstr_destroy(answer);
+    octstr_destroy(os);
+}
+
 
 /*
  * Read an Msg from the bearerbox and send it to the proper receiver
@@ -189,11 +252,9 @@
 	    total++;
 	    list_produce(smsbox_requests, msg);
 	} else if (msg_type(msg) == ack) {
-	    /*
-	     * do nothing for now. Later we will handle this
-	     * gracefully...
-	     */
-	    msg_destroy(msg);
+
+	  delayed_http_reply(msg);
+	  msg_destroy(msg);
 	} else {
 	    warning(0, "Received other message than sms/admin, ignoring!");
 	    msg_destroy(msg);
@@ -2231,6 +2292,19 @@
 	             udh == NULL ? ( text == NULL ? "" : octstr_get_cstr(text) ) : "<< UDH >>");
         }
     }
+    /* XXX  UGLY kludge, to be used in sendsms_thread */
+    if (stored_uuid_os == NULL) {
+        char id[UUID_STR_LEN + 1];
+	  
+        uuid_unparse(msg->sms.id, id);
+        stored_uuid_os = octstr_create(id);
+
+        debug("sms.http", 0, "Stored UUID %s", octstr_get_cstr(stored_uuid_os));
+
+        /* this octstr is then used to store the HTTP client into 
+	 * client_dict, if need to, in sendsms_thread */
+    }
+
     msg_destroy(msg);
     list_destroy(receiver, octstr_destroy_item);
     list_destroy(allowed, octstr_destroy_item);
@@ -3018,17 +3092,12 @@
 
 
 static void sendsms_thread(void *arg)
-{
+ {
     HTTPClient *client;
     Octstr *ip, *url, *body, *answer;
-    List *hdrs, *args, *reply_hdrs;
+    List *hdrs, *args;
     int status;
 
-    reply_hdrs = http_create_empty_headers();
-    http_header_add(reply_hdrs, "Content-type", "text/html");
-    http_header_add(reply_hdrs, "Pragma", "no-cache");
-    http_header_add(reply_hdrs, "Cache-Control", "no-cache");
-
     for (;;) {
     	client = http_accept_request(sendsms_port, &ip, &url, &hdrs, &body, 
 	    	    	    	     &args);
@@ -3084,18 +3153,23 @@
 	debug("sms.http", 0, "Status: %d Answer: <%s>", status,
           octstr_get_cstr(answer));
 
-    octstr_destroy(ip);
-    octstr_destroy(url);
-    http_destroy_headers(hdrs);
-    octstr_destroy(body);
-    http_destroy_cgiargs(args);
-	
-    http_send_reply(client, status, reply_hdrs, answer);
+	octstr_destroy(ip);
+	octstr_destroy(url);
+	http_destroy_headers(hdrs);
+	octstr_destroy(body);
+	http_destroy_cgiargs(args);
 
-    octstr_destroy(answer);
+	if (status != HTTP_ACCEPTED || stored_uuid_os == NULL)
+	  http_send_reply(client, status, sendsms_reply_hdrs, answer);
+	else {
+	  debug("sms.http", 0, "Delayed reply - wait for bearerbox");
+	  dict_put(client_dict, stored_uuid_os, client);
+	  octstr_destroy(stored_uuid_os);
+	  stored_uuid_os = NULL;
+	}
+	octstr_destroy(answer);
     }
 
-    http_destroy_headers(reply_hdrs);
 }
 
 
@@ -3411,6 +3485,13 @@
     if (urltrans_add_cfg(translations, cfg) == -1)
 	panic(0, "urltrans_add_cfg failed");
 
+    client_dict = dict_create(32, NULL);
+    sendsms_reply_hdrs = http_create_empty_headers();
+    http_header_add(sendsms_reply_hdrs, "Content-type", "text/html");
+    http_header_add(sendsms_reply_hdrs, "Pragma", "no-cache");
+    http_header_add(sendsms_reply_hdrs, "Cache-Control", "no-cache");
+
+
     caller = http_caller_create();
     smsbox_requests = list_create();
     smsbox_http_requests = list_create();
@@ -3474,6 +3555,9 @@
     if (black_list_regex != NULL) gw_regex_destroy(black_list_regex);
     cfg_destroy(cfg);
 
+    dict_destroy(client_dict); /* XXX is this right location? */
+    http_destroy_headers(sendsms_reply_hdrs); /* ditto */
+
     /* 
      * Just sleep for a while to get bearerbox chance to restart.
      * Otherwise we will fail while trying to connect to bearerbox!
Index: gwlib/http.h
===================================================================
RCS file: /home/cvs/gateway/gwlib/http.h,v
retrieving revision 1.63
diff -u -r1.63 http.h
--- gwlib/http.h	22 Jan 2004 14:08:25 -0000	1.63
+++ gwlib/http.h	6 Oct 2004 12:34:55 -0000
@@ -158,7 +158,8 @@
     HTTP_UNSUPPORTED_MEDIA_TYPE    = 415,
     HTTP_INTERNAL_SERVER_ERROR     = 500,
     HTTP_NOT_IMPLEMENTED           = 501,
-    HTTP_BAD_GATEWAY               = 502
+    HTTP_BAD_GATEWAY               = 502,
+    HTTP_SERVICE_UNAVAILABLE       = 503
 };
 
 /*
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.