Ady Wicaksono Daily Activities

Archive for the ‘kannel’ Category

Patch Kannel to disable enquire_link/enquire_link_resp logging

leave a comment »

Kannel monitoring sometimes needed by administrator. Normally, we will activate debug log to monitor submit_sm, deliver_sm, data_sm, and similar one. But, maybe you got annoyed by enquire_link & enquire_link_resp which normally done almost every 30 seconds or less.

To enable debug mode of kannel but skip enquire_link/resp you need to modify

1. gw/smsc/smpp_pdu.c

Find function name “void smpp_pdu_dump(SMPP_PDU *pdu)” and add this line at the
on the first line of function body code:

// No need enquire_link debug info
if(pdu->type == 0x80000015){
   return;
}

2. gw/smsc/smsc_smpp.c
Find function name “static void send_enquire_link(SMPP *smpp, Connection *conn, long *last_sent)” and add remove or comment this line.

dump_pdu("Sending enquire link:", smpp->conn->id, pdu);

3. gw/smsc/smsc_smpp.c
Find function name “static void io_thread(void *arg)” and find this line

/* Deal with the PDU we just got */
dump_pdu("Got PDU:", smpp->conn->id, pdu);

Change to

Written by adywicaksono

October 11, 2007 at 4:23 pm

Posted in C/C++, kannel

Kannel Mblox Patch

with one comment

Attached is patched taken from kannel mailing list to connect to mblox
see on my previous post to understand this patch



Patch Kannel to connect to mblox

diff -ru gateway-1.3.2/ChangeLog gateway-1.3.2-mblox/ChangeLog
--- gateway-1.3.2/ChangeLog     2004-07-14 10:42:18.000000000 +0000
+++ gateway-1.3.2-mblox/ChangeLog       2004-08-24 08:33:58.000000000 +0000
@@ -1,2 +1,5 @@
-2004-07-14  Stipe Tolj
-    * Making development release 1.3.2.
+2004-07-09 Ian Cass <[EMAIL PROTECTED]
+    * Add mBlox optional parameters for PSMS
+2004-07-09  Stipe Tolj
+    * test/test_headers.c: fixing command line options and argument handling
+      which breaks "make check" target.
diff -ru gateway-1.3.2/VERSION gateway-1.3.2-mblox/VERSION
--- gateway-1.3.2/VERSION       2004-07-14 13:17:26.000000000 +0000
+++ gateway-1.3.2-mblox/VERSION 2004-08-24 08:34:25.000000000 +0000
@@ -1,4 +1,4 @@
-1.3.2
+1.3.2-mblox
 This file contains the version number of the gateway.
 It is stored on the first line. Nothing else should
 be there.
diff -ru gateway-1.3.2/gw/bb_alog.c gateway-1.3.2-mblox/gw/bb_alog.c
--- gateway-1.3.2/gw/bb_alog.c  2004-06-20 21:25:19.000000000 +0000
+++ gateway-1.3.2-mblox/gw/bb_alog.c    2004-08-24 08:32:25.000000000 +0000
@@ -80,6 +80,8 @@
  *   %i - smsc-id
  *   %n - service-name (for MO) or sendsms-user (for MT)
  *   %A  - account
+ *   %O - mBlox billing tag
+ *   %o - mBlox operator tag
  *   %B - billing identifier/information
  *   %p - sender (from)
  *   %P - receiver (to)
@@ -285,6 +287,18 @@
            octstr_append_decimal(result, octstr_len(msg->sms.udhdata));
            break;

+       case 'O':  /* mBlox billing identifier
+           if (octstr_len(msg->sms.mblox_billing)) {
+                octstr_append(result, msg->sms.mblox_billing);
+            }
+            break;
+
+       case 'o':  /* mBlox operator identifier
+           if (octstr_len(msg->sms.mblox_operator)) {
+                octstr_append(result, msg->sms.mblox_operator);
+            }
+            break;
+
        case 'B':  /* billing identifier/information */
            if (octstr_len(msg->sms.binfo)) {
                 octstr_append(result, msg->sms.binfo);
diff -ru gateway-1.3.2/gw/msg-decl.h gateway-1.3.2-mblox/gw/msg-decl.h
--- gateway-1.3.2/gw/msg-decl.h 2004-06-21 21:16:05.000000000 +0000
+++ gateway-1.3.2-mblox/gw/msg-decl.h   2004-08-24 08:32:25.000000000 +0000
@@ -103,6 +103,8 @@
                OCTSTR(charset);
                OCTSTR(boxc_id);
                OCTSTR(binfo);
+               OCTSTR(mblox_billing);
+               OCTSTR(mblox_operator);
                INTEGER(msg_left);
        })

diff -ru gateway-1.3.2/gw/smsbox.c gateway-1.3.2-mblox/gw/smsbox.c
--- gateway-1.3.2/gw/smsbox.c   2004-06-28 10:37:19.000000000 +0000
+++ gateway-1.3.2-mblox/gw/smsbox.c     2004-08-24 08:32:25.000000000 +0000
@@ -429,7 +429,8 @@
                                      int *validity, int *deferred,
                                      int *dlr_mask, Octstr **dlr_url,
                                      Octstr **account, int *pid, int *alt_dcs,
-                                     int *rpi, Octstr **binfo)
+                                     int *rpi, Octstr **binfo,
+                                      Octstr **mblox_billing, Octstr
**mblox_operator)
 {
     Octstr *name, *val;
     long l;
@@ -482,6 +483,14 @@
            *account = octstr_duplicate(val);
            octstr_strip_blanks(*account);
        }
