Kannel: Open Source WAP and SMS gateway  svn-r5335
emimsg.c File Reference
#include "emimsg.h"

Go to the source code of this file.

Functions

static char * emi_strerror (int errnum)
 
static int field_count_op (int ot, Octstr *whoami)
 
static int field_count_reply (int ot, int posit, Octstr *whoami)
 
static struct emimsgemimsg_create_withlen (int len)
 
struct emimsgemimsg_create_op (int ot, int trn, Octstr *whoami)
 
static struct emimsgemimsg_create_reply_s (int ot, int trn, int positive, Octstr *whoami)
 
struct emimsgemimsg_create_reply (int ot, int trn, int positive, Octstr *whoami)
 
void emimsg_destroy (struct emimsg *emimsg)
 
struct emimsgemimsg_duplicate (struct emimsg *emimsg)
 
static int calculate_checksum (Octstr *message)
 
static Octstremimsg_tostring (struct emimsg *emimsg)
 
struct emimsgget_fields (Octstr *message, Octstr *whoami)
 
int emimsg_send (Connection *conn, struct emimsg *emimsg, Octstr *whoami)
 

Function Documentation

◆ calculate_checksum()

static int calculate_checksum ( Octstr message)
static

Definition at line 252 of file emimsg.c.

References octstr_get_char(), and octstr_len().

Referenced by emimsg_tostring(), and get_fields().

253 {
254  int end, i, checksum;
255 
256  end = octstr_len(message);
257  if (octstr_get_char(message, end - 1) == 3) /* etx, whole message */
258  end -= 3;
259  checksum = 0;
260  for (i = 1; i < end; i++)
261  checksum += octstr_get_char(message, i);
262  return checksum & 0xff;
263 }
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ emi_strerror()

static char* emi_strerror ( int  errnum)
static

Definition at line 67 of file emimsg.c.

Referenced by get_fields().

68 {
69  switch (errnum) {
70  case 1: return "Checksum error";
71  case 2: return "Syntax error";
72  case 3: return "Operation not supported by system";
73  case 4: return "Operation not allowed";
74  case 5: return "Call barring active";
75  case 6: return "AdC invalid";
76  case 7: return "Authentication failure";
77  case 8: return "Legitimisation code for all calls, failure";
78  case 9: return "GA not valid";
79  case 10: return "Repetition not allowed";
80  case 11: return "Legitimisation code for repetition, failure";
81  case 12: return "Priority call not allowed";
82  case 13: return "Legitimisation code for priority call, failure";
83  case 14: return "Urgent message not allowed";
84  case 15: return "Legitimisation code for urgent message, failure";
85  case 16: return "Reverse charging not allowed";
86  case 17: return "Legitimisation code for reverse charging, failure";
87  case 18: return "Deferred delivery not allowed";
88  case 19: return "New AC not valid";
89  case 20: return "New legitimisation code not valid";
90  case 21: return "Standard text not valid";
91  case 22: return "Time period not valid";
92  case 23: return "Message type not supported by system";
93  case 24: return "Message too long";
94  case 25: return "Requested standard text not valid";
95  case 26: return "Message type not valid for the pager type";
96  case 27: return "Message not found in smsc";
97  case 30: return "Subscriber hang-up";
98  case 31: return "Fax group not supported";
99  case 32: return "Fax message type not supported";
100  case 33: return "Address already in list (60 series)";
101  case 34: return "Address not in list (60 series)";
102  case 35: return "List full, cannot add address to list (60 series)";
103  case 36: return "RPID already in use";
104  case 37: return "Delivery in progress";
105  case 38: return "Message forwarded";
106  default: return "!UNRECOGNIZED ERROR CODE!";
107  }
108 }

◆ emimsg_create_op()

struct emimsg* emimsg_create_op ( int  ot,
int  trn,
Octstr whoami 
)

Definition at line 166 of file emimsg.c.

