This is a repost of the tariff patch I posted earlier this summer. It 
has been adapted to reflect the new location of SMSC drivers.

We at Matchem could _really_ use tariff support and I personally would 
like to see this one accepted to the main CVS branch instead of 
maintaining a proprietary in-house patch . How about? Do you think this 
approach is good enough? Does it need more developement first? Should a 
new sub-project be established?


-- 
Marko Saaresto, Software Developer     MatchEm Ltd
[EMAIL PROTECTED]             <www.matchem.com>
Mob. +358-44-380 0013                  fax: +358-9-644 091
Index: doc/userguide/userguide.xml
===================================================================
RCS file: /home/cvs/gateway/doc/userguide/userguide.xml,v
retrieving revision 1.189
diff -u -r1.189 userguide.xml
--- doc/userguide/userguide.xml 22 Aug 2002 17:29:39 -0000      1.189
+++ doc/userguide/userguide.xml 28 Aug 2002 15:40:42 -0000
@@ -2022,6 +2022,9 @@
 send stored messages as soon as Kannel logs in (this is the normal
 configuration).</para>
 
+<para> The CIMD2 driver supports tariff classes. This support should be
+documented.</para>
+
 <programlisting>
 group = smsc
 smsc = cimd2
@@ -3076,6 +3079,10 @@
    <para>This special "SMSC" is used for HTTP based connections with
    other gateways and various other relay services, when direct SMSC
    is not available.</para>
+
+   <para>Relay gateway acknowledges incoming messages and sends
+   replies through sendsms push. Relay gateway uses "tariff"
+   request parameter to deliver billing data.</para>
   
 <programlisting>
 group = smsc
@@ -3404,6 +3411,25 @@
     <entry>?</entry>
    </row>
 
+   <row>
+    <entry spanname="feature">Supports Tariff information</entry>
+   </row>
+   <row>
+    <entry></entry>
+    <entry>?</entry>
+    <entry>y?</entry>
+    <entry>?</entry>
+    <entry>?</entry>
+    <entry>?</entry>
+    <entry>?</entry>
+    <entry>?</entry>
+    <entry>?</entry>
+    <entry>?</entry>
+    <entry>?</entry>
+    <entry>y</entry>
+    <entry>?</entry>
+   </row>
+
   </tbody>
  </tgroup>
 </table>
@@ -4587,6 +4613,9 @@
    <row><entry><literal>alt-dcs</literal></entry>
    <entry><literal>X-Kannel-Alt-DCS</literal></entry></row>
 
+   <row><entry><literal>tariff</literal></entry>
+   <entry><literal>X-Kannel-Tariff</literal></entry></row>
+
   </tbody>
   </tgroup>
  </table>
@@ -5756,6 +5785,15 @@
        but wants to distinguish them in the log. In the case of a HTTP SMSC
        type the account name is prepended with the servicename (username) and a colon 
(:)
        and forwarded to the next insta ce of kannel. This allows hierarchical 
accounting.
+     </entry></row>
+
+    <row><entry><literal>tariff</literal></entry>
+     <entry>number</entry>
+     <entry valign=bottom>
+        Tariff class for the message. Some SMSC drivers support tariff classes and
+        this parameter carries the price information. NOTE: currently there is no
+        unified way to handle tariff classes. Valid values for this parameter are
+        currently SMSC (driver) specific.
      </entry></row>
 
   </tbody>
Index: gw/msg-decl.h
===================================================================
RCS file: /home/cvs/gateway/gw/msg-decl.h,v
retrieving revision 1.19
diff -u -r1.19 msg-decl.h
--- gw/msg-decl.h       5 Aug 2002 15:04:45 -0000       1.19
+++ gw/msg-decl.h       28 Aug 2002 15:40:42 -0000
@@ -44,6 +44,7 @@
                INTEGER(alt_dcs);
         INTEGER(rpi);
                OCTSTR(charset);
