Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
fakesmsc.c File Reference
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>
#include <limits.h>
#include <signal.h>
#include <sys/param.h>
#include "gwlib/gwlib.h"

Go to the source code of this file.

Macros

#define IN_BUFSIZE   256 /* Buffer size for stdin */
 
#define IN_TIMEOUT   1 /* Timeout for stdin */
 

Functions

static void signal_handler (int signum)
 
static void setup_signal_handlers (void)
 
static Octstrchoose_message (Octstr **msgs, int num_msgs)
 
static double get_current_time (void)
 
static int check_args (int i, int argc, char **argv)
 
static Octstrrandomize (Octstr *os)
 
int main (int argc, char **argv)
 

Variables

static char usage []
 
static int port = 10000
 
static Octstrhost
 
static long max_send = LONG_MAX
 
static double interval = 1.0
 
static int sigint_received
 
static int rnd = 0
 

Macro Definition Documentation

#define IN_BUFSIZE   256 /* Buffer size for stdin */

Definition at line 116 of file fakesmsc.c.

Referenced by main().

#define IN_TIMEOUT   1 /* Timeout for stdin */

Definition at line 117 of file fakesmsc.c.

Referenced by main().

Function Documentation

static int check_args ( int  i,
int  argc,
char **  argv 
)
static

Definition at line 166 of file fakesmsc.c.

References interval, max_send, octstr_create, panic, rnd, and usage.

Referenced by main().

167 {
168  if (strcmp(argv[i], "-r")==0 || strcmp(argv[i], "--port")==0)
169  port = atoi(argv[i+1]);
170  else if (!strcmp(argv[i], "-H") || !strcmp(argv[i], "--host"))
171  host = octstr_create(argv[i+1]);
172  else if (strcmp(argv[i], "-m")==0 || strcmp(argv[i], "--messages")==0) {
173  max_send = atoi(argv[i+1]);
174  if (max_send < 0)
175  max_send = LONG_MAX;
176  }
177  else if (strcmp(argv[i], "-i")==0 || strcmp(argv[i], "--interval")==0)
178  interval = atof(argv[i+1]);
179  else if (strcmp(argv[i], "-z")==0 || strcmp(argv[i], "--randomize")==0) {
180  rnd = atoi(argv[i+1]);
181  if (rnd < 0 || rnd > 7)
182  rnd = 0;
183  }
184  else {
185  panic(0, "%s", usage);
186  return 0;
187  }
188 
189  return 1;
190 }
Definition: http.c:1998
static char usage[]
Definition: fakesmsc.c:77
static Octstr * host
Definition: fakesmsc.c:121
static double interval
Definition: fakesmsc.c:123
static long max_send
Definition: fakesmsc.c:122
#define octstr_create(cstr)
Definition: octstr.h:125
#define panic
Definition: log.h:87
static int rnd
Definition: fakesmsc.c:125
static Octstr* choose_message ( Octstr **  msgs,
int  num_msgs 
)
static

Definition at line 148 of file fakesmsc.c.

References gw_rand().

Referenced by main().

149 {
150  /* the following doesn't give an even distribution, but who cares */
151  return msgs[gw_rand() % num_msgs];
152 }
int gw_rand(void)
Definition: protected.c:174
static double get_current_time ( void  )
static

Definition at line 156 of file fakesmsc.c.

Referenced by main().

157 {
158  struct timezone tz;
159  struct timeval now;
160 
161  gettimeofday(&now, &tz);
162  return (double) now.tv_sec + now.tv_usec / 1e6;
163 }
int main ( int  argc,
char **  argv 
)

Definition at line 222 of file fakesmsc.c.

References check_args(), choose_message(), conn_destroy(), conn_eof(), conn_error(), conn_open_tcp(), conn_read_line(), conn_wait(), conn_write(), debug(), end_time, get_and_set_debugs(), get_current_time(), gwlib_init(), IN_BUFSIZE, IN_TIMEOUT, info(), interval, max_send, msg, num_sent, octstr_append_char(), octstr_create, octstr_destroy(), octstr_get_cstr, panic, randomize(), rnd, server(), setup_signal_handlers(), sigint_received, and start_time.