References emimsg_create_withlen(), field_count_op(), emimsg::or, emimsg::ot, and emimsg::trn.

Referenced by get_fields(), make_emi31(), make_emi60(), and msg_to_emimsg().

167 {
168  int len;
169  struct emimsg *ret;
170 
171  len = field_count_op(ot, whoami);
172  if (len < 0)
173  return NULL;
174  ret = emimsg_create_withlen(len);
175  ret->ot = ot;
176  ret->or = 'O';
177  ret->trn = trn;
178  return ret;
179 }
char or
Definition: emimsg.h:72
int trn
Definition: emimsg.h:71
Definition: emimsg.h:70
static struct emimsg * emimsg_create_withlen(int len)
Definition: emimsg.c:153
int ot
Definition: emimsg.h:73
static int field_count_op(int ot, Octstr *whoami)
Definition: emimsg.c:111

◆ emimsg_create_reply()

struct emimsg* emimsg_create_reply ( int  ot,
int  trn,
int  positive,
Octstr whoami 
)

Definition at line 199 of file emimsg.c.

References emimsg_create_reply_s(), emimsg::fields, octstr_create, emimsg::ot, and emimsg::trn.

Referenced by handle_operation().

201 {
202  struct emimsg *ret;
203 
204  ret = emimsg_create_reply_s(ot, trn, positive, whoami);
205  if (ret) {
206  if (positive)
207  ret->fields[0] = octstr_create("A");
208  else
209  ret->fields[0] = octstr_create("N");
210  }
211  return ret;
212 }
int trn
Definition: emimsg.h:71
Definition: emimsg.h:70
#define octstr_create(cstr)
Definition: octstr.h:125
int ot
Definition: emimsg.h:73
Octstr ** fields
Definition: emimsg.h:75
static struct emimsg * emimsg_create_reply_s(int ot, int trn, int positive, Octstr *whoami)
Definition: emimsg.c:182

◆ emimsg_create_reply_s()

static struct emimsg* emimsg_create_reply_s ( int  ot,
int  trn,
int  positive,
Octstr whoami 
)
static

Definition at line 182 of file emimsg.c.

References emimsg_create_withlen(), field_count_reply(), emimsg::or, emimsg::ot, and emimsg::trn.

Referenced by emimsg_create_reply(), and get_fields().

184 {
185  int len;
186  struct emimsg *ret;
187 
188  len = field_count_reply(ot, positive, whoami);
189  if (len < 0)
190  return NULL;
191  ret = emimsg_create_withlen(len);
192  ret->ot = ot;
193  ret->or = 'R';
194  ret->trn = trn;
195  return ret;
196 }
char or
Definition: emimsg.h:72
static int field_count_reply(int ot, int posit, Octstr *whoami)
Definition: emimsg.c:132
int trn
Definition: emimsg.h:71
Definition: emimsg.h:70
static struct emimsg * emimsg_create_withlen(int len)
Definition: emimsg.c:153
int ot
Definition: emimsg.h:73

◆ emimsg_create_withlen()

static struct emimsg* emimsg_create_withlen ( int  len)
static

Definition at line 153 of file emimsg.c.

References emimsg::fields, and emimsg::num_fields.

Referenced by emimsg_create_op(), and emimsg_create_reply_s().

154 {
155  struct emimsg *ret;
156 
157  ret = gw_malloc(sizeof(struct emimsg));
158  ret->fields = gw_malloc(len * sizeof(Octstr *));
159  ret->num_fields = len;
160  while (--len >= 0)
161  ret->fields[len] = NULL;
162  return ret;
163 }
Definition: emimsg.h:70
Definition: octstr.c:118
Octstr ** fields
Definition: emimsg.h:75
int num_fields
Definition: emimsg.h:74

◆ emimsg_destroy()

void emimsg_destroy ( struct emimsg emimsg)

Definition at line 215 of file emimsg.c.

References emimsg::fields, emimsg::num_fields, and octstr_destroy().

