Kannel: Open Source WAP and SMS gateway  svn-r5335
smsc_wrapper.c File Reference
#include "gwlib/gwlib.h"
#include "smscconn.h"
#include "smscconn_p.h"
#include "bb_smscconn_cb.h"
#include "smsc.h"
#include "smsc_p.h"

Go to the source code of this file.

Data Structures

struct  smsc_wrapper
 

Typedefs

typedef struct smsc_wrapper SmscWrapper
 

Functions

static void smscwrapper_destroy (SmscWrapper *wrap)
 
static int reconnect (SMSCConn *conn)
 
static Msgsms_receive (SMSCConn *conn)
 
static void wrapper_receiver (void *arg)
 
static int sms_send (SMSCConn *conn, Msg *msg)
 
static void wrapper_sender (void *arg)
 
static int wrapper_add_msg (SMSCConn *conn, Msg *sms)
 
static int wrapper_shutdown (SMSCConn *conn, int finish_sending)
 
static void wrapper_stop (SMSCConn *conn)
 
static void wrapper_start (SMSCConn *conn)
 
static long wrapper_queued (SMSCConn *conn)
 
int smsc_wrapper_create (SMSCConn *conn, CfgGroup *cfg)
 

Typedef Documentation

◆ SmscWrapper

typedef struct smsc_wrapper SmscWrapper

Function Documentation

◆ reconnect()

static int reconnect ( SMSCConn conn)
static

Definition at line 97 of file smsc_wrapper.c.

References bb_smscconn_connected(), bb_smscconn_send_failed(), smscconn::connect_time, smscconn::data, debug(), error(), smscconn::flow_mutex, gwlist_extract_first(), gwthread_sleep(), info(), msg, mutex_lock, mutex_unlock, smscconn::name, octstr_get_cstr, smsc_wrapper::outgoing_queue, smsc_wrapper::reconnect_mutex, smsc_wrapper::smsc, smsc_reopen(), SMSCCONN_ACTIVE, SMSCCONN_ALIVE, SMSCCONN_DISCONNECTED, SMSCCONN_FAILED_TEMPORARILY, SMSCCONN_RECONNECTING, smscconn::status, and smscconn::why_killed.

Referenced by at2_device_thread(), sms_receive(), and sms_send().

98 {
99  SmscWrapper *wrap = conn->data;
100  Msg *msg;
101  int ret;
102  int wait = 1;
103 
104  /* disable double-reconnect
105  * NOTE: it is still possible that we do double-connect if
106  * first thread gets through this if-statement and then
107  * execution switches to another thread.. this can be avoided
108  * via double-mutex system, but I do not feel it is worth it,
109  * maybe later --rpr
110  */
111  if (conn->status == SMSCCONN_RECONNECTING) {
112  mutex_lock(wrap->reconnect_mutex); /* wait here */
114  return 0;
115  }
117 
118  debug("bb.sms", 0, "smsc_wrapper <%s>: reconnect started",
119  octstr_get_cstr(conn->name));
120 
121  while((msg = gwlist_extract_first(wrap->outgoing_queue))!=NULL) {
123  }
125 
126 
127  while(conn->why_killed == SMSCCONN_ALIVE) {
128  ret = smsc_reopen(wrap->smsc);
129  if (ret == 0) {
130  info(0, "Re-open of %s succeeded.", octstr_get_cstr(conn->name));
131  mutex_lock(conn->flow_mutex);
132  conn->status = SMSCCONN_ACTIVE;
133  conn->connect_time = time(NULL);
134  mutex_unlock(conn->flow_mutex);
135  bb_smscconn_connected(conn);
136  break;
137  }
138  else if (ret == -2) {
139  error(0, "Re-open of %s failed permanently",
140  octstr_get_cstr(conn->name));
141  mutex_lock(conn->flow_mutex);
144  mutex_unlock(conn->flow_mutex);
145  return -1; /* permanent failure */
146  }
147  else {
148  error(0, "Re-open to <%s> failed, retrying after %d minutes...",
149  octstr_get_cstr(conn->name), wait);
150  gwthread_sleep(wait*60.0);
151 
152  wait = wait > 10 ? 10 : wait * 2 + 1;
153  }
154  }
156  return 0;
157 }
Octstr * name
Definition: smscconn_p.h:173
void error(int err, const char *fmt,...)
Definition: log.c:648
void info(int err, const char *fmt,...)
Definition: log.c:672
void bb_smscconn_connected(SMSCConn *conn)
Definition: bb_smscconn.c:192
List * outgoing_queue
Definition: smsc_wrapper.c:76
#define mutex_unlock(m)
Definition: thread.h:136
void * data
Definition: smscconn_p.h:250
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Mutex * reconnect_mutex
Definition: smsc_wrapper.c:80
SMSCenter * smsc
Definition: smsc_wrapper.c:75
smscconn_killed_t why_killed
Definition: smscconn_p.h:153
Definition: msg.h:79
void * gwlist_extract_first(List *list)
Definition: list.c:305
int smsc_reopen(SMSCenter *smsc)
Definition: smsc.c:610
time_t connect_time
Definition: smscconn_p.h:155
Mutex * flow_mutex
Definition: smscconn_p.h:157
void gwthread_sleep(double seconds)
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
smscconn_status_t status
Definition: smscconn_p.h:151
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
Definition: bb_smscconn.c:329
#define mutex_lock(m)
Definition: thread.h:130
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ sms_receive()