+               INTEGER(tariff);
        })
 
 MSG(ack,
Index: gw/smsbox.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsbox.c,v
retrieving revision 1.209
diff -u -r1.209 smsbox.c
--- gw/smsbox.c 20 Aug 2002 21:13:22 -0000      1.209
+++ gw/smsbox.c 28 Aug 2002 15:40:42 -0000
@@ -322,7 +322,7 @@
                                      int *coding, int *compress, 
                                      int *validity, int *deferred, 
                                      int *dlr_mask, Octstr **dlr_url, 
-                                     Octstr **account, int *pid, int *alt_dcs, int 
*rpi)
+                                     Octstr **account, int *pid, int *alt_dcs, int 
+*rpi, int *tariff)
 {
     Octstr *name, *val;
     long l;
@@ -330,7 +330,7 @@
     *dlr_mask = 0;
     *dlr_url = NULL;
     *mclass = *mwi = *coding = *compress = *validity = 
-       *deferred = *pid = *alt_dcs = *rpi = 0;
+        *deferred = *pid = *alt_dcs = *rpi = *tariff = 0;
     for(l=0; l<list_len(headers); l++) {
        http_header_get(headers, l, &name, &val);
 
@@ -393,7 +393,10 @@
            sscanf(octstr_get_cstr(val),"%d", mclass);
         }
        else if (octstr_case_compare(name, octstr_imm("X-Kannel-Alt-DCS")) == 0) {
-           sscanf(octstr_get_cstr(val),"%d", alt_dcs);
+           sscanf(octstr_get_cstr(val),"%d", alt_dcs);
+        }
+       else if (octstr_case_compare(name, octstr_imm("X-Kannel-Tariff")) == 0) {
+           sscanf(octstr_get_cstr(val),"%d", tariff);
         }
        else if (octstr_case_compare(name, octstr_imm("X-Kannel-Compress")) == 0) {
            sscanf(octstr_get_cstr(val),"%d", compress);
@@ -465,7 +468,7 @@
                                   int *validity, int *deferred,
                                   int *dlr_mask, Octstr **dlr_url,
                                   Octstr **account, int *pid, int *alt_dcs,
-                                  int *rpi, List **tolist)
+                                  int *rpi, List **tolist, int *tariff)
 {                                    
 
 /*
@@ -508,7 +511,7 @@
     *dlr_mask = 0;
     *dlr_url = NULL;
     *mclass = *mwi = *coding = *compress = *validity = 
-       *deferred = *pid = *alt_dcs = *rpi = 0;
+       *deferred = *pid = *alt_dcs = *rpi = *tariff = 0;
 
     debug("sms", 0, "XMLParsing: XML: <%s>", octstr_get_cstr(*body));
 
@@ -579,6 +582,14 @@
        O_DESTROY(tmp);
     }
 
+    /*Tariff class (tariff) */
+    get_tag(tmp, octstr_imm("tariff"), &tmp, 0, 0);
+    if(tmp) {
+        if(octstr_parse_long(&tmplong, tmp, 0, 10) != -1)
+           *tariff = tmplong;
+        O_DESTROY(tmp);
+    }
+
     /* rpi */
     get_tag(*body, octstr_imm("rpi"), &tmp, 0, 0);
     if(tmp) {
@@ -688,7 +699,7 @@
                         int mclass, int mwi, int coding, int compress,
                         int validity, int deferred,
                         Octstr *dlr_url, int dlr_mask, int pid, int alt_dcs,
-             int rpi, Octstr *smsc)
+                        int rpi, Octstr *smsc, int tariff)
 {    
     msg->sms.msgdata = replytext;
     msg->sms.time = time(NULL);
@@ -750,6 +761,12 @@
        else 
            warning(0, "Tried to set MClass field, denied.");
     }