+       else if (octstr_case_compare(name,
octstr_imm("X-Kannel-mBlox-Billing")) == 0) {
+            *mblox_billing = octstr_duplicate(val);
+            octstr_strip_blanks(*mblox_billing);
+       }
+       else if (octstr_case_compare(name,
octstr_imm("X-Kannel-mBlox-Operator")) == 0) {
+            *mblox_operator = octstr_duplicate(val);
+            octstr_strip_blanks(*mblox_operator);
+       }
        else if (octstr_case_compare(name, octstr_imm("X-Kannel-BInfo")) == 0) {
             *binfo = octstr_duplicate(val);
             octstr_strip_blanks(*binfo);
@@ -572,7 +581,8 @@
                                   int *dlr_mask, Octstr **dlr_url,
                                   Octstr **account, int *pid, int *alt_dcs,
                                   int *rpi, List **tolist, Octstr **charset,
-                                  Octstr **binfo)
+                                  Octstr **binfo,
+                                  Octstr **mblox_billing, Octstr
**mblox_operator)
 {                                    

     Octstr *text, *tmp, *tmp2;
@@ -598,6 +608,12 @@
        /* account */
        get_tag(tmp, octstr_imm("account"), account, 0, 0);

+       /* mblox_billing */
+       get_tag(tmp, octstr_imm("mblox_billing"), mblox_billing, 0, 0);
+
+       /* mblox_operator */
+       get_tag(tmp, octstr_imm("mblox_operator"), mblox_operator, 0, 0);
+
        /* binfo */
        get_tag(tmp, octstr_imm("binfo"), binfo, 0, 0);

@@ -778,7 +794,8 @@
                         int validity, int deferred,
                         Octstr *dlr_url, int dlr_mask, int pid, int alt_dcs,
                         int rpi, Octstr *smsc, Octstr *account,
-                        Octstr *charset, Octstr *binfo)
+                        Octstr *charset, Octstr *binfo,
+                         Octstr *mblox_billing, Octstr *mblox_operator)
 {
     msg->sms.msgdata = replytext;
     msg->sms.time = time(NULL);
@@ -920,6 +937,26 @@
         }
     }

+    if (mblox_billing) {
+        if (urltrans_accept_x_kannel_headers(trans)) {
+            msg->sms.mblox_billing = mblox_billing;
+        } else {
+            warning(0, "Tried to change mBlox billing info to '%s', denied.",
+                    octstr_get_cstr(mblox_billing));
+            octstr_destroy(mblox_billing);
+        }
+    }
+
+    if (mblox_operator) {
+        if (urltrans_accept_x_kannel_headers(trans)) {
+            msg->sms.mblox_operator = mblox_operator;
+        } else {
+            warning(0, "Tried to change mBlox operator info to '%s', denied.",
+                    octstr_get_cstr(mblox_operator));
+            octstr_destroy(mblox_operator);
+        }
+    }
+
     if (binfo) {
         if (urltrans_accept_x_kannel_headers(trans)) {
             msg->sms.binfo = binfo;
@@ -1005,7 +1042,7 @@
     unsigned int queued; /* indicate if processes reply is requeued */

     Octstr *reply_body, *charset;
-    Octstr *udh, *from, *to, *dlr_url, *account, *smsc, *binfo;
+    Octstr *udh, *from, *to, *dlr_url, *account, *smsc, *binfo,
*mblox_billing, *mblox_operator;
     int dlr_mask, mclass, mwi, coding, compress, pid, alt_dcs, rpi;
     int validity, deferred;

@@ -1023,7 +1060,7 @@
             break;

        octets = 0;
-    from = to = udh = smsc = dlr_url = account = binfo = charset = NULL;
+    from = to = udh = smsc = dlr_url = account = binfo = charset =
mblox_billing = mblox_operator = NULL;
        mclass = mwi = coding = compress = pid = alt_dcs = rpi = dlr_mask
         = validity = deferred = -1;

@@ -1043,7 +1080,8 @@
                                          &coding, &compress, &validity,
                                          &deferred, &dlr_mask, &dlr_url,
                                          &account, &pid, &alt_dcs, &rpi,
-                                         &binfo);
+                                         &binfo,
+                                          &mblox_billing, &mblox_operator);
             } else if (octstr_case_compare(type, text_plain) == 0) {
                 replytext = octstr_duplicate(reply_body);
                 octstr_destroy(reply_body);
@@ -1053,7 +1091,8 @@
                                          &coding, &compress, &validity,
                                          &deferred, &dlr_mask, &dlr_url,
                                          &account, &pid, &alt_dcs, &rpi,
-                                         &binfo);
+                                         &binfo,
+                                          &mblox_billing, &mblox_operator);
             } else if (octstr_case_compare(type, text_xml) == 0) {
                 replytext = octstr_duplicate(reply_body);
                 octstr_destroy(reply_body);
@@ -1062,7 +1101,8 @@
                         &from, &to, &udh, NULL, NULL, &smsc, &mclass, &mwi,
                         &coding, &compress, &validity, &deferred, &dlr_mask,
                         &dlr_url, &account, &pid, &alt_dcs, &rpi, NULL,
&charset,
-                        &binfo);
+                        &binfo,
+                        &mblox_billing, &mblox_operator);
             } else if (octstr_case_compare(type, octet_stream) == 0) {
                 replytext = octstr_duplicate(reply_body);
                 octstr_destroy(reply_body);
@@ -1073,7 +1113,8 @@
                                          &coding, &compress, &validity,
                                          &deferred, &dlr_mask, &dlr_url,
                                          &account, &pid, &alt_dcs, &rpi,
-                                         &binfo);
+                                         &binfo,
+                                          &mblox_billing, &mblox_operator);
             } else {
                 replytext = octstr_duplicate(reply_couldnotrepresent);
             }
@@ -1093,7 +1134,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, account, charset,
-            binfo);
+            binfo, mblox_billing, mblox_operator);

         if (final_url == NULL)
             final_url = octstr_imm("");
@@ -1346,6 +1387,20 @@
                octstr_get_cstr(os));
            octstr_destroy(os);
        }