223 {
225  Octstr *line;
226  Octstr **msgs;
227  int i;
228  int mptr, num_msgs;
229  long num_received, num_sent;
230  double first_received_at, last_received_at;
231  double first_sent_at, last_sent_at;
232  double start_time, end_time;
233  double delta;
234  int interactive, maxfd;
235  char *cptr;
236  char buffer[IN_BUFSIZE];
237  fd_set rset;
238  struct timeval alarm;
239  FILE *fp;
240 
241  gwlib_init();
243  host = octstr_create("localhost");
244  start_time = get_current_time();
245 
246  mptr = get_and_set_debugs(argc, argv, check_args);
247  num_msgs = argc - mptr;
248 
249  interactive = 0;
250  msgs = NULL;
251  fp = NULL;
252  if (num_msgs <= 0) {
253  interactive = 1;
254  num_msgs = 0;
255  info(0, "Entering interactive mode. Type your message on the command line");
256  /* set up file pointer to stdin */
257  fp = stdin;
258  /* initialize set for select */
259  FD_ZERO(&rset);
260  } else {
261  msgs = gw_malloc(sizeof(Octstr *) * num_msgs);
262  for (i = 0; i < num_msgs; i ++) {
263  msgs[i] = octstr_create(argv[mptr + i]);
264  octstr_append_char(msgs[i], 10); /* End of line */
265  }
266  info(0, "Host %s Port %d interval %.3f max-messages %ld",
268 
269  srand((unsigned int) time(NULL));
270  }
271  info(0, "fakesmsc starting");
272  server = conn_open_tcp(host, port, NULL);
273  if (server == NULL)
274  panic(0, "Failed to open connection");
275 
276  num_sent = 0;
277  num_received = 0;
278 
279  first_received_at = 0;
280  first_sent_at = 0;
281  last_received_at = 0;
282  last_sent_at = 0;
283 
284  /* infinitely loop */
285  while (1) {
286  /* Are we on interactive mode? */
287  if (interactive == 1) {
288  /* Check if we need to clean things up beforehand */
289  if ( num_msgs > 0 ) {
290  for (i = 0; i < num_msgs; i ++)
291  octstr_destroy(msgs[i]);
292  gw_free(msgs);
293  num_msgs = 0;
294  }
295 
296  /* we want either the file pointer or timer */
297  FD_SET(fileno(fp), &rset);
298  /* get the largest file descriptor */
299  maxfd = fileno(fp) + 1;
300 
301  /* set timer to go off in 3 seconds */
302  alarm.tv_sec = IN_TIMEOUT;
303  alarm.tv_usec = 0;
304 
305  if (select(maxfd, &rset, NULL, NULL, &alarm) == -1)
306  goto over;
307  /* something went off, let's see if it's stdin */
308  if (FD_ISSET(fileno(fp), &rset)) { /* stdin is readable */
309  cptr = fgets(buffer, IN_BUFSIZE, stdin);
310  if (!cptr)
311  goto over;
312  if( strlen( cptr ) < 2 )
313  goto rcv;
314  } else { /* timer kicked in */
315  goto rcv;
316  }
317  num_msgs = 1;
318  msgs = gw_malloc(sizeof(Octstr*));
319  msgs[0] = octstr_create(cptr);
320  }
321  /* if we still have something to send as MO message */
322  if (num_sent < max_send) {
323  Octstr *os = choose_message(msgs, num_msgs);
324  Octstr *msg = rnd > 0 ? randomize(os) : os;
325 
326  if (conn_write(server, msg) == -1)
327  panic(0, "write failed");
328 
329  ++num_sent;
330  if (num_sent == max_send)
331  info(0, "fakesmsc: sent message %ld", num_sent);
332  else
333  debug("send", 0, "fakesmsc: sent message %ld", num_sent);
334 
335  if (rnd > 0)
336  octstr_destroy(msg);
337 
338  last_sent_at = get_current_time();
339  if (first_sent_at == 0)
340  first_sent_at = last_sent_at;
341  }
342 rcv:
343  do {
344  delta = interval * num_sent - (get_current_time() - first_sent_at);
345  if (delta < 0)
346  delta = 0;
347  if (num_sent >= max_send)
348  delta = -1;
349  conn_wait(server, delta);
350  if (conn_error(server) || conn_eof(server) || sigint_received)
351  goto over;
352 
353  /* read as much as the smsc module provides us */
354  while ((line = conn_read_line(server))) {
355  last_received_at = get_current_time();
356  if (first_received_at == 0)
357  first_received_at = last_received_at;
358  ++num_received;
359  if (num_received == max_send) {
360  info(0, "Got message %ld: <%s>", num_received,
361  octstr_get_cstr(line));
362  } else {
363  debug("receive", 0, "Got message %ld: <%s>", num_received,
364  octstr_get_cstr(line));
365  }
366  octstr_destroy(line);
367  }
368  } while (delta > 0 || num_sent >= max_send);
369  }
370 
371 over:
372  conn_destroy(server);
373 
374  /* destroy the MO messages */
375  for (i = 0; i < num_msgs; i ++)
376  octstr_destroy(msgs[i]);
377  gw_free(msgs);
378 
379  end_time = get_current_time();
380 
381  info(0, "fakesmsc: %ld messages sent and %ld received", num_sent, num_received);
382  info(0, "fakesmsc: total running time %.1f seconds", end_time - start_time);
383  delta = last_sent_at - first_sent_at;
384  if (delta == 0)
385  delta = .01;
386  if (num_sent > 1)
387  info(0, "fakesmsc: from first to last sent message %.1f s, "
388  "%.1f msgs/s", delta, (num_sent - 1) / delta);
389  delta = last_received_at - first_received_at;
390  if (delta == 0)
391  delta = .01;
392  if (num_received > 1)
393  info(0, "fakesmsc: from first to last received message %.1f s, "
394  "%.1f msgs/s", delta, (num_received - 1) / delta);
395  info(0, "fakesmsc: terminating");
396 
397  return 0;
398 }
Octstr * conn_read_line(Connection *conn)
Definition: conn.c:1126
void info(int err, const char *fmt,...)
Definition: log.c:636
#define IN_TIMEOUT
Definition: fakesmsc.c:117
Definition: http.c:1998
Connection * conn_open_tcp(Octstr *host, int port, Octstr *our_host)
Definition: conn.c:488
static Octstr * choose_message(Octstr **msgs, int num_msgs)
Definition: fakesmsc.c:148
static void setup_signal_handlers(void)
Definition: fakesmsc.c:136
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1515
static Octstr * randomize(Octstr *os)
Definition: fakesmsc.c:193
static Octstr * host
Definition: fakesmsc.c:121
static double interval
Definition: fakesmsc.c:123
int conn_eof(Connection *conn)
Definition: conn.c:697
static long max_send
Definition: fakesmsc.c:122
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static time_t start_time
Definition: bearerbox.c:148
int conn_write(Connection *conn, Octstr *data)
Definition: conn.c:1043
int num_sent
Definition: fakewap.c:240
void conn_destroy(Connection *conn)
Definition: conn.c:619
time_t end_time
Definition: fakewap.c:241
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
static int check_args(int i, int argc, char **argv)
Definition: fakesmsc.c:166
Definition: octstr.c:118
int conn_wait(Connection *conn, double seconds)
Definition: conn.c:896
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
#define panic
Definition: log.h:87
#define IN_BUFSIZE
Definition: fakesmsc.c:116
static void server(int lport, int pport)
static int rnd
Definition: fakesmsc.c:125
void gwlib_init(void)
Definition: gwlib.c:78
int conn_error(Connection *conn)
Definition: conn.c:708
static int sigint_received
Definition: fakesmsc.c:124
int get_and_set_debugs(int argc, char **argv, int(*find_own)(int index, int argc, char **argv))
Definition: utils.c:626
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static double get_current_time(void)
Definition: fakesmsc.c:156
static Octstr* randomize ( Octstr os)
static

Definition at line 193 of file fakesmsc.c.

References gw_rand(), gwlist_destroy(), gwlist_get(), gwlist_len(), msg, octstr_append_char(), octstr_create, octstr_destroy_item(), octstr_format_append(), octstr_split_words(), and rnd.

Referenced by main().

194 {
195  Octstr *msg = octstr_create("");
196  List *words = octstr_split_words(os);
197  int i;
198 
199  /* randomize source and receiver number */
200  octstr_format_append(msg, "%S", gwlist_get(words, 0));
201  if (rnd & 0x1)
202  octstr_format_append(msg, "%d", gw_rand());
203 
204  octstr_format_append(msg, " %S", gwlist_get(words, 1));
205  if (rnd & 0x2)
206  octstr_format_append(msg, "%d", gw_rand());
207 
208  for (i = 2; i < gwlist_len(words); i++)
209  octstr_format_append(msg, " %S", gwlist_get(words, i));
210 
211  if (rnd & 0x4)
212  octstr_format_append(msg, " %d", gw_rand());
213 
214  octstr_append_char(msg, 10); /* End of line */
215 
217 
218  return msg;
219 }
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1515
List * octstr_split_words(const Octstr *ostr)
Definition: octstr.c:1600
#define octstr_create(cstr)
Definition: octstr.h:125
void octstr_destroy_item(void *os)
Definition: octstr.c:334
Definition: octstr.c:118
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2505
static int rnd
Definition: fakesmsc.c:125
int gw_rand(void)
Definition: protected.c:174
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
static void setup_signal_handlers ( void  )
static

Definition at line 136 of file fakesmsc.c.

References signal_handler().

Referenced by main().

137 {
138  struct sigaction act;
139 
140  act.sa_handler = signal_handler;
141  sigemptyset(&act.sa_mask);
142  act.sa_flags = 0;
143  sigaction(SIGINT, &act, NULL);
144 }
static void signal_handler(int signum)
Definition: fakesmsc.c:127
static void signal_handler ( int  signum)
static

Definition at line 127 of file fakesmsc.c.

References panic, and sigint_received.

Referenced by setup_signal_handlers().

128 {
129  if (signum == SIGINT)
130  sigint_received = 1;
131  else
132  panic(0, "Caught signal with no handler?!");
133 }
#define panic
Definition: log.h:87
static int sigint_received
Definition: fakesmsc.c:124

Variable Documentation

Octstr* host
static
double interval = 1.0
static

Definition at line 123 of file fakesmsc.c.

Referenced by check_args(), and main().

long max_send = LONG_MAX
static

Definition at line 122 of file fakesmsc.c.

Referenced by check_args(), and main().

int rnd = 0
static

Definition at line 125 of file fakesmsc.c.

Referenced by check_args(), main(), and randomize().

int sigint_received
static

Definition at line 124 of file fakesmsc.c.

Referenced by main(), and signal_handler().

char usage[]
static
Initial value:
= "\n\
Usage: fakesmsc [-H host] [-r port] [-i interval] [-m max] [-z <type>] <msg> ... \n\
\n\
* 'host' and 'port' define bearerbox connection (default localhost:10000),\n\
* 'interval' is time in seconds (floats allowed) between generated messages,\n\
* 'max' is the total number sent (-1, default, means unlimited),\n\
* <type> bitmask of which elements to add randomized numbers for MO messages,\n\
* 1: src no, 2: recv no, 4: last text element,\n\
* where the given static elements in <msg> are used as constant prefixes,\n\
* <msg> is message to send, if several are given, they are sent randomly.\n\
\n\
msg format: \"sender receiver type(text|data|ucs2|udh-data|udh-text|route|dlr-mask) [udhdata|route|dlrmask] msgdata\"\n\
\n\
Type \"text\" means plaintext msgdata, \"data\" urlcoded, \"udh\" url-encoded udh+msg,\n\
\"ucs2\" unicode url-encoded msgdata and \"route\" means smsbox-id routed plaintext msgdata\n\
Examples: \n\
\n\
fakesmsc -m 1 \"123 345 udh %04udh%3f message+data+here\"\n\
fakesmsc -m 1 \"123 345 route smsbox1 message+data+here\"\n\
fakesmsc -i 0.01 -m 1000 \"123 345 text nop\" \"1 2 text another message here\"\n\
fakesmsc -z 7 -m 1000 \"123<rand> 345<rand> text nop <rand>\"\n\
\n\
Server replies are shown in the same message format.\n"

Definition at line 77 of file fakesmsc.c.

Referenced by check_args().

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