Referenced by emi2_do_send(), emi2_handle_smscreq(), emi2_keepalive_handling(), emi2_receiver(), get_fields(), handle_operation(), open_send_connection(), and wait_for_ack().

216 {
217  int len;
218 
219  len = emimsg->num_fields;
220  while (--len >= 0) {
221  octstr_destroy(emimsg->fields[len]); /* octstr_destroy(NULL) is ok */
222  emimsg->fields[len] = NULL;
223  }
224  gw_free(emimsg->fields);
225  gw_free(emimsg);
226 }
Definition: emimsg.h:70
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Octstr ** fields
Definition: emimsg.h:75
int num_fields
Definition: emimsg.h:74

◆ emimsg_duplicate()

struct emimsg* emimsg_duplicate ( struct emimsg emimsg)

Definition at line 229 of file emimsg.c.

References emimsg::fields, emimsg::num_fields, octstr_duplicate, emimsg::or, emimsg::ot, and emimsg::trn.

230 {
231  int len;
232  struct emimsg *ret;
233 
234  len = emimsg->num_fields;
235  if (len < 0)
236  return NULL;
237  ret = gw_malloc(sizeof(struct emimsg));
238  ret->fields = gw_malloc(len * sizeof(Octstr *));
239  ret->num_fields = len;
240  while (--len >= 0)
241  ret->fields[len] = octstr_duplicate(emimsg->fields[len]);
242  ret->ot = emimsg->ot;
243  ret->or = emimsg->or;
244  ret->trn = emimsg->trn;
245 
246  return ret;
247 }
char or
Definition: emimsg.h:72
int trn
Definition: emimsg.h:71
Definition: emimsg.h:70
#define octstr_duplicate(ostr)
Definition: octstr.h:187
int ot
Definition: emimsg.h:73
Definition: octstr.c:118
Octstr ** fields
Definition: emimsg.h:75
int num_fields
Definition: emimsg.h:74

◆ emimsg_send()

int emimsg_send ( Connection conn,
struct emimsg emimsg,
Octstr whoami 
)

Definition at line 368 of file emimsg.c.

References conn_write(), debug(), emimsg_tostring(), error(), octstr_destroy(), octstr_get_cstr, and emimsg::ot.

Referenced by emi2_emimsg_send().