static Msg* sms_receive ( SMSCConn conn)
static

Definition at line 160 of file smsc_wrapper.c.

References smscconn::data, smscconn::id, msg_destroy(), smscconn::name, octstr_duplicate, octstr_get_cstr, reconnect(), smsc_wrapper::smsc, smscconn_shutdown(), smscenter_pending_smsmessage(), smscenter_receive_msg(), and warning().

Referenced by wrapper_receiver().

161 {
162  SmscWrapper *wrap = conn->data;
163  int ret;
164  Msg *newmsg = NULL;
165 
166  if (smscenter_pending_smsmessage(wrap->smsc) == 1) {
167 
168  ret = smscenter_receive_msg(wrap->smsc, &newmsg);
169  if (ret == 1) {
170 
171  /* if any smsc_id available, use it */
172  newmsg->sms.smsc_id = octstr_duplicate(conn->id);
173 
174  return newmsg;
175  } else if (ret == 0) { /* "NEVER" happens */
176  warning(0, "SMSC %s: Pending message returned '1', "
177  "but nothing to receive!", octstr_get_cstr(conn->name));
178  msg_destroy(newmsg);
179  return NULL;
180  } else {
181  msg_destroy(newmsg);
182  if (reconnect(conn) == -1)
183  smscconn_shutdown(conn, 0);
184  return NULL;
185  }
186  }
187  return NULL;
188 }
Octstr * name
Definition: smscconn_p.h:173
void smscconn_shutdown(SMSCConn *conn, int finish_sending)
Definition: smscconn.c:427
Octstr * id
Definition: smscconn_p.h:174
void * data
Definition: smscconn_p.h:250
static int reconnect(SMSCConn *conn)
Definition: smsc_wrapper.c:97
int smscenter_receive_msg(SMSCenter *smsc, Msg **msg)
Definition: smsc.c:251
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
SMSCenter * smsc
Definition: smsc_wrapper.c:75
Definition: msg.h:79
int smscenter_pending_smsmessage(SMSCenter *smsc)
Definition: smsc.c:302
#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

◆ sms_send()

static int sms_send ( SMSCConn conn,
Msg msg 
)
static

Definition at line 235 of file smsc_wrapper.c.

References bb_smscconn_send_failed(), bb_smscconn_sent(), smscconn::data, debug(), msg, smscconn::name, octstr_create, octstr_get_cstr, reconnect(), smsc_wrapper::smsc, SMSCCONN_FAILED_REJECTED, smscconn_shutdown(), and smscenter_submit_msg().

Referenced by wrapper_sender().

