Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
smsc_smpp.c
Go to the documentation of this file.
1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2016 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  * smsc_smpp.c - SMPP v3.3, v3.4 and v5.0 implementation
59  *
60  * Lars Wirzenius
61  * Stipe Tolj <stolj at kannel.org>
62  * Alexander Malysh <amalysh at kannel.org>
63  */
64 
65 /* XXX check SMSCConn conformance */
66 /* XXX UDH reception */
67 /* XXX check UDH sending fields esm_class and data_coding from GSM specs */
68 /* XXX charset conversions on incoming messages (didn't work earlier,
69  either) */
70 /* XXX numbering plans and type of number: check spec */
71 
72 #include "gwlib/gwlib.h"
73 #include "msg.h"
74 #include "smsc_p.h"
75 #include "smpp_pdu.h"
76 #include "smscconn_p.h"
77 #include "bb_smscconn_cb.h"
78 #include "sms.h"
79 #include "dlr.h"
80 #include "bearerbox.h"
81 #include "meta_data.h"
82 #include "load.h"
83 
84 #define SMPP_DEFAULT_CHARSET "UTF-8"
85 
89 };
90 
91 /*
92  * Select these based on whether you want to dump SMPP PDUs as they are
93  * sent and received or not. Not dumping should be the default in at least
94  * stable releases.
95  */
96 
97 #define DEBUG 1
98 
99 #ifndef DEBUG
100 #define dump_pdu(msg, id, pdu, format) do{}while(0)
101 #else
102 
103 #define dump_pdu(msg, id, pdu, format) \
104  do { \
105  debug("bb.sms.smpp", 0, "SMPP[%s]: %s", \
106  octstr_get_cstr(id), msg); \
107  if (format == SMPP_PDU_DUMP_MULTILINE) \
108  smpp_pdu_dump(id, pdu); \
109  else \
110  smpp_pdu_dump_line(id, pdu); \
111  } while(0)
112 #endif
113 
114 
115 /*
116  * Some defaults.
117  */
118 
119 #define SMPP_ENQUIRE_LINK_INTERVAL 30.0
120 #define SMPP_MAX_PENDING_SUBMITS 10
121 #define SMPP_DEFAULT_VERSION 0x34
122 #define SMPP_DEFAULT_PRIORITY 0
123 #define SMPP_THROTTLING_SLEEP_TIME 1
124 #define SMPP_DEFAULT_CONNECTION_TIMEOUT 10 * SMPP_ENQUIRE_LINK_INTERVAL
125 #define SMPP_DEFAULT_WAITACK 60
126 #define SMPP_DEFAULT_SHUTDOWN_TIMEOUT 30
127 #define SMPP_DEFAULT_PORT 2775
128 
129 
130 /*
131  * Some defines
132  */
133 #define SMPP_WAITACK_RECONNECT 0x00
134 #define SMPP_WAITACK_REQUEUE 0x01
135 #define SMPP_WAITACK_NEVER_EXPIRE 0x02
136 
137 /***********************************************************************
138  * Implementation of the actual SMPP protocol: reading and writing
139  * PDUs in the correct order.
140  */
141 
142 
143 typedef struct {
145  long receiver;
161  int our_port;
167  int use_ssl;
169  volatile int quitting;
172  int version;
173  int priority; /* set default priority for messages */
176  int smpp_msg_id_type; /* msg id in C string, hex or decimal */
181  long wait_ack;
187 } SMPP;
188 
189 
190 struct smpp_msg {
191  time_t sent_time;
193 };
194 
195 
196 /*
197  * create smpp_msg struct
198  */
199 static inline struct smpp_msg* smpp_msg_create(Msg *msg)
200 {
201  struct smpp_msg *result = gw_malloc(sizeof(struct smpp_msg));
202 
203  gw_assert(result != NULL);
204  result->sent_time = time(NULL);
205  result->msg = msg;
206 
207  return result;
208 }
209 
210 
211 /*
212  * destroy smpp_msg struct. If destroy_msg flag is set, then message will be freed as well
213  */
214 static inline void smpp_msg_destroy(struct smpp_msg *msg, int destroy_msg)
215 {
216  /* sanity check */
217  if (msg == NULL)
218  return;
219 
220  if (destroy_msg && msg->msg != NULL)
221  msg_destroy(msg->msg);
222 
223  gw_free(msg);
224 }
225 
226 
227 static SMPP *smpp_create(SMSCConn *conn, Octstr *host, int transmit_port,
228  int receive_port, int our_port, int our_receiver_port, Octstr *system_type,
230  Octstr *address_range,
231  int source_addr_ton, int source_addr_npi,
232  int dest_addr_ton, int dest_addr_npi,
233  int enquire_link_interval, int max_pending_submits,
234  int version, int priority, int validity,
235  Octstr *my_number, int smpp_msg_id_type,
236  int autodetect_addr, Octstr *alt_charset, Octstr *alt_addr_charset,
237  Octstr *service_type, long connection_timeout,
238  long wait_ack, int wait_ack_action, int esm_class)
239 {
240  SMPP *smpp;
241 
242  smpp = gw_malloc(sizeof(*smpp));
243  smpp->transmitter = -1;
244  smpp->receiver = -1;
246  smpp->sent_msgs = dict_create(max_pending_submits, NULL);
248  smpp->received_msgs = gwlist_create();
251  smpp->host = octstr_duplicate(host);
252  smpp->system_type = octstr_duplicate(system_type);
253  smpp->our_port = our_port;
254  smpp->our_receiver_port = our_receiver_port;
255  smpp->username = octstr_duplicate(username);
256  smpp->password = octstr_duplicate(password);
257  smpp->address_range = octstr_duplicate(address_range);
258  smpp->source_addr_ton = source_addr_ton;
259  smpp->source_addr_npi = source_addr_npi;
260  smpp->dest_addr_ton = dest_addr_ton;
261  smpp->dest_addr_npi = dest_addr_npi;
262  smpp->my_number = octstr_duplicate(my_number);
263  smpp->service_type = octstr_duplicate(service_type);
264  smpp->transmit_port = transmit_port;
265  smpp->receive_port = receive_port;
266  smpp->enquire_link_interval = enquire_link_interval;
267  smpp->max_pending_submits = max_pending_submits;
268  smpp->quitting = 0;
269  smpp->version = version;
270  smpp->priority = priority;
271  smpp->validityperiod = validity;
272  smpp->conn = conn;
273  smpp->throttling_err_time = 0;
274  smpp->smpp_msg_id_type = smpp_msg_id_type;
275  smpp->autodetect_addr = autodetect_addr;
276  smpp->alt_charset = octstr_duplicate(alt_charset);
277  smpp->alt_addr_charset = octstr_duplicate(alt_addr_charset);
278  smpp->connection_timeout = connection_timeout;
279  smpp->wait_ack = wait_ack;
280  smpp->wait_ack_action = wait_ack_action;
281  smpp->bind_addr_ton = 0;
282  smpp->bind_addr_npi = 0;
283  smpp->use_ssl = 0;
284  smpp->ssl_client_certkey_file = NULL;
285  smpp->load = load_create_real(0);
286  load_add_interval(smpp->load, 1);
287  smpp->esm_class = esm_class;
288 
289  return smpp;
290 }
291 
292 
293 static void smpp_destroy(SMPP *smpp)
294 {
295  if (smpp != NULL) {
297  dict_destroy(smpp->sent_msgs);
300  octstr_destroy(smpp->host);
301  octstr_destroy(smpp->username);
302  octstr_destroy(smpp->password);
306  octstr_destroy(smpp->my_number);
310  load_destroy(smpp->load);
311  gw_free(smpp);
312  }
313 }
314 
315 
316 /*
317  * Try to read an SMPP PDU from a Connection. Return -1 for error (caller
318  * should close the connection), -2 for malformed PDU , 0 for no PDU to
319  * ready yet, or 1 for PDU
320  * read and unpacked. Return a pointer to the PDU in `*pdu'. Use `*len'
321  * to store the length of the PDU to read (it may be possible to read the
322  * length, but not the rest of the PDU - we need to remember the lenght
323  * for the next call). `*len' should be zero at the first call.
324  */
325 static int read_pdu(SMPP *smpp, Connection *conn, long *len, SMPP_PDU **pdu)
326 {
327  Octstr *os;
328 
329  if (*len == 0) {
330  *len = smpp_pdu_read_len(conn);
331  if (*len == -1) {
332  error(0, "SMPP[%s]: Server sent garbage, ignored.",
333  octstr_get_cstr(smpp->conn->id));
334  return -2;
335  } else if (*len == 0) {
336  if (conn_eof(conn) || conn_error(conn))
337  return -1;
338  return 0;
339  }
340  }
341 
342  os = smpp_pdu_read_data(conn, *len);
343  if (os == NULL) {
344  if (conn_eof(conn) || conn_error(conn))
345  return -1;
346  return 0;
347  }
348  *len = 0;
349 
350  *pdu = smpp_pdu_unpack(smpp->conn->id, os);
351  if (*pdu == NULL) {
352  error(0, "SMPP[%s]: PDU unpacking failed.",
353  octstr_get_cstr(smpp->conn->id));
354  debug("bb.sms.smpp", 0, "SMPP[%s]: Failed PDU follows.",
355  octstr_get_cstr(smpp->conn->id));
356  octstr_dump(os, 0);
357  octstr_destroy(os);
358  return -2;
359  }
360 
361  octstr_destroy(os);
362  return 1;
363 }
364 
365 
366 static long convert_addr_from_pdu(Octstr *id, Octstr *addr, long ton, long npi, Octstr *alt_addr_charset)
367 {
368  long reason = SMPP_ESME_ROK;
369 
370  if (addr == NULL)
371  return reason;
372 
373  switch(ton) {
375  /*
376  * Checks to perform:
377  * 1) assume international number has at least 7 chars
378  * 2) the whole source addr consist of digits, exception '+' in front
379  */
380  if (octstr_len(addr) < 7) {
381  /* We consider this as a "non-hard" condition, since there "may"
382  * be international numbers routable that are < 7 digits. Think
383  * of 2 digit country code + 3 digit emergency code. */
384  warning(0, "SMPP[%s]: Malformed addr `%s', generally expected at least 7 digits. ",
385  octstr_get_cstr(id),
386  octstr_get_cstr(addr));
387  } else if (octstr_get_char(addr, 0) == '+' &&
388  !octstr_check_range(addr, 1, 256, gw_isdigit)) {
389  error(0, "SMPP[%s]: Malformed addr `%s', expected all digits. ",
390  octstr_get_cstr(id),
391  octstr_get_cstr(addr));
392  reason = SMPP_ESME_RINVSRCADR;
393  goto error;
394  } else if (octstr_get_char(addr, 0) != '+' &&
395  !octstr_check_range(addr, 0, 256, gw_isdigit)) {
396  error(0, "SMPP[%s]: Malformed addr `%s', expected all digits. ",
397  octstr_get_cstr(id),
398  octstr_get_cstr(addr));
399  reason = SMPP_ESME_RINVSRCADR;
400  goto error;
401  }
402  /* check if we received leading '00', then remove it*/
403  if (octstr_search(addr, octstr_imm("00"), 0) == 0)
404  octstr_delete(addr, 0, 2);
405 
406  /* international, insert '+' if not already here */
407  if (octstr_get_char(addr, 0) != '+')
408  octstr_insert_char(addr, 0, '+');
409 
410  break;
412  if (octstr_len(addr) > 11) {
413  /* alphanum sender, max. allowed length is 11 (according to GSM specs) */
414  error(0, "SMPP[%s]: Malformed addr `%s', alphanumeric length greater 11 chars. ",
415  octstr_get_cstr(id),
416  octstr_get_cstr(addr));
417  reason = SMPP_ESME_RINVSRCADR;
418  goto error;
419  }
420  if (alt_addr_charset) {
421  if (octstr_str_case_compare(alt_addr_charset, "gsm") == 0)
422  charset_gsm_to_utf8(addr);
423  else if (charset_convert(addr, octstr_get_cstr(alt_addr_charset), SMPP_DEFAULT_CHARSET) != 0)
424  error(0, "Failed to convert address from charset <%s> to <%s>, leave as is.",
425  octstr_get_cstr(alt_addr_charset), SMPP_DEFAULT_CHARSET);
426  }
427  break;
428  default: /* otherwise don't touch addr, user should handle it */
429  break;
430  }
431 
432 error:
433  return reason;
434 }
435 
436 
437 static void handle_mt_dcs(Octstr *short_message, int data_coding)
438 {
439  /*
440  * Keep in mind that we do transcode the encoding here,
441  * but effectively we're limited to the GSM 03.38 alphabet character
442  * range, since we do a round-trip conversion from/to UTF-8/GSM in
443  * function gw/sms.c:extract_msgdata_part_by_coding().
444  *
445  * If your underlying radio network is NOT GSM, and you want to support
446  * the extended range of characters of the tables, then remove the
447  * round-trip conversion from the above mentioned function.
448  */
449  switch (data_coding) {
450  case 0x01: /* ASCII or IA5 */
451  if (charset_convert(short_message, SMPP_DEFAULT_CHARSET, "ASCII") != 0) {
452  error(0, "Failed to convert msgdata from " SMPP_DEFAULT_CHARSET " to ASCII, will leave as is");
453  }
454  break;
455  case 0x03: /* ISO-8859-1 (aka latin1) */
456  if (charset_convert(short_message, SMPP_DEFAULT_CHARSET, "LATIN1") != 0) {
457  error(0, "Failed to convert msgdata from " SMPP_DEFAULT_CHARSET " to LATIN1, will leave as is");
458  }
459  break;
460  case 0x02: /* 8 bit binary - do nothing */
461  case 0x04: /* 8 bit binary - do nothing */
462  break;
463  case 0x05: /* Japanese, JIS(X 0208-1990) */
464  if (charset_convert(short_message, SMPP_DEFAULT_CHARSET, "JIS_X0208-1990") != 0)
465  error(0, "Failed to convert msgdata from " SMPP_DEFAULT_CHARSET " to Japanese (JIS-X0208-1990), "
466  "will leave as is");
467  break;
468  case 0x06: /* Cyrllic - iso-8859-5 */
469  if (charset_convert(short_message, SMPP_DEFAULT_CHARSET, "ISO-8859-5") != 0)
470  error(0, "Failed to convert msgdata from " SMPP_DEFAULT_CHARSET " to Cyrllic (ISO-8859-5), "
471  "will leave as is");
472  break;
473  case 0x07: /* Hebrew iso-8859-8 */
474  if (charset_convert(short_message, SMPP_DEFAULT_CHARSET, "ISO-8859-8") != 0)
475  error(0, "Failed to convert msgdata from " SMPP_DEFAULT_CHARSET " to Hebrew (ISO-8859-8), "
476  "will leave as is");
477  break;
478  case 0x08: /* unicode UCS-2, don't convert here anything. */
479  break;
480  case 0x0D: /* Japanese, Extended Kanji JIS(X 0212-1990) */
481  if (charset_convert(short_message, SMPP_DEFAULT_CHARSET, "JIS_X0212-1990") != 0)
482  error(0, "Failed to convert msgdata from " SMPP_DEFAULT_CHARSET " to Japanese (JIS-X0212-1990), "
483  "will leave as is");
484  break;
485  case 0x0E: /* Korean, KS C 5601 - now called KS X 1001, convert to Unicode */
486  if (charset_convert(short_message, SMPP_DEFAULT_CHARSET, "KSC_5601") != 0 &&
487  charset_convert(short_message, SMPP_DEFAULT_CHARSET, "KSC5636") != 0)
488  error(0, "Failed to convert msgdata from " SMPP_DEFAULT_CHARSET " to Korean (KSC_5601/KSC5636), "
489  "will leave as is");
490  break;
491  case 0x00: /* GSM 03.38 */
492  default:
493  charset_utf8_to_gsm(short_message);
494  break;
495 
496  /*
497  * don't much care about the others,
498  * you implement them if you feel like it
499  */
500  }
501 }
502 
503 
504 static void handle_mo_dcs(Msg *msg, Octstr *alt_charset, int data_coding, int esm_class)
505 {
506  switch (data_coding) {
507  case 0x00: /* default SMSC alphabet */
508  /*
509  * try to convert from something interesting if specified so
510  * unless it was specified binary, i.e. UDH indicator was detected
511  */
512  if (alt_charset && msg->sms.coding != DC_8BIT) {
513  if (charset_convert(msg->sms.msgdata, octstr_get_cstr(alt_charset), SMPP_DEFAULT_CHARSET) != 0)
514  error(0, "Failed to convert msgdata from charset <%s> to <%s>, will leave as is.",
515  octstr_get_cstr(alt_charset), SMPP_DEFAULT_CHARSET);
516  msg->sms.coding = DC_7BIT;
517  } else { /* assume GSM 03.38 7-bit alphabet */
518  charset_gsm_to_utf8(msg->sms.msgdata);
519  msg->sms.coding = DC_7BIT;
520  }
521  break;
522  case 0x01:
523  /* ASCII/IA5 - we don't need to perform any conversion
524  * due that UTF-8's first range is exactly the ASCII table */
525  msg->sms.coding = DC_7BIT; break;
526  case 0x03: /* ISO-8859-1 - I'll convert to internal encoding */
527  if (charset_convert(msg->sms.msgdata, "ISO-8859-1", SMPP_DEFAULT_CHARSET) != 0)
528  error(0, "Failed to convert msgdata from ISO-8859-1 to " SMPP_DEFAULT_CHARSET ", will leave as is");
529  msg->sms.coding = DC_7BIT; break;
530  case 0x02: /* 8 bit binary - do nothing */
531  case 0x04: /* 8 bit binary - do nothing */
532  msg->sms.coding = DC_8BIT; break;
533  case 0x05: /* Japanese, JIS(X 0208-1990) */
534  if (charset_convert(msg->sms.msgdata, "JIS_X0208-1990", SMPP_DEFAULT_CHARSET) != 0)
535  error(0, "Failed to convert msgdata from Japanese (JIS_X0208-1990) to " SMPP_DEFAULT_CHARSET ", will leave as is");
536  msg->sms.coding = DC_7BIT; break;
537  case 0x06: /* Cyrllic - iso-8859-5, I'll convert to internal encoding */
538  if (charset_convert(msg->sms.msgdata, "ISO-8859-5", SMPP_DEFAULT_CHARSET) != 0)
539  error(0, "Failed to convert msgdata from Cyrllic (ISO-8859-5) to " SMPP_DEFAULT_CHARSET ", will leave as is");
540  msg->sms.coding = DC_7BIT; break;
541  case 0x07: /* Hebrew iso-8859-8, I'll convert to internal encoding */
542  if (charset_convert(msg->sms.msgdata, "ISO-8859-8", SMPP_DEFAULT_CHARSET) != 0)
543  error(0, "Failed to convert msgdata from Hebrew (ISO-8859-8) to " SMPP_DEFAULT_CHARSET ", will leave as is");
544  msg->sms.coding = DC_7BIT; break;
545  case 0x08: /* unicode UCS-2, yey */
546  msg->sms.coding = DC_UCS2; break;
547  case 0x0D: /* Japanese, Extended Kanji JIS(X 0212-1990) */
548  if (charset_convert(msg->sms.msgdata, "JIS_X0212-1990", SMPP_DEFAULT_CHARSET) != 0)
549  error(0, "Failed to convert msgdata from Japanese (JIS-X0212-1990) to " SMPP_DEFAULT_CHARSET ", will leave as is");
550  msg->sms.coding = DC_7BIT; break;
551  case 0x0E: /* Korean, KS C 5601 - now called KS X 1001, convert to Unicode */
552  if (charset_convert(msg->sms.msgdata, "KSC_5601", SMPP_DEFAULT_CHARSET) != 0 &&
553  charset_convert(msg->sms.msgdata, "KSC5636", SMPP_DEFAULT_CHARSET) != 0)
554  error(0, "Failed to convert msgdata from Korean (KSC_5601/KSC5636) to " SMPP_DEFAULT_CHARSET ", will leave as is");
555  msg->sms.coding = DC_7BIT; break;
556 
557  /*
558  * don't much care about the others,
559  * you implement them if you feel like it
560  */
561 
562  default:
563  /*
564  * some of smsc send with dcs from GSM 03.38 , but these are reserved in smpp spec.
565  * So we just look decoded values from dcs_to_fields and if none there make our assumptions.
566  * if we have an UDH indicator, we assume DC_8BIT.
567  */
568  if (msg->sms.coding == DC_UNDEF && (esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR))
569  msg->sms.coding = DC_8BIT;
570  else if (msg->sms.coding == DC_7BIT || msg->sms.coding == DC_UNDEF) { /* assume GSM 7Bit , re-encode */
571  msg->sms.coding = DC_7BIT;
572  charset_gsm_to_utf8(msg->sms.msgdata);
573  }
574  break;
575  }
576 }
577 
578 
579 /*
580  * Convert SMPP PDU to internal Msgs structure.
581  * Return the Msg if all was fine and NULL otherwise, while getting
582  * the failing reason delivered back in *reason.
583  * XXX semantical check on the incoming values can be extended here.
584  */
585 static Msg *pdu_to_msg(SMPP *smpp, SMPP_PDU *pdu, long *reason)
586 {
587  Msg *msg;
588  int ton, npi;
589 
590  gw_assert(pdu->type == deliver_sm);
591 
592  msg = msg_create(sms);
593  gw_assert(msg != NULL);
594  *reason = SMPP_ESME_ROK;
595 
596  /*
597  * Reset source addr to have a prefixed '+' in case we have an
598  * intl. TON to allow backend boxes (ie. smsbox) to distinguish
599  * between national and international numbers.
600  */
601  ton = pdu->u.deliver_sm.source_addr_ton;
602  npi = pdu->u.deliver_sm.source_addr_npi;
603  /* check source addr */
604  if ((*reason = convert_addr_from_pdu(smpp->conn->id, pdu->u.deliver_sm.source_addr, ton, npi, smpp->alt_addr_charset)) != SMPP_ESME_ROK)
605  goto error;
606  msg->sms.sender = pdu->u.deliver_sm.source_addr;
607  pdu->u.deliver_sm.source_addr = NULL;
608 
609  /*
610  * Follows SMPP spec. v3.4. issue 1.2
611  * it's not allowed to have destination_addr NULL
612  */
613  if (pdu->u.deliver_sm.destination_addr == NULL) {
614  error(0, "SMPP[%s]: Malformed destination_addr `%s', may not be empty. "
615  "Discarding MO message.", octstr_get_cstr(smpp->conn->id),
616  octstr_get_cstr(pdu->u.deliver_sm.destination_addr));
617  *reason = SMPP_ESME_RINVDSTADR;
618  goto error;
619  }
620 
621  /* Same reset of destination number as for source */
622  ton = pdu->u.deliver_sm.dest_addr_ton;
623  npi = pdu->u.deliver_sm.dest_addr_npi;
624  /* check destination addr */
625  if ((*reason = convert_addr_from_pdu(smpp->conn->id, pdu->u.deliver_sm.destination_addr, ton, npi, smpp->alt_addr_charset)) != SMPP_ESME_ROK)
626  goto error;
627  msg->sms.receiver = pdu->u.deliver_sm.destination_addr;
628  pdu->u.deliver_sm.destination_addr = NULL;
629 
630  /* SMSCs use service_type for billing information
631  * According to SMPP v5.0 there is no 'billing_identification'
632  * TLV in the deliver_sm PDU optional TLVs. */
633  msg->sms.binfo = pdu->u.deliver_sm.service_type;
634  pdu->u.deliver_sm.service_type = NULL;
635 
636  /* Foreign ID on MO */
637  msg->sms.foreign_id = pdu->u.deliver_sm.receipted_message_id;
638  pdu->u.deliver_sm.receipted_message_id = NULL;
639 
640  if (pdu->u.deliver_sm.esm_class & ESM_CLASS_SUBMIT_RPI)
641  msg->sms.rpi = 1;
642 
643  /*
644  * Check for message_payload if version > 0x33 and sm_length == 0
645  * Note: SMPP spec. v3.4. doesn't allow to send both: message_payload & short_message!
646  */
647  if (smpp->version > 0x33 && pdu->u.deliver_sm.sm_length == 0 && pdu->u.deliver_sm.message_payload) {
648  msg->sms.msgdata = pdu->u.deliver_sm.message_payload;
649  pdu->u.deliver_sm.message_payload = NULL;
650  }
651  else {
652  msg->sms.msgdata = pdu->u.deliver_sm.short_message;
653  pdu->u.deliver_sm.short_message = NULL;
654  }
655 
656  /* check sar_msg_ref_num, sar_segment_seqnum, sar_total_segments */
657  if (smpp->version > 0x33 &&
658  pdu->u.deliver_sm.sar_msg_ref_num >= 0 && pdu->u.deliver_sm.sar_segment_seqnum > 0 && pdu->u.deliver_sm.sar_total_segments > 0) {
659  /*
660  For GSM networks, the concatenation related TLVs (sar_msg_ref_num, sar_total_segments, sar_segment_seqnum)
661  or port addressing related TLVs
662  (source_port, dest_port) cannot be used in conjunction with encoded User Data Header in the short_message
663  (user data) field. This means that the above listed TLVs cannot be used if the User Data Header Indicator flag is set.
664  */
665  if (pdu->u.deliver_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR) {
666  error(0, "SMPP[%s]: sar_msg_ref_num, sar_segment_seqnum, sar_total_segments in conjuction with UDHI used, rejected.",
667  octstr_get_cstr(smpp->conn->id));
668  *reason = SMPP_ESME_RINVTLVVAL;
669  goto error;
670  }
671  /* create multipart UDH */
673  pdu->u.deliver_sm.sar_segment_seqnum,
674  pdu->u.deliver_sm.sar_total_segments,
675  pdu->u.deliver_sm.sar_msg_ref_num);
676  }
677 
678  /*
679  * Encode udh if udhi set
680  * for reference see GSM03.40, section 9.2.3.24
681  */
682  if (pdu->u.deliver_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR) {
683  int udhl;
684  udhl = octstr_get_char(msg->sms.msgdata, 0) + 1;
685  debug("bb.sms.smpp",0,"SMPP[%s]: UDH length read as %d",
686  octstr_get_cstr(smpp->conn->id), udhl);
687  if (udhl > octstr_len(msg->sms.msgdata)) {
688  error(0, "SMPP[%s]: Malformed UDH length indicator 0x%03x while message length "
689  "0x%03lx. Discarding MO message.", octstr_get_cstr(smpp->conn->id),
690  udhl, octstr_len(msg->sms.msgdata));
691  *reason = SMPP_ESME_RINVESMCLASS;
692  goto error;
693  }
694  msg->sms.udhdata = octstr_copy(msg->sms.msgdata, 0, udhl);
695  octstr_delete(msg->sms.msgdata, 0, udhl);
696  }
697 
698  dcs_to_fields(&msg, pdu->u.deliver_sm.data_coding);
699 
700  /* handle default data coding */
701  handle_mo_dcs(msg, smpp->alt_charset, pdu->u.deliver_sm.data_coding, pdu->u.deliver_sm.esm_class);
702 
703  msg->sms.pid = pdu->u.deliver_sm.protocol_id;
704 
705  /* set priority flag */
706  msg->sms.priority = pdu->u.deliver_sm.priority_flag;
707 
708  if (msg->sms.meta_data == NULL)
709  msg->sms.meta_data = octstr_create("");
710  meta_data_set_values(msg->sms.meta_data, pdu->u.deliver_sm.tlv, "smpp", 1);
711 
712  return msg;
713 
714 error:
715  msg_destroy(msg);
716  return NULL;
717 }
718 
719 
720 /*
721  * Convert SMPP PDU to internal Msgs structure.
722  * Return the Msg if all was fine and NULL otherwise, while getting
723  * the failing reason delivered back in *reason.
724  * XXX semantical check on the incoming values can be extended here.
725  */
726 static Msg *data_sm_to_msg(SMPP *smpp, SMPP_PDU *pdu, long *reason)
727 {
728  Msg *msg;
729  int ton, npi;
730 
731  gw_assert(pdu->type == data_sm);
732 
733  msg = msg_create(sms);
734  gw_assert(msg != NULL);
735  *reason = SMPP_ESME_ROK;
736 
737  /*
738  * Reset source addr to have a prefixed '+' in case we have an
739  * intl. TON to allow backend boxes (ie. smsbox) to distinguish
740  * between national and international numbers.
741  */
742  ton = pdu->u.data_sm.source_addr_ton;
743  npi = pdu->u.data_sm.source_addr_npi;
744  /* check source addr */
745  if ((*reason = convert_addr_from_pdu(smpp->conn->id, pdu->u.data_sm.source_addr, ton, npi, smpp->alt_addr_charset)) != SMPP_ESME_ROK)
746  goto error;
747  msg->sms.sender = pdu->u.data_sm.source_addr;
748  pdu->u.data_sm.source_addr = NULL;
749 
750  /*
751  * Follows SMPP spec. v3.4. issue 1.2
752  * it's not allowed to have destination_addr NULL
753  */
754  if (pdu->u.data_sm.destination_addr == NULL) {
755  error(0, "SMPP[%s]: Malformed destination_addr `%s', may not be empty. "
756  "Discarding MO message.", octstr_get_cstr(smpp->conn->id),
757  octstr_get_cstr(pdu->u.data_sm.destination_addr));
758  *reason = SMPP_ESME_RINVDSTADR;
759  goto error;
760  }
761 
762  /* Same reset of destination number as for source */
763  ton = pdu->u.data_sm.dest_addr_ton;
764  npi = pdu->u.data_sm.dest_addr_npi;
765  /* check destination addr */
766  if ((*reason = convert_addr_from_pdu(smpp->conn->id, pdu->u.data_sm.destination_addr, ton, npi, smpp->alt_addr_charset)) != SMPP_ESME_ROK)
767  goto error;
768  msg->sms.receiver = pdu->u.data_sm.destination_addr;
769  pdu->u.data_sm.destination_addr = NULL;
770 
771  /* SMSCs use service_type for billing information */
772  if (smpp->version == 0x50 && pdu->u.data_sm.billing_identification) {
773  msg->sms.binfo = pdu->u.data_sm.billing_identification;
774  pdu->u.data_sm.billing_identification = NULL;
775  } else {
776  msg->sms.binfo = pdu->u.data_sm.service_type;
777  pdu->u.data_sm.service_type = NULL;
778  }
779 
780  /* Foreign ID on MO */
781  msg->sms.foreign_id = pdu->u.data_sm.receipted_message_id;
782  pdu->u.data_sm.receipted_message_id = NULL;
783 
784  if (pdu->u.data_sm.esm_class & ESM_CLASS_SUBMIT_RPI)
785  msg->sms.rpi = 1;
786 
787  msg->sms.msgdata = pdu->u.data_sm.message_payload;
788  pdu->u.data_sm.message_payload = NULL;
789 
790  /* check sar_msg_ref_num, sar_segment_seqnum, sar_total_segments */
791  if (pdu->u.data_sm.sar_msg_ref_num >= 0 && pdu->u.data_sm.sar_segment_seqnum > 0 && pdu->u.data_sm.sar_total_segments > 0) {
792  /*
793  For GSM networks, the concatenation related TLVs (sar_msg_ref_num, sar_total_segments, sar_segment_seqnum)
794  or port addressing related TLVs
795  (source_port, dest_port) cannot be used in conjunction with encoded User Data Header in the short_message
796  (user data) field. This means that the above listed TLVs cannot be used if the User Data Header Indicator flag is set.
797  */
798  if (pdu->u.data_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR) {
799  error(0, "SMPP[%s]: sar_msg_ref_num, sar_segment_seqnum, sar_total_segments in conjuction with UDHI used, rejected.",
800  octstr_get_cstr(smpp->conn->id));
801  *reason = SMPP_ESME_RINVTLVVAL;
802  goto error;
803  }
804  /* create multipart UDH */
806  pdu->u.data_sm.sar_segment_seqnum,
807  pdu->u.data_sm.sar_total_segments,
808  pdu->u.data_sm.sar_msg_ref_num);
809  }
810 
811  /*
812  * Encode udh if udhi set
813  * for reference see GSM03.40, section 9.2.3.24
814  */
815  if (pdu->u.data_sm.esm_class & ESM_CLASS_SUBMIT_UDH_INDICATOR) {
816  int udhl;
817  udhl = octstr_get_char(msg->sms.msgdata, 0) + 1;
818  debug("bb.sms.smpp",0,"SMPP[%s]: UDH length read as %d",
819  octstr_get_cstr(smpp->conn->id), udhl);
820  if (udhl > octstr_len(msg->sms.msgdata)) {
821  error(0, "SMPP[%s]: Malformed UDH length indicator 0x%03x while message length "
822  "0x%03lx. Discarding MO message.", octstr_get_cstr(smpp->conn->id),
823  udhl, octstr_len(msg->sms.msgdata));
824  *reason = SMPP_ESME_RINVESMCLASS;
825  goto error;
826  }
827  msg->sms.udhdata = octstr_copy(msg->sms.msgdata, 0, udhl);
828  octstr_delete(msg->sms.msgdata, 0, udhl);
829  }
830 
831  dcs_to_fields(&msg, pdu->u.data_sm.data_coding);
832 
833  /* handle default data coding */
834  handle_mo_dcs(msg, smpp->alt_charset, pdu->u.data_sm.data_coding, pdu->u.data_sm.esm_class);
835 
836  if (msg->sms.meta_data == NULL)
837  msg->sms.meta_data = octstr_create("");
838  meta_data_set_values(msg->sms.meta_data, pdu->u.data_sm.tlv, "smpp", 1);
839 
840  return msg;
841 
842 error:
843  msg_destroy(msg);
844  return NULL;
845 }
846 
847 
848 
850 {
851  switch(status) {
852  case SMPP_ESME_RMSGQFUL:
854  case SMPP_ESME_RX_T_APPN:
855  case SMPP_ESME_RSYSERR:
857  break;
858 
859  default:
861  }
862 }
863 
864 
865 static SMPP_PDU *msg_to_pdu(SMPP *smpp, Msg *msg)
866 {
867  SMPP_PDU *pdu;
868  int validity;
869  Octstr *tmp;
870  int ton_npi_forced;
871  int data_coding = -1;
872 
873  pdu = smpp_pdu_create(submit_sm,
875 
876  pdu->u.submit_sm.source_addr = octstr_duplicate(msg->sms.sender);
877  pdu->u.submit_sm.destination_addr = octstr_duplicate(msg->sms.receiver);
878 
879  /* Set the service type of the outgoing message. We'll use the config
880  * directive as default and 'binfo' as specific parameter. */
881  if (octstr_len(msg->sms.binfo)) {
882  /* SMPP v5.0 has an own TLV for billing information */
883  if (smpp->version == 0x50) {
884  pdu->u.submit_sm.billing_identification = octstr_duplicate(msg->sms.binfo);
885  } else {
886  pdu->u.submit_sm.service_type = octstr_duplicate(msg->sms.binfo);
887  }
888  } else {
889  pdu->u.submit_sm.service_type = octstr_duplicate(smpp->service_type);
890  }
891 
892  /* Check for manual override of source ton and npi values */
893  if (smpp->source_addr_ton > -1 && smpp->source_addr_npi > -1) {
894  pdu->u.submit_sm.source_addr_ton = smpp->source_addr_ton;
895  pdu->u.submit_sm.source_addr_npi = smpp->source_addr_npi;
896  debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced source addr ton = %d, source add npi = %d",
897  octstr_get_cstr(smpp->conn->id), smpp->source_addr_ton,
898  smpp->source_addr_npi);
899  } else {
900  /* setup default values */
901  pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */
902  pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */
903  }
904 
905  /* Check for forced source ton and npi values via meta-data */
906  ton_npi_forced = 0;
907  tmp = meta_data_get_value(msg->sms.meta_data, METADATA_SMPP_GROUP, octstr_imm("source_addr_ton"));
908  if (tmp != NULL) {
909  ton_npi_forced = 1;
910  pdu->u.submit_sm.source_addr_ton = atoi(octstr_get_cstr(tmp));
911  octstr_destroy(tmp);
912  }
913  tmp = meta_data_get_value(msg->sms.meta_data, METADATA_SMPP_GROUP, octstr_imm("source_addr_npi"));
914  if (tmp != NULL) {
915  ton_npi_forced = 1;
916  pdu->u.submit_sm.source_addr_npi = atoi(octstr_get_cstr(tmp));
917  octstr_destroy(tmp);
918  }
919 
920  /* don't touch source_addr ton/npi if overwritten in meta_data */
921  if (pdu->u.submit_sm.source_addr && !ton_npi_forced && smpp->autodetect_addr) {
922  /* lets see if its international or alphanumeric sender */
923  if (octstr_get_char(pdu->u.submit_sm.source_addr, 0) == '+') {
924  if (!octstr_check_range(pdu->u.submit_sm.source_addr, 1, 256, gw_isdigit)) {
925  pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC; /* alphanum */
926  pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN; /* short code */
927  if (smpp->alt_addr_charset) {
928  if (octstr_str_case_compare(smpp->alt_addr_charset, "gsm") == 0) {
929  /* @ would break PDU if converted into GSM*/
930  octstr_replace(pdu->u.submit_sm.source_addr, octstr_imm("@"), octstr_imm("?"));
931  charset_utf8_to_gsm(pdu->u.submit_sm.source_addr);
932  } else if (charset_convert(pdu->u.submit_sm.source_addr, SMPP_DEFAULT_CHARSET, octstr_get_cstr(smpp->alt_addr_charset)) != 0)
933  error(0, "Failed to convert source_addr from charset <%s> to <%s>, will send as is.",
935  }
936  } else {
937  /* numeric sender address with + in front -> international (remove the +) */
938  octstr_delete(pdu->u.submit_sm.source_addr, 0, 1);
939  pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_INTERNATIONAL;
940  }
941  } else {
942  if (!octstr_check_range(pdu->u.submit_sm.source_addr,0, 256, gw_isdigit)) {
943  pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC;
944  pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN;
945  if (smpp->alt_addr_charset) {
946  if (octstr_str_case_compare(smpp->alt_addr_charset, "gsm") == 0) {
947  /* @ would break PDU if converted into GSM */
948  octstr_replace(pdu->u.submit_sm.source_addr, octstr_imm("@"), octstr_imm("?"));
949  charset_utf8_to_gsm(pdu->u.submit_sm.source_addr);
950  } else if (charset_convert(pdu->u.submit_sm.source_addr, SMPP_DEFAULT_CHARSET, octstr_get_cstr(smpp->alt_addr_charset)) != 0)
951  error(0, "Failed to convert source_addr from charset <%s> to <%s>, will send as is.",
953  }
954  }
955  }
956  }
957 
958  /* Check for manual override of destination ton and npi values */
959  if (smpp->dest_addr_ton > -1 && smpp->dest_addr_npi > -1) {
960  pdu->u.submit_sm.dest_addr_ton = smpp->dest_addr_ton;
961  pdu->u.submit_sm.dest_addr_npi = smpp->dest_addr_npi;
962  debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced dest addr ton = %d, dest add npi = %d",
963  octstr_get_cstr(smpp->conn->id), smpp->dest_addr_ton,
964  smpp->dest_addr_npi);
965  } else {
966  pdu->u.submit_sm.dest_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */
967  pdu->u.submit_sm.dest_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */
968  }
969 
970  /* Check for forced destination ton and npi values via meta-data */
971  ton_npi_forced = 0;
972  tmp = meta_data_get_value(msg->sms.meta_data, METADATA_SMPP_GROUP, octstr_imm("dest_addr_ton"));
973  if (tmp != NULL) {
974  ton_npi_forced = 1;
975  pdu->u.submit_sm.dest_addr_ton = atoi(octstr_get_cstr(tmp));
976  octstr_destroy(tmp);
977  }
978  tmp = meta_data_get_value(msg->sms.meta_data, METADATA_SMPP_GROUP, octstr_imm("dest_addr_npi"));
979  if (tmp != NULL) {
980  ton_npi_forced = 1;
981  pdu->u.submit_sm.dest_addr_npi = atoi(octstr_get_cstr(tmp));
982  octstr_destroy(tmp);
983  }
984 
985  /* don't touch source_addr ton/npi if overwritten in meta_data */
986  if (!ton_npi_forced) {
987  /*
988  * if its a international number starting with +, lets remove the
989  * '+' and set number type to international instead
990  */
991  if (octstr_get_char(pdu->u.submit_sm.destination_addr,0) == '+') {
992  octstr_delete(pdu->u.submit_sm.destination_addr, 0,1);
993  pdu->u.submit_sm.dest_addr_ton = GSM_ADDR_TON_INTERNATIONAL;
994  }
995  }
996 
997  /* check length of src/dst address */
998  if (octstr_len(pdu->u.submit_sm.destination_addr) > 20 ||
999  octstr_len(pdu->u.submit_sm.source_addr) > 20) {
1000  smpp_pdu_destroy(pdu);
1001  return NULL;
1002  }
1003 
1004  /*
1005  * set the data coding scheme (DCS) field
1006  * check if we have a forced value for this from the smsc-group.
1007  * Note: if message class is set, then we _must_ force alt_dcs otherwise
1008  * dcs has reserved values (e.g. mclass=2, dcs=0x11). We check MWI flag
1009  * first here, because MWI and MCLASS can not be set at the same time and
1010  * function fields_to_dcs check MWI first, so we have no need to force alt_dcs
1011  * if MWI is set.
1012  */
1013  if (msg->sms.mwi == MWI_UNDEF && msg->sms.mclass != MC_UNDEF)
1014  pdu->u.submit_sm.data_coding = fields_to_dcs(msg, 1); /* force alt_dcs */
1015  else
1016  pdu->u.submit_sm.data_coding = fields_to_dcs(msg,
1017  (msg->sms.alt_dcs != SMS_PARAM_UNDEFINED ?
1018  msg->sms.alt_dcs : smpp->conn->alt_dcs));
1019 
1020  /* set protocol id */
1021  if (msg->sms.pid != SMS_PARAM_UNDEFINED)
1022  pdu->u.submit_sm.protocol_id = msg->sms.pid;
1023 
1024  /*
1025  * set the esm_class field
1026  * default is store and forward, plus udh and rpi if requested
1027  */
1028  pdu->u.submit_sm.esm_class = smpp->esm_class;
1029  if (octstr_len(msg->sms.udhdata))
1030  pdu->u.submit_sm.esm_class = pdu->u.submit_sm.esm_class |
1032  if (msg->sms.rpi > 0)
1033  pdu->u.submit_sm.esm_class = pdu->u.submit_sm.esm_class |
1035 
1036  /*
1037  * set data segments and length
1038  */
1039 
1040  pdu->u.submit_sm.short_message = octstr_duplicate(msg->sms.msgdata);
1041 
1042  /* Check for forced data_coding value via meta-data */
1043  tmp = meta_data_get_value(msg->sms.meta_data, METADATA_SMPP_GROUP, octstr_imm("data_coding"));
1044  if (tmp != NULL) {
1045  data_coding = atoi(octstr_get_cstr(tmp));
1046  octstr_destroy(tmp);
1047  }
1048 
1049  /*
1050  * only re-encoding if using default smsc charset that is defined via
1051  * alt-charset in smsc group and if MT is not binary
1052  */
1053  if (msg->sms.coding == DC_7BIT || (msg->sms.coding == DC_UNDEF && octstr_len(msg->sms.udhdata) == 0)) {
1054  /*
1055  * consider 4 cases:
1056  * a) data_coding 0xFX: encoding should always be GSM 03.38 charset
1057  * b) data_coding 0xXX: encoding based on forced meta-data value
1058  * c) data_coding 0x00: encoding may be converted according to alt-charset
1059  * d) data_coding 0x00: assume GSM 03.38 charset if alt-charset is not defined
1060  */
1061  if (pdu->u.submit_sm.data_coding & 0xF0) {
1062  charset_utf8_to_gsm(pdu->u.submit_sm.short_message);
1063  } else if (pdu->u.submit_sm.data_coding == 0 && !smpp->alt_charset) {
1064  /*
1065  * convert to a forced data_coding value, or GSM 03.38 if not
1066  */
1067  handle_mt_dcs(pdu->u.submit_sm.short_message, data_coding);
1068  if (data_coding != -1)
1069  pdu->u.submit_sm.data_coding = data_coding;
1070  } else if (pdu->u.submit_sm.data_coding == 0 && smpp->alt_charset) {
1071  /*
1072  * convert to the given alternative charset
1073  */
1074  if (charset_convert(pdu->u.submit_sm.short_message, SMPP_DEFAULT_CHARSET,
1075  octstr_get_cstr(smpp->alt_charset)) != 0)
1076  error(0, "Failed to convert msgdata from charset <%s> to <%s>, will send as is.",
1078  }
1079  }
1080 
1081  /* prepend udh if present */
1082  if (octstr_len(msg->sms.udhdata)) {
1083  octstr_insert(pdu->u.submit_sm.short_message, msg->sms.udhdata, 0);
1084  }
1085 
1086  pdu->u.submit_sm.sm_length = octstr_len(pdu->u.submit_sm.short_message);
1087 
1088  /*
1089  * check for validity and deferred settings
1090  * were message value has higher priority then smsc config group value
1091  * Note: we always send in UTC and just define "Time Difference" as 00 and
1092  * direction '+'.
1093  */
1094  validity = SMS_PARAM_UNDEFINED;
1095  if (msg->sms.validity != SMS_PARAM_UNDEFINED)
1096  validity = msg->sms.validity;
1097  else if (smpp->validityperiod != SMS_PARAM_UNDEFINED)
1098  validity = time(NULL) + smpp->validityperiod * 60;
1099  if (validity != SMS_PARAM_UNDEFINED) {
1100  struct tm tm = gw_gmtime(validity);
1101  pdu->u.submit_sm.validity_period = octstr_format("%02d%02d%02d%02d%02d%02d000+",
1102  tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
1103  tm.tm_hour, tm.tm_min, tm.tm_sec);
1104  }
1105 
1106  if (msg->sms.deferred != SMS_PARAM_UNDEFINED) {
1107  struct tm tm = gw_gmtime(msg->sms.deferred);
1108  pdu->u.submit_sm.schedule_delivery_time = octstr_format("%02d%02d%02d%02d%02d%02d000+",
1109  tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
1110  tm.tm_hour, tm.tm_min, tm.tm_sec);
1111  }
1112 
1113  /* ask for the delivery reports if needed */
1114  if (DLR_IS_FAIL(msg->sms.dlr_mask) && !DLR_IS_SUCCESS(msg->sms.dlr_mask))
1115  pdu->u.submit_sm.registered_delivery = 2;
1116  else if (DLR_IS_SUCCESS_OR_FAIL(msg->sms.dlr_mask))
1117  pdu->u.submit_sm.registered_delivery = 1;
1118 
1119  if (DLR_IS_BUFFERED(msg->sms.dlr_mask))
1120  pdu->u.submit_sm.registered_delivery += 16;
1121 
1122  /* set priority */
1123  if (msg->sms.priority >= 0 && msg->sms.priority <= 3)
1124  pdu->u.submit_sm.priority_flag = msg->sms.priority;
1125  else
1126  pdu->u.submit_sm.priority_flag = smpp->priority;
1127 
1128  /* set more messages to send */
1129  if (smpp->version > 0x33 && msg->sms.msg_left > 0)
1130  pdu->u.submit_sm.more_messages_to_send = 1;
1131 
1132  dict_destroy(pdu->u.submit_sm.tlv);
1133  pdu->u.submit_sm.tlv = meta_data_get_values(msg->sms.meta_data, "smpp");
1134 
1135  return pdu;
1136 }
1137 
1138 
1139 static int send_enquire_link(SMPP *smpp, Connection *conn, long *last_sent)
1140 {
1141  SMPP_PDU *pdu;
1142  Octstr *os;
1143  int ret;
1144 
1145  if (difftime(date_universal_now(),*last_sent) < smpp->enquire_link_interval)
1146  return 0;
1147  *last_sent = date_universal_now();
1148 
1149  pdu = smpp_pdu_create(enquire_link, counter_increase(smpp->message_id_counter));
1150  dump_pdu("Sending enquire link:", smpp->conn->id, pdu, smpp->log_format);
1151  os = smpp_pdu_pack(smpp->conn->id, pdu);
1152  if (os != NULL)
1153  ret = conn_write(conn, os); /* Write errors checked by caller. */
1154  else
1155  ret = -1;
1156  octstr_destroy(os);
1157  smpp_pdu_destroy(pdu);
1158 
1159  return ret;
1160 }
1161 
1162 static int send_gnack(SMPP *smpp, Connection *conn, long reason, unsigned long seq_num)
1163 {
1164  SMPP_PDU *pdu;
1165  Octstr *os;
1166  int ret;
1167 
1168  pdu = smpp_pdu_create(generic_nack, seq_num);
1169  pdu->u.generic_nack.command_status = reason;
1170  dump_pdu("Sending generic_nack:", smpp->conn->id, pdu, smpp->log_format);
1171  os = smpp_pdu_pack(smpp->conn->id, pdu);
1172  if (os != NULL)
1173  ret = conn_write(conn, os);
1174  else
1175  ret = -1;
1176  octstr_destroy(os);
1177  smpp_pdu_destroy(pdu);
1178 
1179  return ret;
1180 }
1181 
1182 static int send_unbind(SMPP *smpp, Connection *conn)
1183 {
1184  SMPP_PDU *pdu;
1185  Octstr *os;
1186  int ret;
1187 
1188  pdu = smpp_pdu_create(unbind, counter_increase(smpp->message_id_counter));
1189  dump_pdu("Sending unbind:", smpp->conn->id, pdu, smpp->log_format);
1190  os = smpp_pdu_pack(smpp->conn->id, pdu);
1191  if (os != NULL)
1192  ret = conn_write(conn, os);
1193  else
1194  ret = -1;
1195  octstr_destroy(os);
1196  smpp_pdu_destroy(pdu);
1197 
1198  return ret;
1199 }
1200 
1201 
1202 static int send_pdu(Connection *conn, SMPP *smpp, SMPP_PDU *pdu)
1203 {
1204  Octstr *os;
1205  int ret;
1206 
1207  dump_pdu("Sending PDU:", smpp->conn->id, pdu, smpp->log_format);
1208  os = smpp_pdu_pack(smpp->conn->id, pdu);
1209  if (os) {
1210  /* Caller checks for write errors later */
1211  ret = conn_write(conn, os);
1212  /* it's not a error if we still have data buffered */
1213  ret = (ret == 1) ? 0 : ret;
1214  } else
1215  ret = -1;
1216  octstr_destroy(os);
1217  return ret;
1218 }
1219 
1220 
1221 static int send_messages(SMPP *smpp, Connection *conn, long *pending_submits)
1222 {
1223  Msg *msg;
1224  SMPP_PDU *pdu;
1225  Octstr *os;
1226 
1227  if (*pending_submits == -1)
1228  return 0;
1229 
1230  while (*pending_submits < smpp->max_pending_submits) {
1231  /* check our throughput */
1232  if (smpp->conn->throughput > 0 && load_get(smpp->load, 0) >= smpp->conn->throughput) {
1233  debug("bb.sms.smpp", 0, "SMPP[%s]: throughput limit exceeded (%.02f,%.02f)",
1234  octstr_get_cstr(smpp->conn->id), load_get(smpp->load, 0), smpp->conn->throughput);
1235  break;
1236  }
1237  debug("bb.sms.smpp", 0, "SMPP[%s]: throughput (%.02f,%.02f)",
1238  octstr_get_cstr(smpp->conn->id), load_get(smpp->load, 0), smpp->conn->throughput);
1239 
1240  /* Get next message, quit if none to be sent */
1241  msg = gw_prioqueue_remove(smpp->msgs_to_send);
1242  if (msg == NULL)
1243  break;
1244 
1245  /* Send PDU, record it as waiting for ack from SMS center */
1246  pdu = msg_to_pdu(smpp, msg);
1247  if (pdu == NULL) {
1249  continue;
1250  }
1251  /* check for write errors */
1252  if (send_pdu(conn, smpp, pdu) == 0) {
1253  struct smpp_msg *smpp_msg = smpp_msg_create(msg);
1254  os = octstr_format("%ld", pdu->u.submit_sm.sequence_number);
1255  dict_put(smpp->sent_msgs, os, smpp_msg);
1256  smpp_pdu_destroy(pdu);
1257  octstr_destroy(os);
1258  ++(*pending_submits);
1259  load_increase(smpp->load);
1260  }
1261  else { /* write error occurs */
1262  smpp_pdu_destroy(pdu);
1264  return -1;
1265  }
1266  }
1267 
1268  return 0;
1269 }
1270 
1271 
1272 /*
1273  * Open transmission connection to SMS center. Return NULL for error,
1274  * open Connection for OK. Caller must set smpp->conn->status correctly
1275  * before calling this.
1276  */
1278 {
1279  SMPP_PDU *bind;
1280  Connection *conn;
1281 
1282 #ifdef HAVE_LIBSSL
1283  if (smpp->use_ssl)
1284  conn = conn_open_ssl(smpp->host, smpp->transmit_port, smpp->ssl_client_certkey_file, smpp->conn->our_host);
1285  else
1286 #endif
1287 
1288  if (smpp->our_port > 0)
1289  conn = conn_open_tcp_with_port(smpp->host, smpp->transmit_port, smpp->our_port, smpp->conn->our_host );
1290  else
1291  conn = conn_open_tcp(smpp->host, smpp->transmit_port, smpp->conn->our_host);
1292 
1293  if (conn == NULL) {
1294  error(0, "SMPP[%s]: Couldn't connect to server.",
1295  octstr_get_cstr(smpp->conn->id));
1296  return NULL;
1297  }
1298 
1299  bind = smpp_pdu_create(bind_transmitter,
1301  bind->u.bind_transmitter.system_id = octstr_duplicate(smpp->username);
1302  bind->u.bind_transmitter.password = octstr_duplicate(smpp->password);
1303  if (smpp->system_type == NULL)
1304  bind->u.bind_transmitter.system_type = octstr_create("VMA");
1305  else
1306  bind->u.bind_transmitter.system_type =
1308  bind->u.bind_transmitter.interface_version = smpp->version;
1309  bind->u.bind_transmitter.address_range =
1311  bind->u.bind_transmitter.addr_ton = smpp->bind_addr_ton;
1312  bind->u.bind_transmitter.addr_npi = smpp->bind_addr_npi;
1313  if (send_pdu(conn, smpp, bind) == -1) {
1314  error(0, "SMPP[%s]: Couldn't send bind_transmitter to server.",
1315  octstr_get_cstr(smpp->conn->id));
1316  conn_destroy(conn);
1317  conn = NULL;
1318  }
1319  smpp_pdu_destroy(bind);
1320 
1321  return conn;
1322 }
1323 
1324 
1325 /*
1326  * Open transceiver connection to SMS center. Return NULL for error,
1327  * open Connection for OK. Caller must set smpp->conn->status correctly
1328  * before calling this.
1329  */
1331 {
1332  SMPP_PDU *bind;
1333  Connection *conn;
1334 
1335 #ifdef HAVE_LIBSSL
1336  if (smpp->use_ssl)
1337  conn = conn_open_ssl(smpp->host, smpp->transmit_port, smpp->ssl_client_certkey_file, smpp->conn->our_host);
1338  else
1339 #endif
1340 
1341  if (smpp->our_port > 0)
1342  conn = conn_open_tcp_with_port(smpp->host, smpp->transmit_port, smpp->our_port, smpp->conn->our_host );
1343  else
1344  conn = conn_open_tcp(smpp->host, smpp->transmit_port, smpp->conn->our_host);
1345 
1346  if (conn == NULL) {
1347  error(0, "SMPP[%s]: Couldn't connect to server.",
1348  octstr_get_cstr(smpp->conn->id));
1349  return NULL;
1350  }
1351 
1352  bind = smpp_pdu_create(bind_transceiver,
1354  bind->u.bind_transceiver.system_id = octstr_duplicate(smpp->username);
1355  bind->u.bind_transceiver.password = octstr_duplicate(smpp->password);
1356  if (smpp->system_type == NULL)
1357  bind->u.bind_transceiver.system_type = octstr_create("VMA");
1358  else
1359  bind->u.bind_transceiver.system_type = octstr_duplicate(smpp->system_type);
1360  bind->u.bind_transceiver.interface_version = smpp->version;
1361  bind->u.bind_transceiver.address_range = octstr_duplicate(smpp->address_range);
1362  bind->u.bind_transceiver.addr_ton = smpp->bind_addr_ton;
1363  bind->u.bind_transceiver.addr_npi = smpp->bind_addr_npi;
1364  if (send_pdu(conn, smpp, bind) == -1) {
1365  error(0, "SMPP[%s]: Couldn't send bind_transceiver to server.",
1366  octstr_get_cstr(smpp->conn->id));
1367  conn_destroy(conn);
1368  conn = NULL;
1369  }
1370  smpp_pdu_destroy(bind);
1371 
1372  return conn;
1373 }
1374 
1375 
1376 /*
1377  * Open reception connection to SMS center. Return NULL for error,
1378  * open Connection for OK. Caller must set smpp->conn->status correctly
1379  * before calling this.
1380  */
1382 {
1383  SMPP_PDU *bind;
1384  Connection *conn;
1385 
1386 #ifdef HAVE_LIBSSL
1387  if (smpp->use_ssl)
1388  conn = conn_open_ssl(smpp->host, smpp->receive_port, smpp->ssl_client_certkey_file, smpp->conn->our_host);
1389  else
1390 #endif
1391 
1392  if (smpp->our_receiver_port > 0)
1393  conn = conn_open_tcp_with_port(smpp->host, smpp->receive_port, smpp->our_receiver_port, smpp->conn->our_host);
1394  else
1395  conn = conn_open_tcp(smpp->host, smpp->receive_port, smpp->conn->our_host);
1396 
1397  if (conn == NULL) {
1398  error(0, "SMPP[%s]: Couldn't connect to server.",
1399  octstr_get_cstr(smpp->conn->id));
1400  return NULL;
1401  }
1402 
1403  bind = smpp_pdu_create(bind_receiver,
1405  bind->u.bind_receiver.system_id = octstr_duplicate(smpp->username);
1406  bind->u.bind_receiver.password = octstr_duplicate(smpp->password);
1407  if (smpp->system_type == NULL)
1408  bind->u.bind_receiver.system_type = octstr_create("VMA");
1409  else
1410  bind->u.bind_receiver.system_type =
1412  bind->u.bind_receiver.interface_version = smpp->version;
1413  bind->u.bind_receiver.address_range =
1415  bind->u.bind_receiver.addr_ton = smpp->bind_addr_ton;
1416  bind->u.bind_receiver.addr_npi = smpp->bind_addr_npi;
1417  if (send_pdu(conn, smpp, bind) == -1) {
1418  error(0, "SMPP[%s]: Couldn't send bind_receiver to server.",
1419  octstr_get_cstr(smpp->conn->id));
1420  conn_destroy(conn);
1421  conn = NULL;
1422  }
1423  smpp_pdu_destroy(bind);
1424 
1425  return conn;
1426 }
1427 
1428 
1429 /*
1430  * See SMPP v5.0 spec [http://www.smsforum.net/smppv50.pdf.zip],
1431  * section 4.8.4.42 network_error_code for correct encoding.
1432  */
1433 static int error_from_network_error_code(Octstr *network_error_code)
1434 {
1435  unsigned char *nec;
1436  int type;
1437  int err;
1438 
1439  if (network_error_code == NULL || octstr_len(network_error_code) != 3)
1440  return 0;
1441 
1442  nec = (unsigned char*) octstr_get_cstr(network_error_code);
1443  type = nec[0];
1444  err = (nec[1] << 8) | nec[2];
1445 
1446  if ((type >= '0') && (type <= '9')) {
1447  /* this is a bogous SMSC sending back network_error_code as
1448  * 3 digit string instead as in the delivery report. */
1449  sscanf((char*) nec, "%03d", &err);
1450  return err;
1451  }
1452 
1453  return err;
1454 }
1455 
1456 
1457 static Msg *handle_dlr(SMPP *smpp, Octstr *destination_addr, Octstr *short_message, Octstr *message_payload, Octstr *receipted_message_id, long message_state, Octstr *network_error_code)
1458 {
1459  Msg *dlrmsg = NULL;
1460  Octstr *respstr = NULL, *msgid = NULL, *network_err = NULL, *dlr_err = NULL, *tmp;
1461  int dlrstat = -1;
1462  int err_int = 0;
1463 
1464  /* first check for SMPP v3.4 and above */
1465  if (smpp->version > 0x33 && receipted_message_id) {
1466  msgid = octstr_duplicate(receipted_message_id);
1467  switch(message_state) {
1468  case 0: /* SCHEDULED, defined in SMPP v5.0, sec. 4.7.15, page 127 */
1469  if (smpp->version == 0x50) /* being very pedantic here */
1470  dlrstat = DLR_BUFFERED;
1471  break;
1472  case 1: /* ENROUTE */
1473  case 6: /* ACCEPTED */
1474  dlrstat = DLR_BUFFERED;
1475  break;
1476  case 2: /* DELIVERED */
1477  dlrstat = DLR_SUCCESS;
1478  break;
1479  case 3: /* EXPIRED */
1480  dlrstat = DLR_EXPIRED;
1481  break;
1482  case 4: /* DELETED */
1483  case 5: /* UNDELIVERABLE */
1484  case 7: /* UNKNOWN */
1485  case 8: /* REJECTED */
1486  dlrstat = DLR_FAIL;
1487  break;
1488  case 9: /* SKIPPED, defined in SMPP v5.0, sec. 4.7.15, page 127 */
1489  if (smpp->version == 0x50)
1490  dlrstat = DLR_FAIL;
1491  break;
1492  case -1: /* message state is not present, partial SMPP v3.4 */
1493  debug("bb.sms.smpp", 0, "SMPP[%s]: Partial SMPP v3.4, receipted_message_id present but not message_state.",
1494  octstr_get_cstr(smpp->conn->id));
1495  dlrstat = -1;
1496  break;
1497  default:
1498  warning(0, "SMPP[%s]: Got DLR with unknown 'message_state' (%ld).",
1499  octstr_get_cstr(smpp->conn->id), message_state);
1500  dlrstat = DLR_FAIL;
1501  break;
1502  }
1503  }
1504 
1505  if (network_error_code != NULL) {
1506  err_int = error_from_network_error_code(network_error_code);
1507  network_err = octstr_duplicate(network_error_code);
1508  }
1509 
1510  /* check for SMPP v.3.4. and message_payload */
1511  if (smpp->version > 0x33 && octstr_len(short_message) == 0)
1512  respstr = message_payload;
1513  else
1514  respstr = short_message;
1515 
1516  if (msgid == NULL || network_err == NULL || dlrstat == -1) {
1517  /* parse the respstr if it exists */
1518  if (respstr) {
1519  long curr = 0, vpos = 0;
1520  Octstr *stat = NULL;
1521  char id_cstr[65], stat_cstr[16], sub_d_cstr[15], done_d_cstr[15];
1522  char err_cstr[4];
1523  int sub, dlrvrd, ret;
1524 
1525  /* get server message id */
1526  /* first try sscanf way if thus failed then old way */
1527  ret = sscanf(octstr_get_cstr(respstr),
1528  "id:%64[^ ] sub:%d dlvrd:%d submit date:%14[0-9] done "
1529  "date:%14[0-9] stat:%15[^ ] err:%3[^ ]",
1530  id_cstr, &sub, &dlrvrd, sub_d_cstr, done_d_cstr,
1531  stat_cstr, err_cstr);
1532  if (ret == 7) {
1533  /* only if not already here */
1534  if (msgid == NULL) {
1535  msgid = octstr_create(id_cstr);
1536  octstr_strip_blanks(msgid);
1537  }
1538  stat = octstr_create(stat_cstr);
1539  octstr_strip_blanks(stat);
1540  sscanf(err_cstr, "%d", &err_int);
1541  dlr_err = octstr_create(err_cstr);
1542  octstr_strip_blanks(dlr_err);
1543  } else {
1544  debug("bb.sms.smpp", 0, "SMPP[%s]: Could not parse DLR string sscanf way, "
1545  "fallback to old way. Please report!", octstr_get_cstr(smpp->conn->id));
1546 
1547  /* only if not already here */
1548  if (msgid == NULL) {
1549  if ((curr = octstr_search(respstr, octstr_imm("id:"), 0)) != -1) {
1550  if ((vpos = octstr_search_char(respstr, ' ', curr)) == -1)
1551  vpos = octstr_len(respstr);
1552  if (vpos-curr > 0)
1553  msgid = octstr_copy(respstr, curr+3, vpos-curr-3);
1554  }
1555  }
1556 
1557  /* get err & status code */
1558  if ((curr = octstr_search(respstr, octstr_imm("stat:"), 0)) != -1) {
1559  if ((vpos = octstr_search_char(respstr, ' ', curr)) == -1)
1560  vpos = octstr_len(respstr);
1561  if (vpos-curr > 0)
1562  stat = octstr_copy(respstr, curr+5, vpos-curr-5);
1563  } else {
1564  stat = NULL;
1565  }
1566  if ((curr = octstr_search(respstr, octstr_imm("err:"), 0)) != -1) {
1567  if ((vpos = octstr_search_char(respstr, ' ', curr)) == -1)
1568  vpos = octstr_len(respstr);
1569  if (vpos-curr > 0)
1570  dlr_err = octstr_copy(respstr, curr+4, vpos-curr-4);
1571  } else {
1572  dlr_err = NULL;
1573  }
1574  }
1575 
1576  /*
1577  * we get the following status:
1578  * DELIVRD, ACCEPTD, EXPIRED, DELETED, UNDELIV, UNKNOWN, REJECTD
1579  *
1580  * Note: some buggy SMSC's send us immediately delivery notifications although
1581  * we doesn't requested these.
1582  */
1583  if (dlrstat == -1) {
1584  if (stat != NULL && octstr_compare(stat, octstr_imm("DELIVRD")) == 0)
1585  dlrstat = DLR_SUCCESS;
1586  else if (stat != NULL && (octstr_compare(stat, octstr_imm("ACCEPTD")) == 0 ||
1587  octstr_compare(stat, octstr_imm("ACKED")) == 0 ||
1588  octstr_compare(stat, octstr_imm("BUFFRED")) == 0 ||
1589  octstr_compare(stat, octstr_imm("BUFFERD")) == 0 ||
1590  octstr_compare(stat, octstr_imm("ENROUTE")) == 0))
1591  dlrstat = DLR_BUFFERED;
1592  else
1593  dlrstat = DLR_FAIL;
1594  }
1595  octstr_destroy(stat);
1596  }
1597  }
1598 
1599  if (msgid != NULL && dlrstat != -1) {
1600  /*
1601  * Obey which SMPP msg_id type this SMSC is using, where we
1602  * have the following semantics for the variable smpp_msg_id:
1603  *
1604  * bit 1: type for submit_sm_resp, bit 2: type for deliver_sm
1605  *
1606  * if bit is set value is hex otherwise dec
1607  *
1608  * 0x00 deliver_sm dec, submit_sm_resp dec
1609  * 0x01 deliver_sm dec, submit_sm_resp hex
1610  * 0x02 deliver_sm hex, submit_sm_resp dec
1611  * 0x03 deliver_sm hex, submit_sm_resp hex
1612  *
1613  * Default behaviour is SMPP spec compliant, which means
1614  * msg_ids should be C strings and hence non modified.
1615  */
1616  if (smpp->smpp_msg_id_type == -1) {
1617  /* the default, C string */
1618  tmp = octstr_duplicate(msgid);
1619  } else {
1620  if ((smpp->smpp_msg_id_type & 0x02) ||
1621  (!octstr_check_range(msgid, 0, octstr_len(msgid), gw_isdigit))) {
1622  tmp = octstr_format("%llu", strtoll(octstr_get_cstr(msgid), NULL, 16));
1623  } else {
1624  tmp = octstr_format("%llu", strtoll(octstr_get_cstr(msgid), NULL, 10));
1625  }
1626  }
1627 
1628  dlrmsg = dlr_find(smpp->conn->id,
1629  tmp, /* smsc message id */
1630  destination_addr, /* destination */
1631  dlrstat, 0);
1632 
1633  octstr_destroy(msgid);
1634  } else
1635  tmp = octstr_create("");
1636 
1637  if (network_err == NULL && dlr_err != NULL) {
1638  unsigned char ctmp[3];
1639 
1640  ctmp[0] = 3; /* we assume here its a GSM error due to lack of other information */
1641  ctmp[1] = (err_int >> 8) & 0xFF;
1642  ctmp[2] = (err_int & 0xFF);
1643  network_err = octstr_create_from_data((char*)ctmp, 3);
1644  }
1645 
1646  if (dlrmsg != NULL) {
1647  /*
1648  * we found the delivery report in our storage, so recode the
1649  * message structure.
1650  * The DLR trigger URL is indicated by msg->sms.dlr_url.
1651  * Add the DLR error code to meta-data.
1652  */
1653  dlrmsg->sms.msgdata = octstr_duplicate(respstr);
1654  dlrmsg->sms.sms_type = report_mo;
1655  dlrmsg->sms.account = octstr_duplicate(smpp->username);
1656  if (network_err != NULL) {
1657  if (dlrmsg->sms.meta_data == NULL) {
1658  dlrmsg->sms.meta_data = octstr_create("");
1659  }
1660  meta_data_set_value(dlrmsg->sms.meta_data, "smpp", octstr_imm("dlr_err"), network_err, 1);
1661  }
1662  } else {
1663  error(0,"SMPP[%s]: got DLR but could not find message or was not interested "
1664  "in it id<%s> dst<%s>, type<%d>",
1665  octstr_get_cstr(smpp->conn->id), octstr_get_cstr(tmp),
1666  octstr_get_cstr(destination_addr), dlrstat);
1667  }
1668  octstr_destroy(tmp);
1669  octstr_destroy(network_err);
1670  octstr_destroy(dlr_err);
1671 
1672  return dlrmsg;
1673 }
1674 
1675 
1677 {
1678  switch (reason) {
1680  return SMPP_ESME_RX_R_APPN;
1681  case SMSCCONN_SUCCESS:
1682  return SMPP_ESME_ROK;
1683  case SMSCCONN_FAILED_QFULL:
1685  return SMPP_ESME_RX_T_APPN;
1686  }
1687  return SMPP_ESME_RX_T_APPN;
1688 }
1689 
1690 
1691 static int handle_pdu(SMPP *smpp, Connection *conn, SMPP_PDU *pdu,
1692  long *pending_submits)
1693 {
1694  SMPP_PDU *resp = NULL;
1695  Octstr *os;
1696  Msg *msg = NULL, *dlrmsg=NULL;
1697  struct smpp_msg *smpp_msg = NULL;
1698  long reason, cmd_stat;
1699  int ret = 0;
1700 
1701  /*
1702  * In order to keep the protocol implementation logically clean,
1703  * we will obey the required SMPP session state while processing
1704  * the PDUs, see Table 2-1, SMPP v3.4 spec, section 2.3, page 17.
1705  * Therefore we will interpret our abstracted smpp->conn->status
1706  * value as SMPP session state here.
1707  */
1708  switch (pdu->type) {
1709  case data_sm:
1710  /*
1711  * Session state check
1712  */
1713  if (!(smpp->conn->status == SMSCCONN_ACTIVE ||
1714  smpp->conn->status == SMSCCONN_ACTIVE_RECV)) {
1715  warning(0, "SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
1716  octstr_get_cstr(smpp->conn->id), pdu->type_name);
1717  return 0;
1718  }
1719  resp = smpp_pdu_create(data_sm_resp, pdu->u.data_sm.sequence_number);
1720  /*
1721  * If SMSCConn stopped then send temp. error code
1722  */
1723  mutex_lock(smpp->conn->flow_mutex);
1724  if (smpp->conn->is_stopped) {
1725  mutex_unlock(smpp->conn->flow_mutex);
1726  resp->u.data_sm_resp.command_status = SMPP_ESME_RX_T_APPN;
1727  break;
1728  }
1729  mutex_unlock(smpp->conn->flow_mutex);
1730  /* got a deliver ack (DLR)?
1731  * NOTE: following SMPP v3.4. spec. we are interested
1732  * only on bits 2-5 (some SMSC's send 0x44, and it's
1733  * spec. conforme)
1734  */
1735  if (pdu->u.data_sm.esm_class & (0x04|0x08|0x20)) {
1736  debug("bb.sms.smpp",0,"SMPP[%s] handle_pdu, got DLR",
1737  octstr_get_cstr(smpp->conn->id));
1738  dlrmsg = handle_dlr(smpp, pdu->u.data_sm.source_addr, NULL, pdu->u.data_sm.message_payload,
1739  pdu->u.data_sm.receipted_message_id, pdu->u.data_sm.message_state, pdu->u.data_sm.network_error_code);
1740  if (dlrmsg != NULL) {
1741  if (dlrmsg->sms.meta_data == NULL)
1742  dlrmsg->sms.meta_data = octstr_create("");
1743  meta_data_set_values(dlrmsg->sms.meta_data, pdu->u.data_sm.tlv, "smpp", 0);
1744  /* passing DLR to upper layer */
1745  reason = bb_smscconn_receive(smpp->conn, dlrmsg);
1746  } else {
1747  /* no DLR will be passed, but we write an access-log entry */
1748  msg = data_sm_to_msg(smpp, pdu, &reason);
1749  if (msg == NULL || reason != SMPP_ESME_ROK) {
1750  resp->u.data_sm_resp.command_status = reason;
1751  break;
1752  }
1753  reason = SMSCCONN_SUCCESS;
1754  bb_alog_sms(smpp->conn, msg, "FAILED Receive DLR");
1755  msg_destroy(msg);
1756  }
1757  resp->u.data_sm_resp.command_status = smscconn_failure_reason_to_smpp_status(reason);
1758  } else { /* MO message */
1759  msg = data_sm_to_msg(smpp, pdu, &reason);
1760  if (msg == NULL || reason != SMPP_ESME_ROK) {
1761  resp->u.data_sm_resp.command_status = reason;
1762  break;
1763  }
1764  /* Replace MO destination number with my-number */
1765  if (octstr_len(smpp->my_number)) {
1766  octstr_destroy(msg->sms.receiver);
1767  msg->sms.receiver = octstr_duplicate(smpp->my_number);
1768  }
1769  time(&msg->sms.time);
1770  msg->sms.smsc_id = octstr_duplicate(smpp->conn->id);
1771  reason = bb_smscconn_receive(smpp->conn, msg);
1772  resp->u.data_sm_resp.command_status = smscconn_failure_reason_to_smpp_status(reason);
1773  }
1774  break;
1775 
1776  case deliver_sm:
1777  /*
1778  * Session state check
1779  */
1780  if (!(smpp->conn->status == SMSCCONN_ACTIVE ||
1781  smpp->conn->status == SMSCCONN_ACTIVE_RECV)) {
1782  warning(0, "SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
1783  octstr_get_cstr(smpp->conn->id), pdu->type_name);
1784  return 0;
1785  }
1786 
1787  /*
1788  * If SMSCConn stopped then send temp. error code
1789  */
1790  mutex_lock(smpp->conn->flow_mutex);
1791  if (smpp->conn->is_stopped) {
1792  mutex_unlock(smpp->conn->flow_mutex);
1793  resp = smpp_pdu_create(deliver_sm_resp,
1794  pdu->u.deliver_sm.sequence_number);
1795  resp->u.deliver_sm_resp.command_status = SMPP_ESME_RX_T_APPN;
1796  break;
1797  }
1798  mutex_unlock(smpp->conn->flow_mutex);
1799 
1800  /*
1801  * Got a deliver ack (DLR)?
1802  * NOTE: following SMPP v3.4. spec. we are interested
1803  * only on bits 2-5 (some SMSC's send 0x44, and it's
1804  * spec. conforme)
1805  */
1806  if (pdu->u.deliver_sm.esm_class & (0x04|0x08|0x20)) {
1807 
1808  debug("bb.sms.smpp",0,"SMPP[%s] handle_pdu, got DLR",
1809  octstr_get_cstr(smpp->conn->id));
1810 
1811  dlrmsg = handle_dlr(smpp, pdu->u.deliver_sm.source_addr, pdu->u.deliver_sm.short_message, pdu->u.deliver_sm.message_payload,
1812  pdu->u.deliver_sm.receipted_message_id, pdu->u.deliver_sm.message_state, pdu->u.deliver_sm.network_error_code);
1813  resp = smpp_pdu_create(deliver_sm_resp, pdu->u.deliver_sm.sequence_number);
1814  if (dlrmsg != NULL) {
1815  if (dlrmsg->sms.meta_data == NULL)
1816  dlrmsg->sms.meta_data = octstr_create("");
1817  meta_data_set_values(dlrmsg->sms.meta_data, pdu->u.deliver_sm.tlv, "smpp", 0);
1818  /* passing DLR to upper layer */
1819  reason = bb_smscconn_receive(smpp->conn, dlrmsg);
1820  } else {
1821  /* no DLR will be passed, but we write an access-log entry */
1822  msg = pdu_to_msg(smpp, pdu, &reason);
1823  if (msg == NULL) {
1824  resp->u.deliver_sm_resp.command_status = reason;
1825  break;
1826  }
1827  reason = SMSCCONN_SUCCESS;
1828  bb_alog_sms(smpp->conn, msg, "FAILED Receive DLR");
1829  msg_destroy(msg);
1830  }
1831  resp->u.deliver_sm_resp.command_status = smscconn_failure_reason_to_smpp_status(reason);
1832  } else {/* MO-SMS */
1833  resp = smpp_pdu_create(deliver_sm_resp,
1834  pdu->u.deliver_sm.sequence_number);
1835  /* ensure the smsc-id is set */
1836  msg = pdu_to_msg(smpp, pdu, &reason);
1837  if (msg == NULL) {
1838  resp->u.deliver_sm_resp.command_status = reason;
1839  break;
1840  }
1841 
1842  /* Replace MO destination number with my-number */
1843  if (octstr_len(smpp->my_number)) {
1844  octstr_destroy(msg->sms.receiver);
1845  msg->sms.receiver = octstr_duplicate(smpp->my_number);
1846  }
1847 
1848  time(&msg->sms.time);
1849  msg->sms.smsc_id = octstr_duplicate(smpp->conn->id);
1850  msg->sms.account = octstr_duplicate(smpp->username);
1851  reason = bb_smscconn_receive(smpp->conn, msg);
1852  resp->u.deliver_sm_resp.command_status = smscconn_failure_reason_to_smpp_status(reason);
1853  }
1854  break;
1855 
1856  case enquire_link:
1857  /*
1858  * Session state check
1859  */
1860  if (!(smpp->conn->status == SMSCCONN_ACTIVE ||
1861  smpp->conn->status == SMSCCONN_ACTIVE_RECV)) {
1862  warning(0, "SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
1863  octstr_get_cstr(smpp->conn->id), pdu->type_name);
1864  return 0;
1865  }
1866  resp = smpp_pdu_create(enquire_link_resp,
1867  pdu->u.enquire_link.sequence_number);
1868  break;
1869 
1870  case enquire_link_resp:
1871  /*
1872  * Session state check
1873  */
1874  if (!(smpp->conn->status == SMSCCONN_ACTIVE ||
1875  smpp->conn->status == SMSCCONN_ACTIVE_RECV)) {
1876  warning(0, "SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
1877  octstr_get_cstr(smpp->conn->id), pdu->type_name);
1878  return 0;
1879  }
1880  if (pdu->u.enquire_link_resp.command_status != 0) {
1881  error(0, "SMPP[%s]: SMSC got error to enquire_link PDU, code 0x%08lx (%s).",
1882  octstr_get_cstr(smpp->conn->id),
1883  pdu->u.enquire_link_resp.command_status,
1884  smpp_error_to_string(pdu->u.enquire_link_resp.command_status));
1885  }
1886  break;
1887 
1888  case submit_sm_resp:
1889  /*
1890  * Session state check
1891  */
1892  if (!(smpp->conn->status == SMSCCONN_ACTIVE)) {
1893  warning(0, "SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
1894  octstr_get_cstr(smpp->conn->id), pdu->type_name);
1895  return 0;
1896  }
1897 
1898  os = octstr_format("%ld", pdu->u.submit_sm_resp.sequence_number);
1899  smpp_msg = dict_remove(smpp->sent_msgs, os);
1900  octstr_destroy(os);
1901  if (smpp_msg == NULL) {
1902  warning(0, "SMPP[%s]: SMSC sent submit_sm_resp PDU "
1903  "with wrong sequence number 0x%08lx",
1904  octstr_get_cstr(smpp->conn->id),
1905  pdu->u.submit_sm_resp.sequence_number);
1906  break;
1907  }
1908  msg = smpp_msg->msg;
1909  smpp_msg_destroy(smpp_msg, 0);
1910 
1911  /* pack submit_sm_resp TLVs into metadata */
1912  if (msg->sms.meta_data == NULL)
1913  msg->sms.meta_data = octstr_create("");
1914  meta_data_set_values(msg->sms.meta_data, pdu->u.submit_sm_resp.tlv, "smpp_resp", 1);
1915 
1916  if (pdu->u.submit_sm_resp.command_status != 0) {
1917  error(0, "SMPP[%s]: SMSC returned error code 0x%08lx (%s) "
1918  "in response to submit_sm PDU.",
1919  octstr_get_cstr(smpp->conn->id),
1920  pdu->u.submit_sm_resp.command_status,
1921  smpp_error_to_string(pdu->u.submit_sm_resp.command_status));
1923  pdu->u.submit_sm_resp.command_status);
1924 
1925  /*
1926  * check to see if we got a "throttling error", in which case we'll just
1927  * sleep for a while
1928  */
1929  if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RTHROTTLED)
1930  time(&(smpp->throttling_err_time));
1931  else
1932  smpp->throttling_err_time = 0;
1933 
1934  bb_smscconn_send_failed(smpp->conn, msg, reason, octstr_format("0x%08lx/%s", pdu->u.submit_sm_resp.command_status,
1935  smpp_error_to_string(pdu->u.submit_sm_resp.command_status)));
1936  --(*pending_submits);
1937  }
1938  else if (pdu->u.submit_sm_resp.message_id != NULL) {
1939  Octstr *tmp;
1940 
1941  /* check if msg_id is C string, decimal or hex for this SMSC */
1942  if (smpp->smpp_msg_id_type == -1) {
1943  /* the default, C string */
1944  tmp = octstr_duplicate(pdu->u.submit_sm_resp.message_id);
1945  } else {
1946  if ((smpp->smpp_msg_id_type & 0x01) ||
1947  (!octstr_check_range(pdu->u.submit_sm_resp.message_id, 0,
1948  octstr_len(pdu->u.submit_sm_resp.message_id), gw_isdigit))) {
1949  tmp = octstr_format("%llu", strtoll( /* hex */
1950  octstr_get_cstr(pdu->u.submit_sm_resp.message_id), NULL, 16));
1951  } else {
1952  tmp = octstr_format("%llu", strtoll( /* decimal */
1953  octstr_get_cstr(pdu->u.submit_sm_resp.message_id), NULL, 10));
1954  }
1955  }
1956 
1957  /*
1958  * SMSC ACK.. now we have the message ID.
1959  * The message ID is inserted into the msg struct in dlr_add(),
1960  * and we add it manually here if no DLR was requested, in
1961  * order to get it logged to access-log.
1962  */
1963  if (DLR_IS_ENABLED_DEVICE(msg->sms.dlr_mask)) {
1964  dlr_add(smpp->conn->id, tmp, msg, 0);
1965  octstr_destroy(tmp);
1966  } else {
1967  octstr_destroy(msg->sms.foreign_id);
1968  msg->sms.foreign_id = tmp;
1969  }
1970 
1971  bb_smscconn_sent(smpp->conn, msg, NULL);
1972  --(*pending_submits);
1973  } /* end if for SMSC ACK */
1974  else {
1975  error(0, "SMPP[%s]: SMSC returned error code 0x%08lx (%s) "
1976  "in response to submit_sm PDU, but no `message_id' value!",
1977  octstr_get_cstr(smpp->conn->id),
1978  pdu->u.submit_sm_resp.command_status,
1979  smpp_error_to_string(pdu->u.submit_sm_resp.command_status));
1980  bb_smscconn_sent(smpp->conn, msg, NULL);
1981  --(*pending_submits);
1982  }
1983  break;
1984 
1985  case bind_transmitter_resp:
1986  /*
1987  * Session state check
1988  */
1989  if (smpp->conn->status == SMSCCONN_ACTIVE ||
1990  smpp->conn->status == SMSCCONN_ACTIVE_RECV) {
1991  warning(0, "SMPP[%s]: SMSC sent %s PDU while session bound, ignored.",
1992  octstr_get_cstr(smpp->conn->id), pdu->type_name);
1993  return 0;
1994  }
1995  if (pdu->u.bind_transmitter_resp.command_status != 0 &&
1996  pdu->u.bind_transmitter_resp.command_status != SMPP_ESME_RALYBND) {
1997  error(0, "SMPP[%s]: SMSC rejected login to transmit, code 0x%08lx (%s).",
1998  octstr_get_cstr(smpp->conn->id),
1999  pdu->u.bind_transmitter_resp.command_status,
2000  smpp_error_to_string(pdu->u.bind_transmitter_resp.command_status));
2001  mutex_lock(smpp->conn->flow_mutex);
2003  mutex_unlock(smpp->conn->flow_mutex);
2004  if (pdu->u.bind_transmitter_resp.command_status == SMPP_ESME_RINVSYSID ||
2005  pdu->u.bind_transmitter_resp.command_status == SMPP_ESME_RINVPASWD ||
2006  pdu->u.bind_transmitter_resp.command_status == SMPP_ESME_RINVSYSTYP) {
2007  smpp->quitting = 1;
2008  }
2009  } else {
2010  *pending_submits = 0;
2011  mutex_lock(smpp->conn->flow_mutex);
2012  smpp->conn->status = SMSCCONN_ACTIVE;
2013  time(&smpp->conn->connect_time);
2014  mutex_unlock(smpp->conn->flow_mutex);
2015  bb_smscconn_connected(smpp->conn);
2016  }
2017  break;
2018 
2019  case bind_transceiver_resp:
2020  /*
2021  * Session state check
2022  */
2023  if (smpp->conn->status == SMSCCONN_ACTIVE ||
2024  smpp->conn->status == SMSCCONN_ACTIVE_RECV) {
2025  warning(0, "SMPP[%s]: SMSC sent %s PDU while session bound, ignored.",
2026  octstr_get_cstr(smpp->conn->id), pdu->type_name);
2027  return 0;
2028  }
2029  if (pdu->u.bind_transceiver_resp.command_status != 0 &&
2030  pdu->u.bind_transceiver_resp.command_status != SMPP_ESME_RALYBND) {
2031  error(0, "SMPP[%s]: SMSC rejected login to transmit, code 0x%08lx (%s).",
2032  octstr_get_cstr(smpp->conn->id),
2033  pdu->u.bind_transceiver_resp.command_status,
2034  smpp_error_to_string(pdu->u.bind_transceiver_resp.command_status));
2035  mutex_lock(smpp->conn->flow_mutex);
2037  mutex_unlock(smpp->conn->flow_mutex);
2038  if (pdu->u.bind_transceiver_resp.command_status == SMPP_ESME_RINVSYSID ||
2039  pdu->u.bind_transceiver_resp.command_status == SMPP_ESME_RINVPASWD ||
2040  pdu->u.bind_transceiver_resp.command_status == SMPP_ESME_RINVSYSTYP) {
2041  smpp->quitting = 1;
2042  }
2043  } else {
2044  *pending_submits = 0;
2045  mutex_lock(smpp->conn->flow_mutex);
2046  smpp->conn->status = SMSCCONN_ACTIVE;
2047  time(&smpp->conn->connect_time);
2048  mutex_unlock(smpp->conn->flow_mutex);
2049  bb_smscconn_connected(smpp->conn);
2050  }
2051  break;
2052 
2053  case bind_receiver_resp:
2054  /*
2055  * Session state check
2056  */
2057  if (smpp->conn->status == SMSCCONN_ACTIVE ||
2058  smpp->conn->status == SMSCCONN_ACTIVE_RECV) {
2059  warning(0, "SMPP[%s]: SMSC sent %s PDU while session bound, ignored.",
2060  octstr_get_cstr(smpp->conn->id), pdu->type_name);
2061  return 0;
2062  }
2063  if (pdu->u.bind_receiver_resp.command_status != 0 &&
2064  pdu->u.bind_receiver_resp.command_status != SMPP_ESME_RALYBND) {
2065  error(0, "SMPP[%s]: SMSC rejected login to receive, code 0x%08lx (%s).",
2066  octstr_get_cstr(smpp->conn->id),
2067  pdu->u.bind_receiver_resp.command_status,
2068  smpp_error_to_string(pdu->u.bind_receiver_resp.command_status));
2069  mutex_lock(smpp->conn->flow_mutex);
2071  mutex_unlock(smpp->conn->flow_mutex);
2072  if (pdu->u.bind_receiver_resp.command_status == SMPP_ESME_RINVSYSID ||
2073  pdu->u.bind_receiver_resp.command_status == SMPP_ESME_RINVPASWD ||
2074  pdu->u.bind_receiver_resp.command_status == SMPP_ESME_RINVSYSTYP) {
2075  smpp->quitting = 1;
2076  }
2077  } else {
2078  /* set only receive status if no transmit is bind */
2079  mutex_lock(smpp->conn->flow_mutex);
2080  if (smpp->conn->status != SMSCCONN_ACTIVE) {
2081  smpp->conn->status = SMSCCONN_ACTIVE_RECV;
2082  time(&smpp->conn->connect_time);
2083  }
2084  mutex_unlock(smpp->conn->flow_mutex);
2085  }
2086  break;
2087 
2088  case unbind:
2089  /*
2090  * Session state check
2091  */
2092  if (!(smpp->conn->status == SMSCCONN_ACTIVE ||
2093  smpp->conn->status == SMSCCONN_ACTIVE_RECV)) {
2094  warning(0, "SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
2095  octstr_get_cstr(smpp->conn->id), pdu->type_name);
2096  return 0;
2097  }
2098  resp = smpp_pdu_create(unbind_resp, pdu->u.unbind.sequence_number);
2099  mutex_lock(smpp->conn->flow_mutex);
2101  mutex_unlock(smpp->conn->flow_mutex);
2102  *pending_submits = -1;
2103  break;
2104 
2105  case unbind_resp:
2106  /*
2107  * Session state check
2108  */
2109  if (!(smpp->conn->status == SMSCCONN_ACTIVE ||
2110  smpp->conn->status == SMSCCONN_ACTIVE_RECV)) {
2111  warning(0, "SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
2112  octstr_get_cstr(smpp->conn->id), pdu->type_name);
2113  return 0;
2114  }
2115  mutex_lock(smpp->conn->flow_mutex);
2117  mutex_unlock(smpp->conn->flow_mutex);
2118  break;
2119 
2120  case generic_nack:
2121  /*
2122  * Session state check
2123  */
2124  if (!(smpp->conn->status == SMSCCONN_ACTIVE ||
2125  smpp->conn->status == SMSCCONN_ACTIVE_RECV)) {
2126  warning(0, "SMPP[%s]: SMSC sent %s PDU while session not bound, ignored.",
2127  octstr_get_cstr(smpp->conn->id), pdu->type_name);
2128  return 0;
2129  }
2130 
2131  cmd_stat = pdu->u.generic_nack.command_status;
2132 
2133  os = octstr_format("%ld", pdu->u.generic_nack.sequence_number);
2134  smpp_msg = dict_remove(smpp->sent_msgs, os);
2135  octstr_destroy(os);
2136 
2137  if (smpp_msg == NULL) {
2138  error(0, "SMPP[%s]: SMSC rejected last command, code 0x%08lx (%s).",
2139  octstr_get_cstr(smpp->conn->id),
2140  cmd_stat,
2141  smpp_error_to_string(cmd_stat));
2142  } else {
2143  msg = smpp_msg->msg;
2144  smpp_msg_destroy(smpp_msg, 0);
2145 
2146  error(0, "SMPP[%s]: SMSC returned error code 0x%08lx (%s) in response to submit_sm PDU.",
2147  octstr_get_cstr(smpp->conn->id),
2148  cmd_stat,
2149  smpp_error_to_string(cmd_stat));
2150 
2151  /*
2152  * check to see if we got a "throttling error", in which case we'll just
2153  * sleep for a while
2154  */
2155  if (cmd_stat == SMPP_ESME_RTHROTTLED)
2156  time(&(smpp->throttling_err_time));
2157  else
2158  smpp->throttling_err_time = 0;
2159 
2160  reason = smpp_status_to_smscconn_failure_reason(cmd_stat);
2161  bb_smscconn_send_failed(smpp->conn, msg, reason,
2162  octstr_format("0x%08lx/%s", cmd_stat, smpp_error_to_string(cmd_stat)));
2163  --(*pending_submits);
2164  }
2165  break;
2166 
2167  default:
2168  error(0, "SMPP[%s]: Unhandled %s PDU type 0x%08lx, ignored.",
2169  octstr_get_cstr(smpp->conn->id), pdu->type_name, pdu->type);
2170  /*
2171  * We received an unknown PDU type, therefore we will respond
2172  * with a generic_nack PDU, see SMPP v3.4 spec, section 3.3.
2173  */
2174  ret = send_gnack(smpp, conn, SMPP_ESME_RINVCMDID, pdu->u.generic_nack.sequence_number);
2175  break;
2176  }
2177 
2178  if (resp != NULL) {
2179  ret = send_pdu(conn, smpp, resp) != -1 ? 0 : -1;
2180  smpp_pdu_destroy(resp);
2181  }
2182 
2183  return ret;
2184 }
2185 
2186 
2187 struct io_arg {
2190 };
2191 
2192 
2194 {
2195  struct io_arg *io_arg;
2196 
2197  io_arg = gw_malloc(sizeof(*io_arg));
2198  io_arg->smpp = smpp;
2199  io_arg->transmitter = transmitter;
2200  return io_arg;
2201 }
2202 
2203 
2204 /*
2205  * sent queue cleanup.
2206  * @return 1 if io_thread should reconnect; 0 if not
2207  */
2208 static int do_queue_cleanup(SMPP *smpp, long *pending_submits)
2209 {
2210  List *keys;
2211  Octstr *key;
2212  struct smpp_msg *smpp_msg;
2213  time_t now = time(NULL);
2214 
2215  if (*pending_submits <= 0)
2216  return 0;
2217 
2218  /* check if action set to wait ack for ever */
2220  return 0;
2221 
2222  keys = dict_keys(smpp->sent_msgs);
2223  if (keys == NULL)
2224  return 0;
2225 
2226  while ((key = gwlist_extract_first(keys)) != NULL) {
2227  smpp_msg = dict_get(smpp->sent_msgs, key);
2228  if (smpp_msg != NULL && difftime(now, smpp_msg->sent_time) > smpp->wait_ack) {
2229  switch(smpp->wait_ack_action) {
2230  case SMPP_WAITACK_RECONNECT: /* reconnect */
2231  /* found at least one not acked msg */
2232  warning(0, "SMPP[%s]: Not ACKED message found, reconnecting.",
2233  octstr_get_cstr(smpp->conn->id));
2234  octstr_destroy(key);
2236  return 1; /* io_thread will reconnect */
2237  case SMPP_WAITACK_REQUEUE: /* requeue */
2238  smpp_msg = dict_remove(smpp->sent_msgs, key);
2239  if (smpp_msg != NULL) {
2240  warning(0, "SMPP[%s]: Not ACKED message found, will retransmit."
2241  " SENT<%ld>sec. ago, SEQ<%s>, DST<%s>",
2242  octstr_get_cstr(smpp->conn->id),
2243  (long)difftime(now, smpp_msg->sent_time) ,
2244  octstr_get_cstr(key),
2245  octstr_get_cstr(smpp_msg->msg->sms.receiver));
2247  smpp_msg_destroy(smpp_msg, 0);
2248  (*pending_submits)--;
2249  }
2250  break;
2251  default:
2252  error(0, "SMPP[%s] Unknown clenup action defined 0x%02x.",
2253  octstr_get_cstr(smpp->conn->id), smpp->wait_ack_action);
2254  octstr_destroy(key);
2256  return 0;
2257  }
2258  }
2259  octstr_destroy(key);
2260  }
2262 
2263  return 0;
2264 }
2265 
2266 
2267 /*
2268  * This is the main function for the background thread for doing I/O on
2269  * one SMPP connection (the one for transmitting or receiving messages).
2270  * It makes the initial connection to the SMPP server and re-connects
2271  * if there are I/O errors or other errors that require it.
2272  */
2273 static void io_thread(void *arg)
2274 {
2275  SMPP *smpp;
2276  struct io_arg *io_arg;
2277  int transmitter;
2278  Connection *conn;
2279  int ret;
2280  long pending_submits;
2281  long len;
2282  SMPP_PDU *pdu;
2283  double timeout;
2284  time_t last_cleanup, last_enquire_sent, last_response, now;
2285 
2286  io_arg = arg;
2287  smpp = io_arg->smpp;
2288  transmitter = io_arg->transmitter;
2289  gw_free(io_arg);
2290 
2291  /* Make sure we log into our own log-file if defined */
2292  log_thread_to(smpp->conn->log_idx);
2293 
2294 #define IS_ACTIVE (smpp->conn->status == SMSCCONN_ACTIVE || smpp->conn->status == SMSCCONN_ACTIVE_RECV)
2295 
2296  conn = NULL;
2297  while (!smpp->quitting) {
2298  if (transmitter == 1)
2299  conn = open_transmitter(smpp);
2300  else if (transmitter == 2)
2301  conn = open_transceiver(smpp);
2302  else
2303  conn = open_receiver(smpp);
2304 
2305  pending_submits = -1;
2306  len = 0;
2307  last_response = last_cleanup = last_enquire_sent = time(NULL);
2308  while(conn != NULL) {
2309  ret = read_pdu(smpp, conn, &len, &pdu);
2310  if (ret == -1) { /* connection broken */
2311  error(0, "SMPP[%s]: I/O error or other error. Re-connecting.",
2312  octstr_get_cstr(smpp->conn->id));
2313  break;
2314  } else if (ret == -2) {
2315  /* wrong pdu length , send gnack */
2316  len = 0;
2317  if (send_gnack(smpp, conn, SMPP_ESME_RINVCMDLEN, 0) == -1) {
2318  error(0, "SMPP[%s]: I/O error or other error. Re-connecting.",
2319  octstr_get_cstr(smpp->conn->id));
2320  break;
2321  }
2322  } else if (ret == 1) { /* data available */
2323  /* Deal with the PDU we just got */
2324  dump_pdu("Got PDU:", smpp->conn->id, pdu, smpp->log_format);
2325  ret = handle_pdu(smpp, conn, pdu, &pending_submits);
2326  smpp_pdu_destroy(pdu);
2327  if (ret == -1) {
2328  error(0, "SMPP[%s]: I/O error or other error. Re-connecting.",
2329  octstr_get_cstr(smpp->conn->id));
2330  break;
2331  }
2332 
2333  /*
2334  * check if we are still connected
2335  * Note: Function handle_pdu will set status to SMSCCONN_DISCONNECTED
2336  * when unbind was received.
2337  */
2338  if (smpp->conn->status == SMSCCONN_DISCONNECTED)
2339  break;
2340 
2341  /*
2342  * If we are not bounded then no PDU may coming from SMSC.
2343  * It's just a workaround for buggy SMSC's who send enquire_link's
2344  * although link is not bounded. Means: we doesn't notice these and if link
2345  * keep to be not bounden we are reconnect after defined timeout elapsed.
2346  */
2347  if (IS_ACTIVE) {
2348  /*
2349  * Store last response time.
2350  */
2351  time(&last_response);
2352  }
2353  } else { /* no data available */
2354  /* check last enquire_resp, if difftime > as idle_timeout
2355  * mark connection as broken.
2356  * We have some SMSC connections where connection seems to be OK, but
2357  * in reality is broken, because no responses received.
2358  */
2359  if (smpp->connection_timeout > 0 &&
2360  difftime(time(NULL), last_response) > smpp->connection_timeout) {
2361  /* connection seems to be broken */
2362  warning(0, "Got no responses within %ld sec., reconnecting...",
2363  (long) difftime(time(NULL), last_response));
2364  break;
2365  }
2366 
2367  time(&now);
2368  timeout = last_enquire_sent + smpp->enquire_link_interval - now;
2369  if (!IS_ACTIVE && timeout <= 0)
2370  timeout = smpp->enquire_link_interval;
2371  if (transmitter && gw_prioqueue_len(smpp->msgs_to_send) > 0 &&
2372  smpp->throttling_err_time > 0 && pending_submits < smpp->max_pending_submits) {
2373  time_t tr_timeout = smpp->throttling_err_time + SMPP_THROTTLING_SLEEP_TIME - now;
2374  timeout = timeout > tr_timeout ? tr_timeout : timeout;
2375  } else if (transmitter && gw_prioqueue_len(smpp->msgs_to_send) > 0 && smpp->conn->throughput > 0 &&
2376  smpp->max_pending_submits > pending_submits) {
2377  double t = 1.0 / smpp->conn->throughput;
2378  timeout = t < timeout ? t : timeout;
2379  }
2380  /* sleep a while */
2381  if (timeout > 0 && conn_wait(conn, timeout) == -1)
2382  break;
2383  }
2384 
2385  /* send enquire link, only if connection is active */
2386  if (IS_ACTIVE && send_enquire_link(smpp, conn, &last_enquire_sent) == -1)
2387  break;
2388 
2389  /* cleanup sent queue */
2390  if (transmitter && difftime(time(NULL), last_cleanup) > smpp->wait_ack) {
2391  if (do_queue_cleanup(smpp, &pending_submits))
2392  break; /* reconnect */
2393  time(&last_cleanup);
2394  }
2395 
2396  /* make sure we send */
2397  if (transmitter && difftime(time(NULL), smpp->throttling_err_time) > SMPP_THROTTLING_SLEEP_TIME) {
2398  smpp->throttling_err_time = 0;
2399  if (send_messages(smpp, conn, &pending_submits) == -1)
2400  break;
2401  }
2402 
2403  /* unbind
2404  * Read so long as unbind_resp received or timeout passed. Otherwise we have
2405  * double delivered messages.
2406  */
2407  if (smpp->quitting) {
2408  if (!IS_ACTIVE || send_unbind(smpp, conn) == -1)
2409  break;
2410  time(&last_response);
2411  while(conn_wait(conn, 1.00) != -1 && IS_ACTIVE &&
2412  difftime(time(NULL), last_response) < SMPP_DEFAULT_SHUTDOWN_TIMEOUT) {
2413  if (read_pdu(smpp, conn, &len, &pdu) == 1) {
2414  dump_pdu("Got PDU:", smpp->conn->id, pdu, smpp->log_format);
2415  handle_pdu(smpp, conn, pdu, &pending_submits);
2416  smpp_pdu_destroy(pdu);
2417  }
2418  }
2419  debug("bb.sms.smpp", 0, "SMPP[%s]: %s: break and shutting down",
2420  octstr_get_cstr(smpp->conn->id), __PRETTY_FUNCTION__);
2421 
2422  break;
2423  }
2424  }
2425 
2426  if (conn != NULL) {
2427  conn_destroy(conn);
2428  conn = NULL;
2429  }
2430  /* set reconnecting status first so that core don't put msgs into our queue */
2431  if (!smpp->quitting) {
2432  error(0, "SMPP[%s]: Couldn't connect to SMS center (retrying in %ld seconds).",
2433  octstr_get_cstr(smpp->conn->id), smpp->conn->reconnect_delay);
2434  mutex_lock(smpp->conn->flow_mutex);
2436  mutex_unlock(smpp->conn->flow_mutex);
2438  }
2439  /*
2440  * put all queued messages back into global queue,so if
2441  * we have another link running than messages will be delivered
2442  * quickly
2443  */
2444  if (transmitter) {
2445  Msg *msg;
2446  struct smpp_msg *smpp_msg;
2447  List *noresp;
2448  Octstr *key;
2449 
2451 
2452  while((msg = gw_prioqueue_remove(smpp->msgs_to_send)) != NULL)
2453  bb_smscconn_send_failed(smpp->conn, msg, reason, NULL);
2454 
2455  noresp = dict_keys(smpp->sent_msgs);
2456  while((key = gwlist_extract_first(noresp)) != NULL) {
2457  smpp_msg = dict_remove(smpp->sent_msgs, key);
2458  if (smpp_msg != NULL) {
2459  bb_smscconn_send_failed(smpp->conn, smpp_msg->msg, reason, NULL);
2460  smpp_msg_destroy(smpp_msg, 0);
2461  }
2462  octstr_destroy(key);
2463  }
2464  gwlist_destroy(noresp, NULL);
2465  }
2466  }
2467 
2468 #undef IS_ACTIVE
2469 
2470  /*
2471  * Shutdown sequence as follow:
2472  * 1) if this is TX session so join receiver and free SMPP
2473  * 2) if RX session available but no TX session so nothing to join then free SMPP
2474  */
2475  if (transmitter && smpp->receiver != -1) {
2476  gwthread_wakeup(smpp->receiver);
2477  gwthread_join(smpp->receiver);
2478  }
2479  if (transmitter || smpp->transmitter == -1) {
2480  debug("bb.smpp", 0, "SMSCConn %s shut down.",
2481  octstr_get_cstr(smpp->conn->name));
2482 
2483  mutex_lock(smpp->conn->flow_mutex);
2484  smpp->conn->status = SMSCCONN_DEAD;
2485  smpp->conn->data = NULL;
2486  mutex_unlock(smpp->conn->flow_mutex);
2487 
2488  smpp_destroy(smpp);
2490  }
2491 }
2492 
2493 
2494 /***********************************************************************
2495  * Functions called by smscconn.c via the SMSCConn function pointers.
2496  */
2497 
2498 
2499 static long queued_cb(SMSCConn *conn)
2500 {
2501  SMPP *smpp;
2502 
2503  smpp = conn->data;
2504  conn->load = (smpp ? (conn->status != SMSCCONN_DEAD ?
2505  gw_prioqueue_len(smpp->msgs_to_send) : 0) : 0);
2506  return conn->load;
2507 }
2508 
2509 
2510 static int send_msg_cb(SMSCConn *conn, Msg *msg)
2511 {
2512  SMPP *smpp;
2513 
2514  smpp = conn->data;
2517  return 0;
2518 }
2519 
2520 
2521 static int shutdown_cb(SMSCConn *conn, int finish_sending)
2522 {
2523  SMPP *smpp;
2524 
2525  if (conn == NULL)
2526  return -1;
2527 
2528  debug("bb.smpp", 0, "Shutting down SMSCConn %s (%s)",
2529  octstr_get_cstr(conn->name),
2530  finish_sending ? "slow" : "instant");
2531 
2532  mutex_lock(conn->flow_mutex);
2533 
2535 
2536  smpp = conn->data;
2537  if (smpp == NULL) {
2538  mutex_unlock(conn->flow_mutex);
2539  return 0;
2540  }
2541 
2542  smpp->quitting = 1;
2543  if (smpp->transmitter != -1)
2545 
2546  if (smpp->receiver != -1)
2547  gwthread_wakeup(smpp->receiver);
2548 
2549  mutex_unlock(conn->flow_mutex);
2550 
2551  return 0;
2552 }
2553 
2554 
2555 /***********************************************************************
2556  * Public interface. This version is suitable for the Kannel bearerbox
2557  * SMSCConn interface.
2558  */
2559 
2560 
2562 {
2563  Octstr *host;
2564  long port;
2565  long receive_port;
2566  Octstr *username;
2567  Octstr *password;
2568  Octstr *system_id;
2569  Octstr *system_type;
2570  Octstr *address_range;
2571  long source_addr_ton;
2572  long source_addr_npi;
2573  long dest_addr_ton;
2574  long dest_addr_npi;
2575  long our_port;
2576  long our_receiver_port;
2577  Octstr *my_number;
2578  Octstr *service_type;
2579  SMPP *smpp;
2580  int ok;
2581  int transceiver_mode;
2582  Octstr *smsc_id;
2583  long enquire_link_interval;
2584  long max_pending_submits;
2585  long version;
2586  long priority;
2587  long validity;
2588  long smpp_msg_id_type;
2589  int autodetect_addr;
2590  Octstr *alt_charset;
2591  Octstr *alt_addr_charset;
2592  long connection_timeout, wait_ack, wait_ack_action;
2593  long esm_class;
2594 
2595  my_number = alt_addr_charset = alt_charset = NULL;
2596  transceiver_mode = 0;
2597  autodetect_addr = 1;
2598 
2599  host = cfg_get(grp, octstr_imm("host"));
2600  if (cfg_get_integer(&port, grp, octstr_imm("port")) == -1)
2601  port = 0;
2602  if (cfg_get_integer(&receive_port, grp, octstr_imm("receive-port")) == -1)
2603  receive_port = 0;
2604 
2605  if (cfg_get_integer(&our_port, grp, octstr_imm("our-port")) == -1)
2606  our_port = 0;
2607  if (cfg_get_integer(&our_receiver_port, grp, octstr_imm("our-receiver-port")) == -1)
2608  our_receiver_port = 0;
2609 
2610  cfg_get_bool(&transceiver_mode, grp, octstr_imm("transceiver-mode"));
2611  username = cfg_get(grp, octstr_imm("smsc-username"));
2612  password = cfg_get(grp, octstr_imm("smsc-password"));
2613  system_type = cfg_get(grp, octstr_imm("system-type"));
2614  address_range = cfg_get(grp, octstr_imm("address-range"));
2615  my_number = cfg_get(grp, octstr_imm("my-number"));
2616  service_type = cfg_get(grp, octstr_imm("service-type"));
2617 
2618  system_id = cfg_get(grp, octstr_imm("system-id"));
2619  if (system_id != NULL) {
2620  warning(0, "SMPP: obsolete system-id variable is set, "
2621  "use smsc-username instead.");
2622  if (username == NULL) {
2623  warning(0, "SMPP: smsc-username not set, using system-id instead");
2624  username = system_id;
2625  } else
2626  octstr_destroy(system_id);
2627  }
2628 
2629  /*
2630  * check if timing values have been configured, otherwise
2631  * use the predefined default values.
2632  */
2633  if (cfg_get_integer(&enquire_link_interval, grp,
2634  octstr_imm("enquire-link-interval")) == -1)
2635  enquire_link_interval = SMPP_ENQUIRE_LINK_INTERVAL;
2636  if (cfg_get_integer(&max_pending_submits, grp,
2637  octstr_imm("max-pending-submits")) == -1)
2638  max_pending_submits = SMPP_MAX_PENDING_SUBMITS;
2639 
2640  /* Check that config is OK */
2641  ok = 1;
2642  if (host == NULL) {
2643  error(0, "SMPP: Configuration file doesn't specify host");
2644  ok = 0;
2645  }
2646  if (port == 0 && receive_port == 0) {
2647  port = SMPP_DEFAULT_PORT;
2648  warning(0, "SMPP: Configuration file doesn't specify port or receive-port. "
2649  "Using 'port = %ld' as default.", port);
2650  }
2651  if (port != 0 && receive_port != 0) {
2652  error(0, "SMPP: Configuration file can only have port or receive-port. "
2653  "Usage of both in one group is deprecated!");
2654  ok = 0;
2655  }
2656  if (username == NULL) {
2657  error(0, "SMPP: Configuration file doesn't specify username.");
2658  ok = 0;
2659  }
2660  if (password == NULL) {
2661  error(0, "SMPP: Configuration file doesn't specify password.");
2662  ok = 0;
2663  }
2664  if (system_type == NULL) {
2665  error(0, "SMPP: Configuration file doesn't specify system-type.");
2666  ok = 0;
2667  }
2668  if (octstr_len(service_type) > 6) {
2669  error(0, "SMPP: Service type must be 6 characters or less.");
2670  ok = 0;
2671  }
2672  if (transceiver_mode && receive_port != 0) {
2673  warning(0, "SMPP: receive-port for transceiver mode defined, ignoring.");
2674  receive_port = 0;
2675  }
2676 
2677  if (!ok)
2678  return -1;
2679 
2680  /* if the ton and npi values are forced, set them, else set them to -1 */
2681  if (cfg_get_integer(&source_addr_ton, grp,
2682  octstr_imm("source-addr-ton")) == -1)
2683  source_addr_ton = -1;
2684  if (cfg_get_integer(&source_addr_npi, grp,
2685  octstr_imm("source-addr-npi")) == -1)
2686  source_addr_npi = -1;
2687  if (cfg_get_integer(&dest_addr_ton, grp,
2688  octstr_imm("dest-addr-ton")) == -1)
2689  dest_addr_ton = -1;
2690  if (cfg_get_integer(&dest_addr_npi, grp,
2691  octstr_imm("dest-addr-npi")) == -1)
2692  dest_addr_npi = -1;
2693 
2694  /* if source addr autodetection should be used set this to 1 */
2695  if (cfg_get_bool(&autodetect_addr, grp, octstr_imm("source-addr-autodetect")) == -1)
2696  autodetect_addr = 1; /* default is autodetect if no option defined */
2697 
2698  /* check for any specified interface version */
2699  if (cfg_get_integer(&version, grp, octstr_imm("interface-version")) == -1)
2700  version = SMPP_DEFAULT_VERSION;
2701  else
2702  /* convert decimal to BCD */
2703  version = ((version / 10) << 4) + (version % 10);
2704 
2705  /* check for any specified priority value in range [0-5] */
2706  if (cfg_get_integer(&priority, grp, octstr_imm("priority")) == -1)
2707  priority = SMPP_DEFAULT_PRIORITY;
2708  else if (priority < 0 || priority > 3)
2709  panic(0, "SMPP: Invalid value for priority directive in configuraton (allowed range 0-3).");
2710 
2711  /* check for message validity period */
2712  if (cfg_get_integer(&validity, grp, octstr_imm("validityperiod")) == -1)
2713  validity = SMS_PARAM_UNDEFINED;
2714  else if (validity < 0)
2715  panic(0, "SMPP: Invalid value for validity period (allowed value >= 0).");
2716 
2717  /* set the msg_id type variable for this SMSC */
2718  if (cfg_get_integer(&smpp_msg_id_type, grp, octstr_imm("msg-id-type")) == -1) {
2719  /*
2720  * defaults to C string "as-is" style
2721  */
2722  smpp_msg_id_type = -1;
2723  } else {
2724  if (smpp_msg_id_type < 0 || smpp_msg_id_type > 3)
2725  panic(0,"SMPP: Invalid value for msg-id-type directive in configuraton");
2726  }
2727 
2728  /* check for an alternative charset */
2729  alt_charset = cfg_get(grp, octstr_imm("alt-charset"));
2730  alt_addr_charset = cfg_get(grp, octstr_imm("alt-addr-charset"));
2731 
2732  /* check for connection timeout */
2733  if (cfg_get_integer(&connection_timeout, grp, octstr_imm("connection-timeout")) == -1)
2734  connection_timeout = SMPP_DEFAULT_CONNECTION_TIMEOUT;
2735 
2736  /* check if wait-ack timeout set */
2737  if (cfg_get_integer(&wait_ack, grp, octstr_imm("wait-ack")) == -1)
2738  wait_ack = SMPP_DEFAULT_WAITACK;
2739 
2740  if (cfg_get_integer(&wait_ack_action, grp, octstr_imm("wait-ack-expire")) == -1)
2741  wait_ack_action = SMPP_WAITACK_REQUEUE;
2742  else if (wait_ack_action > 0x03 || wait_ack_action < 0)
2743  panic(0, "SMPP: Invalid wait-ack-expire directive in configuration.");
2744 
2745  if (cfg_get_integer(&esm_class, grp, octstr_imm("esm-class")) == -1) {
2747  } else if ( esm_class != ESM_CLASS_SUBMIT_DEFAULT_SMSC_MODE &&
2749  error(0, "SMPP: Invalid esm_class mode '%ld' in configuration. Switching to \"Store and Forward\".",
2750  esm_class);
2752  }
2753 
2754  smpp = smpp_create(conn, host, port, receive_port, our_port, our_receiver_port, system_type,
2755  username, password, address_range,
2756  source_addr_ton, source_addr_npi, dest_addr_ton,
2757  dest_addr_npi, enquire_link_interval,
2758  max_pending_submits, version, priority, validity, my_number,
2759  smpp_msg_id_type, autodetect_addr, alt_charset, alt_addr_charset,
2760  service_type, connection_timeout, wait_ack, wait_ack_action, esm_class);
2761 
2762  cfg_get_integer(&smpp->bind_addr_ton, grp, octstr_imm("bind-addr-ton"));
2763  cfg_get_integer(&smpp->bind_addr_npi, grp, octstr_imm("bind-addr-npi"));
2764 
2765  cfg_get_bool(&smpp->use_ssl, grp, octstr_imm("use-ssl"));
2766  if (smpp->use_ssl)
2767 #ifndef HAVE_LIBSSL
2768  panic(0, "SMPP: Can not use 'use-ssl' without SSL support compiled in.");
2769 #else
2770  smpp->ssl_client_certkey_file = cfg_get(grp, octstr_imm("ssl-client-certkey-file"));
2771 #endif
2772 
2773  conn->data = smpp;
2774  conn->name = octstr_format("%sSMPP:%S:%d/%d:%S:%S",
2775  (smpp->use_ssl ? "S" : ""), host, port,
2776  (!receive_port && transceiver_mode ? port : receive_port),
2777  username, system_type);
2778 
2779  smsc_id = cfg_get(grp, octstr_imm("smsc-id"));
2780  if (smsc_id == NULL) {
2781  conn->id = octstr_duplicate(conn->name);
2782  }
2783 
2784  if (cfg_get_integer(&smpp->log_format, grp, octstr_imm("log-format")) == -1)
2786 
2787  octstr_destroy(host);
2788  octstr_destroy(username);
2789  octstr_destroy(password);
2790  octstr_destroy(system_type);
2791  octstr_destroy(address_range);
2792  octstr_destroy(my_number);
2793  octstr_destroy(smsc_id);
2794  octstr_destroy(alt_charset);
2795  octstr_destroy(alt_addr_charset);
2796  octstr_destroy(service_type);
2797 
2798  conn->status = SMSCCONN_CONNECTING;
2799 
2800  /*
2801  * I/O threads are only started if the corresponding ports
2802  * have been configured with positive numbers. Use 0 to
2803  * disable the creation of the corresponding thread.
2804  */
2805  if (port != 0)
2807  (transceiver_mode ? 2 : 1)));
2808  if (receive_port != 0)
2809  smpp->receiver = gwthread_create(io_thread, io_arg_create(smpp, 0));
2810 
2811  if ((port != 0 && smpp->transmitter == -1) ||
2812  (receive_port != 0 && smpp->receiver == -1)) {
2813  error(0, "SMPP[%s]: Couldn't start I/O threads.",
2814  octstr_get_cstr(smpp->conn->id));
2815  smpp->quitting = 1;
2816  if (smpp->transmitter != -1) {
2818  gwthread_join(smpp->transmitter);
2819  }
2820  if (smpp->receiver != -1) {
2821  gwthread_wakeup(smpp->receiver);
2822  gwthread_join(smpp->receiver);
2823  }
2824  smpp_destroy(conn->data);
2825  conn->data = NULL;
2826  return -1;
2827  }
2828 
2829  conn->shutdown = shutdown_cb;
2830  conn->queued = queued_cb;
2831  conn->send_msg = send_msg_cb;
2832 
2833  return 0;
2834 }
2835 
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
const char * smpp_error_to_string(enum SMPP_ERROR_MESSAGES error)
Definition: smpp_pdu.c:858
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:381
Octstr * name
Definition: smscconn_p.h:173
static Connection * open_transmitter(SMPP *smpp)
Definition: smsc_smpp.c:1277
void error(int err, const char *fmt,...)
Definition: log.c:612
void bb_alog_sms(SMSCConn *conn, Msg *msg, const char *message)
Definition: bb_alog.c:374
Dict * meta_data_get_values(const Octstr *data, const char *group)
Definition: meta_data.c:248
#define MWI_UNDEF
Definition: sms.h:99
static long our_port
Definition: radius_acct.c:87
static long queued_cb(SMSCConn *conn)
Definition: smsc_smpp.c:2499
Msg * msg_duplicate(Msg *msg)
Definition: msg.c:111
static int send_enquire_link(SMPP *smpp, Connection *conn, long *last_sent)
Definition: smsc_smpp.c:1139
void bb_smscconn_connected(SMSCConn *conn)
Definition: bb_smscconn.c:192
int octstr_str_case_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:984
void octstr_replace(Octstr *haystack, Octstr *needle, Octstr *repl)
Definition: octstr.c:2647
Connection * conn_open_tcp(Octstr *host, int port, Octstr *our_host)
Definition: conn.c:488
gw_prioqueue_t * msgs_to_send
Definition: smsc_smpp.c:146
int our_receiver_port
Definition: smsc_smpp.c:162
Octstr * service_type
Definition: smsc_smpp.c:156
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
void counter_destroy(Counter *counter)
Definition: counter.c:110
#define mutex_unlock(m)
Definition: thread.h:136
int alt_dcs
Definition: smscconn_p.h:201
void bb_smscconn_killed(void)
Definition: bb_smscconn.c:199
#define dump_pdu(msg, id, pdu, format)
Definition: smsc_smpp.c:103
static int send_pdu(Connection *conn, SMPP *smpp, SMPP_PDU *pdu)
Definition: smsc_smpp.c:1202
int octstr_check_range(Octstr *ostr, long pos, long len, octstr_func_t filter)
Definition: octstr.c:812
long bind_addr_npi
Definition: smsc_smpp.c:164
struct tm gw_gmtime(time_t t)
Definition: protected.c:137
static int send_gnack(SMPP *smpp, Connection *conn, long reason, unsigned long seq_num)
Definition: smsc_smpp.c:1162
Definition: msg.h:109
#define IS_ACTIVE
Octstr * id
Definition: smscconn_p.h:174
void gwthread_join(long thread)
void * data
Definition: smscconn_p.h:249
long max_pending_submits
Definition: smsc_smpp.c:171
long enquire_link_interval
Definition: smsc_smpp.c:170
static struct io_arg * io_arg_create(SMPP *smpp, int transmitter)
Definition: smsc_smpp.c:2193
int meta_data_set_value(Octstr *data, const char *group, const Octstr *key, const Octstr *value, int replace)
Definition: meta_data.c:324
#define GSM_ADDR_TON_NATIONAL
Definition: smasi_pdu.h:104
#define SMPP_ENQUIRE_LINK_INTERVAL
Definition: smsc_smpp.c:119
int transmit_port
Definition: smsc_smpp.c:165
const char * type_name
Definition: smpp_pdu.h:92
#define DLR_IS_ENABLED_DEVICE(dlr)
Definition: dlr.h:82
void charset_utf8_to_gsm(Octstr *ostr)
Definition: charset.c:288
int load_add_interval(Load *load, int interval)
Definition: load.c:111
#define SMPP_THROTTLING_SLEEP_TIME
Definition: smsc_smpp.c:123
#define ESM_CLASS_SUBMIT_UDH_INDICATOR
Definition: smpp_pdu.h:142
int log_idx
Definition: smscconn_p.h:197
SMSCConn * conn
Definition: smsc_smpp.c:186
int type
Definition: smsc_cimd2.c:215
#define SMPP_DEFAULT_CONNECTION_TIMEOUT
Definition: smsc_smpp.c:124
#define DLR_EXPIRED
Definition: dlr.h:77
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1068
int version
Definition: smsc_smpp.c:172
static Octstr * host
Definition: fakesmsc.c:121
static Msg * data_sm_to_msg(SMPP *smpp, SMPP_PDU *pdu, long *reason)
Definition: smsc_smpp.c:726
#define cfg_get(grp, varname)
Definition: cfg.h:86
long bind_addr_ton
Definition: smsc_smpp.c:163
unsigned long type
Definition: smpp_pdu.h:91
#define ESM_CLASS_SUBMIT_DEFAULT_SMSC_MODE
Definition: smpp_pdu.h:136
#define SMPP_WAITACK_NEVER_EXPIRE
Definition: smsc_smpp.c:135
#define DC_8BIT
Definition: sms.h:111
int validityperiod
Definition: smsc_smpp.c:174
#define DLR_IS_FAIL(dlr)
Definition: dlr.h:87
Load * load_create_real(int heuristic)
Definition: load.c:97
#define gw_prioqueue_produce(queue, item)
Definition: gw-prioqueue.h:98
long smpp_pdu_read_len(Connection *conn)
Definition: smpp_pdu.c:816
static int do_queue_cleanup(SMPP *smpp, long *pending_submits)
Definition: smsc_smpp.c:2208
Octstr * meta_data_get_value(Octstr *data, const char *group, const Octstr *key)
Definition: meta_data.c:368
#define DLR_IS_SUCCESS(dlr)
Definition: dlr.h:86
#define msg_create(type)
Definition: msg.h:136
static struct smpp_msg * smpp_msg_create(Msg *msg)
Definition: smsc_smpp.c:199
int source_addr_npi
Definition: smsc_smpp.c:158
Octstr * our_host
Definition: smscconn_p.h:192
int conn_eof(Connection *conn)
Definition: conn.c:697
time_t throttling_err_time
Definition: smsc_smpp.c:175
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1344
double load_get(Load *load, int pos)
Definition: load.c:191
#define SMPP_WAITACK_RECONNECT
Definition: smsc_smpp.c:133
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
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1010
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
#define GSM_ADDR_TON_INTERNATIONAL
Definition: smasi_pdu.h:103
Octstr * alt_addr_charset
Definition: smsc_smpp.c:179
long reconnect_delay
Definition: smscconn_p.h:199
void log_thread_to(int idx)
Definition: log.c:723
static void io_thread(void *arg)
Definition: smsc_smpp.c:2273
unsigned char * username
Definition: test_cimd2.c:99
int use_ssl
Definition: smsc_smpp.c:167
smscconn_killed_t why_killed
Definition: smscconn_p.h:153
static int read_pdu(SMPP *smpp, Connection *conn, long *len, SMPP_PDU **pdu)
Definition: smsc_smpp.c:325
static int port
Definition: fakesmsc.c:120
#define DLR_SUCCESS
Definition: dlr.h:72
static long convert_addr_from_pdu(Octstr *id, Octstr *addr, long ton, long npi, Octstr *alt_addr_charset)
Definition: smsc_smpp.c:366
time_t sent_time
Definition: smsc_smpp.c:191
static int shutdown_cb(SMSCConn *conn, int finish_sending)
Definition: smsc_smpp.c:2521
void msg_destroy_item(void *msg)
Definition: msg.c:147
unsigned char * password
Definition: test_cimd2.c:100
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
long receiver
Definition: smsc_smpp.c:145
int conn_write(Connection *conn, Octstr *data)
Definition: conn.c:1043
Definition: msg.h:79
int sms_priority_compare(const void *a, const void *b)
Definition: sms.c:395
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1301
void * dict_remove(Dict *dict, Octstr *key)
Definition: dict.c:307
Counter * counter_create(void)
Definition: counter.c:94
#define SMPP_DEFAULT_VERSION
Definition: smsc_smpp.c:121
static Msg * pdu_to_msg(SMPP *smpp, SMPP_PDU *pdu, long *reason)
Definition: smsc_smpp.c:585
void * gwlist_extract_first(List *list)
Definition: list.c:305
#define DLR_IS_BUFFERED(dlr)
Definition: dlr.h:88
Octstr * alt_charset
Definition: smsc_smpp.c:178
static int send_unbind(SMPP *smpp, Connection *conn)
Definition: smsc_smpp.c:1182
int smpp_msg_id_type
Definition: smsc_smpp.c:176
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
static void handle_mo_dcs(Msg *msg, Octstr *alt_charset, int data_coding, int esm_class)
Definition: smsc_smpp.c:504
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
static long smpp_status_to_smscconn_failure_reason(long status)
Definition: smsc_smpp.c:849
int transmitter
Definition: smsc_smpp.c:2189
static void smpp_destroy(SMPP *smpp)
Definition: smsc_smpp.c:293
#define SMPP_DEFAULT_CHARSET
Definition: smsc_smpp.c:84
long bb_smscconn_receive(SMSCConn *conn, Msg *sms)
Definition: bb_smscconn.c:478
void conn_destroy(Connection *conn)
Definition: conn.c:619
void octstr_insert_char(Octstr *ostr, long pos, const char c)
Definition: octstr.c:1479
static int send_msg_cb(SMSCConn *conn, Msg *msg)
Definition: smsc_smpp.c:2510
static SMPP * smpp_create(SMSCConn *conn, Octstr *host, int transmit_port, int receive_port, int our_port, int our_receiver_port, Octstr *system_type, Octstr *username, Octstr *password, Octstr *address_range, int source_addr_ton, int source_addr_npi, int dest_addr_ton, int dest_addr_npi, int enquire_link_interval, int max_pending_submits, int version, int priority, int validity, Octstr *my_number, int smpp_msg_id_type, int autodetect_addr, Octstr *alt_charset, Octstr *alt_addr_charset, Octstr *service_type, long connection_timeout, long wait_ack, int wait_ack_action, int esm_class)
Definition: smsc_smpp.c:227
time_t connect_time
Definition: smscconn_p.h:155
#define ESM_CLASS_SUBMIT_STORE_AND_FORWARD_MODE
Definition: smpp_pdu.h:139
static Connection * open_transceiver(SMPP *smpp)
Definition: smsc_smpp.c:1330
Definition: dict.c:116
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
static Octstr * smsc_id
Definition: mtbatch.c:98
double throughput
Definition: smscconn_p.h:203
Octstr * smpp_pdu_pack(Octstr *smsc_id, SMPP_PDU *pdu)
Definition: smpp_pdu.c:405
int dest_addr_ton
Definition: smsc_smpp.c:159
#define SMPP_DEFAULT_PORT
Definition: smsc_smpp.c:127
SMPP_PDU * smpp_pdu_unpack(Octstr *smsc_id, Octstr *data_without_len)
Definition: smpp_pdu.c:544
Mutex * flow_mutex
Definition: smscconn_p.h:157
void msg_destroy(Msg *msg)
Definition: msg.c:132
static int handle_pdu(SMPP *smpp, Connection *conn, SMPP_PDU *pdu, long *pending_submits)
Definition: smsc_smpp.c:1691
Connection * conn_open_tcp_with_port(Octstr *host, int port, int our_port, Octstr *our_host)
Definition: conn.c:540
int gw_isdigit(int c)
Definition: utils.c:988
Octstr * my_number
Definition: smsc_smpp.c:155
void warning(int err, const char *fmt,...)
Definition: log.c:624
void * gw_prioqueue_remove(gw_prioqueue_t *queue)
Definition: gw-prioqueue.c:265
#define SMPP_MAX_PENDING_SUBMITS
Definition: smsc_smpp.c:120
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
long gw_prioqueue_len(gw_prioqueue_t *queue)
Definition: gw-prioqueue.c:220
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define gwthread_create(func, arg)
Definition: gwthread.h:90
#define octstr_create(cstr)
Definition: octstr.h:125
void octstr_destroy_item(void *os)
Definition: octstr.c:334
int fields_to_dcs(Msg *msg, int mode)
Definition: sms.c:73
gw_assert(wtls_machine->packet_to_send!=NULL)
gw_prioqueue_t * gw_prioqueue_create(int(*cmp)(const void *, const void *))
Definition: gw-prioqueue.c:174
void gwthread_sleep(double seconds)
#define SMS_PARAM_UNDEFINED
Definition: sms.h:91
Load * load
Definition: smsc_smpp.c:185
long connection_timeout
Definition: smsc_smpp.c:180
volatile sig_atomic_t is_stopped
Definition: smscconn_p.h:169
int autodetect_addr
Definition: smsc_smpp.c:177
int smsc_smpp_create(SMSCConn *conn, CfgGroup *grp)
Definition: smsc_smpp.c:2561
Octstr * system_type
Definition: smsc_smpp.c:151
long wait_ack
Definition: smsc_smpp.c:181
long log_format
Definition: smsc_smpp.c:184
long date_universal_now(void)
Definition: date.c:304
Octstr * smpp_pdu_read_data(Connection *conn, long len)
Definition: smpp_pdu.c:842
#define load_increase(load)
Definition: load.h:94
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Msg * msg
Definition: smsc_smpp.c:192
Octstr * address_range
Definition: smsc_smpp.c:154
#define GSM_ADDR_NPI_UNKNOWN
Definition: smasi_pdu.h:111
void dict_destroy(Dict *dict)
Definition: dict.c:215
static int send_messages(SMPP *smpp, Connection *conn, long *pending_submits)
Definition: smsc_smpp.c:1221
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:756
void gw_prioqueue_destroy(gw_prioqueue_t *queue, void(*item_destroy)(void *))
Definition: gw-prioqueue.c:201
Dict * sent_msgs
Definition: smsc_smpp.c:147
#define MC_UNDEF
Definition: sms.h:93
Definition: octstr.c:118
void bb_smscconn_sent(SMSCConn *conn, Msg *sms, Octstr *reply)
Definition: bb_smscconn.c:279
static SMPP_PDU * msg_to_pdu(SMPP *smpp, Msg *msg)
Definition: smsc_smpp.c:865
int conn_wait(Connection *conn, double seconds)
Definition: conn.c:896
#define GSM_ADDR_NPI_E164
Definition: smasi_pdu.h:112
int(* shutdown)(SMSCConn *conn, int finish_sending)
Definition: smscconn_p.h:229
#define ESM_CLASS_SUBMIT_RPI
Definition: smpp_pdu.h:143
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:739
Definition: wtp_tid.h:82
Octstr * host
Definition: smsc_smpp.c:150
#define SMPP_DEFAULT_WAITACK
Definition: smsc_smpp.c:125
#define panic
Definition: log.h:87
int source_addr_ton
Definition: smsc_smpp.c:157
void gwthread_wakeup(long thread)
Definition: cfg.c:73
List * received_msgs
Definition: smsc_smpp.c:148
smpp_pdu_dump_format
Definition: smsc_smpp.c:86
void load_destroy(Load *load)
Definition: load.c:145
Definition: load.c:76
smscconn_status_t status
Definition: smscconn_p.h:151
static Connection * open_receiver(SMPP *smpp)
Definition: smsc_smpp.c:1381
int wait_ack_action
Definition: smsc_smpp.c:182
List * dict_keys(Dict *dict)
Definition: dict.c:347
#define gwlist_create()
Definition: list.h:136
long(* queued)(SMSCConn *conn)
Definition: smscconn_p.h:240
union SMPP_PDU::@14 u
#define METADATA_SMPP_GROUP
Definition: meta_data.h:76
int(* send_msg)(SMSCConn *conn, Msg *msg)
Definition: smscconn_p.h:235
#define SMPP_DEFAULT_PRIORITY
Definition: smsc_smpp.c:122
#define DLR_BUFFERED
Definition: dlr.h:74
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
Definition: bb_smscconn.c:328
static Msg * handle_dlr(SMPP *smpp, Octstr *destination_addr, Octstr *short_message, Octstr *message_payload, Octstr *receipted_message_id, long message_state, Octstr *network_error_code)
Definition: smsc_smpp.c:1457
int dcs_to_fields(Msg **msg, int dcs)
Definition: sms.c:139
int dest_addr_npi
Definition: smsc_smpp.c:160
Octstr * username
Definition: smsc_smpp.c:152
int conn_error(Connection *conn)
Definition: conn.c:708
#define SMPP_DEFAULT_SHUTDOWN_TIMEOUT
Definition: smsc_smpp.c:126
static int error_from_network_error_code(Octstr *network_error_code)
Definition: smsc_smpp.c:1433
#define DC_UNDEF
Definition: sms.h:109
int receive_port
Definition: smsc_smpp.c:166
#define GSM_ADDR_TON_ALPHANUMERIC
Definition: smasi_pdu.h:107
void prepend_catenation_udh(Msg *sms, int part_no, int num_messages, int msg_sequence)
Definition: sms.c:224
static long smscconn_failure_reason_to_smpp_status(long reason)
Definition: smsc_smpp.c:1676
SMPP * smpp
Definition: smsc_smpp.c:2188
#define SMPP_WAITACK_REQUEUE
Definition: smsc_smpp.c:134
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
#define mutex_lock(m)
Definition: thread.h:130
int our_port
Definition: smsc_smpp.c:161
#define octstr_create_from_data(data, len)
Definition: octstr.h:134
Definition: list.c:102
#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:347
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
#define DLR_FAIL
Definition: dlr.h:73
Counter * message_id_counter
Definition: smsc_smpp.c:149
static void smpp_msg_destroy(struct smpp_msg *msg, int destroy_msg)
Definition: smsc_smpp.c:214
long transmitter
Definition: smsc_smpp.c:144
int meta_data_set_values(Octstr *data, const Dict *dict, const char *group, int replace)
Definition: meta_data.c:273
static void handle_mt_dcs(Octstr *short_message, int data_coding)
Definition: smsc_smpp.c:437
volatile int quitting
Definition: smsc_smpp.c:169
Octstr * ssl_client_certkey_file
Definition: smsc_smpp.c:168
int priority
Definition: smsc_smpp.c:173
void gw_prioqueue_add_producer(gw_prioqueue_t *queue)
Definition: gw-prioqueue.c:331
#define DC_UCS2
Definition: sms.h:112
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
Definition: charset.c:589
#define DC_7BIT
Definition: sms.h:110
int esm_class
Definition: smsc_smpp.c:183
Octstr * password
Definition: smsc_smpp.c:153
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
int load
Definition: smscconn_p.h:152
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.