Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
smsc_http.c File Reference
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <limits.h>
#include "gwlib/gwlib.h"
#include "smscconn.h"
#include "smscconn_p.h"
#include "bb_smscconn_cb.h"
#include "msg.h"
#include "sms.h"
#include "dlr.h"
#include "urltrans.h"
#include "meta_data.h"
#include "http/generic.c"
#include "http/brunet.c"
#include "http/xidris.c"
#include "http/clickatell.c"
#include "http/wapme.c"

Go to the source code of this file.

Data Structures

struct  smsc_http_fn_callbacks
 
struct  conndata
 

Macros

#define DEFAULT_CHARSET   "UTF-8"
 

Typedefs

typedef struct conndata ConnData
 

Enumerations

enum  { HEX_NOT_UPPERCASE = 0 }
 

Functions

static void conndata_destroy (ConnData *conndata)
 
static void httpsmsc_receiver (void *arg)
 
static void httpsmsc_sender (void *arg)
 
static void httpsmsc_send_cb (void *arg)
 
static int kannel_send_sms (SMSCConn *conn, Msg *sms)
 
static void kannel_parse_reply (SMSCConn *conn, Msg *msg, int status, List *headers, Octstr *body)
 
static void kannel_receive_sms (SMSCConn *conn, HTTPClient *client, List *headers, Octstr *body, List *cgivars)
 
static int httpsmsc_send (SMSCConn *conn, Msg *msg)
 
static long httpsmsc_queued (SMSCConn *conn)
 
static int httpsmsc_shutdown (SMSCConn *conn, int finish_sending)
 
int smsc_http_create (SMSCConn *conn, CfgGroup *cfg)
 

Variables

struct smsc_http_fn_callbacks smsc_http_kannel_callback
 

Macro Definition Documentation

#define DEFAULT_CHARSET   "UTF-8"

Definition at line 131 of file smsc_http.c.

Referenced by generic_receive_sms(), and httpsmsc_send().

Typedef Documentation

typedef struct conndata ConnData

Enumeration Type Documentation

anonymous enum
Enumerator
HEX_NOT_UPPERCASE 

Definition at line 492 of file smsc_http.c.

Function Documentation

static void conndata_destroy ( ConnData conndata)
static

Definition at line 174 of file smsc_http.c.

References conndata::allow_ip, conndata::alt_charset, counter_destroy(), conndata::dlr_url, gwlist_destroy(), http_caller_destroy(), conndata::http_ref, conndata::max_pending_sends, conndata::msg_to_send, octstr_destroy(), conndata::open_sends, conndata::password, conndata::proxy, semaphore_destroy(), conndata::send_url, conndata::system_id, and conndata::username.

Referenced by httpsmsc_receiver(), httpsmsc_sender(), and smsc_http_create().

175 {
176  if (conndata == NULL)
177  return;
178  if (conndata->http_ref)
179  http_caller_destroy(conndata->http_ref);
180  octstr_destroy(conndata->allow_ip);
181  octstr_destroy(conndata->send_url);
182  octstr_destroy(conndata->dlr_url);
183  octstr_destroy(conndata->username);
184  octstr_destroy(conndata->password);
185  octstr_destroy(conndata->proxy);
186  octstr_destroy(conndata->system_id);
187  octstr_destroy(conndata->alt_charset);
188  counter_destroy(conndata->open_sends);
189  gwlist_destroy(conndata->msg_to_send, NULL);
190  if (conndata->max_pending_sends)
192 
193  gw_free(conndata);
194 }
Octstr * dlr_url
Definition: smsc_http.c:151
Octstr * alt_charset
Definition: smsc_http.c:161
void counter_destroy(Counter *counter)
Definition: counter.c:110
HTTPCaller * http_ref
Definition: smsc_http.c:143
Octstr * allow_ip
Definition: smsc_http.c:149
Octstr * proxy
Definition: smsc_http.c:160
Octstr * system_id
Definition: smsc_http.c:156
Counter * open_sends
Definition: smsc_http.c:152
List * msg_to_send
Definition: smsc_http.c:162
void semaphore_destroy(Semaphore *semaphore)
Definition: semaphore.c:104
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Semaphore * max_pending_sends
Definition: smsc_http.c:153
Octstr * password
Definition: smsc_http.c:155
Octstr * username
Definition: smsc_http.c:154
void http_caller_destroy(HTTPCaller *caller)
Definition: http.c:907
Octstr * send_url
Definition: smsc_http.c:150
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static long httpsmsc_queued ( SMSCConn conn)
static

Definition at line 835 of file smsc_http.c.

References smscconn::data, gwlist_len(), smscconn::load, conndata::msg_to_send, SMSCCONN_DEAD, and smscconn::status.

Referenced by smsc_http_create().

836 {
837  ConnData *conndata = conn->data;
838 
839  conn->load = (conndata ? (conn->status != SMSCCONN_DEAD ?
840  gwlist_len(conndata->msg_to_send) : 0) : 0);
841 
842  return conn->load;
843 }
long gwlist_len(List *list)
Definition: list.c:166
void * data
Definition: smscconn_p.h:249
List * msg_to_send
Definition: smsc_http.c:162
smscconn_status_t status
Definition: smscconn_p.h:151
int load
Definition: smscconn_p.h:152
static void httpsmsc_receiver ( void *  arg)
static

Definition at line 200 of file smsc_http.c.

References conndata::allow_ip, bb_smscconn_killed(), conndata::callbacks, client(), conndata_destroy(), connect_denied(), counter_value(), smscconn::data, debug(), smsc_http_fn_callbacks::destroy, smscconn::flow_mutex, gwthread_join(), gwthread_wakeup(), http_accept_request(), http_caller_signal_shutdown(), http_cgivar_dump_into(), http_close_client(), http_close_port(), http_destroy_cgiargs(), http_destroy_headers(), conndata::http_ref, smscconn::id, info(), smscconn::log_idx, log_thread_to(), mutex_lock, mutex_unlock, octstr_append_char(), octstr_destroy(), octstr_get_cstr, conndata::open_sends, conndata::port, smsc_http_fn_callbacks::receive_sms, conndata::send_cb_thread, conndata::sender_thread, conndata::shutdown, SMSCCONN_DEAD, smscconn::status, and url.

Referenced by smsc_http_create().