236 {
237  SmscWrapper *wrap = conn->data;
238  int ret;
239 
240  debug("bb.sms", 0, "smscconn_sender (%s): sending message",
241  octstr_get_cstr(conn->name));
242 
243  ret = smscenter_submit_msg(wrap->smsc, msg);
244  if (ret == -1) {
247 
248  if (reconnect(conn) == -1)
249  smscconn_shutdown(conn, 0);
250  return -1;
251  } else {
252  bb_smscconn_sent(conn, msg, NULL);
253  return 0;
254  }
255 }
Octstr * name
Definition: smscconn_p.h:173
void smscconn_shutdown(SMSCConn *conn, int finish_sending)
Definition: smscconn.c:427
void * data
Definition: smscconn_p.h:250
static int reconnect(SMSCConn *conn)
Definition: smsc_wrapper.c:97
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
SMSCenter * smsc
Definition: smsc_wrapper.c:75
#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
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
Definition: bb_smscconn.c:329
int smscenter_submit_msg(SMSCenter *smsc, Msg *msg)
Definition: smsc.c:209
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ smsc_wrapper_create()

int smsc_wrapper_create ( SMSCConn conn,
CfgGroup cfg 
)

Definition at line 397 of file smsc_wrapper.c.

References cfg, smscconn::connect_time, smscconn::data, error(), gwlist_add_producer(), gwlist_create, gwthread_create, smscconn::is_stopped, mutex_create, smscconn::name, octstr_create, smsc_wrapper::outgoing_queue, smscconn::queued, smsc_wrapper::receiver_thread, smsc_wrapper::reconnect_mutex, smscconn::send_msg, smsc_wrapper::sender_thread, smscconn::shutdown, smsc_wrapper::smsc, smsc_name(), smsc_open(), SMSCCONN_ACTIVE, SMSCCONN_DEAD, SMSCCONN_KILLED_CANNOT_CONNECT, smscwrapper_destroy(), smscconn::start_conn, smscconn::status, smscconn::stop_conn, smsc_wrapper::stopped, smscconn::why_killed, wrapper_add_msg(), wrapper_queued(), wrapper_receiver(), wrapper_sender(), wrapper_shutdown(), wrapper_start(), and wrapper_stop().

Referenced by smscconn_create().

