Kannel: Open Source WAP and SMS gateway  svn-r5335
bb_smscconn.c File Reference
#include "gw-config.h"
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include "gwlib/gwlib.h"
#include "msg.h"
#include "sms.h"
#include "bearerbox.h"
#include "numhash.h"
#include "smscconn.h"
#include "dlr.h"
#include "load.h"
#include "bb_smscconn_cb.h"
#include "smscconn_p.h"
#include "smsc/smpp_pdu.h"

Go to the source code of this file.

Data Structures

struct  ConcatMsg
 

Macros

#define OCTSTR(os)   octstr_imm(#os)
 

Typedefs

typedef struct ConcatMsg ConcatMsg
 

Enumerations

enum  { concat_error = -1, concat_complete = 0, concat_pending = 1, concat_none }
 

Functions

static long route_incoming_to_smsc (SMSCConn *conn, Msg *msg)
 
static void concat_handling_init (void)
 
static void concat_handling_shutdown (void)
 
static void concat_handling_cleanup (void)
 
static int concat_handling_check_and_handle (Msg **msg, Octstr *smscid)
 
static void concat_handling_clear_old_parts (int force)
 
void bb_smscconn_ready (SMSCConn *conn)
 
void bb_smscconn_connected (SMSCConn *conn)
 
void bb_smscconn_killed (void)
 
static void handle_split (SMSCConn *conn, Msg *msg, long reason, Octstr *reply)
 
void bb_smscconn_sent (SMSCConn *conn, Msg *sms, Octstr *reply)
 
void bb_smscconn_send_failed (SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
 
static long bb_smscconn_receive_internal (SMSCConn *conn, Msg *sms)
 
long bb_smscconn_receive (SMSCConn *conn, Msg *sms)
 
int bb_reload_smsc_groups ()
 
static void sms_router (void *arg)
 
static int cmp_conn_grp_checksum (void *a, void *b)
 
static int cmp_rout_grp_checksum (void *a, void *b)
 
static int cmp_conn_grp_id (void *a, void *b)
 
int smsc2_start (Cfg *cfg)
 
static long smsc2_find (Octstr *id, long start)
 
int smsc2_stop_smsc (Octstr *id)
 
int smsc2_restart_smsc (Octstr *id)
 
int smsc2_remove_smsc (Octstr *id)
 
int smsc2_add_smsc (Octstr *id)
 
int smsc2_reload_lists (void)
 
void smsc2_resume (int is_init)
 
void smsc2_suspend (void)
 
int smsc2_shutdown (void)
 
void smsc2_cleanup (void)
 
Octstrsmsc2_status (int status_type)
 
int smsc2_graceful_restart (Cfg *cfg)
 
long smsc2_rout (Msg *msg, int resend)
 
static void destroy_concatMsg (void *x)
 

Variables

volatile sig_atomic_t bb_status
 
Listincoming_sms
 
Listoutgoing_sms
 
Counterincoming_sms_counter
 
Counteroutgoing_sms_counter
 
Counterincoming_dlr_counter
 
Counteroutgoing_dlr_counter
 
Loadoutgoing_sms_load
 
Loadincoming_sms_load
 
Loadincoming_dlr_load
 
Loadoutgoing_dlr_load
 
Listflow_threads
 
Listsuspended
 
Listisolated
 
long max_outgoing_sms_qlength
 
long max_incoming_sms_qlength
 
Octstrcfg_filename
 
static volatile sig_atomic_t smsc_running
 
static Listsmsc_list
 
static RWLock smsc_list_lock
 
static Cfgcfg_reloaded
 
static Listsmsc_groups
 
static Octstrunified_prefix
 
static RWLock white_black_list_lock
 
static Octstrblack_list_sender_url
 
static Octstrwhite_list_sender_url
 
static Octstrblack_list_receiver_url
 
static Octstrwhite_list_receiver_url
 
static Numhashblack_list_sender
 
static Numhashwhite_list_sender
 
static Numhashblack_list_receiver
 
static Numhashwhite_list_receiver
 
static regex_t * white_list_sender_regex
 
static regex_t * black_list_sender_regex
 
static regex_t * white_list_receiver_regex
 
static regex_t * black_list_receiver_regex
 
static long router_thread = -1
 
static long sms_resend_frequency
 
static long sms_resend_retry
 
Countersplit_msg_counter
 
static volatile sig_atomic_t handle_concatenated_mo
 
static long concatenated_mo_timeout
 
static Dictincoming_concat_msgs
 
static Mutexconcat_lock
 

Macro Definition Documentation

◆ OCTSTR

#define OCTSTR (   os)    octstr_imm(#os)

Definition at line 732 of file bb_smscconn.c.

Referenced by cmp_rout_grp_checksum().

Typedef Documentation

◆ ConcatMsg

typedef struct ConcatMsg ConcatMsg

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
concat_error 
concat_complete 
concat_pending 
concat_none 

Definition at line 166 of file bb_smscconn.c.

Function Documentation

◆ bb_reload_smsc_groups()

int bb_reload_smsc_groups ( void  )

Definition at line 627 of file bb_smscconn.c.

References cfg_create(), cfg_destroy(), cfg_filename, cfg_get_multi_group(), cfg_read(), cfg_reloaded, debug(), gwlist_destroy(), octstr_get_cstr, octstr_imm(), smsc_groups, and warning().

Referenced by smsc2_add_smsc(), and smsc2_restart_smsc().

628 {
629  debug("bb.sms", 0, "Reloading smsc groups list from config resource");
632  if (cfg_read(cfg_reloaded) == -1) {
633  warning(0, "Error opening configuration file %s", octstr_get_cstr(cfg_filename));
634  return -1;
635  }
638 
639  return 0;
640 }
static Cfg * cfg_reloaded
Definition: bb_smscconn.c:130
static List * smsc_groups
Definition: bb_smscconn.c:131
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Cfg * cfg_create(Octstr *filename)
Definition: cfg.c:318
int cfg_read(Cfg *cfg)
Definition: cfg.c:452
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
void cfg_destroy(Cfg *cfg)
Definition: cfg.c:331
Octstr * cfg_filename
Definition: bearerbox.c:130
List * cfg_get_multi_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:645
void warning(int err, const char *fmt,...)
Definition: log.c:660
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ bb_smscconn_connected()

void bb_smscconn_connected ( SMSCConn conn)

Definition at line 192 of file bb_smscconn.c.

References gwthread_wakeup(), and router_thread.

Referenced by at2_device_thread(), cgw_open_send_connection(), cgw_sender(), fake_listener(), handle_pdu(), httpsmsc_send_cb(), io_thread(), open_send_connection(), reconnect(), and soap_listener().

193 {
194  if (router_thread >= 0)
196 }
static long router_thread
Definition: bb_smscconn.c:149
void gwthread_wakeup(long thread)

◆ bb_smscconn_killed()

void bb_smscconn_killed ( void  )

Definition at line 199 of file bb_smscconn.c.

References flow_threads, gwlist_remove_producer(), and incoming_sms.

Referenced by at2_device_thread(), cgw_sender(), cimd2_shutdown_cb(), emi2_sender(), fake_listener(), httpsmsc_receiver(), httpsmsc_sender(), io_thread(), oisd_shutdown_cb(), shutdown_cb(), soap_listener(), and wrapper_sender().

200 {
201  /* NOTE: after status has been set to SMSCCONN_DEAD, bearerbox
202  * is free to release/delete 'conn'
203  */
206 }
List * flow_threads
Definition: bearerbox.c:116
List * incoming_sms
Definition: bearerbox.c:84
void gwlist_remove_producer(List *list)
Definition: list.c:401

◆ bb_smscconn_ready()

void bb_smscconn_ready ( SMSCConn conn)

Definition at line 185 of file bb_smscconn.c.

References flow_threads, gwlist_add_producer(), and incoming_sms.

Referenced by smscconn_create().

186 {
189 }
List * flow_threads
Definition: bearerbox.c:116
List * incoming_sms
Definition: bearerbox.c:84
void gwlist_add_producer(List *list)
Definition: list.c:383

◆ bb_smscconn_receive()

long bb_smscconn_receive ( SMSCConn conn,
Msg sms 
)

Definition at line 477 of file bb_smscconn.c.

References bb_alog_sms(), bb_smscconn_receive_internal(), black_list_receiver, black_list_receiver_regex, black_list_sender, black_list_sender_regex, concat_complete, concat_error, concat_handling_check_and_handle(), concat_none, concat_pending, counter_increase(), gw_rwlock_rdlock(), gw_rwlock_unlock(), handle_concatenated_mo, smscconn::id, incoming_sms_counter, incoming_sms_load, smscconn::incoming_sms_load, info(), load_increase, mo, msg_destroy(), normalize_number(), numhash_find_number(), octstr_create, octstr_get_cstr, panic, smscconn::received, report_mo, SMSCCONN_FAILED_REJECTED, SMSCCONN_FAILED_TEMPORARILY, SMSCCONN_SUCCESS, store_save, unified_prefix, smscconn::unified_prefix, white_black_list_lock, white_list_receiver, white_list_receiver_regex, white_list_sender, and white_list_sender_regex.

Referenced by at2_wait_modem_command(), bb_smscconn_send_failed(), bb_smscconn_sent(), brunet_receive_sms(), cgw_handle_op(), clickatell_receive_sms(), generic_receive_sms(), handle_operation(), handle_pdu(), io_thread(), kannel_receive_sms(), main_connection_loop(), msg_cb(), msg_to_bb(), soap_parse_dlr(), soap_parse_mo(), wrapper_receiver(), and xidris_receive_sms().

478 {
479  char *uf;
480  int ret;
481 
482  /*
483  * first check whether msgdata data is NULL and set it to empty
484  * because seems too much kannels parts rely on msgdata not to be NULL.
485  */
486  if (sms->sms.msgdata == NULL)
487  sms->sms.msgdata = octstr_create("");
488 
489  /*
490  * First normalize in smsc level and then on global level.
491  * In outbound direction it's vise versa, hence first global then smsc.
492  */
493  uf = (conn && conn->unified_prefix) ? octstr_get_cstr(conn->unified_prefix) : NULL;
494  normalize_number(uf, &(sms->sms.sender));
495 
497  normalize_number(uf, &(sms->sms.sender));
498 
499  /*
500  * We don't perform white/black-listing for DLRs.
501  * Fix sms type if not set already.
502  */
503  if (sms->sms.sms_type != report_mo) {
504  sms->sms.sms_type = mo;
505 
507  if (white_list_sender &&
508  numhash_find_number(white_list_sender, sms->sms.sender) < 1) {
510  info(0, "Number <%s> is not in white-list-sender, message discarded",
511  octstr_get_cstr(sms->sms.sender));
512  bb_alog_sms(conn, sms, "REJECTED Receive SMS - not white-listed SMS");
513  msg_destroy(sms);
515  }
516 
518  gw_regex_match_pre(white_list_sender_regex, sms->sms.sender) == 0) {
520  info(0, "Number <%s> is not in white-list-sender, message discarded",
521  octstr_get_cstr(sms->sms.sender));
522  bb_alog_sms(conn, sms, "REJECTED Receive SMS - not white-regex-listed SMS");
523  msg_destroy(sms);
525  }
526 
527  if (black_list_sender &&
528  numhash_find_number(black_list_sender, sms->sms.sender) == 1) {
530  info(0, "Number <%s> is in black-list-sender, message discarded",
531  octstr_get_cstr(sms->sms.sender));
532  bb_alog_sms(conn, sms, "REJECTED Receive SMS - black-listed SMS");
533  msg_destroy(sms);
535  }
536 
538  gw_regex_match_pre(black_list_sender_regex, sms->sms.sender) != 0) {
540  info(0, "Number <%s> is in black-list-sender, message discarded",
541  octstr_get_cstr(sms->sms.sender));
542  bb_alog_sms(conn, sms, "REJECTED Receive SMS - black-regex-listed SMS");
543  msg_destroy(sms);
545  }
546 
547  if (white_list_receiver &&
548  numhash_find_number(white_list_receiver, sms->sms.receiver) < 1) {
550  info(0, "Number <%s> is not in white-list-receiver, message discarded",
551  octstr_get_cstr(sms->sms.receiver));
552  bb_alog_sms(conn, sms, "REJECTED Receive SMS - not white-listed SMS");
553  msg_destroy(sms);
555  }
556 
558  gw_regex_match_pre(white_list_receiver_regex, sms->sms.receiver) == 0) {
560  info(0, "Number <%s> is not in white-list-receiver, message discarded",
561  octstr_get_cstr(sms->sms.receiver));
562  bb_alog_sms(conn, sms, "REJECTED Receive SMS - not white-regex-listed SMS");
563  msg_destroy(sms);
565  }
566 
567  if (black_list_receiver &&
568  numhash_find_number(black_list_receiver, sms->sms.receiver) == 1) {
570  info(0, "Number <%s> is in black-list-receiver, message discarded",
571  octstr_get_cstr(sms->sms.receiver));
572  bb_alog_sms(conn, sms, "REJECTED Receive SMS - black-listed SMS");
573  msg_destroy(sms);
575  }
576 
578  gw_regex_match_pre(black_list_receiver_regex, sms->sms.receiver) != 0) {
580  info(0, "Number <%s> is in black-list-receiver, message discarded",
581  octstr_get_cstr(sms->sms.receiver));
582  bb_alog_sms(conn, sms, "REJECTED Receive SMS - black-regex-listed SMS");
583  msg_destroy(sms);
585  }
587  }
588 
589  /* write to store (if enabled) */
590  if (store_save(sms) == -1) {
591  msg_destroy(sms);
593  }
594 
595  /* Before routing to some box or re-routing, do concatenation handling
596  * and replace copy as such.
597  */
598  if (handle_concatenated_mo && sms->sms.sms_type == mo) {
599  ret = concat_handling_check_and_handle(&sms, (conn ? conn->id : NULL));
600  switch(ret) {
601  case concat_pending:
604  if (conn != NULL) {
605  counter_increase(conn->received);
607  }
608  return SMSCCONN_SUCCESS;
609  case concat_complete:
610  /* Combined sms received! save new one since it is now combined. */
611  break;
612  case concat_error:
613  /* failed to save, go away. */
614  msg_destroy(sms);
616  case concat_none:
617  break;
618  default:
619  panic(0, "Internal error: Unhandled concat result.");
620  break;
621  }
622  }
623 
624  return bb_smscconn_receive_internal(conn, sms);
625 }
Load * incoming_sms_load
Definition: smscconn_p.h:216
void bb_alog_sms(SMSCConn *conn, Msg *msg, const char *message)
Definition: bb_alog.c:374
void info(int err, const char *fmt,...)
Definition: log.c:672
Counter * incoming_sms_counter
Definition: bearerbox.c:90
Definition: msg.h:106
static regex_t * white_list_sender_regex
Definition: bb_smscconn.c:144
Definition: msg.h:109
Octstr * id
Definition: smscconn_p.h:174
static regex_t * black_list_receiver_regex
Definition: bb_smscconn.c:147
int gw_rwlock_rdlock(RWLock *lock)
Definition: gw-rwlock.c:134
static long bb_smscconn_receive_internal(SMSCConn *conn, Msg *sms)
Definition: bb_smscconn.c:416
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static RWLock white_black_list_lock
Definition: bb_smscconn.c:134
Load * incoming_sms_load
Definition: bearerbox.c:103
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
static Numhash * white_list_sender
Definition: bb_smscconn.c:140
int numhash_find_number(Numhash *table, Octstr *nro)
Definition: numhash.c:218
static Numhash * black_list_sender
Definition: bb_smscconn.c:139
Octstr * unified_prefix
Definition: smscconn_p.h:190
void msg_destroy(Msg *msg)
Definition: msg.c:132
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
#define octstr_create(cstr)
Definition: octstr.h:125
static regex_t * white_list_receiver_regex
Definition: bb_smscconn.c:146
Counter * received
Definition: smscconn_p.h:162
#define load_increase(load)
Definition: load.h:94
static Numhash * white_list_receiver
Definition: bb_smscconn.c:142
#define panic
Definition: log.h:87
int normalize_number(char *dial_prefixes, Octstr **number)
Definition: utils.c:882
int(* store_save)(Msg *msg)
Definition: bb_store.c:72
static Octstr * unified_prefix
Definition: bb_smscconn.c:132
static regex_t * black_list_sender_regex
Definition: bb_smscconn.c:145
static volatile sig_atomic_t handle_concatenated_mo
Definition: bb_smscconn.c:162
static Numhash * black_list_receiver
Definition: bb_smscconn.c:141
static int concat_handling_check_and_handle(Msg **msg, Octstr *smscid)
Definition: bb_smscconn.c:2181

◆ bb_smscconn_receive_internal()

static long bb_smscconn_receive_internal ( SMSCConn conn,
Msg sms 
)
static

Definition at line 416 of file bb_smscconn.c.

References ack_failed, bb_alog_sms(), counter_increase(), gwthread_sleep(), incoming_dlr_counter, incoming_dlr_load, smscconn::incoming_dlr_load, incoming_sms_counter, incoming_sms_load, smscconn::incoming_sms_load, load_increase, msg_destroy(), msg_duplicate(), smscconn::received, smscconn::received_dlr, report_mo, route_incoming_to_boxc(), route_incoming_to_smsc(), SMSCCONN_FAILED_QFULL, SMSCCONN_QUEUED, SMSCCONN_SUCCESS, store_save_ack, and warning().

