Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
smscconn.h File Reference
#include "gwlib/gwlib.h"
#include "gw/msg.h"

Go to the source code of this file.

Data Structures

struct  smsc_state
 

Typedefs

typedef struct smscconn SMSCConn
 
typedef struct smsc_state StatusInfo
 

Enumerations

enum  smscconn_status_t {
  SMSCCONN_CONNECTING, SMSCCONN_ACTIVE, SMSCCONN_ACTIVE_RECV, SMSCCONN_RECONNECTING,
  SMSCCONN_DISCONNECTED, SMSCCONN_DEAD
}
 
enum  smscconn_killed_t { SMSCCONN_ALIVE = 0, SMSCCONN_KILLED_WRONG_PASSWORD = 1, SMSCCONN_KILLED_CANNOT_CONNECT = 2, SMSCCONN_KILLED_SHUTDOWN = 3 }
 

Functions

SMSCConnsmscconn_create (CfgGroup *cfg, int start_as_stopped)
 
void smscconn_shutdown (SMSCConn *smscconn, int finish_sending)
 
int smscconn_destroy (SMSCConn *smscconn)
 
int smscconn_stop (SMSCConn *smscconn)
 
void smscconn_start (SMSCConn *smscconn)
 
const Octstrsmscconn_name (SMSCConn *smscconn)
 
const Octstrsmscconn_id (SMSCConn *conn)
 
const Octstrsmscconn_admin_id (SMSCConn *conn)
 
int smscconn_usable (SMSCConn *conn, Msg *msg)
 
int smscconn_send (SMSCConn *smsccconn, Msg *msg)
 
int smscconn_status (SMSCConn *smscconn)
 
int smscconn_info (SMSCConn *smscconn, StatusInfo *infotable)
 
unsigned int smscconn_instances (CfgGroup *grp)
 
void smscconn_reconfig (SMSCConn *conn, CfgGroup *grp)
 

Typedef Documentation

typedef struct smscconn SMSCConn

Definition at line 94 of file smscconn.h.

typedef struct smsc_state StatusInfo

Enumeration Type Documentation

Enumerator
SMSCCONN_ALIVE 
SMSCCONN_KILLED_WRONG_PASSWORD 
SMSCCONN_KILLED_CANNOT_CONNECT 
SMSCCONN_KILLED_SHUTDOWN 

Definition at line 105 of file smscconn.h.

Enumerator
SMSCCONN_CONNECTING 
SMSCCONN_ACTIVE 
SMSCCONN_ACTIVE_RECV 
SMSCCONN_RECONNECTING 
SMSCCONN_DISCONNECTED 
SMSCCONN_DEAD 

Definition at line 96 of file smscconn.h.

Function Documentation

const Octstr* smscconn_admin_id ( SMSCConn conn)

Definition at line 507 of file smscconn.c.

References smscconn::admin_id, and gw_assert().

Referenced by smsc2_status().

508 {
509  gw_assert(conn != NULL);
510  return conn->admin_id;
511 }
Octstr * admin_id
Definition: smscconn_p.h:176
gw_assert(wtls_machine->packet_to_send!=NULL)
SMSCConn* smscconn_create ( CfgGroup cfg,
int  start_as_stopped 
)

Definition at line 162 of file smscconn.c.

References smscconn::admin_id, smscconn::allowed_prefix, smscconn::allowed_prefix_regex, smscconn::allowed_smsc_id, smscconn::allowed_smsc_id_regex, smscconn::alt_dcs, bb_smscconn_ready(), cfg_get, cfg_get_bool(), cfg_get_group_checksum(), cfg_get_integer(), smscconn::chksum, smscconn::chksum_conn, smscconn::connect_time, counter_create(), smscconn::dead_start, smscconn::denied_prefix, smscconn::denied_prefix_regex, smscconn::denied_smsc_id, smscconn::denied_smsc_id_regex, error(), smscconn::failed, smscconn::flow_mutex, GET_OPTIONAL_VAL, gw_assert(), GW_EXCL, smscconn::id, smscconn::incoming_dlr_load, smscconn::incoming_sms_load, info(), init_reroute(), smscconn::is_stopped, load_add_interval(), load_create, smscconn::log_file, smscconn::log_idx, smscconn::log_level, log_open(), MAX_SMS_OCTETS, smscconn::max_sms_octets, mutex_create, OCTSTR, octstr_compare(), octstr_destroy(), octstr_duplicate, octstr_get_cstr, octstr_imm(), octstr_parse_double(), smscconn::our_host, smscconn::outgoing_dlr_load, smscconn::outgoing_sms_load, panic, smscconn::preferred_prefix, smscconn::preferred_prefix_regex, smscconn::preferred_smsc_id, smscconn::received, smscconn::received_dlr, smscconn::reconnect_delay, smscconn::send_msg, smscconn::sent, smscconn::sent_dlr, smsc_at2_create(), smsc_cgw_create(), smsc_cimd2_create(), smsc_emi2_create(), smsc_fake_create(), smsc_http_create(), smsc_loopback_create(), smsc_oisd_create(), smsc_smasi_create(), smsc_smpp_create(), smsc_wrapper_create(), SMSCCONN_ALIVE, SMSCCONN_CONNECTING, smscconn_destroy(), SMSCCONN_RECONNECT_DELAY, SPLIT_OPTIONAL_VAL, smscconn::status, smscconn::throughput, smscconn::unified_prefix, warning(), and smscconn::why_killed.

Referenced by smsc2_add_smsc(), smsc2_graceful_restart(), smsc2_restart_smsc(), and smsc2_start().