+    if (tariff) {
+        if (urltrans_accept_x_kannel_headers(trans))
+           msg->sms.tariff = tariff;     
+       else 
+           warning(0, "Tried to set Tariff field, denied.");
+    }
     if (pid) {
         if (urltrans_accept_x_kannel_headers(trans))
            msg->sms.pid = pid;   
@@ -888,7 +905,7 @@
     Octstr *smsc;
     int dlr_mask;
     int octets;
-    int mclass, mwi, coding, compress, pid, alt_dcs, rpi;
+    int mclass, mwi, coding, compress, pid, alt_dcs, rpi, tariff;
     int validity, deferred;
     unsigned long retries;
     unsigned int queued; /* indicate if processes reply is requeued */
@@ -927,7 +944,7 @@
                                          NULL, NULL, &smsc, &mclass, &mwi, 
                                          &coding, &compress, &validity, 
                                          &deferred, &dlr_mask, &dlr_url, 
-                                         &account, &pid, &alt_dcs, &rpi);
+                                         &account, &pid, &alt_dcs, &rpi, &tariff);
             } else if (octstr_case_compare(type, text_plain) == 0) {
                 replytext = octstr_duplicate(reply_body);
                 octstr_destroy(reply_body);
@@ -937,7 +954,7 @@
                                          NULL, NULL, &smsc, &mclass, &mwi, 
                                          &coding, &compress, &validity, 
                                          &deferred, &dlr_mask, &dlr_url, 
-                                         &account, &pid, &alt_dcs, &rpi);
+                                         &account, &pid, &alt_dcs, &rpi, &tariff);
             } else if (octstr_case_compare(type, text_xml) == 0) {
                 replytext = octstr_duplicate(reply_body);
                 octstr_destroy(reply_body); 
@@ -945,7 +962,7 @@
                 get_x_kannel_from_xml(mt_reply, &type, &replytext, reply_headers, 
                         &from, &to, &udh, NULL, NULL, &smsc, &mclass, &mwi, 
                         &coding, &compress, &validity, &deferred, &dlr_mask, 
-                        &dlr_url, &account, &pid, &alt_dcs, &rpi, NULL);
+                        &dlr_url, &account, &pid, &alt_dcs, &rpi, NULL, &tariff);
             } else if (octstr_case_compare(type, octet_stream) == 0) {
                 replytext = octstr_duplicate(reply_body);
                 octstr_destroy(reply_body);
@@ -955,7 +972,7 @@
                                          NULL, NULL, &smsc, &mclass, &mwi, 
                                          &coding, &compress, &validity, 
                                          &deferred, &dlr_mask, &dlr_url, 
-                                         &account, &pid, &alt_dcs, &rpi);
+                                         &account, &pid, &alt_dcs, &rpi, &tariff);
             } else {
                 replytext = octstr_duplicate(reply_couldnotrepresent); 
             }
@@ -975,7 +992,7 @@
 
         fill_message(msg, trans, replytext, octets, from, to, udh, mclass,
             mwi, coding, compress, validity, deferred, dlr_url, 
-           dlr_mask, pid, alt_dcs, rpi, smsc);
+           dlr_mask, pid, alt_dcs, rpi, smsc, tariff);
 
         if (final_url == NULL)
             final_url = octstr_imm("");
@@ -1165,6 +1182,13 @@
                octstr_get_cstr(os));
            octstr_destroy(os);
        }
+       if(msg->sms.tariff) {
+           Octstr *os;
+           os = octstr_format("%d",msg->sms.tariff);
+           http_header_add(request_headers, "X-Kannel-Tariff", 
+               octstr_get_cstr(os));
+           octstr_destroy(os);
+       }
        if(msg->sms.mwi) {
            Octstr *os;
            os = octstr_format("%d",msg->sms.mwi);
@@ -1658,7 +1682,7 @@
                                 int validity, int deferred, 
                                 int *status, int dlr_mask, Octstr *dlr_url, 
                                 Octstr *account, int pid, int alt_dcs, int rpi,
-                                List *receiver)
+                                List *receiver, int tariff)
 {                                   
     Msg *msg = NULL;
     Octstr *newfrom, *returnerror, *receiv;
@@ -1816,7 +1840,13 @@
        goto fielderror;
     }
     msg->sms.alt_dcs = alt_dcs;
-    
+
+    if ( tariff < 0 || tariff > 999 ) {
+       returnerror = octstr_create("Tariff field misformed, rejected");
+       goto fielderror;
+    }
+    msg->sms.tariff = tariff;
+
     if ( mwi < 0 || mwi > 8 ) {
        returnerror = octstr_create("MWI field misformed, rejected");
        goto fielderror;
@@ -2065,7 +2095,7 @@
     Octstr *account = NULL;
     int        dlr_mask = 0;
     Octstr *dlr_mask_string;
-    int mclass, mwi, coding, compress, validity, deferred, pid, alt_dcs, rpi;
+    int mclass, mwi, coding, compress, validity, deferred, pid, alt_dcs, rpi, tariff;
    
     /* check the username and password */
     t = authorise_user(args, client_ip);
@@ -2090,7 +2120,7 @@
        dlr_mask = 0;
 
     mclass = mwi = coding = compress = validity = 
-       deferred = pid = alt_dcs = rpi = 0;
+        deferred = pid = alt_dcs = rpi = tariff = 0;
 
     tmp_string = NULL;
     tmp_string = http_cgi_variable(args, "flash");
@@ -2120,6 +2150,11 @@
         sscanf(octstr_get_cstr(tmp_string),"%d", &alt_dcs);
 
     tmp_string = NULL;
+    tmp_string = http_cgi_variable(args, "tariff");
+    if(tmp_string != NULL)
+        sscanf(octstr_get_cstr(tmp_string),"%d", &tariff);
+
+    tmp_string = NULL;
     tmp_string = http_cgi_variable(args, "mwi");
     if(tmp_string != NULL)
         sscanf(octstr_get_cstr(tmp_string),"%d", &mwi);
@@ -2164,7 +2199,7 @@
     return smsbox_req_handle(t, client_ip, from, to, text, charset, udh, 
                             smsc, mclass, mwi, coding, compress, validity, 
                             deferred, status, dlr_mask, dlr_url, account,
-                            pid, alt_dcs, rpi, NULL);
+                            pid, alt_dcs, rpi, NULL, tariff);
     
 }
 