+       if (octstr_len(msg->sms.mblox_billing)) {
+           Octstr *os;
+           os = octstr_duplicate(msg->sms.mblox_billing);
+           http_header_add(request_headers, "X-Kannel-mBlox-Billing",
+               octstr_get_cstr(os));
+           octstr_destroy(os);
+       }
+       if (octstr_len(msg->sms.mblox_operator)) {
+           Octstr *os;
+           os = octstr_duplicate(msg->sms.mblox_operator);
+           http_header_add(request_headers, "X-Kannel-mBlox-Operator",
+               octstr_get_cstr(os));
+           octstr_destroy(os);
+       }
        if (octstr_len(msg->sms.binfo)) {
            Octstr *os;
            os = octstr_duplicate(msg->sms.binfo);
@@ -1842,7 +1897,8 @@
                                 int validity, int deferred,
                                 int *status, int dlr_mask, Octstr *dlr_url,
                                 Octstr *account, int pid, int alt_dcs, int rpi,
-                                List *receiver, Octstr *binfo)
+                                List *receiver, Octstr *binfo,
+                                Octstr *mblox_billing, Octstr *mblox_operator)
 {
     Msg *msg = NULL;
     Octstr *newfrom, *returnerror, *receiv;
@@ -2027,6 +2083,12 @@
     msg->sms.msgdata = text ? octstr_duplicate(text) : octstr_create("");
     msg->sms.udhdata = udh ? octstr_duplicate(udh) : octstr_create("");

+    if (octstr_len(mblox_billing))
+        msg->sms.mblox_billing = octstr_duplicate(mblox_billing);
+
+    if (octstr_len(mblox_operator))
+        msg->sms.mblox_operator = octstr_duplicate(mblox_operator);
+
     if (octstr_len(binfo))
         msg->sms.binfo = octstr_duplicate(binfo);

@@ -2337,10 +2399,12 @@
     Octstr *tmp_string;
     Octstr *from, *to, *charset, *text, *udh, *smsc, *dlr_url, *account;
     Octstr *binfo;
+    Octstr *mblox_billing, *mblox_operator;
     int        dlr_mask, mclass, mwi, coding, compress, validity, deferred,
pid;
     int alt_dcs, rpi;

-    from = to = udh = text = smsc = account = dlr_url = charset = binfo = NULL;
+    from = to = udh = text = smsc = account = dlr_url = charset = binfo =
+       mblox_billing = mblox_operator = NULL;
     mclass = mwi = coding = compress = validity = deferred = dlr_mask =
         pid = alt_dcs = rpi = -1;

@@ -2358,6 +2422,8 @@
     from = http_cgi_variable(args, "from");
     to = http_cgi_variable(args, "to");
     account = http_cgi_variable(args, "account");
+    mblox_billing = http_cgi_variable(args, "mblox_billing");
+    mblox_operator = http_cgi_variable(args, "mblox_operator");
     binfo = http_cgi_variable(args, "binfo");
     dlr_url = http_cgi_variable(args, "dlr-url");
     if(dlr_url == NULL) { /* deprecated dlrurl without "-" */
@@ -2428,7 +2494,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, binfo);
+                            pid, alt_dcs, rpi, NULL, binfo, mblox_billing,
mblox_operator);

 }

@@ -2446,6 +2512,7 @@
     Octstr *text_html, *text_plain, *text_wml, *text_xml, *octet_stream;
     Octstr *text;
     Octstr *from, *to, *udh, *smsc, *charset, *dlr_url, *account, *binfo;
+    Octstr *mblox_billing, *mblox_operator;
     int dlr_mask, mclass, mwi, coding, compress, validity, deferred;
     int pid, alt_dcs, rpi;

@@ -2457,7 +2524,8 @@

     user = pass = ret = type = NULL;
     tolist = NULL;
-    from = to = udh = smsc = account = dlr_url = charset = binfo = NULL;
+    from = to = udh = smsc = account = dlr_url = charset = binfo =
+       mblox_billing, mblox_operator = NULL;
     mclass = mwi = coding = compress = validity = deferred = dlr_mask =
         pid = alt_dcs = rpi = -1;

@@ -2473,7 +2541,7 @@
                                  &coding, &compress, &validity,
                                  &deferred, &dlr_mask, &dlr_url,
                                  &account, &pid, &alt_dcs, &rpi,
-                                 &binfo);
+                                 &binfo, &mblox_billing, &mblox_operator);
     } else if (octstr_case_compare(type, text_plain) == 0 ||
                octstr_case_compare(type, octet_stream) == 0) {
        get_x_kannel_from_headers(headers, &from, &to, &udh,
@@ -2481,13 +2549,13 @@
                                  &coding, &compress, &validity,
                                  &deferred, &dlr_mask, &dlr_url,
                                  &account, &pid, &alt_dcs, &rpi,
-                                 &binfo);
+                                 &binfo, &mblox_billing, &mblox_operator);
     } else if (octstr_case_compare(type, text_xml) == 0) {
        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, &charset, &binfo);
+                             &rpi, &tolist, &charset, &binfo, &mblox_billing,
&mblox_operator);
     } else {
        *status = HTTP_BAD_REQUEST;
        ret = octstr_create("Invalid content-type");
@@ -2538,7 +2606,7 @@
                                    udh, smsc, mclass, mwi, coding, compress,
                                    validity, deferred, status, dlr_mask,
                                    dlr_url, account, pid, alt_dcs, rpi, tolist,
-                                   binfo);
+                                   binfo, mblox_billing, mblox_operator);

     }
 error2:
@@ -2550,6 +2618,8 @@
     octstr_destroy(smsc);
     octstr_destroy(dlr_url);
     octstr_destroy(account);
+    octstr_destroy(mblox_billing);
+    octstr_destroy(mblox_operator);
     octstr_destroy(binfo);
 error:
     octstr_destroy(type);
@@ -2574,6 +2644,7 @@
 {
     Octstr *ret, *type, *user, *pass;
     Octstr *from, *to, *udh, *smsc, *charset, *dlr_url, *account, *binfo;
+    Octstr *mblox_billing, *mblox_operator;
     Octstr *output;
     Octstr *method_name;
     XMLRPCDocument *msg;
@@ -2581,7 +2652,8 @@
     int        dlr_mask, mclass, mwi, coding, compress, validity,
        deferred, pid, alt_dcs, rpi;

-    from = to = udh = smsc = account = dlr_url = charset = binfo = NULL;
+    from = to = udh = smsc = account = dlr_url = charset = binfo =
+       mblox_billing = mblox_operator = NULL;
     mclass = mwi = coding = compress = validity = deferred = dlr_mask =
         pid = alt_dcs = rpi = -1;

diff -ru gateway-1.3.2/gw/smsc/smpp_pdu.def
gateway-1.3.2-mblox/gw/smsc/smpp_pdu.def
--- gateway-1.3.2/gw/smsc/smpp_pdu.def  2004-03-27 17:55:43.000000000 +0000
+++ gateway-1.3.2-mblox/gw/smsc/smpp_pdu.def    2004-08-24 08:32:25.000000000
+0000
@@ -253,6 +253,8 @@
     TLV_INTEGER(its_reply_type, 1)
     TLV_OCTETS(its_session_info, 2, 2)
     TLV_OCTETS(ussd_service_op, 1, 1)
+    TLV_OCTETS(mblox_billing, 0, 5)
+    TLV_OCTETS(mblox_operator, 0, 5)
     OPTIONAL_END
 )