163 {
164  SMSCConn *conn;
165  Octstr *smsc_type;
166  int ret;
167  Octstr *allowed_smsc_id_regex;
168  Octstr *denied_smsc_id_regex;
169  Octstr *allowed_prefix_regex;
170  Octstr *denied_prefix_regex;
171  Octstr *preferred_prefix_regex;
172  Octstr *tmp;
173 
174  if (grp == NULL)
175  return NULL;
176 
177  conn = gw_malloc(sizeof(*conn));
178  memset(conn, 0, sizeof(*conn));
179 
180  conn->why_killed = SMSCCONN_ALIVE;
181  conn->status = SMSCCONN_CONNECTING;
182  conn->connect_time = -1;
183  conn->is_stopped = start_as_stopped;
184 
185 #define OCTSTR(os) octstr_imm(#os)
186 
187  /* checksum of the whole config, without instance multiplier */
188  conn->chksum = cfg_get_group_checksum(grp,
189  NULL
190  );
191 
192  /* checksum of the connection related part, without routing
193  * and without instance multiplier */
195  OCTSTR(denied-smsc-id),
196  OCTSTR(allowed-smsc-id),
197  OCTSTR(preferred-smsc-id),
198  OCTSTR(allowed-prefix),
199  OCTSTR(denied-prefix),
200  OCTSTR(preferred-prefix),
201  OCTSTR(unified-prefix),
202  OCTSTR(reroute),
203  OCTSTR(reroute-smsc-id),
204  OCTSTR(reroute-receiver),
205  OCTSTR(reroute-dlr),
206  OCTSTR(allowed-smsc-id-regex),
207  OCTSTR(denied-smsc-id-regex),
208  OCTSTR(preferred-smsc-id-regex),
209  OCTSTR(allowed-prefix-regex),
210  OCTSTR(denied-prefix-regex),
211  OCTSTR(preferred-prefix-regex),
212  NULL
213  );
214 
215  conn->received = counter_create();
216  conn->received_dlr = counter_create();
217  conn->sent = counter_create();
218  conn->sent_dlr = counter_create();
219  conn->failed = counter_create();
220  conn->flow_mutex = mutex_create();
221 
222  conn->outgoing_sms_load = load_create();
223  /* add 60,300,-1 entries */
227 
228  conn->incoming_sms_load = load_create();
229  /* add 60,300,-1 entries */
233 
234  conn->incoming_dlr_load = load_create();
235  /* add 60,300,-1 entries to dlr */
239 
240  conn->outgoing_dlr_load = load_create();
241  /* add 60,300,-1 entries to dlr */
245 
246 
247 #define GET_OPTIONAL_VAL(x, n) x = cfg_get(grp, octstr_imm(n))
248 #define SPLIT_OPTIONAL_VAL(x, n) \
249  do { \
250  Octstr *tmp = cfg_get(grp, octstr_imm(n)); \
251  if (tmp) x = octstr_split(tmp, octstr_imm(";")); \
252  else x = NULL; \
253  octstr_destroy(tmp); \
254  }while(0)
255 
256  GET_OPTIONAL_VAL(conn->id, "smsc-id");
257  SPLIT_OPTIONAL_VAL(conn->allowed_smsc_id, "allowed-smsc-id");
258  SPLIT_OPTIONAL_VAL(conn->denied_smsc_id, "denied-smsc-id");
259  SPLIT_OPTIONAL_VAL(conn->preferred_smsc_id, "preferred-smsc-id");
260  GET_OPTIONAL_VAL(conn->allowed_prefix, "allowed-prefix");
261  GET_OPTIONAL_VAL(conn->denied_prefix, "denied-prefix");
262  GET_OPTIONAL_VAL(conn->preferred_prefix, "preferred-prefix");
263  GET_OPTIONAL_VAL(conn->unified_prefix, "unified-prefix");
264  GET_OPTIONAL_VAL(conn->our_host, "our-host");
265  GET_OPTIONAL_VAL(conn->log_file, "log-file");
266  cfg_get_bool(&conn->alt_dcs, grp, octstr_imm("alt-dcs"));
267 
268  GET_OPTIONAL_VAL(allowed_smsc_id_regex, "allowed-smsc-id-regex");
269  if (allowed_smsc_id_regex != NULL)
270  if ((conn->allowed_smsc_id_regex = gw_regex_comp(allowed_smsc_id_regex, REG_EXTENDED)) == NULL)
271  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(allowed_smsc_id_regex));
272  GET_OPTIONAL_VAL(denied_smsc_id_regex, "denied-smsc-id-regex");
273  if (denied_smsc_id_regex != NULL)
274  if ((conn->denied_smsc_id_regex = gw_regex_comp(denied_smsc_id_regex, REG_EXTENDED)) == NULL)
275  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(denied_smsc_id_regex));
276  GET_OPTIONAL_VAL(allowed_prefix_regex, "allowed-prefix-regex");
277  if (allowed_prefix_regex != NULL)
278  if ((conn->allowed_prefix_regex = gw_regex_comp(allowed_prefix_regex, REG_EXTENDED)) == NULL)
279  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(allowed_prefix_regex));
280  GET_OPTIONAL_VAL(denied_prefix_regex, "denied-prefix-regex");
281  if (denied_prefix_regex != NULL)
282  if ((conn->denied_prefix_regex = gw_regex_comp(denied_prefix_regex, REG_EXTENDED)) == NULL)
283  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(denied_prefix_regex));
284  GET_OPTIONAL_VAL(preferred_prefix_regex, "preferred-prefix-regex");
285  if (preferred_prefix_regex != NULL)
286  if ((conn->preferred_prefix_regex = gw_regex_comp(preferred_prefix_regex, REG_EXTENDED)) == NULL)
287  panic(0, "Could not compile pattern '%s'", octstr_get_cstr(preferred_prefix_regex));
288 
289  if ((tmp = cfg_get(grp, octstr_imm("throughput"))) != NULL) {
290  if (octstr_parse_double(&conn->throughput, tmp, 0) == -1)
291  conn->throughput = 0;
292  octstr_destroy(tmp);
293  info(0, "Set throughput to %.3f for smsc id <%s>", conn->throughput, octstr_get_cstr(conn->id));
294  }
295  /* Sets the admin_id. Equals to connection id if empty */
296  GET_OPTIONAL_VAL(conn->admin_id, "smsc-admin-id");
297  if (conn->admin_id == NULL)
298  conn->admin_id = octstr_duplicate(conn->id);
299 
300  /* configure the internal rerouting rules for this smsc id */
301  init_reroute(conn, grp);
302 
303  if (cfg_get_integer(&conn->log_level, grp, octstr_imm("log-level")) == -1)
304  conn->log_level = 0;
305 
306  if (cfg_get_integer(&conn->max_sms_octets, grp, octstr_imm("max-sms-octets")) == -1)
308 
309  if (cfg_get_bool(&conn->dead_start, grp, octstr_imm("dead-start")) == -1)
310  conn->dead_start = 0; /* default to connect at start-up time */
311 
312  /* open a smsc-id specific log-file in exlusive mode */
313  if (conn->log_file)
314  conn->log_idx = log_open(octstr_get_cstr(conn->log_file),
315  conn->log_level, GW_EXCL);
316 #undef GET_OPTIONAL_VAL
317 #undef SPLIT_OPTIONAL_VAL
318 
319  if (conn->allowed_smsc_id && conn->denied_smsc_id)
320  warning(0, "Both 'allowed-smsc-id' and 'denied-smsc-id' set, deny-list "
321  "automatically ignored");
322  if (conn->allowed_smsc_id_regex && conn->denied_smsc_id_regex)
323  warning(0, "Both 'allowed-smsc-id_regex' and 'denied-smsc-id_regex' set, deny-regex "
324  "automatically ignored");
325 
326  if (cfg_get_integer(&conn->reconnect_delay, grp,
327  octstr_imm("reconnect-delay")) == -1)
329 
330  smsc_type = cfg_get(grp, octstr_imm("smsc"));
331  if (smsc_type == NULL) {
332  error(0, "Required field 'smsc' missing for smsc group.");
333  smscconn_destroy(conn);
334  octstr_destroy(smsc_type);
335  return NULL;
336  }
337 
338  if (octstr_compare(smsc_type, octstr_imm("fake")) == 0)
339  ret = smsc_fake_create(conn, grp);
340  else if (octstr_compare(smsc_type, octstr_imm("cimd2")) == 0)
341  ret = smsc_cimd2_create(conn, grp);
342  else if (octstr_compare(smsc_type, octstr_imm("emi")) == 0)
343  ret = smsc_emi2_create(conn, grp);
344  else if (octstr_compare(smsc_type, octstr_imm("http")) == 0)
345  ret = smsc_http_create(conn, grp);
346  else if (octstr_compare(smsc_type, octstr_imm("smpp")) == 0)
347  ret = smsc_smpp_create(conn, grp);
348  else if (octstr_compare(smsc_type, octstr_imm("at")) == 0)
349  ret = smsc_at2_create(conn,grp);
350  else if (octstr_compare(smsc_type, octstr_imm("cgw")) == 0)
351  ret = smsc_cgw_create(conn,grp);
352  else if (octstr_compare(smsc_type, octstr_imm("smasi")) == 0)
353  ret = smsc_smasi_create(conn, grp);
354  else if (octstr_compare(smsc_type, octstr_imm("oisd")) == 0)
355  ret = smsc_oisd_create(conn, grp);
356  else if (octstr_compare(smsc_type, octstr_imm("loopback")) == 0)
357  ret = smsc_loopback_create(conn, grp);
358 #ifdef HAVE_GSOAP
359  else if (octstr_compare(smsc_type, octstr_imm("parlayx")) == 0)
360  ret = smsc_soap_parlayx_create(conn, grp);
361 #endif
362  else
363  ret = smsc_wrapper_create(conn, grp);
364 
365  octstr_destroy(smsc_type);
366  if (ret == -1) {
367  smscconn_destroy(conn);
368  return NULL;
369  }
370  gw_assert(conn->send_msg != NULL);
371 
372  bb_smscconn_ready(conn);
373 
374  return conn;
375 }
Load * incoming_sms_load
Definition: smscconn_p.h:215
void error(int err, const char *fmt,...)
Definition: log.c:612
int smsc_oisd_create(SMSCConn *conn, CfgGroup *grp)
Definition: smsc_oisd.c:1498
void info(int err, const char *fmt,...)
Definition: log.c:636
#define MAX_SMS_OCTETS
Definition: sms.h:129
int smsc_cgw_create(SMSCConn *conn, CfgGroup *cfg)
Definition: smsc_cgw.c:431
regex_t * allowed_smsc_id_regex
Definition: smscconn_p.h:180
long max_sms_octets
Definition: smscconn_p.h:212
void bb_smscconn_ready(SMSCConn *conn)
Definition: bb_smscconn.c:185
int smscconn_destroy(SMSCConn *conn)
Definition: smscconn.c:406
int smsc_cimd2_create(SMSCConn *conn, CfgGroup *grp)
Definition: smsc_cimd2.c:2321
int alt_dcs
Definition: smscconn_p.h:201
int dead_start
Definition: smscconn_p.h:210
Octstr * id
Definition: smscconn_p.h:174
Counter * failed
Definition: smscconn_p.h:166
#define mutex_create()
Definition: thread.h:96
Octstr * denied_prefix
Definition: smscconn_p.h:186
int load_add_interval(Load *load, int interval)
Definition: load.c:111
Octstr * cfg_get_group_checksum(CfgGroup *grp,...)
Definition: cfg.c:663
int log_idx
Definition: smscconn_p.h:197
int smsc_emi2_create(SMSCConn *conn, CfgGroup *cfg)
Definition: smsc_emi.c:1612
#define cfg_get(grp, varname)
Definition: cfg.h:86
Octstr * allowed_prefix
Definition: smscconn_p.h:184
Octstr * our_host
Definition: smscconn_p.h:192
int smsc_wrapper_create(SMSCConn *conn, CfgGroup *cfg)
Definition: smsc_wrapper.c:397
long log_level
Definition: smscconn_p.h:196
List * denied_smsc_id
Definition: smscconn_p.h:178
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
int smsc_http_create(SMSCConn *conn, CfgGroup *cfg)
Definition: smsc_http.c:881
#define OCTSTR(os)
Definition: log.h:74
long reconnect_delay
Definition: smscconn_p.h:199
int smsc_at2_create(SMSCConn *conn, CfgGroup *cfg)
Definition: smsc_at.c:1519
long octstr_parse_double(double *nump, Octstr *ostr, long pos)
Definition: octstr.c:780
regex_t * preferred_prefix_regex
Definition: smscconn_p.h:189
Octstr * log_file
Definition: smscconn_p.h:195
#define SPLIT_OPTIONAL_VAL(x, n)
Load * outgoing_sms_load
Definition: smscconn_p.h:214
int smsc_smasi_create(SMSCConn *conn, CfgGroup *config)
Definition: smsc_smasi.c:1129
smscconn_killed_t why_killed
Definition: smscconn_p.h:153
regex_t * allowed_prefix_regex
Definition: smscconn_p.h:185
Counter * sent
Definition: smscconn_p.h:164
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Counter * received_dlr
Definition: smscconn_p.h:163
Counter * counter_create(void)
Definition: counter.c:94
Octstr * chksum_conn
Definition: smscconn_p.h:172
Octstr * admin_id
Definition: smscconn_p.h:176
List * preferred_smsc_id
Definition: smscconn_p.h:179
Octstr * unified_prefix
Definition: smscconn_p.h:190
Octstr * chksum
Definition: smscconn_p.h:171
time_t connect_time
Definition: smscconn_p.h:155
#define octstr_duplicate(ostr)
Definition: octstr.h:187
double throughput
Definition: smscconn_p.h:203
int smsc_loopback_create(SMSCConn *conn, CfgGroup *cfg)
Mutex * flow_mutex
Definition: smscconn_p.h:157
static void init_reroute(SMSCConn *conn, CfgGroup *grp)
Definition: smscconn.c:87
Octstr * preferred_prefix
Definition: smscconn_p.h:188
regex_t * denied_prefix_regex
Definition: smscconn_p.h:187
void warning(int err, const char *fmt,...)
Definition: log.c:624
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
gw_assert(wtls_machine->packet_to_send!=NULL)
#define load_create()
Definition: load.h:78
#define GET_OPTIONAL_VAL(x, n)
#define SMSCCONN_RECONNECT_DELAY
Definition: smscconn.c:80
volatile sig_atomic_t is_stopped
Definition: smscconn_p.h:169
List * allowed_smsc_id
Definition: smscconn_p.h:177
int smsc_smpp_create(SMSCConn *conn, CfgGroup *grp)
Definition: smsc_smpp.c:2561
Counter * received
Definition: smscconn_p.h:162
int smsc_fake_create(SMSCConn *conn, CfgGroup *cfg)
Definition: smsc_fake.c:534
Counter * sent_dlr
Definition: smscconn_p.h:165
int log_open(char *filename, int level, enum excl_state excl)
Definition: log.c:339
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:756
Definition: octstr.c:118
Load * outgoing_dlr_load
Definition: smscconn_p.h:217
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:739
#define panic
Definition: log.h:87
smscconn_status_t status
Definition: smscconn_p.h:151
Load * incoming_dlr_load
Definition: smscconn_p.h:216
int(* send_msg)(SMSCConn *conn, Msg *msg)
Definition: smscconn_p.h:235
regex_t * denied_smsc_id_regex
Definition: smscconn_p.h:181
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
int smscconn_destroy ( SMSCConn smscconn)