Referenced by bb_smscconn_receive(), and concat_handling_clear_old_parts().

417 {
418  int rc;
419  Msg *copy;
420 
421  copy = msg_duplicate(sms);
422 
423  /*
424  * Try to reroute internally to an smsc-id without leaving
425  * actually bearerbox scope.
426  * Scope: internal routing (to smsc-ids)
427  */
428  if ((rc = route_incoming_to_smsc(conn, copy)) == -1) {
429  /*
430  * Now try to route the message to a specific smsbox
431  * connection based on the existing msg->sms.boxc_id or
432  * the registered receiver numbers for specific smsbox'es.
433  * Scope: external routing (to smsbox connections)
434  */
435  rc = route_incoming_to_boxc(copy);
436  }
437 
438  if (rc == -1 || (rc != SMSCCONN_SUCCESS && rc != SMSCCONN_QUEUED)) {
439  warning(0, "incoming messages queue too long, dropping a message");
440  if (sms->sms.sms_type == report_mo)
441  bb_alog_sms(conn, sms, "DROPPED Received DLR");
442  else
443  bb_alog_sms(conn, sms, "DROPPED Received SMS");
444 
445  /* put nack into store-file */
447 
448  msg_destroy(copy);
449  msg_destroy(sms);
450  gwthread_sleep(0.1); /* letting the queue go down */
451  return (rc == -1 ? SMSCCONN_FAILED_QFULL : rc);
452  }
453 
454  if (sms->sms.sms_type != report_mo) {
455  bb_alog_sms(conn, sms, "Receive SMS");
458  if (conn != NULL) {
459  counter_increase(conn->received);
461  }
462  } else {
463  bb_alog_sms(conn, sms, "Receive DLR");
466  if (conn != NULL) {
469  }
470  }
471 
472  msg_destroy(sms);
473 
474  return SMSCCONN_SUCCESS;
475 }
Load * incoming_sms_load
Definition: smscconn_p.h:216
void bb_alog_sms(SMSCConn *conn, Msg *msg, const char *message)
Definition: bb_alog.c:374
Msg * msg_duplicate(Msg *msg)
Definition: msg.c:111
Counter * incoming_sms_counter
Definition: bearerbox.c:90
Definition: msg.h:109
int(* store_save_ack)(Msg *msg, ack_status_t status)
Definition: bb_store.c:73
static long route_incoming_to_smsc(SMSCConn *conn, Msg *msg)
Definition: bb_smscconn.c:1930
Load * incoming_sms_load
Definition: bearerbox.c:103
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
Counter * incoming_dlr_counter
Definition: bearerbox.c:92
Load * incoming_dlr_load
Definition: bearerbox.c:104
Counter * received_dlr
Definition: smscconn_p.h:163
Definition: msg.h:79
int route_incoming_to_boxc(Msg *msg)
Definition: bb_boxc.c:1549
void msg_destroy(Msg *msg)
Definition: msg.c:132
void warning(int err, const char *fmt,...)
Definition: log.c:660
void gwthread_sleep(double seconds)
Counter * received
Definition: smscconn_p.h:162
#define load_increase(load)
Definition: load.h:94
Load * incoming_dlr_load
Definition: smscconn_p.h:217

◆ bb_smscconn_send_failed()

void bb_smscconn_send_failed ( SMSCConn conn,
Msg sms,
int  reason,
Octstr reply 
)

Definition at line 329 of file bb_smscconn.c.

References ack_failed, bb_alog_sms(), bb_smscconn_receive(), bb_smscconn_send_failed(), counter_increase(), create_dlr_from_msg(), DLR_IS_FAIL, DLR_IS_SMSC_FAIL, DLR_SMSC_FAIL, smscconn::failed, gwlist_produce(), handle_split(), smscconn::id, msg_destroy(), smscconn::name, octstr_create, octstr_destroy(), octstr_insert_data(), outgoing_sms, reply(), report_mt, sms_resend_retry, SMSCCONN_ACTIVE, SMSCCONN_FAILED_DISCARDED, SMSCCONN_FAILED_EXPIRED, SMSCCONN_FAILED_REJECTED, SMSCCONN_FAILED_SHUTDOWN, SMSCCONN_FAILED_TEMPORARILY, smscconn_status(), store_save_ack, and warning().

Referenced by at2_send_one_message(), at2_shutdown_cb(), bb_smscconn_send_failed(), brunet_parse_reply(), cgw_handle_op(), cgw_open_send_connection(), cgw_sender(), cgw_shutdown_cb(), cimd2_shutdown_cb(), cimd2_submit_msg(), clickatell_parse_reply(), do_queue_cleanup(), emi2_handle_smscreq(), emi2_sender(), fake_listener(), generic_parse_reply(), handle_pdu(), handle_split(), httpsmsc_send_cb(), httpsmsc_sender(), io_thread(), kannel_parse_reply(), main_connection_loop(), oisd_shutdown_cb(), oisd_submit_msg(), open_send_connection(), reconnect(), send_messages(), shutdown_cb(), sms_send(), smsc2_rout(), soap_listener(), soap_read_response(), soap_send_loop(), soap_shutdown_cb(), wrapper_sender(), wrapper_shutdown(), and xidris_parse_reply().

330 {
331  if (sms->sms.split_parts != NULL) {
332  handle_split(conn, sms, reason, reply);
333  return;
334  }
335 
336  switch (reason) {
338  /*
339  * Check if SMSC link alive and if so increase resend_try and set resend_time.
340  * If SMSC link is not active don't increase resend_try and don't set resend_time
341  * because we don't want to delay messages due to a broken connection.
342  */
343  if (conn && smscconn_status(conn) == SMSCCONN_ACTIVE) {
344  /*
345  * Check if sms_resend_retry set and this msg has exceeded a limit also
346  * honor "single shot" with sms_resend_retry set to zero.
347  */
348  if (sms_resend_retry >= 0 && sms->sms.resend_try >= sms_resend_retry) {
349  warning(0, "Maximum retries for message exceeded, discarding it!");
351  octstr_create("Retries Exceeded"));
352  break;
353  }
354  sms->sms.resend_try = (sms->sms.resend_try > 0 ? sms->sms.resend_try + 1 : 1);
355  time(&sms->sms.resend_time);
356  }
358  break;
359 
362  break;
363 
364  default:
365  /* write NACK to store file */
367 
368  if (conn) counter_increase(conn->failed);
369  if (reason == SMSCCONN_FAILED_DISCARDED) {
370  if (sms->sms.sms_type != report_mt)
371  bb_alog_sms(conn, sms, "DISCARDED SMS");
372  else
373  bb_alog_sms(conn, sms, "DISCARDED DLR");
374  }
375  else if (reason == SMSCCONN_FAILED_EXPIRED) {
376  if (sms->sms.sms_type != report_mt)
377  bb_alog_sms(conn, sms, "EXPIRED SMS");
378  else
379  bb_alog_sms(conn, sms, "EXPIRED DLR");
380  }
381  else if (reason == SMSCCONN_FAILED_REJECTED) {
382  if (sms->sms.sms_type != report_mt)
383  bb_alog_sms(conn, sms, "REJECTED Send SMS");
384  else
385  bb_alog_sms(conn, sms, "REJECTED Send DLR");
386  }
387  else {
388  if (sms->sms.sms_type != report_mt)
389  bb_alog_sms(conn, sms, "FAILED Send SMS");
390  else
391  bb_alog_sms(conn, sms, "FAILED Send DLR");
392  }
393 
394  /* generate relay confirmancy message */
395  if (DLR_IS_SMSC_FAIL(sms->sms.dlr_mask) || DLR_IS_FAIL(sms->sms.dlr_mask)) {
396  Msg *dlrmsg;
397 
398  if (reply == NULL)
399  reply = octstr_create("");
400 
401  octstr_insert_data(reply, 0, "NACK/", 5);
402  dlrmsg = create_dlr_from_msg((conn ? (conn->id?conn->id:conn->name) : NULL), sms,
404  if (dlrmsg != NULL) {
405  bb_smscconn_receive(conn, dlrmsg);
406  }
407  }
408 
409  msg_destroy(sms);
410  break;
411  }
412 
414 }
Octstr * name
Definition: smscconn_p.h:173
void bb_alog_sms(SMSCConn *conn, Msg *msg, const char *message)
Definition: bb_alog.c:374
void gwlist_produce(List *list, void *item)
Definition: list.c:411
Octstr * id
Definition: smscconn_p.h:174
int(* store_save_ack)(Msg *msg, ack_status_t status)
Definition: bb_store.c:73
Counter * failed
Definition: smscconn_p.h:166
Msg * create_dlr_from_msg(const Octstr *smsc, const Msg *msg, const Octstr *reply, long stat)
Definition: dlr.c:501
List * outgoing_sms
Definition: bearerbox.c:85
static long sms_resend_retry
Definition: bb_smscconn.c:153
#define DLR_IS_SMSC_FAIL(dlr)
Definition: dlr.h:90
Definition: msg.h:110
void octstr_insert_data(Octstr *ostr, long pos, const char *data, long len)
Definition: octstr.c:1461
static void handle_split(SMSCConn *conn, Msg *msg, long reason, Octstr *reply)
Definition: bb_smscconn.c:209
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
Definition: msg.h:79
int smscconn_status(SMSCConn *conn)
Definition: smscconn.c:724
long bb_smscconn_receive(SMSCConn *conn, Msg *sms)
Definition: bb_smscconn.c:477
void msg_destroy(Msg *msg)
Definition: msg.c:132
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
#define DLR_SMSC_FAIL
Definition: dlr.h:76
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
Definition: bb_smscconn.c:329
#define DLR_IS_FAIL(dlr)
Definition: dlr.h:87
static void reply(HTTPClient *c, List *push_headers)

◆ bb_smscconn_sent()

void bb_smscconn_sent ( SMSCConn conn,
Msg sms,
Octstr reply 
)

Definition at line 281 of file bb_smscconn.c.

References ack_success, bb_alog_sms(), bb_smscconn_receive(), counter_increase(), create_dlr_from_msg(), DLR_IS_SMSC_SUCCESS, DLR_SMSC_SUCCESS, handle_split(), smscconn::id, load_increase, msg_destroy(), smscconn::name, octstr_create, octstr_destroy(), octstr_insert_data(), outgoing_dlr_counter, outgoing_dlr_load, smscconn::outgoing_dlr_load, outgoing_sms_counter, outgoing_sms_load, smscconn::outgoing_sms_load, reply(), report_mt, smscconn::sent, smscconn::sent_dlr, SMSCCONN_SUCCESS, and store_save_ack.

Referenced by at2_send_one_message(), brunet_parse_reply(), cgw_handle_op(), cimd2_submit_msg(), clickatell_parse_reply(), emi2_handle_smscreq(), generic_parse_reply(), handle_pdu(), handle_split(), kannel_parse_reply(), main_connection_loop(), msg_cb(), oisd_submit_msg(), sms_send(), soap_read_response(), and xidris_parse_reply().

282 {
283  if (sms->sms.split_parts != NULL) {
284  handle_split(conn, sms, SMSCCONN_SUCCESS, reply);
285  return;
286  }
287 
288  /* write ACK to store file */
290 
291  if (sms->sms.sms_type != report_mt) {
292  bb_alog_sms(conn, sms, "Sent SMS");
295  if (conn != NULL) {
296  counter_increase(conn->sent);
298  }
299  } else {
300  bb_alog_sms(conn, sms, "Sent DLR");
303  if (conn != NULL) {
304  counter_increase(conn->sent_dlr);
306  }
307  }
308 
309  /* generate relay confirmancy message */
310  if (DLR_IS_SMSC_SUCCESS(sms->sms.dlr_mask)) {
311  Msg *dlrmsg;
312 
313  if (reply == NULL)
314  reply = octstr_create("");
315 
316  octstr_insert_data(reply, 0, "ACK/", 4);
317  dlrmsg = create_dlr_from_msg((conn->id?conn->id:conn->name), sms,
319  if (dlrmsg != NULL) {
320  bb_smscconn_receive(conn, dlrmsg);
321  }
322  }
323 
324  msg_destroy(sms);
326 }
Octstr * name
Definition: smscconn_p.h:173
void bb_alog_sms(SMSCConn *conn, Msg *msg, const char *message)
Definition: bb_alog.c:374
Load * outgoing_dlr_load
Definition: bearerbox.c:105
Counter * outgoing_sms_counter
Definition: bearerbox.c:91
Octstr * id
Definition: smscconn_p.h:174
int(* store_save_ack)(Msg *msg, ack_status_t status)
Definition: bb_store.c:73
Msg * create_dlr_from_msg(const Octstr *smsc, const Msg *msg, const Octstr *reply, long stat)
Definition: dlr.c:501
Definition: msg.h:110
void octstr_insert_data(Octstr *ostr, long pos, const char *data, long len)
Definition: octstr.c:1461
static void handle_split(SMSCConn *conn, Msg *msg, long reason, Octstr *reply)
Definition: bb_smscconn.c:209
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
Load * outgoing_sms_load
Definition: smscconn_p.h:215
Counter * outgoing_dlr_counter
Definition: bearerbox.c:93
Counter * sent
Definition: smscconn_p.h:164
Definition: msg.h:79
long bb_smscconn_receive(SMSCConn *conn, Msg *sms)
Definition: bb_smscconn.c:477
void msg_destroy(Msg *msg)
Definition: msg.c:132
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
#define DLR_IS_SMSC_SUCCESS(dlr)
Definition: dlr.h:89
Load * outgoing_sms_load
Definition: bearerbox.c:102
Counter * sent_dlr
Definition: smscconn_p.h:165
#define load_increase(load)
Definition: load.h:94
Load * outgoing_dlr_load
Definition: smscconn_p.h:218
#define DLR_SMSC_SUCCESS
Definition: dlr.h:75
static void reply(HTTPClient *c, List *push_headers)

◆ cmp_conn_grp_checksum()

static int cmp_conn_grp_checksum ( void *  a,
void *  b 
)
static

Definition at line 734 of file bb_smscconn.c.

References cfg_get_group_checksum(), smscconn::chksum, octstr_compare(), and octstr_destroy().

Referenced by smsc2_graceful_restart().

735 {
736  int ret;
737  SMSCConn *conn = a;
738  Octstr *os;
739 
741  NULL
742  );
743 
744  ret = (octstr_compare(conn->chksum, os) == 0);
745  octstr_destroy(os);
746 
747  return ret;
748 }
Octstr * cfg_get_group_checksum(CfgGroup *grp,...)
Definition: cfg.c:666
Octstr * chksum
Definition: smscconn_p.h:171
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
Definition: cfg.c:73
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ cmp_conn_grp_id()

static int cmp_conn_grp_id ( void *  a,
void *  b 
)
static

Definition at line 788 of file bb_smscconn.c.

References cfg_get, smscconn::id, octstr_compare(), octstr_destroy(), and octstr_imm().

Referenced by smsc2_graceful_restart().

789 {
790  int ret;
791  SMSCConn *conn = a;
792  Octstr *os = cfg_get((CfgGroup*)b, octstr_imm("smsc-id"));
793 
794  ret = (os && octstr_compare(conn->id, os) == 0);
795  octstr_destroy(os);
796 
797  return ret;
798 }
Octstr * id
Definition: smscconn_p.h:174
#define cfg_get(grp, varname)
Definition: cfg.h:86
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
Definition: cfg.c:73
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ cmp_rout_grp_checksum()

static int cmp_rout_grp_checksum ( void *  a,
void *  b 
)
static

Definition at line 751 of file bb_smscconn.c.

References cfg_get_group_checksum(), smscconn::chksum_conn, OCTSTR, octstr_compare(), and octstr_destroy().

Referenced by smsc2_graceful_restart().

752 {
753  int ret;
754  SMSCConn *conn = a;
755  Octstr *os;
756 
758  OCTSTR(denied-smsc-id),
759  OCTSTR(allowed-smsc-id),
760  OCTSTR(preferred-smsc-id),
761  OCTSTR(allowed-prefix),
762  OCTSTR(denied-prefix),
763  OCTSTR(preferred-prefix),
764  OCTSTR(unified-prefix),
765  OCTSTR(reroute),
766  OCTSTR(reroute-smsc-id),
767  OCTSTR(reroute-receiver),
768  OCTSTR(reroute-receiver-regex),
769  OCTSTR(reroute-dlr),
770  OCTSTR(allowed-smsc-id-regex),
771  OCTSTR(denied-smsc-id-regex),
772  OCTSTR(preferred-smsc-id-regex),
773  OCTSTR(allowed-prefix-regex),
774  OCTSTR(denied-prefix-regex),
775  OCTSTR(preferred-prefix-regex),
776  NULL
777  );
778 
779  ret = (octstr_compare(conn->chksum_conn, os) == 0);
780  octstr_destroy(os);
781 
782  return ret;
783 }
Octstr * cfg_get_group_checksum(CfgGroup *grp,...)
Definition: cfg.c:666
Octstr * chksum_conn
Definition: smscconn_p.h:172
#define OCTSTR(os)
Definition: bb_smscconn.c:732
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
Definition: cfg.c:73
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ concat_handling_check_and_handle()

static int concat_handling_check_and_handle ( Msg **  msg,
Octstr smscid 
)
static

Definition at line 2181 of file bb_smscconn.c.