@@ -2184,7 +2219,7 @@
     Octstr *account;
     List *tolist;
     int dlr_mask = 0;
-    int mclass, mwi, coding, compress, validity, deferred, pid, alt_dcs, rpi;
+    int mclass, mwi, coding, compress, validity, deferred, pid, alt_dcs, rpi, tariff;
  
     from = to = user = pass = udh = smsc = dlr_url = account = NULL;
     tolist = NULL;
@@ -2198,12 +2233,12 @@
        get_x_kannel_from_xml(mt_push, &type, &body, headers, &from, &to, &udh,
                        &user, &pass, &smsc, &mclass, &mwi, &coding,
                        &compress, &validity, &deferred, &dlr_mask, &dlr_url, 
-                       &account, &pid, &alt_dcs, &rpi, &tolist);
+                       &account, &pid, &alt_dcs, &rpi, &tolist, &tariff);
     } else {
        get_x_kannel_from_headers(headers, &from, &to, &udh,
                              &user, &pass, &smsc, &mclass, &mwi, &coding,
                              &compress, &validity, &deferred, 
-                             &dlr_mask, &dlr_url, &account, &pid, &alt_dcs, &rpi);
+                             &dlr_mask, &dlr_url, &account, &pid, &alt_dcs, &rpi, 
+&tariff);
     }
 
     /* check the username and password */
@@ -2243,7 +2278,7 @@
            ret = smsbox_req_handle(t, client_ip, from, to, body, charset,
                                    udh, smsc, mclass, mwi, coding, compress, 
                                    validity, deferred, status, dlr_mask, 
-                                   dlr_url, account, pid, alt_dcs, rpi, tolist);
+                                   dlr_url, account, pid, alt_dcs, rpi, tolist, 
+tariff);
 
        octstr_destroy(type);
        octstr_destroy(charset);
Index: gw/smsc/smsc_cimd2.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsc/smsc_cimd2.c,v
retrieving revision 1.1
diff -u -r1.1 smsc_cimd2.c
--- gw/smsc/smsc_cimd2.c        8 Aug 2002 17:44:38 -0000       1.1
+++ gw/smsc/smsc_cimd2.c        28 Aug 2002 15:40:43 -0000
@@ -164,6 +164,10 @@
     { NULL }
 };
 
+static const int chval2(char one, char two) {
+       return (one & 0x0f) * 10 + (two & 0x0f); 
+}
+
 /* Return the index in the parameters array for this parameter id.
  * Return -1 if it is not found. */
 static const int parm_index(int parmno)
@@ -582,6 +586,16 @@
  * a 2-digit year and no DST information.  We can do without.
  */
 
+/* It is essential reference - <T.F>
+ * We use local timezone and century!
+ */
+
+static Octstr *packet_get_time_parm(struct packet *packet, int parmno) {
+       /* Our code should never even try a bad parameter access. */
+       gw_assert(parm_type(parmno) == P_TIME);
+       return packet_get_parm(packet, parmno);
+}
+
 /* Look for a Hex parameter with id 'parmno' in the packet and return
  * its value.  Return NULL if the parameter was not found.  The value
  * is de-hexed. */
@@ -801,6 +815,8 @@
                 octstr_get_cstr(name));
         octstr_destroy(name);
     }
+    info(0, "CIMD2 received: <%s>", octstr_get_cstr(packet->data));
+
 }
 
 /* Table of known error codes */
