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