@@ -355,6 +357,8 @@
     TLV_OCTETS(network_error_code, 3, 3)
     TLV_INTEGER(message_state, 1)
     TLV_NULTERMINATED(receipted_message_id, 65)
+    TLV_OCTETS(mblox_billing, 0, 5)
+    TLV_OCTETS(mblox_operator, 0, 5)
     OPTIONAL_END
 )

diff -ru gateway-1.3.2/gw/smsc/smpp_pdu_opt.def
gateway-1.3.2-mblox/gw/smsc/smpp_pdu_opt.def
--- gateway-1.3.2/gw/smsc/smpp_pdu_opt.def      2004-03-27 17:55:43.000000000
+0000
+++ gateway-1.3.2-mblox/gw/smsc/smpp_pdu_opt.def        2004-08-24
08:32:25.000000000 +0000
@@ -105,6 +105,8 @@
 #define        SMPP_alert_on_message_delivery          0x130C
 #define        SMPP_its_reply_type                     0x1380
 #define        SMPP_its_session_info                   0x1383
+#define        SMPP_mblox_operator                     0x1402
+#define        SMPP_mblox_billing                      0x1403 

 #endif

diff -ru gateway-1.3.2/gw/smsc/smsc_smpp.c
gateway-1.3.2-mblox/gw/smsc/smsc_smpp.c
--- gateway-1.3.2/gw/smsc/smsc_smpp.c   2004-06-29 08:17:45.000000000 +0000
+++ gateway-1.3.2-mblox/gw/smsc/smsc_smpp.c     2004-08-24 08:32:25.000000000
+0000
@@ -408,6 +408,18 @@
     msg->sms.receiver = pdu->u.deliver_sm.destination_addr;
     pdu->u.deliver_sm.destination_addr = NULL;

+    /* Check for mBlox billing identifier */
+    if (smpp->version > 0x33 && octstr_len(pdu->u.deliver_sm.mblox_billing)) {
+        msg->sms.mblox_billing = pdu->u.deliver_sm.mblox_billing;
+        pdu->u.deliver_sm.mblox_billing = NULL;
+    }
+
+    /* Check for mBlox operator identifier */
+    if (smpp->version > 0x33 && octstr_len(pdu->u.deliver_sm.mblox_operator)) {
+        msg->sms.mblox_operator = pdu->u.deliver_sm.mblox_operator;
+        pdu->u.deliver_sm.mblox_operator = NULL;
+    }
+
     /* SMSCs use service_type for billing information */
     msg->sms.binfo = pdu->u.deliver_sm.service_type;
     pdu->u.deliver_sm.service_type = NULL;
@@ -739,6 +751,16 @@
     if (smpp->version > 0x33 && msg->sms.msg_left > 0)
         pdu->u.submit_sm.more_messages_to_send = 1;

+    /* set mBlox billing identifier */
+    if (smpp->version > 0x33 && octstr_len(msg->sms.mblox_billing)) {
+        pdu->u.submit_sm.mblox_billing =
octstr_duplicate(msg->sms.mblox_billing);
+    }
+
+    /* set mBlox operator identifier */
+    if (smpp->version > 0x33 && octstr_len(msg->sms.mblox_operator)) {
+        pdu->u.submit_sm.mblox_operator =
octstr_duplicate(msg->sms.mblox_operator);
+    }
+
     return pdu;
 }

diff -ru gateway-1.3.2/gw/urltrans.c gateway-1.3.2-mblox/gw/urltrans.c
--- gateway-1.3.2/gw/urltrans.c 2004-03-08 23:12:56.000000000 +0000
+++ gateway-1.3.2-mblox/gw/urltrans.c   2004-08-24 08:32:25.000000000 +0000
@@ -625,6 +625,24 @@
            }
            break;

+       case 'O':  /* mBlox billing identifier */
+           if (octstr_len(request->sms.mblox_billing)) {
+            enc = octstr_duplicate(request->sms.mblox_billing);
+            octstr_url_encode(enc);
+            octstr_append(result, enc);
+            octstr_destroy(enc);
+        }
+        break;
+
+       case 'o':  /* mBlox operator identifier */
+           if (octstr_len(request->sms.mblox_operator)) {
+            enc = octstr_duplicate(request->sms.mblox_operator);
+            octstr_url_encode(enc);
+            octstr_append(result, enc);
+            octstr_destroy(enc);
+        }
+        break;
+
        case 'B':  /* billing identifier/information */
            if (octstr_len(request->sms.binfo)) {
             enc = octstr_duplicate(request->sms.binfo);

Written by adywicaksono

September 30, 2007 at 11:27 am

Posted in kannel

How to patch kannel to support additional vendor specific TLV case study Opera SMPP

with 3 comments

Last time I need to patch my kannel, because mblox (www.mblox.com) use additional specific vendor parameters.
This article will tell you how to do it? This article is based on experience and this email archieve:

http://www.mail-archive.com/devel@kannel.org/msg05603.html

Rather than using Mblox, we will now patch kannel to connect to Opera SMPP, it just another SMPP server
which add some additional parameters:


1. TLV_OPERA_CAMPAIGNID with value 0x1400, type octet string
2. TLV_OPERA_REFERENCE with value 0x1401, type octet string
3. TLV_OPERA_CHANNEL with value 0x1402, type octet string

For more information about Opera SMPP visit http://www.oitg.com/

Ok follow these steps
* Change file gw/bb_alog.c
This file purpose is “encapsulate custom access log logic and escape code parsing”
For our case we want to add 3 additional custom parameters as defined above.
Look at function “static Octstr *get_pattern(…)”, you find that some %x notation is already used, e.g


* %l - log message
* %i - smsc-id
* %n - service-name (for MO) or sendsms-user (for MT)
* %A - account

Now we add unused one, which is:


* %z - Opera campaign id
* %y - Opera reference
* %w - Opera channel

Now, there’s a line around line 301:

/* XXX add more here if needed */

then you add these lines

———– cut here ————

// Since Opera Parameter contains NULL char, we don't need to log 0x00/NULL char
case 'z': /* Opera Campaign Id */
     if (octstr_len(msg->sms.opera_campaign_id)) {
            for (i = 0; i < octstr_len(msg->sms.opera_campaign_id); ++i) {
                if (octstr_get_char(msg->sms.opera_campaign_id, i) != 0x00)
                    octstr_append_char(result, octstr_get_char(msg->sms.opera_campaign_id, i));
            }

     }
     break;
case 'y': /* Opera Reference */
     if (octstr_len(msg->sms.opera_reference)) {
            for (i = 0; i < octstr_len(msg->sms.opera_reference); ++i) {
                if (octstr_get_char(msg->sms.opera_reference, i) != 0x00)
                    octstr_append_char(result, octstr_get_char(msg->sms.opera_reference, i));
            }
     }
     break;
case 'w': /* Opera Channel */
     if (octstr_len(msg->sms.opera_channel)) {
            for (i = 0; i < octstr_len(msg->sms.opera_channel); ++i) {
                if (octstr_get_char(msg->sms.opera_channel, i) != 0x00)
                    octstr_append_char(result, octstr_get_char(msg->sms.opera_channel, i));
            }

     }
     break;

———– cut here ————

* Change file gw/msg-decl.h – a message declarations file

You see these lines?


104 OCTSTR(charset);
105 OCTSTR(boxc_id);
106 OCTSTR(binfo);
107 INTEGER(msg_left);

Just add after INTEGER(msg_left); this line:
——— cut here ———-

OCTSTR(opera_campaign_id);
OCTSTR(opera_reference);
OCTSTR(opera_channel);

——— cut here ———-

OCTSTR declare that we have octet string as additional parameter, meanwhile if you have
additional parameter which is integer value use INTEGER() instead of OCTSTR().

* Change file gw/smsc/smpp_pdu_opt.def, which contains PDU definition

You add these lines before the latest #endif

—- cut here —

#define SMPP_opera_campaign_id 0x1400
#define SMPP_opera_reference 0x1401
#define SMPP_opera_channel 0x1402

—- cut here —

* Change file gw/smsc/smsc_smpp.c (SMPP v3.3 and v3.4 implementation file)

Find function “static Msg *pdu_to_msg()” and find these linese (should be around line no. 458):


458 msg->sms.receiver = pdu->u.deliver_sm.destination_addr;
459 pdu->u.deliver_sm.destination_addr = NULL;
460
461
462 /* SMSCs use service_type for billing information */
463 msg->sms.binfo = pdu->u.deliver_sm.service_type;
464 pdu->u.deliver_sm.service_type = NULL;

You add on lines between 459 and 462 these lines:

—- cut here —-


/* Check for Opera Campaign ID */
if (smpp->version > 0x33 && octstr_len(pdu->u.deliver_sm.opera_campaign_id)) {
    msg->sms.opera_campaign_id = pdu->u.deliver_sm.opera_campaign_id;
    pdu->u.deliver_sm.opera_campaign_id = NULL;
}

/* Check for Opera Reference */
if (smpp->version > 0x33 && octstr_len(pdu->u.deliver_sm.opera_reference)) {
    msg->sms.opera_reference = pdu->u.deliver_sm.opera_reference;
    pdu->u.deliver_sm.opera_reference = NULL;
}

/* Check for Opera Channel */
if (smpp->version > 0x33 && octstr_len(pdu->u.deliver_sm.opera_channel)) {
    msg->sms.opera_channel = pdu->u.deliver_sm.opera_channel;
    pdu->u.deliver_sm.opera_channel = NULL;
}

—- cut here —-

Find also function “static Msg *data_sm_to_msg()” and find these lines inside this function:


637 msg->sms.receiver = pdu->u.data_sm.destination_addr;
638 pdu->u.data_sm.destination_addr = NULL;
639
640 /* SMSCs use service_type for billing information */
641 msg->sms.binfo = pdu->u.data_sm.service_type;
642 pdu->u.data_sm.service_type = NULL;

Should be around lines 637-642, you put the similar lines between 638 – 640 with these lines:

—- cut here —-

/* Check for Opera Campaign ID */
if (smpp->version > 0x33 && octstr_len(pdu->u.data_sm.opera_campaign_id)) {
   msg->sms.opera_campaign_id = pdu->u.data_sm.opera_campaign_id;
   pdu->u.data_sm.opera_campaign_id = NULL;
}

/* Check for Opera Reference */
if (smpp->version > 0x33 && octstr_len(pdu->u.data_sm.opera_reference)) {
   msg->sms.opera_reference = pdu->u.data_sm.opera_reference;
   pdu->u.data_sm.opera_reference = NULL;
}

/* Check for Opera Channel */
if (smpp->version > 0x33 && octstr_len(pdu->u.data_sm.opera_channel)) {
   msg->sms.opera_channel = pdu->u.data_sm.opera_channel;
   pdu->u.data_sm.opera_channel = NULL;
}

—- cut here —-

Find this function “static SMPP_PDU *msg_to_pdu(…)”, and you should see
these lines

    966     /* set more messages to send */
    967     if (smpp->version > 0x33 && msg->sms.msg_left > 0)
    968         pdu->u.submit_sm.more_messages_to_send = 1;

Just add after that part, these lines:
—— cut here —–

    // Each Opera Param STring must be added 0x00 or NULL chars
    /* set Opera campaign id */
    if (smpp->version > 0x33 && octstr_len(msg->sms.opera_campaign_id)) {
        pdu->u.submit_sm.opera_campaign_id = octstr_duplicate(msg->sms.opera_campaign_id);
        // Append NULL
        octstr_append_char(pdu->u.submit_sm.opera_campaign_id,0x00);
    }
    /* set Opera reference */
    if (smpp->version > 0x33 && octstr_len(msg->sms.opera_reference)) {
        pdu->u.submit_sm.opera_reference = octstr_duplicate(msg->sms.opera_reference);
        octstr_append_char(pdu->u.submit_sm.opera_reference,0x00);
    }
    /* set Opera channel */
    if (smpp->version > 0x33 && octstr_len(msg->sms.opera_channel)) {
        pdu->u.submit_sm.opera_channel = octstr_duplicate(msg->sms.opera_channel);
        octstr_append_char(pdu->u.submit_sm.opera_channel,0x00);
    }

—— cut here —–

* Change file gw/urltrans.c (URL translations file)
Find function name: “Octstr *urltrans_fill_escape_codes(Octstr *pattern, Msg *request)”
and find this lines:

    600     case 'B':  /* billing identifier/information */
    601         if (octstr_len(request->sms.binfo)) {
    602             enc = octstr_duplicate(request->sms.binfo);
    603             octstr_url_encode(enc);
    604             octstr_append(result, enc);
    605             octstr_destroy(enc);
    606         }
    607         break;
    608

Just add these lines on those “switch() case:”
—- cut here —-


       case 'z':  /* Opera Campaign Id */
           if (octstr_len(request->sms.opera_campaign_id)) {
               enc = octstr_duplicate(request->sms.opera_campaign_id);
               octstr_url_encode(enc);
               octstr_append(result, enc);
               octstr_destroy(enc);
           }
           break;
        case 'y':  /* Opera Reference */
           if (octstr_len(request->sms.opera_reference)) {
               enc = octstr_duplicate(request->sms.opera_reference);
               octstr_url_encode(enc);
               octstr_append(result, enc);
               octstr_destroy(enc);
           }
           break;
        case 'w':  /* Opera Channel */
           if (octstr_len(request->sms.opera_channel)) {
               enc = octstr_duplicate(request->sms.opera_channel);
               octstr_url_encode(enc);
               octstr_append(result, enc);
               octstr_destroy(enc);
           }
           break;

—- cut here —-
* Change file gw/smsc/smpp_pdu.def (definitions of SMPP PDU structure)

Find this line:

     PDU(submit_sm,
         0x00000004,
         HEADER

After you find that line… scroll down and find first appearance of these lines
after that line above:

         TLV_OCTETS(its_session_info, 2, 2)
         TLV_OCTETS(ussd_service_op, 1, 1)
         OPTIONAL_END

Change those lines become

         TLV_OCTETS(its_session_info, 2, 2)
         TLV_OCTETS(ussd_service_op, 1, 1)
         TLV_OCTETS(opera_campaign_id, 0, 128)
         TLV_OCTETS(opera_reference, 0, 128)
         TLV_OCTETS(opera_channel, 0, 128)
	 OPTIONAL_END

We assume each optional parameters has length between 0-128 octet.

Now continue by finding this line:

     PDU(deliver_sm,
         0x00000005,
         HEADER

After you find that line… scroll down and find first appearance of these lines
after that line:

     TLV_INTEGER(message_state, 1)
     TLV_NULTERMINATED(receipted_message_id, 65)
     OPTIONAL_END

Change it to:

     TLV_INTEGER(message_state, 1)
     TLV_NULTERMINATED(receipted_message_id, 65)
     TLV_OCTETS(opera_campaign_id, 0, 128)
     TLV_OCTETS(opera_reference, 0, 128)
     TLV_OCTETS(opera_channel, 0, 128)
     OPTIONAL_END

Now continue by finding this line:

	PDU(data_sm,
	    0x00000103,
	    HEADER

After you find that line… scroll down and find first appearance of these lines
after that line:

    TLV_INTEGER(language_indicator, 1)
    TLV_INTEGER(its_reply_type, 1)
    TLV_OCTETS(its_session_info, 2, 2)
    OPTIONAL_END

Change it to:

    TLV_INTEGER(language_indicator, 1)
    TLV_INTEGER(its_reply_type, 1)
    TLV_OCTETS(its_session_info, 2, 2)
     TLV_OCTETS(opera_campaign_id, 0, 128)
     TLV_OCTETS(opera_reference, 0, 128)
     TLV_OCTETS(opera_channel, 0, 128)
     OPTIONAL_END

* Change gw/smsbox.c (main program of the smsbox)

We’ll change a lot here :), so be patient
1. Modify function

static void get_x_kannel_from_headers(List *headers, Octstr **from,
                                      Octstr **to, Octstr **udh,
                                      Octstr **user, Octstr **pass,
                                      Octstr **smsc, int *mclass, int *mwi,
                                      int *coding, int *compress,
                                      int *validity, int *deferred,
                                      int *dlr_mask, Octstr **dlr_url,
                                      Octstr **account, int *pid, int *alt_dcs,
                                      int *rpi, Octstr **binfo, int *priority)

Add this additional 3 parameters:
1. Octstr **opera_campaign_id,
2. Octstr **opera_reference,
3. Octstr **opera_channel,

so the latest line changed from

     int *rpi, Octstr **binfo, int *priority)

become

     int *rpi, Octstr **binfo,
     Octstr **opera_campaign_id,
     Octstr **opera_reference,
     Octstr **opera_channel,
     int *priority)

Also still on the same function, inside this function find:


        else if (octstr_case_compare(name, octstr_imm("X-Kannel-BInfo")) == 0) {
            *binfo = octstr_duplicate(val);
            octstr_strip_blanks(*binfo);
        }

Add to the same if-else block these lines:


        else if (octstr_case_compare(name, octstr_imm("X-Kannel-Opera_Campaign_Id")) == 0) {
            *opera_campaign_id = octstr_duplicate(val);
            octstr_strip_blanks(*opera_campaign_id);
        }else if (octstr_case_compare(name, octstr_imm("X-Kannel-Opera_Reference")) == 0) {
            *opera_reference = octstr_duplicate(val);
            octstr_strip_blanks(*opera_reference);
        }else if (octstr_case_compare(name, octstr_imm("X-Kannel-Opera_Channel")) == 0) {
            *opera_channel = octstr_duplicate(val);
            octstr_strip_blanks(*opera_channel);
        }

Scroll down and find this function:

static void get_x_kannel_from_xml(int requesttype , Octstr **type, Octstr **body,
                                  List *headers, Octstr **from,
                                  Octstr **to, Octstr **udh,
                                  Octstr **user, Octstr **pass,
                                  Octstr **smsc, int *mclass, int *mwi,
                                  int *coding, int *compress,
                                  int *validity, int *deferred,
                                  int *dlr_mask, Octstr **dlr_url,
                                  Octstr **account, int *pid, int *alt_dcs,
                                  int *rpi, List **tolist, Octstr **charset,
                                  Octstr **binfo, int *priority)

do the same thing, so

     Octstr **binfo, int *priority)