398 {
399  /* 1. Call smsc_open()
400  * 2. create sender/receiver threads
401  * 3. fill up the conn
402  *
403  * XXX open() SHOULD be done in distinct thread, not here!
404  */
405 
406  SmscWrapper *wrap;
407 
408  wrap = gw_malloc(sizeof(SmscWrapper));
409  wrap->smsc = NULL;
410  conn->data = wrap;
411  conn->send_msg = wrapper_add_msg;
412 
413 
414  wrap->outgoing_queue = gwlist_create();
415  wrap->stopped = gwlist_create();
416  wrap->reconnect_mutex = mutex_create();
418 
419  if ((wrap->smsc = smsc_open(cfg)) == NULL)
420  goto error;
421 
422  conn->name = octstr_create(smsc_name(wrap->smsc));
423  conn->status = SMSCCONN_ACTIVE;
424  conn->connect_time = time(NULL);
425 
426  if (conn->is_stopped)
428 
429 
430  /* XXX here we could fail things... specially if the second one
431  * fails.. so fix this ASAP
432  *
433  * moreover, open should be in sender/receiver, so that we can continue
434  * while trying to open... maybe move this, or just wait for new
435  * implementations of various SMSC protocols
436  */
437 
438  if ((wrap->receiver_thread = gwthread_create(wrapper_receiver, conn))==-1)
439  goto error;
440 
441  if ((wrap->sender_thread = gwthread_create(wrapper_sender, conn))==-1)
442  goto error;
443 
444  conn->shutdown = wrapper_shutdown;
445  conn->queued = wrapper_queued;
446  conn->stop_conn = wrapper_stop;
447  conn->start_conn = wrapper_start;
448 
449  return 0;
450 
451 error:
452  error(0, "Failed to create Smsc wrapper");
453  conn->data = NULL;
454  smscwrapper_destroy(wrap);
456  conn->status = SMSCCONN_DEAD;
457  return -1;
458 }
Octstr * name
Definition: smscconn_p.h:173
void error(int err, const char *fmt,...)
Definition: log.c:648
List * outgoing_queue
Definition: smsc_wrapper.c:76
List * stopped
Definition: smsc_wrapper.c:77
void * data
Definition: smscconn_p.h:250
#define mutex_create()
Definition: thread.h:96
char * smsc_name(SMSCenter *smsc)
Definition: smsc.c:643
void(* stop_conn)(SMSCConn *conn)
Definition: smscconn_p.h:247
static void wrapper_sender(void *arg)
Definition: smsc_wrapper.c:258
long receiver_thread
Definition: smsc_wrapper.c:78
static Cfg * cfg
Definition: opensmppbox.c:95
void(* start_conn)(SMSCConn *conn)
Definition: smscconn_p.h:246
static void wrapper_stop(SMSCConn *conn)
Definition: smsc_wrapper.c:368
Mutex * reconnect_mutex
Definition: smsc_wrapper.c:80
static int wrapper_add_msg(SMSCConn *conn, Msg *sms)
Definition: smsc_wrapper.c:337
SMSCenter * smsc
Definition: smsc_wrapper.c:75
smscconn_killed_t why_killed
Definition: smscconn_p.h:153
SMSCenter * smsc_open(CfgGroup *grp)
Definition: smsc.c:444
static void smscwrapper_destroy(SmscWrapper *wrap)
Definition: smsc_wrapper.c:84
time_t connect_time
Definition: smscconn_p.h:155
static void wrapper_start(SMSCConn *conn)
Definition: smsc_wrapper.c:377
#define gwthread_create(func, arg)
Definition: gwthread.h:90
#define octstr_create(cstr)
Definition: octstr.h:125
static int wrapper_shutdown(SMSCConn *conn, int finish_sending)
Definition: smsc_wrapper.c:349
volatile sig_atomic_t is_stopped
Definition: smscconn_p.h:169
static void wrapper_receiver(void *arg)
Definition: smsc_wrapper.c:191
int(* shutdown)(SMSCConn *conn, int finish_sending)
Definition: smscconn_p.h:230
smscconn_status_t status
Definition: smscconn_p.h:151
#define gwlist_create()
Definition: list.h:136
long(* queued)(SMSCConn *conn)
Definition: smscconn_p.h:241
int(* send_msg)(SMSCConn *conn, Msg *msg)
Definition: smscconn_p.h:236
long sender_thread
Definition: smsc_wrapper.c:79
void gwlist_add_producer(List *list)
Definition: list.c:383
static long wrapper_queued(SMSCConn *conn)
Definition: smsc_wrapper.c:386

◆ smscwrapper_destroy()

static void smscwrapper_destroy ( SmscWrapper wrap)
static

Definition at line 84 of file smsc_wrapper.c.

References gwlist_destroy(), mutex_destroy(), smsc_wrapper::outgoing_queue, smsc_wrapper::reconnect_mutex, smsc_wrapper::smsc, smsc_close(), and smsc_wrapper::stopped.

Referenced by smsc_wrapper_create(), and wrapper_sender().

85 {
86  if (wrap == NULL)
87  return;
88  gwlist_destroy(wrap->outgoing_queue, NULL);
89  gwlist_destroy(wrap->stopped, NULL);
91  if (wrap->smsc != NULL)
92  smsc_close(wrap->smsc);
93  gw_free(wrap);
94 }
List * outgoing_queue
Definition: smsc_wrapper.c:76
List * stopped
Definition: smsc_wrapper.c:77
Mutex * reconnect_mutex
Definition: smsc_wrapper.c:80
SMSCenter * smsc
Definition: smsc_wrapper.c:75
void mutex_destroy(Mutex *mutex)
Definition: thread.c:97
int smsc_close(SMSCenter *smsc)
Definition: smsc.c:648
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ wrapper_add_msg()

static int wrapper_add_msg ( SMSCConn conn,
Msg sms 
)
static

