Kannel: Open Source WAP and SMS gateway  svn-r5335
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

◆ IN_BUFSIZE

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

Definition at line 117 of file fakesmsc.c.

Referenced by main().

◆ IN_TIMEOUT

#define IN_TIMEOUT   1 /* Timeout for stdin */

Definition at line 118 of file fakesmsc.c.

Referenced by main().

Function Documentation

◆ check_args()

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

Definition at line 167 of file fakesmsc.c.

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

Referenced by main().

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

◆ choose_message()

static Octstr* choose_message ( Octstr **  msgs,
int  num_msgs 
)
static

Definition at line 149 of file fakesmsc.c.

References gw_rand().

Referenced by main().

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

◆ get_current_time()

static double get_current_time ( void  )
static

Definition at line 157 of file fakesmsc.c.

Referenced by main().

158 {
159  struct timezone tz;
160  struct timeval now;
161 
162  gettimeofday(&now, &tz);
163  return (double) now.tv_sec + now.tv_usec / 1e6;
164 }

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 223 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(), host, 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.

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

◆ randomize()

static Octstr* randomize ( Octstr os)
static

Definition at line 194 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().

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

◆ setup_signal_handlers()

static void setup_signal_handlers ( void  )
static

Definition at line 137 of file fakesmsc.c.

References signal_handler().

Referenced by main().

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

◆ signal_handler()

static void signal_handler ( int  signum)
static

Definition at line 128 of file fakesmsc.c.

References panic, and sigint_received.

Referenced by setup_signal_handlers().

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

Variable Documentation

◆ host

◆ interval

double interval = 1.0
static

Definition at line 124 of file fakesmsc.c.

Referenced by check_args(), and main().

◆ max_send

long max_send = LONG_MAX
static

Definition at line 123 of file fakesmsc.c.

Referenced by check_args(), and main().

◆ port

◆ rnd

int rnd = 0
static

Definition at line 126 of file fakesmsc.c.

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

◆ sigint_received

int sigint_received
static

Definition at line 125 of file fakesmsc.c.

Referenced by main(), and signal_handler().

◆ usage

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\" url-encoded, \"udh\" url-encoded udh+msg,\n\
\"utf8\" utf-8 url-encoded msgdata, \"ucs2\" unicode url-encoded msgdata \n\
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.