become

     Octstr **binfo,
     Octstr **opera_campaign_id,
     Octstr **opera_reference,
     Octstr **opera_channel,
     int *priority)

Still on the same function, modify the body of function by finding this line inside
this function:

        /* binfo */
        get_tag(tmp, octstr_imm("binfo"), binfo, 0, 0);

Modify to:

        /* binfo */
        get_tag(tmp, octstr_imm("binfo"), binfo, 0, 0);
        get_tag(tmp, octstr_imm("opera_campaign_id"), opera_campaign_id, 0, 0);
        get_tag(tmp, octstr_imm("opera_reference"), opera_reference, 0, 0);
        get_tag(tmp, octstr_imm("opera_reference"), opera_reference, 0, 0);

Scrolldown and find this function

static void fill_message(Msg *msg, URLTranslation *trans,
                         Octstr *replytext, int octet_stream,
                         Octstr *from, Octstr *to, Octstr *udh,
                         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, Octstr *account,
                         Octstr *charset, Octstr *binfo, int priority)

do the similar thing, so

     Octstr *binfo, int priority)

become

     Octstr *binfo,
     Octstr *opera_campaign_id,
     Octstr *opera_reference,
     Octstr *opera_channel,
     int priority)

Still on the same function, find these lines:

    if (priority != SMS_PARAM_UNDEFINED) {
        if (urltrans_accept_x_kannel_headers(trans))
            msg->sms.priority = priority;
        else
            warning(0, "Tried to change priority to '%d', denied.", priority);
    }