References ConcatMsg::ack, ack_success, concat_complete, concat_error, concat_lock, concat_none, concat_pending, debug(), dict_get(), dict_put(), error(), handle_concatenated_mo, incoming_concat_msgs, ConcatMsg::key, msg, msg_destroy(), msg_dump(), msg_duplicate(), mutex_lock, mutex_unlock, ConcatMsg::num_parts, octstr_append(), octstr_delete(), octstr_destroy(), octstr_duplicate, octstr_format(), octstr_get_char(), octstr_get_cstr, octstr_len(), octstr_set_char(), ConcatMsg::parts, ConcatMsg::refnum, ConcatMsg::smsc_id, store_save, store_save_ack, ConcatMsg::total_parts, ConcatMsg::trecv, ConcatMsg::udh, uuid_generate(), and warning().

Referenced by bb_smscconn_receive().

2182 {
2183  Msg *msg = *pmsg;
2184  int l, iel = 0, refnum, pos, c, part, totalparts, i, sixteenbit;
2185  Octstr *udh = msg->sms.udhdata, *key;
2186  ConcatMsg *cmsg;
2187  int ret = concat_complete;
2188 
2190  return concat_none;
2191 
2192  /* ... module not initialised or there is no UDH or smscid is NULL. */
2193  if (incoming_concat_msgs == NULL || (l = octstr_len(udh)) == 0 || smscid == NULL)
2194  return concat_none;
2195 
2196  for (pos = 1, c = -1; pos < l - 1; pos += iel + 2) {
2197  iel = octstr_get_char(udh, pos + 1);
2198  if ((c = octstr_get_char(udh, pos)) == 0 || c == 8)
2199  break;
2200  }
2201  if (pos >= l) /* no concat UDH found. */
2202  return concat_none;
2203 
2204  /* c = 0 means 8 bit, c = 8 means 16 bit concat info */
2205  sixteenbit = (c == 8);
2206  refnum = (!sixteenbit) ? octstr_get_char(udh, pos + 2) :
2207  (octstr_get_char(udh, pos + 2) << 8) | octstr_get_char(udh, pos + 3);
2208  totalparts = octstr_get_char(udh, pos + 3 + sixteenbit);
2209  part = octstr_get_char(udh, pos + 4 + sixteenbit);
2210 
2211  if (part < 1 || part > totalparts) {
2212  warning(0, "Invalid concatenation UDH [ref = %d] in message from %s!",
2213  refnum, octstr_get_cstr(msg->sms.sender));
2214  return concat_none;
2215  }
2216 
2217  /* extract UDH */
2218  udh = octstr_duplicate(msg->sms.udhdata);
2219  octstr_delete(udh, pos, iel + 2);
2220  if (octstr_len(udh) <= 1) /* no other UDH elements. */
2221  octstr_delete(udh, 0, octstr_len(udh));
2222  else
2223  octstr_set_char(udh, 0, octstr_len(udh) - 1);
2224 
2225  debug("bb.sms.splits", 0, "Got part %d [ref %d, total parts %d] of message from %s. Dump follows:",
2226  part, refnum, totalparts, octstr_get_cstr(msg->sms.sender));
2227 
2228  msg_dump(msg, 0);
2229 
2230  key = octstr_format("'%S' '%S' '%S' '%d' '%d' '%H'", msg->sms.sender, msg->sms.receiver, smscid, refnum, totalparts, udh);
2232  if ((cmsg = dict_get(incoming_concat_msgs, key)) == NULL) {
2233  cmsg = gw_malloc(sizeof(*cmsg));
2234  cmsg->refnum = refnum;
2235  cmsg->total_parts = totalparts;
2236  cmsg->udh = udh;
2237  udh = NULL;
2238  cmsg->num_parts = 0;
2239  cmsg->key = octstr_duplicate(key);
2240  cmsg->ack = ack_success;
2241  cmsg->smsc_id = octstr_duplicate(smscid);
2242  cmsg->parts = gw_malloc(totalparts * sizeof(*cmsg->parts));
2243  memset(cmsg->parts, 0, cmsg->total_parts * sizeof(*cmsg->parts)); /* clear it. */
2244 
2245  dict_put(incoming_concat_msgs, key, cmsg);
2246  }
2247  octstr_destroy(key);
2248  octstr_destroy(udh);
2249 
2250  /* check if we have seen message part before... */
2251  if (cmsg->parts[part - 1] != NULL) {
2252  error(0, "Duplicate message part %d, ref %d, from %s, to %s. Discarded!",
2253  part, refnum, octstr_get_cstr(msg->sms.sender), octstr_get_cstr(msg->sms.receiver));
2255  msg_destroy(msg);
2256  *pmsg = msg = NULL;
2258  return concat_pending;
2259  } else {
2260  cmsg->parts[part -1] = msg;
2261  cmsg->num_parts++;
2262  /* always update receive time so we have it from last part and don't timeout */
2263  cmsg->trecv = time(NULL);
2264  }
2265 
2266  if (cmsg->num_parts < cmsg->total_parts) { /* wait for more parts. */
2267  *pmsg = msg = NULL;
2269  return concat_pending;
2270  }
2271 
2272  /* we have all the parts: Put them together, modify UDH, return message. */
2273  msg = msg_duplicate(cmsg->parts[0]);
2274  uuid_generate(msg->sms.id); /* give it a new ID. */
2275 
2276  debug("bb.sms.splits",0,"Received all concatenated message parts from %s, to %s, refnum %d",
2277  octstr_get_cstr(msg->sms.sender), octstr_get_cstr(msg->sms.receiver), refnum);
2278 
2279  for (i = 1; i < cmsg->total_parts; i++)
2280  octstr_append(msg->sms.msgdata, cmsg->parts[i]->sms.msgdata);
2281 
2282  /* Attempt to save the new one, if that fails, then reply with fail. */
2283  if (store_save(msg) == -1) {
2285  msg_destroy(msg);
2286  *pmsg = msg = NULL;
2287  return concat_error;
2288  } else
2289  *pmsg = msg; /* return the message part. */
2290 
2291  /* fix up UDH */
2292  octstr_destroy(msg->sms.udhdata);
2293  msg->sms.udhdata = cmsg->udh;
2294  cmsg->udh = NULL;
2295 
2296  /* Delete it from the queue and from the Dict. */
2297  /* Note: dict_put with NULL value delete and destroy value */
2298  dict_put(incoming_concat_msgs, cmsg->key, NULL);
2300 
2301  debug("bb.sms.splits", 0, "Got full message [ref %d] of message from %s to %s. Dumping: ",
2302  refnum, octstr_get_cstr(msg->sms.sender), octstr_get_cstr(msg->sms.receiver));
2303  msg_dump(msg,0);
2304 
2305  return ret;
2306 }
void msg_dump(Msg *msg, int level)
Definition: msg.c:152
void error(int err, const char *fmt,...)
Definition: log.c:648
Msg * msg_duplicate(Msg *msg)
Definition: msg.c:111
Octstr * key
Definition: bb_smscconn.c:2014
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
#define mutex_unlock(m)
Definition: thread.h:136
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
static Mutex * concat_lock
Definition: bb_smscconn.c:2022
int(* store_save_ack)(Msg *msg, ack_status_t status)
Definition: bb_store.c:73
void uuid_generate(uuid_t out)
Definition: gw_uuid.c:393
Octstr * smsc_id
Definition: bb_smscconn.c:2018
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Definition: msg.h:79
static Dict * incoming_concat_msgs
Definition: bb_smscconn.c:2021
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
time_t trecv
Definition: bb_smscconn.c:2013
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void msg_destroy(Msg *msg)
Definition: msg.c:132
void warning(int err, const char *fmt,...)
Definition: log.c:660
Octstr * udh
Definition: bb_smscconn.c:2012
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int total_parts
Definition: bb_smscconn.c:2010
int(* store_save)(Msg *msg)
Definition: bb_store.c:72
Msg ** parts
Definition: bb_smscconn.c:2017
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
#define mutex_lock(m)
Definition: thread.h:130
void octstr_set_char(Octstr *ostr, long pos, int ch)
Definition: octstr.c:415
static volatile sig_atomic_t handle_concatenated_mo
Definition: bb_smscconn.c:162
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ concat_handling_cleanup()

static void concat_handling_cleanup ( void  )
static

Definition at line 2066 of file bb_smscconn.c.

References concat_lock, debug(), dict_destroy(), incoming_concat_msgs, and mutex_destroy().

Referenced by smsc2_cleanup().

2067 {
2068  if (incoming_concat_msgs == NULL)
2069  return;
2072 
2073  incoming_concat_msgs = NULL;
2074  concat_lock = NULL;
2075  debug("bb.sms",0,"MO concatenated message handling cleaned up");
2076 }
static Mutex * concat_lock
Definition: bb_smscconn.c:2022
static Dict * incoming_concat_msgs
Definition: bb_smscconn.c:2021
void mutex_destroy(Mutex *mutex)
Definition: thread.c:97
void dict_destroy(Dict *dict)
Definition: dict.c:215
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726

◆ concat_handling_clear_old_parts()

static void concat_handling_clear_old_parts ( int  force)
static

TODO handle cases where we goes down and have to clean concat parts for rerouting

Definition at line 2078 of file bb_smscconn.c.

References bb_smscconn_receive_internal(), concat_lock, concatenated_mo_timeout, debug(), destroy_concatMsg(), dict_get(), dict_keys(), dict_put(), dict_remove(), gw_rwlock_rdlock(), gw_rwlock_unlock(), gwlist_destroy(), gwlist_extract_first(), gwlist_get(), incoming_concat_msgs, ConcatMsg::key, msg, msg_destroy(), msg_duplicate(), mutex_lock, mutex_unlock, ConcatMsg::num_parts, octstr_destroy(), octstr_destroy_item(), octstr_format_append(), octstr_get_cstr, ConcatMsg::parts, smsc2_find(), ConcatMsg::smsc_id, smsc_list, smsc_list_lock, SMSCCONN_FAILED_QFULL, SMSCCONN_FAILED_REJECTED, SMSCCONN_FAILED_TEMPORARILY, SMSCCONN_QUEUED, SMSCCONN_SUCCESS, store_save, ConcatMsg::total_parts, ConcatMsg::trecv, and warning().

Referenced by concat_handling_shutdown(), and sms_router().

2079 {
2080  List *keys;
2081  Octstr *key;
2082 
2083  /* not initialized, go away */
2084  if (incoming_concat_msgs == NULL)
2085  return;
2086 
2087  debug("bb.sms.splits", 0, "clear_old_concat_parts called");
2088 
2089  /* Remove any pending messages that are too old. */
2091  while((key = gwlist_extract_first(keys)) != NULL) {
2092  ConcatMsg *x;
2093  Msg *msg;
2094  SMSCConn *conn;
2095  int i, destroy = 1, smsc_index;
2096 
2098  x = dict_get(incoming_concat_msgs, key);
2099  octstr_destroy(key);
2100  if (x == NULL || (!force && difftime(time(NULL), x->trecv) < concatenated_mo_timeout)) {
2102  continue;
2103  }
2106 
2107  /* try to find SMSCConn */
2112  smsc_index = smsc2_find(x->smsc_id, 0);
2113  if (smsc_index != -1) {
2114  conn = gwlist_get(smsc_list, smsc_index);
2115  warning(0, "Time-out waiting for concatenated message '%s'. Send message parts as is.",
2116  octstr_get_cstr(x->key));
2117  for (i = 0; i < x->total_parts && destroy == 1; i++) {
2118  if (x->parts[i] == NULL)
2119  continue;
2120  msg = msg_duplicate(x->parts[i]);
2121  switch(bb_smscconn_receive_internal(conn, msg)) {
2123  case SMSCCONN_QUEUED:
2124  case SMSCCONN_SUCCESS:
2125  msg_destroy(x->parts[i]);
2126  x->parts[i] = NULL;
2127  x->num_parts--;
2128  break;
2130  case SMSCCONN_FAILED_QFULL:
2131  default:
2132  /* oops put it back into dict and retry on next run */
2133  store_save(x->parts[i]);
2134  destroy = 0;
2135  break;
2136  }
2137  }
2138  }
2140 
2141  if (destroy) {
2142  destroy_concatMsg(x);
2143  } else {
2144  ConcatMsg *x1;
2146  x1 = dict_get(incoming_concat_msgs, x->key);
2147  if (x1 != NULL) { /* oops we have new part */
2148  int i;
2149  if (x->total_parts != x1->total_parts) {
2150  /* broken handset, don't know what todo here??
2151  * for now just put old concatMsg into dict with
2152  * another key and it will be cleaned up on next run.
2153  */
2154  octstr_format_append(x->key, " %d", x->total_parts);
2156  } else {
2157  for (i = 0; i < x->total_parts; i++) {
2158  if (x->parts[i] == NULL)
2159  continue;
2160  if (x1->parts[i] == NULL) {
2161  x1->parts[i] = x->parts[i];
2162  x->parts[i] = NULL;
2163  }
2164  }
2165  destroy_concatMsg(x);
2166  }
2167  } else {
2169  }
2171  }
2172  }
2174 }
Msg * msg_duplicate(Msg *msg)
Definition: msg.c:111
static long concatenated_mo_timeout
Definition: bb_smscconn.c:164
Octstr * key
Definition: bb_smscconn.c:2014
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
#define mutex_unlock(m)
Definition: thread.h:136
static Mutex * concat_lock
Definition: bb_smscconn.c:2022
static RWLock smsc_list_lock
Definition: bb_smscconn.c:129
void * gwlist_get(List *list, long pos)
Definition: list.c:292
Octstr * smsc_id
Definition: bb_smscconn.c:2018
int gw_rwlock_rdlock(RWLock *lock)
Definition: gw-rwlock.c:134
static long bb_smscconn_receive_internal(SMSCConn *conn, Msg *sms)
Definition: bb_smscconn.c:416
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Definition: msg.h:79
void * dict_remove(Dict *dict, Octstr *key)
Definition: dict.c:307
void * gwlist_extract_first(List *list)
Definition: list.c:305
static Dict * incoming_concat_msgs
Definition: bb_smscconn.c:2021
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
time_t trecv
Definition: bb_smscconn.c:2013
void msg_destroy(Msg *msg)
Definition: msg.c:132
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
void octstr_destroy_item(void *os)
Definition: octstr.c:336
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2507
List * dict_keys(Dict *dict)
Definition: dict.c:347
int total_parts
Definition: bb_smscconn.c:2010
int(* store_save)(Msg *msg)
Definition: bb_store.c:72
static void destroy_concatMsg(void *x)
Definition: bb_smscconn.c:2024
Msg ** parts
Definition: bb_smscconn.c:2017
#define mutex_lock(m)
Definition: thread.h:130
Definition: list.c:102
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static List * smsc_list
Definition: bb_smscconn.c:128
static long smsc2_find(Octstr *id, long start)
Definition: bb_smscconn.c:948
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ concat_handling_init()

static void concat_handling_init ( void  )
static

Definition at line 2043 of file bb_smscconn.c.

References concat_lock, debug(), destroy_concatMsg(), dict_create(), incoming_concat_msgs, max_incoming_sms_qlength, and mutex_create.

Referenced by smsc2_start().

2044 {
2045  if (incoming_concat_msgs != NULL) /* already initialised? */
2046  return;
2050  debug("bb.sms",0,"MO concatenated message handling enabled");
2051 }
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
static Mutex * concat_lock
Definition: bb_smscconn.c:2022
#define mutex_create()
Definition: thread.h:96
static Dict * incoming_concat_msgs
Definition: bb_smscconn.c:2021
long max_incoming_sms_qlength
Definition: bearerbox.c:98
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
static void destroy_concatMsg(void *x)
Definition: bb_smscconn.c:2024

◆ concat_handling_shutdown()

static void concat_handling_shutdown ( void  )
static

Definition at line 2053 of file bb_smscconn.c.

References concat_handling_clear_old_parts(), and handle_concatenated_mo.

Referenced by smsc2_shutdown().

2054 {
2055  /* check if we were enabled at all? */
2057  return;
2058 
2059  /* deactivate */
2061 
2062  /* go through the queue and send messages as is */
2064 }
static void concat_handling_clear_old_parts(int force)
Definition: bb_smscconn.c:2078
static volatile sig_atomic_t handle_concatenated_mo
Definition: bb_smscconn.c:162

◆ destroy_concatMsg()

static void destroy_concatMsg ( void *  x)
static

Definition at line 2024 of file bb_smscconn.c.

References gw_assert(), msg, msg_destroy(), octstr_destroy(), and store_save_ack.

Referenced by concat_handling_clear_old_parts(), and concat_handling_init().

2025 {
2026  int i;
2027  ConcatMsg *msg = x;
2028 
2029  gw_assert(msg);
2030  for (i = 0; i < msg->total_parts; i++) {
2031  if (msg->parts[i]) {
2032  store_save_ack(msg->parts[i], msg->ack);
2033  msg_destroy(msg->parts[i]);
2034  }
2035  }
2036  gw_free(msg->parts);
2037  octstr_destroy(msg->key);
2038  octstr_destroy(msg->udh);
2039  octstr_destroy(msg->smsc_id);
2040  gw_free(msg);
2041 }
gw_assert(wtls_machine->packet_to_send !=NULL)
int(* store_save_ack)(Msg *msg, ack_status_t status)
Definition: bb_store.c:73
void msg_destroy(Msg *msg)
Definition: msg.c:132
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ handle_split()

static void handle_split ( SMSCConn conn,
Msg msg,
long  reason,
Octstr reply 
)
static