@@ -1234,6 +1250,11 @@
 
     packet_add_address_parm(packet, P_DESTINATION_ADDRESS, msg->sms.receiver);
 
+       if ( octstr_len(msg->sms.sender) > 0 )
+               packet_add_address_parm(packet,
+                       P_ORIGINATING_ADDRESS, msg->sms.sender);
+       /* T.F if we give orig. addr, let SMSC prepend service nr */
+
     /* CIMD2 interprets the originating address as a sub-address to
      * our connection number (so if the connection is "400" and we
      * fill in "600" as the sender number, the user sees "400600").
@@ -1270,6 +1291,9 @@
     else
        packet_add_int_parm(packet, P_STATUS_REPORT_REQUEST, 0);
 
+    if ( msg->sms.tariff > 0 )
+        packet_add_int_parm(packet, P_TARIFF_CLASS, msg->sms.tariff);
+
     truncated = 0;
 
     spaceleft = 140;
@@ -1401,6 +1425,8 @@
     Octstr *origin = NULL;
     Octstr *UDH = NULL;
     Octstr *text = NULL;
+    Octstr *cimdt = NULL;
+    struct tm tm;
     int DCS;
 
     /* See GSM 03.38.  The bit patterns we can handle are:
@@ -1420,6 +1446,21 @@
     UDH = packet_get_hex_parm(request, P_USER_DATA_HEADER);
     /* Text is either in User Data or User Data Binary field. */
     text = packet_get_sms_parm(request, P_USER_DATA);
+       
+       cimdt = packet_get_time_parm(request, P_MC_TIMESTAMP);
+
+       /* Initialize tm with current time */
+       tm = gw_gmtime(time(NULL));
+       /* extract century */
+       tm.tm_year = (tm.tm_year / 100) * 100;
+       tm.tm_year+= chval2(octstr_get_char(cimdt, 0), octstr_get_char(cimdt, 1));
+       tm.tm_mon  = chval2(octstr_get_char(cimdt, 2), octstr_get_char(cimdt, 3)) - 1;
+       tm.tm_mday = chval2(octstr_get_char(cimdt, 4), octstr_get_char(cimdt, 5));
+       tm.tm_hour = chval2(octstr_get_char(cimdt, 6), octstr_get_char(cimdt, 7));
+       tm.tm_min  = chval2(octstr_get_char(cimdt, 8), octstr_get_char(cimdt, 9));
+       tm.tm_sec  = chval2(octstr_get_char(cimdt,10), octstr_get_char(cimdt,11));
+       /* some problems if timedrift T.F */
+
     if (text != NULL) {
 #if CIMD2_TRACE
         debug("bb.sms.cimd2", 0, "CIMD2 received message.  Text:");
@@ -1469,6 +1510,8 @@
         message->sms.udhdata = UDH;
     }
     message->sms.msgdata = text;
+       message->sms.time = (int)mktime(&tm);
+
     return message;
 
 error:
@@ -1535,6 +1578,7 @@
 retransmit:
     packet_set_send_sequence(request, smsc);
     packet_set_checksum(request);
+    info(0, "CIMD2 sending: <%s>", octstr_get_cstr(request->data));
 
     ret = octstr_write_to_socket(smsc->socket, request->data);
     if (ret < 0)
Index: gw/smsc/smsc_http.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsc/smsc_http.c,v
retrieving revision 1.3
diff -u -r1.3 smsc_http.c
--- gw/smsc/smsc_http.c 20 Aug 2002 21:13:56 -0000      1.3
+++ gw/smsc/smsc_http.c 28 Aug 2002 15:40:43 -0000
@@ -258,6 +258,19 @@
        octstr_format_append(url, "&account=%E:%E", sms->sms.service, 
sms->sms.account);
 
     headers = list_create();
+
+    // if there is tariff information, append it here
+    if(sms->sms.tariff!=0) {
+        Octstr *os;
+        os = octstr_format("%d",sms->sms.tariff);
+       http_header_add(headers, "X-Kannel-Tariff", 
+                       octstr_get_cstr(os));
+       octstr_destroy(os);
+
+       octstr_format_append(url, "&tariff=%d", sms->sms.tariff);
+
+       debug("smsc.http.kannel", 0, "Adding tariff information");
+    }
     debug("smsc.http.kannel", 0, "start request");
     http_start_request(conndata->http_ref, HTTP_METHOD_GET, url, headers, 
                        NULL, 0, sms, NULL);

Reply via email to