Definition at line 337 of file smsc_wrapper.c.

References smscconn::data, gwlist_produce(), msg_duplicate(), and smsc_wrapper::outgoing_queue.

Referenced by smsc_wrapper_create().

338 {
339  SmscWrapper *wrap = conn->data;
340  Msg *copy;
341 
342  copy = msg_duplicate(sms);
343  gwlist_produce(wrap->outgoing_queue, copy);
344 
345  return 0;
346 }
Msg * msg_duplicate(Msg *msg)
Definition: msg.c:111
List * outgoing_queue
Definition: smsc_wrapper.c:76
void gwlist_produce(List *list, void *item)
Definition: list.c:411
void * data
Definition: smscconn_p.h:250
Definition: msg.h:79

◆ wrapper_queued()

static long wrapper_queued ( SMSCConn conn)
static

Definition at line 386 of file smsc_wrapper.c.

References smscconn::data, gwlist_len(), smscconn::load, and smsc_wrapper::outgoing_queue.

Referenced by smsc_wrapper_create().

387 {
388  SmscWrapper *wrap = conn->data;
389  long ret = gwlist_len(wrap->outgoing_queue);
390 
391  /* use internal queue as load, maybe something else later */
392 
393  conn->load = ret;
394  return ret;
395 }
List * outgoing_queue
Definition: smsc_wrapper.c:76
long gwlist_len(List *list)
Definition: list.c:166
void * data
Definition: smscconn_p.h:250
int load
Definition: smscconn_p.h:152

◆ wrapper_receiver()

static void wrapper_receiver ( void *  arg)
static

Definition at line 191 of file smsc_wrapper.c.

References bb_smscconn_receive(), smscconn::data, debug(), gwlist_consume(), gwthread_sleep(), smscconn::log_idx, log_thread_to(), msg, smscconn::name, octstr_get_cstr, sms_receive(), SMSCCONN_ALIVE, SMSCCONN_KILLED_SHUTDOWN, smsc_wrapper::stopped, and smscconn::why_killed.

Referenced by smsc_wrapper_create().

192 {
193  Msg *msg;
194  SMSCConn *conn = arg;
195  SmscWrapper *wrap = conn->data;
196  /* SmscWrapper *wrap = conn->data; ** non-used */
197  double sleep = 0.0001;
198 
199  /* Make sure we log into our own log-file if defined */
200  log_thread_to(conn->log_idx);
201 
202  /* remove messages from SMSC until we are killed */
203  while(conn->why_killed == SMSCCONN_ALIVE) {
204 
205  gwlist_consume(wrap->stopped); /* block here if suspended/isolated */
206 
207  msg = sms_receive(conn);
208  if (msg) {
209  debug("bb.sms", 0, "smscconn (%s): new message received",
210  octstr_get_cstr(conn->name));
211  sleep = 0.0001;
212  bb_smscconn_receive(conn, msg);
213  }
214  else {
215  /* note that this implementations means that we sleep even
216  * when we fail connection.. but time is very short, anyway
217  */
218  gwthread_sleep(sleep);
219  /* gradually sleep longer and longer times until something starts to
220  * happen - this of course reduces response time, but that's better than
221  * extensive CPU usage when it is not used
222  */
223  sleep *= 2;
224  if (sleep >= 2.0)
225  sleep = 1.999999;
226  }
227  }
229 
230  /* this thread is joined at sender */
231 }
Octstr * name
Definition: smscconn_p.h:173
List * stopped
Definition: smsc_wrapper.c:77
void * data
Definition: smscconn_p.h:250
int log_idx
Definition: smscconn_p.h:197
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void log_thread_to(int idx)
Definition: log.c:759
smscconn_killed_t why_killed
Definition: smscconn_p.h:153
Definition: msg.h:79
long bb_smscconn_receive(SMSCConn *conn, Msg *sms)
Definition: bb_smscconn.c:477
void gwthread_sleep(double seconds)
void * gwlist_consume(List *list)
Definition: list.c:427
static Msg * sms_receive(SMSCConn *conn)
Definition: smsc_wrapper.c:160
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ wrapper_sender()

static void wrapper_sender ( void *  arg)
static

Definition at line 258 of file smsc_wrapper.c.

References bb_smscconn_killed(), bb_smscconn_send_failed(), smscconn::data, debug(), smscconn::flow_mutex, gwlist_consume(), gwlist_destroy(), gwlist_extract_first(), gwlist_get(), gwlist_len(), gwlist_remove_producer(), gwthread_join(), gwthread_wakeup(), smscconn::is_stopped, smscconn::log_idx, log_thread_to(), msg, msg_destroy(), msg_duplicate(), mutex_lock, mutex_unlock, smscconn::name, octstr_destroy(), octstr_get_cstr, octstr_search_char(), octstr_split_words(), smsc_wrapper::outgoing_queue, smsc_wrapper::receiver_thread, sms_send(), SMSCCONN_DEAD, SMSCCONN_FAILED_SHUTDOWN, SMSCCONN_KILLED_SHUTDOWN, smscwrapper_destroy(), smscconn::status, smsc_wrapper::stopped, and smscconn::why_killed.

Referenced by smsc_wrapper_create().

259 {
260  Msg *msg;
261  SMSCConn *conn = arg;
262  SmscWrapper *wrap = conn->data;
263 
264  /* Make sure we log into our own log-file if defined */
265  log_thread_to(conn->log_idx);
266 
267  /* send messages to SMSC until our outgoing_list is empty and
268  * no producer anymore (we are set to shutdown) */
269  while(conn->status != SMSCCONN_DEAD) {
270 
271  if ((msg = gwlist_consume(wrap->outgoing_queue)) == NULL)
272  break;
273 
274  if (octstr_search_char(msg->sms.receiver, ' ', 0) != -1) {
275  /*
276  * multi-send: this should be implemented in corresponding
277  * SMSC protocol, but while we are waiting for that...
278  */
279  int i;
280  Msg *newmsg;
281  /* split from spaces: in future, split with something more sensible,
282  * this is dangerous... (as space is url-encoded as '+')
283  */
284  List *nlist = octstr_split_words(msg->sms.receiver);
285 
286  debug("bb.sms", 0, "Handling multi-receiver message");
287 
288  for(i=0; i < gwlist_len(nlist); i++) {
289 
290  newmsg = msg_duplicate(msg);
291  octstr_destroy(newmsg->sms.receiver);
292 
293  newmsg->sms.receiver = gwlist_get(nlist, i);
294  sms_send(conn, newmsg);
295  }
296  gwlist_destroy(nlist, NULL);
297  msg_destroy(msg);
298  }
299  else
300  sms_send(conn,msg);
301 
302  }
303  /* cleanup, we are now dying */
304 
305  debug("bb.sms", 0, "SMSCConn %s sender died, waiting for receiver",
306  octstr_get_cstr(conn->name));
307 
309 
310  if (conn->is_stopped) {
312  conn->is_stopped = 0;
313  }
314 
317 
318  /* call 'failed' to all messages still in queue */
319 
320  mutex_lock(conn->flow_mutex);
321 
322  conn->status = SMSCCONN_DEAD;
323 
324  while((msg = gwlist_extract_first(wrap->outgoing_queue))!=NULL) {
326  }
327  smscwrapper_destroy(wrap);
328  conn->data = NULL;
329 
330  mutex_unlock(conn->flow_mutex);
331 
333 }
Octstr * name
Definition: smscconn_p.h:173
Msg * msg_duplicate(Msg *msg)
Definition: msg.c:111
static int sms_send(SMSCConn *conn, Msg *msg)
Definition: smsc_wrapper.c:235
List * outgoing_queue
Definition: smsc_wrapper.c:76
#define mutex_unlock(m)
Definition: thread.h:136
List * stopped
Definition: smsc_wrapper.c:77
void bb_smscconn_killed(void)
Definition: bb_smscconn.c:199
void gwthread_join(long thread)
long gwlist_len(List *list)
Definition: list.c:166
void * data
Definition: smscconn_p.h:250
void * gwlist_get(List *list, long pos)
Definition: list.c:292
int log_idx
Definition: smscconn_p.h:197
long receiver_thread
Definition: smsc_wrapper.c:78
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
void log_thread_to(int idx)
Definition: log.c:759
smscconn_killed_t why_killed
Definition: smscconn_p.h:153
static void smscwrapper_destroy(SmscWrapper *wrap)
Definition: smsc_wrapper.c:84
Definition: msg.h:79
void * gwlist_extract_first(List *list)
Definition: list.c:305
void gwlist_remove_producer(List *list)
Definition: list.c:401
Mutex * flow_mutex
Definition: smscconn_p.h:157
void msg_destroy(Msg *msg)
Definition: msg.c:132
List * octstr_split_words(const Octstr *ostr)
Definition: octstr.c:1602
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
volatile sig_atomic_t is_stopped
Definition: smscconn_p.h:169
void * gwlist_consume(List *list)
Definition: list.c:427
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
void gwthread_wakeup(long thread)
smscconn_status_t status
Definition: smscconn_p.h:151
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
Definition: bb_smscconn.c:329
#define mutex_lock(m)
Definition: thread.h:130
Definition: list.c:102
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ wrapper_shutdown()

