Kannel: Open Source WAP and SMS gateway  svn-r5262
opensmppbox.c
Go to the documentation of this file.
1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2010 Kannel Group
5  * Copyright (c) 1998-2001 WapIT Ltd.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Kannel Group (http://www.kannel.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Kannel" and "Kannel Group" must not be used to
28  * endorse or promote products derived from this software without
29  * prior written permission. For written permission, please
30  * contact org@kannel.org.
31  *
32  * 5. Products derived from this software may not be called "Kannel",
33  * nor may "Kannel" appear in their name, without prior written
34  * permission of the Kannel Group.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS
40  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
41  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
42  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
46  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Kannel Group. For more information on
51  * the Kannel Group, please see <http://www.kannel.org/>.
52  *
53  * Portions of this software are based upon software originally written at
54  * WapIT Ltd., Helsinki, Finland for the Kannel project.
55  */
56 
57 /*
58  * Author: 2006 Chimit Software Development.
59  * http://www.chimit.nl/ rene.kluwen@chimit.nl
60  */
61 
62 /*
63  * opensmppbox.c - main program of the opensmppbox
64  */
65 
66 #include <errno.h>
67 #include <unistd.h>
68 #include <signal.h>
69 #include <string.h>
70 #include <math.h>
71 
72 #include "gwlib/gwlib.h"
73 #include "gw/msg.h"
74 #include "gw/shared.h"
75 #include "gw/bb.h"
76 
77 #include "gw/smsc/smpp_pdu.h"
78 #include "gw/sms.h"
79 #include "gw/dlr.h"
80 #include "gw/heartbeat.h"
81 #include "gw/meta_data.h"
82 #include "gw/bb_store.h"
83 
84 #undef GW_NAME
85 #undef GW_VERSION
86 #include "../sb-config.h"
87 
88 #ifdef HAVE_PAM_SECURITY
89 #include <security/pam_appl.h>
90 #elif defined HAVE_PAM_PAM
91 #include <pam/pam_appl.h>
92 #endif
93 
94 /* our config */
95 static Cfg *cfg;
96 /* have we received restart cmd from bearerbox? */
97 static volatile sig_atomic_t restart_smppbox = 0;
98 static volatile sig_atomic_t smppbox_status;
99 #define SMPP_DEAD 0
100 #define SMPP_SHUTDOWN 1
101 #define SMPP_RUNNING 2
102 static long smppbox_port;
103 static int smppbox_port_ssl = 0;
104 static long bearerbox_port;
106 static int bearerbox_port_ssl = 0;
108 static Counter *boxid;
109 static int restart = 0;
110 static List *all_boxes;
111 static Dict *list_dict;
114 static long smpp_source_addr_ton = -1;
115 static long smpp_source_addr_npi = -1;
116 static int smpp_autodetect_addr = 0;
117 static long smpp_dest_addr_ton = -1;
118 static long smpp_dest_addr_npi = -1;
119 
120 static Dict *smsc_by_receiver = NULL;
121 static Dict *smsc_by_smsbox_id = NULL;
122 static Dict *smsc_by_sender = NULL;
124 
128 static time_t smpp_timeout;
130 
131 static int systemidisboxcid;
132 static int enablepam;
133 static Octstr *pamacl;
134 
135 
136 #define TIMEOUT_SECONDS 300
137 
139 
140 typedef struct _boxc {
145  int is_wap;
146  long id;
147  int load;
148  int version;
150  time_t connect_time;
154  List *retry; /* If sending fails */
158  volatile sig_atomic_t alive;
159  Octstr *boxc_id; /* identifies the connected opensmppbox instance */
165  /* used to mark connection usable or still waiting for ident. msg */
166  volatile int routable;
167 
168 
175  int alt_dcs;
177  int priority;
179 
180 
181 } Boxc;
182 
183 void smpp_pdu_destroy_item(void *pdu)
184 {
185  smpp_pdu_destroy(pdu);
186 }
187 
188 static Octstr *boxc_route_msg_to_smsc(Boxc *box, Msg *msg);
189 
190 /*
191  * Use PAM (Pluggable Authentication Module) to check sendsms authentication.
192  */
193 
194 #ifdef HAVE_PAM
195 
196 typedef const struct pam_message pam_message_type;
197 
198 static const char *PAM_username;
199 static const char *PAM_password;
200 
201 static int PAM_conv (int num_msg, pam_message_type **msg,
202  struct pam_response **resp,
203  void *appdata_ptr)
204 {
205  int count = 0, replies = 0;
206  struct pam_response *repl = NULL;
207  int size = sizeof(struct pam_response);
208 
209 #define GET_MEM \
210  repl = gw_realloc(repl, size); \
211  size += sizeof(struct pam_response)
212 #define COPY_STRING(s) (s) ? gw_strdup(s) : NULL
213 
214  for (count = 0; count < num_msg; count++) {
215  switch (msg[count]->msg_style) {
216  case PAM_PROMPT_ECHO_ON:
217  GET_MEM;
218  repl[replies].resp_retcode = PAM_SUCCESS;
219  repl[replies++].resp = COPY_STRING(PAM_username);
220  /* PAM frees resp */
221  break;
222 
223  case PAM_PROMPT_ECHO_OFF:
224  GET_MEM;
225  repl[replies].resp_retcode = PAM_SUCCESS;
226  repl[replies++].resp = COPY_STRING(PAM_password);
227  /* PAM frees resp */
228  break;
229 
230  case PAM_TEXT_INFO:
231  warning(0, "unexpected message from PAM: %s", msg[count]->msg);
232  break;
233 
234  case PAM_ERROR_MSG:
235  default:
236  /* Must be an error of some sort... */
237  error(0, "unexpected error from PAM: %s", msg[count]->msg);
238  gw_free(repl);
239  return PAM_CONV_ERR;
240  }
241  }
242  if (repl)
243  *resp = repl;
244  return PAM_SUCCESS;
245 }
246 
247 static struct pam_conv PAM_conversation = {
248  &PAM_conv,
249  NULL
250 };
251 
252 
253 static int authenticate(const char *acl, const char *login, const char *passwd)
254 {
255  pam_handle_t *pamh;
256  int pam_error;
257 
258  PAM_username = login;
259  PAM_password = passwd;
260 
261  pam_error = pam_start(acl, login, &PAM_conversation, &pamh);
262  info(0, "Starting PAM for user: %s", login);
263  if (pam_error != PAM_SUCCESS ||
264  (pam_error = pam_authenticate(pamh, 0)) != PAM_SUCCESS) {
265  warning(0, "PAM auth failed for user: %s", login);
266  pam_end(pamh, pam_error);
267  return 0;
268  }
269  pam_end(pamh, PAM_SUCCESS);
270  info(0, "opensmppbox login by <%s>", login);
271  return 1;
272 }
273 
274 #endif /* HAVE_PAM */
275 
276 /* check if login exists in database */
277 int check_login(Boxc *boxc, Octstr *system_id, Octstr *password, Octstr *system_type, smpp_login login_type) {
278  int box;
279  int success;
280  Boxc *thisbox;
281  FILE *fp;
282  char systemid[255], passw[255], systemtype[255], allowed_ips[1024];
283  Octstr *allowed_ips_str;
284 
285  fp = fopen(octstr_get_cstr(smpp_logins), "r");
286  if (fp == NULL) {
287  return 0;
288  }
289  while (!feof(fp)) {
290  fscanf(fp, "%s %s %s %s\n", systemid, passw, systemtype, allowed_ips);
291  if (systemidisboxcid) {
292  success = (strcmp(octstr_get_cstr(system_id), systemid) == 0 && strcmp(octstr_get_cstr(password), passw) == 0);
293  }
294  else {
295  success = (strcmp(octstr_get_cstr(system_id), systemid) == 0 && strcmp(octstr_get_cstr(password), passw) == 0 && strcmp(octstr_get_cstr(system_type), systemtype) == 0);
296  }
297  if (success) {
298  if (strcmp(allowed_ips, "") != 0) {
299  allowed_ips_str = octstr_create(allowed_ips);
300  if (is_allowed_ip(allowed_ips_str, octstr_imm("*.*.*.*"), boxc->client_ip) == 0) {
301  info(0, "Box connection tried from denied host <%s>, disconnected", octstr_get_cstr(boxc->client_ip));
302  octstr_destroy(allowed_ips_str);
303  continue;
304  }
305  octstr_destroy(allowed_ips_str);
306  }
307  fclose(fp);
308  goto valid_login;
309  }
310  }
311  fclose(fp);
312 #ifdef HAVE_PAM
313  if (enablepam && authenticate(octstr_get_cstr(pamacl), octstr_get_cstr(system_id), octstr_get_cstr(password))) {
314  goto valid_login;
315  }
316 #endif
317  return 0;
318 valid_login:
319  for (box = 0; box < gwlist_len(all_boxes); box++) {
320  thisbox = (Boxc *)gwlist_get(all_boxes, box);
321  if (octstr_compare(system_type, thisbox->boxc_id) == 0 && (thisbox->login_type == SMPP_LOGIN_TRANSCEIVER || (thisbox->login_type == login_type))) {
322  debug("bb.sms.smpp", 0, "opensmppbox[%s]: Multiple login: disconnect.",
323  octstr_get_cstr(thisbox->boxc_id));
324  thisbox->alive = 0;
325 #ifdef HAVE_SHUTDOWN_CONNECTION
326  shutdown_connection(thisbox->bearerbox_connection);
327  shutdown_connection(thisbox->smpp_connection);
328 #endif
329  }
330  }
331  return 1;
332 }
333 
334 /*
335  * Select these based on whether you want to dump SMPP PDUs as they are
336  * sent and received or not. Not dumping should be the default in at least
337  * stable releases.
338  */
339 
340 #define DEBUG 1
341 
342 #ifndef DEBUG
343 #define dump_pdu(msg, id, pdu) do{}while(0)
344 #else
345 
346 #define dump_pdu(msg, id, pdu) \
347  do { \
348  debug("opensmppbox", 0, "SMPP[%s]: %s", \
349  octstr_get_cstr(id), msg); \
350  smpp_pdu_dump(id, pdu); \
351  } while(0)
352 #endif
353 
354 
355 /*
356  * Converting SMPP timestamp to minutes relative
357  * to our localtime.
358  * Return -1 if error detected
359  * Author: amalysh@kannel.org
360 */
361 static int timestamp_to_minutes(Octstr *timestamp)
362 {
363  struct tm tm, local;
364  time_t valutc, utc;
365  int rc, diff, dummy, localdiff;
366  char relation;
367 
368  if (octstr_len(timestamp) == 0)
369  return 0;
370 
371  if (octstr_len(timestamp) != 16)
372  return -1;
373 
374  /*
375  * Timestamp format:
376  * YYMMDDhhmmsstnn[+-R]
377  * t - tenths of second (not used by us)
378  * nn - Time difference in quarter hours between local and UTC time
379  */
380  rc = sscanf(octstr_get_cstr(timestamp),
381  "%02d%02d%02d%02d%02d%02d%1d%02d%1c",
382  &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
383  &tm.tm_hour, &tm.tm_min, &tm.tm_sec,
384  &dummy, &diff, &relation);
385  if (rc != 9)
386  return -1;
387 
388  utc = time(NULL);
389  if (utc == ((time_t)-1))
390  return 0;
391 
392  if (relation == '+' || relation == '-') {
393  tm.tm_year += 100; /* number of years since 1900 */
394  tm.tm_mon--; /* month 0-11 */
395  tm.tm_isdst = -1;
396  /* convert to sec. since 1970 */
397  valutc = gw_mktime(&tm);
398  if (valutc == ((time_t)-1))
399  return -1;
400 
401  /* work out local time, because gw_mktime assume local time */
402  local = gw_localtime(utc);
403  tm = gw_gmtime(utc);
404  local.tm_isdst = tm.tm_isdst = -1;
405  localdiff = difftime(gw_mktime(&local), gw_mktime(&tm));
406  valutc += localdiff;
407 
408  debug("sms.smpp",0, "diff between utc and localtime (%d)", localdiff);
409  diff = diff*15*60;
410  switch(relation) {
411  case '+':
412  valutc -= diff;
413  break;
414  case '-':
415  valutc += diff;
416  break;
417  }
418  } else if (relation == 'R') { /* relative to SMSC localtime */
419  local = gw_localtime(utc);
420  local.tm_year += tm.tm_year;
421  local.tm_mon += tm.tm_mon;
422  local.tm_mday += tm.tm_mday;
423  local.tm_hour += tm.tm_hour;
424  local.tm_min += tm.tm_min;
425  local.tm_sec += tm.tm_sec;
426  valutc = gw_mktime(&local);
427  if (valutc == ((time_t)-1))
428  return -1;
429  } else {
430  return -1;
431  }
432  tm = gw_gmtime(valutc);
433  debug("sms.smpp",0,"Requested UTC timestamp: %02d-%02d-%02d %02d:%02d:%02d",
434  tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
435 
436  debug("sms.smpp", 0, "requested timestamp in min. (%ld)", (valutc - utc)/60);
437 
438  return ceil ( difftime (valutc, utc) / 60 );
439 }
440 
441 
442 
443 /*
444  *-------------------------------------------------
445  * receiver thingies
446  *-------------------------------------------------
447  *
448 */
449 
450 /* send to bearerbox */
451 
452 static int send_msg(Connection *conn, Boxc *boxconn, Msg *pmsg)
453 {
454  /* Caution: implicit msg_destroy */
455  write_to_bearerbox_real(conn, pmsg);
456  return 0;
457 }
458 
459 /* for heartbeat fn */
460 /*
461 static void write_to_bearerboxes(Msg *msg)
462 {
463  long pos;
464  Boxc *box;
465 
466  for (pos = 0; pos < gwlist_len(all_boxes); pos++) {
467  box = (Boxc *)gwlist_get(all_boxes, pos);
468  send_msg(box->bearerbox_connection, box, msg);
469  }
470 }
471 */
472 
473 /* for heartbeat fn */
474 /*
475 static long outstanding_requests(void)
476 {
477  return 10;
478 }
479 */
480 
481 /*
482  * Identify ourself to bearerbox for opensmppbox-specific routing inside bearerbox.
483  * Do this even while no opensmppbox-id is given to unlock the sender thread in
484  * bearerbox.
485  */
487 {
488  Msg *msg;
489 
490  msg = msg_create(admin);
491  msg->admin.command = cmd_identify;
492  msg->admin.boxc_id = octstr_duplicate(conn->boxc_id);
493  send_msg(conn->bearerbox_connection, conn, msg);
494 }
495 
496 /* read from bearerbox */
497 
498 static Msg *read_from_box(Connection *conn, Boxc *boxconn)
499 {
500  Octstr *pack;
501  Msg *msg;
502 
503  pack = NULL;
504  while (boxconn->alive) {
505  switch (read_from_bearerbox_real(conn, &msg, 1.0)) {
506  case -1:
507  /* connection to bearerbox lost */
508  return NULL;
509  break;
510  case 0:
511  /* all is well */
512  return msg;
513  break;
514  case 1:
515  /* timeout */
516  break;
517  }
518  }
519 
520  return msg;
521 }
522 
523 Msg *catenate_msg(List *list, int total)
524 {
525  int current = 1, partno = 1, thismsg, max = 0;
526  Msg *current_msg;
527  Msg *ret = msg_duplicate(gwlist_get(list, 0));
528  uuid_generate(ret->sms.id);
529 
530  octstr_destroy(ret->sms.udhdata);
531  ret->sms.udhdata = NULL;
532  octstr_delete(ret->sms.msgdata, 0, octstr_len(ret->sms.msgdata));
533  while (max < total) {
534  current_msg = gwlist_get(list, current - 1);
535  if (current_msg) {
536  thismsg = octstr_get_char(current_msg->sms.udhdata, 5);
537  if (thismsg == partno) {
538  octstr_append(ret->sms.msgdata, current_msg->sms.msgdata);
539  max = 0;
540  if (++partno > total) {
541  return ret;
542  }
543  }
544  }
545  if (current >= total) {
546  current = 0;
547  }
548  current++;
549  max++;
550  }
551  /* fail */
552  debug("opensmppbox", 0, "re-assembling message failed.");
553  msg_destroy(ret);
554  return NULL;
555 }
556 
557 static long convert_addr_from_pdu(Octstr *id, Octstr *addr, long ton, long npi)
558 {
559  long reason = SMPP_ESME_ROK;
560 
561  if (addr == NULL)
562  return reason;
563 
564  switch(ton) {
566  /*
567  * Checks to perform:
568  * 1) assume international number has at least 7 chars
569  * 2) the whole source addr consist of digits, exception '+' in front
570  */
571  if (octstr_len(addr) < 7) {
572  error(0, "SMPP[%s]: Mallformed addr `%s', expected at least 7 digits. ",
573  octstr_get_cstr(id),
574  octstr_get_cstr(addr));
575  reason = SMPP_ESME_RINVSRCADR;
576  goto error;
577  } else if (octstr_get_char(addr, 0) == '+' &&
578  !octstr_check_range(addr, 1, 256, gw_isdigit)) {
579  error(0, "SMPP[%s]: Mallformed addr `%s', expected all digits. ",
580  octstr_get_cstr(id),
581  octstr_get_cstr(addr));
582  reason = SMPP_ESME_RINVSRCADR;
583  goto error;
584  } else if (octstr_get_char(addr, 0) != '+' &&
585  !octstr_check_range(addr, 0, 256, gw_isdigit)) {
586  error(0, "SMPP[%s]: Mallformed addr `%s', expected all digits. ",
587  octstr_get_cstr(id),
588  octstr_get_cstr(addr));
589  reason = SMPP_ESME_RINVSRCADR;
590  goto error;
591  }
592  /* check if we received leading '00', then remove it*/
593  if (octstr_search(addr, octstr_imm("00"), 0) == 0)
594  octstr_delete(addr, 0, 2);
595 
596  /* international, insert '+' if not already here */
597  if (octstr_get_char(addr, 0) != '+')
598  octstr_insert_char(addr, 0, '+');
599 
600  break;
602  if (octstr_len(addr) > 11) {
603  /* alphanum sender, max. allowed length is 11 (according to GSM specs) */
604  error(0, "SMPP[%s]: Mallformed addr `%s', alphanum length greater 11 chars. ",
605  octstr_get_cstr(id),
606  octstr_get_cstr(addr));
607  reason = SMPP_ESME_RINVSRCADR;
608  goto error;
609  }
610  break;
611  default: /* otherwise don't touch addr, user should handle it */
612  break;
613  }
614 
615 error:
616  return reason;
617 }
618 
619 static int send_pdu(Connection *conn, Octstr *id, SMPP_PDU *pdu)
620 {
621  Octstr *os;
622  int ret;
623 
624  dump_pdu("Sending PDU:", id, pdu);
625  os = smpp_pdu_pack(id, pdu);
626  if (os) {
627  ret = conn_write(conn, os); /* Caller checks for write errors later */
628  octstr_destroy(os);
629  }
630  else {
631  ret = -1;
632  }
633  return ret;
634 }
635 
636 /* generate 8 character ID, taken from msgid */
637 static Octstr *generate_smppid(Msg *msg, int version)
638 {
639  char uuidbuf[100];
640  Octstr *result;
641 
642  // gw_assert(msg->type == sms); // we segfault on this
643 
644  uuid_unparse(msg->sms.id, uuidbuf);
645  result = octstr_create_from_data(uuidbuf, version > 0x33 ? UUID_STR_LEN : 8);
646  return result;
647 }
648 
649 /*
650  * Try to read an SMPP PDU from a Connection. Return -1 for error (caller
651  * should close the connection), 0 for no PDU to ready yet, or 1 for PDU
652  * read and unpacked. Return a pointer to the PDU in `*pdu'. Use `*len'
653  * to store the length of the PDU to read (it may be possible to read the
654  * length, but not the rest of the PDU - we need to remember the lenght
655  * for the next call). `*len' should be zero at the first call.
656  */
657 static int read_pdu(Boxc *box, Connection *conn, long *len, SMPP_PDU **pdu)
658 {
659  Octstr *os;
660 
661  if (*len == 0) {
662  *len = smpp_pdu_read_len(conn);
663  if (*len == -1) {
664  error(0, "opensmppbox[%s]: Server sent garbage, ignored.",
665  octstr_get_cstr(box->boxc_id));
666  return -1;
667  } else if (*len == 0) {
668  if (conn_eof(conn) || conn_error(conn))
669  return -1;
670  return 0;
671  }
672  }
673 
674  os = smpp_pdu_read_data(conn, *len);
675  if (os == NULL) {
676  if (conn_eof(conn) || conn_error(conn))
677  return -1;
678  return 0;
679  }
680  *len = 0;
681 
682  *pdu = smpp_pdu_unpack(box->boxc_id, os);
683  if (*pdu == NULL) {
684  error(0, "opensmppbox[%s]: PDU unpacking failed.",
685  octstr_get_cstr(box->boxc_id));
686  debug("bb.sms.smpp", 0, "opensmppbox[%s]: Failed PDU omitted.",
687  octstr_get_cstr(box->boxc_id));
688  /* octstr_dump(os, 0); */
689  octstr_destroy(os);
690  return -1;
691  }
692 
693  octstr_destroy(os);
694  return 1;
695 }
696 
697 static List *msg_to_pdu(Boxc *box, Msg *msg)
698 {
699  SMPP_PDU *pdu, *pdu2;
700  List *pdulist = gwlist_create(), *parts;
701  int dlrtype, catenate;
702  int dlr_state = 7; /* UNKNOWN */
703  Msg *dlr;
704  char *text, *tmps, err[4] = { '0', '0', '0', '\0' };
705  char submit_date_c_str[11] = { '\0' }, done_date_c_str[11] = { '\0' };
706  struct tm tm_tmp;
707  Octstr *msgid, *msgid2, *dlr_status, *dlvrd;
708  /* split variables */
709  unsigned long msg_sequence, msg_count;
710  unsigned long submit_date;
711  int max_msgs;
712  Octstr *header, *footer, *suffix, *split_chars;
713  Msg *msg2;
714 
715  pdu = smpp_pdu_create(deliver_sm,
717 
718  pdu->u.deliver_sm.source_addr = octstr_duplicate(msg->sms.sender);
719  pdu->u.deliver_sm.destination_addr = octstr_duplicate(msg->sms.receiver);
720 
721  /* Set the service type of the outgoing message. We'll use the config
722  * directive as default and 'binfo' as specific parameter. */
723  pdu->u.deliver_sm.service_type = octstr_len(msg->sms.binfo) ?
724  octstr_duplicate(msg->sms.binfo) : octstr_duplicate(box->service_type);
725 
726  /* Check for manual override of source ton and npi values */
727  if(box->source_addr_ton > -1 && box->source_addr_npi > -1) {
728  pdu->u.deliver_sm.source_addr_ton = box->source_addr_ton;
729  pdu->u.deliver_sm.source_addr_npi = box->source_addr_npi;
730  debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced source addr ton = %ld, source add npi = %ld",
732  box->source_addr_npi);
733  } else {
734  /* setup default values */
735  pdu->u.deliver_sm.source_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */
736  pdu->u.deliver_sm.source_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */
737  }
738 
739  if (box->autodetect_addr) {
740  /* lets see if its international or alphanumeric sender */
741  if (octstr_get_char(pdu->u.deliver_sm.source_addr, 0) == '+') {
742  if (!octstr_check_range(pdu->u.deliver_sm.source_addr, 1, 256, gw_isdigit)) {
743  pdu->u.deliver_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC; /* alphanum */
744  pdu->u.deliver_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN; /* short code */
745  } else {
746  /* numeric sender address with + in front -> international (remove the +) */
747  octstr_delete(pdu->u.deliver_sm.source_addr, 0, 1);
748  pdu->u.deliver_sm.source_addr_ton = GSM_ADDR_TON_INTERNATIONAL;
749  }
750  } else {
751  if (!octstr_check_range(pdu->u.deliver_sm.source_addr,0, 256, gw_isdigit)) {
752  pdu->u.deliver_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC;
753  pdu->u.deliver_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN;
754  }
755  }
756  }
757 
758  /* Check for manual override of destination ton and npi values */
759  if (box->dest_addr_ton > -1 && box->dest_addr_npi > -1) {
760  pdu->u.deliver_sm.dest_addr_ton = box->dest_addr_ton;
761  pdu->u.deliver_sm.dest_addr_npi = box->dest_addr_npi;
762  debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced dest addr ton = %ld, dest add npi = %ld",
764  box->dest_addr_npi);
765  } else {
766  pdu->u.deliver_sm.dest_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */
767  pdu->u.deliver_sm.dest_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */
768  }
769 
770  /*
771  * if its a international number starting with +, lets remove the
772  * '+' and set number type to international instead
773  */
774  if (octstr_get_char(pdu->u.deliver_sm.destination_addr,0) == '+') {
775  octstr_delete(pdu->u.deliver_sm.destination_addr, 0,1);
776  pdu->u.deliver_sm.dest_addr_ton = GSM_ADDR_TON_INTERNATIONAL;
777  }
778 
779  /* check length of src/dst address */
780  if (octstr_len(pdu->u.deliver_sm.destination_addr) > 20 ||
781  octstr_len(pdu->u.deliver_sm.source_addr) > 20) {
782  smpp_pdu_destroy(pdu);
783  gwlist_destroy(pdulist, NULL);
784  return NULL;
785  }
786 
787  /*
788  * set the data coding scheme (DCS) field
789  * check if we have a forced value for this from the smsc-group.
790  * Note: if message class is set, then we _must_ force alt_dcs otherwise
791  * dcs has reserved values (e.g. mclass=2, dcs=0x11). We check MWI flag
792  * first here, because MWI and MCLASS can not be set at the same time and
793  * function fields_to_dcs check MWI first, so we have no need to force alt_dcs
794  * if MWI is set.
795  */
796  if (msg->sms.mwi == MWI_UNDEF && msg->sms.mclass != MC_UNDEF)
797  pdu->u.deliver_sm.data_coding = fields_to_dcs(msg, 1); /* force alt_dcs */
798  else
799  pdu->u.deliver_sm.data_coding = fields_to_dcs(msg,
800  (msg->sms.alt_dcs != SMS_PARAM_UNDEFINED ?
801  msg->sms.alt_dcs : box->alt_dcs));
802 
803  /* set protocol id */
804  if(msg->sms.pid != SMS_PARAM_UNDEFINED)
805  pdu->u.deliver_sm.protocol_id = msg->sms.pid;
806 
807  /*
808  * set the esm_class field
809  * default is store and forward, plus udh and rpi if requested
810  */
811  pdu->u.deliver_sm.esm_class = 0;
812  if (octstr_len(msg->sms.udhdata))
813  pdu->u.deliver_sm.esm_class = pdu->u.deliver_sm.esm_class |
815  if (msg->sms.rpi > 0)
816  pdu->u.deliver_sm.esm_class = pdu->u.deliver_sm.esm_class |
818 
819  /* Is this a delivery report? */
820  if (msg->sms.sms_type == report_mo) {
821  pdu->u.deliver_sm.esm_class |= ESM_CLASS_DELIVER_SMSC_DELIVER_ACK;
822  dlrtype = msg->sms.dlr_mask;
823  parts = octstr_split(msg->sms.dlr_url, octstr_imm(";"));
824  msgid = gwlist_extract_first(parts);
825  dlr = dlr_find(box->boxc_id, msgid, msg->sms.receiver, dlrtype, 0);
826  if (dlr == NULL) {
827  /* we could not find a corresponding dlr; nothing to send */
828  smpp_pdu_destroy(pdu);
829  gwlist_destroy(pdulist, NULL);
830  octstr_destroy(msgid);
832  return NULL;
833  }
834  dlvrd = octstr_imm("000");
835  switch (dlrtype) {
836  case DLR_UNDEFINED:
837  case DLR_NOTHING:
838  dlr_state = 8;
839  dlr_status = octstr_imm("REJECTD");
840  break;
841  case DLR_SUCCESS:
842  dlr_state = 2;
843  dlr_status = octstr_imm("DELIVRD");
844  dlvrd = octstr_imm("001");
845  break;
846  case DLR_BUFFERED:
847  dlr_state = 6;
848  dlr_status = octstr_imm("ACCEPTD");
849  break;
850  case DLR_SMSC_SUCCESS:
851  /* please note that this state does not quite conform to the SMMP v3.4 spec */
852  dlr_state = 0;
853  dlr_status = octstr_imm("BUFFRED");
854  break;
855  case DLR_FAIL:
856  case DLR_SMSC_FAIL:
857  dlr_state = 5;
858  dlr_status = octstr_imm("UNDELIV");
859  break;
860  }
861 
862  text = octstr_get_cstr(msg->sms.msgdata);
863 
864  tmps = strstr(text, "err:");
865  if (tmps != NULL) {
866  /* we can't use 0-padding with %s, if this is really required,
867  * then convert the numeric string to a real integer. - st */
868  snprintf(err, sizeof(err), "%3.3s", tmps + (4 * sizeof(char)));
869  tmps = strstr(tmps, " ");
870  text = tmps ? tmps + (1 * sizeof(char)) : "";
871  }
872 
873  tmps = strstr(text, "text:");
874  if (tmps != NULL) {
875  text = tmps + (5 * sizeof(char));
876  }
877 
878  /* restore original submission date from service */
879  submit_date = 0;
880  if (octstr_len(dlr->sms.service) > 0) {
881  sscanf(octstr_get_cstr(dlr->sms.service), "%ld", &submit_date);
882  }
883  if (!submit_date || submit_date > dlr->sms.time) {
884  submit_date = msg->sms.time;
885  }
886 
887  tm_tmp = gw_localtime(submit_date);
888  gw_strftime(submit_date_c_str, sizeof(submit_date_c_str), "%y%m%d%H%M", &tm_tmp);
889 
890  tm_tmp = gw_localtime(dlr->sms.time);
891  gw_strftime(done_date_c_str, sizeof(done_date_c_str), "%y%m%d%H%M", &tm_tmp);
892 
893  /* the msgids are in dlr->dlr_url as reported by Victor Luchitz */
895  parts = octstr_split(dlr->sms.dlr_url, octstr_imm(";"));
897  if (gwlist_len(parts) > 0) {
898  while ((msgid2 = gwlist_extract_first(parts)) != NULL) {
899  debug("opensmppbox", 0, "DLR for multipart message: sending %s.", octstr_get_cstr(msgid2));
900  pdu2 = smpp_pdu_create(deliver_sm, counter_increase(box->smpp_pdu_counter));
901  pdu2->u.deliver_sm.esm_class = pdu->u.deliver_sm.esm_class;
902  pdu2->u.deliver_sm.source_addr_ton = pdu->u.deliver_sm.source_addr_ton;
903  pdu2->u.deliver_sm.source_addr_npi = pdu->u.deliver_sm.source_addr_npi;
904  pdu2->u.deliver_sm.dest_addr_ton = pdu->u.deliver_sm.dest_addr_ton;
905  pdu2->u.deliver_sm.dest_addr_npi = pdu->u.deliver_sm.dest_addr_npi;
906  pdu2->u.deliver_sm.data_coding = pdu->u.deliver_sm.data_coding;
907  pdu2->u.deliver_sm.protocol_id = pdu->u.deliver_sm.protocol_id;
908  pdu2->u.deliver_sm.source_addr = octstr_duplicate(pdu->u.deliver_sm.source_addr);
909  pdu2->u.deliver_sm.destination_addr = octstr_duplicate(pdu->u.deliver_sm.destination_addr);
910  pdu2->u.deliver_sm.service_type = octstr_duplicate(pdu->u.deliver_sm.service_type);
911  if (box->version > 0x33) {
912  pdu2->u.deliver_sm.receipted_message_id = octstr_duplicate(msgid2);
913  pdu2->u.deliver_sm.message_state = dlr_state;
914  dict_destroy(pdu2->u.deliver_sm.tlv);
915  pdu2->u.deliver_sm.tlv = meta_data_get_values(msg->sms.meta_data, "smpp");
916  }
917  pdu2->u.deliver_sm.short_message = octstr_format("id:%S sub:001 dlvrd:%S submit date:%s done date:%s stat:%S err:%s text:%12s", msgid2, dlvrd, submit_date_c_str, done_date_c_str, dlr_status, err, text);
918  octstr_destroy(msgid2);
919  gwlist_append(pdulist, pdu2);
920  }
921  smpp_pdu_destroy(pdu);
922  }
923  else {
924  if (box->version > 0x33) {
925  pdu->u.deliver_sm.receipted_message_id = octstr_duplicate(msgid);
926  pdu->u.deliver_sm.message_state = dlr_state;
927  dict_destroy(pdu->u.deliver_sm.tlv);
928  pdu->u.deliver_sm.tlv = meta_data_get_values(msg->sms.meta_data, "smpp");
929  }
930  pdu->u.deliver_sm.short_message = octstr_format("id:%S sub:001 dlvrd:%S submit date:%s done date:%s stat:%S err:%s text:%12s", msgid, dlvrd, submit_date_c_str, done_date_c_str, dlr_status, err, text);
931  gwlist_append(pdulist, pdu);
932  }
933  octstr_destroy(msgid);
934  msg_destroy(dlr);
936  return pdulist;
937  }
938  else {
939  /* ask for the delivery reports if needed */
940  if (DLR_IS_SUCCESS_OR_FAIL(msg->sms.dlr_mask))
941  pdu->u.deliver_sm.registered_delivery = 1;
942  else if (DLR_IS_FAIL(msg->sms.dlr_mask) && !DLR_IS_SUCCESS(msg->sms.dlr_mask))
943  pdu->u.deliver_sm.registered_delivery = 2;
944  /*
945  * set data segments and length
946  */
947 
948  pdu->u.deliver_sm.short_message = octstr_duplicate(msg->sms.msgdata);
949 
950  }
951 
952 
953  /*
954  * only re-encoding if using default smsc charset that is defined via
955  * alt-charset in smsc group and if MT is not binary
956  */
957  if (msg->sms.coding == DC_7BIT || (msg->sms.coding == DC_UNDEF && octstr_len(msg->sms.udhdata))) {
958  /*
959  * consider 3 cases:
960  * a) data_coding 0xFX: encoding should always be GSM 03.38 charset
961  * b) data_coding 0x00: encoding may be converted according to alt-charset
962  * c) data_coding 0x00: assume GSM 03.38 charset if alt-charset is not defined
963  */
964  if ((pdu->u.deliver_sm.data_coding & 0xF0) ||
965  (!box->alt_charset && pdu->u.deliver_sm.data_coding == 0)) {
966  charset_utf8_to_gsm(pdu->u.deliver_sm.short_message);
967  }
968  else if (pdu->u.deliver_sm.data_coding == 0 && box->alt_charset) {
969  /*
970  * convert to the given alternative charset
971  */
972  if (charset_convert(pdu->u.deliver_sm.short_message, "UTF-8", octstr_get_cstr(box->alt_charset)) != 0)
973  error(0, "Failed to convert msgdata from charset <%s> to <%s>, will send as is.",
974  octstr_get_cstr(box->alt_charset), "UTF-8");
975  pdu->u.deliver_sm.sm_length = octstr_len(pdu->u.deliver_sm.short_message);
976  }
977  }
978 
979  /* prepend udh if present */
980  if (octstr_len(msg->sms.udhdata)) {
981  octstr_insert(pdu->u.deliver_sm.short_message, msg->sms.udhdata, 0);
982  }
983 
984  pdu->u.deliver_sm.sm_length = octstr_len(pdu->u.deliver_sm.short_message);
985 
986  /* set priority */
987  if (msg->sms.priority >= 0 && msg->sms.priority <= 3)
988  pdu->u.deliver_sm.priority_flag = msg->sms.priority;
989  else
990  pdu->u.deliver_sm.priority_flag = box->priority;
991 
992  /* set more messages to send */
993 /*
994  if (box->version > 0x33 && msg->sms.msg_left > 0)
995  pdu->u.deliver_sm.more_messages_to_send = 1;
996 */
997 
998  header = NULL;
999  footer = NULL;
1000  suffix = NULL;
1001  split_chars = NULL;
1002  catenate = 1;
1003  max_msgs = 255;
1004  if (catenate)
1005  msg_sequence = counter_increase(catenated_sms_counter) & 0xFF;
1006  else
1007  msg_sequence = 0;
1008 
1009  /* split sms */
1010  parts = sms_split(msg, header, footer, suffix, split_chars, catenate,
1011  msg_sequence, max_msgs, sms_max_length);
1012  msg_count = gwlist_len(parts);
1013 
1014  if ((msg_count > 1) && (box->version > 0x33)) {
1015  Octstr *use_message_payload_meta;
1016  long use_message_payload;
1017 
1018  use_message_payload_meta = meta_data_get_value(msg->sms.meta_data, "smpp", octstr_imm("use_message_payload"));
1019  use_message_payload = strtol(octstr_get_cstr(use_message_payload_meta), 0, 0);
1020 
1021  if (use_message_payload) {
1022  /* copy short message data to message_payload TLV */
1023  pdu->u.deliver_sm.message_payload = octstr_duplicate(pdu->u.deliver_sm.short_message);
1024  octstr_destroy(pdu->u.deliver_sm.short_message);
1025  pdu->u.deliver_sm.short_message = NULL;
1026  pdu->u.deliver_sm.sm_length = 0;
1027 
1028  /* pass the message as a single pdu */
1029  msg_count = 1;
1030  }
1031 
1032  octstr_destroy(use_message_payload_meta);
1033  }
1034 
1035  if (msg_count == 1) {
1036  /* don't create split_parts of sms fit into one */
1038  parts = NULL;
1039  }
1040 
1041  debug("SMPP", 0, "message length %ld, sending %ld message%s",
1042  octstr_len(msg->sms.msgdata), msg_count, msg_count == 1 ? "" : "s");
1043 
1044  if (parts) {
1045  while((msg2 = gwlist_extract_first(parts)) != NULL) {
1046  pdu2 = smpp_pdu_create(deliver_sm, counter_increase(box->smpp_pdu_counter));
1047  pdu2->u.deliver_sm.source_addr_ton = pdu->u.deliver_sm.source_addr_ton;
1048  pdu2->u.deliver_sm.source_addr_npi = pdu->u.deliver_sm.source_addr_npi;
1049  pdu2->u.deliver_sm.dest_addr_ton = pdu->u.deliver_sm.dest_addr_ton;
1050  pdu2->u.deliver_sm.dest_addr_npi = pdu->u.deliver_sm.dest_addr_npi;
1051  pdu2->u.deliver_sm.data_coding = pdu->u.deliver_sm.data_coding;
1052  pdu2->u.deliver_sm.protocol_id = pdu->u.deliver_sm.protocol_id;
1053  pdu2->u.deliver_sm.source_addr = octstr_duplicate(pdu->u.deliver_sm.source_addr);
1054  pdu2->u.deliver_sm.destination_addr = octstr_duplicate(pdu->u.deliver_sm.destination_addr);
1055  pdu2->u.deliver_sm.service_type = octstr_duplicate(pdu->u.deliver_sm.service_type);
1056 
1057  /* the following condition is currently always true */
1058  /* uncomment in case we're doing a SAR-split instead */
1059  if (/*octstr_len(msg2->sms.udhdata) > 0*/1) {
1060  pdu2->u.deliver_sm.esm_class = pdu->u.deliver_sm.esm_class | ESM_CLASS_DELIVER_UDH_INDICATOR;
1061  pdu2->u.deliver_sm.short_message = octstr_cat(msg2->sms.udhdata, msg2->sms.msgdata);
1062  }
1063  else {
1064  pdu2->u.deliver_sm.short_message = octstr_duplicate(msg2->sms.msgdata);
1065  }
1066 
1067  if (box->version > 0x33) {
1068  dict_destroy(pdu2->u.deliver_sm.tlv);
1069  pdu2->u.deliver_sm.tlv = meta_data_get_values(msg->sms.meta_data, "smpp");
1070  }
1071 
1072  gwlist_append(pdulist, pdu2);
1073  msg_destroy(msg2);
1074  }
1075 
1076  smpp_pdu_destroy(pdu);
1077  }
1078  else {
1079  if (box->version > 0x33) {
1080  dict_destroy(pdu->u.deliver_sm.tlv);
1081  pdu->u.deliver_sm.tlv = meta_data_get_values(msg->sms.meta_data, "smpp");
1082  }
1083 
1084  gwlist_append(pdulist, pdu);
1085  }
1086 
1087  return pdulist;
1088 }
1089 
1090 /*
1091  * Convert SMPP PDU to internal Msgs structure.
1092  * Return the Msg if all was fine and NULL otherwise, while getting
1093  * the failing reason delivered back in *reason.
1094  * XXX semantical check on the incoming values can be extended here.
1095  */
1096 static Msg *pdu_to_msg(Boxc *box, SMPP_PDU *pdu, long *reason)
1097 {
1098  Msg *msg;
1099  int ton, npi;
1100 
1101  gw_assert(pdu->type == submit_sm);
1102 
1103  msg = msg_create(sms);
1104  gw_assert(msg != NULL);
1105  msg->sms.sms_type = mt_push;
1106  *reason = SMPP_ESME_ROK;
1107 
1108  /*
1109  * Reset source addr to have a prefixed '+' in case we have an
1110  * intl. TON to allow backend boxes (ie. smsbox) to distinguish
1111  * between national and international numbers.
1112  */
1113  ton = pdu->u.submit_sm.source_addr_ton;
1114  npi = pdu->u.submit_sm.source_addr_npi;
1115  /* check source addr */
1116  if ((*reason = convert_addr_from_pdu(box->boxc_id, pdu->u.submit_sm.source_addr, ton, npi)) != SMPP_ESME_ROK)
1117  goto error;
1118  msg->sms.sender = pdu->u.submit_sm.source_addr;
1119  pdu->u.submit_sm.source_addr = NULL;
1120  msg->sms.service = octstr_duplicate(box->sms_service);
1121 
1122  /*
1123  * Follows SMPP spec. v3.4. issue 1.2
1124  * it's not allowed to have destination_addr NULL
1125  */
1126  if (pdu->u.submit_sm.destination_addr == NULL) {
1127  error(0, "SMPP[%s]: Mallformed destination_addr `%s', may not be empty. "
1128  "Discarding MO message.", octstr_get_cstr(box->boxc_id),
1129  octstr_get_cstr(pdu->u.submit_sm.destination_addr));
1130  *reason = SMPP_ESME_RINVDSTADR;
1131  goto error;
1132  }
1133 
1134  /* copy priority_flag into msg */
1135  if (pdu->u.submit_sm.priority_flag >= 0 && pdu->u.submit_sm.priority_flag <= 3) {
1136  msg->sms.priority = pdu->u.submit_sm.priority_flag;
1137  }
1138 
1139  /* Same reset of destination number as for source */
1140  ton = pdu->u.submit_sm.dest_addr_ton;
1141  npi = pdu->u.submit_sm.dest_addr_npi;
1142  /* check destination addr */
1143  if ((*reason = convert_addr_from_pdu(box->boxc_id, pdu->u.submit_sm.destination_addr, ton, npi)) != SMPP_ESME_ROK)
1144  goto error;
1145  msg->sms.receiver = pdu->u.submit_sm.destination_addr;
1146  pdu->u.submit_sm.destination_addr = NULL;
1147 
1148  /* SMSCs use service_type for billing information */
1149  msg->sms.binfo = pdu->u.submit_sm.service_type;
1150  pdu->u.submit_sm.service_type = NULL;
1151 
1152  if (pdu->u.submit_sm.esm_class & ESM_CLASS_SUBMIT_RPI)
1153  msg->sms.rpi = 1;
1154 
1155  /*
1156  * Check for message_payload if version > 0x33 and sm_length == 0
1157  * Note: SMPP spec. v3.4. doesn't allow to send both: message_payload & short_message!
1158  */
1159  if (box->version > 0x33 && pdu->u.submit_sm.sm_length == 0 && pdu->u.submit_sm.message_payload) {
1160  msg->sms.msgdata = pdu->u.submit_sm.message_payload;
1161  pdu->u.submit_sm.message_payload = NULL;
1162  }
1163  else {
1164  msg->sms.msgdata = pdu->u.submit_sm.short_message;
1165  pdu->u.submit_sm.short_message = NULL;
1166  }
1167 
1168  /*
1169  * Encode udh if udhi set
1170  * for reference see GSM03.40, section 9.2.3.24
1171  */
1172  if (pdu->u.submit_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR) {
1173  int udhl;
1174  udhl = octstr_get_char(msg->sms.msgdata, 0) + 1;
1175  debug("bb.sms.smpp",0,"SMPP[%s]: UDH length read as %d",
1176  octstr_get_cstr(box->boxc_id), udhl);
1177  if (udhl > octstr_len(msg->sms.msgdata)) {
1178  error(0, "SMPP[%s]: Mallformed UDH length indicator 0x%03x while message length "
1179  "0x%03lx. Discarding MO message.", octstr_get_cstr(box->boxc_id),
1180  udhl, octstr_len(msg->sms.msgdata));
1181  *reason = SMPP_ESME_RINVESMCLASS;
1182  goto error;
1183  }
1184  msg->sms.udhdata = octstr_copy(msg->sms.msgdata, 0, udhl);
1185  octstr_delete(msg->sms.msgdata, 0, udhl);
1186  }
1187 
1188  dcs_to_fields(&msg, pdu->u.submit_sm.data_coding);
1189 
1190  /* handle default data coding */
1191  switch (pdu->u.submit_sm.data_coding) {
1192  case 0x00: /* default SMSC alphabet */
1193  /*
1194  * try to convert from something interesting if specified so
1195  * unless it was specified binary, ie. UDH indicator was detected
1196  */
1197  if (box->alt_charset && msg->sms.coding != DC_8BIT) {
1198  if (charset_convert(msg->sms.msgdata, octstr_get_cstr(box->alt_charset), "UTF-8") != 0)
1199  error(0, "Failed to convert msgdata from charset <%s> to <%s>, will leave as is.",
1200  "UTF-8", octstr_get_cstr(box->alt_charset));
1201  msg->sms.coding = DC_7BIT;
1202  } else { /* assume GSM 03.38 7-bit alphabet */
1203  charset_gsm_to_utf8(msg->sms.msgdata);
1204  msg->sms.coding = DC_7BIT;
1205  }
1206  break;
1207  case 0x01: /* ASCII or IA5 - not sure if I need to do anything */
1208  case 0x03: /* ISO-8859-1 - do nothing */
1209  msg->sms.coding = DC_7BIT; break;
1210  case 0x02: /* 8 bit binary - do nothing */
1211  case 0x04: /* 8 bit binary - do nothing */
1212  msg->sms.coding = DC_8BIT; break;
1213  case 0x05: /* JIS - what do I do with that ? */
1214  break;
1215  case 0x06: /* Cyrllic - iso-8859-5, I'll convert to unicode */
1216  if (charset_convert(msg->sms.msgdata, "ISO-8859-5", "UCS-2BE") != 0)
1217  error(0, "Failed to convert msgdata from cyrllic to UCS-2, will leave as is");
1218  msg->sms.coding = DC_UCS2; break;
1219  case 0x07: /* Hebrew iso-8859-8, I'll convert to unicode */
1220  if (charset_convert(msg->sms.msgdata, "ISO-8859-8", "UCS-2BE") != 0)
1221  error(0, "Failed to convert msgdata from hebrew to UCS-2, will leave as is");
1222  msg->sms.coding = DC_UCS2; break;
1223  case 0x08: /* unicode UCS-2, yey */
1224  msg->sms.coding = DC_UCS2; break;
1225 
1226  /*
1227  * don't much care about the others,
1228  * you implement them if you feel like it
1229  */
1230 
1231  default:
1232  /*
1233  * some of smsc send with dcs from GSM 03.38 , but these are reserved in smpp spec.
1234  * So we just look decoded values from dcs_to_fields and if none there make our assumptions.
1235  * if we have an UDH indicator, we assume DC_8BIT.
1236  */
1237  if (msg->sms.coding == DC_UNDEF && pdu->u.submit_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR)
1238  msg->sms.coding = DC_8BIT;
1239  else if (msg->sms.coding == DC_7BIT || msg->sms.coding == DC_UNDEF) { /* assume GSM 7Bit , reencode */
1240  msg->sms.coding = DC_7BIT;
1241  charset_gsm_to_utf8(msg->sms.msgdata);
1242  }
1243  }
1244  msg->sms.pid = pdu->u.submit_sm.protocol_id;
1245 
1246  /* set priority flag */
1247  msg->sms.priority = pdu->u.submit_sm.priority_flag;
1248 
1249  /* ask for the delivery reports if needed */
1250  switch (pdu->u.submit_sm.registered_delivery & 0x03) {
1251  case 1:
1252  msg->sms.dlr_mask = (DLR_SUCCESS | DLR_FAIL | DLR_SMSC_FAIL);
1253  break;
1254  case 2:
1255  msg->sms.dlr_mask = (DLR_FAIL | DLR_SMSC_FAIL);
1256  break;
1257  default:
1258  msg->sms.dlr_mask = 0;
1259  break;
1260  }
1261  if (pdu->u.submit_sm.esm_class & (0x04|0x08)) {
1262  msg->sms.sms_type = report_mo;
1263  }
1264 
1265  if (box->version > 0x33) {
1266  if (msg->sms.meta_data == NULL)
1267  msg->sms.meta_data = octstr_create("");
1268  meta_data_set_values(msg->sms.meta_data, pdu->u.submit_sm.tlv, "smpp", 1);
1269  }
1270 
1271  msg->sms.time = time(NULL);
1272 
1273  /* set validity period if needed */
1274  if (pdu->u.submit_sm.validity_period) {
1275  msg->sms.validity = time(NULL) + timestamp_to_minutes(pdu->u.submit_sm.validity_period) * 60;
1276  }
1277 
1278 
1279  /* set schedule delivery time if needed */
1280  if (pdu->u.submit_sm.schedule_delivery_time) {
1281  msg->sms.deferred = time(NULL) + timestamp_to_minutes(pdu->u.submit_sm.schedule_delivery_time) * 60;
1282  }
1283 
1284  return msg;
1285 
1286 error:
1287  msg_destroy(msg);
1288  return NULL;
1289 }
1290 
1291 
1292 /*
1293  * Convert SMPP PDU to internal Msgs structure.
1294  * Return the Msg if all was fine and NULL otherwise, while getting
1295  * the failing reason delivered back in *reason.
1296  * XXX semantical check on the incoming values can be extended here.
1297  */
1298 static Msg *data_sm_to_msg(Boxc *box, SMPP_PDU *pdu, long *reason)
1299 {
1300  Msg *msg;
1301  int ton, npi;
1302 
1303  gw_assert(pdu->type == data_sm);
1304 
1305  msg = msg_create(sms);
1306  gw_assert(msg != NULL);
1307  msg->sms.sms_type = mt_push;
1308  *reason = SMPP_ESME_ROK;
1309 
1310  /*
1311  * Reset source addr to have a prefixed '+' in case we have an
1312  * intl. TON to allow backend boxes (ie. smsbox) to distinguish
1313  * between national and international numbers.
1314  */
1315  ton = pdu->u.data_sm.source_addr_ton;
1316  npi = pdu->u.data_sm.source_addr_npi;
1317  /* check source addr */
1318  if ((*reason = convert_addr_from_pdu(box->boxc_id, pdu->u.data_sm.source_addr, ton, npi)) != SMPP_ESME_ROK)
1319  goto error;
1320  msg->sms.sender = pdu->u.data_sm.source_addr;
1321  pdu->u.data_sm.source_addr = NULL;
1322 
1323  /*
1324  * Follows SMPP spec. v3.4. issue 1.2
1325  * it's not allowed to have destination_addr NULL
1326  */
1327  if (pdu->u.data_sm.destination_addr == NULL) {
1328  error(0, "SMPP[%s]: Mallformed destination_addr `%s', may not be empty. "
1329  "Discarding MO message.", octstr_get_cstr(box->boxc_id),
1330  octstr_get_cstr(pdu->u.data_sm.destination_addr));
1331  *reason = SMPP_ESME_RINVDSTADR;
1332  goto error;
1333  }
1334 
1335  /* Same reset of destination number as for source */
1336  ton = pdu->u.data_sm.dest_addr_ton;
1337  npi = pdu->u.data_sm.dest_addr_npi;
1338  /* check destination addr */
1339  if ((*reason = convert_addr_from_pdu(box->boxc_id, pdu->u.data_sm.destination_addr, ton, npi)) != SMPP_ESME_ROK)
1340  goto error;
1341  msg->sms.receiver = pdu->u.data_sm.destination_addr;
1342  pdu->u.data_sm.destination_addr = NULL;
1343 
1344  /* SMSCs use service_type for billing information */
1345  msg->sms.binfo = pdu->u.data_sm.service_type;
1346  pdu->u.data_sm.service_type = NULL;
1347 
1348  if (pdu->u.data_sm.esm_class & ESM_CLASS_SUBMIT_RPI)
1349  msg->sms.rpi = 1;
1350 
1351  msg->sms.msgdata = pdu->u.data_sm.message_payload;
1352  pdu->u.data_sm.message_payload = NULL;
1353 
1354  /*
1355  * Encode udh if udhi set
1356  * for reference see GSM03.40, section 9.2.3.24
1357  */
1358  if (pdu->u.data_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR) {
1359  int udhl;
1360  udhl = octstr_get_char(msg->sms.msgdata, 0) + 1;
1361  debug("bb.sms.smpp",0,"SMPP[%s]: UDH length read as %d",
1362  octstr_get_cstr(box->boxc_id), udhl);
1363  if (udhl > octstr_len(msg->sms.msgdata)) {
1364  error(0, "SMPP[%s]: Mallformed UDH length indicator 0x%03x while message length "
1365  "0x%03lx. Discarding MO message.", octstr_get_cstr(box->boxc_id),
1366  udhl, octstr_len(msg->sms.msgdata));
1367  *reason = SMPP_ESME_RINVESMCLASS;
1368  goto error;
1369  }
1370  msg->sms.udhdata = octstr_copy(msg->sms.msgdata, 0, udhl);
1371  octstr_delete(msg->sms.msgdata, 0, udhl);
1372  }
1373 
1374  dcs_to_fields(&msg, pdu->u.data_sm.data_coding);
1375 
1376  /* handle default data coding */
1377  switch (pdu->u.data_sm.data_coding) {
1378  case 0x00: /* default SMSC alphabet */
1379  /*
1380  * try to convert from something interesting if specified so
1381  * unless it was specified binary, ie. UDH indicator was detected
1382  */
1383  if (box->alt_charset && msg->sms.coding != DC_8BIT) {
1384  if (charset_convert(msg->sms.msgdata, "UTF-8", octstr_get_cstr(box->alt_charset)) != 0)
1385  error(0, "Failed to convert msgdata from charset <%s> to <%s>, will leave as is.",
1386  "UTF-8", octstr_get_cstr(box->alt_charset));
1387  msg->sms.coding = DC_7BIT;
1388  } else { /* assume GSM 03.38 7-bit alphabet */
1389  charset_gsm_to_utf8(msg->sms.msgdata);
1390  msg->sms.coding = DC_7BIT;
1391  }
1392  break;
1393  case 0x01: /* ASCII or IA5 - not sure if I need to do anything */
1394  case 0x03: /* ISO-8859-1 - do nothing */
1395  msg->sms.coding = DC_7BIT; break;
1396  case 0x02: /* 8 bit binary - do nothing */
1397  case 0x04: /* 8 bit binary - do nothing */
1398  msg->sms.coding = DC_8BIT; break;
1399  case 0x05: /* JIS - what do I do with that ? */
1400  break;
1401  case 0x06: /* Cyrllic - iso-8859-5, I'll convert to unicode */
1402  if (charset_convert(msg->sms.msgdata, "ISO-8859-5", "UCS-2BE") != 0)
1403  error(0, "Failed to convert msgdata from cyrllic to UCS-2, will leave as is");
1404  msg->sms.coding = DC_UCS2; break;
1405  case 0x07: /* Hebrew iso-8859-8, I'll convert to unicode */
1406  if (charset_convert(msg->sms.msgdata, "ISO-8859-8", "UCS-2BE") != 0)
1407  error(0, "Failed to convert msgdata from hebrew to UCS-2, will leave as is");
1408  msg->sms.coding = DC_UCS2; break;
1409  case 0x08: /* unicode UCS-2, yey */
1410  msg->sms.coding = DC_UCS2; break;
1411 
1412  /*
1413  * don't much care about the others,
1414  * you implement them if you feel like it
1415  */
1416 
1417  default:
1418  /*
1419  * some of smsc send with dcs from GSM 03.38 , but these are reserved in smpp spec.
1420  * So we just look decoded values from dcs_to_fields and if none there make our assumptions.
1421  * if we have an UDH indicator, we assume DC_8BIT.
1422  */
1423  if (msg->sms.coding == DC_UNDEF && pdu->u.data_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR)
1424  msg->sms.coding = DC_8BIT;
1425  else if (msg->sms.coding == DC_7BIT || msg->sms.coding == DC_UNDEF) { /* assume GSM 7Bit , reencode */
1426  msg->sms.coding = DC_7BIT;
1427  charset_gsm_to_utf8(msg->sms.msgdata);
1428  }
1429  }
1430 
1431  if (box->version > 0x33) {
1432  if (msg->sms.meta_data == NULL)
1433  msg->sms.meta_data = octstr_create("");
1434  meta_data_set_values(msg->sms.meta_data, pdu->u.data_sm.tlv, "smpp", 1);
1435  }
1436 
1437  msg->sms.time = time(NULL);
1438 
1439  return msg;
1440 
1441 error:
1442  msg_destroy(msg);
1443  return NULL;
1444 }
1445 
1447 {
1448  Octstr *ret = octstr_duplicate(msgid);
1449  int i;
1450  Msg *msg;
1451 
1452  for (i = 0; i < gwlist_len(list); i++) {
1453  msg = gwlist_get(list, i);
1454  octstr_append(ret, octstr_imm(";"));
1455  octstr_append(ret, msg->sms.dlr_url);
1456  }
1457  return ret;
1458 }
1459 
1460 void check_multipart(Boxc *box, Msg *msg, int *msg_to_send, Msg **msg2, List **parts_list)
1461 {
1462  int reference, total;
1463  Octstr *key;
1464 
1465  if (msg->sms.udhdata && octstr_len(msg->sms.udhdata) == 6 && octstr_get_char(msg->sms.udhdata, 1) == 0) {
1466  /* We collect long messages as one and send them to bearerbox as a whole, so they can be sent
1467  from the same smsc. */
1468  (*msg_to_send) = 0;
1469  debug("opensmppbox", 0, "assemble multi-part message.");
1470  reference = octstr_get_char(msg->sms.udhdata, 3);
1471  total = octstr_get_char(msg->sms.udhdata, 4);
1472  key = octstr_format("%S-%i", msg->sms.receiver, reference);
1473  (*parts_list) = dict_get(list_dict, key);
1474  if (NULL == (*parts_list)) {
1475  (*parts_list) = gwlist_create();
1476  dict_put(list_dict, key, (*parts_list));
1477  }
1478  debug("opensmppbox", 0, "received %ld of %d.", gwlist_len((*parts_list)) + 1, total);
1479  if ((gwlist_len((*parts_list)) + 1) == total) {
1480  debug("opensmppbox", 0, "received all parts of multi-part message.");
1481  gwlist_append((*parts_list), msg);
1482  /* assemble message */
1483  (*msg2) = catenate_msg((*parts_list), total);
1484  dict_put(list_dict, key, NULL);
1485  octstr_destroy(key);
1486  if (NULL == (*msg2)) {
1487  /* we could not assemble an appropiate message */
1488  debug("opensmppbox", 0, "Invalid multi-part message.");
1489 
1490  }
1491  else {
1492  Octstr *smsc_id = boxc_route_msg_to_smsc(box, *msg2);
1493  (*msg2)->sms.smsc_id = smsc_id ? octstr_duplicate(smsc_id) : NULL;
1494  (*msg2)->sms.boxc_id = octstr_duplicate(box->boxc_id);
1495  debug("opensmppbox", 0, "multi-part message, length: %ld.", octstr_len((*msg2)->sms.msgdata));
1496  (*msg_to_send) = 1;
1497  }
1498  }
1499  else {
1500  gwlist_append((*parts_list), msg);
1501  octstr_destroy(key);
1502  }
1503  }
1504 }
1505 
1506 static void handle_pdu(Connection *conn, Boxc *box, SMPP_PDU *pdu) {
1507  SMPP_PDU *resp = NULL;
1508  Msg *msg, *msg2, *mack;
1509  long reason;
1510  Octstr *msgid = NULL, *hold_service, *system_type;
1511  int msg_to_send = 1;
1512  List *parts_list = NULL;
1513  char id[UUID_STR_LEN + 1];
1514 
1515  dump_pdu("Got PDU:", box->boxc_id, pdu);
1516  switch (pdu->type) {
1517  case bind_transmitter:
1518  case bind_receiver:
1519  case bind_transceiver:
1520  break;
1521  default:
1522  if (!box->logged_in) {
1523  resp = smpp_pdu_create(generic_nack, pdu->u.generic_nack.sequence_number);
1524  resp->u.generic_nack.command_status = SMPP_ESME_RINVPASWD;
1525  goto error;
1526  }
1527  break;
1528  }
1529  switch (pdu->type) {
1530  case bind_transmitter:
1531  system_type = pdu->u.bind_transmitter.system_type ? pdu->u.bind_transmitter.system_type : octstr_imm("");
1532  if (check_login(box, pdu->u.bind_transmitter.system_id, pdu->u.bind_transmitter.password, system_type, SMPP_LOGIN_TRANSMITTER)) {
1533  box->logged_in = 1;
1534  box->version = pdu->u.bind_transmitter.interface_version;
1536  box->boxc_id = systemidisboxcid ? octstr_duplicate(pdu->u.bind_transmitter.system_id) : octstr_duplicate(system_type);
1537  box->sms_service = octstr_duplicate(pdu->u.bind_transmitter.system_id);
1538  identify_to_bearerbox(box);
1539  resp = smpp_pdu_create(bind_transmitter_resp, pdu->u.bind_transmitter.sequence_number);
1540  resp->u.bind_transmitter_resp.system_id = octstr_duplicate(our_system_id);
1541  }
1542  else {
1543  resp = smpp_pdu_create(bind_transmitter_resp, pdu->u.bind_transmitter_resp.sequence_number);
1544  resp->u.bind_transmitter.command_status = 0x0d; /* invalid login */
1545  }
1546  break;
1547  case bind_receiver:
1548  system_type = pdu->u.bind_receiver.system_type ? pdu->u.bind_receiver.system_type : octstr_imm("");
1549  if (check_login(box, pdu->u.bind_receiver.system_id, pdu->u.bind_receiver.password, system_type, SMPP_LOGIN_RECEIVER)) {
1550  box->logged_in = 1;
1551  box->version = pdu->u.bind_receiver.interface_version;
1553  box->boxc_id = systemidisboxcid ? octstr_duplicate(pdu->u.bind_transmitter.system_id) : octstr_duplicate(system_type);
1554  box->sms_service = octstr_duplicate(pdu->u.bind_receiver.system_id);
1555  identify_to_bearerbox(box);
1556  resp = smpp_pdu_create(bind_receiver_resp, pdu->u.bind_receiver.sequence_number);
1557  resp->u.bind_receiver_resp.system_id = octstr_duplicate(our_system_id);
1558  }
1559  else {
1560  resp = smpp_pdu_create(bind_receiver_resp, pdu->u.bind_receiver.sequence_number);
1561  resp->u.bind_receiver_resp.command_status = 0x0d; /* invalid login */
1562  }
1563  break;
1564  case bind_transceiver:
1565  system_type = pdu->u.bind_transceiver.system_type ? pdu->u.bind_transceiver.system_type : octstr_imm("");
1566  if (check_login(box, pdu->u.bind_transceiver.system_id, pdu->u.bind_transceiver.password, system_type, SMPP_LOGIN_TRANSCEIVER)) {
1567  box->logged_in = 1;
1568  box->version = pdu->u.bind_transceiver.interface_version;
1570  box->boxc_id = systemidisboxcid ? octstr_duplicate(pdu->u.bind_transmitter.system_id) : octstr_duplicate(system_type);
1571  box->sms_service = octstr_duplicate(pdu->u.bind_transceiver.system_id);
1572  identify_to_bearerbox(box);
1573  resp = smpp_pdu_create(bind_transceiver_resp, pdu->u.bind_transceiver.sequence_number);
1574  resp->u.bind_transceiver_resp.system_id = octstr_duplicate(our_system_id);
1575  }
1576  else {
1577  resp = smpp_pdu_create(bind_transceiver_resp, pdu->u.bind_transceiver.sequence_number);
1578  resp->u.bind_transceiver_resp.command_status = 0x0d; /* invalid login */
1579  }
1580  break;
1581  case unbind:
1582  resp = smpp_pdu_create(unbind_resp, pdu->u.unbind.sequence_number);
1583  box->logged_in = 0;
1584  box->alive = 0;
1585  break;
1586  case enquire_link:
1587  resp = smpp_pdu_create(enquire_link_resp,
1588  pdu->u.enquire_link.sequence_number);
1589  break;
1590  case data_sm:
1591  msg = data_sm_to_msg(box, pdu, &reason);
1592  msg2 = msg;
1593  if (msg == NULL) {
1594  resp = smpp_pdu_create(generic_nack, pdu->u.data_sm.sequence_number);
1595  resp->u.generic_nack.command_status = SMPP_ESME_RUNKNOWNERR;
1596  }
1597  else {
1598  Octstr *smsc_id = boxc_route_msg_to_smsc(box, msg);
1599  check_multipart(box, msg, &msg_to_send, &msg2, &parts_list);
1600  msg->sms.smsc_id = smsc_id ? octstr_duplicate(smsc_id) : NULL;
1601  msg->sms.boxc_id = octstr_duplicate(box->boxc_id);
1602  msg_dump(msg, 0);
1603  resp = smpp_pdu_create(data_sm_resp, pdu->u.data_sm.sequence_number);
1604  msgid = generate_smppid(msg, box->version);
1605  msg->sms.dlr_url = octstr_duplicate(msgid);
1606  resp->u.data_sm_resp.message_id = msgid;
1607  if (msg_to_send) {
1608  if (DLR_IS_ENABLED(msg2->sms.dlr_mask)) {
1609  hold_service = msg2->sms.service;
1610  msg2->sms.service = octstr_format("%ld", msg2->sms.time);
1611  msgid = generate_smppid(msg2, box->version);
1612  if (parts_list) {
1613  msg2->sms.dlr_url = concat_msgids(msgid, parts_list);
1614  }
1615  dlr_add(box->boxc_id, msgid, msg2, 0);
1616  octstr_destroy(msgid);
1617  octstr_destroy(msg2->sms.service);
1618  msg2->sms.service = hold_service;
1619  }
1620  uuid_unparse(msg2->sms.id, id);
1621  msgid = octstr_create(id);
1622  dict_put(box->msg_acks, msgid, resp);
1623  resp = NULL;
1624  send_msg(box->bearerbox_connection, box, msg2);
1625  if (parts_list) {
1626  /* destroy values */
1627  gwlist_destroy(parts_list, msg_destroy_item);
1628  }
1629  else if (msg != msg2) {
1630  msg_destroy(msg);
1631  }
1632  }
1633  }
1634  break;
1635  case submit_sm:
1636  msg = pdu_to_msg(box, pdu, &reason);
1637  msg2 = msg;
1638  if (msg == NULL) {
1639  resp = smpp_pdu_create(generic_nack, pdu->u.submit_sm.sequence_number);
1640  resp->u.generic_nack.command_status = SMPP_ESME_RUNKNOWNERR;
1641  }
1642  else {
1643  Octstr *smsc_id = boxc_route_msg_to_smsc(box, msg);
1644  check_multipart(box, msg, &msg_to_send, &msg2, &parts_list);
1645  msg->sms.smsc_id = smsc_id ? octstr_duplicate(smsc_id) : NULL;
1646  msg->sms.boxc_id = octstr_duplicate(box->boxc_id);
1647  msg_dump(msg, 0);
1648  resp = smpp_pdu_create(submit_sm_resp, pdu->u.submit_sm.sequence_number);
1649  msgid = generate_smppid(msg, box->version);
1650  msg->sms.dlr_url = octstr_duplicate(msgid);
1651  resp->u.submit_sm_resp.message_id = msgid;
1652  if (msg_to_send) {
1653  if (DLR_IS_ENABLED(msg2->sms.dlr_mask)) {
1654  hold_service = msg2->sms.service;
1655  msg2->sms.service = octstr_format("%ld", msg2->sms.time);
1656  msgid = generate_smppid(msg2, box->version);
1657  if (parts_list) {
1658  msg2->sms.dlr_url = concat_msgids(msgid, parts_list);
1659  }
1660  dlr_add(box->boxc_id, msgid, msg2, 0);
1661  octstr_destroy(msgid);
1662  octstr_destroy(msg2->sms.service);
1663  msg2->sms.service = hold_service;
1664  }
1665  uuid_unparse(msg2->sms.id, id);
1666  msgid = octstr_create(id);
1667  dict_put(box->msg_acks, msgid, resp);
1668  octstr_destroy(msgid);
1669  resp = NULL;
1670  send_msg(box->bearerbox_connection, box, msg2);
1671  if (parts_list) {
1672  /* destroy values */
1673  gwlist_destroy(parts_list, msg_destroy_item);
1674  }
1675  else if (msg != msg2) {
1676  msg_destroy(msg);
1677  }
1678  }
1679  }
1680  break;
1681  case deliver_sm_resp:
1682  msgid = octstr_format("%ld", pdu->u.deliver_sm_resp.sequence_number);
1683  mack = dict_get(box->deliver_acks, msgid);
1684  if (mack) {
1685  msg = msg_duplicate(mack);
1686  /* TODO: ack_failed_tmp */
1687  if (pdu->u.deliver_sm_resp.command_status != 0) {
1688  msg->ack.nack = ack_failed;
1689  }
1690  send_msg(box->bearerbox_connection, box, msg);
1691  dict_put(box->deliver_acks, msgid, NULL);
1692  }
1693  octstr_destroy(msgid);
1694  break;
1695  case unbind_resp:
1696  box->logged_in = 0;
1697  box->alive = 0;
1698  default:
1699  error(0, "SMPP[%s]: Unknown PDU type 0x%08lx, ignored.",
1700  octstr_get_cstr(box->boxc_id), pdu->type);
1701  /*
1702  send gnack , see smpp3.4 spec., section 3.3
1703  because we doesn't know what kind of pdu received, we assume generick_nack_resp
1704  (header always the same)
1705  */
1706  resp = smpp_pdu_create(generic_nack, pdu->u.generic_nack.sequence_number);
1707  resp->u.generic_nack.command_status = SMPP_ESME_RINVCMDID;
1708  break;
1709  }
1710 error:
1711  smpp_pdu_destroy(pdu);
1712  if (resp != NULL) {
1713  send_pdu(conn, box->boxc_id, resp);
1714  smpp_pdu_destroy(resp);
1715  }
1716 }
1717 
1718 /*
1719  *-------------------------------------------------
1720  * sender thingies
1721  *-------------------------------------------------
1722  *
1723 */
1724 
1725 static Boxc *boxc_create(int fd, Octstr *ip, int ssl)
1726 {
1727  Boxc *boxc;
1728 
1729  boxc = gw_malloc(sizeof(Boxc));
1730  boxc->logged_in = 0;
1731  boxc->is_wap = 0;
1732  boxc->load = 0;
1733  boxc->smpp_connection = conn_wrap_fd(fd, ssl);
1734  boxc->id = counter_increase(boxid);
1735  boxc->client_ip = octstr_duplicate(ip);
1736  boxc->alive = 1;
1737  boxc->connect_time = time(NULL);
1738  boxc->boxc_id = NULL;
1739  boxc->routable = 0;
1740  boxc->smpp_pdu_counter = counter_create();
1741  boxc->alt_charset = NULL;
1742  if (NULL != alt_charset) boxc->alt_charset = octstr_duplicate(alt_charset); /* todo: make this configurable on a per-esme basis */
1743  boxc->version = 0x33; /* default value, set upon receiving a bind */
1744  boxc->route_to_smsc = route_to_smsc ? octstr_duplicate(route_to_smsc) : NULL;
1747 
1748  boxc->service_type = NULL;
1749 
1755 
1756  boxc->alt_dcs = 0;
1757  boxc->validityperiod = -1;
1758  boxc->priority = 0;
1759  boxc->mo_recode = 0;
1760  boxc->sms_service = NULL;
1761 
1762  return boxc;
1763 }
1764 
1765 static void boxc_destroy(Boxc *boxc)
1766 {
1767  if (boxc == NULL)
1768  return;
1769 
1770  /* do nothing to the lists, as they are only references */
1771 
1772  if (boxc->smpp_connection)
1774  if (boxc->bearerbox_connection)
1776  if (boxc->boxc_id)
1777  octstr_destroy(boxc->boxc_id);
1778  if (boxc->alt_charset)
1779  octstr_destroy(boxc->alt_charset);
1781  if (boxc->route_to_smsc) {
1783  }
1784  if (boxc->client_ip)
1785  octstr_destroy(boxc->client_ip);
1786  if (boxc->alt_charset) {
1787  octstr_destroy(boxc->alt_charset);
1788  }
1789  dict_destroy(boxc->msg_acks);
1790  dict_destroy(boxc->deliver_acks);
1791  if (boxc->sms_service)
1792  octstr_destroy(boxc->sms_service);
1793  gw_free(boxc);
1794 }
1795 
1797 {
1798  Octstr *os = NULL, *smsc_id;
1799 
1800  if (msg->sms.smsc_id != NULL)
1801  return msg->sms.smsc_id;
1802 
1803  char *receiver = octstr_get_cstr(msg->sms.receiver);
1804  if ( (receiver) && (strlen(receiver) > 0) ) {
1805  smsc_id = dict_get(smsc_by_receiver, msg->sms.receiver);
1806  }
1807  else {
1808  receiver = "";
1809  }
1810 
1811  if (!smsc_id) {
1812  os = octstr_format("%s:%s", octstr_get_cstr(msg->sms.sender),
1813  octstr_get_cstr(box->boxc_id));
1814  smsc_id = dict_get(smsc_by_sender_smsbox_id, os);
1815  octstr_destroy(os);
1816  };
1817  if (!smsc_id)
1818  smsc_id = dict_get(smsc_by_sender, msg->sms.sender);
1819  if (!smsc_id)
1820  smsc_id = dict_get(smsc_by_smsbox_id, box->boxc_id);
1821  if (!smsc_id)
1822  smsc_id = box->route_to_smsc;
1823 
1824  if (smsc_id)
1825  debug("opensmppbox", 0, "routed msg '%s' to smsc '%s'",
1826  receiver, octstr_get_cstr(smsc_id));
1827 
1828  return smsc_id;
1829 }
1830 
1831 /* ------------------------------------------------------------------
1832  * SMPP thingies
1833  * ------------------------------------------------------------------
1834 */
1835 
1836 /* generally, SMPP connections are always non-encrypted. */
1837 static Boxc *accept_smpp(int fd, int ssl)
1838 {
1839  Boxc *newconn;
1840  Octstr *ip;
1841 
1842  int newfd;
1843  struct sockaddr_in client_addr;
1844  socklen_t client_addr_len;
1845 
1846  client_addr_len = sizeof(client_addr);
1847 
1848  newfd = accept(fd, (struct sockaddr *)&client_addr, &client_addr_len);
1849  if (newfd < 0)
1850  return NULL;
1851 
1852  ip = host_ip(client_addr);
1853 
1854  newconn = boxc_create(newfd, ip, 0);
1855 
1856  /*
1857  * check if the SSL handshake was successfull, otherwise
1858  * this is no valid box connection any more
1859  */
1860 #ifdef HAVE_LIBSSL
1861  if (ssl && !conn_get_ssl(newconn->smpp_connection))
1862  return NULL;
1863 #endif
1864 
1865  info(0, "Client connected from <%s>", octstr_get_cstr(ip));
1866  octstr_destroy(ip);
1867 
1868  /* XXX TODO: do the hand-shake, baby, yeah-yeah! */
1869 
1870  return newconn;
1871 }
1872 
1873 static void smpp_to_bearerbox(void *arg)
1874 {
1875  Boxc *box = arg;
1877  SMPP_PDU *pdu;
1878  long len;
1879 
1880  box->last_pdu_received = time(NULL);
1881  len = 0;
1882  while (smppbox_status == SMPP_RUNNING && box->alive) {
1883  switch (read_pdu(box, conn, &len, &pdu)) {
1884  case -1:
1885  error(0, "Invalid SMPP PDU received.");
1886  box->alive = 0;
1887  break;
1888  case 0:
1889  // idling
1890  if (time(NULL) - box->last_pdu_received > smpp_timeout) {
1891  box->alive = 0;
1892  }
1893  gwthread_sleep(1);
1894  break;
1895  case 1:
1896  box->last_pdu_received = time(NULL);
1897  handle_pdu(conn, box, pdu);
1898  break;
1899  }
1900  }
1901 #ifdef HAVE_SHUTDOWN_CONNECTION
1902  shutdown_connection(box->bearerbox_connection);
1903 #endif
1904 }
1905 
1906 /* if this login was made as a transmitter, then find the corresponding receiver connection */
1908 {
1909  Boxc *thisbox;
1910  int cnt;
1911 
1913  return box;
1914  }
1915  for (cnt = 0; cnt < gwlist_len(all_boxes); cnt++) {
1916  thisbox = (Boxc *)gwlist_get(all_boxes, cnt);
1917  if ((thisbox->login_type == SMPP_LOGIN_RECEIVER || thisbox->login_type == SMPP_LOGIN_TRANSCEIVER) && (octstr_compare(thisbox->boxc_id, box->boxc_id) == 0) && thisbox->alive) {
1918  return thisbox;
1919  }
1920  }
1921  return box;
1922 }
1923 
1924 static void bearerbox_to_smpp(void *arg)
1925 {
1926  Msg *msg, *mack;
1927  Boxc *box = arg;
1928  SMPP_PDU *pdu;
1929  List *pdulist;
1930  int dreport, errcode;
1931  Boxc *receiver_box;
1932  char id[UUID_STR_LEN + 1];
1933  Octstr *msgid;
1934 
1935  while (smppbox_status == SMPP_RUNNING && box->alive) {
1936 
1937  msg = read_from_box(box->bearerbox_connection, box);
1938  if (msg == NULL) {
1939  if ((!box->alive) || conn_eof(box->bearerbox_connection)) {
1940  /* tell opensmppbox to die */
1941  /* the client closes the connection, after that die in receiver */
1942  box->alive = 0;
1943  }
1944  continue;
1945  }
1946  if (msg_type(msg) == admin) {
1947  if (msg->admin.command == cmd_shutdown) {
1948  info(0, "Bearerbox told us to die");
1949  box->alive = 0;
1950  } else if (msg->admin.command == cmd_restart) {
1951  info(0, "Bearerbox told us to restart");
1952  restart = 1;
1953  box->alive = 0;
1954  }
1955  }
1956  if (msg_type(msg) == heartbeat) {
1957  // todo
1958  debug("opensmppbox", 0, "bearerbox_to_smpp: catch an heartbeat - we are alive");
1959  msg_destroy(msg);
1960  continue;
1961  }
1962  if (msg_type(msg) == ack) {
1963  uuid_unparse(msg->ack.id, id);
1964  msgid = octstr_create(id);
1965  pdu = dict_get(box->msg_acks, msgid);
1966  errcode = SMPP_ESME_RMSGQFUL; /* in case we get ack_failed_tmp */
1967  if (pdu) {
1968  switch (msg->ack.nack) {
1969  case ack_buffered:
1970  case ack_success:
1971  /* we can send the submit_sm_resp as-is */
1972  break;
1973  case ack_failed:
1974  errcode = SMPP_ESME_RSUBMITFAIL;
1975  /* no break */
1976  case ack_failed_tmp:
1977  switch (pdu->type) {
1978  case submit_sm_resp:
1979  octstr_destroy(pdu->u.submit_sm_resp.message_id);
1980  pdu->u.submit_sm_resp.message_id = NULL;
1981  pdu->u.submit_sm_resp.command_status = errcode;
1982  break;
1983  case data_sm_resp:
1984  octstr_destroy(pdu->u.data_sm_resp.message_id);
1985  pdu->u.data_sm_resp.message_id = NULL;
1986  pdu->u.data_sm_resp.command_status = errcode;
1987  break;
1988  default:
1989  debug("opensmppbox", 0, "Getting failure ack on unexpected pdu: %s.", pdu->type_name);
1990  break;
1991  }
1992  break;
1993  default:
1994  debug("opensmppbox", 0, "Unknown ack.nack type: %ld.", msg->ack.nack);
1995  break;
1996  }
1997  send_pdu(box->smpp_connection, box->boxc_id, pdu);
1998  dict_put(box->msg_acks, msgid, NULL); /* also destroys item */
1999  }
2000  else {
2001  debug("opensmppbox", 0, "Ack to unknown message: %s.", id);
2002  }
2003  octstr_destroy(msgid);
2004  }
2005  if (!box->alive) {
2006  msg_destroy(msg);
2007  break;
2008  }
2009  if (msg_type(msg) == sms) {
2010  info(0, "We received an SMS message.");
2011  if (msg->sms.sms_type == report_mo)
2012  dreport = 1;
2013  else
2014  dreport = 0;
2015  /* Recode to iso-8859-1 the MO message if possible */
2016  if (box->mo_recode && msg->sms.coding == DC_UCS2) {
2017  int converted = 0;
2018  Octstr *text;
2019 
2020  text = octstr_duplicate(msg->sms.msgdata);
2021  if(0 == octstr_recode (octstr_imm("UTF-8"), octstr_imm("UTF-16BE"), text)) {
2022  if(octstr_search(text, octstr_imm("&#"), 0) == -1) {
2023  /* XXX I'm trying to search for &#xxxx; text, which indicates that the
2024  * text couldn't be recoded.
2025  * We should use other function to do the recode or detect it using
2026  * other method */
2027  info(0, "MO message converted from UCS-2 to UTF-8");
2028  octstr_destroy(msg->sms.msgdata);
2029  msg->sms.msgdata = octstr_duplicate(text);
2030  msg->sms.charset = octstr_create("UTF-8");
2031  msg->sms.coding = DC_7BIT;
2032  converted=1;
2033  } else {
2034  octstr_destroy(text);
2035  text = octstr_duplicate(msg->sms.msgdata);
2036  }
2037  }
2038  if(!converted && 0 == octstr_recode (octstr_imm("UTF-8"), octstr_imm("UTF-16BE"), text)) {
2039  if(octstr_search(text, octstr_imm("&#"), 0) == -1) {
2040  /* XXX I'm trying to search for &#xxxx; text, which indicates that the
2041  * text couldn't be recoded.
2042  * We should use other function to do the recode or detect it using
2043  * other method */
2044  info(0, "MO message converted from UCS-2 to UTF-8");
2045  octstr_destroy(msg->sms.msgdata);
2046  msg->sms.msgdata = octstr_duplicate(text);
2047  msg->sms.charset = octstr_create("UTF-8");
2048  msg->sms.coding = DC_7BIT;
2049  /* redundant, but this code could be used if another convertion is required
2050  converted=1;
2051  } else {
2052  octstr_destroy(text);
2053  text = octstr_duplicate(msg->sms.msgdata);
2054  */
2055  }
2056  }
2057  octstr_destroy(text);
2058  }
2059  if (octstr_len(msg->sms.sender) == 0 ||
2060  octstr_len(msg->sms.receiver) == 0) {
2061  error(0, "smppbox_req_thread: no sender/receiver, dump follows:");
2062  msg_dump(msg, 0);
2063  /*
2064  * Send NACK to bearerbox, otherwise message remains in store file.
2065  */
2066  mack = msg_create(ack);
2067  mack->ack.nack = ack_failed;
2068  mack->ack.time = msg->sms.time;
2069  uuid_copy(mack->ack.id, msg->sms.id);
2070  send_msg(box->bearerbox_connection, box, mack);
2071 
2072  msg_destroy(msg);
2073  continue;
2074  }
2075  /* create ack message to be sent afterwards */
2076  mack = msg_create(ack);
2077  mack->ack.nack = ack_success;
2078  mack->ack.time = msg->sms.time;
2079  uuid_copy(mack->ack.id, msg->sms.id);
2080 
2081  msgid = NULL;
2082  receiver_box = find_receiver_box(box);
2083  pdulist = msg_to_pdu(receiver_box, msg);
2084  if (pdulist != NULL) {
2085  while ((pdu = gwlist_extract_first(pdulist)) != NULL) {
2086  if (NULL == msgid) {
2087  /* Put ack in dict. We will send it as soon as we received a deliver_sm_resp */
2088  msgid = octstr_format("%ld", pdu->u.deliver_sm.sequence_number);
2089  dict_put(receiver_box->deliver_acks, msgid, mack);
2090  }
2091  send_pdu(receiver_box->smpp_connection, box->boxc_id, pdu);
2092  smpp_pdu_destroy(pdu);
2093  }
2094  if (msgid)
2095  octstr_destroy(msgid);
2096  gwlist_destroy(pdulist, NULL);
2097  }
2098  else {
2099  /* Send NACK to bearerbox, otherwise message remains in store file. */
2100  warning(0, "msg_to_pdu failed, sending negative ack");
2101  mack->ack.nack = ack_failed;
2102  send_msg(box->bearerbox_connection, box, mack);
2103  }
2104  }
2105  msg_destroy(msg);
2106  }
2107 }
2108 
2109 static void run_smppbox(void *arg)
2110 {
2111  int fd;
2112  Boxc *newconn;
2113  long sender;
2114 
2115  fd = (int)arg;
2116  newconn = accept_smpp(fd, 0);
2117  if (newconn == NULL) {
2118  panic(0, "Socket accept failed");
2119  return;
2120  }
2121  newconn->boxc_id = octstr_duplicate(smppbox_id);
2122  newconn->bearerbox_connection = connect_to_bearerbox_real(bearerbox_host, bearerbox_port, bearerbox_port_ssl, NULL /* bb_our_host */);
2123  /* XXX add our_host if required */
2124  if (newconn->bearerbox_connection == NULL) {
2125  error(0, "opensmppbox: Failed to connect to bearerbox." );
2126  boxc_destroy(newconn);
2127  return;
2128  }
2129 
2130  gwlist_append(all_boxes, newconn);
2131 
2132 #ifdef DO_HEARTBEATS
2133  /* we dont do heartbeats for now */
2134  if (0 > heartbeat_start(write_to_bearerboxes, DEFAULT_HEARTBEAT,
2136  info(0, "OpenSMPPBox: Could not start heartbeat.");
2137  }
2138 #endif
2139 
2140  sender = gwthread_create(smpp_to_bearerbox, newconn);
2141  if (sender == -1) {
2142  error(0, "Failed to start a new thread, disconnecting client <%s>",
2143  octstr_get_cstr(newconn->client_ip));
2144  boxc_destroy(newconn);
2145  return;
2146  }
2147  bearerbox_to_smpp(newconn);
2148  gwthread_join(sender);
2149  gwlist_delete_equal(all_boxes, newconn);
2150  boxc_destroy(newconn);
2151 }
2152 
2153 static void wait_for_connections(int fd, void (*function) (void *arg),
2154  List *waited)
2155 {
2156  int ret = 0;
2157  int timeout = 10; /* 10 sec. */
2158 
2159  gw_assert(function != NULL);
2160 
2161  while(smppbox_status == SMPP_RUNNING) {
2162 
2163  ret = gwthread_pollfd(fd, POLLIN, 1.0);
2164  if (smppbox_status == SMPP_SHUTDOWN) {
2165  if (ret == -1 || !timeout)
2166  break;
2167  else
2168  timeout--;
2169  }
2170 
2171  if (ret > 0) {
2172  gwthread_create(function, (void *)fd);
2173  gwthread_sleep(1.0);
2174  } else if (ret < 0) {
2175  if(errno==EINTR) continue;
2176  if(errno==EAGAIN) continue;
2177  error(errno, "wait_for_connections failed");
2178  }
2179  }
2180 }
2181 
2182 static void smppboxc_run(void *arg)
2183 {
2184  int fd;
2185  int port;
2186 
2187  port = (int)arg;
2188 
2189  fd = make_server_socket(port, NULL);
2190  /* XXX add interface_name if required */
2191 
2192  if (fd < 0) {
2193  panic(0, "Could not open opensmppbox port %d", port);
2194  }
2195 
2196  /*
2197  * infinitely wait for new connections;
2198  * to shut down the system, SIGTERM is send and then
2199  * select drops with error, so we can check the status
2200  */
2201 
2202  info(0, "Waiting for SMPP connections on port %d.", port);
2203  wait_for_connections(fd, run_smppbox, NULL);
2204  info(0, "No more waiting for SMPP connections.");
2205 
2206  /* close listen socket */
2207  close(fd);
2208 }
2209 
2210 
2211 
2212 /***********************************************************************
2213  * Main program. Configuration, signal handling, etc.
2214  */
2215 
2216 static void signal_handler(int signum) {
2217  /* On some implementations (i.e. linuxthreads), signals are delivered
2218  * to all threads. We only want to handle each signal once for the
2219  * entire box, and we let the gwthread wrapper take care of choosing
2220  * one.
2221  */
2222  if (!gwthread_shouldhandlesignal(signum))
2223  return;
2224 
2225  switch (signum) {
2226  case SIGINT:
2227 
2228  if (smppbox_status == SMPP_RUNNING) {
2229  error(0, "SIGINT received, aborting program...");
2231  }
2232  break;
2233 
2234  case SIGHUP:
2235  warning(0, "SIGHUP received, catching and re-opening logs");
2236  log_reopen();
2237  alog_reopen();
2238  break;
2239 
2240  /*
2241  * It would be more proper to use SIGUSR1 for this, but on some
2242  * platforms that's reserved by the pthread support.
2243  */
2244  case SIGQUIT:
2245  warning(0, "SIGQUIT received, reporting memory usage.");
2246  gw_check_leaks();
2247  break;
2248  }
2249 }
2250 
2251 
2252 static void setup_signal_handlers(void) {
2253  struct sigaction act;
2254 
2255  act.sa_handler = signal_handler;
2256  sigemptyset(&act.sa_mask);
2257  act.sa_flags = 0;
2258  sigaction(SIGINT, &act, NULL);
2259  sigaction(SIGQUIT, &act, NULL);
2260  sigaction(SIGHUP, &act, NULL);
2261  sigaction(SIGPIPE, &act, NULL);
2262 }
2263 
2264 
2265 
2266 static void gw_smpp_enter(Cfg *cfg)
2267 {
2268 }
2269 
2270 static void gw_smpp_leave()
2271 {
2272 }
2273 
2274 static void init_smsc_routes(Cfg *cfg)
2275 {
2276  CfgGroup *grp;
2277  List *list, *items;
2278  Octstr *smsc_id, *boxc_ids, *shortcodes, *receiver_shortcodes;
2279  int i, j;
2280 
2281  smsc_by_receiver = dict_create(1000, (void(*)(void *)) octstr_destroy);
2282  smsc_by_smsbox_id = dict_create(30, (void(*)(void *)) octstr_destroy);
2283  smsc_by_sender = dict_create(50, (void(*)(void *)) octstr_destroy);
2284  smsc_by_sender_smsbox_id = dict_create(50, (void(*)(void *)) octstr_destroy);
2285 
2286  smsc_id = boxc_ids = shortcodes = receiver_shortcodes = NULL;
2287  list = items = NULL;
2288 
2289  list = cfg_get_multi_group(cfg, octstr_imm("smsc-route"));
2290 
2291  /* loop multi-group "client-route" */
2292  while (list && (grp = gwlist_extract_first(list)) != NULL) {
2293  if ((smsc_id = cfg_get(grp, octstr_imm("smsc-id"))) == NULL) {
2294  grp_dump(grp);
2295  panic(0,"'smsc-id-route' group without valid 'smsc-id' directive!");
2296  }
2297 
2298  /*
2299  * If smsbox-id is given, then any message coming from the specified
2300  * smsbox-id in the list will be routed to this smsc.
2301  * If shortcode is given, then any message with sender number
2302  * matching those will be routed to this smsc.
2303  * If both are given, then only sender within shortcode originating
2304  * from sysmtem-id list will be routed to this smsc. So if both are
2305  * present then this is a logical AND operation.
2306  */
2307  boxc_ids = cfg_get(grp, octstr_imm("smsbox-id"));
2308  shortcodes = cfg_get(grp, octstr_imm("shortcode"));
2309  receiver_shortcodes = cfg_get(grp, octstr_imm("receiver-shortcode"));
2310 
2311  /* Consider the receiver options: receiver-shortcode. */
2312  if (receiver_shortcodes) {
2313  /* receiver-shortcode applies to all MTs from all smscs */
2314  items = octstr_split(receiver_shortcodes, octstr_imm(";"));
2315  for (i = 0; i < gwlist_len(items); i++) {
2316  Octstr *item = gwlist_get(items, i);
2317  octstr_strip_blanks(item);
2318 
2319  debug("opensmppbox",0,"Adding smsc routing to id <%s> for receiver no <%s>",
2320  octstr_get_cstr(smsc_id), octstr_get_cstr(item));
2321 
2322  if (!dict_put_once(smsc_by_receiver, item, octstr_duplicate(smsc_id)))
2323  panic(0, "Routing for receiver no <%s> already exists!",
2324  octstr_get_cstr(item));
2325  }
2327  };
2328 
2329  /* consider now the 3 possibilities: */
2330  if (boxc_ids && !shortcodes) {
2331  /* smsbox-id only, so all MT traffic */
2332  items = octstr_split(boxc_ids, octstr_imm(";"));
2333  for (i = 0; i < gwlist_len(items); i++) {
2334  Octstr *item = gwlist_get(items, i);
2335  octstr_strip_blanks(item);
2336 
2337  debug("opensmppbox",0,"Adding smsc routing to id <%s> for box id <%s>",
2338  octstr_get_cstr(smsc_id), octstr_get_cstr(item));
2339 
2340  if (!dict_put_once(smsc_by_smsbox_id, item, octstr_duplicate(smsc_id)))
2341  panic(0, "Routing for box-id <%s> already exists!",
2342  octstr_get_cstr(item));
2343  }
2345  octstr_destroy(boxc_ids);
2346  }
2347  else if (!boxc_ids && shortcodes) {
2348  /* shortcode only, so these MTs from all smscs */
2349  items = octstr_split(shortcodes, octstr_imm(";"));
2350  for (i = 0; i < gwlist_len(items); i++) {
2351  Octstr *item = gwlist_get(items, i);
2352  octstr_strip_blanks(item);
2353 
2354  debug("opensmppbox",0,"Adding smsc routing to id <%s> for sender no <%s>",
2355  octstr_get_cstr(smsc_id), octstr_get_cstr(item));
2356 
2357  if (!dict_put_once(smsc_by_sender, item, octstr_duplicate(smsc_id)))
2358  panic(0, "Routing for sender no <%s> already exists!",
2359  octstr_get_cstr(item));
2360  }
2362  octstr_destroy(shortcodes);
2363  }
2364  else if (boxc_ids && shortcodes) {
2365  /* both, so only specified MTs from specified smsbox ids */
2366  items = octstr_split(shortcodes, octstr_imm(";"));
2367  for (i = 0; i < gwlist_len(items); i++) {
2368  List *subitems;
2369  Octstr *item = gwlist_get(items, i);
2370  octstr_strip_blanks(item);
2371  subitems = octstr_split(boxc_ids, octstr_imm(";"));
2372  for (j = 0; j < gwlist_len(subitems); j++) {
2373  Octstr *subitem = gwlist_get(subitems, j);
2374  octstr_strip_blanks(subitem);
2375 
2376  debug("opensmppbox",0,"Adding smsc routing to id <%s> "
2377  "for sender no <%s> and smsbox id <%s>",
2378  octstr_get_cstr(smsc_id), octstr_get_cstr(item),
2379  octstr_get_cstr(subitem));
2380 
2381  /* construct the dict key '<shortcode>:<smsbox-id>' */
2382  octstr_insert(subitem, item, 0);
2383  octstr_insert_char(subitem, octstr_len(item), ':');
2384  if (!dict_put_once(smsc_by_sender_smsbox_id, subitem, octstr_duplicate(smsc_id)))
2385  panic(0, "Routing for sender:smsbox-id <%s> already exists!",
2386  octstr_get_cstr(subitem));
2387  }
2389  }
2391  octstr_destroy(shortcodes);
2392  }
2393  octstr_destroy(smsc_id);
2394  octstr_destroy(boxc_ids);
2395  octstr_destroy(shortcodes);
2396  }
2397 
2398  gwlist_destroy(list, NULL);
2399 }
2400 
2401 static void destroy_smsc_routes(void)
2402 {
2403  dict_destroy(smsc_by_receiver);
2404  smsc_by_receiver = NULL;
2405 
2406  dict_destroy(smsc_by_smsbox_id);
2407  smsc_by_smsbox_id = NULL;
2408 
2409  dict_destroy(smsc_by_sender);
2410  smsc_by_sender = NULL;
2411 
2412  dict_destroy(smsc_by_sender_smsbox_id);
2413  smsc_by_sender_smsbox_id = NULL;
2414 }
2415 
2416 static void init_smppbox(Cfg *cfg)
2417 {
2418  CfgGroup *grp;
2419  Octstr *logfile;
2420  long lvl;
2421  Octstr *val, *log; /* temporary store variables */
2422  long store_dump_freq = -1; /* dummy variable */
2423 
2424  /* some default values */
2425  smppbox_port = 13005;
2426  smppbox_port_ssl = 0;
2427  bearerbox_host = NULL;
2428  bearerbox_port_ssl = 0;
2429  logfile = NULL;
2430  lvl = 0;
2431  systemidisboxcid = 0; /* default backward compatible */
2432  enablepam = 0; /* also default false */
2433 
2434  /* init dlr storage */
2435  dlr_init(cfg);
2436  /* init storage store */
2437  grp= cfg_get_single_group(cfg, octstr_imm("core"));
2438  if (grp != NULL) {
2439  log = cfg_get(grp, octstr_imm("store-file"));
2440  if (log != NULL) {
2441  warning(0, "'store-file' option deprecated, please use 'store-location' and 'store-type' instead.");
2442  val = octstr_create("file");
2443  } else {
2444  log = cfg_get(grp, octstr_imm("store-location"));
2445  val = cfg_get(grp, octstr_imm("store-type"));
2446  }
2447  if (val != NULL) {
2448  if (store_init(cfg, val, log, store_dump_freq, msg_pack, msg_unpack_wrapper) == -1) {
2449  panic(0, "Could not start with store init failed.");
2450  }
2451  }
2452  octstr_destroy(val);
2453  octstr_destroy(log);
2454  }
2455 
2456  /* initialize low level PDUs */
2457  if (smpp_pdu_init(cfg) == -1)
2458  panic(0, "Connot start with PDU init failed.");
2459 
2460  /*
2461  * first we take the port number in bearerbox and other values from the
2462  * opensmppbox group in configuration file
2463  */
2464 
2465  grp = cfg_get_single_group(cfg, octstr_imm("opensmppbox"));
2466  if (grp == NULL)
2467  panic(0, "No 'opensmppbox' group in configuration");
2468 
2469  bearerbox_host = cfg_get(grp, octstr_imm("bearerbox-host"));
2470  if (!bearerbox_host) {
2471  bearerbox_host = octstr_create(BB_DEFAULT_HOST);
2472  }
2473  if (cfg_get_integer(&bearerbox_port, grp, octstr_imm("bearerbox-port")) == -1)
2475 #ifdef HAVE_LIBSSL
2476 #if 0
2477  cfg_get_bool(&bearerbox_port_ssl, grp, octstr_imm("bearerbox-port-ssl"));
2478  conn_config_ssl(grp);
2479 #endif
2480 #endif
2481 
2482  smppbox_id = cfg_get(grp, octstr_imm("opensmppbox-id"));
2483  our_system_id = cfg_get(grp, octstr_imm("our-system-id"));
2484  route_to_smsc = cfg_get(grp, octstr_imm("route-to-smsc"));
2485  if (our_system_id == NULL) {
2486  panic(0, "our-system-id is not set.");
2487  }
2488  alt_charset = cfg_get(grp, octstr_imm("alt-charset"));
2489 
2490  /* setup logfile stuff */
2491  logfile = cfg_get(grp, octstr_imm("log-file"));
2492 
2493  cfg_get_integer(&lvl, grp, octstr_imm("log-level"));
2494 
2495  if (cfg_get_integer(&smppbox_port, grp, octstr_imm("opensmppbox-port")) == -1)
2496  smppbox_port = 2345;
2497 
2498  smpp_logins = cfg_get(grp, octstr_imm("smpp-logins"));
2499 
2500  if (smpp_logins == NULL) {
2501  panic(0, "No user file specified.");
2502  }
2503 
2504  if (logfile != NULL) {
2505  info(0, "Starting to log to file %s level %ld",
2506  octstr_get_cstr(logfile), lvl);
2507  log_open(octstr_get_cstr(logfile), lvl, GW_NON_EXCL);
2508  octstr_destroy(logfile);
2509  }
2510 
2511  if (cfg_get_integer(&smpp_timeout, grp, octstr_imm("timeout")) == -1)
2513  if (cfg_get_integer(&smpp_source_addr_ton, grp, octstr_imm("source-addr-ton")) == -1)
2514  smpp_source_addr_ton = -1;
2515  if (cfg_get_integer(&smpp_source_addr_npi, grp, octstr_imm("source-addr-npi")) == -1)
2516  smpp_source_addr_npi = -1;
2517  if (cfg_get_bool(&smpp_autodetect_addr, grp, octstr_imm("source-addr-auto")) == -1)
2519  if (cfg_get_integer(&smpp_dest_addr_ton, grp, octstr_imm("dest-addr-ton")) == -1)
2520  smpp_dest_addr_ton = -1;
2521  if (cfg_get_integer(&smpp_dest_addr_npi, grp, octstr_imm("dest-addr-npi")) == -1)
2522  smpp_dest_addr_npi = -1;
2523 
2524  cfg_get_bool(&systemidisboxcid, grp, octstr_imm("use-systemid-as-smsboxid"));
2525  cfg_get_bool(&enablepam, grp, octstr_imm("enable-pam"));
2526  pamacl = cfg_get(grp, octstr_imm("pam-acl"));
2527  if (NULL == pamacl) {
2528  pamacl = octstr_create("kannel");
2529  }
2530  if (enablepam && !systemidisboxcid) {
2531  panic(0, "enable-pam requires systemid-is-boxcid=true.");
2532  }
2533 #ifndef HAVE_PAM
2534  if (enablepam) {
2535  panic(0, "enable-pam is set but we are compiled without pam support.");
2536  }
2537 #endif
2538  if (enablepam) {
2539  info(0, "Using PAM authentication.");
2540  }
2541 
2542  init_smsc_routes(cfg);
2543 
2544  catenated_sms_counter = counter_create();
2545  boxid = counter_create();
2546  gw_smpp_enter(cfg);
2547 
2549 }
2550 
2551 static int check_args(int i, int argc, char **argv) {
2552  if (strcmp(argv[i], "-H")==0 || strcmp(argv[i], "--tryhttp")==0) {
2553  //only_try_http = 1;
2554  } else
2555  return -1;
2556 
2557  return 0;
2558 }
2559 
2560 /*
2561  * Adding hooks to kannel check config
2562  *
2563  * Martin Conte.
2564  */
2565 
2566 static int smppbox_is_allowed_in_group(Octstr *group, Octstr *variable)
2567 {
2568  Octstr *groupstr;
2569 
2570  groupstr = octstr_imm("group");
2571 
2572  #define OCTSTR(name) \
2573  if (octstr_compare(octstr_imm(#name), variable) == 0) \
2574  return 1;
2575  #define SINGLE_GROUP(name, fields) \
2576  if (octstr_compare(octstr_imm(#name), group) == 0) { \
2577  if (octstr_compare(groupstr, variable) == 0) \
2578  return 1; \
2579  fields \
2580  return 0; \
2581  }
2582  #define MULTI_GROUP(name, fields) \
2583  if (octstr_compare(octstr_imm(#name), group) == 0) { \
2584  if (octstr_compare(groupstr, variable) == 0) \
2585  return 1; \
2586  fields \
2587  return 0; \
2588  }
2589  #include "opensmppbox-cfg.def"
2590 
2591  return 0;
2592 }
2593 
2594 #undef OCTSTR
2595 #undef SINGLE_GROUP
2596 #undef MULTI_GROUP
2597 
2599 {
2600  #define OCTSTR(name)
2601  #define SINGLE_GROUP(name, fields) \
2602  if (octstr_compare(octstr_imm(#name), query) == 0) \
2603  return 1;
2604  #define MULTI_GROUP(name, fields) \
2605  if (octstr_compare(octstr_imm(#name), query) == 0) \
2606  return 0;
2607  #include "opensmppbox-cfg.def"
2608  return 0;
2609 }
2610 
2611 int main(int argc, char **argv)
2612 {
2613  int cf_index;
2614  Octstr *filename, *version;
2615 
2616  gwlib_init();
2617  all_boxes = gwlist_create();
2618  list_dict = dict_create(1, NULL);
2619 
2620  cf_index = get_and_set_debugs(argc, argv, check_args);
2622 
2623  if (argv[cf_index] == NULL)
2624  filename = octstr_create("opensmppbox.conf");
2625  else
2626  filename = octstr_create(argv[cf_index]);
2627 
2628  cfg = cfg_create(filename);
2629 
2630  /* Adding cfg-checks to core */
2631 
2633 
2634  if (cfg_read(cfg) == -1)
2635  panic(0, "Couldn't read configuration from `%s'.", octstr_get_cstr(filename));
2636 
2637  octstr_destroy(filename);
2638 
2639  version = octstr_format("opensmppbox version %s gwlib", GW_VERSION);
2640  report_versions(octstr_get_cstr(version));
2641  octstr_destroy(version);
2642 
2643  init_smppbox(cfg);
2644 
2645  smppboxc_run((void *)smppbox_port);
2646 
2647  /* shutdown dlr storage */
2649  dlr_shutdown();
2651  counter_destroy(catenated_sms_counter);
2652  counter_destroy(boxid);
2653 
2654  if (restart_smppbox) {
2655  gwthread_sleep(1.0);
2656  }
2657 
2658  gwlist_destroy(all_boxes, NULL);
2659  gw_smpp_leave();
2660  gwlib_shutdown();
2661 
2662  if (restart_smppbox)
2663  execvp(argv[0], argv);
2664  return 0;
2665 }
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:434
void msg_dump(Msg *msg, int level)
Definition: msg.c:152
Connection * conn
Definition: bb_boxc.c:135
void error(int err, const char *fmt,...)
Definition: log.c:648
static Octstr * route_to_smsc
Definition: opensmppbox.c:127
static volatile sig_atomic_t smppbox_status
Definition: opensmppbox.c:98
void info(int err, const char *fmt,...)
Definition: log.c:672
List * incoming
Definition: opensmppbox.c:153
Dict * meta_data_get_values(const Octstr *data, const char *group)
Definition: meta_data.c:248
#define MWI_UNDEF
Definition: sms.h:99
int autodetect_addr
Definition: opensmppbox.c:172
#define MAX_SMS_OCTETS
Definition: sms.h:129
Msg * msg_duplicate(Msg *msg)
Definition: msg.c:111
static volatile sig_atomic_t restart_smppbox
Definition: opensmppbox.c:97
static Octstr * boxc_route_msg_to_smsc(Boxc *box, Msg *msg)
Definition: opensmppbox.c:1796
int size
Definition: wsasm.c:84
static Octstr * smppbox_id
Definition: opensmppbox.c:125
Connection * connect_to_bearerbox_real(Octstr *host, int port, int ssl, Octstr *our_host)
Definition: shared.c:83
static Counter * catenated_sms_counter
Definition: opensmppbox.c:112
static int timestamp_to_minutes(Octstr *timestamp)
Definition: opensmppbox.c:361
Dict * msg_acks
Definition: opensmppbox.c:162
smpp_login
Definition: opensmppbox.c:138
static List * all_boxes
Definition: opensmppbox.c:110
Octstr * route_to_smsc
Definition: opensmppbox.c:161
static long smpp_dest_addr_npi
Definition: opensmppbox.c:118
gw_assert(wtls_machine->packet_to_send !=NULL)
int ssl
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
void counter_destroy(Counter *counter)
Definition: counter.c:110
void smpp_pdu_destroy_item(void *pdu)
Definition: opensmppbox.c:183
void gwlist_append(List *list, void *item)
Definition: list.c:179
static void init_smppbox(Cfg *cfg)
Definition: opensmppbox.c:2416
int read_from_bearerbox_real(Connection *conn, Msg **msg, double seconds)
Definition: shared.c:172
int octstr_check_range(Octstr *ostr, long pos, long len, octstr_func_t filter)
Definition: octstr.c:812
Octstr * client_ip
Definition: opensmppbox.c:152
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1502
#define DLR_IS_SUCCESS(dlr)
Definition: dlr.h:86
struct tm gw_gmtime(time_t t)
Definition: protected.c:137
Definition: msg.h:109
void log_reopen(void)
Definition: log.c:297
List * outgoing
Definition: opensmppbox.c:155
void gwthread_join(long thread)
static void destroy_smsc_routes(void)
Definition: opensmppbox.c:2401
long source_addr_ton
Definition: opensmppbox.c:170
long gwlist_len(List *list)
Definition: list.c:166
static long smpp_source_addr_ton
Definition: opensmppbox.c:114
int octstr_recode(Octstr *tocode, Octstr *fromcode, Octstr *orig)
Definition: octstr.c:2574
#define DLR_NOTHING
Definition: dlr.h:71
void * gwlist_get(List *list, long pos)
Definition: list.c:292
static void identify_to_bearerbox(Boxc *conn)
Definition: opensmppbox.c:486
static Octstr * generate_smppid(Msg *msg, int version)
Definition: opensmppbox.c:637
static List * msg_to_pdu(Boxc *box, Msg *msg)
Definition: opensmppbox.c:697
#define GSM_ADDR_TON_NATIONAL
Definition: smasi_pdu.h:104
void check_multipart(Boxc *box, Msg *msg, int *msg_to_send, Msg **msg2, List **parts_list)
Definition: opensmppbox.c:1460
Msg * msg_unpack_wrapper(Octstr *os)
Definition: msg.c:256
const char * type_name
Definition: smpp_pdu.h:92
#define BB_DEFAULT_HOST
Definition: bb.h:67
void charset_utf8_to_gsm(Octstr *ostr)
Definition: charset.c:288
msg_type
Definition: msg.h:73
#define ESM_CLASS_SUBMIT_UDH_INDICATOR
Definition: smpp_pdu.h:142
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1068
#define cfg_get(grp, varname)
Definition: cfg.h:86
unsigned long type
Definition: smpp_pdu.h:91
int load
Definition: opensmppbox.c:147
static Dict * list_dict
Definition: opensmppbox.c:111
#define DC_8BIT
Definition: sms.h:111
void uuid_unparse(const uuid_t uu, char *out)
Definition: gw_uuid.c:562
long source_addr_npi
Definition: opensmppbox.c:171
static void setup_signal_handlers(void)
Definition: opensmppbox.c:2252
void uuid_generate(uuid_t out)
Definition: gw_uuid.c:393
Octstr * service_type
Definition: opensmppbox.c:169
long smpp_pdu_read_len(Connection *conn)
Definition: smpp_pdu.c:869
Octstr * meta_data_get_value(Octstr *data, const char *group, const Octstr *key)
Definition: meta_data.c:368
static void init_smsc_routes(Cfg *cfg)
Definition: opensmppbox.c:2274
#define msg_create(type)
Definition: msg.h:136
static void signal_handler(int signum)
Definition: opensmppbox.c:2216
#define TIMEOUT_SECONDS
Definition: opensmppbox.c:136
int gwthread_shouldhandlesignal(int signal)
static long outstanding_requests(void)
Definition: smsbox.c:502
static Cfg * cfg
Definition: opensmppbox.c:95
int conn_eof(Connection *conn)
Definition: conn.c:699
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1344
size_t gw_strftime(char *s, size_t max, const char *format, const struct tm *tm)
Definition: protected.c:164
Msg * dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int typ, int use_dst)
Definition: dlr.c:387
void dlr_add(const Octstr *smsc, const Octstr *ts, Msg *msg, int use_dst)
Definition: dlr.c:330
int mo_recode
Definition: opensmppbox.c:178
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
int version
Definition: opensmppbox.c:148
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
List * sms_split(Msg *orig, Octstr *header, Octstr *footer, Octstr *nonlast_suffix, Octstr *split_chars, int catenate, unsigned long msg_sequence, int max_messages, int max_octets)
Definition: sms.c:309
static Octstr * pamacl
Definition: opensmppbox.c:133
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
#define GSM_ADDR_TON_INTERNATIONAL
Definition: smasi_pdu.h:103
static void run_smppbox(void *arg)
Definition: opensmppbox.c:2109
Dict * deliver_acks
Definition: opensmppbox.c:163
static Boxc * find_receiver_box(Boxc *box)
Definition: opensmppbox.c:1907
static int bearerbox_port_ssl
Definition: opensmppbox.c:106
static int restart
Definition: opensmppbox.c:109
int is_allowed_ip(Octstr *allow_ip, Octstr *deny_ip, Octstr *ip)
Definition: utils.c:815
Cfg * cfg_create(Octstr *filename)
Definition: cfg.c:318
static int send_msg(Connection *conn, Boxc *boxconn, Msg *pmsg)
Definition: opensmppbox.c:452
Connection * bearerbox_connection
Definition: opensmppbox.c:142
void heartbeat_stop(long hb_thread)
Definition: heartbeat.c:160
#define SMPP_SHUTDOWN
Definition: opensmppbox.c:100
volatile sig_atomic_t alive
Definition: opensmppbox.c:158
int alt_dcs
Definition: opensmppbox.c:175
int cfg_read(Cfg *cfg)
Definition: cfg.c:452
static long smppbox_port
Definition: opensmppbox.c:102
#define dump_pdu(msg, id, pdu)
Definition: opensmppbox.c:346
List * retry
Definition: opensmppbox.c:154
static int port
Definition: fakesmsc.c:120
#define DLR_SUCCESS
Definition: dlr.h:72
#define POLLIN
Definition: gwpoll.h:91
Definition: msg.h:108
Counter * smpp_pdu_counter
Definition: opensmppbox.c:151
void msg_destroy_item(void *msg)
Definition: msg.c:147
static void wait_for_connections(int fd, void(*function)(void *arg), List *waited)
Definition: opensmppbox.c:2153
static int send_pdu(Connection *conn, Octstr *id, SMPP_PDU *pdu)
Definition: opensmppbox.c:619
unsigned char * password
Definition: test_cimd2.c:100
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
void cfg_add_hooks(void *allowed, void *single)
Definition: cfg.c:253
static int enablepam
Definition: opensmppbox.c:132
int conn_write(Connection *conn, Octstr *data)
Definition: conn.c:1045
Definition: msg.h:79
Definition: cfg.c:164
static int smppbox_is_allowed_in_group(Octstr *group, Octstr *variable)
Definition: opensmppbox.c:2566
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1301
Octstr * boxc_id
Definition: opensmppbox.c:159
Counter * counter_create(void)
Definition: counter.c:94
Octstr * concat_msgids(Octstr *msgid, List *list)
Definition: opensmppbox.c:1446
void * gwlist_extract_first(List *list)
Definition: list.c:305
Octstr * alt_charset
Definition: opensmppbox.c:149
time_t gw_mktime(struct tm *tm)
Definition: protected.c:153
static long smpp_dest_addr_ton
Definition: opensmppbox.c:117
static void handle_pdu(Connection *conn, Boxc *box, SMPP_PDU *pdu)
Definition: opensmppbox.c:1506
void grp_dump(CfgGroup *grp)
Definition: cfg.c:808
void conn_config_ssl(CfgGroup *grp)
Definition: conn.c:1538
#define ESM_CLASS_DELIVER_UDH_INDICATOR
Definition: smpp_pdu.h:151
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
static long smpp_source_addr_npi
Definition: opensmppbox.c:115
static int systemidisboxcid
Definition: opensmppbox.c:131
static Msg * pdu_to_msg(Boxc *box, SMPP_PDU *pdu, long *reason)
Definition: opensmppbox.c:1096
char * text
Definition: smsc_cimd2.c:921
void conn_destroy(Connection *conn)
Definition: conn.c:621
void octstr_insert_char(Octstr *ostr, long pos, const char c)
Definition: octstr.c:1479
int store_init(Cfg *cfg, const Octstr *type, const Octstr *fname, long dump_freq, void *pack_func, void *unpack_func)
Definition: bb_store.c:82
static void gw_smpp_enter(Cfg *cfg)
Definition: opensmppbox.c:2266
Definition: dict.c:116
#define octstr_duplicate(ostr)
Definition: octstr.h:187
static Octstr * smsc_id
Definition: mtbatch.c:98
List * cfg_get_multi_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:642
static Octstr * our_system_id
Definition: opensmppbox.c:126
static void smppboxc_run(void *arg)
Definition: opensmppbox.c:2182
Octstr * smpp_pdu_pack(Octstr *smsc_id, SMPP_PDU *pdu)
Definition: smpp_pdu.c:458
static Boxc * accept_smpp(int fd, int ssl)
Definition: opensmppbox.c:1837
static Dict * smsc_by_smsbox_id
Definition: opensmppbox.c:121
long gwlist_delete_equal(List *list, void *item)
Definition: list.c:266
SMPP_PDU * smpp_pdu_unpack(Octstr *smsc_id, Octstr *data_without_len)
Definition: smpp_pdu.c:597
void uuid_copy(uuid_t dst, const uuid_t src)
Definition: gw_uuid.c:150
void msg_destroy(Msg *msg)
Definition: msg.c:132
int gw_isdigit(int c)
Definition: utils.c:988
int make_server_socket(int port, const char *interface_name)
Definition: socket.c:93
time_t connect_time
Definition: opensmppbox.c:150
void warning(int err, const char *fmt,...)
Definition: log.c:660
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
int main(int argc, char **argv)
Definition: opensmppbox.c:2611
char filename[FILENAME_MAX+1]
Definition: log.c:171
#define gwthread_create(func, arg)
Definition: gwthread.h:90
static Counter * boxid
Definition: opensmppbox.c:108
#define octstr_create(cstr)
Definition: octstr.h:125
static void smpp_to_bearerbox(void *arg)
Definition: opensmppbox.c:1873
void octstr_destroy_item(void *os)
Definition: octstr.c:334
#define DLR_SMSC_FAIL
Definition: dlr.h:76
int fields_to_dcs(Msg *msg, int mode)
Definition: sms.c:73
void gwthread_sleep(double seconds)
#define SMS_PARAM_UNDEFINED
Definition: sms.h:91
int validityperiod
Definition: opensmppbox.c:176
static void gw_smpp_leave()
Definition: opensmppbox.c:2270
static Boxc * boxc_create(int fd, Octstr *ip, int ssl)
Definition: opensmppbox.c:1725
union SMPP_PDU::@15 u
#define UUID_STR_LEN
Definition: gw_uuid.h:19
int gwthread_pollfd(int fd, int events, double timeout)
#define ALL_HEARTBEATS
Definition: heartbeat.h:68
Connection * smpp_connection
Definition: opensmppbox.c:141
void alog_reopen(void)
Definition: accesslog.c:85
static Octstr * smpp_logins
Definition: opensmppbox.c:107
Octstr * smpp_pdu_read_data(Connection *conn, long len)
Definition: smpp_pdu.c:895
static long bearerbox_port
Definition: opensmppbox.c:104
void report_versions(const char *boxname)
Definition: utils.c:539
int log_open(char *filename, int level, enum excl_state excl)
Definition: log.c:375
#define DLR_UNDEFINED
Definition: dlr.h:70
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
#define GSM_ADDR_NPI_UNKNOWN
Definition: smasi_pdu.h:111
void dict_destroy(Dict *dict)
Definition: dict.c:215
void dlr_init(Cfg *cfg)
Definition: dlr.c:233
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:756
#define DEFAULT_HEARTBEAT
Definition: heartbeat.h:67
static int smppbox_is_single_group(Octstr *query)
Definition: opensmppbox.c:2598
#define MC_UNDEF
Definition: sms.h:93
static Msg * read_from_box(Connection *conn, Boxc *boxconn)
Definition: opensmppbox.c:498
int priority
Definition: opensmppbox.c:177
Definition: octstr.c:118
long heartbeat_start(hb_send_func_t *send_func, double freq, hb_load_func_t *load_func)
Definition: heartbeat.c:126
void write_to_bearerbox_real(Connection *conn, Msg *pmsg)
Definition: shared.c:129
#define GSM_ADDR_NPI_E164
Definition: smasi_pdu.h:112
#define ESM_CLASS_SUBMIT_RPI
Definition: smpp_pdu.h:143
Octstr * host_ip(struct sockaddr_in addr)
Definition: socket.c:615
static long convert_addr_from_pdu(Octstr *id, Octstr *addr, long ton, long npi)
Definition: opensmppbox.c:557
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:739
#define panic
Definition: log.h:87
struct tm gw_localtime(time_t t)
Definition: protected.c:121
static time_t smpp_timeout
Definition: opensmppbox.c:128
Definition: cfg.c:73
struct _boxc Boxc
static int smppbox_port_ssl
Definition: opensmppbox.c:103
Octstr * sms_service
Definition: opensmppbox.c:160
int check_login(Boxc *boxc, Octstr *system_id, Octstr *password, Octstr *system_type, smpp_login login_type)
Definition: opensmppbox.c:277
int socklen_t
Definition: socket.h:73
Octstr * octstr_cat(Octstr *ostr1, Octstr *ostr2)
Definition: octstr.c:381
Msg * catenate_msg(List *list, int total)
Definition: opensmppbox.c:523
void gwlib_shutdown(void)
Definition: gwlib.c:94
Octstr * msg_pack(Msg *msg)
Definition: msg.c:181
static Msg * data_sm_to_msg(Boxc *box, SMPP_PDU *pdu, long *reason)
Definition: opensmppbox.c:1298
int smpp_pdu_init(Cfg *cfg)
Definition: smpp_pdu.c:184
#define gwlist_create()
Definition: list.h:136
static Dict * smsc_by_receiver
Definition: opensmppbox.c:120
#define DLR_BUFFERED
Definition: dlr.h:74
long id
Definition: opensmppbox.c:146
int dict_put_once(Dict *dict, Octstr *key, void *value)
Definition: dict.c:271
int dcs_to_fields(Msg **msg, int dcs)
Definition: sms.c:139
void gwlib_init(void)
Definition: gwlib.c:78
int conn_error(Connection *conn)
Definition: conn.c:710
#define DC_UNDEF
Definition: sms.h:109
int is_wap
Definition: opensmppbox.c:145
#define DLR_IS_FAIL(dlr)
Definition: dlr.h:87
#define GSM_ADDR_TON_ALPHANUMERIC
Definition: smasi_pdu.h:107
static Dict * smsc_by_sender
Definition: opensmppbox.c:122
static void bearerbox_to_smpp(void *arg)
Definition: opensmppbox.c:1924
static int check_args(int i, int argc, char **argv)
Definition: opensmppbox.c:2551
long dest_addr_ton
Definition: opensmppbox.c:173
Dict * sent
Definition: opensmppbox.c:156
smpp_login login_type
Definition: opensmppbox.c:143
CfgGroup * cfg_get_single_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:636
#define BB_DEFAULT_SMSBOX_PORT
Definition: bb.h:68
volatile int routable
Definition: opensmppbox.c:166
#define DLR_SMSC_SUCCESS
Definition: dlr.h:75
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
int get_and_set_debugs(int argc, char **argv, int(*find_own)(int index, int argc, char **argv))
Definition: utils.c:626
#define DLR_IS_ENABLED(dlr)
Definition: dlr.h:81
Semaphore * pending
Definition: opensmppbox.c:157
static int read_pdu(Boxc *box, Connection *conn, long *len, SMPP_PDU **pdu)
Definition: opensmppbox.c:657
#define octstr_create_from_data(data, len)
Definition: octstr.h:134
List * octstr_split(const Octstr *os, const Octstr *sep)
Definition: octstr.c:1638
Definition: list.c:102
static Octstr * alt_charset
Definition: opensmppbox.c:129
static long sms_max_length
Definition: opensmppbox.c:113
#define SMPP_RUNNING
Definition: opensmppbox.c:101
#define DLR_IS_SUCCESS_OR_FAIL(dlr)
Definition: dlr.h:85
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
Definition: smpp_pdu.c:400
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
#define DLR_FAIL
Definition: dlr.h:73
void dlr_shutdown()
Definition: dlr.c:299
static void boxc_destroy(Boxc *boxc)
Definition: opensmppbox.c:1765
int meta_data_set_values(Octstr *data, const Dict *dict, const char *group, int replace)
Definition: meta_data.c:273
int logged_in
Definition: opensmppbox.c:144
time_t last_pdu_received
Definition: opensmppbox.c:164
static int smpp_autodetect_addr
Definition: opensmppbox.c:116
#define DC_UCS2
Definition: sms.h:112
long dest_addr_npi
Definition: opensmppbox.c:174
Connection * conn_wrap_fd(int fd, int ssl)
Definition: conn.c:560
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
Definition: charset.c:589
#define DC_7BIT
Definition: sms.h:110
#define ESM_CLASS_DELIVER_SMSC_DELIVER_ACK
Definition: smpp_pdu.h:147
static Octstr * bearerbox_host
Definition: opensmppbox.c:105
static Dict * smsc_by_sender_smsbox_id
Definition: opensmppbox.c:123
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
void charset_gsm_to_utf8(Octstr *ostr)
Definition: charset.c:220
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.