Definition at line 406 of file smscconn.c.

References smscconn::admin_id, smscconn::allowed_prefix, smscconn::allowed_prefix_regex, smscconn::allowed_smsc_id, smscconn::allowed_smsc_id_regex, smscconn::chksum, smscconn::chksum_conn, counter_destroy(), smscconn::denied_prefix, smscconn::denied_prefix_regex, smscconn::denied_smsc_id, smscconn::denied_smsc_id_regex, dict_destroy(), smscconn::failed, smscconn::flow_mutex, gwlist_destroy(), smscconn::id, smscconn::incoming_dlr_load, smscconn::incoming_sms_load, load_destroy(), smscconn::log_file, mutex_destroy(), mutex_lock, mutex_unlock, smscconn::name, octstr_destroy(), octstr_destroy_item(), smscconn::our_host, smscconn::outgoing_dlr_load, smscconn::outgoing_sms_load, smscconn::preferred_prefix, smscconn::preferred_prefix_regex, smscconn::preferred_smsc_id, smscconn::received, smscconn::received_dlr, smscconn::reroute_by_receiver, smscconn::reroute_to_smsc, smscconn::sent, smscconn::sent_dlr, SMSCCONN_DEAD, smscconn::status, and smscconn::unified_prefix.

Referenced by smsc2_cleanup(), smsc2_graceful_restart(), smsc2_remove_smsc(), smsc2_restart_smsc(), and smscconn_create().