Add after this “if(…){…}” block these lines:

    if (opera_campaign_id) {
        if (urltrans_accept_x_kannel_headers(trans)) {
            msg->sms.opera_campaign_id = opera_campaign_id;
        } else {
            warning(0, "Tried to change opera_campaign_id to '%s', denied.",
                    octstr_get_cstr(opera_campaign_id));
            octstr_destroy(opera_campaign_id);
        }
    }
    if (opera_reference) {
        if (urltrans_accept_x_kannel_headers(trans)) {
            msg->sms.opera_reference = opera_reference;
        } else {
            warning(0, "Tried to change opera_reference to '%s', denied.",
                    octstr_get_cstr(opera_reference));
            octstr_destroy(opera_reference);
        }
    }
    if (opera_channel) {
        if (urltrans_accept_x_kannel_headers(trans)) {
            msg->sms.opera_channel = opera_channel;
        } else {
            warning(0, "Tried to change opera_channel to '%s', denied.",
                    octstr_get_cstr(opera_channel));
            octstr_destroy(opera_channel);
        }
    }

Scroll down find this function: “static void url_result_thread(void *arg)”
On this function, after this variable declaration:

unsigned int queued; /* indicate if processes reply is requeued */

Add this variable declaration:

Octstr *opera_campaign_id, *opera_reference, *opera_channel;

Add after

from = to = udh = smsc = dlr_url = account = binfo = charset = NULL;

this line:

opera_campaign_id = opera_reference = opera_channel = NULL;

Still in this function, modify:

get_x_kannel_from_headers(reply_headers, &from, &to, &udh,
NULL, NULL, &smsc, &mclass, &mwi,
&coding, &compress, &validity,
&deferred, &dlr_mask, &dlr_url,
&account, &pid, &alt_dcs, &rpi,
&binfo, &priority);

to

get_x_kannel_from_headers(reply_headers, &from, &to, &udh,
NULL, NULL, &smsc, &mclass, &mwi,
&coding, &compress, &validity,
&deferred, &dlr_mask, &dlr_url,
&account, &pid, &alt_dcs, &rpi,
&binfo,&opera_campaign_id,&opera_reference,&opera_channel, &priority);

also

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, &charset,
&binfo, &priority);

to

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, &charset,
&binfo, &opera_campaign_id,&opera_reference,&opera_channel,&priority);

Remember we previously change number of parameter for those function.

Scroll down find this function call

fill_message(msg, trans, replytext, octets, from, to, udh, mclass,
mwi, coding, compress, validity, deferred, dlr_url,
dlr_mask, pid, alt_dcs, rpi, smsc, account, charset,
binfo, priority);

change to

fill_message(msg, trans, replytext, octets, from, to, udh, mclass,
mwi, coding, compress, validity, deferred, dlr_url,
dlr_mask, pid, alt_dcs, rpi, smsc, account, charset,
binfo,opera_campaign_id,opera_reference,opera_channel, priority);

Scroll down find this function:
“static int obey_request(Octstr **result, URLTranslation *trans, Msg *msg)”
Inside this function find these lines:

if (octstr_len(msg->sms.binfo)) {
Octstr *os;
os = octstr_duplicate(msg->sms.binfo);
http_header_add(request_headers, "X-Kannel-BInfo",
octstr_get_cstr(os));
octstr_destroy(os);
}

Add after those if(){…} block:


       if (octstr_len(msg->sms.opera_campaign_id)) {
           Octstr *os;
           os = octstr_duplicate(msg->sms.opera_campaign_id);
           http_header_add(request_headers, "X-Kannel-Opera_Campaign_Id",
               octstr_get_cstr(os));
           octstr_destroy(os);
       }
       if (octstr_len(msg->sms.opera_reference)) {
           Octstr *os;
           os = octstr_duplicate(msg->sms.opera_reference);
           http_header_add(request_headers, "X-Kannel-Opera_Reference",
               octstr_get_cstr(os));
           octstr_destroy(os);
       }
       if (octstr_len(msg->sms.opera_channel)) {
           Octstr *os;
           os = octstr_duplicate(msg->sms.opera_channel);
           http_header_add(request_headers, "X-Kannel-Opera_Channel",
               octstr_get_cstr(os));
           octstr_destroy(os);
       }

Scroll down, find this function:

static Octstr *smsbox_req_handle(URLTranslation *t, Octstr *client_ip,
                                 HTTPClient *client,
                                 Octstr *from, Octstr *to, Octstr *text,
                                 Octstr *charset, Octstr *udh, Octstr *smsc,
                                 int mclass, int mwi, int coding, int compress,
                                 int validity, int deferred,
                                 int *status, int dlr_mask, Octstr *dlr_url,
                                 Octstr *account, int pid, int alt_dcs, int rpi,
                                 List *receiver, Octstr *binfo, int priority)

Change it to

static Octstr *smsbox_req_handle(URLTranslation *t, Octstr *client_ip,
                                 HTTPClient *client,
                                 Octstr *from, Octstr *to, Octstr *text,
                                 Octstr *charset, Octstr *udh, Octstr *smsc,
                                 int mclass, int mwi, int coding, int compress,
                                 int validity, int deferred,
                                 int *status, int dlr_mask, Octstr *dlr_url,
                                 Octstr *account, int pid, int alt_dcs, int rpi,
                                 List *receiver, Octstr *binfo,
				      Octstr *opera_campaign_id,
     Octstr *opera_reference,
     Octstr *opera_channel,
int priority)

Still in the same function
Change these lines:

    msg->sms.msgdata = text ? octstr_duplicate(text) : octstr_create("");
    msg->sms.udhdata = udh ? octstr_duplicate(udh) : octstr_create("");

    if (octstr_len(binfo))
        msg->sms.binfo = octstr_duplicate(binfo);

to

    msg->sms.msgdata = text ? octstr_duplicate(text) : octstr_create("");
    msg->sms.udhdata = udh ? octstr_duplicate(udh) : octstr_create("");

    if (octstr_len(binfo))
        msg->sms.binfo = octstr_duplicate(binfo);
    if (octstr_len(opera_campaign_id))
        msg->sms.opera_campaign_id = octstr_duplicate(opera_campaign_id);
    if (octstr_len(opera_reference))
        msg->sms.opera_reference = octstr_duplicate(opera_reference);
    if (octstr_len(opera_channel))
        msg->sms.opera_channel = octstr_duplicate(opera_channel);

Scroll down and find this code:

static Octstr *smsbox_req_sendsms(List *args, Octstr *client_ip, int *status,
                                  HTTPClient *client)

Inside this function Add this variable declaration and set it’s initial value to NULL:

Octstr *opera_campaign_id, *opera_reference, *opera_channel;
 opera_campaign_id = opera_reference = opera_channel = NULL;

Still in the same function, find this code:

binfo = http_cgi_variable(args, "binfo");

Change to

binfo = http_cgi_variable(args, "binfo");
opera_campaign_id = http_cgi_variable(args, "opera_campaign_id");
opera_reference   = http_cgi_variable(args, "opera_reference");
opera_channel     = http_cgi_variable(args, "opera_channel");

Scroll down, find this code:

    return smsbox_req_handle(t, client_ip, client, from, to, text, charset, udh,
                             smsc, mclass, mwi, coding, compress, validity,
                             deferred, status, dlr_mask, dlr_url, account,
                             pid, alt_dcs, rpi, NULL, binfo, priority);

And change to

    return smsbox_req_handle(t, client_ip, client, from, to, text, charset, udh,
                             smsc, mclass, mwi, coding, compress, validity,
                             deferred, status, dlr_mask, dlr_url, account,
                             pid, alt_dcs, rpi, NULL, binfo,opera_campaign_id,opera_reference,opera_channel, priority);

Scroll down, find


static Octstr *smsbox_sendsms_post(List *headers, Octstr *body,
                                   Octstr *client_ip, int *status,
                                   HTTPClient *client)

Inside this function Add this variable declaration and set it’s initial value to NULL:

Octstr *opera_campaign_id, *opera_reference, *opera_channel;
 opera_campaign_id = opera_reference = opera_channel = NULL;

Still in this function, modify:

                get_x_kannel_from_headers(reply_headers, &from, &to, &udh,
                                          NULL, NULL, &smsc, &mclass, &mwi,
                                          &coding, &compress, &validity,
                                          &deferred, &dlr_mask, &dlr_url,
                                          &account, &pid, &alt_dcs, &rpi,
                                          &binfo, &priority);

to

                get_x_kannel_from_headers(reply_headers, &from, &to, &udh,
                                          NULL, NULL, &smsc, &mclass, &mwi,
                                          &coding, &compress, &validity,
                                          &deferred, &dlr_mask, &dlr_url,
                                          &account, &pid, &alt_dcs, &rpi,
                                          &binfo,&opera_campaign_id,&opera_reference,&opera_channel, &priority);

also

                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, &charset,
                        &binfo, &priority);

to

                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, &charset,
                        &binfo, &opera_campaign_id,&opera_reference,&opera_channel,&priority);

Scroll down, find this code:

            ret = smsbox_req_handle(t, client_ip, client, from, to, body, charset,
                                    udh, smsc, mclass, mwi, coding, compress,
                                    validity, deferred, status, dlr_mask,
                                    dlr_url, account, pid, alt_dcs, rpi, tolist,
                                    binfo, priority);

Change to

    return smsbox_req_handle(t, client_ip, client, from, to, text, charset, udh,
                             smsc, mclass, mwi, coding, compress, validity,
                             deferred, status, dlr_mask, dlr_url, account,
                             pid, alt_dcs, rpi, NULL, binfo,opera_campaign_id,opera_reference,opera_channel, priority);

Scroll down, find this code:

    octstr_destroy(account);
    octstr_destroy(binfo);

Change to:

    octstr_destroy(account);
    octstr_destroy(binfo);
    octstr_destroy(opera_campaign_id);
    octstr_destroy(opera_reference);
    octstr_destroy(opera_channel);

Scroll down, find this code:

static Octstr *smsbox_xmlrpc_post(List *headers, Octstr *body,
                                  Octstr *client_ip, int *status)

Inside this function Add this variable declaration and set it’s initial value to NULL:

Octstr *opera_campaign_id, *opera_reference, *opera_channel;
 opera_campaign_id = opera_reference = opera_channel = NULL;

Now, compile:

sh configure --disable-ssl --with-mysql

Good luck 🙂

Written by adywicaksono

September 30, 2007 at 8:26 am

Posted in kannel, Linux, Programming