Archive for September 2007
OMA DS OTA Setting
Maybe you have ever visited www.zyb.com, this website provide backup and synchronization between your sms, calendar, notepad, phonebook with servers. Normally, when you register their server will send you a setting over SMS. Not every mobile phone support it, only mobile phone with OMA DS compliant. For this OMA DS Over The Air setting, I’m selling library (a Java class library) which could build OMA Data Synchronization Over The Air setting.
Please contact me over email at ady.wicaksono at gmail.com, just replace at with @.
Thanks
Kannel Mblox Patch
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);
How to patch kannel to support additional vendor specific TLV case study Opera SMPP
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
iaitbsg.com MX use google mail
Just now, I configure iaitbsg.com to use googlemail, yes since it’s free and has big mailbox.
> iaitbsg.com
Server: resolver1.opendns.com
Address: 208.67.222.222
Non-authoritative answer:
iaitbsg.com MX preference = 1, mail exchanger = aspmx.l.google.com
iaitbsg.com MX preference = 5, mail exchanger = alt2.aspmx.l.google.com
iaitbsg.com MX preference = 5, mail exchanger = alt1.aspmx.l.google.com
iaitbsg.com MX preference = 10, mail exchanger = aspmx2.googlemail.com
iaitbsg.com MX preference = 10, mail exchanger = aspmx5.googlemail.com
iaitbsg.com MX preference = 10, mail exchanger = aspmx4.googlemail.com
iaitbsg.com MX preference = 10, mail exchanger = aspmx3.googlemail.com
anyone want to have email @iaitbsg.com?