407 {
408  if (conn == NULL)
409  return 0;
410  if (conn->status != SMSCCONN_DEAD)
411  return -1;
412  mutex_lock(conn->flow_mutex);
413 
414  counter_destroy(conn->received);
415  counter_destroy(conn->received_dlr);
416  counter_destroy(conn->sent);
417  counter_destroy(conn->sent_dlr);
418  counter_destroy(conn->failed);
419 
420  load_destroy(conn->incoming_sms_load);
421  load_destroy(conn->incoming_dlr_load);
422  load_destroy(conn->outgoing_sms_load);
423  load_destroy(conn->outgoing_dlr_load);
424 
425  octstr_destroy(conn->name);
426  octstr_destroy(conn->id);
427  octstr_destroy(conn->admin_id);
428  gwlist_destroy(conn->allowed_smsc_id, octstr_destroy_item);
429  gwlist_destroy(conn->denied_smsc_id, octstr_destroy_item);
430  gwlist_destroy(conn->preferred_smsc_id, octstr_destroy_item);
431  octstr_destroy(conn->denied_prefix);
432  octstr_destroy(conn->allowed_prefix);
433  octstr_destroy(conn->preferred_prefix);
434  octstr_destroy(conn->unified_prefix);
435  octstr_destroy(conn->our_host);
436  octstr_destroy(conn->log_file);
437  octstr_destroy(conn->chksum);
438  octstr_destroy(conn->chksum_conn);
439 
440  if (conn->denied_smsc_id_regex != NULL) gw_regex_destroy(conn->denied_smsc_id_regex);
441  if (conn->allowed_smsc_id_regex != NULL) gw_regex_destroy(conn->allowed_smsc_id_regex);
442  if (conn->preferred_prefix_regex != NULL) gw_regex_destroy(conn->preferred_prefix_regex);
443  if (conn->denied_prefix_regex != NULL) gw_regex_destroy(conn->denied_prefix_regex);
444  if (conn->allowed_prefix_regex != NULL) gw_regex_destroy(conn->allowed_prefix_regex);
445 
446  octstr_destroy(conn->reroute_to_smsc);
447  dict_destroy(conn->reroute_by_receiver);
448 
449  mutex_unlock(conn->flow_mutex);
450  mutex_destroy(conn->flow_mutex);
451 
452  gw_free(conn);
453  return 0;
454 }
void counter_destroy(Counter *counter)
Definition: counter.c:110
#define mutex_unlock(m)
Definition: thread.h:136
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
void octstr_destroy_item(void *os)
Definition: octstr.c:334
void mutex_destroy(Mutex *mutex)
Definition: thread.c:97
void dict_destroy(Dict *dict)
Definition: dict.c:215
void load_destroy(Load *load)
Definition: load.c:145
#define mutex_lock(m)
Definition: thread.h:130
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
const Octstr* smscconn_id ( SMSCConn conn)

Definition at line 500 of file smscconn.c.

References gw_assert(), and smscconn::id.

Referenced by bb_alog_sms(), get_pattern(), and smsc2_status().

501 {
502  gw_assert(conn != NULL);
503  return conn->id;
504 }
Octstr * id
Definition: smscconn_p.h:174
gw_assert(wtls_machine->packet_to_send!=NULL)
int smscconn_info ( SMSCConn smscconn,
StatusInfo infotable 
)

Definition at line 673 of file smscconn.c.

References smscconn::connect_time, counter_value(), smsc_state::failed, smscconn::failed, smscconn::flow_mutex, smsc_state::is_stopped, smscconn::is_stopped, smsc_state::killed, smsc_state::load, smscconn::load, mutex_lock, mutex_unlock, smsc_state::online, smsc_state::queued, smscconn::queued, smsc_state::received, smscconn::received, smsc_state::received_dlr, smscconn::received_dlr, smsc_state::sent, smscconn::sent, smsc_state::sent_dlr, smscconn::sent_dlr, smsc_state::status, smscconn::status, and smscconn::why_killed.

Referenced by smsc2_rout(), and smsc2_status().

674 {
675  if (conn == NULL || infotable == NULL)
676  return -1;
677 
678  mutex_lock(conn->flow_mutex);
679 
680  infotable->status = conn->status;
681  infotable->killed = conn->why_killed;
682  infotable->is_stopped = conn->is_stopped;
683  infotable->online = time(NULL) - conn->connect_time;
684 
685  infotable->sent = counter_value(conn->sent);
686  infotable->received = counter_value(conn->received);
687  infotable->sent_dlr = counter_value(conn->sent_dlr);
688  infotable->received_dlr = counter_value(conn->received_dlr);
689  infotable->failed = counter_value(conn->failed);
690 
691  if (conn->queued)
692  infotable->queued = conn->queued(conn);
693  else
694  infotable->queued = -1;
695 
696  infotable->load = conn->load;
697 
698  mutex_unlock(conn->flow_mutex);
699 
700  return 0;
701 }
long online
Definition: smscconn.h:122
unsigned long received_dlr
Definition: smscconn.h:117
#define mutex_unlock(m)
Definition: thread.h:136
smscconn_status_t status
Definition: smscconn.h:113
smscconn_killed_t killed
Definition: smscconn.h:114
unsigned long sent_dlr
Definition: smscconn.h:119
long queued
Definition: smscconn.h:121
unsigned long sent
Definition: smscconn.h:118
unsigned long failed
Definition: smscconn.h:120
int is_stopped
Definition: smscconn.h:115
unsigned long counter_value(Counter *counter)
Definition: counter.c:145
int load
Definition: smscconn.h:123
#define mutex_lock(m)
Definition: thread.h:130
unsigned long received
Definition: smscconn.h:116
unsigned int smscconn_instances ( CfgGroup grp)

Definition at line 149 of file smscconn.c.

References cfg_get_integer(), and octstr_imm().

Referenced by smsc2_graceful_restart(), and smsc2_start().

150 {
151  long i;
152 
153  if (cfg_get_integer(&i, grp, octstr_imm("instances")) == -1)
154  i = 1;
155  else if (i < 0)
156  i = 0;
157 
158  return i;
159 }
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:739
const Octstr* smscconn_name ( SMSCConn smscconn)

Definition at line 493 of file smscconn.c.

References gw_assert(), and smscconn::name.

Referenced by bb_alog_sms(), get_pattern(), and smsc2_status().

494 {
495  gw_assert(conn != NULL);
496  return conn->name;
497 }
gw_assert(wtls_machine->packet_to_send!=NULL)
void smscconn_reconfig ( SMSCConn conn,
CfgGroup grp 
)

Definition at line 704 of file smscconn.c.

References smscconn::allowed_prefix, smscconn::allowed_prefix_regex, smscconn::allowed_smsc_id, smscconn::allowed_smsc_id_regex, cfg_get_group_checksum(), smscconn::chksum, smscconn::denied_prefix, smscconn::denied_prefix_regex, smscconn::denied_smsc_id, smscconn::denied_smsc_id_regex, dict_destroy(), GET_OPTIONAL_REGEX, GET_OPTIONAL_VAL, gw_assert(), init_reroute(), octstr_destroy(), smscconn::preferred_prefix, smscconn::preferred_prefix_regex, smscconn::preferred_smsc_id, smscconn::preferred_smsc_id_regex, smscconn::reroute_by_receiver, smscconn::reroute_to_smsc, SPLIT_OPTIONAL_VAL, and smscconn::unified_prefix.

Referenced by smsc2_graceful_restart().

705 {
706  Octstr *tmp;
707 
708  gw_assert(conn != NULL);
709 
710  if (grp == NULL)
711  return;
712 
713 #define GET_OPTIONAL_VAL(x, n) \
714  octstr_destroy(x); \
715  x = cfg_get(grp, octstr_imm(n))
716 #define SPLIT_OPTIONAL_VAL(x, n) \
717  gwlist_destroy(x, octstr_destroy_item); \
718  if ((tmp = cfg_get(grp, octstr_imm(n))) != NULL) \
719  x = octstr_split(tmp, octstr_imm(";")); \
720  else \
721  x = NULL; \
722  octstr_destroy(tmp);
723 #define GET_OPTIONAL_REGEX(x, n) \
724  gw_regex_destroy(x); \
725  if ((tmp = cfg_get(grp, octstr_imm(n))) != NULL) { \
726  if ((x = gw_regex_comp(tmp, REG_EXTENDED)) == NULL) \
727  error(0, "Could not compile pattern '%s'", octstr_get_cstr(tmp)); \
728  octstr_destroy(tmp); \
729  }
730 
731  SPLIT_OPTIONAL_VAL(conn->allowed_smsc_id, "allowed-smsc-id");
732  SPLIT_OPTIONAL_VAL(conn->denied_smsc_id, "denied-smsc-id");
733  SPLIT_OPTIONAL_VAL(conn->preferred_smsc_id, "preferred-smsc-id");
734  GET_OPTIONAL_VAL(conn->allowed_prefix, "allowed-prefix");
735  GET_OPTIONAL_VAL(conn->denied_prefix, "denied-prefix");
736  GET_OPTIONAL_VAL(conn->preferred_prefix, "preferred-prefix");
737  GET_OPTIONAL_VAL(conn->unified_prefix, "unified-prefix");
738  GET_OPTIONAL_REGEX(conn->allowed_smsc_id_regex, "allowed-smsc-id-regex");
739  GET_OPTIONAL_REGEX(conn->denied_smsc_id_regex, "denied-smsc-id-regex");
740  GET_OPTIONAL_REGEX(conn->preferred_smsc_id_regex, "preferred-smsc-id-regex");
741  GET_OPTIONAL_REGEX(conn->allowed_prefix_regex, "allowed-prefix-regex");
742  GET_OPTIONAL_REGEX(conn->denied_prefix_regex, "denied-prefix-regex");
743  GET_OPTIONAL_REGEX(conn->preferred_prefix_regex, "preferred-prefix-regex");
744 
747  init_reroute(conn, grp);
748 
749  /*
750  * Since we applied changes, we need to re-compute
751  * at least the overall checksum. The other one
752  * is not changed as the routing values are excluded.
753  * also the checksum hash values.
754  */
755  octstr_destroy(conn->chksum);
756  conn->chksum = cfg_get_group_checksum(grp, NULL);
757 }
regex_t * allowed_smsc_id_regex
Definition: smscconn_p.h:180
Octstr * denied_prefix
Definition: smscconn_p.h:186
Octstr * cfg_get_group_checksum(CfgGroup *grp,...)
Definition: cfg.c:663
Octstr * allowed_prefix
Definition: smscconn_p.h:184
Dict * reroute_by_receiver
Definition: smscconn_p.h:207
List * denied_smsc_id
Definition: smscconn_p.h:178
regex_t * preferred_prefix_regex
Definition: smscconn_p.h:189
#define SPLIT_OPTIONAL_VAL(x, n)
regex_t * allowed_prefix_regex
Definition: smscconn_p.h:185
regex_t * preferred_smsc_id_regex
Definition: smscconn_p.h:182
Octstr * reroute_to_smsc
Definition: smscconn_p.h:208
List * preferred_smsc_id
Definition: smscconn_p.h:179
Octstr * unified_prefix
Definition: smscconn_p.h:190
Octstr * chksum
Definition: smscconn_p.h:171
static void init_reroute(SMSCConn *conn, CfgGroup *grp)
Definition: smscconn.c:87
Octstr * preferred_prefix
Definition: smscconn_p.h:188
regex_t * denied_prefix_regex
Definition: smscconn_p.h:187
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
gw_assert(wtls_machine->packet_to_send!=NULL)
#define GET_OPTIONAL_VAL(x, n)
List * allowed_smsc_id
Definition: smscconn_p.h:177
void dict_destroy(Dict *dict)
Definition: dict.c:215
Definition: octstr.c:118
regex_t * denied_smsc_id_regex
Definition: smscconn_p.h:181
#define GET_OPTIONAL_REGEX(x, n)
int smscconn_send ( SMSCConn smsccconn,
Msg msg 
)

Definition at line 596 of file smscconn.c.

References counter_create(), counter_destroy(), counter_increase(), counter_increase_with(), counter_set(), debug(), smscconn::flow_mutex, gw_assert(), gwlist_destroy(), gwlist_get(), gwlist_len(), smscconn::max_sms_octets, msg_destroy_item(), msg_duplicate(), mutex_lock, mutex_unlock, normalize_number(), octstr_get_cstr, split_parts::orig, split_parts::parts_left, smscconn::send_msg, sms_split(), split_parts::smsc_conn, SMSCCONN_ALIVE, SMSCCONN_DEAD, SMSCCONN_FAILED_REJECTED, SMSCCONN_SUCCESS, split, split_parts::status, smscconn::status, smscconn::unified_prefix, warning(), and smscconn::why_killed.

Referenced by smsc2_rout().

