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