Definition at line 209 of file bb_smscconn.c.

References bb_smscconn_send_failed(), bb_smscconn_sent(), counter_decrease(), counter_destroy(), debug(), gwlist_produce(), msg, msg_destroy(), octstr_create, octstr_destroy(), outgoing_sms, reply(), sms_resend_retry, SMSCCONN_ACTIVE, SMSCCONN_FAILED_DISCARDED, SMSCCONN_FAILED_MALFORMED, SMSCCONN_FAILED_REJECTED, SMSCCONN_FAILED_TEMPORARILY, smscconn_status(), SMSCCONN_SUCCESS, split, and warning().

Referenced by bb_smscconn_send_failed(), and bb_smscconn_sent().

210 {
211  struct split_parts *split = msg->sms.split_parts;
212 
213  /*
214  * if the reason is not a success and status is still success
215  * then set status of a split to the reason.
216  * Note: reason 'malformed','discarded' or 'rejected' has higher priority!
217  */
218  switch(reason) {
220  /*
221  * Check if SMSC link alive and if so increase resend_try and set resend_time.
222  * If SMSC link is not active don't increase resend_try and don't set resend_time
223  * because we don't want to delay messages due to broken connection.
224  */
225  if (smscconn_status(conn) == SMSCCONN_ACTIVE) {
226  /*
227  * Check if sms_resend_retry set and this msg has exceeded a limit also
228  * honor "single shot" with sms_resend_retry set to zero.
229  */
230  if (sms_resend_retry >= 0 && msg->sms.resend_try >= sms_resend_retry) {
231  warning(0, "Maximum retries for message exceeded, discarding it!");
233  octstr_create("Retries Exceeded"));
234  return;
235  }
236  msg->sms.resend_try = (msg->sms.resend_try > 0 ? msg->sms.resend_try + 1 : 1);
237  time(&msg->sms.resend_time);
238  }
240  return;
244  debug("bb.sms.splits", 0, "Set split msg status to %ld", reason);
245  split->status = reason;
246  break;
247  case SMSCCONN_SUCCESS:
248  break; /* nothing todo */
249  default:
250  if (split->status == SMSCCONN_SUCCESS) {
251  debug("bb.sms.splits", 0, "Set split msg status to %ld", reason);
252  split->status = reason;
253  }
254  break;
255  }
256 
257  /*
258  * now destroy this message, because we don't need it anymore.
259  * we will split it again in smscconn_send(...).
260  */
261  msg_destroy(msg);
262 
263  if (counter_decrease(split->parts_left) <= 1) {
264  /* all splited parts were processed */
265  counter_destroy(split->parts_left);
266  msg = split->orig;
267  msg->sms.split_parts = NULL;
268  if (split->status == SMSCCONN_SUCCESS)
269  bb_smscconn_sent(conn, msg, reply);
270  else {
271  debug("bb.sms.splits", 0, "Parts of concatenated message failed.");
272  bb_smscconn_send_failed(conn, msg, split->status, reply);
273  }
274  gw_free(split);
275  } else {
277  }
278 }
void counter_destroy(Counter *counter)
Definition: counter.c:110
void gwlist_produce(List *list, void *item)
Definition: list.c:411
List * outgoing_sms
Definition: bearerbox.c:85
static long sms_resend_retry
Definition: bb_smscconn.c:153
unsigned long counter_decrease(Counter *counter)
Definition: counter.c:155
int smscconn_status(SMSCConn *conn)
Definition: smscconn.c:724
void msg_destroy(Msg *msg)
Definition: msg.c:132
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
void bb_smscconn_sent(SMSCConn *conn, Msg *sms, Octstr *reply)
Definition: bb_smscconn.c:281
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
static List * split
Definition: test_http.c:88
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
Definition: bb_smscconn.c:329
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static void reply(HTTPClient *c, List *push_headers)

◆ route_incoming_to_smsc()

static long route_incoming_to_smsc ( SMSCConn conn,
Msg msg 
)
static

Definition at line 1930 of file bb_smscconn.c.

References ack_success, dict_get(), gwlist_get(), gwlist_len(), pattern_route::id, msg, mt_push, octstr_destroy(), octstr_duplicate, pattern_route::re, report_mo, report_mt, smscconn::reroute, smscconn::reroute_by_receiver, smscconn::reroute_by_receiver_regex, smscconn::reroute_dlr, smscconn::reroute_to_smsc, smsc2_rout(), store_save, and store_save_ack.

Referenced by bb_smscconn_receive_internal().

1931 {
1932  Octstr *smsc;
1933 
1934  /* sanity check */
1935  if (!conn || !msg)
1936  return -1;
1937 
1938  /* check for dlr rerouting */
1939  if (!conn->reroute_dlr && (msg->sms.sms_type == report_mo || msg->sms.sms_type == report_mt))
1940  return -1;
1941 
1942  /*
1943  * Check if we have any "reroute" rules to obey. Which means msg gets
1944  * transported internally from MO to MT msg.
1945  */
1946  if (conn->reroute) {
1947  /* change message direction */
1949  msg->sms.sms_type = mt_push;
1950  store_save(msg);
1951  /* drop into outbound queue again for routing */
1952  return smsc2_rout(msg, 0);
1953  }
1954 
1955  if (conn->reroute_to_smsc) {
1956  /* change message direction */
1958  msg->sms.sms_type = mt_push;
1959  store_save(msg);
1960  /* apply directly to the given smsc-id for MT traffic */
1961  octstr_destroy(msg->sms.smsc_id);
1962  msg->sms.smsc_id = octstr_duplicate(conn->reroute_to_smsc);
1963  return smsc2_rout(msg, 0);
1964  }
1965 
1966  if (conn->reroute_by_receiver && msg->sms.receiver &&
1967  (smsc = dict_get(conn->reroute_by_receiver, msg->sms.receiver))) {
1968  /* change message direction */
1970  msg->sms.sms_type = mt_push;
1971  store_save(msg);
1972  /* route by receiver number */
1973  octstr_destroy(msg->sms.smsc_id);
1974  msg->sms.smsc_id = octstr_duplicate(smsc);
1975  return smsc2_rout(msg, 0);
1976  }
1977 
1978  if (conn->reroute_by_receiver_regex && msg->sms.receiver) {
1979  int i, l;
1980  pattern_route *r;
1981 
1983  for (i = 0; i < l; i++) {
1984  r = gwlist_get(conn->reroute_by_receiver_regex, i);
1985  /* match against regex pattern */
1986  if (r != NULL && r->re != NULL &&
1987  gw_regex_match_pre(r->re, msg->sms.receiver) == 1) {
1988  /* matched, change message direction */
1990  msg->sms.sms_type = mt_push;
1991  store_save(msg);
1992  /* route by receiver number */
1993  octstr_destroy(msg->sms.smsc_id);
1994  msg->sms.smsc_id = octstr_duplicate(r->id);
1995  return smsc2_rout(msg, 0);
1996  }
1997  }
1998  }
1999 
2000  return -1;
2001 }
regex_t * re
Definition: smscconn_p.h:255
List * reroute_by_receiver_regex
Definition: smscconn_p.h:208
Definition: msg.h:109
long gwlist_len(List *list)
Definition: list.c:166
int(* store_save_ack)(Msg *msg, ack_status_t status)
Definition: bb_store.c:73
void * gwlist_get(List *list, long pos)
Definition: list.c:292
Octstr * id
Definition: smscconn_p.h:256
Dict * reroute_by_receiver
Definition: smscconn_p.h:207
Definition: msg.h:110
Definition: msg.h:108
Octstr * reroute_to_smsc
Definition: smscconn_p.h:209
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
int reroute
Definition: smscconn_p.h:206
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
int(* store_save)(Msg *msg)
Definition: bb_store.c:72
int reroute_dlr
Definition: smscconn_p.h:210
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
long smsc2_rout(Msg *msg, int resend)
Definition: bb_smscconn.c:1716

◆ sms_router()

static void sms_router ( void *  arg)
static

Definition at line 650 of file bb_smscconn.c.

References BB_DEAD, BB_SHUTDOWN, bb_status, concat_handling_clear_old_parts(), concatenated_mo_timeout, debug(), flow_threads, gwlist_add_producer(), gwlist_len(), gwlist_produce(), gwlist_remove_producer(), gwlist_timed_consume(), gwthread_sleep(), gwthread_wakeup(), MAIN_THREAD_ID, msg, msg_destroy(), outgoing_sms, sms_resend_frequency, smsc2_rout(), SMSCCONN_FAILED_DISCARDED, SMSCCONN_FAILED_EXPIRED, SMSCCONN_FAILED_QFULL, SMSCCONN_QUEUED, and SMSCCONN_SUCCESS.

Referenced by smsc2_start().

651 {
652  Msg *msg, *startmsg, *newmsg;
653  long ret;
654  time_t concat_mo_check;
655 
658 
659  startmsg = newmsg = NULL;
660  ret = SMSCCONN_SUCCESS;
661  concat_mo_check = time(NULL);
662 
663  while(bb_status != BB_SHUTDOWN && bb_status != BB_DEAD) {
664 
665  if (newmsg == startmsg) {
666  if (ret == SMSCCONN_QUEUED || ret == SMSCCONN_FAILED_QFULL) {
667  /* sleep: sms_resend_frequency / 2 , so we reduce amount of msgs to send */
668  double sleep_time = (sms_resend_frequency / 2 > 1 ? sms_resend_frequency / 2 : sms_resend_frequency);
669  debug("bb.sms", 0, "sms_router: time to sleep %.2f secs.", sleep_time);
670  gwthread_sleep(sleep_time);
671  debug("bb.sms", 0, "sms_router: gwlist_len = %ld", gwlist_len(outgoing_sms));
672  }
674  newmsg = NULL;
675  } else {
677  }
678 
679  if (difftime(time(NULL), concat_mo_check) > concatenated_mo_timeout) {
680  concat_mo_check = time(NULL);
682  }
683 
684  /* shutdown or timeout */
685  if (msg == NULL) {
686  newmsg = startmsg = NULL;
687  continue;
688  }
689 
690  debug("bb.sms", 0, "sms_router: handling message (%p vs %p)",
691  msg, startmsg);
692 
693  /* handle delayed msgs */
694  if (msg->sms.resend_try > 0 && difftime(time(NULL), msg->sms.resend_time) < sms_resend_frequency &&
696  debug("bb.sms", 0, "re-queing SMS not-yet-to-be resent");
698  ret = SMSCCONN_QUEUED;
699  continue;
700  }
701 
702  ret = smsc2_rout(msg, 1);
703  switch(ret) {
704  case SMSCCONN_SUCCESS:
705  debug("bb.sms", 0, "Message routed successfully.");
706  newmsg = startmsg = NULL;
707  break;
708  case SMSCCONN_QUEUED:
709  debug("bb.sms", 0, "Routing failed, re-queued.");
710  break;
712  msg_destroy(msg);
713  newmsg = startmsg = NULL;
714  break;
716  debug("bb.sms", 0, "Routing failed, re-queuing.");
718  break;
720  debug("bb.sms", 0, "Routing failed, expired.");
721  msg_destroy(msg);
722  newmsg = startmsg = NULL;
723  break;
724  default:
725  break;
726  }
727  }
729 }
static long concatenated_mo_timeout
Definition: bb_smscconn.c:164
List * flow_threads
Definition: bearerbox.c:116
void gwlist_produce(List *list, void *item)
Definition: list.c:411
long gwlist_len(List *list)
Definition: list.c:166
List * outgoing_sms
Definition: bearerbox.c:85
static void concat_handling_clear_old_parts(int force)
Definition: bb_smscconn.c:2078
Definition: msg.h:79
void gwlist_remove_producer(List *list)
Definition: list.c:401
void msg_destroy(Msg *msg)
Definition: msg.c:132
void gwthread_sleep(double seconds)
static long sms_resend_frequency
Definition: bb_smscconn.c:152
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
volatile sig_atomic_t bb_status
Definition: bearerbox.c:132
void gwthread_wakeup(long thread)
#define MAIN_THREAD_ID
Definition: gwthread.h:77
void gwlist_add_producer(List *list)
Definition: list.c:383
void * gwlist_timed_consume(List *list, long sec)
Definition: list.c:453
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
long smsc2_rout(Msg *msg, int resend)
Definition: bb_smscconn.c:1716

◆ smsc2_add_smsc()

int smsc2_add_smsc ( Octstr id)

Definition at line 1112 of file bb_smscconn.c.

References bb_reload_smsc_groups(), cfg_get, smscconn::dead_start, error(), gw_rwlock_unlock(), gw_rwlock_wrlock(), gwlist_add_producer(), gwlist_append(), gwlist_get(), gwlist_len(), gwlist_remove_producer(), octstr_compare(), octstr_destroy(), octstr_get_cstr, octstr_imm(), smsc2_find(), smsc_groups, smsc_list, smsc_list_lock, smsc_running, smscconn_create(), smscconn_instances(), smscconn_shutdown(), smscconn_start(), and warning().

Referenced by bb_add_smsc().

1113 {
1114  CfgGroup *grp;
1115  SMSCConn *conn = NULL;
1116  Octstr *smscid = NULL;
1117  long i, m, j;
1118  int success = 0;
1119 
1120  if (!smsc_running)
1121  return -1;
1122 
1124  if (bb_reload_smsc_groups() != 0) {
1126  return -1;
1127  }
1128 
1129  if (smsc2_find(id, 0) != -1) {
1130  warning(0, "Could not add already existing SMSC %s", octstr_get_cstr(id));
1132  return -1;
1133  }
1134 
1136  grp = NULL;
1137  for (i = 0; i < gwlist_len(smsc_groups) &&
1138  (grp = gwlist_get(smsc_groups, i)) != NULL; i++) {
1139  smscid = cfg_get(grp, octstr_imm("smsc-admin-id"));
1140  if (smscid == NULL)
1141  smscid = cfg_get(grp, octstr_imm("smsc-id"));
1142 
1143  if (smscid != NULL && octstr_compare(smscid, id) == 0) {
1144  /* multiple instances for the same group? */
1145  m = smscconn_instances(grp);
1146  for (j = 0; j < m; j++) {
1147  conn = smscconn_create(grp, 1);
1148  if (conn != NULL) {
1149  gwlist_append(smsc_list, conn);
1150  if (conn->dead_start) {
1151  /* Shutdown connection if it's not configured to connect at start-up time */
1152  smscconn_shutdown(conn, 0);
1153  } else {
1154  smscconn_start(conn);
1155  }
1156  success = 1;
1157  } else {
1158  error(0, "Cannot start with SMSC %s connection failing", octstr_get_cstr(id));
1159  }
1160  }
1161  }
1162  octstr_destroy(smscid);
1163  smscid = NULL;
1164  }
1167  if (success == 0) {
1168  error(0, "SMSC %s not found", octstr_get_cstr(id));
1169  return -1;
1170  }
1171  return 0;
1172 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static List * smsc_groups
Definition: bb_smscconn.c:131
void gwlist_append(List *list, void *item)
Definition: list.c:179
int dead_start
Definition: smscconn_p.h:211
void smscconn_shutdown(SMSCConn *conn, int finish_sending)
Definition: smscconn.c:427
static RWLock smsc_list_lock
Definition: bb_smscconn.c:129
long gwlist_len(List *list)
Definition: list.c:166
int gw_rwlock_wrlock(RWLock *lock)
Definition: gw-rwlock.c:177
void * gwlist_get(List *list, long pos)
Definition: list.c:292
#define cfg_get(grp, varname)
Definition: cfg.h:86
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
unsigned int smscconn_instances(CfgGroup *grp)
Definition: smscconn.c:197
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
void gwlist_remove_producer(List *list)
Definition: list.c:401
int bb_reload_smsc_groups()
Definition: bb_smscconn.c:627
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
Definition: cfg.c:73
SMSCConn * smscconn_create(CfgGroup *grp, int start_as_stopped)
Definition: smscconn.c:210
void gwlist_add_producer(List *list)
Definition: list.c:383
static volatile sig_atomic_t smsc_running
Definition: bb_smscconn.c:127
void smscconn_start(SMSCConn *conn)
Definition: smscconn.c:536
static List * smsc_list
Definition: bb_smscconn.c:128
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871
static long smsc2_find(Octstr *id, long start)
Definition: bb_smscconn.c:948

◆ smsc2_cleanup()

void smsc2_cleanup ( void  )

Definition at line 1314 of file bb_smscconn.c.

References black_list_receiver, black_list_receiver_regex, black_list_receiver_url, black_list_sender, black_list_sender_regex, black_list_sender_url, concat_handling_cleanup(), counter_destroy(), debug(), gw_rwlock_destroy(), gw_rwlock_unlock(), gw_rwlock_wrlock(), gwlist_destroy(), gwlist_get(), gwlist_len(), numhash_destroy(), octstr_destroy(), smsc_groups, smsc_list, smsc_list_lock, smsc_running, smscconn_destroy(), split_msg_counter, unified_prefix, white_black_list_lock, white_list_receiver, white_list_receiver_regex, white_list_receiver_url, white_list_sender, white_list_sender_regex, and white_list_sender_url.

Referenced by main().

1315 {
1316  SMSCConn *conn;
1317  long i;
1318 
1319  if (!smsc_running)
1320  return;
1321 
1322  debug("smscconn", 0, "final clean-up for SMSCConn");
1323 
1325  for (i = 0; i < gwlist_len(smsc_list); i++) {
1326  conn = gwlist_get(smsc_list, i);
1327  smscconn_destroy(conn);
1328  }
1329  gwlist_destroy(smsc_list, NULL);
1330  smsc_list = NULL;
1332  gwlist_destroy(smsc_groups, NULL);
1338  if (white_list_sender_regex != NULL)
1339  gw_regex_destroy(white_list_sender_regex);
1340  if (black_list_sender_regex != NULL)
1341  gw_regex_destroy(black_list_sender_regex);
1346  if (white_list_receiver_regex != NULL)
1347  gw_regex_destroy(white_list_receiver_regex);
1348  if (black_list_receiver_regex != NULL)
1349  gw_regex_destroy(black_list_receiver_regex);
1350  /* destroy msg split counter */
1354 
1355  /* Stop concat handling */
1357 
1358  smsc_running = 0;
1359 }
static List * smsc_groups
Definition: bb_smscconn.c:131
int smscconn_destroy(SMSCConn *conn)
Definition: smscconn.c:464
void counter_destroy(Counter *counter)
Definition: counter.c:110
static regex_t * white_list_sender_regex
Definition: bb_smscconn.c:144
static RWLock smsc_list_lock
Definition: bb_smscconn.c:129
long gwlist_len(List *list)
Definition: list.c:166
void gw_rwlock_destroy(RWLock *lock)
Definition: gw-rwlock.c:112
int gw_rwlock_wrlock(RWLock *lock)
Definition: gw-rwlock.c:177
void * gwlist_get(List *list, long pos)
Definition: list.c:292
static regex_t * black_list_receiver_regex
Definition: bb_smscconn.c:147
void numhash_destroy(Numhash *table)
Definition: numhash.c:275
static RWLock white_black_list_lock
Definition: bb_smscconn.c:134
static Numhash * white_list_sender
Definition: bb_smscconn.c:140
static Octstr * black_list_receiver_url
Definition: bb_smscconn.c:137
static Numhash * black_list_sender
Definition: bb_smscconn.c:139
static void concat_handling_cleanup(void)
Definition: bb_smscconn.c:2066
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
Counter * split_msg_counter
Definition: bb_smscconn.c:159
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
static regex_t * white_list_receiver_regex
Definition: bb_smscconn.c:146
static Octstr * white_list_sender_url
Definition: bb_smscconn.c:136
static Numhash * white_list_receiver
Definition: bb_smscconn.c:142
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
static Octstr * unified_prefix
Definition: bb_smscconn.c:132
static Octstr * black_list_sender_url
Definition: bb_smscconn.c:135
static Octstr * white_list_receiver_url
Definition: bb_smscconn.c:138
static regex_t * black_list_sender_regex
Definition: bb_smscconn.c:145
static volatile sig_atomic_t smsc_running
Definition: bb_smscconn.c:127
static Numhash * black_list_receiver
Definition: bb_smscconn.c:141
static List * smsc_list
Definition: bb_smscconn.c:128
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ smsc2_find()

static long smsc2_find ( Octstr id,
long  start 
)
static

Definition at line 948 of file bb_smscconn.c.

References smscconn::admin_id, gwlist_get(), gwlist_len(), octstr_compare(), smsc_list, and start.

Referenced by concat_handling_clear_old_parts(), smsc2_add_smsc(), smsc2_remove_smsc(), smsc2_restart_smsc(), and smsc2_stop_smsc().

949 {
950  SMSCConn *conn = NULL;
951  long i;
952 
953  if (start > gwlist_len(smsc_list) || start < 0 || id == NULL)
954  return -1;
955 
956  for (i = start; i < gwlist_len(smsc_list); i++) {
957  conn = gwlist_get(smsc_list, i);
958  if (conn != NULL && conn->admin_id != NULL && octstr_compare(conn->admin_id, id) == 0) {
959  break;
960  }
961  }
962  if (i >= gwlist_len(smsc_list))
963  i = -1;
964 
965  return i;
966 }
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
Octstr * admin_id
Definition: smscconn_p.h:176
static int start
static List * smsc_list
Definition: bb_smscconn.c:128
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ smsc2_graceful_restart()

int smsc2_graceful_restart ( Cfg cfg)

Definition at line 1530 of file bb_smscconn.c.

References cfg, cfg_get_multi_group(), cmp_conn_grp_checksum(), cmp_conn_grp_id(), cmp_rout_grp_checksum(), gw_rwlock_unlock(), gw_rwlock_wrlock(), gwlist_add_producer(), gwlist_append(), gwlist_create, gwlist_delete(), gwlist_destroy(), gwlist_extract_first(), gwlist_get(), gwlist_len(), gwlist_remove_producer(), gwlist_search_all(), gwlist_search_equal(), gwthread_sleep(), gwthread_wakeup(), smscconn::id, info(), octstr_get_cstr, octstr_imm(), router_thread, smsc_groups, smsc_list, smsc_list_lock, smsc_running, smscconn_create(), smscconn_destroy(), smscconn_instances(), smscconn_reconfig(), smscconn_shutdown(), and smscconn_start().

Referenced by bb_graceful_restart().

1531 {
1532  CfgGroup *grp;
1533  SMSCConn *conn;
1534  List *keep, *add, *remove;
1535  List *l;
1536  int i, m;
1537 
1538  if (!smsc_running)
1539  return -1;
1540 
1542 
1543  /* load the smsc groups from the config resource */
1544  gwlist_destroy(smsc_groups, NULL);
1546 
1547  /* List of SMSCConn that we keep running */
1548  keep = gwlist_create();
1549 
1550  /* List of CfgGroup that we will add */
1551  add = gwlist_create();
1552 
1553  /* List of SMSCConnn that we will shutdown */
1554  remove = gwlist_create();
1555 
1556  /*
1557  * Loop through the loaded smsc groups
1558  */
1559  for (i = 0; i < gwlist_len(smsc_groups) &&
1560  (grp = gwlist_get(smsc_groups, i)) != NULL; i++) {
1561  /*
1562  * 1st check: Search for the same md5 hash of the whole group.
1563  * If we find it, then this group is already running, and no
1564  * routing information has changed, bail out.
1565  */
1566  if ((l = gwlist_search_all(smsc_list, grp, cmp_conn_grp_checksum)) != NULL) {
1567  while ((conn = gwlist_extract_first(l)) != NULL) {
1568  gwlist_append(keep, conn);
1569  }
1570  gwlist_destroy(l, NULL);
1571  continue;
1572  }
1573  /*
1574  * 2nd check: Search for the same md5 hash minus the routing
1575  * information. If we find it, then this group is already running
1576  * and the routing information changed, we'll apply only the new
1577  * routing information.
1578  */
1579  if ((l = gwlist_search_all(smsc_list, grp, cmp_rout_grp_checksum)) != NULL) {
1580  while ((conn = gwlist_extract_first(l)) != NULL) {
1581  gwlist_append(keep, conn);
1582  smscconn_reconfig(conn, grp);
1583  info(0, "Re-configured routing for smsc-id `%s'.", octstr_get_cstr(conn->id));
1584  }
1585  gwlist_destroy(l, NULL);
1586  continue;
1587  }
1588  /*
1589  * 3rd check: if the smsc-id is NOT in the running list, then
1590  * this is a new group, add it. If the smsc-id IS found, then
1591  * mark it/them to be removed, and add the new group.
1592  */
1593  if ((l = gwlist_search_all(smsc_list, grp, cmp_conn_grp_id)) == NULL) {
1594  gwlist_append(add, grp);
1595  continue;
1596  } else {
1597  while ((conn = gwlist_extract_first(l)) != NULL) {
1598  /* add them to the remove list only
1599  * if they are not yet present inside. */
1600  if (gwlist_search_equal(remove, conn) != -1)
1601  gwlist_append(remove, conn);
1602  }
1603  gwlist_destroy(l, NULL);
1604  gwlist_append(add, grp);
1605  continue;
1606  }
1607  }
1608 
1609  /*
1610  * TODO Effectively a change in the 'instances' multiplier will result in a
1611  * disconnect of all running instances, and re-connecting the number of
1612  * configured instances. The reason for this is that the change in the
1613  * 'instances' value causes the md5 hash to be different for that connection.
1614  * We MAY exclude the 'instances' directive from the while md5 checksum, this
1615  * makes the down-grading easier, allowing the rest to keep running. But the
1616  * up-grading is more difficult, since we can't use the 'add' list here, it
1617  * would create too much instances.
1618  */
1619 
1620  /*
1621  * We may have running smsc-ids now, that haven't been
1622  * re-loaded from the new config, hence add them to be removed.
1623  */
1624  for (i = 0; i < gwlist_len(smsc_list) &&
1625  (conn = gwlist_get(smsc_list, i)) != NULL; i++) {
1626  /* if this is already in the remove list, bail out. */
1627  if (gwlist_search_equal(remove, conn) != -1)
1628  continue;
1629  /* if this is in the keep list, bail out. */
1630  if (gwlist_search_equal(keep, conn) != -1)
1631  continue;
1632  /* mark it to be removed */
1633  gwlist_append(remove, conn);
1634  }
1635  gwlist_destroy(keep, NULL);
1636 
1637  /*
1638  * Stop any connections from the remove list.
1639  *
1640  * The smscconn_shutdown() only initiates the shutdown,
1641  * it is not guaranteed that the SMSC connection is stopped
1642  * and the status is SMSCCONN_DEAD when we return from the
1643  * function call. Therefore we pass the connection to a
1644  * retry list, in order to cleanly destroy all connection
1645  * structures that have been stopped and reached SMSSCONN_DEAD.
1646  */
1647  l = gwlist_create();
1649  while ((conn = gwlist_extract_first(remove)) != NULL) {
1650  if ((i = gwlist_search_equal(smsc_list, conn)) != -1) {
1651  gwlist_delete(smsc_list, i, 1);
1652  smscconn_shutdown(conn, 0);
1653  /* if smsc is still in shutdown, then add to retry list */
1654  if (smscconn_destroy(conn) == -1)
1655  gwlist_append(l, conn);
1656  }
1657  }
1659  gwlist_destroy(remove, NULL);
1660 
1661  /*
1662  * Start any connections from the add list.
1663  */
1665  while ((grp = gwlist_extract_first(add)) != NULL) {
1666  /* multiple instances for the same group? */
1667  m = smscconn_instances(grp);
1668  for (i = 0; i < m; i++) {
1669  conn = smscconn_create(grp, 1);
1670  if (conn != NULL) {
1671  gwlist_append(smsc_list, conn);
1672  if (conn->dead_start) {
1673  /* Shutdown connection if it's not configured to connect at start-up time */
1674  smscconn_shutdown(conn, 0);
1675  } else {
1676  smscconn_start(conn);
1677  }
1678  }
1679  }
1680  }
1682  gwlist_destroy(add, NULL);
1683 
1685 
1686  /* wake-up the router */
1687  if (router_thread >= 0)
1689 
1690  /*
1691  * We may still have pending connections in the retry list
1692  * that haven't been destroyed yet.
1693  */
1694  while ((conn = gwlist_extract_first(l)) != NULL) {
1695  if (smscconn_destroy(conn) == -1) {
1696  gwlist_append(l, conn);
1697  gwthread_sleep(2);
1698  }
1699  }
1700  gwlist_destroy(l, NULL);
1701 
1702  return 0;
1703 }
void info(int err, const char *fmt,...)
Definition: log.c:672
long gwlist_search_equal(List *list, void *item)
Definition: list.c:534
static List * smsc_groups
Definition: bb_smscconn.c:131
static long router_thread
Definition: bb_smscconn.c:149
int smscconn_destroy(SMSCConn *conn)
Definition: smscconn.c:464
void gwlist_append(List *list, void *item)
Definition: list.c:179
void smscconn_shutdown(SMSCConn *conn, int finish_sending)
Definition: smscconn.c:427
static RWLock smsc_list_lock
Definition: bb_smscconn.c:129
Octstr * id
Definition: smscconn_p.h:174
long gwlist_len(List *list)
Definition: list.c:166
int gw_rwlock_wrlock(RWLock *lock)
Definition: gw-rwlock.c:177
void * gwlist_get(List *list, long pos)
Definition: list.c:292
static int cmp_conn_grp_id(void *a, void *b)
Definition: bb_smscconn.c:788
static Cfg * cfg
Definition: opensmppbox.c:95
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
unsigned int smscconn_instances(CfgGroup *grp)
Definition: smscconn.c:197
List * gwlist_search_all(List *list, void *pattern, int(*cmp)(void *, void *))
Definition: list.c:508
void smscconn_reconfig(SMSCConn *conn, CfgGroup *grp)
Definition: smscconn.c:763
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
void * gwlist_extract_first(List *list)
Definition: list.c:305
void gwlist_delete(List *list, long pos, long count)
Definition: list.c:232
void gwlist_remove_producer(List *list)
Definition: list.c:401
static int cmp_conn_grp_checksum(void *a, void *b)
Definition: bb_smscconn.c:734
List * cfg_get_multi_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:645
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
void gwthread_sleep(double seconds)
static int cmp_rout_grp_checksum(void *a, void *b)
Definition: bb_smscconn.c:751
void gwthread_wakeup(long thread)
Definition: cfg.c:73
#define gwlist_create()
Definition: list.h:136
SMSCConn * smscconn_create(CfgGroup *grp, int start_as_stopped)
Definition: smscconn.c:210
void gwlist_add_producer(List *list)
Definition: list.c:383
static volatile sig_atomic_t smsc_running
Definition: bb_smscconn.c:127
Definition: list.c:102
void smscconn_start(SMSCConn *conn)
Definition: smscconn.c:536
static List * smsc_list
Definition: bb_smscconn.c:128
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ smsc2_reload_lists()

int smsc2_reload_lists ( void  )

Definition at line 1174 of file bb_smscconn.c.

References black_list_receiver, black_list_receiver_url, black_list_sender, black_list_sender_url, error(), gw_rwlock_unlock(), gw_rwlock_wrlock(), numhash_create(), numhash_destroy(), octstr_get_cstr, white_black_list_lock, white_list_receiver, white_list_receiver_url, white_list_sender, and white_list_sender_url.

Referenced by bb_reload_lists().

1175 {
1176  Numhash *tmp;
1177  int rc = 1;
1178 
1179  if (white_list_sender_url != NULL) {
1181  if (white_list_sender == NULL) {
1182  error(0, "Unable to reload white_list."),
1183  rc = -1;
1184  } else {
1187  white_list_sender = tmp;
1189  }
1190  }
1191 
1192  if (black_list_sender_url != NULL) {
1194  if (black_list_sender == NULL) {
1195  error(0, "Unable to reload black_list");
1196  rc = -1;
1197  } else {
1200  black_list_sender = tmp;
1202  }
1203  }
1204 
1205  if (white_list_receiver_url != NULL) {
1207  if (white_list_receiver == NULL) {
1208  error(0, "Unable to reload white_list."),
1209  rc = -1;
1210  } else {
1213  white_list_receiver = tmp;
1215  }
1216  }
1217 
1218  if (black_list_receiver_url != NULL) {
1220  if (black_list_receiver == NULL) {
1221  error(0, "Unable to reload black_list");
1222  rc = -1;
1223  } else {
1226  black_list_receiver = tmp;
1228  }
1229  }
1230 
1231  return rc;
1232 }
void error(int err, const char *fmt,...)
Definition: log.c:648
int gw_rwlock_wrlock(RWLock *lock)
Definition: gw-rwlock.c:177
void numhash_destroy(Numhash *table)
Definition: numhash.c:275
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static RWLock white_black_list_lock
Definition: bb_smscconn.c:134
Numhash * numhash_create(const char *seek_url)
Definition: numhash.c:313
static Numhash * white_list_sender
Definition: bb_smscconn.c:140
static Octstr * black_list_receiver_url
Definition: bb_smscconn.c:137
static Numhash * black_list_sender
Definition: bb_smscconn.c:139
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
static Octstr * white_list_sender_url
Definition: bb_smscconn.c:136
static Numhash * white_list_receiver
Definition: bb_smscconn.c:142
static Octstr * black_list_sender_url
Definition: bb_smscconn.c:135
static Octstr * white_list_receiver_url
Definition: bb_smscconn.c:138
static Numhash * black_list_receiver
Definition: bb_smscconn.c:141

◆ smsc2_remove_smsc()

int smsc2_remove_smsc ( Octstr id)

Definition at line 1083 of file bb_smscconn.c.

References error(), gw_rwlock_unlock(), gw_rwlock_wrlock(), gwlist_add_producer(), gwlist_delete(), gwlist_get(), gwlist_remove_producer(), octstr_get_cstr, smsc2_find(), smsc_list, smsc_list_lock, smsc_running, smscconn_destroy(), and smscconn_shutdown().

Referenced by bb_remove_smsc().

1084 {
1085  SMSCConn *conn;
1086  long i = -1;
1087  int success = 0;
1088 
1089  if (!smsc_running)
1090  return -1;
1091 
1093 
1095  while ((i = smsc2_find(id, ++i)) != -1) {
1096  conn = gwlist_get(smsc_list, i);
1097  gwlist_delete(smsc_list, i--, 1);
1098  smscconn_shutdown(conn, 0);
1099  smscconn_destroy(conn);
1100  success = 1;
1101  }
1103 
1105  if (success == 0) {
1106  error(0, "SMSC %s not found", octstr_get_cstr(id));
1107  return -1;
1108  }
1109  return 0;
1110 }
void error(int err, const char *fmt,...)
Definition: log.c:648
int smscconn_destroy(SMSCConn *conn)
Definition: smscconn.c:464
void smscconn_shutdown(SMSCConn *conn, int finish_sending)
Definition: smscconn.c:427
static RWLock smsc_list_lock
Definition: bb_smscconn.c:129
int gw_rwlock_wrlock(RWLock *lock)
Definition: gw-rwlock.c:177
void * gwlist_get(List *list, long pos)
Definition: list.c:292
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void gwlist_delete(List *list, long pos, long count)
Definition: list.c:232
void gwlist_remove_producer(List *list)
Definition: list.c:401
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
void gwlist_add_producer(List *list)
Definition: list.c:383
static volatile sig_atomic_t smsc_running
Definition: bb_smscconn.c:127
static List * smsc_list
Definition: bb_smscconn.c:128
static long smsc2_find(Octstr *id, long start)
Definition: bb_smscconn.c:948

◆ smsc2_restart_smsc()

int smsc2_restart_smsc ( Octstr id)

Definition at line 998 of file bb_smscconn.c.

References bb_reload_smsc_groups(), cfg_get, error(), gw_rwlock_unlock(), gw_rwlock_wrlock(), gwlist_delete(), gwlist_get(), gwlist_insert(), gwlist_len(), gwthread_wakeup(), info(), octstr_compare(), octstr_destroy(), octstr_get_cstr, octstr_imm(), router_thread, smsc2_find(), smsc_groups, smsc_list, smsc_list_lock, smsc_running, smscconn_create(), SMSCCONN_DEAD, smscconn_destroy(), smscconn_start(), smscconn_status(), and warning().

Referenced by bb_restart_smsc().

999 {
1000  CfgGroup *grp;
1001  SMSCConn *conn, *new_conn;
1002  Octstr *smscid = NULL;
1003  long i = -1;
1004  int hit;
1005  int num = 0;
1006  int success = 0;
1007 
1008  if (!smsc_running)
1009  return -1;
1010 
1012 
1013  if (bb_reload_smsc_groups() != 0) {
1015  return -1;
1016  }
1017  /* find the specific smsc via id */
1018  while((i = smsc2_find(id, ++i)) != -1) {
1019  long group_index;
1020  /* check if smsc has online status already */
1021  conn = gwlist_get(smsc_list, i);
1022  if (conn != NULL && smscconn_status(conn) != SMSCCONN_DEAD) {
1023  warning(0, "HTTP: Could not re-start already running smsc-id `%s'",
1024  octstr_get_cstr(id));
1025  continue;
1026  }
1027  /* find the group with equal smsc (admin-)id */
1028  hit = -1;
1029  grp = NULL;
1030  for (group_index = 0; group_index < gwlist_len(smsc_groups) &&
1031  (grp = gwlist_get(smsc_groups, group_index)) != NULL; group_index++) {
1032  smscid = cfg_get(grp, octstr_imm("smsc-admin-id"));
1033  if (smscid == NULL)
1034  smscid = cfg_get(grp, octstr_imm("smsc-id"));
1035  if (smscid != NULL && octstr_compare(smscid, id) == 0) {
1036  if (hit < 0)
1037  hit = 0;
1038  if (hit == num)
1039  break;
1040  else
1041  hit++;
1042  }
1043  octstr_destroy(smscid);
1044  smscid = NULL;
1045  }
1046  octstr_destroy(smscid);
1047  if (hit != num) {
1048  /* config group not found */
1049  error(0, "HTTP: Could not find config for smsc-id `%s'", octstr_get_cstr(id));
1050  break;
1051  }
1052 
1053  info(0,"HTTP: Re-starting smsc-id `%s'", octstr_get_cstr(id));
1054 
1055  new_conn = smscconn_create(grp, 1);
1056  if (new_conn == NULL) {
1057  error(0, "Start of SMSC connection failed, smsc-id `%s'", octstr_get_cstr(id));
1058  continue; /* keep old connection on the list */
1059  }
1060 
1061  /* drop old connection from the active smsc list */
1062  gwlist_delete(smsc_list, i, 1);
1063  /* destroy the connection */
1064  smscconn_destroy(conn);
1065  gwlist_insert(smsc_list, i, new_conn);
1066  smscconn_start(new_conn);
1067  success = 1;
1068  num++;
1069  }
1070 
1072 
1073  if (success == 0) {
1074  error(0, "SMSC %s not found", octstr_get_cstr(id));
1075  return -1;
1076  }
1077  /* wake-up the router */
1078  if (router_thread >= 0)
1080  return 0;
1081 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void info(int err, const char *fmt,...)
Definition: log.c:672
static List * smsc_groups
Definition: bb_smscconn.c:131
static long router_thread
Definition: bb_smscconn.c:149
int smscconn_destroy(SMSCConn *conn)
Definition: smscconn.c:464
static RWLock smsc_list_lock
Definition: bb_smscconn.c:129
long gwlist_len(List *list)
Definition: list.c:166
int gw_rwlock_wrlock(RWLock *lock)
Definition: gw-rwlock.c:177
void * gwlist_get(List *list, long pos)
Definition: list.c:292
#define cfg_get(grp, varname)
Definition: cfg.h:86
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
int smscconn_status(SMSCConn *conn)
Definition: smscconn.c:724
void gwlist_delete(List *list, long pos, long count)
Definition: list.c:232
int bb_reload_smsc_groups()
Definition: bb_smscconn.c:627
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
void gwlist_insert(List *list, long pos, void *item)
Definition: list.c:214
Definition: octstr.c:118
void gwthread_wakeup(long thread)
Definition: cfg.c:73
SMSCConn * smscconn_create(CfgGroup *grp, int start_as_stopped)
Definition: smscconn.c:210
static volatile sig_atomic_t smsc_running
Definition: bb_smscconn.c:127
void smscconn_start(SMSCConn *conn)
Definition: smscconn.c:536
static List * smsc_list
Definition: bb_smscconn.c:128
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871
static long smsc2_find(Octstr *id, long start)
Definition: bb_smscconn.c:948

◆ smsc2_resume()

void smsc2_resume ( int  is_init)

Definition at line 1234 of file bb_smscconn.c.

References smscconn::dead_start, gw_rwlock_rdlock(), gw_rwlock_unlock(), gwlist_get(), gwlist_len(), gwthread_wakeup(), router_thread, smsc_list, smsc_list_lock, smsc_running, smscconn_shutdown(), and smscconn_start().

Referenced by bb_resume(), and main().

1235 {
1236  SMSCConn *conn;
1237  long i;
1238 
1239  if (!smsc_running)
1240  return;
1241 
1243  for (i = 0; i < gwlist_len(smsc_list); i++) {
1244  conn = gwlist_get(smsc_list, i);
1245  if (!is_init || !conn->dead_start) {
1246  smscconn_start(conn);
1247  } else {
1248  /* Shutdown the connections that are not configured to start at boot */
1249  smscconn_shutdown(conn, 0);
1250  }
1251  }
1253 
1254  if (router_thread >= 0)
1256 }
static long router_thread
Definition: bb_smscconn.c:149
int dead_start
Definition: smscconn_p.h:211
void smscconn_shutdown(SMSCConn *conn, int finish_sending)
Definition: smscconn.c:427
static RWLock smsc_list_lock
Definition: bb_smscconn.c:129
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
int gw_rwlock_rdlock(RWLock *lock)
Definition: gw-rwlock.c:134
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
void gwthread_wakeup(long thread)
static volatile sig_atomic_t smsc_running
Definition: bb_smscconn.c:127
void smscconn_start(SMSCConn *conn)
Definition: smscconn.c:536
static List * smsc_list
Definition: bb_smscconn.c:128

◆ smsc2_rout()

long smsc2_rout ( Msg msg,
int  resend 
)

Definition at line 1716 of file bb_smscconn.c.

References BB_SHUTDOWN, bb_smscconn_send_failed(), bb_status, black_list_receiver, black_list_receiver_regex, black_list_sender, black_list_sender_regex, debug(), error(), gw_rand(), gw_rwlock_rdlock(), gw_rwlock_unlock(), gwlist_get(), gwlist_len(), gwlist_produce(), gwlist_search_equal(), info(), smsc_state::load, max_outgoing_sms_qlength, msg, msg_destroy(), msg_duplicate(), normalize_number(), numhash_find_number(), octstr_create, octstr_get_cstr, outgoing_sms, smsc_state::queued, SMS_PARAM_UNDEFINED, smsc2_rout(), split_parts::smsc_conn, smsc_list, smsc_list_lock, SMSCCONN_ACTIVE, SMSCCONN_FAILED_DISCARDED, SMSCCONN_FAILED_EXPIRED, SMSCCONN_FAILED_QFULL, SMSCCONN_FAILED_REJECTED, smscconn_info(), SMSCCONN_QUEUED, smscconn_send(), SMSCCONN_SUCCESS, smscconn_usable(), smsc_state::status, unified_prefix, warning(), white_black_list_lock, white_list_receiver, white_list_receiver_regex, white_list_sender, and white_list_sender_regex.

Referenced by deliver_sms_to_queue(), route_incoming_to_smsc(), sms_router(), and smsc2_rout().

1717 {
1718  StatusInfo stat;
1719  SMSCConn *conn, *best_preferred, *best_ok;
1720  long bp_load, bo_load;
1721  int i, s, ret, bad_found, full_found;
1722  long max_queue, queue_length;
1723  char *uf;
1724 
1725  /* XXX handle ack here? */
1726  if (msg_type(msg) != sms) {
1727  error(0, "Attempt to route non SMS message through smsc2_rout!");
1729  }
1730 
1731  /* check if validity period has expired */
1732  if (msg->sms.validity != SMS_PARAM_UNDEFINED && time(NULL) > msg->sms.validity) {
1734  return SMSCCONN_FAILED_EXPIRED;
1735  }
1736 
1737  /* unify prefix of receiver, in case of it has not been
1738  * already done */
1740  normalize_number(uf, &(msg->sms.receiver));
1741 
1742  /* check for white/back-listed sender/receiver */
1744  if (white_list_sender && numhash_find_number(white_list_sender, msg->sms.sender) < 1) {
1746  info(0, "Number <%s> is not in white-list-sender, message rejected",
1747  octstr_get_cstr(msg->sms.sender));
1748  bb_smscconn_send_failed(NULL, msg_duplicate(msg), SMSCCONN_FAILED_REJECTED, octstr_create("sender not in white-list"));
1749  return SMSCCONN_FAILED_REJECTED;
1750  }
1751 
1752  if (white_list_sender_regex && gw_regex_match_pre(white_list_sender_regex, msg->sms.sender) == 0) {
1754  info(0, "Number <%s> is not in white-list-sender, message rejected",
1755  octstr_get_cstr(msg->sms.sender));
1756  bb_smscconn_send_failed(NULL, msg_duplicate(msg), SMSCCONN_FAILED_REJECTED, octstr_create("sender not in white-list"));
1757  return SMSCCONN_FAILED_REJECTED;
1758  }
1759 
1760  if (black_list_sender && numhash_find_number(black_list_sender, msg->sms.sender) == 1) {
1762  info(0, "Number <%s> is in black-list-sender, message rejected",
1763  octstr_get_cstr(msg->sms.sender));
1765  return SMSCCONN_FAILED_REJECTED;
1766  }
1767 
1768  if (black_list_sender_regex && gw_regex_match_pre(black_list_sender_regex, msg->sms.sender) != 0) {
1770  info(0, "Number <%s> is in black-list-sender, message rejected",
1771  octstr_get_cstr(msg->sms.sender));
1773  return SMSCCONN_FAILED_REJECTED;
1774  }
1775 
1776  if (white_list_receiver && numhash_find_number(white_list_receiver, msg->sms.receiver) < 1) {
1778  info(0, "Number <%s> is not in white-list-receiver, message rejected",
1779  octstr_get_cstr(msg->sms.receiver));
1780  bb_smscconn_send_failed(NULL, msg_duplicate(msg), SMSCCONN_FAILED_REJECTED, octstr_create("receiver not in white-list"));
1781  return SMSCCONN_FAILED_REJECTED;
1782  }
1783 
1784  if (white_list_receiver_regex && gw_regex_match_pre(white_list_receiver_regex, msg->sms.receiver) == 0) {
1786  info(0, "Number <%s> is not in white-list-receiver, message rejected",
1787  octstr_get_cstr(msg->sms.receiver));
1788  bb_smscconn_send_failed(NULL, msg_duplicate(msg), SMSCCONN_FAILED_REJECTED, octstr_create("receiver not in white-list"));
1789  return SMSCCONN_FAILED_REJECTED;
1790  }
1791 
1792  if (black_list_receiver && numhash_find_number(black_list_receiver, msg->sms.receiver) == 1) {
1794  info(0, "Number <%s> is in black-list-receiver, message rejected",
1795  octstr_get_cstr(msg->sms.receiver));
1797  return SMSCCONN_FAILED_REJECTED;
1798  }
1799 
1800  if (black_list_receiver_regex && gw_regex_match_pre(black_list_receiver_regex, msg->sms.receiver) != 0) {
1802  info(0, "Number <%s> is in black-list-receiver, message rejected",
1803  octstr_get_cstr(msg->sms.receiver));
1805  return SMSCCONN_FAILED_REJECTED;
1806  }
1808 
1809  /* select in which list to add this
1810  * start - from random SMSCConn, as they are all 'equal'
1811  */
1813  if (gwlist_len(smsc_list) == 0) {
1814  warning(0, "No SMSCes to receive message");
1817  }
1818 
1819  best_preferred = best_ok = NULL;
1820  bad_found = full_found = 0;
1821  bp_load = bo_load = queue_length = 0;
1822 
1823  if (msg->sms.split_parts == NULL) {
1824  /*
1825  * if global queue not empty then 20% reserved for old msgs
1826  * and 80% for new msgs. So we can guarantee that old msgs find
1827  * place in the SMSC's queue.
1828  */
1829  if (gwlist_len(outgoing_sms) > 0) {
1830  max_queue = (resend ? max_outgoing_sms_qlength :
1831  max_outgoing_sms_qlength * 0.8);
1832  } else
1833  max_queue = max_outgoing_sms_qlength;
1834 
1835  s = gw_rand() % gwlist_len(smsc_list);
1836 
1837  conn = NULL;
1838  for (i = 0; i < gwlist_len(smsc_list); i++) {
1839  conn = gwlist_get(smsc_list, (i+s) % gwlist_len(smsc_list));
1840 
1841  smscconn_info(conn, &stat);
1842  queue_length += (stat.queued > 0 ? stat.queued : 0);
1843 
1844  ret = smscconn_usable(conn,msg);
1845  if (ret == -1)
1846  continue;
1847 
1848  /* if we already have a preferred one, skip non-preferred */
1849  if (ret != 1 && best_preferred)
1850  continue;
1851 
1852  /* If connection is not currently answering ... */
1853  if (stat.status != SMSCCONN_ACTIVE) {
1854  bad_found = 1;
1855  continue;
1856  }
1857  /* check queue length */
1858  if (stat.queued > max_queue) {
1859  full_found = 1;
1860  continue;
1861  }
1862  if (ret == 1) { /* preferred */
1863  if (best_preferred == NULL || stat.load < bp_load) {
1864  best_preferred = conn;
1865  bp_load = stat.load;
1866  continue;
1867  }
1868  }
1869  if (best_ok == NULL || stat.load < bo_load) {
1870  best_ok = conn;
1871  bo_load = stat.load;
1872  }
1873  }
1874  queue_length += gwlist_len(outgoing_sms);
1875  if (max_outgoing_sms_qlength > 0 && !resend &&
1876  queue_length > gwlist_len(smsc_list) * max_outgoing_sms_qlength) {
1878  debug("bb.sms", 0, "sum(#queues) limit");
1879  return SMSCCONN_FAILED_QFULL;
1880  }
1881  } else {
1882  struct split_parts *parts = msg->sms.split_parts;
1883  /* check whether this SMSCConn still on the list */
1884  if (gwlist_search_equal(smsc_list, parts->smsc_conn) != -1)
1885  best_preferred = parts->smsc_conn;
1886  }
1887 
1888  if (best_preferred)
1889  ret = smscconn_send(best_preferred, msg);
1890  else if (best_ok)
1891  ret = smscconn_send(best_ok, msg);
1892  else if (bad_found) {
1896  return SMSCCONN_QUEUED;
1897  }
1898  debug("bb.sms", 0, "bad_found queue full");
1899  return SMSCCONN_FAILED_QFULL; /* queue full */
1900  } else if (full_found) {
1902  debug("bb.sms", 0, "full_found queue full");
1903  return SMSCCONN_FAILED_QFULL;
1904  } else {
1906  if (bb_status == BB_SHUTDOWN) {
1907  msg_destroy(msg);
1908  return SMSCCONN_QUEUED;
1909  }
1910  warning(0, "Cannot find SMSCConn for message to <%s>, rejected.",
1911  octstr_get_cstr(msg->sms.receiver));
1914  }
1915 
1917  /* check the status of sending operation */
1918  if (ret == -1)
1919  return smsc2_rout(msg, resend); /* re-try */
1920 
1921  msg_destroy(msg);
1922  return SMSCCONN_SUCCESS;
1923 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void info(int err, const char *fmt,...)
Definition: log.c:672
Msg * msg_duplicate(Msg *msg)
Definition: msg.c:111
long gwlist_search_equal(List *list, void *item)
Definition: list.c:534
static regex_t * white_list_sender_regex
Definition: bb_smscconn.c:144
void gwlist_produce(List *list, void *item)
Definition: list.c:411
static RWLock smsc_list_lock
Definition: bb_smscconn.c:129
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
msg_type
Definition: msg.h:73
static regex_t * black_list_receiver_regex
Definition: bb_smscconn.c:147
List * outgoing_sms
Definition: bearerbox.c:85
long max_outgoing_sms_qlength
Definition: bearerbox.c:99
int gw_rwlock_rdlock(RWLock *lock)
Definition: gw-rwlock.c:134
smscconn_status_t status
Definition: smscconn.h:113
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static RWLock white_black_list_lock
Definition: bb_smscconn.c:134
long queued
Definition: smscconn.h:121
static Numhash * white_list_sender
Definition: bb_smscconn.c:140
int numhash_find_number(Numhash *table, Octstr *nro)
Definition: numhash.c:218
static Numhash * black_list_sender
Definition: bb_smscconn.c:139
void msg_destroy(Msg *msg)
Definition: msg.c:132
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
void warning(int err, const char *fmt,...)
Definition: log.c:660
#define octstr_create(cstr)
Definition: octstr.h:125
static regex_t * white_list_receiver_regex
Definition: bb_smscconn.c:146
#define SMS_PARAM_UNDEFINED
Definition: sms.h:91
int load
Definition: smscconn.h:123
int smscconn_send(SMSCConn *conn, Msg *msg)
Definition: smscconn.c:655
void * smsc_conn
Definition: msg.h:98
static Numhash * white_list_receiver
Definition: bb_smscconn.c:142
int smscconn_usable(SMSCConn *conn, Msg *msg)
Definition: smscconn.c:573
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
volatile sig_atomic_t bb_status
Definition: bearerbox.c:132
int normalize_number(char *dial_prefixes, Octstr **number)
Definition: utils.c:882
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
Definition: bb_smscconn.c:329
static Octstr * unified_prefix
Definition: bb_smscconn.c:132
int smscconn_info(SMSCConn *conn, StatusInfo *infotable)
Definition: smscconn.c:732
static regex_t * black_list_sender_regex
Definition: bb_smscconn.c:145
int gw_rand(void)
Definition: protected.c:174
static Numhash * black_list_receiver
Definition: bb_smscconn.c:141
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static List * smsc_list
Definition: bb_smscconn.c:128
long smsc2_rout(Msg *msg, int resend)
Definition: bb_smscconn.c:1716

◆ smsc2_shutdown()

int smsc2_shutdown ( void  )

Definition at line 1276 of file bb_smscconn.c.

References concat_handling_shutdown(), gw_rwlock_rdlock(), gw_rwlock_unlock(), gwlist_get(), gwlist_len(), gwlist_remove_producer(), gwthread_wakeup(), incoming_sms, router_thread, smpp_pdu_shutdown(), smsc_list, smsc_list_lock, smsc_running, and smscconn_shutdown().

Referenced by bb_shutdown().

1277 {
1278  SMSCConn *conn;
1279  long i;
1280 
1281  if (!smsc_running)
1282  return -1;
1283 
1284  /* stop concat handling */
1286 
1287  /* Call shutdown for all SMSC Connections; they should
1288  * handle that they quit, by emptying queues and then dying off
1289  */
1291  for(i=0; i < gwlist_len(smsc_list); i++) {
1292  conn = gwlist_get(smsc_list, i);
1293  smscconn_shutdown(conn, 1);
1294  }
1296  if (router_thread >= 0)
1298 
1299  /* start avalanche by calling shutdown */
1300 
1301  /* XXX shouldn'w we be sure that all smsces have closed their
1302  * receive thingies? Is this guaranteed by setting bb_status
1303  * to shutdown before calling these?
1304  */
1306 
1307  /* shutdown low levele PDU things */
1309 
1310  return 0;
1311 }
static long router_thread
Definition: bb_smscconn.c:149
void smscconn_shutdown(SMSCConn *conn, int finish_sending)
Definition: smscconn.c:427
static RWLock smsc_list_lock
Definition: bb_smscconn.c:129
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
int gw_rwlock_rdlock(RWLock *lock)
Definition: gw-rwlock.c:134
List * incoming_sms
Definition: bearerbox.c:84
int smpp_pdu_shutdown(void)
Definition: smpp_pdu.c:314
void gwlist_remove_producer(List *list)
Definition: list.c:401
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
void gwthread_wakeup(long thread)
static void concat_handling_shutdown(void)
Definition: bb_smscconn.c:2053
static volatile sig_atomic_t smsc_running
Definition: bb_smscconn.c:127
static List * smsc_list
Definition: bb_smscconn.c:128

◆ smsc2_start()

int smsc2_start ( Cfg cfg)

Definition at line 806 of file bb_smscconn.c.

References black_list_receiver, black_list_receiver_regex, black_list_receiver_url, black_list_sender, black_list_sender_regex, black_list_sender_url, cfg, cfg_get, cfg_get_bool(), cfg_get_integer(), cfg_get_multi_group(), cfg_get_single_group(), cfg_reloaded, concat_handling_init(), concatenated_mo_timeout, counter_create(), gw_rwlock_init_static(), gwlist_add_producer(), gwlist_append(), gwlist_create, gwlist_get(), gwlist_len(), gwlist_remove_producer(), gwthread_create, handle_concatenated_mo, incoming_sms, info(), numhash_create(), octstr_destroy(), octstr_get_cstr, octstr_imm(), panic, router_thread, smpp_pdu_init(), sms_resend_frequency, sms_resend_retry, sms_router(), smsc_groups, smsc_list, smsc_list_lock, smsc_running, smscconn_create(), smscconn_instances(), split_msg_counter, unified_prefix, warning(), white_black_list_lock, white_list_receiver, white_list_receiver_regex, white_list_receiver_url, white_list_sender, white_list_sender_regex, and white_list_sender_url.

Referenced by start_smsc().

807 {
808  CfgGroup *grp;
809  SMSCConn *conn;
810  Octstr *os;
811  int i, j, m;
812 
813  if (smsc_running) return -1;
814 
815  /* at start-up time there is no reloaded config */
816  cfg_reloaded = NULL;
817 
818  /* create split sms counter */
820 
821  /* create smsc list and rwlock for it */
824 
825  grp = cfg_get_single_group(cfg, octstr_imm("core"));
826  unified_prefix = cfg_get(grp, octstr_imm("unified-prefix"));
827 
831  if ((white_list_sender_url = cfg_get(grp, octstr_imm("white-list"))) != NULL) /* TODO deprecated, remove */
832  warning(0, "Option 'white-list' is deprecated! Please use 'white-list-sender' instead!");
833  else
834  white_list_sender_url = cfg_get(grp, octstr_imm("white-list-sender"));
835  if (white_list_sender_url != NULL) {
837  panic(0, "Could not get white-list at URL <%s>",
839  }
840  if ((os = cfg_get(grp, octstr_imm("white-list-regex"))) != NULL) /* TODO deprecated, remove */
841  warning(0, "Option 'white-list-regex' is deprecated! Please use 'white-list-sender-regex' instead!");
842  else
843  os = cfg_get(grp, octstr_imm("white-list-sender-regex"));
844  if (os != NULL) {
845  if ((white_list_sender_regex = gw_regex_comp(os, REG_EXTENDED)) == NULL)
846  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(os));
847  octstr_destroy(os);
848  }
849 
850  if ((black_list_sender_url = cfg_get(grp, octstr_imm("black-list"))) != NULL) /* TODO deprecated, remove */
851  warning(0, "Option 'black-list' is deprecated! Please use 'black-list-sender' instead!");
852  else
853  black_list_sender_url = cfg_get(grp, octstr_imm("black-list-sender"));
854  if (black_list_sender_url != NULL) {
856  panic(0, "Could not get black-list at URL <%s>",
858  }
859  if ((os = cfg_get(grp, octstr_imm("black-list-regex"))) != NULL) /* TODO deprecated, remove */
860  warning(0, "Option 'black-list-regex' is deprecated! Please use 'black-list-sender-regex' instead!");
861  else
862  os = cfg_get(grp, octstr_imm("black-list-sender-regex"));
863  if (os != NULL) {
864  if ((black_list_sender_regex = gw_regex_comp(os, REG_EXTENDED)) == NULL)
865  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(os));
866  octstr_destroy(os);
867  }
868 
871  white_list_receiver_url = cfg_get(grp, octstr_imm("white-list-receiver"));
872  if (white_list_receiver_url != NULL) {
874  panic(0, "Could not get white-list-receiver at URL <%s>",
876  }
877  if ((os = cfg_get(grp, octstr_imm("white-list-receiver-regex"))) != NULL) {
878  if ((white_list_receiver_regex = gw_regex_comp(os, REG_EXTENDED)) == NULL)
879  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(os));
880  octstr_destroy(os);
881  }
882 
883  black_list_receiver_url = cfg_get(grp, octstr_imm("black-list-receiver"));
884  if (black_list_receiver_url != NULL) {
886  panic(0, "Could not get black-list-receiver at URL <%s>",
888  }
889  if ((os = cfg_get(grp, octstr_imm("black-list-receiver-regex"))) != NULL) {
890  if ((black_list_receiver_regex = gw_regex_comp(os, REG_EXTENDED)) == NULL)
891  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(os));
892  octstr_destroy(os);
893  }
894 
896  octstr_imm("sms-resend-freq")) == -1 || sms_resend_frequency <= 0) {
898  }
899  info(0, "Set SMS resend frequency to %ld seconds.", sms_resend_frequency);
900 
901  if (cfg_get_integer(&sms_resend_retry, grp, octstr_imm("sms-resend-retry")) == -1) {
902  sms_resend_retry = -1;
903  info(0, "SMS resend retry set to unlimited.");
904  }
905  else
906  info(0, "SMS resend retry set to %ld.", sms_resend_retry);
907 
908  if (cfg_get_bool((int*)&handle_concatenated_mo, grp, octstr_imm("sms-combine-concatenated-mo")) == -1)
909  handle_concatenated_mo = 1; /* default is TRUE. */
910 
911  if (cfg_get_integer(&concatenated_mo_timeout, grp, octstr_imm("sms-combine-concatenated-mo-timeout")) == -1)
913 
916 
917  /* initialize low level PDUs */
918  if (smpp_pdu_init(cfg) == -1)
919  panic(0, "Connot start with PDU init failed.");
920 
923  for (i = 0; i < gwlist_len(smsc_groups) &&
924  (grp = gwlist_get(smsc_groups, i)) != NULL; i++) {
925  /* multiple instances for the same group? */
926  m = smscconn_instances(grp);
927  for (j = 0; j < m; j++) {
928  conn = smscconn_create(grp, 1);
929  if (conn == NULL)
930  panic(0, "Cannot start with SMSC connection failing");
931  gwlist_append(smsc_list, conn);
932  }
933  }
935 
936  if ((router_thread = gwthread_create(sms_router, NULL)) == -1)
937  panic(0, "Failed to start a new thread for SMS routing");
938 
940  smsc_running = 1;
941  return 0;
942 }
void info(int err, const char *fmt,...)
Definition: log.c:672
static Cfg * cfg_reloaded
Definition: bb_smscconn.c:130
static long concatenated_mo_timeout
Definition: bb_smscconn.c:164
static List * smsc_groups
Definition: bb_smscconn.c:131
static long router_thread
Definition: bb_smscconn.c:149
void gwlist_append(List *list, void *item)
Definition: list.c:179
static regex_t * white_list_sender_regex
Definition: bb_smscconn.c:144
static RWLock smsc_list_lock
Definition: bb_smscconn.c:129
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
#define cfg_get(grp, varname)
Definition: cfg.h:86
static regex_t * black_list_receiver_regex
Definition: bb_smscconn.c:147
static long sms_resend_retry
Definition: bb_smscconn.c:153
static Cfg * cfg
Definition: opensmppbox.c:95
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
List * incoming_sms
Definition: bearerbox.c:84
static RWLock white_black_list_lock
Definition: bb_smscconn.c:134
unsigned int smscconn_instances(CfgGroup *grp)
Definition: smscconn.c:197
Numhash * numhash_create(const char *seek_url)
Definition: numhash.c:313
static Numhash * white_list_sender
Definition: bb_smscconn.c:140
static Octstr * black_list_receiver_url
Definition: bb_smscconn.c:137
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
Counter * counter_create(void)
Definition: counter.c:94
static Numhash * black_list_sender
Definition: bb_smscconn.c:139
void gwlist_remove_producer(List *list)
Definition: list.c:401
static void concat_handling_init(void)
Definition: bb_smscconn.c:2043
List * cfg_get_multi_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:645
static void sms_router(void *arg)
Definition: bb_smscconn.c:650
Counter * split_msg_counter
Definition: bb_smscconn.c:159
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define gwthread_create(func, arg)
Definition: gwthread.h:90
static regex_t * white_list_receiver_regex
Definition: bb_smscconn.c:146
static Octstr * white_list_sender_url
Definition: bb_smscconn.c:136
static Numhash * white_list_receiver
Definition: bb_smscconn.c:142
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:759
Definition: octstr.c:118
static long sms_resend_frequency
Definition: bb_smscconn.c:152
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:742
#define panic
Definition: log.h:87
Definition: cfg.c:73
int smpp_pdu_init(Cfg *cfg)
Definition: smpp_pdu.c:184
#define gwlist_create()
Definition: list.h:136
SMSCConn * smscconn_create(CfgGroup *grp, int start_as_stopped)
Definition: smscconn.c:210
void gw_rwlock_init_static(RWLock *lock)
Definition: gw-rwlock.c:96
static Octstr * unified_prefix
Definition: bb_smscconn.c:132
static Octstr * black_list_sender_url
Definition: bb_smscconn.c:135
static Octstr * white_list_receiver_url
Definition: bb_smscconn.c:138
CfgGroup * cfg_get_single_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:639
void gwlist_add_producer(List *list)
Definition: list.c:383
static regex_t * black_list_sender_regex
Definition: bb_smscconn.c:145
static volatile sig_atomic_t smsc_running
Definition: bb_smscconn.c:127
static volatile sig_atomic_t handle_concatenated_mo
Definition: bb_smscconn.c:162
static Numhash * black_list_receiver
Definition: bb_smscconn.c:141
static List * smsc_list
Definition: bb_smscconn.c:128

◆ smsc2_status()

Octstr* smsc2_status ( int  status_type)

Definition at line 1362 of file bb_smscconn.c.

References bb_status_linebreak(), BBSTATUS_HTML, BBSTATUS_TEXT, BBSTATUS_WML, BBSTATUS_XML, gw_rwlock_rdlock(), gw_rwlock_unlock(), gwlist_get(), gwlist_len(), smscconn::incoming_dlr_load, smscconn::incoming_sms_load, info(), load_get(), octstr_append(), octstr_append_cstr(), octstr_create, octstr_format(), octstr_format_append(), octstr_imm(), smscconn::outgoing_dlr_load, smscconn::outgoing_sms_load, smsc_list, smsc_list_lock, smsc_running, SMSCCONN_ACTIVE, SMSCCONN_ACTIVE_RECV, smscconn_admin_id(), SMSCCONN_CONNECTING, SMSCCONN_DEAD, SMSCCONN_DISCONNECTED, smscconn_id(), smscconn_info(), smscconn_name(), and SMSCCONN_RECONNECTING.

Referenced by bb_print_status().

1363 {
1364  Octstr *tmp;
1365  char tmp3[64];
1366  char *lb;
1367  long i;
1368  int para = 0;
1369  SMSCConn *conn;
1370  StatusInfo info;
1371  const Octstr *conn_id = NULL;
1372  const Octstr *conn_admin_id = NULL;
1373  const Octstr *conn_name = NULL;
1374  float incoming_sms_load_0, incoming_sms_load_1, incoming_sms_load_2;
1375  float outgoing_sms_load_0, outgoing_sms_load_1, outgoing_sms_load_2;
1376  float incoming_dlr_load_0, incoming_dlr_load_1, incoming_dlr_load_2;
1377  float outgoing_dlr_load_0, outgoing_dlr_load_1, outgoing_dlr_load_2;
1378 
1379  if ((lb = bb_status_linebreak(status_type)) == NULL)
1380  return octstr_create("Un-supported format");
1381 
1382  if (status_type == BBSTATUS_HTML || status_type == BBSTATUS_WML)
1383  para = 1;
1384 
1385  if (!smsc_running) {
1386  if (status_type == BBSTATUS_XML)
1387  return octstr_create ("<smscs>\n\t<count>0</count>\n</smscs>");
1388  else
1389  return octstr_format("%sNo SMSC connections%s\n\n", para ? "<p>" : "",
1390  para ? "</p>" : "");
1391  }
1392 
1393  if (status_type != BBSTATUS_XML)
1394  tmp = octstr_format("%sSMSC connections:%s", para ? "<p>" : "", lb);
1395  else
1396  tmp = octstr_format("<smscs><count>%d</count>\n\t", gwlist_len(smsc_list));
1397 
1399  for (i = 0; i < gwlist_len(smsc_list); i++) {
1400  incoming_sms_load_0 = incoming_sms_load_1 = incoming_sms_load_2 = 0.0;
1401  outgoing_sms_load_0 = outgoing_sms_load_1 = outgoing_sms_load_2 = 0.0;
1402  incoming_dlr_load_0 = incoming_dlr_load_1 = incoming_dlr_load_2 = 0.0;
1403  outgoing_dlr_load_0 = outgoing_dlr_load_1 = outgoing_dlr_load_2 = 0.0;
1404  conn = gwlist_get(smsc_list, i);
1405 
1406  if ((smscconn_info(conn, &info) == -1)) {
1407  /*
1408  * we do not delete SMSCs from the list
1409  * this way we can show in the status which links are dead
1410  */
1411  continue;
1412  }
1413 
1414  conn_id = conn ? smscconn_id(conn) : octstr_imm("unknown");
1415  conn_id = conn_id ? conn_id : octstr_imm("unknown");
1416  conn_admin_id = conn ? smscconn_admin_id(conn) : octstr_imm("unknown");
1417  conn_admin_id = conn_admin_id ? conn_admin_id : octstr_imm("unknown");
1418  conn_name = conn ? smscconn_name(conn) : octstr_imm("unknown");
1419 
1420  if (status_type == BBSTATUS_HTML) {
1421  octstr_append_cstr(tmp, "&nbsp;&nbsp;&nbsp;&nbsp;<b>");
1422  octstr_append(tmp, conn_id);
1423  octstr_append_cstr(tmp, "</b>[");
1424  octstr_append(tmp, conn_admin_id);
1425  octstr_append_cstr(tmp, "]&nbsp;&nbsp;&nbsp;&nbsp;");
1426  } else if (status_type == BBSTATUS_TEXT) {
1427  octstr_append_cstr(tmp, " ");
1428  octstr_append(tmp, conn_id);
1429  octstr_append_cstr(tmp, "[");
1430  octstr_append(tmp, conn_admin_id);
1431  octstr_append_cstr(tmp, "] ");
1432  }
1433  if (status_type == BBSTATUS_XML) {
1434  octstr_append_cstr(tmp, "<smsc>\n\t\t<name>");
1435  octstr_append(tmp, conn_name);
1436  octstr_append_cstr(tmp, "</name>\n\t\t<admin-id>");
1437  octstr_append(tmp, conn_admin_id);
1438  octstr_append_cstr(tmp, "</admin-id>\n\t\t<id>");
1439  octstr_append(tmp, conn_id);
1440  octstr_append_cstr(tmp, "</id>\n\t\t");
1441  } else
1442  octstr_append(tmp, conn_name);
1443 
1444  switch (info.status) {
1445  case SMSCCONN_ACTIVE:
1446  case SMSCCONN_ACTIVE_RECV:
1447  sprintf(tmp3, "online %lds", info.online);
1448  incoming_sms_load_0 = load_get(conn->incoming_sms_load,0);
1449  incoming_sms_load_1 = load_get(conn->incoming_sms_load,1);
1450  incoming_sms_load_2 = load_get(conn->incoming_sms_load,2);
1451  outgoing_sms_load_0 = load_get(conn->outgoing_sms_load,0);
1452  outgoing_sms_load_1 = load_get(conn->outgoing_sms_load,1);
1453  outgoing_sms_load_2 = load_get(conn->outgoing_sms_load,2);
1454  incoming_dlr_load_0 = load_get(conn->incoming_dlr_load,0);
1455  incoming_dlr_load_1 = load_get(conn->incoming_dlr_load,1);
1456  incoming_dlr_load_2 = load_get(conn->incoming_dlr_load,2);
1457  outgoing_dlr_load_0 = load_get(conn->outgoing_dlr_load,0);
1458  outgoing_dlr_load_1 = load_get(conn->outgoing_dlr_load,1);
1459  outgoing_dlr_load_2 = load_get(conn->outgoing_dlr_load,2);
1460  break;
1461  case SMSCCONN_DISCONNECTED:
1462  sprintf(tmp3, "disconnected");
1463  break;
1464  case SMSCCONN_CONNECTING:
1465  sprintf(tmp3, "connecting");
1466  break;
1467  case SMSCCONN_RECONNECTING:
1468  sprintf(tmp3, "re-connecting");
1469  break;
1470  case SMSCCONN_DEAD:
1471  sprintf(tmp3, "dead");
1472  break;
1473  default:
1474  sprintf(tmp3, "unknown");
1475  break;
1476  }
1477 
1478  if (status_type == BBSTATUS_XML)
1479  octstr_format_append(tmp, "<status>%s</status>\n"
1480  "\t\t<failed>%ld</failed>\n"
1481  "\t\t<queued>%ld</queued>\n"
1482  "\t\t<sms>\n"
1483  "\t\t\t<received>%ld</received>\n"
1484  "\t\t\t<sent>%ld</sent>\n"
1485  "\t\t\t<inbound>%.2f,%.2f,%.2f</inbound>\n"
1486  "\t\t\t<outbound>%.2f,%.2f,%.2f</outbound>\n"
1487  "\t\t</sms>\n\t\t<dlr>\n"
1488  "\t\t\t<received>%ld</received>\n"
1489  "\t\t\t<sent>%ld</sent>\n"
1490  "\t\t\t<inbound>%.2f,%.2f,%.2f</inbound>\n"
1491  "\t\t\t<outbound>%.2f,%.2f,%.2f</outbound>\n"
1492  "\t\t</dlr>\n"
1493  "\t</smsc>\n", tmp3,
1494  info.failed, info.queued, info.received, info.sent,
1495  incoming_sms_load_0, incoming_sms_load_1, incoming_sms_load_2,
1496  outgoing_sms_load_0, outgoing_sms_load_1, outgoing_sms_load_2,
1497  info.received_dlr, info.sent_dlr,
1498  incoming_dlr_load_0, incoming_dlr_load_1, incoming_dlr_load_2,
1499  outgoing_dlr_load_0, outgoing_dlr_load_1, outgoing_dlr_load_2);
1500  else
1501  octstr_format_append(tmp, " (%s, rcvd: sms %ld (%.2f,%.2f,%.2f) / dlr %ld (%.2f,%.2f,%.2f), "
1502  "sent: sms %ld (%.2f,%.2f,%.2f) / dlr %ld (%.2f,%.2f,%.2f), failed %ld, "
1503  "queued %ld msgs)%s",
1504  tmp3,
1505  info.received,
1506  incoming_sms_load_0, incoming_sms_load_1, incoming_sms_load_2,
1507  info.received_dlr,
1508  incoming_dlr_load_0, incoming_dlr_load_1, incoming_dlr_load_2,
1509  info.sent,
1510  outgoing_sms_load_0, outgoing_sms_load_1, outgoing_sms_load_2,
1511  info.sent_dlr,
1512  outgoing_dlr_load_0, outgoing_dlr_load_1, outgoing_dlr_load_2,
1513  info.failed,
1514  info.queued,
1515  lb);
1516  }
1517 
1519 
1520  if (para)
1521  octstr_append_cstr(tmp, "</p>");
1522  if (status_type == BBSTATUS_XML)
1523  octstr_append_cstr(tmp, "</smscs>\n");
1524  else
1525  octstr_append_cstr(tmp, "\n\n");
1526  return tmp;
1527 }
Load * incoming_sms_load
Definition: smscconn_p.h:216
void info(int err, const char *fmt,...)
Definition: log.c:672
char * bb_status_linebreak(int status_type)
Definition: bearerbox.c:1109
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
static RWLock smsc_list_lock
Definition: bb_smscconn.c:129
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
const Octstr * smscconn_name(SMSCConn *conn)
Definition: smscconn.c:552
int gw_rwlock_rdlock(RWLock *lock)
Definition: gw-rwlock.c:134
void octstr_append_cstr(Octstr *ostr, const char *cstr)
Definition: octstr.c:1511
double load_get(Load *load, int pos)
Definition: load.c:191
Load * outgoing_sms_load
Definition: smscconn_p.h:215
const Octstr * smscconn_admin_id(SMSCConn *conn)
Definition: smscconn.c:566
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
const Octstr * smscconn_id(SMSCConn *conn)
Definition: smscconn.c:559
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
#define octstr_create(cstr)
Definition: octstr.h:125
Definition: octstr.c:118
Load * outgoing_dlr_load
Definition: smscconn_p.h:218
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2507
Load * incoming_dlr_load
Definition: smscconn_p.h:217
int smscconn_info(SMSCConn *conn, StatusInfo *infotable)
Definition: smscconn.c:732
static volatile sig_atomic_t smsc_running
Definition: bb_smscconn.c:127
static List * smsc_list
Definition: bb_smscconn.c:128

◆ smsc2_stop_smsc()

int smsc2_stop_smsc ( Octstr id)

Definition at line 968 of file bb_smscconn.c.

References error(), gw_rwlock_rdlock(), gw_rwlock_unlock(), gwlist_get(), info(), octstr_get_cstr, smsc2_find(), smsc_list, smsc_list_lock, smsc_running, SMSCCONN_DEAD, smscconn_shutdown(), and smscconn_status().

Referenced by bb_stop_smsc().

969 {
970  SMSCConn *conn;
971  long i = -1;
972  int success = 0;
973 
974  if (!smsc_running)
975  return -1;
976 
978  /* find the specific smsc via id */
979  while((i = smsc2_find(id, ++i)) != -1) {
980  conn = gwlist_get(smsc_list, i);
981  if (conn != NULL && smscconn_status(conn) == SMSCCONN_DEAD) {
982  info(0, "HTTP: Could not shutdown already dead smsc-id `%s'",
983  octstr_get_cstr(id));
984  } else {
985  info(0,"HTTP: Shutting down smsc-id `%s'", octstr_get_cstr(id));
986  smscconn_shutdown(conn, 1); /* shutdown the smsc */
987  success = 1;
988  }
989  }
991  if (success == 0) {
992  error(0, "SMSC %s not found", octstr_get_cstr(id));
993  return -1;
994  }
995  return 0;
996 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void info(int err, const char *fmt,...)
Definition: log.c:672
void smscconn_shutdown(SMSCConn *conn, int finish_sending)
Definition: smscconn.c:427
static RWLock smsc_list_lock
Definition: bb_smscconn.c:129
void * gwlist_get(List *list, long pos)
Definition: list.c:292
int gw_rwlock_rdlock(RWLock *lock)
Definition: gw-rwlock.c:134
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
int smscconn_status(SMSCConn *conn)
Definition: smscconn.c:724
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
static volatile sig_atomic_t smsc_running
Definition: bb_smscconn.c:127
static List * smsc_list
Definition: bb_smscconn.c:128
static long smsc2_find(Octstr *id, long start)
Definition: bb_smscconn.c:948

◆ smsc2_suspend()

void smsc2_suspend ( void  )

Definition at line 1259 of file bb_smscconn.c.

References gw_rwlock_rdlock(), gw_rwlock_unlock(), gwlist_get(), gwlist_len(), smsc_list, smsc_list_lock, smsc_running, and smscconn_stop().

Referenced by bb_isolate(), and bb_suspend().

1260 {
1261  SMSCConn *conn;
1262  long i;
1263 
1264  if (!smsc_running)
1265  return;
1266 
1268  for (i = 0; i < gwlist_len(smsc_list); i++) {
1269  conn = gwlist_get(smsc_list, i);
1270  smscconn_stop(conn);
1271  }
1273 }
static RWLock smsc_list_lock
Definition: bb_smscconn.c:129
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
int gw_rwlock_rdlock(RWLock *lock)
Definition: gw-rwlock.c:134
int smscconn_stop(SMSCConn *conn)
Definition: smscconn.c:516
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
static volatile sig_atomic_t smsc_running
Definition: bb_smscconn.c:127
static List * smsc_list
Definition: bb_smscconn.c:128

Variable Documentation

◆ bb_status

volatile sig_atomic_t bb_status

Definition at line 132 of file bearerbox.c.

Referenced by sms_router(), and smsc2_rout().

◆ black_list_receiver

Numhash* black_list_receiver
static

◆ black_list_receiver_regex

regex_t* black_list_receiver_regex
static

Definition at line 147 of file bb_smscconn.c.

Referenced by bb_smscconn_receive(), smsc2_cleanup(), smsc2_rout(), and smsc2_start().

◆ black_list_receiver_url

Octstr* black_list_receiver_url
static

Definition at line 137 of file bb_smscconn.c.

Referenced by smsc2_cleanup(), smsc2_reload_lists(), and smsc2_start().

◆ black_list_sender

Numhash* black_list_sender
static

◆ black_list_sender_regex

regex_t* black_list_sender_regex
static

Definition at line 145 of file bb_smscconn.c.

Referenced by bb_smscconn_receive(), smsc2_cleanup(), smsc2_rout(), and smsc2_start().

◆ black_list_sender_url

Octstr* black_list_sender_url
static

Definition at line 135 of file bb_smscconn.c.

Referenced by smsc2_cleanup(), smsc2_reload_lists(), and smsc2_start().

◆ cfg_filename

Octstr* cfg_filename

Definition at line 130 of file bearerbox.c.

Referenced by bb_graceful_restart(), bb_reload_smsc_groups(), and main().

◆ cfg_reloaded

Cfg* cfg_reloaded
static

Definition at line 130 of file bb_smscconn.c.

Referenced by bb_reload_smsc_groups(), and smsc2_start().

◆ concat_lock

◆ concatenated_mo_timeout

long concatenated_mo_timeout
static

Definition at line 164 of file bb_smscconn.c.

Referenced by concat_handling_clear_old_parts(), sms_router(), and smsc2_start().

◆ flow_threads

List* flow_threads

Definition at line 116 of file bearerbox.c.

Referenced by bb_smscconn_killed(), bb_smscconn_ready(), and sms_router().

◆ handle_concatenated_mo

volatile sig_atomic_t handle_concatenated_mo
static

◆ incoming_concat_msgs

◆ incoming_dlr_counter

Counter* incoming_dlr_counter

◆ incoming_dlr_load

Load* incoming_dlr_load

◆ incoming_sms

◆ incoming_sms_counter

Counter* incoming_sms_counter

◆ incoming_sms_load

◆ isolated

List* isolated

Definition at line 127 of file bearerbox.c.

◆ max_incoming_sms_qlength

long max_incoming_sms_qlength

Definition at line 98 of file bearerbox.c.

Referenced by concat_handling_init(), and init_bearerbox().

◆ max_outgoing_sms_qlength

long max_outgoing_sms_qlength

Definition at line 99 of file bearerbox.c.

Referenced by init_bearerbox(), and smsc2_rout().

◆ outgoing_dlr_counter

Counter* outgoing_dlr_counter

Definition at line 93 of file bearerbox.c.

Referenced by bb_print_status(), bb_smscconn_sent(), empty_msg_lists(), and init_bearerbox().

◆ outgoing_dlr_load

Load* outgoing_dlr_load

Definition at line 105 of file bearerbox.c.

Referenced by bb_print_status(), bb_smscconn_sent(), empty_msg_lists(), and init_bearerbox().

◆ outgoing_sms

◆ outgoing_sms_counter

Counter* outgoing_sms_counter

Definition at line 91 of file bearerbox.c.

Referenced by bb_print_status(), bb_smscconn_sent(), empty_msg_lists(), and init_bearerbox().

◆ outgoing_sms_load

Load* outgoing_sms_load

Definition at line 102 of file bearerbox.c.

Referenced by bb_print_status(), bb_smscconn_sent(), empty_msg_lists(), and init_bearerbox().

◆ router_thread

long router_thread = -1
static

◆ sms_resend_frequency

long sms_resend_frequency
static

Definition at line 152 of file bb_smscconn.c.

Referenced by sms_router(), and smsc2_start().

◆ sms_resend_retry

long sms_resend_retry
static

Definition at line 153 of file bb_smscconn.c.

Referenced by bb_smscconn_send_failed(), handle_split(), and smsc2_start().

◆ smsc_groups

◆ smsc_list

◆ smsc_list_lock

◆ smsc_running

◆ split_msg_counter

Counter* split_msg_counter

Definition at line 159 of file bb_smscconn.c.

Referenced by smsc2_cleanup(), smsc2_start(), and smscconn_send().

◆ suspended

List* suspended

Definition at line 122 of file bearerbox.c.

◆ unified_prefix

Octstr* unified_prefix
static

Definition at line 132 of file bb_smscconn.c.

Referenced by bb_smscconn_receive(), smsc2_cleanup(), smsc2_rout(), and smsc2_start().

◆ white_black_list_lock

RWLock white_black_list_lock
static

◆ white_list_receiver

Numhash* white_list_receiver
static

◆ white_list_receiver_regex

regex_t* white_list_receiver_regex
static

Definition at line 146 of file bb_smscconn.c.

Referenced by bb_smscconn_receive(), smsc2_cleanup(), smsc2_rout(), and smsc2_start().

◆ white_list_receiver_url

Octstr* white_list_receiver_url
static

Definition at line 138 of file bb_smscconn.c.

Referenced by smsc2_cleanup(), smsc2_reload_lists(), and smsc2_start().

◆ white_list_sender

Numhash* white_list_sender
static

◆ white_list_sender_regex

regex_t* white_list_sender_regex
static

Definition at line 144 of file bb_smscconn.c.

Referenced by bb_smscconn_receive(), smsc2_cleanup(), smsc2_rout(), and smsc2_start().

◆ white_list_sender_url

Octstr* white_list_sender_url
static

Definition at line 136 of file bb_smscconn.c.

Referenced by smsc2_cleanup(), smsc2_reload_lists(), and smsc2_start().

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.