597 {
598  int ret = -1;
599  List *parts = NULL;
600 
601  gw_assert(conn != NULL);
602  mutex_lock(conn->flow_mutex);
603  if (conn->status == SMSCCONN_DEAD || conn->why_killed != SMSCCONN_ALIVE) {
604  mutex_unlock(conn->flow_mutex);
605  return -1;
606  }
607 
608  /* if this a retry of splitted message, don't unify prefix and don't try to split */
609  if (msg->sms.split_parts == NULL) {
610  /* normalize the destination number for this smsc */
611  char *uf = conn->unified_prefix ? octstr_get_cstr(conn->unified_prefix) : NULL;
612  normalize_number(uf, &(msg->sms.receiver));
613 
614  /* split msg */
615  parts = sms_split(msg, NULL, NULL, NULL, NULL, 1,
616  counter_increase(split_msg_counter) & 0xff, 0xff, conn->max_sms_octets);
617  if (gwlist_len(parts) == 1) {
618  /* don't create split_parts of sms fit into one */
620  parts = NULL;
621  }
622  }
623 
624  if (parts == NULL)
625  ret = conn->send_msg(conn, msg);
626  else {
627  long i, parts_len = gwlist_len(parts);
628  struct split_parts *split = gw_malloc(sizeof(*split));
629  /* must duplicate, because smsc2_route will destroy this msg */
630  split->orig = msg_duplicate(msg);
631  split->parts_left = counter_create();
632  split->status = SMSCCONN_SUCCESS;
633  counter_set(split->parts_left, parts_len);
634  split->smsc_conn = conn;
635  debug("bb.sms.splits", 0, "new split_parts created %p", split);
636  for (i = 0; i < parts_len; i++) {
637  msg = gwlist_get(parts, i);
638  msg->sms.split_parts = split;
639  ret = conn->send_msg(conn, msg);
640  if (ret < 0) {
641  if (i == 0) {
642  counter_destroy(split->parts_left);
644  gw_free(split);
645  mutex_unlock(conn->flow_mutex);
646  return ret;
647  }
648  /*
649  * Some parts were sent. So handle this within
650  * bb_smscconn_XXX().
651  */
653  counter_increase_with(split->parts_left, -(parts_len - i));
654  warning(0, "Could not send all parts of a split message");
655  break;
656  }
657  }
659  }
660  mutex_unlock(conn->flow_mutex);
661  return ret;
662 }
Counter * parts_left
Definition: msg.h:94
Msg * msg_duplicate(Msg *msg)
Definition: msg.c:111
void counter_destroy(Counter *counter)
Definition: counter.c:110
#define mutex_unlock(m)
Definition: thread.h:136
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
unsigned long counter_set(Counter *counter, unsigned long n)
Definition: counter.c:167
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
List * sms_split(Msg *orig, Octstr *header, Octstr *footer, Octstr *nonlast_suffix, Octstr *split_chars, int catenate, unsigned long msg_sequence, int max_messages, int max_octets)
Definition: sms.c:309
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
long status
Definition: msg.h:96
void msg_destroy_item(void *msg)
Definition: msg.c:147
Counter * counter_create(void)
Definition: counter.c:94
unsigned long counter_increase_with(Counter *counter, unsigned long value)
Definition: counter.c:134
void warning(int err, const char *fmt,...)
Definition: log.c:624
gw_assert(wtls_machine->packet_to_send!=NULL)
void * smsc_conn
Definition: msg.h:98
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static List * split
Definition: test_http.c:88
Msg * orig
Definition: msg.h:92
int normalize_number(char *dial_prefixes, Octstr **number)
Definition: utils.c:882
#define mutex_lock(m)
Definition: thread.h:130
Definition: list.c:102
Counter * split_msg_counter
Definition: bb_smscconn.c:159
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
void smscconn_shutdown ( SMSCConn smscconn,
int  finish_sending 
)

Definition at line 378 of file smscconn.c.

References smscconn::flow_mutex, gw_assert(), mutex_lock, mutex_unlock, smscconn::shutdown, SMSCCONN_DEAD, SMSCCONN_KILLED_SHUTDOWN, smscconn::status, and smscconn::why_killed.

Referenced by sms_receive(), sms_send(), smsc2_add_smsc(), smsc2_graceful_restart(), smsc2_remove_smsc(), smsc2_resume(), smsc2_shutdown(), and smsc2_stop_smsc().

379 {
380  gw_assert(conn != NULL);
381 
382  mutex_lock(conn->flow_mutex);
383  if (conn->status == SMSCCONN_DEAD) {
384  mutex_unlock(conn->flow_mutex);
385  return;
386  }
387 
388  /* Call SMSC specific destroyer */
389  if (conn->shutdown) {
390  /*
391  * we must unlock here, because module manipulate their state
392  * and will try to lock this mutex.Otherwise we have deadlock!
393  */
394  mutex_unlock(conn->flow_mutex);
395  conn->shutdown(conn, finish_sending);
396  }
397  else {
398  conn->why_killed = SMSCCONN_KILLED_SHUTDOWN;
399  mutex_unlock(conn->flow_mutex);
400  }
401 
402  return;
403 }
#define mutex_unlock(m)
Definition: thread.h:136
gw_assert(wtls_machine->packet_to_send!=NULL)
#define mutex_lock(m)
Definition: thread.h:130
void smscconn_start ( SMSCConn smscconn)

Definition at line 477 of file smscconn.c.

References smscconn::flow_mutex, gw_assert(), smscconn::is_stopped, mutex_lock, mutex_unlock, SMSCCONN_DEAD, smscconn::start_conn, and smscconn::status.

Referenced by smsc2_add_smsc(), smsc2_graceful_restart(), smsc2_restart_smsc(), and smsc2_resume().

478 {
479  gw_assert(conn != NULL);
480  mutex_lock(conn->flow_mutex);
481  if (conn->status == SMSCCONN_DEAD || conn->is_stopped == 0) {
482  mutex_unlock(conn->flow_mutex);
483  return;
484  }
485  conn->is_stopped = 0;
486  mutex_unlock(conn->flow_mutex);
487 
488  if (conn->start_conn)
489  conn->start_conn(conn);
490 }
#define mutex_unlock(m)
Definition: thread.h:136
gw_assert(wtls_machine->packet_to_send!=NULL)
#define mutex_lock(m)
Definition: thread.h:130
int smscconn_status ( SMSCConn smscconn)

Definition at line 665 of file smscconn.c.

References gw_assert(), and smscconn::status.

Referenced by bb_smscconn_send_failed(), handle_split(), smsc2_restart_smsc(), and smsc2_stop_smsc().

666 {
667  gw_assert(conn != NULL);
668 
669  return conn->status;
670 }
gw_assert(wtls_machine->packet_to_send!=NULL)
int smscconn_stop ( SMSCConn smscconn)

Definition at line 457 of file smscconn.c.

References smscconn::flow_mutex, gw_assert(), smscconn::is_stopped, mutex_lock, mutex_unlock, SMSCCONN_ALIVE, SMSCCONN_DEAD, smscconn::status, smscconn::stop_conn, and smscconn::why_killed.

Referenced by smsc2_suspend().

