Ady Wicaksono Daily Activities

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

3 Responses

Subscribe to comments with RSS.

  1. nice work ady😉

    James E

    October 2, 2007 at 7:12 am

  2. Good day!,

    name

    September 1, 2008 at 1:55 am

  3. Hi,

    We need Mythum patch also.
    Mythum uses 0×2150, type octet string for operator id

    shahzad

    December 24, 2008 at 11:00 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: