00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 #include <sys/types.h>
00076 #include <sys/socket.h>
00077 #include <unistd.h>
00078 #include <errno.h>
00079 #include <time.h>
00080 #include <limits.h>
00081 #include <float.h>
00082
00083 #include "gwlib/gwlib.h"
00084 #include "smscconn.h"
00085 #include "smscconn_p.h"
00086 #include "bb_smscconn_cb.h"
00087 #include "msg.h"
00088 #include "sms.h"
00089 #include "emimsg.h"
00090 #include "dlr.h"
00091 #include "alt_charsets.h"
00092
00093 #define EMI2_MAX_TRN 100
00094
00095 typedef struct privdata {
00096 Octstr *name;
00097 gw_prioqueue_t *outgoing_queue;
00098 long receiver_thread;
00099 long sender_thread;
00100 int shutdown;
00101 int listening_socket;
00102 int send_socket;
00103 int port, alt_port;
00104 int our_port;
00105
00106 int rport;
00107 Octstr *allow_ip, *deny_ip;
00108 Octstr *host, *alt_host, *username, *password;
00109 Octstr *my_number;
00110 int unacked;
00111 struct {
00112 time_t sendtime;
00113
00114 int sendtype;
00115 Msg *sendmsg;
00116 } slots[EMI2_MAX_TRN];
00117 int keepalive;
00118 int flowcontrol;
00119 int waitack;
00120 int waitack_expire;
00121 int window;
00122 int can_write;
00123 int priv_nexttrn;
00124
00125
00126 time_t last_activity_time;
00127
00128
00129 time_t check_time;
00130 int idle_timeout;
00131
00132 Octstr *npid;
00133 Octstr *nadc;
00134 int alt_charset;
00135 } PrivData;
00136
00137 typedef enum {
00138 EMI2_SENDREQ,
00139 EMI2_SMSCREQ,
00140 EMI2_CONNERR,
00141 EMI2_TIMEOUT,
00142 } EMI2Event;
00143
00144 #define PRIVDATA(conn) ((PrivData *)((conn)->data))
00145
00146 #define SLOTBUSY(conn,i) (PRIVDATA(conn)->slots[(i)].sendtime != 0)
00147
00148 #define CONNECTIONIDLE(conn) \
00149 ((PRIVDATA(conn)->unacked == 0) && \
00150 (PRIVDATA(conn)->idle_timeout ? \
00151 (PRIVDATA(conn)->last_activity_time + PRIVDATA(conn)->idle_timeout) <= time(0):0))
00152
00153 #define emi2_can_send(conn) \
00154 ((PRIVDATA(conn)->can_write || !PRIVDATA(conn)->flowcontrol) && \
00155 (PRIVDATA(conn)->unacked < PRIVDATA(conn)->window) && \
00156 (!PRIVDATA(conn)->shutdown))
00157
00158 #define emi2_needs_keepalive(conn) \
00159 (emi2_can_send(conn) && \
00160 (PRIVDATA(conn)->keepalive > 0) && \
00161 (time(NULL) > (PRIVDATA(conn)->last_activity_time + PRIVDATA(conn)->keepalive)))
00162
00163
00164
00165
00166 static int emi2_emimsg_send(SMSCConn *conn, Connection *server, struct emimsg *emimsg)
00167 {
00168 int result = emimsg_send(server, emimsg, PRIVDATA(conn)->name);
00169
00170 if (result >= 0 && emimsg->or == 'O' && ( emimsg->ot == 31 || emimsg->ot == 51)) {
00171 PRIVDATA(conn)->last_activity_time = time (NULL);
00172 }
00173
00174 return result;
00175 }
00176
00177
00178
00179
00180
00181
00182 static int wait_for_ack(PrivData *privdata, Connection *server, int ot, int t)
00183 {
00184 time_t timeout_time;
00185 int time_left;
00186 Octstr *str;
00187 struct emimsg *emimsg;
00188
00189 timeout_time = time(NULL) + t;
00190 while (1) {
00191 str = conn_read_packet(server, 2, 3);
00192 if (conn_eof(server)) {
00193 error(0, "EMI2[%s]: connection closed in wait_for_ack",
00194 octstr_get_cstr(privdata->name));
00195 return -1;
00196 }
00197 if (conn_error(server)) {
00198 error(0, "EMI2[%s]: connection error in wait_for_ack",
00199 octstr_get_cstr(privdata->name));
00200 return -1;
00201 }
00202 if (str) {
00203 emimsg = get_fields(str, privdata->name);
00204 if (emimsg == NULL) {
00205 octstr_destroy(str);
00206 continue;
00207 }
00208 if (emimsg->ot == ot && emimsg->trn == 0 && emimsg->or == 'R') {
00209 octstr_destroy(str);
00210 break;
00211 }
00212 warning(0, "EMI2[%s]: ignoring message %s while waiting for ack to"
00213 "ot:%d trn:%d", octstr_get_cstr(privdata->name),
00214 octstr_get_cstr(str), ot, 0);
00215 emimsg_destroy(emimsg);
00216 octstr_destroy(str);
00217 }
00218 time_left = timeout_time - time(NULL);
00219 if (time_left < 0 || privdata->shutdown)
00220 return 0;
00221 conn_wait(server, time_left);
00222 }
00223 if (octstr_get_char(emimsg->fields[0], 0) == 'N') {
00224 emimsg_destroy(emimsg);
00225 return -2;
00226 }
00227 emimsg_destroy(emimsg);
00228 return 1;
00229 }
00230
00231
00232 static struct emimsg *make_emi31(PrivData *privdata, int trn)
00233 {
00234 struct emimsg *emimsg;
00235
00236 if(octstr_len(privdata->username) || octstr_len(privdata->my_number)) {
00237 emimsg = emimsg_create_op(31, trn, privdata->name);
00238 if(octstr_len(privdata->username)) {
00239 emimsg->fields[0] = octstr_duplicate(privdata->username);
00240 } else {
00241 emimsg->fields[0] = octstr_duplicate(privdata->my_number);
00242 }
00243 emimsg->fields[1] = octstr_create("0539");
00244 return emimsg;
00245 } else {
00246 return NULL;
00247 }
00248 }
00249
00250
00251 static struct emimsg *make_emi60(PrivData *privdata)
00252 {
00253 struct emimsg *emimsg;
00254
00255 emimsg = emimsg_create_op(60, 0, privdata->name);
00256 emimsg->fields[E60_OADC] = octstr_duplicate(privdata->username);
00257 emimsg->fields[E60_OTON] = octstr_create("6");
00258 emimsg->fields[E60_ONPI] = octstr_create("5");
00259 emimsg->fields[E60_STYP] = octstr_create("1");
00260 emimsg->fields[E60_PWD] = octstr_duplicate(privdata->password);
00261 octstr_binary_to_hex(emimsg->fields[E60_PWD], 1);
00262 emimsg->fields[E60_VERS] = octstr_create("0100");
00263 return emimsg;
00264 }
00265
00266
00267 static Connection *open_send_connection(SMSCConn *conn)
00268 {
00269 PrivData *privdata = conn->data;
00270 int result, alt_host, do_alt_host;
00271 struct emimsg *emimsg;
00272 Connection *server;
00273 Msg *msg;
00274 int connect_error = 0;
00275 int wait_ack = 0;
00276
00277 do_alt_host = octstr_len(privdata->alt_host) != 0 || privdata->alt_port != 0;
00278
00279 alt_host = 0;
00280
00281 mutex_lock(conn->flow_mutex);
00282 conn->status = SMSCCONN_RECONNECTING;
00283 mutex_unlock(conn->flow_mutex);
00284
00285 while (!privdata->shutdown) {
00286
00287 while ((msg = gw_prioqueue_remove(privdata->outgoing_queue))) {
00288 bb_smscconn_send_failed(conn, msg,
00289 SMSCCONN_FAILED_TEMPORARILY, NULL);
00290 }
00291
00292
00293 if (alt_host == 0 && connect_error) {
00294 error(0, "EMI2[%s]: Couldn't connect to SMS center (retrying in %ld seconds).",
00295 octstr_get_cstr(privdata->name), conn->reconnect_delay);
00296 gwthread_sleep(conn->reconnect_delay);
00297 }
00298
00299 if (alt_host != 1) {
00300 info(0, "EMI2[%s]: connecting to Primary SMSC",
00301 octstr_get_cstr(privdata->name));
00302 mutex_lock(conn->flow_mutex);
00303 octstr_destroy(conn->name);
00304 conn->name = octstr_format("EMI2:%S:%d:%S", privdata->host, privdata->port, privdata->username ? privdata->username : octstr_imm("null"));
00305 mutex_unlock(conn->flow_mutex);
00306 server = conn_open_tcp_with_port(privdata->host, privdata->port,
00307 privdata->our_port,
00308 conn->our_host);
00309 if(do_alt_host)
00310 alt_host=1;
00311 else
00312 alt_host=0;
00313 } else {
00314 info(0, "EMI2[%s]: connecting to Alternate SMSC",
00315 octstr_get_cstr(privdata->name));
00316
00317 mutex_lock(conn->flow_mutex);
00318 octstr_destroy(conn->name);
00319 conn->name = octstr_format("EMI2:%S:%d:%S", octstr_len(privdata->alt_host) ? privdata->alt_host : privdata->host,
00320 privdata->alt_port ? privdata->alt_port : privdata->port,
00321 privdata->username ? privdata->username : octstr_imm("null"));
00322 mutex_unlock(conn->flow_mutex);
00323 server = conn_open_tcp_with_port(
00324 (octstr_len(privdata->alt_host) ? privdata->alt_host : privdata->host),
00325 (privdata->alt_port ? privdata->alt_port : privdata->port),
00326 privdata->our_port, conn->our_host);
00327 alt_host=0;
00328 }
00329 if (privdata->shutdown) {
00330 conn_destroy(server);
00331 return NULL;
00332 }
00333 if (server == NULL) {
00334 error(0, "EMI2[%s]: opening TCP connection to %s failed",
00335 octstr_get_cstr(privdata->name),
00336 octstr_get_cstr(privdata->host));
00337 connect_error = 1;
00338 continue;
00339 }
00340
00341 if (privdata->username && privdata->password) {
00342 emimsg = make_emi60(privdata);
00343 emi2_emimsg_send(conn, server, emimsg);
00344 emimsg_destroy(emimsg);
00345 wait_ack = privdata->waitack > 30 ? privdata->waitack : 30;
00346 result = wait_for_ack(privdata, server, 60, wait_ack);
00347 if (result == -2) {
00348
00349
00350
00351
00352 error(0, "EMI2[%s]: Server rejected our login",
00353 octstr_get_cstr(privdata->name));
00354 conn_destroy(server);
00355 connect_error = 1;
00356 continue;
00357 } else if (result == 0) {
00358 error(0, "EMI2[%s]: Got no reply to login attempt "
00359 "within %d seconds", octstr_get_cstr(privdata->name),
00360 wait_ack);
00361 conn_destroy(server);
00362 connect_error = 1;
00363 continue;
00364 } else if (result == -1) {
00365 conn_destroy(server);
00366 connect_error = 1;
00367 continue;
00368 }
00369 privdata->last_activity_time = 0;
00370 privdata->can_write = 1;
00371 }
00372
00373 mutex_lock(conn->flow_mutex);
00374 conn->status = SMSCCONN_ACTIVE;
00375 conn->connect_time = time(NULL);
00376 mutex_unlock(conn->flow_mutex);
00377 bb_smscconn_connected(conn);
00378 return server;
00379 }
00380 return NULL;
00381 }
00382
00383
00384 static void pack_7bit(Octstr *str)
00385 {
00386 Octstr *result;
00387 int len, i;
00388 int numbits, value;
00389
00390 result = octstr_create("0");
00391 len = octstr_len(str);
00392 value = 0;
00393 numbits = 0;
00394 for (i = 0; i < len; i++) {
00395 value += octstr_get_char(str, i) << numbits;
00396 numbits += 7;
00397 if (numbits >= 8) {
00398 octstr_append_char(result, value & 0xff);
00399 value >>= 8;
00400 numbits -= 8;
00401 }
00402 }
00403 if (numbits > 0)
00404 octstr_append_char(result, value);
00405 octstr_set_char(result, 0, (len * 7 + 3) / 4);
00406 octstr_delete(str, 0, LONG_MAX);
00407 octstr_append(str, result);
00408 octstr_binary_to_hex(str, 1);
00409 octstr_destroy(result);
00410 }
00411
00412
00413 static struct emimsg *msg_to_emimsg(Msg *msg, int trn, PrivData *privdata)
00414 {
00415 Octstr *str;
00416 struct emimsg *emimsg;
00417 int dcs;
00418 struct tm tm;
00419 char p[20];
00420
00421 emimsg = emimsg_create_op(51, trn, privdata->name);
00422 str = octstr_duplicate(msg->sms.sender);
00423 if(octstr_get_char(str,0) == '+') {
00424
00425 if (!octstr_check_range(str, 1, 256, gw_isdigit)) {
00426
00427 charset_utf8_to_gsm(str);
00428 octstr_truncate(str, 11);
00429 emimsg->fields[E50_OTOA] = octstr_create("5039");
00430 pack_7bit(str);
00431 }
00432 else {
00433
00434 emimsg->fields[E50_OTOA] = octstr_create("1139");
00435 octstr_delete(str, 0, 1);
00436 octstr_truncate(str, 22);
00437 }
00438 }
00439 else {
00440 if (!octstr_check_range(str, 0, 256, gw_isdigit)) {
00441
00442 charset_utf8_to_gsm(str);
00443 octstr_truncate(str, 11);
00444 emimsg->fields[E50_OTOA] = octstr_create("5039");
00445 pack_7bit(str);
00446 }
00447 }
00448
00449 emimsg->fields[E50_OADC] = str;
00450
00451
00452 if (msg->sms.pid >= 0) {
00453 emimsg->fields[E50_RPID] = octstr_format("%04d", msg->sms.pid);
00454 }
00455
00456
00457 if (msg->sms.rpi == 2)
00458 emimsg->fields[E50_RPI] = octstr_create("2");
00459 else if (msg->sms.rpi > 0)
00460 emimsg->fields[E50_RPI] = octstr_create("1");
00461
00462 str = octstr_duplicate(msg->sms.receiver);
00463 if(octstr_get_char(str,0) == '+') {
00464
00465
00466
00467
00468 octstr_delete(str, 0, 1);
00469 octstr_insert_data(str, 0, "00",2);
00470 }
00471 octstr_truncate(str, 16);
00472 emimsg->fields[E50_ADC] = str;
00473
00474 emimsg->fields[E50_XSER] = octstr_create("");
00475
00476
00477 if (octstr_len(msg->sms.udhdata)) {
00478 str = octstr_create("");
00479 octstr_append_char(str, 0x01);
00480 octstr_append_char(str, octstr_len(msg->sms.udhdata));
00481 octstr_append(str, msg->sms.udhdata);
00482 octstr_binary_to_hex(str, 1);
00483 octstr_append(emimsg->fields[E50_XSER], str);
00484 octstr_destroy(str);
00485 }
00486
00487
00488 dcs = fields_to_dcs(msg, msg->sms.alt_dcs);
00489 if (dcs != 0 && dcs != 4) {
00490 str = octstr_create("");
00491 octstr_append_char(str, 0x02);
00492 octstr_append_char(str, 1);
00493 octstr_append_char(str, dcs);
00494 octstr_binary_to_hex(str, 1);
00495 octstr_append(emimsg->fields[E50_XSER], str);
00496 octstr_destroy(str);
00497 }
00498
00499
00500 if (octstr_len(msg->sms.binfo)) {
00501 str = octstr_create("");
00502 octstr_append_char(str, 0x0c);
00503 octstr_append_char(str, octstr_len(msg->sms.binfo));
00504 octstr_append(str, msg->sms.binfo);
00505 octstr_binary_to_hex(str, 1);
00506 octstr_append(emimsg->fields[E50_XSER], str);
00507 octstr_destroy(str);
00508 }
00509
00510 if (msg->sms.coding == DC_8BIT || msg->sms.coding == DC_UCS2) {
00511 emimsg->fields[E50_MT] = octstr_create("4");
00512 emimsg->fields[E50_MCLS] = octstr_create("1");
00513 str = octstr_duplicate(msg->sms.msgdata);
00514 emimsg->fields[E50_NB] =
00515 octstr_format("%04d", 8 * octstr_len(str));
00516 octstr_binary_to_hex(str, 1);
00517 emimsg->fields[E50_TMSG] = str;
00518 }
00519 else {
00520 emimsg->fields[E50_MT] = octstr_create("3");
00521 str = octstr_duplicate(msg->sms.msgdata);
00522 charset_utf8_to_gsm(str);
00523
00524
00525
00526
00527 if (privdata->alt_charset == EMI_NRC_ISO_21)
00528 charset_gsm_to_nrc_iso_21_german(str);
00529
00530
00531
00532 if (charset_gsm_truncate(str, 160))
00533 error(0, "EMI2[%s]: Message to send is longer "
00534 "than 160 gsm characters",
00535 octstr_get_cstr(privdata->name));
00536 octstr_binary_to_hex(str, 1);
00537 emimsg->fields[E50_AMSG] = str;
00538 }
00539
00540 if (msg->sms.validity >= 0) {
00541 tm = gw_localtime(time(NULL) + msg->sms.validity * 60);
00542 sprintf(p, "%02d%02d%02d%02d%02d",
00543 tm.tm_mday, tm.tm_mon + 1, tm.tm_year % 100,
00544 tm.tm_hour, tm.tm_min);
00545 str = octstr_create(p);
00546 emimsg->fields[E50_VP] = str;
00547 }
00548 if (msg->sms.deferred >= 0) {
00549 str = octstr_create("1");
00550 emimsg->fields[E50_DD] = str;
00551 tm = gw_localtime(time(NULL) + msg->sms.deferred * 60);
00552 sprintf(p, "%02d%02d%02d%02d%02d",
00553 tm.tm_mday, tm.tm_mon + 1, tm.tm_year % 100,
00554 tm.tm_hour, tm.tm_min);
00555 str = octstr_create(p);
00556 emimsg->fields[E50_DDT] = str;
00557 }
00558
00559
00560
00561
00562
00563 if (DLR_IS_ENABLED_DEVICE(msg->sms.dlr_mask)) {
00564 emimsg->fields[E50_NRQ] = octstr_create("1");
00565 emimsg->fields[E50_NT] = octstr_create("");
00566 octstr_append_decimal(emimsg->fields[E50_NT], 3 + (DLR_IS_BUFFERED(msg->sms.dlr_mask) ? 4 : 0));
00567 if (privdata->npid)
00568 emimsg->fields[E50_NPID] = octstr_duplicate(privdata->npid);
00569 if (privdata->nadc)
00570 emimsg->fields[E50_NADC] = octstr_duplicate(privdata->nadc);
00571 }
00572 return emimsg;
00573 }
00574
00575
00576
00577
00578 static int handle_operation(SMSCConn *conn, Connection *server,
00579 struct emimsg *emimsg)
00580 {
00581 struct emimsg *reply;
00582 Octstr *tempstr, *xser;
00583 int type, len;
00584 Msg *msg = NULL;
00585 struct universaltime unitime;
00586 int st_code;
00587 PrivData *privdata = conn->data;
00588
00589
00590 switch(emimsg->ot) {
00591
00592
00593
00594
00595
00596 case 01:
00597 msg = msg_create(sms);
00598 if (emimsg->fields[E01_AMSG] == NULL)
00599 emimsg->fields[E01_AMSG] = octstr_create("");
00600 else if (octstr_hex_to_binary(emimsg->fields[E01_AMSG]) == -1)
00601 warning(0, "EMI2[%s]: Couldn't decode message text",
00602 octstr_get_cstr(privdata->name));
00603
00604 if (emimsg->fields[E01_MT] == NULL) {
00605 warning(0, "EMI2[%s]: required field MT missing",
00606 octstr_get_cstr(privdata->name));
00607
00608
00609 emimsg->fields[E01_MT] = octstr_create("3");
00610 }
00611
00612 if (octstr_get_char(emimsg->fields[E01_MT], 0) == '3') {
00613 msg->sms.msgdata = emimsg->fields[E01_AMSG];
00614 emimsg->fields[E01_AMSG] = NULL;
00615
00616
00617 if (privdata->alt_charset == EMI_NRC_ISO_21)
00618 charset_nrc_iso_21_german_to_gsm(msg->sms.msgdata);
00619
00620 charset_gsm_to_utf8(msg->sms.msgdata);
00621 }
00622 else {
00623 error(0, "EMI2[%s]: MT == %s isn't supported for operation type 01",
00624 octstr_get_cstr(privdata->name),
00625 octstr_get_cstr(emimsg->fields[E01_MT]));
00626 msg->sms.msgdata = octstr_create("");
00627 }
00628
00629 msg->sms.sender = octstr_duplicate(emimsg->fields[E01_OADC]);
00630 if (msg->sms.sender == NULL) {
00631 warning(0, "EMI2[%s]: Empty sender field in received message",
00632 octstr_get_cstr(privdata->name));
00633 msg->sms.sender = octstr_create("");
00634 }
00635
00636 if(octstr_len(PRIVDATA(conn)->my_number)) {
00637 msg->sms.receiver = octstr_duplicate(PRIVDATA(conn)->my_number);
00638 }
00639 else {
00640 msg->sms.receiver = octstr_duplicate(emimsg->fields[E01_ADC]);
00641 }
00642 if (msg->sms.receiver == NULL) {
00643 warning(0, "EMI2[%s]: Empty receiver field in received message",
00644 octstr_get_cstr(privdata->name));
00645 msg->sms.receiver = octstr_create("");
00646 }
00647
00648
00649 time(&msg->sms.time);
00650
00651 msg->sms.smsc_id = octstr_duplicate(conn->id);
00652 bb_smscconn_receive(conn, msg);
00653 reply = emimsg_create_reply(01, emimsg->trn, 1, privdata->name);
00654 if (emi2_emimsg_send(conn, server, reply) < 0) {
00655 emimsg_destroy(reply);
00656 return -1;
00657 }
00658 emimsg_destroy(reply);
00659 return 1;
00660
00661
00662
00663
00664
00665 case 52:
00666 msg = msg_create(sms);
00667
00668 if (emimsg->fields[E50_AMSG] == NULL)
00669 emimsg->fields[E50_AMSG] = octstr_create("");
00670 else if (octstr_hex_to_binary(emimsg->fields[E50_AMSG]) == -1)
00671 warning(0, "EMI2[%s]: Couldn't decode message text",
00672 octstr_get_cstr(privdata->name));
00673
00674
00675 xser = emimsg->fields[E50_XSER];
00676 while (octstr_len(xser) > 0) {
00677 int tempint;
00678 tempstr = octstr_copy(xser, 0, 4);
00679 if (octstr_hex_to_binary(tempstr) == -1)
00680 error(0, "EMI2[%s]: Invalid XSer",
00681 octstr_get_cstr(privdata->name));
00682 type = octstr_get_char(tempstr, 0);
00683 len = octstr_get_char(tempstr, 1);
00684 octstr_destroy(tempstr);
00685 if (len < 0) {
00686 error(0, "EMI2[%s]: Malformed emi XSer field",
00687 octstr_get_cstr(privdata->name));
00688 break;
00689 }
00690
00691
00692 switch (type) {
00693
00694 case 0x01:
00695 tempstr = octstr_copy(xser, 4, len * 2);
00696 if (octstr_hex_to_binary(tempstr) == -1)
00697 error(0, "EMI2[%s]: Invalid UDH contents",
00698 octstr_get_cstr(privdata->name));
00699 msg->sms.udhdata = tempstr;
00700 break;
00701
00702 case 0x02:
00703 tempstr = octstr_copy(xser, 4, 2);
00704 octstr_hex_to_binary(tempstr);
00705 tempint = octstr_get_char(tempstr, 0);
00706 octstr_destroy(tempstr);
00707 if (!dcs_to_fields(&msg, tempint)) {
00708 error(0, "EMI2[%s]: Invalid DCS received",
00709 octstr_get_cstr(privdata->name));
00710
00711 dcs_to_fields(&msg, 0);
00712 }
00713 break;
00714
00715
00716
00717
00718
00719
00720
00721 case 0x0c:
00722 tempstr = octstr_copy(xser, 4, len * 2);
00723 if (octstr_hex_to_binary(tempstr) == -1) {
00724 error(0, "EMI2[%s] Invalid XSer 0c billing identifier <%s>",
00725 octstr_get_cstr(privdata->name),
00726 octstr_get_cstr(tempstr));
00727 } else {
00728 msg->sms.binfo = tempstr;
00729 }
00730 break;
00731
00732 case 0x0d:
00733 tempstr = octstr_copy(xser, 4, 2);
00734 octstr_hex_to_binary(tempstr);
00735 tempint = octstr_get_char(tempstr, 0);
00736 octstr_destroy(tempstr);
00737 if (tempint)
00738 info(0, "EMI2[%s]: Single shot indicator set.",
00739 octstr_get_cstr(privdata->name));
00740 break;
00741
00742
00743
00744 default:
00745 warning(0, "EMI2[%s]: Unsupported EMI XSer field %d",
00746 octstr_get_cstr(privdata->name), type);
00747 break;
00748 }
00749
00750 octstr_delete(xser, 0, 2 * len + 4);
00751 }
00752
00753 if (emimsg->fields[E50_MT] == NULL) {
00754 warning(0, "EMI2[%s]: required field MT missing",
00755 octstr_get_cstr(privdata->name));
00756
00757
00758 emimsg->fields[E50_MT] = octstr_create("3");
00759 }
00760 if (octstr_get_char(emimsg->fields[E50_MT], 0) == '3') {
00761 msg->sms.msgdata = emimsg->fields[E50_AMSG];
00762 emimsg->fields[E50_AMSG] = NULL;
00763
00764
00765 if (privdata->alt_charset == EMI_NRC_ISO_21)
00766 charset_nrc_iso_21_german_to_gsm(msg->sms.msgdata);
00767
00768 charset_gsm_to_utf8(msg->sms.msgdata);
00769 }
00770 else if (octstr_get_char(emimsg->fields[E50_MT], 0) == '4') {
00771 msg->sms.msgdata = emimsg->fields[E50_TMSG];
00772 emimsg->fields[E50_TMSG] = NULL;
00773 }
00774 else {
00775 error(0, "EMI2[%s]: MT == %s isn't supported yet",
00776 octstr_get_cstr(privdata->name),
00777 octstr_get_cstr(emimsg->fields[E50_MT]));
00778 msg->sms.msgdata = octstr_create("");
00779 }
00780
00781 msg->sms.sender = octstr_duplicate(emimsg->fields[E50_OADC]);
00782 if (msg->sms.sender == NULL) {
00783 warning(0, "EMI2[%s]: Empty sender field in received message",
00784 octstr_get_cstr(privdata->name));
00785 msg->sms.sender = octstr_create("");
00786 }
00787
00788 if(octstr_len(PRIVDATA(conn)->my_number)) {
00789 msg->sms.receiver = octstr_duplicate(PRIVDATA(conn)->my_number);
00790 }
00791 else {
00792 msg->sms.receiver = octstr_duplicate(emimsg->fields[E50_ADC]);
00793 }
00794 if (msg->sms.receiver == NULL) {
00795 warning(0, "EMI2[%s]: Empty receiver field in received message",
00796 octstr_get_cstr(privdata->name));
00797 msg->sms.receiver = octstr_create("");
00798 }
00799
00800 tempstr = emimsg->fields[E50_SCTS];
00801 if (tempstr == NULL) {
00802 warning(0, "EMI2[%s]: Received EMI message doesn't have required timestamp",
00803 octstr_get_cstr(privdata->name));
00804 goto notime;
00805 }
00806 if (octstr_len(tempstr) != 12) {
00807 warning(0, "EMI2[%s]: EMI SCTS field must have length 12, now %ld",
00808 octstr_get_cstr(privdata->name), octstr_len(tempstr));
00809 goto notime;
00810 }
00811 if (octstr_parse_long(&unitime.second, tempstr, 10, 10) != 12 ||
00812 (octstr_delete(tempstr, 10, 2),
00813 octstr_parse_long(&unitime.minute, tempstr, 8, 10) != 10) ||
00814 (octstr_delete(tempstr, 8, 2),
00815 octstr_parse_long(&unitime.hour, tempstr, 6, 10) != 8) ||
00816 (octstr_delete(tempstr, 6, 2),
00817 octstr_parse_long(&unitime.year, tempstr, 4, 10) != 6) ||
00818 (octstr_delete(tempstr, 4, 2),
00819 octstr_parse_long(&unitime.month, tempstr, 2, 10) != 4) ||
00820 (octstr_delete(tempstr, 2, 2),
00821 octstr_parse_long(&unitime.day, tempstr, 0, 10) != 2)) {
00822 error(0, "EMI2[%s]: EMI delivery time stamp looks malformed",
00823 octstr_get_cstr(privdata->name));
00824 notime:
00825 time(&msg->sms.time);
00826 }
00827 else {
00828 unitime.year += 2000;
00829 unitime.month -= 1;
00830 msg->sms.time = date_convert_universal(&unitime);
00831 }
00832
00833 msg->sms.smsc_id = octstr_duplicate(conn->id);
00834 bb_smscconn_receive(conn, msg);
00835 reply = emimsg_create_reply(52, emimsg->trn, 1, privdata->name);
00836 if (emi2_emimsg_send(conn, server, reply) < 0) {
00837 emimsg_destroy(reply);
00838 return -1;
00839 }
00840 emimsg_destroy(reply);
00841 return 1;
00842
00843
00844
00845
00846 case 53:
00847 st_code = atoi(octstr_get_cstr(emimsg->fields[E50_DST]));
00848 switch(st_code)
00849 {
00850 case 0:
00851 msg = dlr_find((conn->id ? conn->id : privdata->name),
00852 emimsg->fields[E50_SCTS],
00853 emimsg->fields[E50_OADC],
00854 DLR_SUCCESS);
00855 break;
00856 case 1:
00857 msg = dlr_find((conn->id ? conn->id : privdata->name),
00858 emimsg->fields[E50_SCTS],
00859 emimsg->fields[E50_OADC],
00860 DLR_BUFFERED);
00861 break;
00862 case 2:
00863 msg = dlr_find((conn->id ? conn->id : privdata->name),
00864 emimsg->fields[E50_SCTS],
00865 emimsg->fields[E50_OADC],
00866 DLR_FAIL);
00867 break;
00868 }
00869 if (msg != NULL) {
00870
00871
00872
00873
00874 if ((emimsg->fields[E50_AMSG]) == NULL)
00875 msg->sms.msgdata = octstr_create("Delivery Report without text");
00876 else
00877 msg->sms.msgdata = octstr_duplicate(emimsg->fields[E50_AMSG]);
00878 octstr_hex_to_binary(msg->sms.msgdata);
00879 if (octstr_get_char(emimsg->fields[E50_MT], 0) == '3') {
00880
00881 if (privdata->alt_charset == EMI_NRC_ISO_21)
00882 charset_nrc_iso_21_german_to_gsm(msg->sms.msgdata);
00883 charset_gsm_to_utf8(msg->sms.msgdata);
00884 }
00885 bb_smscconn_receive(conn, msg);
00886 }
00887 reply = emimsg_create_reply(53, emimsg->trn, 1, privdata->name);
00888 if (emi2_emimsg_send(conn, server, reply) < 0) {
00889 emimsg_destroy(reply);
00890 return -1;
00891 }
00892 emimsg_destroy(reply);
00893 return 1;
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904 case 31:
00905 reply = emimsg_create_reply(31, emimsg->trn, 1, privdata->name);
00906 st_code = emi2_emimsg_send(conn, server, reply);
00907 emimsg_destroy(reply);
00908 return (st_code < 0 ? -1 : 1);
00909
00910 default:
00911 error(0, "EMI2[%s]: I don't know how to handle operation type %d",
00912 octstr_get_cstr(privdata->name), emimsg->ot);
00913 return 0;
00914 }
00915 }
00916
00917
00918
00919
00920
00921 static void clear_sent(PrivData *privdata)
00922 {
00923 int i;
00924 debug("smsc.emi2", 0, "EMI2[%s]: clear_sent called",
00925 octstr_get_cstr(privdata->name));
00926 for (i = 0; i < EMI2_MAX_TRN; i++) {
00927 if (privdata->slots[i].sendtime && privdata->slots[i].sendtype == 51)
00928 gw_prioqueue_produce(privdata->outgoing_queue, privdata->slots[i].sendmsg);
00929 privdata->slots[i].sendtime = 0;
00930 }
00931 privdata->unacked = 0;
00932 }
00933
00934
00935
00936
00937
00938
00939 static EMI2Event emi2_wait (SMSCConn *conn, Connection *server, double seconds)
00940 {
00941 if (emi2_can_send(conn) && gw_prioqueue_len(PRIVDATA(conn)->outgoing_queue)) {
00942 return EMI2_SENDREQ;
00943 }
00944
00945 if (server != NULL) {
00946 switch (conn_wait(server, seconds)) {
00947 case 1: return gw_prioqueue_len(PRIVDATA(conn)->outgoing_queue) ? EMI2_SENDREQ : EMI2_TIMEOUT;
00948 case 0: return EMI2_SMSCREQ;
00949 default: return EMI2_CONNERR;
00950 }
00951 } else {
00952 gwthread_sleep(seconds);
00953 return gw_prioqueue_len(PRIVDATA(conn)->outgoing_queue) ? EMI2_SENDREQ : EMI2_TIMEOUT;
00954 }
00955 }
00956
00957
00958
00959
00960 static int emi2_next_trn (SMSCConn *conn)
00961 {
00962 #define INC_TRN(x) ((x)=((x) + 1) % EMI2_MAX_TRN)
00963 int result;
00964
00965 while (SLOTBUSY(conn,PRIVDATA(conn)->priv_nexttrn))
00966 INC_TRN(PRIVDATA(conn)->priv_nexttrn);
00967
00968 result = PRIVDATA(conn)->priv_nexttrn;
00969 INC_TRN(PRIVDATA(conn)->priv_nexttrn);
00970
00971 return result;
00972 #undef INC_TRN
00973 }
00974
00975
00976
00977
00978 static int emi2_keepalive_handling (SMSCConn *conn, Connection *server)
00979 {
00980 struct emimsg *emimsg;
00981 int nexttrn = emi2_next_trn (conn);
00982
00983 emimsg = make_emi31(PRIVDATA(conn), nexttrn);
00984 if(emimsg) {
00985 PRIVDATA(conn)->slots[nexttrn].sendtype= 31;
00986 PRIVDATA(conn)->slots[nexttrn].sendtime = time(NULL);
00987 PRIVDATA(conn)->unacked++;
00988
00989 if (emi2_emimsg_send(conn, server, emimsg) == -1) {
00990 emimsg_destroy(emimsg);
00991 return -1;
00992 }
00993 emimsg_destroy(emimsg);
00994 }
00995
00996 PRIVDATA(conn)->can_write = 0;
00997
00998 return 0;
00999 }
01000
01001
01002
01003
01004
01005 static int emi2_do_send(SMSCConn *conn, Connection *server)
01006 {
01007 struct emimsg *emimsg;
01008 Msg *msg;
01009 double delay = 0;
01010
01011 if (conn->throughput > 0) {
01012 delay = 1.0 / conn->throughput;
01013 }
01014
01015
01016 while (emi2_can_send(conn) &&
01017 (msg = gw_prioqueue_remove(PRIVDATA(conn)->outgoing_queue)) != NULL) {
01018 int nexttrn = emi2_next_trn(conn);
01019
01020 if (conn->throughput > 0)
01021 gwthread_sleep(delay);
01022
01023
01024 emimsg = msg_to_emimsg(msg, nexttrn, PRIVDATA(conn));
01025
01026
01027 PRIVDATA(conn)->slots[nexttrn].sendmsg = msg;
01028 PRIVDATA(conn)->slots[nexttrn].sendtype = 51;
01029 PRIVDATA(conn)->slots[nexttrn].sendtime = time(NULL);
01030
01031
01032 if (emi2_emimsg_send(conn, server, emimsg) == -1) {
01033 emimsg_destroy(emimsg);
01034 return -1;
01035 }
01036
01037
01038 PRIVDATA(conn)->unacked++;
01039
01040 emimsg_destroy(emimsg);
01041
01042
01043
01044
01045
01046
01047 PRIVDATA(conn)->can_write = 0;
01048 }
01049
01050 return 0;
01051 }
01052
01053 static int emi2_handle_smscreq(SMSCConn *conn, Connection *server)
01054 {
01055 Octstr *str;
01056 struct emimsg *emimsg;
01057 PrivData *privdata = conn->data;
01058
01059
01060 while ((str = conn_read_packet(server, 2, 3))) {
01061 debug("smsc.emi2", 0, "EMI2[%s]: Got packet from the main socket",
01062 octstr_get_cstr(privdata->name));
01063
01064
01065 emimsg = get_fields(str, privdata->name);
01066 octstr_destroy(str);
01067
01068 if (emimsg == NULL) {
01069 continue;
01070 }
01071
01072 if (emimsg->or == 'O') {
01073
01074
01075
01076
01077 if (!conn->is_stopped) {
01078 if (handle_operation(conn, server, emimsg) < 0)
01079 return -1;
01080 } else {
01081 info(0, "EMI2[%s]: Ignoring operation from main socket "
01082 "because the connection is stopped.",
01083 octstr_get_cstr(privdata->name));
01084 }
01085 } else {
01086 if (!SLOTBUSY(conn,emimsg->trn) ||
01087 emimsg->ot != PRIVDATA(conn)->slots[emimsg->trn].sendtype) {
01088 error(0, "EMI2[%s]: Got ack for TRN %d, don't remember sending O?",
01089 octstr_get_cstr(privdata->name), emimsg->trn);
01090 } else {
01091 PRIVDATA(conn)->can_write = 1;
01092 PRIVDATA(conn)->slots[emimsg->trn].sendtime = 0;
01093 PRIVDATA(conn)->unacked--;
01094
01095 if (emimsg->ot == 51) {
01096 if (octstr_get_char(emimsg->fields[0], 0) == 'A') {
01097
01098
01099 Octstr *ts, *adc;
01100 int i;
01101 Msg *m;
01102
01103 ts = octstr_duplicate(emimsg->fields[2]);
01104 if (octstr_len(ts)) {
01105 i = octstr_search_char(ts,':',0);
01106 if (i>0) {
01107 octstr_delete(ts,0,i+1);
01108 adc = octstr_duplicate(emimsg->fields[2]);
01109 octstr_truncate(adc,i);
01110
01111 m = PRIVDATA(conn)->slots[emimsg->trn].sendmsg;
01112 if(m == NULL) {
01113 info(0,"EMI2[%s]: uhhh m is NULL, very bad",
01114 octstr_get_cstr(privdata->name));
01115 } else if (DLR_IS_ENABLED_DEVICE(m->sms.dlr_mask)) {
01116 dlr_add((conn->id ? conn->id : privdata->name), ts, m);
01117 }
01118 octstr_destroy(ts);
01119 octstr_destroy(adc);
01120 } else {
01121 octstr_destroy(ts);
01122 }
01123 }
01124
01125
01126
01127 bb_smscconn_sent(conn,
01128 PRIVDATA(conn)->slots[emimsg->trn].sendmsg,
01129 NULL);
01130 } else {
01131 Octstr *reply;
01132
01133
01134 reply = octstr_create("");
01135 octstr_append(reply, emimsg->fields[1]);
01136 octstr_append_char(reply, '-');
01137
01138 if (emimsg->fields[2] != NULL)
01139 octstr_append(reply, emimsg->fields[2]);
01140
01141
01142
01143
01144
01145
01146
01147
01148 bb_smscconn_send_failed(conn,
01149 PRIVDATA(conn)->slots[emimsg->trn].sendmsg,
01150 SMSCCONN_FAILED_REJECTED, reply);
01151
01152 }
01153 } else if (emimsg->ot == 31) {
01154
01155
01156
01157
01158
01159
01160
01161
01162 ;
01163
01164 } else {
01165 panic(0, "EMI2[%s]: Bug, ACK handler missing for sent packet",
01166 octstr_get_cstr(privdata->name));
01167 }
01168 }
01169 }
01170 emimsg_destroy(emimsg);
01171 }
01172
01173 if (conn_error(server)) {
01174 error(0, "EMI2[%s]: Error trying to read ACKs from SMSC",
01175 octstr_get_cstr(privdata->name));
01176 return -1;
01177 }
01178
01179 if (conn_eof(server)) {
01180 info(0, "EMI2[%s]: Main connection closed by SMSC",
01181 octstr_get_cstr(privdata->name));
01182 return -1;
01183 }
01184
01185 return 0;
01186 }
01187
01188 static void emi2_idleprocessing(SMSCConn *conn, Connection **server)
01189 {
01190 time_t current_time;
01191 int i;
01192 PrivData *privdata = conn->data;
01193
01194
01195
01196
01197
01198 current_time = time(NULL);
01199
01200 if (PRIVDATA(conn)->unacked && (current_time > (PRIVDATA(conn)->check_time + 30))) {
01201 PRIVDATA(conn)->check_time = current_time;
01202 for (i = 0; i < PRIVDATA(conn)->window; i++) {
01203 if (SLOTBUSY(conn,i)
01204 && PRIVDATA(conn)->slots[i].sendtime < (current_time - PRIVDATA(conn)->waitack)) {
01205
01206 if (PRIVDATA(conn)->slots[i].sendtype == 51) {
01207 if (PRIVDATA(conn)->waitack_expire == 0x00) {
01208
01209 warning(0, "EMI2[%s]: received neither ACK nor NACK for message %d "
01210 "in %d seconds, disconnecting and reconnection",
01211 octstr_get_cstr(privdata->name), i, PRIVDATA(conn)->waitack);
01212 PRIVDATA(conn)->slots[i].sendtime = 0;
01213 PRIVDATA(conn)->unacked--;
01214 info(0, "EMI2[%s]: closing connection.",
01215 octstr_get_cstr(privdata->name));
01216 conn_destroy(*server);
01217 *server = NULL;
01218 break;
01219 } else if (PRIVDATA(conn)->waitack_expire == 0x01) {
01220
01221 warning(0, "EMI2[%s]: received neither ACK nor NACK for message %d "
01222 "in %d seconds, resending message", octstr_get_cstr(privdata->name),
01223 i, PRIVDATA(conn)->waitack);
01224 gw_prioqueue_produce(PRIVDATA(conn)->outgoing_queue,
01225 PRIVDATA(conn)->slots[i].sendmsg);
01226 PRIVDATA(conn)->slots[i].sendtime = 0;
01227 PRIVDATA(conn)->unacked--;
01228 if (PRIVDATA(conn)->flowcontrol) PRIVDATA(conn)->can_write=1;
01229
01230
01231 gwthread_wakeup(PRIVDATA(conn)->sender_thread);
01232 } else if (PRIVDATA(conn)->waitack_expire == 0x02) {
01233
01234 warning(0, "EMI2[%s]: received neither ACK nor NACK for message %d "
01235 "in %d seconds, carrying on waiting", octstr_get_cstr(privdata->name),
01236 i, PRIVDATA(conn)->waitack);
01237 }
01238 } else if (PRIVDATA(conn)->slots[i].sendtype == 31) {
01239 warning(0, "EMI2[%s]: Alert (operation 31) was not "
01240 "ACKed within %d seconds", octstr_get_cstr(privdata->name),
01241 PRIVDATA(conn)->waitack);
01242 if (PRIVDATA(conn)->flowcontrol) PRIVDATA(conn)->can_write=1;
01243 } else {
01244 panic(0, "EMI2[%s]: Bug, no timeout handler for sent packet",
01245 octstr_get_cstr(privdata->name));
01246 }
01247 }
01248 }
01249 }
01250 }
01251
01252 static void emi2_idletimeout_handling (SMSCConn *conn, Connection **server)
01253 {
01254 PrivData *privdata = conn->data;
01255
01256
01257
01258
01259 if ((*server != NULL) && CONNECTIONIDLE(conn)) {
01260 info(0, "EMI2[%s]: closing idle connection.",
01261 octstr_get_cstr(privdata->name));
01262 conn_destroy(*server);
01263 *server = NULL;
01264 }
01265 }
01266
01267
01268
01269
01270 static double emi2_get_timeouttime (SMSCConn *conn, Connection *server)
01271 {
01272 double ka_timeouttime = PRIVDATA(conn)->keepalive ? PRIVDATA(conn)->keepalive + 1 : DBL_MAX;
01273 double idle_timeouttime = (PRIVDATA(conn)->idle_timeout && server) ? PRIVDATA(conn)->idle_timeout : DBL_MAX;
01274 double result = ka_timeouttime < idle_timeouttime ? ka_timeouttime : idle_timeouttime;
01275
01276 if (result == DBL_MAX)
01277 result = 30;
01278
01279 return result;
01280 }
01281
01282
01283
01284
01285 static void emi2_send_loop(SMSCConn *conn, Connection **server)
01286 {
01287 PrivData *privdata = conn->data;
01288
01289 for (;;) {
01290 double timeouttime;
01291 EMI2Event event;
01292
01293 if (emi2_needs_keepalive (conn)) {
01294 if (*server == NULL) {
01295 return;
01296 }
01297
01298 emi2_keepalive_handling (conn, *server);
01299 }
01300
01301 timeouttime = emi2_get_timeouttime (conn, *server);
01302
01303 event = emi2_wait (conn, *server, timeouttime);
01304
01305 switch (event) {
01306 case EMI2_CONNERR:
01307 return;
01308
01309 case EMI2_SENDREQ:
01310 if (*server == NULL) {
01311 return;
01312 }
01313
01314 if (emi2_do_send (conn, *server) < 0) {
01315 return;
01316 }
01317 break;
01318
01319 case EMI2_SMSCREQ:
01320 if (emi2_handle_smscreq (conn, *server) < 0) {
01321 return;
01322 }
01323 break;
01324
01325 case EMI2_TIMEOUT:
01326 break;
01327 }
01328
01329 if ((*server !=NULL) && (emi2_handle_smscreq (conn, *server) < 0)) {
01330 return;
01331 }
01332
01333 emi2_idleprocessing (conn, server);
01334 emi2_idletimeout_handling (conn, server);
01335
01336 if (PRIVDATA(conn)->shutdown && (PRIVDATA(conn)->unacked == 0)) {
01337
01338 break;
01339 }
01340
01341 if (*server != NULL) {
01342 if (conn_error(*server)) {
01343 warning(0, "EMI2[%s]: Error reading from the main connection",
01344 octstr_get_cstr(privdata->name));
01345 break;
01346 }
01347
01348 if (conn_eof(*server)) {
01349 info(0, "EMI2[%s]: Main connection closed by SMSC",
01350 octstr_get_cstr(privdata->name));
01351 break;
01352 }
01353 }
01354 }
01355 }
01356
01357 static void emi2_sender(void *arg)
01358 {
01359 SMSCConn *conn = arg;
01360 PrivData *privdata = conn->data;
01361 Msg *msg;
01362 Connection *server;
01363
01364
01365 log_thread_to(conn->log_idx);
01366
01367 while (!privdata->shutdown) {
01368 if ((server = open_send_connection(conn)) == NULL) {
01369 privdata->shutdown = 1;
01370 if (privdata->rport > 0)
01371 gwthread_wakeup(privdata->receiver_thread);
01372 break;
01373 }
01374 emi2_send_loop(conn, &server);
01375 clear_sent(privdata);
01376
01377 if (server != NULL) {
01378 conn_destroy(server);
01379 }
01380 }
01381
01382 while((msg = gw_prioqueue_remove(privdata->outgoing_queue)) != NULL)
01383 bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL);
01384 if (privdata->rport > 0)
01385 gwthread_join(privdata->receiver_thread);
01386 mutex_lock(conn->flow_mutex);
01387
01388 conn->status = SMSCCONN_DEAD;
01389
01390 debug("bb.sms", 0, "EMI2[%s]: connection has completed shutdown.",
01391 octstr_get_cstr(privdata->name));
01392
01393 gw_prioqueue_destroy(privdata->outgoing_queue, NULL);
01394 octstr_destroy(privdata->name);
01395 octstr_destroy(privdata->allow_ip);
01396 octstr_destroy(privdata->deny_ip);
01397 octstr_destroy(privdata->host);
01398 octstr_destroy(privdata->alt_host);
01399 octstr_destroy(privdata->my_number);
01400 octstr_destroy(privdata->username);
01401 octstr_destroy(privdata->password);
01402 octstr_destroy(privdata->npid);
01403 octstr_destroy(privdata->nadc);
01404 gw_free(privdata);
01405 conn->data = NULL;
01406
01407 mutex_unlock(conn->flow_mutex);
01408 bb_smscconn_killed();
01409 }
01410
01411
01412 static void emi2_receiver(SMSCConn *conn, Connection *server)
01413 {
01414 PrivData *privdata = conn->data;
01415 Octstr *str;
01416 struct emimsg *emimsg;
01417
01418 while (1) {
01419 if (conn_eof(server)) {
01420 info(0, "EMI2[%s]: receive connection closed by SMSC",
01421 octstr_get_cstr(privdata->name));
01422 return;
01423 }
01424 if (conn_error(server)) {
01425 error(0, "EMI2[%s]: receive connection broken",
01426 octstr_get_cstr(privdata->name));
01427 return;
01428 }
01429 if (conn->is_stopped)
01430 str = NULL;
01431 else
01432 str = conn_read_packet(server, 2, 3);
01433 if (str) {
01434 debug("smsc.emi2", 0, "EMI2[%s]: Got packet from the receive connection.",
01435 octstr_get_cstr(privdata->name));
01436 if ( (emimsg = get_fields(str, privdata->name)) ) {
01437 if (emimsg->or == 'O') {
01438 if (handle_operation(conn, server, emimsg) < 0) {
01439 emimsg_destroy(emimsg);
01440 return;
01441 }
01442 }
01443 else
01444 error(0, "EMI2[%s]: No ACKs expected on receive connection!",
01445 octstr_get_cstr(privdata->name));
01446 emimsg_destroy(emimsg);
01447 }
01448 octstr_destroy(str);
01449 }
01450 else
01451 conn_wait(server, -1);
01452 if (privdata->shutdown)
01453 break;
01454 }
01455 return;
01456 }
01457
01458
01459 static int emi2_open_listening_socket(SMSCConn *conn, PrivData *privdata)
01460 {
01461 int s;
01462
01463 if ( (s = make_server_socket(privdata->rport, (conn->our_host ? octstr_get_cstr(conn->our_host) : NULL))) == -1) {
01464 error(0, "EMI2[%s]: could not create listening socket in port %d",
01465 octstr_get_cstr(privdata->name), privdata->rport);
01466 return -1;
01467 }
01468 if (socket_set_blocking(s, 0) == -1) {
01469 error(0, "EMI2[%s]: couldn't make listening socket port %d "
01470 "non-blocking", octstr_get_cstr(privdata->name), privdata->rport);
01471 close(s);
01472 return -1;
01473 }
01474 privdata->listening_socket = s;
01475 return 0;
01476 }
01477
01478
01479 static void emi2_listener(void *arg)
01480 {
01481 SMSCConn *conn = arg;
01482 PrivData *privdata = conn->data;
01483 struct sockaddr_in server_addr;
01484 socklen_t server_addr_len;
01485 Octstr *ip;
01486 Connection *server;
01487 int s, ret;
01488
01489
01490 log_thread_to(conn->log_idx);
01491
01492 while (!privdata->shutdown) {
01493 server_addr_len = sizeof(server_addr);
01494 ret = gwthread_pollfd(privdata->listening_socket, POLLIN, -1);
01495 if (ret == -1) {
01496 if (errno == EINTR)
01497 continue;
01498 error(0, "EMI2[%s]: Poll for emi2 smsc connections failed, shutting down",
01499 octstr_get_cstr(privdata->name));
01500 break;
01501 }
01502 if (privdata->shutdown)
01503 break;
01504 if (ret == 0)
01505
01506 continue;
01507 s = accept(privdata->listening_socket, (struct sockaddr *)&server_addr,
01508 &server_addr_len);
01509 if (s == -1) {
01510 warning(errno, "EMI2[%s]: emi2_listener: accept() failed, retrying...",
01511 octstr_get_cstr(privdata->name));
01512 continue;
01513 }
01514 ip = host_ip(server_addr);
01515 if (!is_allowed_ip(privdata->allow_ip, privdata->deny_ip, ip)) {
01516 info(0, "EMI2[%s]: smsc connection tried from denied host <%s>,"
01517 " disconnected", octstr_get_cstr(privdata->name),
01518 octstr_get_cstr(ip));
01519 octstr_destroy(ip);
01520 close(s);
01521 continue;
01522 }
01523 server = conn_wrap_fd(s, 0);
01524 if (server == NULL) {
01525 error(0, "EMI2[%s]: emi2_listener: conn_wrap_fd failed on accept()ed fd",
01526 octstr_get_cstr(privdata->name));
01527 octstr_destroy(ip);
01528 close(s);
01529 continue;
01530 }
01531 conn_claim(server);
01532 info(0, "EMI2[%s]: smsc connected from %s",
01533 octstr_get_cstr(privdata->name), octstr_get_cstr(ip));
01534 octstr_destroy(ip);
01535
01536 emi2_receiver(conn, server);
01537 conn_destroy(server);
01538 }
01539 if (close(privdata->listening_socket) == -1)
01540 warning(errno, "EMI2[%s]: couldn't close listening socket "
01541 "at shutdown", octstr_get_cstr(privdata->name));
01542 gwthread_wakeup(privdata->sender_thread);
01543 }
01544
01545
01546 static int add_msg_cb(SMSCConn *conn, Msg *sms)
01547 {
01548 PrivData *privdata = conn->data;
01549 Msg *copy;
01550
01551 copy = msg_duplicate(sms);
01552 gw_prioqueue_produce(privdata->outgoing_queue, copy);
01553 gwthread_wakeup(privdata->sender_thread);
01554
01555 return 0;
01556 }
01557
01558
01559 static int shutdown_cb(SMSCConn *conn, int finish_sending)
01560 {
01561 PrivData *privdata = conn->data;
01562
01563 debug("bb.sms", 0, "EMI2[%s]: Shutting down SMSCConn EMI2, %s",
01564 octstr_get_cstr(privdata->name),
01565 finish_sending ? "slow" : "instant");
01566
01567
01568
01569 conn->why_killed = SMSCCONN_KILLED_SHUTDOWN;
01570 privdata->shutdown = 1;
01571
01572
01573 if (finish_sending == 0) {
01574 Msg *msg;
01575 while((msg = gw_prioqueue_remove(privdata->outgoing_queue)) != NULL) {
01576 bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL);
01577 }
01578 }
01579
01580 if (privdata->rport > 0)
01581 gwthread_wakeup(privdata->receiver_thread);
01582 return 0;
01583 }
01584
01585
01586 static void start_cb(SMSCConn *conn)
01587 {
01588 PrivData *privdata = conn->data;
01589
01590
01591 if (privdata->rport > 0)
01592 gwthread_wakeup(privdata->receiver_thread);
01593 debug("smsc.emi2", 0, "EMI2[%s]: start called",
01594 octstr_get_cstr(privdata->name));
01595 }
01596
01597
01598 static long queued_cb(SMSCConn *conn)
01599 {
01600 PrivData *privdata = conn->data;
01601 long ret;
01602
01603 ret = (privdata ? gw_prioqueue_len(privdata->outgoing_queue) : 0);
01604
01605
01606
01607 conn->load = ret;
01608 return ret;
01609 }
01610
01611
01612 int smsc_emi2_create(SMSCConn *conn, CfgGroup *cfg)
01613 {
01614 PrivData *privdata;
01615 Octstr *allow_ip, *deny_ip, *host, *alt_host;
01616 long portno, our_port, keepalive, flowcontrol, waitack,
01617 idle_timeout, alt_portno, alt_charset, waitack_expire;
01618 long window;
01619
01620 int i;
01621
01622 allow_ip = deny_ip = host = alt_host = NULL;
01623
01624 privdata = gw_malloc(sizeof(PrivData));
01625 privdata->outgoing_queue = gw_prioqueue_create(sms_priority_compare);
01626 privdata->listening_socket = -1;
01627 privdata->can_write = 1;
01628 privdata->priv_nexttrn = 0;
01629 privdata->last_activity_time = 0;
01630 privdata->check_time = 0;
01631
01632 host = cfg_get(cfg, octstr_imm("host"));
01633 if (host == NULL) {
01634 error(0, "EMI2[-]: 'host' missing in emi2 configuration.");
01635 goto error;
01636 }
01637 privdata->host = host;
01638
01639 if (cfg_get_integer(&portno, cfg, octstr_imm("port")) == -1)
01640 portno = 0;
01641 privdata->port = portno;
01642 if (privdata->port <= 0 || privdata->port > 65535) {
01643 error(0, "EMI2[%s]: 'port' missing/invalid in emi2 configuration.",
01644 octstr_get_cstr(host));
01645 goto error;
01646 }
01647
01648 if (cfg_get_integer(&our_port, cfg, octstr_imm("our-port")) == -1)
01649 privdata->our_port = 0;
01650 else
01651 privdata->our_port = our_port;
01652
01653 privdata->name = cfg_get(cfg, octstr_imm("smsc-id"));
01654 if(privdata->name == NULL) {
01655 privdata->name = octstr_create("");
01656
01657
01658 if(octstr_len(conn->our_host)) {
01659 octstr_append(privdata->name, conn->our_host);
01660 }
01661
01662
01663 if(privdata->our_port != 0) {
01664
01665 if(octstr_len(privdata->name) == 0) {
01666 octstr_append(privdata->name, octstr_imm("kannel"));
01667 }
01668 octstr_append_char(privdata->name, ':');
01669 octstr_append_decimal(privdata->name, privdata->our_port);
01670 } else {
01671 if(octstr_len(privdata->name) != 0) {
01672 octstr_append(privdata->name, octstr_imm(":*"));
01673 }
01674 }
01675
01676
01677 if(octstr_len(privdata->name) != 0)
01678 octstr_append(privdata->name, octstr_imm("->"));
01679
01680 octstr_append(privdata->name, privdata->host);
01681 octstr_append_char(privdata->name, ':');
01682 octstr_append_decimal(privdata->name, privdata->port);
01683 }
01684
01685
01686 if (cfg_get_integer(&idle_timeout, cfg, octstr_imm("idle-timeout")) == -1)
01687 idle_timeout = 0;
01688
01689 privdata->idle_timeout = idle_timeout;
01690
01691 alt_host = cfg_get(cfg, octstr_imm("alt-host"));
01692 privdata->alt_host = alt_host;
01693
01694 if (cfg_get_integer(&portno, cfg, octstr_imm("receive-port")) < 0)
01695 portno = 0;
01696 privdata->rport = portno;
01697
01698 if (cfg_get_integer(&alt_portno, cfg, octstr_imm("alt-port")) < 0)
01699 alt_portno = 0;
01700 privdata->alt_port = alt_portno;
01701
01702 allow_ip = cfg_get(cfg, octstr_imm("connect-allow-ip"));
01703 if (allow_ip)
01704 deny_ip = octstr_create("*.*.*.*");
01705 else
01706 deny_ip = NULL;
01707 privdata->username = cfg_get(cfg, octstr_imm("smsc-username"));
01708 privdata->password = cfg_get(cfg, octstr_imm("smsc-password"));
01709
01710 privdata->my_number = cfg_get(cfg, octstr_imm("my-number"));
01711
01712 privdata->npid = cfg_get(cfg, octstr_imm("notification-pid"));
01713 privdata->nadc = cfg_get(cfg, octstr_imm("notification-addr"));
01714
01715 if ( (privdata->username == NULL && privdata->my_number == NULL)
01716 || cfg_get_integer(&keepalive, cfg, octstr_imm("keepalive")) < 0)
01717 privdata->keepalive = 0;
01718 else
01719 privdata->keepalive = keepalive;
01720
01721 if (cfg_get_integer(&flowcontrol, cfg, octstr_imm("flow-control")) < 0)
01722 privdata->flowcontrol = 0;
01723 else
01724 privdata->flowcontrol = flowcontrol;
01725 if (privdata->flowcontrol < 0 || privdata->flowcontrol > 1) {
01726 error(0, "EMI2[%s]: 'flow-control' invalid in emi2 configuration.",
01727 octstr_get_cstr(privdata->name));
01728 goto error;
01729 }
01730
01731 if (cfg_get_integer(&window, cfg, octstr_imm("window")) < 0)
01732 privdata->window = EMI2_MAX_TRN;
01733 else
01734 privdata->window = window;
01735 if (privdata->window > EMI2_MAX_TRN) {
01736 warning(0, "EMI2[%s]: Value of 'window' should be lesser or equal to %d..",
01737 octstr_get_cstr(privdata->name), EMI2_MAX_TRN);
01738 privdata->window = EMI2_MAX_TRN;
01739 }
01740
01741 if (cfg_get_integer(&waitack, cfg, octstr_imm("wait-ack")) < 0)
01742 privdata->waitack = 60;
01743 else
01744 privdata->waitack = waitack;
01745 if (privdata->waitack < 30 ) {
01746 error(0, "EMI2[%s]: 'wait-ack' invalid in emi2 configuration.",
01747 octstr_get_cstr(privdata->name));
01748 goto error;
01749 }
01750
01751 if (cfg_get_integer(&waitack_expire, cfg, octstr_imm("wait-ack-expire")) < 0)
01752 privdata->waitack_expire = 0;
01753 else
01754 privdata->waitack_expire = waitack_expire;
01755 if (privdata->waitack_expire >3 ) {
01756 error(0, "EMI2[%s]: 'wait-ack-expire' invalid in emi2 configuration.",
01757 octstr_get_cstr(privdata->name));
01758 goto error;
01759 }
01760
01761 if (privdata->rport < 0 || privdata->rport > 65535) {
01762 error(0, "EMI2[%s]: 'receive-port' missing/invalid in emi2 configuration.",
01763 octstr_get_cstr(privdata->name));
01764 goto error;
01765 }
01766
01767 if (cfg_get_integer(&alt_charset, cfg, octstr_imm("alt-charset")) < 0)
01768 privdata->alt_charset = 0;
01769 else
01770 privdata->alt_charset = alt_charset;
01771
01772 privdata->allow_ip = allow_ip;
01773 privdata->deny_ip = deny_ip;
01774
01775 if (privdata->rport > 0 && emi2_open_listening_socket(conn,privdata) < 0) {
01776 gw_free(privdata);
01777 privdata = NULL;
01778 goto error;
01779 }
01780
01781 conn->data = privdata;
01782
01783 conn->name = octstr_format("EMI2:%S:%d:%S", privdata->host, privdata->port,
01784 privdata->username ? privdata->username : octstr_imm("null"));
01785
01786 privdata->shutdown = 0;
01787
01788 for (i = 0; i < EMI2_MAX_TRN; i++)
01789 privdata->slots[i].sendtime = 0;
01790 privdata->unacked = 0;
01791
01792 conn->status = SMSCCONN_CONNECTING;
01793 conn->connect_time = time(NULL);
01794
01795 if ( privdata->rport > 0 && (privdata->receiver_thread =
01796 gwthread_create(emi2_listener, conn)) == -1)
01797 goto error;
01798
01799 if ((privdata->sender_thread = gwthread_create(emi2_sender, conn)) == -1) {
01800 privdata->shutdown = 1;
01801 if (privdata->rport > 0) {
01802 gwthread_wakeup(privdata->receiver_thread);
01803 gwthread_join(privdata->receiver_thread);
01804 }
01805 goto error;
01806 }
01807
01808 conn->shutdown = shutdown_cb;
01809 conn->queued = queued_cb;
01810 conn->start_conn = start_cb;
01811 conn->send_msg = add_msg_cb;
01812
01813 return 0;
01814
01815 error:
01816 error(0, "EMI2[%s]: Failed to create emi2 smsc connection",
01817 octstr_get_cstr(privdata->name));
01818 if (privdata != NULL) {
01819 gw_prioqueue_destroy(privdata->outgoing_queue, NULL);
01820 }
01821 gw_free(privdata);
01822 octstr_destroy(allow_ip);
01823 octstr_destroy(deny_ip);
01824 octstr_destroy(host);
01825 conn->why_killed = SMSCCONN_KILLED_CANNOT_CONNECT;
01826 conn->status = SMSCCONN_DEAD;
01827 info(0, "EMI2[%s]: exiting", octstr_get_cstr(privdata->name));
01828 return -1;
01829 }
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.