458 {
459  gw_assert(conn != NULL);
460  mutex_lock(conn->flow_mutex);
461  if (conn->status == SMSCCONN_DEAD || conn->is_stopped != 0
462  || conn->why_killed != SMSCCONN_ALIVE)
463  {
464  mutex_unlock(conn->flow_mutex);
465  return -1;
466  }
467  conn->is_stopped = 1;
468  mutex_unlock(conn->flow_mutex);
469 
470  if (conn->stop_conn)
471  conn->stop_conn(conn);
472 
473  return 0;
474 }
#define mutex_unlock(m)
Definition: thread.h:136
gw_assert(wtls_machine->packet_to_send!=NULL)
#define mutex_lock(m)
Definition: thread.h:130
int smscconn_usable ( SMSCConn conn,
Msg msg 
)

Definition at line 514 of file smscconn.c.

References smscconn::allowed_prefix, smscconn::allowed_prefix_regex, smscconn::allowed_smsc_id, smscconn::allowed_smsc_id_regex, smscconn::denied_prefix, smscconn::denied_prefix_regex, smscconn::denied_smsc_id, smscconn::denied_smsc_id_regex, does_prefix_match(), gw_assert(), gwlist_search(), octstr_item_match(), smscconn::preferred_prefix, smscconn::preferred_prefix_regex, smscconn::preferred_smsc_id, SMSCCONN_ACTIVE_RECV, SMSCCONN_ALIVE, SMSCCONN_DEAD, smscconn::status, and smscconn::why_killed.

Referenced by smsc2_rout().

515 {
516  gw_assert(conn != NULL);
517  gw_assert(msg != NULL && msg_type(msg) == sms);
518 
519  /* dead transmitter or active receiver connections are not feasible */
520  if (conn->status == SMSCCONN_DEAD || conn->status == SMSCCONN_ACTIVE_RECV ||
521  conn->why_killed != SMSCCONN_ALIVE)
522  return -1;
523 
524  /* if allowed-smsc-id set, then only allow this SMSC if message
525  * smsc-id matches any of its allowed SMSCes
526  */
527  if (conn->allowed_smsc_id && (msg->sms.smsc_id == NULL ||
528  gwlist_search(conn->allowed_smsc_id, msg->sms.smsc_id, octstr_item_match) == NULL)) {
529  return -1;
530  }
531  /* ..if no allowed-smsc-id set but denied-smsc-id and message smsc-id
532  * is set, deny message if smsc-ids match */
533  else if (conn->denied_smsc_id && msg->sms.smsc_id != NULL &&
534  gwlist_search(conn->denied_smsc_id, msg->sms.smsc_id, octstr_item_match) != NULL) {
535  return -1;
536  }
537 
538  if (conn->allowed_smsc_id_regex) {
539  if (msg->sms.smsc_id == NULL)
540  return -1;
541 
542  if (gw_regex_match_pre(conn->allowed_smsc_id_regex, msg->sms.smsc_id) == 0)
543  return -1;
544  }
545  else if (conn->denied_smsc_id_regex && msg->sms.smsc_id != NULL) {
546  if (gw_regex_match_pre(conn->denied_smsc_id_regex, msg->sms.smsc_id) == 1)
547  return -1;
548  }
549 
550  /* Have allowed */
551  if (conn->allowed_prefix && !conn->denied_prefix &&
552  (does_prefix_match(conn->allowed_prefix, msg->sms.receiver) != 1))
553  return -1;
554 
555  if (conn->allowed_prefix_regex && !conn->denied_prefix_regex &&
556  gw_regex_match_pre(conn->allowed_prefix_regex, msg->sms.receiver) == 0)
557  return -1;
558 
559  /* Have denied */
560  if (conn->denied_prefix && !conn->allowed_prefix &&
561  (does_prefix_match(conn->denied_prefix, msg->sms.receiver) == 1))
562  return -1;
563 
564  if (conn->denied_prefix_regex && !conn->allowed_prefix_regex &&
565  gw_regex_match_pre(conn->denied_prefix_regex, msg->sms.receiver) == 1)
566  return -1;
567 
568  /* Have allowed and denied */
569  if (conn->denied_prefix && conn->allowed_prefix &&
570  (does_prefix_match(conn->allowed_prefix, msg->sms.receiver) != 1) &&
571  (does_prefix_match(conn->denied_prefix, msg->sms.receiver) == 1))
572  return -1;
573 
574  if (conn->allowed_prefix_regex && conn->denied_prefix_regex &&
575  gw_regex_match_pre(conn->allowed_prefix_regex, msg->sms.receiver) == 0 &&
576  gw_regex_match_pre(conn->denied_prefix_regex, msg->sms.receiver) == 1)
577  return -1;
578 
579  /* then see if it is preferred one */
580  if (conn->preferred_smsc_id && msg->sms.smsc_id != NULL &&
581  gwlist_search(conn->preferred_smsc_id, msg->sms.smsc_id, octstr_item_match) != NULL)
582  return 1;
583 
584  if (conn->preferred_prefix &&
585  does_prefix_match(conn->preferred_prefix, msg->sms.receiver) == 1)
586  return 1;
587 
588  if (conn->preferred_prefix_regex &&
589  gw_regex_match_pre(conn->preferred_prefix_regex, msg->sms.receiver) == 1)
590  return 1;
591 
592  return 0;
593 }
regex_t * allowed_smsc_id_regex
Definition: smscconn_p.h:180
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
Definition: list.c:486
Octstr * denied_prefix
Definition: smscconn_p.h:186
msg_type
Definition: msg.h:73
Octstr * allowed_prefix
Definition: smscconn_p.h:184
List * denied_smsc_id
Definition: smscconn_p.h:178
regex_t * preferred_prefix_regex
Definition: smscconn_p.h:189
smscconn_killed_t why_killed
Definition: smscconn_p.h:153
regex_t * allowed_prefix_regex
Definition: smscconn_p.h:185
int does_prefix_match(Octstr *prefix, Octstr *number)
Definition: utils.c:850
List * preferred_smsc_id
Definition: smscconn_p.h:179
int octstr_item_match(void *item, void *pattern)
Definition: octstr.c:1659
Octstr * preferred_prefix
Definition: smscconn_p.h:188
regex_t * denied_prefix_regex
Definition: smscconn_p.h:187
gw_assert(wtls_machine->packet_to_send!=NULL)
List * allowed_smsc_id
Definition: smscconn_p.h:177
smscconn_status_t status
Definition: smscconn_p.h:151
regex_t * denied_smsc_id_regex
Definition: smscconn_p.h:181
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.