static int wrapper_shutdown ( SMSCConn conn,
int  finish_sending 
)
static

Definition at line 349 of file smsc_wrapper.c.

References bb_smscconn_send_failed(), smscconn::data, debug(), gwlist_extract_first(), gwlist_remove_producer(), gwthread_wakeup(), msg, smscconn::name, octstr_get_cstr, smsc_wrapper::outgoing_queue, smsc_wrapper::receiver_thread, smsc_wrapper::sender_thread, and SMSCCONN_FAILED_SHUTDOWN.

Referenced by smsc_wrapper_create().

350 {
351  SmscWrapper *wrap = conn->data;
352 
353  debug("bb.sms", 0, "Shutting down SMSCConn %s, %s",
354  octstr_get_cstr(conn->name), finish_sending ? "slow" : "instant");
355 
356  if (finish_sending == 0) {
357  Msg *msg;
358  while((msg = gwlist_extract_first(wrap->outgoing_queue))!=NULL) {
360  }
361  }
365  return 0;
366 }
Octstr * name
Definition: smscconn_p.h:173
List * outgoing_queue
Definition: smsc_wrapper.c:76
void * data
Definition: smscconn_p.h:250
long receiver_thread
Definition: smsc_wrapper.c:78
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Definition: msg.h:79
void * gwlist_extract_first(List *list)
Definition: list.c:305
void gwlist_remove_producer(List *list)
Definition: list.c:401
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
void gwthread_wakeup(long thread)
long sender_thread
Definition: smsc_wrapper.c:79
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

◆ wrapper_start()

static void wrapper_start ( SMSCConn conn)
static

Definition at line 377 of file smsc_wrapper.c.

References smscconn::data, debug(), gwlist_remove_producer(), and smsc_wrapper::stopped.

Referenced by smsc_wrapper_create().

378 {
379  SmscWrapper *wrap = conn->data;
380 
381  debug("smscconn", 0, "Starting wrapper");
383 }
List * stopped
Definition: smsc_wrapper.c:77
void * data
Definition: smscconn_p.h:250
void gwlist_remove_producer(List *list)
Definition: list.c:401
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726

◆ wrapper_stop()

static void wrapper_stop ( SMSCConn conn)
static

Definition at line 368 of file smsc_wrapper.c.

References smscconn::data, debug(), gwlist_add_producer(), and smsc_wrapper::stopped.

Referenced by smsc_wrapper_create().

369 {
370  SmscWrapper *wrap = conn->data;
371 
372  debug("smscconn", 0, "Stopping wrapper");
374 
375 }
List * stopped
Definition: smsc_wrapper.c:77
void * data
Definition: smscconn_p.h:250
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
void gwlist_add_producer(List *list)
Definition: list.c:383
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.