201 {
202  SMSCConn *conn = arg;
203  ConnData *conndata = conn->data;
205  Octstr *ip, *url, *body;
206  List *headers, *cgivars;
207 
208  /* Make sure we log into our own log-file if defined */
209  log_thread_to(conn->log_idx);
210 
211  while (conndata->shutdown == 0) {
212  /* reset */
213  ip = url = body = NULL;
214  headers = cgivars = NULL;
215 
216  /* XXX if conn->is_stopped, do not receive new messages.. */
217 
218  client = http_accept_request(conndata->port, &ip, &url,
219  &headers, &body, &cgivars);
220  if (client == NULL)
221  break;
222 
223  if (cgivars != NULL) {
224  octstr_append_char(url, '?');
225  http_cgivar_dump_into(cgivars, url);
226  }
227 
228  debug("smsc.http", 0, "HTTP[%s]: Got request `%s'",
229  octstr_get_cstr(conn->id), octstr_get_cstr(url));
230 
231  if (connect_denied(conndata->allow_ip, ip)) {
232  info(0, "HTTP[%s]: Connection `%s' tried from denied "
233  "host %s, ignored", octstr_get_cstr(conn->id),
234  octstr_get_cstr(url), octstr_get_cstr(ip));
235  http_close_client(client);
236  } else
237  conndata->callbacks->receive_sms(conn, client, headers, body, cgivars);
238 
239  debug("smsc.http", 0, "HTTP[%s]: Destroying client information",
240  octstr_get_cstr(conn->id));
241  octstr_destroy(url);
242  octstr_destroy(ip);
243  octstr_destroy(body);
244  http_destroy_headers(headers);
245  http_destroy_cgiargs(cgivars);
246  }
247  debug("smsc.http", 0, "HTTP[%s]: httpsmsc_receiver dying",
248  octstr_get_cstr(conn->id));
249 
250  conndata->shutdown = 1;
251  http_close_port(conndata->port);
252 
253  /* unblock http_receive_result() if there are no open sends */
254  if (counter_value(conndata->open_sends) == 0)
256 
257  if (conndata->sender_thread != -1) {
258  gwthread_wakeup(conndata->sender_thread);
259  gwthread_join(conndata->sender_thread);
260  }
261  if (conndata->send_cb_thread != -1) {
262  gwthread_wakeup(conndata->send_cb_thread);
263  gwthread_join(conndata->send_cb_thread);
264  }
265 
266  mutex_lock(conn->flow_mutex);
267  conn->status = SMSCCONN_DEAD;
268  mutex_unlock(conn->flow_mutex);
269 
270  if (conndata->callbacks != NULL && conndata->callbacks->destroy != NULL)
271  conndata->callbacks->destroy(conn);
272  conn->data = NULL;
273  conndata_destroy(conndata);
275 }
void info(int err, const char *fmt,...)
Definition: log.c:636
static void conndata_destroy(ConnData *conndata)
Definition: smsc_http.c:174
void http_caller_signal_shutdown(HTTPCaller *caller)
Definition: http.c:913
#define mutex_unlock(m)
Definition: thread.h:136
void http_close_client(HTTPClient *client)
Definition: http.c:2735
void bb_smscconn_killed(void)
Definition: bb_smscconn.c:199
Octstr * id
Definition: smscconn_p.h:174
void gwthread_join(long thread)
void * data
Definition: smscconn_p.h:249
static void client(int port)
Definition: test_udp.c:77
HTTPCaller * http_ref
Definition: smsc_http.c:143
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1515
int log_idx
Definition: smscconn_p.h:197
Octstr * allow_ip
Definition: smsc_http.c:149
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void(* destroy)(SMSCConn *conn)
Definition: smsc_http.c:136
int connect_denied(Octstr *allow_ip, Octstr *ip)
Definition: utils.c:833
void log_thread_to(int idx)
Definition: log.c:723
void http_destroy_headers(List *headers)
Definition: http.c:2856
volatile int shutdown
Definition: smsc_http.c:147
void http_destroy_cgiargs(List *args)
Definition: http.c:2795
long port
Definition: smsc_http.c:148
Counter * open_sends
Definition: smsc_http.c:152
HTTPClient * http_accept_request(int port, Octstr **client_ip, Octstr **url, List **headers, Octstr **body, List **cgivars)
Definition: http.c:2574
void http_close_port(int port)
Definition: http.c:2504
Mutex * flow_mutex
Definition: smscconn_p.h:157
long sender_thread
Definition: smsc_http.c:146
void http_cgivar_dump_into(List *cgiargs, Octstr *os)
Definition: http.c:3436
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
unsigned long counter_value(Counter *counter)
Definition: counter.c:145
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
void gwthread_wakeup(long thread)
smscconn_status_t status
Definition: smscconn_p.h:151
void(* receive_sms)(SMSCConn *conn, HTTPClient *client, List *headers, Octstr *body, List *cgivars)
Definition: smsc_http.c:139
static Octstr * url
Definition: test_xmlrpc.c:84
#define mutex_lock(m)
Definition: thread.h:130
struct smsc_http_fn_callbacks * callbacks
Definition: smsc_http.c:167
Definition: list.c:102
long send_cb_thread
Definition: smsc_http.c:145
static int httpsmsc_send ( SMSCConn conn,
Msg msg 
)
static

Definition at line 810 of file smsc_http.c.

References conndata::alt_charset, conndata::callbacks, charset_convert(), smscconn::data, DC_7BIT, DEFAULT_CHARSET, error(), gwlist_produce(), msg_duplicate(), conndata::msg_to_send, octstr_get_cstr, and smsc_http_fn_callbacks::send_sms.

Referenced by smsc_http_create().

811 {
812  ConnData *conndata = conn->data;
813  Msg *sms;
814 
815 
816  /* don't crash if no send_sms handle defined */
817  if (!conndata || !conndata->callbacks->send_sms)
818  return -1;
819 
820  sms = msg_duplicate(msg);
821  /* convert character encoding if required */
822  if (msg->sms.coding == DC_7BIT && conndata->alt_charset &&
823  charset_convert(sms->sms.msgdata, DEFAULT_CHARSET,
824  octstr_get_cstr(conndata->alt_charset)) != 0) {
825  error(0, "Failed to convert msgdata from charset <%s> to <%s>, will send as is.",
827  }
828 
829  gwlist_produce(conndata->msg_to_send, sms);
830 
831  return 0;
832 }
void error(int err, const char *fmt,...)
Definition: log.c:612
#define DEFAULT_CHARSET
Definition: smsc_http.c:131
Msg * msg_duplicate(Msg *msg)
Definition: msg.c:111
Octstr * alt_charset
Definition: smsc_http.c:161
int(* send_sms)(SMSCConn *conn, Msg *msg)
Definition: smsc_http.c:137
void gwlist_produce(List *list, void *item)
Definition: list.c:411
void * data
Definition: smscconn_p.h:249
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Definition: msg.h:79
List * msg_to_send
Definition: smsc_http.c:162
struct smsc_http_fn_callbacks * callbacks
Definition: smsc_http.c:167
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
Definition: charset.c:589
#define DC_7BIT
Definition: sms.h:110
static void httpsmsc_send_cb ( void *  arg)
static

Definition at line 351 of file smsc_http.c.

References bb_smscconn_connected(), bb_smscconn_send_failed(), conndata::callbacks, smscconn::connect_time, counter_decrease(), counter_value(), smscconn::data, debug(), error(), smscconn::flow_mutex, gwthread_sleep(), http_destroy_headers(), http_receive_result, conndata::http_ref, smscconn::id, smscconn::log_idx, log_thread_to(), conndata::max_pending_sends, msg, mutex_lock, mutex_unlock, octstr_destroy(), octstr_get_cstr, conndata::open_sends, smsc_http_fn_callbacks::parse_reply, smscconn::reconnect_delay, semaphore_up(), conndata::shutdown, SMSCCONN_ACTIVE, SMSCCONN_FAILED_SHUTDOWN, SMSCCONN_FAILED_TEMPORARILY, SMSCCONN_RECONNECTING, smscconn::status, and warning().

Referenced by smsc_http_create().

352 {
353  SMSCConn *conn = arg;
354  ConnData *conndata = conn->data;
355  Msg *msg;
356  int status;
357  List *headers;
358  Octstr *final_url, *body;
359 
360  /* Make sure we log into our own log-file if defined */
361  log_thread_to(conn->log_idx);
362 
363  while(conndata->shutdown == 0 || counter_value(conndata->open_sends)) {
364 
365  msg = http_receive_result(conndata->http_ref, &status,
366  &final_url, &headers, &body);
367 
368  if (msg == NULL)
369  break; /* they told us to die, by unlocking */
370 
371  counter_decrease(conndata->open_sends);
372  if (conndata->max_pending_sends)
373  semaphore_up(conndata->max_pending_sends);
374 
375  /* Handle various states here. */
376 
377  /* request failed and we are not in shutdown mode */
378  if (status == -1 && conndata->shutdown == 0) {
379  error(0, "HTTP[%s]: Couldn't connect to SMS center."
380  "(retrying in %ld seconds) %ld.",
381  octstr_get_cstr(conn->id), conn->reconnect_delay, counter_value(conndata->open_sends));
382  mutex_lock(conn->flow_mutex);
384  mutex_unlock(conn->flow_mutex);
385  /* XXX how should we know whether it's temp. error ?? */
387  /*
388  * Just sleep reconnect delay and set conn to ACTIVE again;
389  * otherwise if no pending request are here, we leave conn in
390  * RECONNECTING state for ever and no routing (trials) take place.
391  */
392  if (counter_value(conndata->open_sends) == 0) {
394  /* and now enable routing again */
395  mutex_lock(conn->flow_mutex);
396  conn->status = SMSCCONN_ACTIVE;
397  time(&conn->connect_time);
398  mutex_unlock(conn->flow_mutex);
399  /* tell bearerbox core that we are connected again */
400  bb_smscconn_connected(conn);
401  }
402  continue;
403  }
404  /* request failed and we *are* in shutdown mode, drop the message */
405  else if (status == -1 && conndata->shutdown == 1) {
407  }
408  /* request succeeded */
409  else {
410  /* we received a response, so this link is considered online again */
411  if (conn->status != SMSCCONN_ACTIVE) {
412  mutex_lock(conn->flow_mutex);
413  conn->status = SMSCCONN_ACTIVE;
414  time(&conn->connect_time);
415  mutex_unlock(conn->flow_mutex);
416  /* tell bearerbox core that we are connected again */
417  bb_smscconn_connected(conn);
418  }
419  conndata->callbacks->parse_reply(conn, msg, status, headers, body);
420  }
421 
422  http_destroy_headers(headers);
423  octstr_destroy(final_url);
424  octstr_destroy(body);
425  }
426  debug("smsc.http", 0, "HTTP[%s]: httpsmsc_send_cb dying",
427  octstr_get_cstr(conn->id));
428  conndata->shutdown = 1;
429 
430  if (counter_value(conndata->open_sends)) {
431  warning(0, "HTTP[%s]: Shutdown while <%ld> requests are pending.",
432  octstr_get_cstr(conn->id), counter_value(conndata->open_sends));
433  }
434 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void bb_smscconn_connected(SMSCConn *conn)
Definition: bb_smscconn.c:192
void semaphore_up(Semaphore *semaphore)
Definition: semaphore.c:118
#define mutex_unlock(m)
Definition: thread.h:136
Octstr * id
Definition: smscconn_p.h:174
void * data
Definition: smscconn_p.h:249
HTTPCaller * http_ref
Definition: smsc_http.c:143
int log_idx
Definition: smscconn_p.h:197
void(* parse_reply)(SMSCConn *conn, Msg *msg, int status, List *headers, Octstr *body)
Definition: smsc_http.c:138
unsigned long counter_decrease(Counter *counter)
Definition: counter.c:155
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
long reconnect_delay
Definition: smscconn_p.h:199
void log_thread_to(int idx)
Definition: log.c:723
void http_destroy_headers(List *headers)
Definition: http.c:2856
volatile int shutdown
Definition: smsc_http.c:147
Counter * open_sends
Definition: smsc_http.c:152
Definition: msg.h:79
time_t connect_time
Definition: smscconn_p.h:155
Mutex * flow_mutex
Definition: smscconn_p.h:157
void warning(int err, const char *fmt,...)
Definition: log.c:624
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
unsigned long counter_value(Counter *counter)
Definition: counter.c:145
void gwthread_sleep(double seconds)
Semaphore * max_pending_sends
Definition: smsc_http.c:153
#define http_receive_result(caller, status, final_url, headers, body)
Definition: http.h:383
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
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:328
#define mutex_lock(m)
Definition: thread.h:130
struct smsc_http_fn_callbacks * callbacks
Definition: smsc_http.c:167
Definition: list.c:102
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static void httpsmsc_sender ( void *  arg)
static

Definition at line 281 of file smsc_http.c.

References bb_smscconn_killed(), bb_smscconn_send_failed(), conndata::callbacks, conndata_destroy(), counter_decrease(), counter_increase(), counter_value(), smscconn::data, delay, smsc_http_fn_callbacks::destroy, smscconn::flow_mutex, gwlist_consume(), gwlist_extract_first(), gwthread_join(), gwthread_sleep(), gwthread_wakeup(), http_caller_signal_shutdown(), conndata::http_ref, smscconn::log_idx, log_thread_to(), conndata::max_pending_sends, msg, conndata::msg_to_send, mutex_lock, mutex_unlock, conndata::open_sends, conndata::port, semaphore_down(), semaphore_up(), conndata::send_cb_thread, smsc_http_fn_callbacks::send_sms, conndata::shutdown, SMSCCONN_DEAD, SMSCCONN_FAILED_SHUTDOWN, smscconn::status, and smscconn::throughput.

Referenced by smsc_http_create().

282 {
283  SMSCConn *conn = arg;
284  ConnData *conndata = conn->data;
285  Msg *msg;
286  double delay = 0;
287 
288  /* Make sure we log into our own log-file if defined */
289  log_thread_to(conn->log_idx);
290 
291  if (conn->throughput) {
292  delay = 1.0 / conn->throughput;
293  }
294 
295  while (conndata->shutdown == 0) {
296  /* check if we can send ; otherwise block on semaphore */
297  if (conndata->max_pending_sends)
299 
300  if (conndata->shutdown) {
301  if (conndata->max_pending_sends)
302  semaphore_up(conndata->max_pending_sends);
303  break;
304  }
305 
306  msg = gwlist_consume(conndata->msg_to_send);
307  if (msg == NULL)
308  break;
309 
310  /* obey throughput speed limit, if any */
311  if (conn->throughput > 0) {
312  gwthread_sleep(delay);
313  }
314  counter_increase(conndata->open_sends);
315  if (conndata->callbacks->send_sms(conn, msg) == -1) {
316  counter_decrease(conndata->open_sends);
317  if (conndata->max_pending_sends)
318  semaphore_up(conndata->max_pending_sends);
319  }
320  }
321 
322  /* put outstanding sends back into global queue */
323  while((msg = gwlist_extract_first(conndata->msg_to_send)))
325 
326  /* if there no receiver shutdown */
327  if (conndata->port <= 0) {
328  /* unblock http_receive_result() if there are no open sends */
329  if (counter_value(conndata->open_sends) == 0)
331 
332  if (conndata->send_cb_thread != -1) {
333  gwthread_wakeup(conndata->send_cb_thread);
334  gwthread_join(conndata->send_cb_thread);
335  }
336  mutex_lock(conn->flow_mutex);
337  conn->status = SMSCCONN_DEAD;
338  mutex_unlock(conn->flow_mutex);
339 
340  if (conndata->callbacks != NULL && conndata->callbacks->destroy != NULL)
341  conndata->callbacks->destroy(conn);
342  conn->data = NULL;
343  conndata_destroy(conndata);
345  }
346 }
static void conndata_destroy(ConnData *conndata)
Definition: smsc_http.c:174
void semaphore_up(Semaphore *semaphore)
Definition: semaphore.c:118
int(* send_sms)(SMSCConn *conn, Msg *msg)
Definition: smsc_http.c:137
void http_caller_signal_shutdown(HTTPCaller *caller)
Definition: http.c:913
#define mutex_unlock(m)
Definition: thread.h:136
void bb_smscconn_killed(void)
Definition: bb_smscconn.c:199
void gwthread_join(long thread)
void * data
Definition: smscconn_p.h:249
HTTPCaller * http_ref
Definition: smsc_http.c:143
int log_idx
Definition: smscconn_p.h:197
void semaphore_down(Semaphore *semaphore)
Definition: semaphore.c:132
unsigned long counter_decrease(Counter *counter)
Definition: counter.c:155
void(* destroy)(SMSCConn *conn)
Definition: smsc_http.c:136
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
void log_thread_to(int idx)
Definition: log.c:723
volatile int shutdown
Definition: smsc_http.c:147
long port
Definition: smsc_http.c:148
Counter * open_sends
Definition: smsc_http.c:152
Definition: msg.h:79
List * msg_to_send
Definition: smsc_http.c:162
void * gwlist_extract_first(List *list)
Definition: list.c:305
double throughput
Definition: smscconn_p.h:203
Mutex * flow_mutex
Definition: smscconn_p.h:157
static double delay
Definition: mtbatch.c:99
unsigned long counter_value(Counter *counter)
Definition: counter.c:145
void gwthread_sleep(double seconds)
Semaphore * max_pending_sends
Definition: smsc_http.c:153
void * gwlist_consume(List *list)
Definition: list.c:427
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:328
#define mutex_lock(m)
Definition: thread.h:130
struct smsc_http_fn_callbacks * callbacks
Definition: smsc_http.c:167
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
long send_cb_thread
Definition: smsc_http.c:145
static int httpsmsc_shutdown ( SMSCConn conn,
int  finish_sending 
)
static

Definition at line 846 of file smsc_http.c.

References smscconn::data, debug(), smscconn::flow_mutex, gwlist_remove_producer(), gwthread_wakeup(), http_close_port(), smscconn::id, conndata::msg_to_send, mutex_lock, mutex_unlock, octstr_get_cstr, conndata::port, conndata::receive_thread, conndata::sender_thread, conndata::shutdown, SMSCCONN_KILLED_SHUTDOWN, and smscconn::why_killed.

Referenced by smsc_http_create().

847 {
848  ConnData *conndata = conn->data;
849 
850  if (conndata == NULL)
851  return 0;
852 
853  debug("httpsmsc_shutdown", 0, "HTTP[%s]: Shutting down",
854  octstr_get_cstr(conn->id));
855 
856  mutex_lock(conn->flow_mutex);
858 
859  conndata->shutdown = 1;
860 
861  if (conndata->port > 0)
862  http_close_port(conndata->port);
864  if (conndata->receive_thread != -1)
865  gwthread_wakeup(conndata->receive_thread);
866  if (conndata->sender_thread != -1)
867  gwthread_wakeup(conndata->sender_thread);
868  mutex_unlock(conn->flow_mutex);
869 
870  return 0;
871 }
long receive_thread
Definition: smsc_http.c:144
#define mutex_unlock(m)
Definition: thread.h:136
Octstr * id
Definition: smscconn_p.h:174
void * data
Definition: smscconn_p.h:249
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
smscconn_killed_t why_killed
Definition: smscconn_p.h:153
volatile int shutdown
Definition: smsc_http.c:147
long port
Definition: smsc_http.c:148
List * msg_to_send
Definition: smsc_http.c:162
void http_close_port(int port)
Definition: http.c:2504
void gwlist_remove_producer(List *list)
Definition: list.c:401
Mutex * flow_mutex
Definition: smscconn_p.h:157
long sender_thread
Definition: smsc_http.c:146
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
void gwthread_wakeup(long thread)
#define mutex_lock(m)
Definition: thread.h:130
static void kannel_parse_reply ( SMSCConn conn,
Msg msg,
int  status,
List headers,
Octstr body 
)
static

Definition at line 598 of file smsc_http.c.

References bb_smscconn_send_failed(), bb_smscconn_sent(), dlr_add(), DLR_IS_ENABLED_DEVICE, HTTP_ACCEPTED, HTTP_OK, smscconn::id, octstr_case_compare(), octstr_create, octstr_destroy(), octstr_duplicate, octstr_imm(), octstr_ncompare(), SMSCCONN_FAILED_MALFORMED, UUID_STR_LEN, and uuid_unparse().

600 {
601  /* Test on three cases:
602  * 1. an smsbox reply of an remote kannel instance
603  * 2. an smsc_http response (if used for MT to MO looping)
604  * 3. an smsbox reply of partly successful sendings */
605  if ((status == HTTP_OK || status == HTTP_ACCEPTED)
606  && (octstr_case_compare(body, octstr_imm("0: Accepted for delivery")) == 0 ||
607  octstr_case_compare(body, octstr_imm("Sent.")) == 0 ||
608  octstr_case_compare(body, octstr_imm("Ok.")) == 0 ||
609  octstr_ncompare(body, octstr_imm("Result: OK"),10) == 0)) {
610  char id[UUID_STR_LEN + 1];
611  Octstr *mid;
612 
613  /* create Octstr from UUID */
614  uuid_unparse(msg->sms.id, id);
615  mid = octstr_create(id);
616 
617  /* add to our own DLR storage */
618  if (DLR_IS_ENABLED_DEVICE(msg->sms.dlr_mask))
619  dlr_add(conn->id, mid, msg, 0);
620 
621  octstr_destroy(mid);
622 
623  bb_smscconn_sent(conn, msg, NULL);
624  } else {
625  bb_smscconn_send_failed(conn, msg,
627  }
628 }
Octstr * id
Definition: smscconn_p.h:174
#define DLR_IS_ENABLED_DEVICE(dlr)
Definition: dlr.h:82
void uuid_unparse(const uuid_t uu, char *out)
Definition: gw_uuid.c:561
void dlr_add(const Octstr *smsc, const Octstr *ts, Msg *msg, int use_dst)
Definition: dlr.c:330
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Definition: http.h:142
int octstr_ncompare(const Octstr *ostr1, const Octstr *ostr2, long n)
Definition: octstr.c:950
#define octstr_duplicate(ostr)
Definition: octstr.h:187
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:901
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
#define UUID_STR_LEN
Definition: gw_uuid.h:19
Definition: octstr.c:118
void bb_smscconn_sent(SMSCConn *conn, Msg *sms, Octstr *reply)
Definition: bb_smscconn.c:279
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
Definition: bb_smscconn.c:328
static void kannel_receive_sms ( SMSCConn conn,
HTTPClient client,
List headers,
Octstr body,
List cgivars 
)
static

Definition at line 631 of file smsc_http.c.

References account, bb_smscconn_receive(), charset, smscconn::data, debug(), dlr_find(), error(), from, gwlist_create, HTTP_ACCEPTED, http_cgi_variable(), http_destroy_headers(), http_header_add(), http_send_reply(), smscconn::id, MAX_SMS_OCTETS, meta_data_set_value(), METADATA_DLR_GROUP, METADATA_DLR_GROUP_ERRORCODE, msg, msg_create, octstr_compare(), octstr_create, octstr_destroy(), octstr_duplicate, octstr_get_char(), octstr_get_cstr, octstr_imm(), octstr_len(), conndata::password, report_mo, sms_charset_processing(), SMS_PARAM_UNDEFINED, text, and conndata::username.

633 {
634  ConnData *conndata = conn->data;
635  Octstr *user, *pass, *from, *to, *text, *udh, *account, *binfo, *charset;
636  Octstr *dlrmid, *dlrerr;
637  Octstr *tmp_string, *retmsg;
638  int mclass, mwi, coding, validity, deferred, dlrmask;
639  List *reply_headers;
640  int ret;
641 
642  mclass = mwi = coding = validity =
643  deferred = dlrmask = SMS_PARAM_UNDEFINED;
644 
645  user = http_cgi_variable(cgivars, "username");
646  pass = http_cgi_variable(cgivars, "password");
647  from = http_cgi_variable(cgivars, "from");
648  to = http_cgi_variable(cgivars, "to");
649  text = http_cgi_variable(cgivars, "text");
650  udh = http_cgi_variable(cgivars, "udh");
651  charset = http_cgi_variable(cgivars, "charset");
652  account = http_cgi_variable(cgivars, "account");
653  binfo = http_cgi_variable(cgivars, "binfo");
654  dlrmid = http_cgi_variable(cgivars, "dlr-mid");
655  tmp_string = http_cgi_variable(cgivars, "flash");
656  if (tmp_string) {
657  sscanf(octstr_get_cstr(tmp_string),"%d", &mclass);
658  }
659  tmp_string = http_cgi_variable(cgivars, "mclass");
660  if (tmp_string) {
661  sscanf(octstr_get_cstr(tmp_string),"%d", &mclass);
662  }
663  tmp_string = http_cgi_variable(cgivars, "mwi");
664  if (tmp_string) {
665  sscanf(octstr_get_cstr(tmp_string),"%d", &mwi);
666  }
667  tmp_string = http_cgi_variable(cgivars, "coding");
668  if (tmp_string) {
669  sscanf(octstr_get_cstr(tmp_string),"%d", &coding);
670  }
671  tmp_string = http_cgi_variable(cgivars, "validity");
672  if (tmp_string) {
673  sscanf(octstr_get_cstr(tmp_string),"%d", &validity);
674  }
675  tmp_string = http_cgi_variable(cgivars, "deferred");
676  if (tmp_string) {
677  sscanf(octstr_get_cstr(tmp_string),"%d", &deferred);
678  }
679  tmp_string = http_cgi_variable(cgivars, "dlr-mask");
680  if (tmp_string) {
681  sscanf(octstr_get_cstr(tmp_string),"%d", &dlrmask);
682  }
683  dlrerr = http_cgi_variable(cgivars, "dlr-err");
684 
685  debug("smsc.http.kannel", 0, "HTTP[%s]: Received an HTTP request",
686  octstr_get_cstr(conn->id));
687 
688  if (user == NULL || pass == NULL ||
689  octstr_compare(user, conndata->username) != 0 ||
690  octstr_compare(pass, conndata->password) != 0) {
691 
692  error(0, "HTTP[%s]: Authorization failure",
693  octstr_get_cstr(conn->id));
694  retmsg = octstr_create("Authorization failed for sendsms");
695  } else if (dlrmask != 0 && dlrmid != NULL) {
696  /* we got a DLR, and we don't require additional values */
697  Msg *dlrmsg;
698 
699  dlrmsg = dlr_find(conn->id,
700  dlrmid, /* message id */
701  to, /* destination */
702  dlrmask, 0);
703 
704  if (dlrmsg != NULL) {
705  dlrmsg->sms.sms_type = report_mo;
706  dlrmsg->sms.msgdata = octstr_duplicate(text);
707  dlrmsg->sms.account = octstr_duplicate(conndata->username);
708 
709  debug("smsc.http.kannel", 0, "HTTP[%s]: Received DLR for DLR-URL <%s>",
710  octstr_get_cstr(conn->id), octstr_get_cstr(dlrmsg->sms.dlr_url));
711 
712  if (dlrerr != NULL) {
713  /* pass errorcode as is */
714  if (dlrmsg->sms.meta_data == NULL)
715  dlrmsg->sms.meta_data = octstr_create("");
716 
717  meta_data_set_value(dlrmsg->sms.meta_data, METADATA_DLR_GROUP,
719  }
720 
721  ret = bb_smscconn_receive(conn, dlrmsg);
722  if (ret == -1)
723  retmsg = octstr_create("Not accepted");
724  else
725  retmsg = octstr_create("Sent.");
726  } else {
727  error(0,"HTTP[%s]: Got DLR but could not find message or was not interested "
728  "in it id<%s> dst<%s>, type<%d>",
729  octstr_get_cstr(conn->id), octstr_get_cstr(dlrmid),
730  octstr_get_cstr(to), dlrmask);
731  retmsg = octstr_create("Unknown DLR, not accepted");
732  }
733  }
734  else if (from == NULL || to == NULL || text == NULL) {
735 
736  error(0, "HTTP[%s]: Insufficient args",
737  octstr_get_cstr(conn->id));
738  retmsg = octstr_create("Insufficient args, rejected");
739  }
740  else if (udh != NULL && (octstr_len(udh) != octstr_get_char(udh, 0) + 1)) {
741  error(0, "HTTP[%s]: UDH field misformed, rejected",
742  octstr_get_cstr(conn->id));
743  retmsg = octstr_create("UDH field misformed, rejected");
744  }
745  else if (udh != NULL && octstr_len(udh) > MAX_SMS_OCTETS) {
746  error(0, "HTTP[%s]: UDH field is too long, rejected",
747  octstr_get_cstr(conn->id));
748  retmsg = octstr_create("UDH field is too long, rejected");
749  }
750  else {
751  /* we got a normal MO SMS */
752  Msg *msg;
753  msg = msg_create(sms);
754 
755  debug("smsc.http.kannel", 0, "HTTP[%s]: Constructing new SMS",
756  octstr_get_cstr(conn->id));
757 
758  msg->sms.service = octstr_duplicate(user);
759  msg->sms.sender = octstr_duplicate(from);
760  msg->sms.receiver = octstr_duplicate(to);
761  msg->sms.msgdata = octstr_duplicate(text);
762  msg->sms.udhdata = octstr_duplicate(udh);
763 
764  msg->sms.smsc_id = octstr_duplicate(conn->id);
765  msg->sms.time = time(NULL);
766  msg->sms.mclass = mclass;
767  msg->sms.mwi = mwi;
768  msg->sms.coding = coding;
769  msg->sms.validity = (validity == SMS_PARAM_UNDEFINED ? validity : time(NULL) + validity * 60);
770  msg->sms.deferred = (deferred == SMS_PARAM_UNDEFINED ? deferred : time(NULL) + deferred * 60);
771  msg->sms.account = octstr_duplicate(account);
772  msg->sms.binfo = octstr_duplicate(binfo);
773 
774  /* re-encode content if necessary */
775  if (sms_charset_processing(charset, msg->sms.msgdata, msg->sms.coding) == -1) {
776  error(0, "HTTP[%s]: Charset or body misformed, rejected",
777  octstr_get_cstr(conn->id));
778  retmsg = octstr_create("Charset or body misformed, rejected");
779  }
780  else {
781 
782  ret = bb_smscconn_receive(conn, msg);
783  if (ret == -1)
784  retmsg = octstr_create("Not accepted");
785  else
786  retmsg = octstr_create("Sent.");
787  }
788  }
789 
790  reply_headers = gwlist_create();
791  http_header_add(reply_headers, "Content-Type", "text/plain");
792  debug("smsc.http.kannel", 0, "HTTP[%s]: Sending reply",
793  octstr_get_cstr(conn->id));
794  http_send_reply(client, HTTP_ACCEPTED, reply_headers, retmsg);
795 
796  octstr_destroy(retmsg);
797  http_destroy_headers(reply_headers);
798 }
void error(int err, const char *fmt,...)
Definition: log.c:612
#define MAX_SMS_OCTETS
Definition: sms.h:129
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
Definition: msg.h:109
Octstr * id
Definition: smscconn_p.h:174
void * data
Definition: smscconn_p.h:249
#define METADATA_DLR_GROUP_ERRORCODE
Definition: meta_data.h:71
int meta_data_set_value(Octstr *data, const char *group, const Octstr *key, const Octstr *value, int replace)
Definition: meta_data.c:324
#define msg_create(type)
Definition: msg.h:136
Msg * dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int typ, int use_dst)
Definition: dlr.c:387
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * charset
Definition: test_ota.c:68
Octstr * http_cgi_variable(List *list, char *name)
Definition: http.c:2813
void http_destroy_headers(List *headers)
Definition: http.c:2856
static Octstr * from
Definition: mtbatch.c:95
void http_send_reply(HTTPClient *client, int status, List *headers, Octstr *body)
Definition: http.c:2671
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Definition: msg.h:79
long bb_smscconn_receive(SMSCConn *conn, Msg *sms)
Definition: bb_smscconn.c:478
char * text
Definition: smsc_cimd2.c:921
#define METADATA_DLR_GROUP
Definition: meta_data.h:68
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
int sms_charset_processing(Octstr *charset, Octstr *body, int coding)
Definition: sms.c:419
#define octstr_create(cstr)
Definition: octstr.h:125
#define SMS_PARAM_UNDEFINED
Definition: sms.h:91
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
Octstr * password
Definition: smsc_http.c:155
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
#define gwlist_create()
Definition: list.h:136
Octstr * username
Definition: smsc_http.c:154
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
Definition: list.c:102
static Octstr * account
Definition: mtbatch.c:94
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
static int kannel_send_sms ( SMSCConn conn,
Msg sms 
)
static

Definition at line 495 of file smsc_http.c.

References smscconn::data, DC_7BIT, DC_UCS2, DC_UNDEF, debug(), DLR_NOTHING, DLR_UNDEFINED, conndata::dlr_url, gwlist_create, HEX_NOT_UPPERCASE, http_destroy_headers(), HTTP_METHOD_GET, conndata::http_ref, http_start_request(), smscconn::id, MC_UNDEF, MWI_UNDEF, conndata::no_coding, conndata::no_sender, conndata::no_sep, octstr_append_cstr(), octstr_binary_to_hex(), octstr_create, octstr_destroy(), octstr_duplicate, octstr_format(), octstr_format_append(), octstr_get_cstr, octstr_imm(), octstr_len(), conndata::password, conndata::send_url, SMS_PARAM_UNDEFINED, url, conndata::username, UUID_STR_LEN, and uuid_unparse().

496 {
497  ConnData *conndata = conn->data;
498  Octstr *url;
499  List *headers;
500 
501  if (!conndata->no_sep) {
502  url = octstr_format("%S?"
503  "username=%E&password=%E&to=%E&text=%E",
504  conndata->send_url,
505  conndata->username, conndata->password,
506  sms->sms.receiver, sms->sms.msgdata);
507  } else {
508  Octstr *msgdata = octstr_duplicate(sms->sms.msgdata);
509 
511  url = octstr_format("%S?"
512  "username=%E&password=%E&to=%E&text=%S",
513  conndata->send_url,
514  conndata->username, conndata->password,
515  sms->sms.receiver, msgdata);
516  octstr_destroy(msgdata);
517  }
518 
519  if (octstr_len(sms->sms.udhdata)) {
520  if (!conndata->no_sep) {
521  octstr_format_append(url, "&udh=%E", sms->sms.udhdata);
522  } else {
523  Octstr *udhdata = octstr_duplicate(sms->sms.udhdata);
524 
526  octstr_format_append(url, "&udh=%S", udhdata);
527  octstr_destroy(udhdata);
528  }
529  }
530 
531  if (!conndata->no_sender)
532  octstr_format_append(url, "&from=%E", sms->sms.sender);
533  if (sms->sms.mclass != MC_UNDEF)
534  octstr_format_append(url, "&mclass=%d", sms->sms.mclass);
535  if (!conndata->no_coding && sms->sms.coding != DC_UNDEF)
536  octstr_format_append(url, "&coding=%d", sms->sms.coding);
537 
538  /* Obey that smsbox's sendsms HTTP interface is still expecting
539  * WINDOWS-1252 as default charset, while all other internal parts
540  * use UTF-8 as internal encoding. This means, when we pass a SMS
541  * into a next Kannel instance, we need to let the smsbox know which
542  * charset we have in use.
543  * XXX TODO: change smsbox interface to use UTF-8 as default
544  * in next major release. */
545  if (sms->sms.coding == DC_7BIT)
546  octstr_append_cstr(url, "&charset=UTF-8");
547  else if (sms->sms.coding == DC_UCS2)
548  octstr_append_cstr(url, "&charset=UTF-16BE");
549 
550  if (sms->sms.mwi != MWI_UNDEF)
551  octstr_format_append(url, "&mwi=%d", sms->sms.mwi);
552  if (sms->sms.account) /* prepend account with local username */
553  octstr_format_append(url, "&account=%E:%E", sms->sms.service, sms->sms.account);
554  if (sms->sms.binfo) /* prepend billing info */
555  octstr_format_append(url, "&binfo=%S", sms->sms.binfo);
556  if (sms->sms.smsc_id) /* proxy the smsc-id to the next instance */
557  octstr_format_append(url, "&smsc=%S", sms->sms.smsc_id);
558  if (conndata->dlr_url) {
559  char id[UUID_STR_LEN + 1];
560  Octstr *mid;
561 
562  /* create Octstr from UUID */
563  uuid_unparse(sms->sms.id, id);
564  mid = octstr_create(id);
565 
566  octstr_format_append(url, "&dlr-url=%E", conndata->dlr_url);
567 
568  /* encapsulate the original DLR-URL, escape code for DLR mask
569  * and message id */
570  octstr_format_append(url, "%E%E%E%E%E",
571  octstr_imm("&dlr-url="), sms->sms.dlr_url != NULL ? sms->sms.dlr_url : octstr_imm(""),
572  octstr_imm("&dlr-mask=%d"),
573  octstr_imm("&dlr-mid="), mid);
574 
575  octstr_destroy(mid);
576  } else if (sms->sms.dlr_url != NULL)
577  octstr_format_append(url, "&dlr-url=%E", sms->sms.dlr_url);
578  if (sms->sms.dlr_mask != DLR_UNDEFINED && sms->sms.dlr_mask != DLR_NOTHING)
579  octstr_format_append(url, "&dlr-mask=%d", sms->sms.dlr_mask);
580 
581  if (sms->sms.validity != SMS_PARAM_UNDEFINED)
582  octstr_format_append(url, "&validity=%ld", (sms->sms.validity - time(NULL)) / 60);
583  if (sms->sms.deferred != SMS_PARAM_UNDEFINED)
584  octstr_format_append(url, "&deferred=%ld", (sms->sms.deferred - time(NULL)) / 60);
585 
586  headers = gwlist_create();
587  debug("smsc.http.kannel", 0, "HTTP[%s]: Start request",
588  octstr_get_cstr(conn->id));
589  http_start_request(conndata->http_ref, HTTP_METHOD_GET, url, headers,
590  NULL, 0, sms, NULL);
591 
592  octstr_destroy(url);
593  http_destroy_headers(headers);
594 
595  return 0;
596 }
#define MWI_UNDEF
Definition: sms.h:99
Octstr * dlr_url
Definition: smsc_http.c:151
int no_sep
Definition: smsc_http.c:159
Octstr * id
Definition: smscconn_p.h:174
void * data
Definition: smscconn_p.h:249
HTTPCaller * http_ref
Definition: smsc_http.c:143
#define DLR_NOTHING
Definition: dlr.h:71
void uuid_unparse(const uuid_t uu, char *out)
Definition: gw_uuid.c:561
void octstr_append_cstr(Octstr *ostr, const char *cstr)
Definition: octstr.c:1509
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void octstr_binary_to_hex(Octstr *ostr, int uppercase)
Definition: octstr.c:463
void http_destroy_headers(List *headers)
Definition: http.c:2856
void http_start_request(HTTPCaller *caller, int method, Octstr *url, List *headers, Octstr *body, int follow, void *id, Octstr *certkeyfile)
Definition: http.c:1745
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
int no_coding
Definition: smsc_http.c:158
#define octstr_duplicate(ostr)
Definition: octstr.h:187
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
#define SMS_PARAM_UNDEFINED
Definition: sms.h:91
int no_sender
Definition: smsc_http.c:157
#define UUID_STR_LEN
Definition: gw_uuid.h:19
#define DLR_UNDEFINED
Definition: dlr.h:70
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
#define MC_UNDEF
Definition: sms.h:93
Definition: octstr.c:118
Octstr * password
Definition: smsc_http.c:155
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2505
#define gwlist_create()
Definition: list.h:136
Octstr * username
Definition: smsc_http.c:154
#define DC_UNDEF
Definition: sms.h:109
Octstr * send_url
Definition: smsc_http.c:150
static Octstr * url
Definition: test_xmlrpc.c:84
Definition: list.c:102
#define DC_UCS2
Definition: sms.h:112
#define DC_7BIT
Definition: sms.h:110
int smsc_http_create ( SMSCConn conn,
CfgGroup cfg 
)

Definition at line 881 of file smsc_http.c.

References conndata::allow_ip, conndata::alt_charset, conndata::callbacks, cfg_get, cfg_get_bool(), cfg_get_integer(), conndata_destroy(), smscconn::connect_time, counter_create(), conndata::data, smscconn::data, smsc_http_fn_callbacks::destroy, conndata::dlr_url, error(), gwlist_add_producer(), gwlist_create, gwthread_create, http_caller_create(), http_open_port(), conndata::http_ref, httpsmsc_queued(), httpsmsc_receiver(), httpsmsc_send(), httpsmsc_send_cb(), httpsmsc_sender(), httpsmsc_shutdown(), smscconn::id, info(), smsc_http_fn_callbacks::init, conndata::max_pending_sends, conndata::msg_to_send, smscconn::name, conndata::no_coding, conndata::no_sender, conndata::no_sep, octstr_case_compare(), octstr_destroy(), octstr_format(), octstr_get_cstr, octstr_imm(), conndata::open_sends, panic, conndata::password, conndata::port, conndata::proxy, smscconn::queued, conndata::receive_thread, semaphore_create(), conndata::send_cb_thread, smscconn::send_msg, conndata::send_url, conndata::sender_thread, conndata::shutdown, smscconn::shutdown, smsc_http_brunet_callback, smsc_http_clickatell_callback, smsc_http_generic_callback, smsc_http_kannel_callback, smsc_http_wapme_callback, smsc_http_xidris_callback, SMSCCONN_ACTIVE, SMSCCONN_ACTIVE_RECV, SMSCCONN_DEAD, SMSCCONN_KILLED_CANNOT_CONNECT, ssl, smscconn::status, conndata::system_id, type, conndata::username, warning(), and smscconn::why_killed.

Referenced by smscconn_create().

882 {
883  ConnData *conndata = NULL;
884  Octstr *type;
885  int ssl = 0; /* indicate if SSL-enabled server should be used */
886  long max_ps;
887 
888  if ((type = cfg_get(cfg, octstr_imm("system-type"))) == NULL) {
889  error(0, "HTTP[%s]: 'system-type' missing in smsc 'http' record.",
890  octstr_get_cstr(conn->id));
891  octstr_destroy(type);
892  return -1;
893  }
894 
895  conndata = gw_malloc(sizeof(ConnData));
896  /* reset conndata */
897  memset(conndata, 0, sizeof(ConnData));
898 
899  conn->data = conndata;
900  conndata->http_ref = NULL;
901  conndata->data = NULL;
902 
903  if (cfg_get_integer(&conndata->port, cfg, octstr_imm("port")) == -1) {
904  warning(0, "HTTP[%s]: 'port' not set in smsc 'http' group.",
905  octstr_get_cstr(conn->id));
906  conndata->port = -1;
907  }
908 
909  conndata->allow_ip = cfg_get(cfg, octstr_imm("connect-allow-ip"));
910  conndata->send_url = cfg_get(cfg, octstr_imm("send-url"));
911  conndata->username = cfg_get(cfg, octstr_imm("smsc-username"));
912  conndata->password = cfg_get(cfg, octstr_imm("smsc-password"));
913  conndata->system_id = cfg_get(cfg, octstr_imm("system-id"));
914  cfg_get_bool(&conndata->no_sender, cfg, octstr_imm("no-sender"));
915  cfg_get_bool(&conndata->no_coding, cfg, octstr_imm("no-coding"));
916  cfg_get_bool(&conndata->no_sep, cfg, octstr_imm("no-sep"));
917  conndata->proxy = cfg_get(cfg, octstr_imm("system-id"));
918  cfg_get_bool(&ssl, cfg, octstr_imm("use-ssl"));
919  conndata->dlr_url = cfg_get(cfg, octstr_imm("dlr-url"));
920  conndata->alt_charset = cfg_get(cfg, octstr_imm("alt-charset"));
921 
922  if (cfg_get_integer(&max_ps, cfg, octstr_imm("max-pending-submits")) == -1 || max_ps < 1)
923  max_ps = 10;
924 
925  conndata->max_pending_sends = semaphore_create(max_ps);
926 
927  if (conndata->port <= 0 && conndata->send_url == NULL) {
928  error(0, "Sender and receiver disabled. Dummy SMSC not allowed.");
929  goto error;
930  }
931  if (conndata->send_url == NULL)
932  panic(0, "HTTP[%s]: Sending not allowed. No 'send-url' specified.",
933  octstr_get_cstr(conn->id));
934 
935  if (octstr_case_compare(type, octstr_imm("kannel")) == 0) {
936  if (conndata->username == NULL || conndata->password == NULL) {
937  error(0, "HTTP[%s]: 'username' and 'password' required for Kannel http smsc",
938  octstr_get_cstr(conn->id));
939  goto error;
940  }
942  } else if (octstr_case_compare(type, octstr_imm("brunet")) == 0) {
944  } else if (octstr_case_compare(type, octstr_imm("xidris")) == 0) {
946  } else if (octstr_case_compare(type, octstr_imm("generic")) == 0) {
948  } else if (octstr_case_compare(type, octstr_imm("clickatell")) == 0) {
950  } else if (octstr_case_compare(type, octstr_imm("wapme")) == 0) {
951  conndata->callbacks = &smsc_http_wapme_callback;
952  }
953  /*
954  * ADD NEW HTTP SMSC TYPES HERE
955  */
956  else {
957  error(0, "HTTP[%s]: system-type '%s' unknown smsc 'http' record.",
958  octstr_get_cstr(conn->id), octstr_get_cstr(type));
959  goto error;
960  }
961 
962  if (conndata->callbacks != NULL && conndata->callbacks->init != NULL && conndata->callbacks->init(conn, cfg)) {
963  error(0, "HTTP[%s]: submodule '%s' init failed.", octstr_get_cstr(conn->id), octstr_get_cstr(type));
964  goto error;
965  }
966 
967  conndata->open_sends = counter_create();
968  conndata->msg_to_send = gwlist_create();
969  gwlist_add_producer(conndata->msg_to_send);
970  conndata->http_ref = http_caller_create();
971 
972  conn->name = octstr_format("HTTP%s:%S:%d", (ssl?"S":""), type, conndata->port);
973 
974  if (conndata->send_url != NULL) {
975  conn->status = SMSCCONN_ACTIVE;
976  } else {
978  }
979 
980 
981  conn->connect_time = time(NULL);
982 
983  conn->shutdown = httpsmsc_shutdown;
984  conn->queued = httpsmsc_queued;
985  conn->send_msg = httpsmsc_send;
986 
987  conndata->shutdown = 0;
988 
989  /* start receiver thread */
990  if (conndata->port > 0) {
991  if (http_open_port(conndata->port, ssl) == -1)
992  goto error;
993  if ((conndata->receive_thread = gwthread_create(httpsmsc_receiver, conn)) == -1)
994  goto error;
995  } else
996  conndata->receive_thread = -1;
997 
998  /* start sender threads */
999  if (conndata->send_url) {
1000  if ((conndata->send_cb_thread =
1001  gwthread_create(httpsmsc_send_cb, conn)) == -1)
1002  goto error;
1003  if ((conndata->sender_thread =
1004  gwthread_create(httpsmsc_sender, conn)) == -1)
1005  goto error;
1006  }
1007  else {
1008  conndata->send_cb_thread = conndata->sender_thread = -1;
1009  }
1010 
1011  info(0, "HTTP[%s]: Initiated and ready", octstr_get_cstr(conn->id));
1012 
1013  octstr_destroy(type);
1014  return 0;
1015 
1016 error:
1017  error(0, "HTTP[%s]: Failed to create HTTP SMSC connection",
1018  octstr_get_cstr(conn->id));
1019 
1020  if (conndata->callbacks != NULL && conndata->callbacks->destroy != NULL)
1021  conndata->callbacks->destroy(conn);
1022  conn->data = NULL;
1023  conndata_destroy(conndata);
1025  conn->status = SMSCCONN_DEAD;
1026  octstr_destroy(type);
1027  return -1;
1028 }
Octstr * name
Definition: smscconn_p.h:173
void error(int err, const char *fmt,...)
Definition: log.c:612
struct smsc_http_fn_callbacks smsc_http_wapme_callback
Definition: wapme.c:123
void info(int err, const char *fmt,...)
Definition: log.c:636
Octstr * dlr_url
Definition: smsc_http.c:151
void * data
Definition: smsc_http.c:170
static void httpsmsc_receiver(void *arg)
Definition: smsc_http.c:200
static void conndata_destroy(ConnData *conndata)
Definition: smsc_http.c:174
struct smsc_http_fn_callbacks smsc_http_xidris_callback
Definition: xidris.c:330
Octstr * alt_charset
Definition: smsc_http.c:161
long receive_thread
Definition: smsc_http.c:144
int ssl
int no_sep
Definition: smsc_http.c:159
Semaphore * semaphore_create(long n)
Definition: semaphore.c:81
Octstr * id
Definition: smscconn_p.h:174
void * data
Definition: smscconn_p.h:249
HTTPCaller * http_ref
Definition: smsc_http.c:143
struct smsc_http_fn_callbacks smsc_http_kannel_callback
Definition: smsc_http.c:800
int type
Definition: smsc_cimd2.c:215
Octstr * allow_ip
Definition: smsc_http.c:149
#define cfg_get(grp, varname)
Definition: cfg.h:86
struct smsc_http_fn_callbacks smsc_http_clickatell_callback
Definition: clickatell.c:308
Octstr * proxy
Definition: smsc_http.c:160
Octstr * system_id
Definition: smsc_http.c:156
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void(* destroy)(SMSCConn *conn)
Definition: smsc_http.c:136
smscconn_killed_t why_killed
Definition: smscconn_p.h:153
struct smsc_http_fn_callbacks smsc_http_brunet_callback
Definition: brunet.c:317
volatile int shutdown
Definition: smsc_http.c:147
long port
Definition: smsc_http.c:148
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Counter * open_sends
Definition: smsc_http.c:152
int no_coding
Definition: smsc_http.c:158
List * msg_to_send
Definition: smsc_http.c:162
Counter * counter_create(void)
Definition: counter.c:94
static void httpsmsc_send_cb(void *arg)
Definition: smsc_http.c:351
time_t connect_time
Definition: smscconn_p.h:155
struct smsc_http_fn_callbacks smsc_http_generic_callback
Definition: generic.c:608
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:901
long sender_thread
Definition: smsc_http.c:146
void warning(int err, const char *fmt,...)
Definition: log.c:624
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define gwthread_create(func, arg)
Definition: gwthread.h:90
int no_sender
Definition: smsc_http.c:157
static int httpsmsc_shutdown(SMSCConn *conn, int finish_sending)
Definition: smsc_http.c:846
int http_open_port(int port, int ssl)
Definition: http.c:2498
Semaphore * max_pending_sends
Definition: smsc_http.c:153
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:756
int(* init)(SMSCConn *conn, CfgGroup *cfg)
Definition: smsc_http.c:135
Definition: octstr.c:118
static long httpsmsc_queued(SMSCConn *conn)
Definition: smsc_http.c:835
int(* shutdown)(SMSCConn *conn, int finish_sending)
Definition: smscconn_p.h:229
Octstr * password
Definition: smsc_http.c:155
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
HTTPCaller * http_caller_create(void)
Definition: http.c:897
#define gwlist_create()
Definition: list.h:136
long(* queued)(SMSCConn *conn)
Definition: smscconn_p.h:240
int(* send_msg)(SMSCConn *conn, Msg *msg)
Definition: smscconn_p.h:235
Octstr * username
Definition: smsc_http.c:154
static int httpsmsc_send(SMSCConn *conn, Msg *msg)
Definition: smsc_http.c:810
Octstr * send_url
Definition: smsc_http.c:150
void gwlist_add_producer(List *list)
Definition: list.c:383
static void httpsmsc_sender(void *arg)
Definition: smsc_http.c:281
struct smsc_http_fn_callbacks * callbacks
Definition: smsc_http.c:167
long send_cb_thread
Definition: smsc_http.c:145

Variable Documentation

struct smsc_http_fn_callbacks smsc_http_kannel_callback
Initial value:
= {
.send_sms = kannel_send_sms,
.parse_reply = kannel_parse_reply,
.receive_sms = kannel_receive_sms,
}
static void kannel_parse_reply(SMSCConn *conn, Msg *msg, int status, List *headers, Octstr *body)
Definition: smsc_http.c:598
static void kannel_receive_sms(SMSCConn *conn, HTTPClient *client, List *headers, Octstr *body, List *cgivars)
Definition: smsc_http.c:631
static int kannel_send_sms(SMSCConn *conn, Msg *sms)
Definition: smsc_http.c:495

Definition at line 800 of file smsc_http.c.

Referenced by smsc_http_create().

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