369 {
370  Octstr *string;
371 
372  string = emimsg_tostring(emimsg);
373  if (!string) {
374  error(0, "EMI2[%s]: emimsg_send: conversion to string failed",
375  octstr_get_cstr(whoami));
376  return -1;
377  }
378  if (emimsg->ot == 60)
379  debug("smsc.emi2", 0, "EMI2[%s]: Sending operation type 60, message with "
380  "password not shown in log file.", octstr_get_cstr(whoami));
381  else
382  debug("smsc.emi2", 0, "EMI2[%s]: emi2 sending packet: <%s>",
383  octstr_get_cstr(whoami), octstr_get_cstr(string));
384  if (conn_write(conn, string) == -1) {
385  octstr_destroy(string);
386  error(0, "EMI2[%s]: emimsg_send: write failed",
387  octstr_get_cstr(whoami));
388  return -1;
389  }
390  octstr_destroy(string);
391  return 1;
392 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static Octstr * emimsg_tostring(struct emimsg *emimsg)
Definition: emimsg.c:266
Definition: emimsg.h:70
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
int conn_write(Connection *conn, Octstr *data)
Definition: conn.c:1051
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
int ot
Definition: emimsg.h:73
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726

◆ emimsg_tostring()

static Octstr* emimsg_tostring ( struct emimsg emimsg)
static

Definition at line 266 of file emimsg.c.

References calculate_checksum(), emimsg::fields, emimsg::num_fields, octstr_append(), octstr_append_char(), octstr_create, octstr_destroy(), octstr_format(), octstr_len(), emimsg::or, emimsg::ot, and emimsg::trn.

Referenced by emimsg_send().

267 {
268  int i, checksum;
269  Octstr *result, *data;
270  char *hexits = "0123456789ABCDEF";
271 
272  data = octstr_create("");
273  for (i = 0; i < emimsg->num_fields; i++) {
274  if (emimsg->fields[i])
275  octstr_append(data, emimsg->fields[i]);
276  octstr_append_char(data, '/');
277  }
278  result = octstr_format("\02%02d/%05d/%c/%02d/%S", emimsg->trn,
279  octstr_len(data) + 16, emimsg->or, emimsg->ot, data);
280  checksum = calculate_checksum(result);
281  octstr_append_char(result, hexits[checksum >> 4 & 15]);
282  octstr_append_char(result, hexits[checksum & 15]);
283  octstr_append_char(result, 3);
284  octstr_destroy(data);
285  return result;
286 }
char or
Definition: emimsg.h:72
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517
int trn
Definition: emimsg.h:71
Definition: emimsg.h:70
static int calculate_checksum(Octstr *message)
Definition: emimsg.c:252
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
int ot
Definition: emimsg.h:73
Definition: octstr.c:118
Octstr ** fields
Definition: emimsg.h:75
int num_fields
Definition: emimsg.h:74

◆ field_count_op()

static int field_count_op ( int  ot,
Octstr whoami 
)
static

Definition at line 111 of file emimsg.c.

References error(), octstr_get_cstr, SZ01, SZ50, and SZ60.

Referenced by emimsg_create_op().

112 {
113  switch (ot) {
114  case 01:
115  return SZ01;
116  case 31:
117  return 2;
118  case 51:
119  case 52:
120  case 53:
121  return SZ50;
122  case 60:
123  return SZ60;
124  default:
125  error(0, "EMI2[%s]: Unsupported EMI operation request type %d",
126  octstr_get_cstr(whoami), ot);
127  return -1;
128  }
129 }
void error(int err, const char *fmt,...)
Definition: log.c:648
Definition: emimsg.h:91
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Definition: emimsg.h:81
Definition: emimsg.h:97
int ot
Definition: emimsg.h:73

◆ field_count_reply()

static int field_count_reply ( int  ot,
int  posit,
Octstr whoami 
)
static

Definition at line 132 of file emimsg.c.

References error(), and octstr_get_cstr.

Referenced by emimsg_create_reply_s().

133 {
134  switch(ot) {
135  case 01:
136  return posit ? 2 : 3;
137  case 31:
138  return posit ? 2 : 3;
139  case 51:
140  case 52:
141  case 53:
142  return 3;
143  case 60:
144  return posit ? 2 : 3;
145  default:
146  error(0, "EMI2[%s]: Unsupported EMI operation reply type %d",
147  octstr_get_cstr(whoami), ot);
148  return -1;
149  }
150 }
void error(int err, const char *fmt,...)
Definition: log.c:648
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
int ot
Definition: emimsg.h:73

◆ get_fields()

struct emimsg* get_fields ( Octstr message,
Octstr whoami 
)

Definition at line 290 of file emimsg.c.

References calculate_checksum(), debug(), emi_strerror(), emimsg_create_op(), emimsg_create_reply_s(), emimsg_destroy(), error(), emimsg::fields, emimsg::num_fields, octstr_copy, octstr_get_char(), octstr_get_cstr, octstr_len(), octstr_parse_long(), octstr_search_char(), emimsg::or, emimsg::ot, emimsg::trn, and warning().

Referenced by emi2_handle_smscreq(), emi2_receiver(), main(), and wait_for_ack().

291 {
292  long trn, len, ot, checksum; /* because of Octstr_parse_long... */
293  char or, posit;
294  long fieldno, pos, pos2;
295  struct emimsg *result = NULL;
296 
297  debug("smsc.emi2", 0, "EMI2[%s]: emi2 parsing packet: <%s>",
298  octstr_get_cstr(whoami), octstr_get_cstr(message));
299  if (octstr_get_char(message, 0) != 2 ||
300  octstr_get_char(message, octstr_len(message) - 1) != 3)
301  goto error;
302  if (octstr_parse_long(&trn, message, 1, 10) != 3)
303  goto error;
304  if (octstr_parse_long(&len, message, 4, 10) != 9)
305  goto error;
306  if (octstr_len(message) != len + 2) /* +2 for start/end markers */
307  goto error;
308  if ( (or = octstr_get_char(message, 10)) != 'O' && or != 'R')
309  goto error;
310  if (octstr_parse_long(&ot, message, 12, 10) != 14)
311  goto error;
312  if (or == 'O')
313  result = emimsg_create_op(ot, trn, whoami);
314  else {
315  posit = octstr_get_char(message, 15);
316  if (posit == 'A')
317  result = emimsg_create_reply_s(ot, trn, 1, whoami);
318  else if (posit == 'N')
319  result = emimsg_create_reply_s(ot, trn, 0, whoami);
320  else
321  goto error;
322  }
323  if (result == NULL)
324  goto error;
325  pos2 = 14;
326  for (fieldno = 0; fieldno < result->num_fields; fieldno++) {
327  pos = pos2 + 1;
328  if ( (pos2 = octstr_search_char(message, '/', pos)) == -1)
329  goto error;
330  if (pos2 > pos)
331  result->fields[fieldno] = octstr_copy(message, pos, pos2 - pos);
332  }
333  if (octstr_search_char(message, '/', pos2 + 1) != -1) {
334  int extrafields = 0;
335 
336  pos = pos2;
337  while ((pos = octstr_search_char(message, '/', pos + 1)) != -1) {
338  extrafields++;
339  pos2 = pos;
340  }
341  /* The extra fields are ignored */
342  warning(0, "get_fields: EMI message of type %d/%c has %d more fields "
343  "than expected.", result->ot, result->or, extrafields);
344  }
345  if (octstr_parse_long(&checksum, message, pos2 + 1, 16) !=
346  octstr_len(message) - 1 || checksum != calculate_checksum(message))
347  goto error;
348  if (result->or == 'R' && octstr_get_char(result->fields[0], 0) == 'N') {
349  long errcode;
350  if (!result->fields[1] ||
351  octstr_parse_long(&errcode, result->fields[1], 0, 10) != 2)
352  goto error;
353  error(0, "EMI2[%s]: Got negative ack. op:%d, trn:%d, error:%ld (%s), message:%s",
354  octstr_get_cstr(whoami),
355  result->ot, result->trn, errcode, emi_strerror(errcode),
356  result->fields[2] ? octstr_get_cstr(result->fields[2]) : "");
357  }
358  return result;
359 error:
360  error(0, "EMI2[%s]: Invalid EMI packet: %s", octstr_get_cstr(whoami),
361  octstr_get_cstr(message));
362  if (result)
363  emimsg_destroy(result);
364  return NULL;
365 }
void error(int err, const char *fmt,...)
Definition: log.c:648
char or
Definition: emimsg.h:72
void emimsg_destroy(struct emimsg *emimsg)
Definition: emimsg.c:215
int trn
Definition: emimsg.h:71
struct emimsg * emimsg_create_op(int ot, int trn, Octstr *whoami)
Definition: emimsg.c:166
Definition: emimsg.h:70
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
static int calculate_checksum(Octstr *message)
Definition: emimsg.c:252
void warning(int err, const char *fmt,...)
Definition: log.c:660
static char * emi_strerror(int errnum)
Definition: emimsg.c:67
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
int ot
Definition: emimsg.h:73
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
Octstr ** fields
Definition: emimsg.h:75
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
Definition: octstr.c:749
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
static struct emimsg * emimsg_create_reply_s(int ot, int trn, int positive, Octstr *whoami)
Definition: emimsg.c:182
int num_fields
Definition: emimsg.h:74
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.