Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
smasi_pdu.c File Reference
#include <string.h>
#include "smasi_pdu.h"
#include "smasi_pdu.def"

Go to the source code of this file.

Macros

#define NONTERMINATED(name)   p->name = NULL;
 
#define COMATERMINATED(name)   p->name = NULL;
 
#define PDU(name, id, fields)
 
#define NONTERMINATED(name)   octstr_destroy(p->name);
 
#define COMATERMINATED(name)   octstr_destroy(p->name);
 
#define PDU(name, id, fields)   case id: { struct name *p = &pdu->u.name; fields } break;
 
#define NONTERMINATED(name)   p = *(&p);
 
#define COMATERMINATED(name)   p = *(&p);
 
#define PDU(name, id, fields)   case id: { struct name *p = &pdu->u.name; fields } break;
 
#define NONTERMINATED(name)   p = *(&p);
 
#define COMATERMINATED(name)
 
#define PDU(name, id, fields)   case id: { struct name *p = &pdu->u.name; fields } break;
 
#define NONTERMINATED(name)   p = *(&p);
 
#define COMATERMINATED(name)   p = *(&p);
 
#define PDU(name, id, fields)   else if (strcmp(type_name, #name) == 0) type = id;
 
#define NONTERMINATED(name)   p = *(&p);
 
#define COMATERMINATED(name)
 
#define PDU(name, id, fields)
 
#define NONTERMINATED(name)   p = *(&p);
 
#define COMATERMINATED(name)   octstr_dump_short(p->name, 2, #name);
 
#define PDU(name, id, fields)   case id: { struct name *p = &pdu->u.name; fields } break;
 

Functions

static Octstrdecode_type (Octstr *os)
 
static Octstrcopy_until_coma (Octstr *os, long *pos)
 
static Octstrcopy_until_assign (Octstr *os, long *pos)
 
static void skip_until_after_colon (Octstr *os, long *pos)
 
SMASI_PDUsmasi_pdu_create (unsigned long type)
 
void smasi_pdu_destroy (SMASI_PDU *pdu)
 
Octstrsmasi_pdu_pack (SMASI_PDU *pdu)
 
SMASI_PDUsmasi_pdu_unpack (Octstr *data_without_len)
 
void smasi_pdu_dump (SMASI_PDU *pdu)
 
Octstrsmasi_pdu_read (Connection *conn)
 

Macro Definition Documentation

#define COMATERMINATED (   name)    p->name = NULL;
#define COMATERMINATED (   name)    octstr_destroy(p->name);
#define COMATERMINATED (   name)    p = *(&p);
#define COMATERMINATED (   name)
Value:
if (p->name != NULL) { octstr_append_cstr(os, #name); \
octstr_append_char(os, '='); \
octstr_append(os, p->name); \
octstr_append_char(os, ','); }
void octstr_append_cstr(Octstr *ostr, const char *cstr)
Definition: octstr.c:1509
char * name
Definition: smsc_cimd2.c:212
#define COMATERMINATED (   name)    p = *(&p);
#define COMATERMINATED (   name)
Value:
if (octstr_str_compare(field_name, #name) == 0 && field_value != NULL) \
p->name = octstr_duplicate(field_value);
#define octstr_duplicate(ostr)
Definition: octstr.h:187
char * name
Definition: smsc_cimd2.c:212
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:971
#define COMATERMINATED (   name)    octstr_dump_short(p->name, 2, #name);
#define NONTERMINATED (   name)    p->name = NULL;
#define NONTERMINATED (   name)    octstr_destroy(p->name);
#define NONTERMINATED (   name)    p = *(&p);
#define NONTERMINATED (   name)    p = *(&p);
#define NONTERMINATED (   name)    p = *(&p);
#define NONTERMINATED (   name)    p = *(&p);
#define NONTERMINATED (   name)    p = *(&p);
#define PDU (   name,
  id,
  fields 
)
Value:
case id: { \
struct name *p = &pdu->u.name; \
pdu->type_name = #name; \
pdu->needs_hyphen = (id < SMASI_HYPHEN_ID ? 1 : 0); \
fields \
} break;
char * name
Definition: smsc_cimd2.c:212
#define SMASI_HYPHEN_ID
Definition: smasi_pdu.h:73
#define PDU (   name,
  id,
  fields 
)    case id: { struct name *p = &pdu->u.name; fields } break;
#define PDU (   name,
  id,
  fields 
)    case id: { struct name *p = &pdu->u.name; fields } break;
#define PDU (   name,
  id,
  fields 
)    case id: { struct name *p = &pdu->u.name; fields } break;
#define PDU (   name,
  id,
  fields 
)    else if (strcmp(type_name, #name) == 0) type = id;
#define PDU (   name,
  id,
  fields 
)
Value:
case id: { \
Octstr * field_name = NULL; \
Octstr * field_value = NULL; \
struct name *p = &pdu->u.name; \
while (pos < octstr_len(data_without_len)) { \
field_name = copy_until_assign(data_without_len, &pos); \
if (field_name == NULL) break; \
field_value = copy_until_coma(data_without_len, &pos); \
if (field_value == NULL) continue; \
fields \
octstr_destroy(field_name); \
octstr_destroy(field_value); \
} \
} break;
static Octstr * copy_until_coma(Octstr *os, long *pos)
Definition: smasi_pdu.c:88
char * name
Definition: smsc_cimd2.c:212
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
static Octstr * copy_until_assign(Octstr *os, long *pos)
Definition: smasi_pdu.c:104
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
#define PDU (   name,
  id,
  fields 
)    case id: { struct name *p = &pdu->u.name; fields } break;

Function Documentation

static Octstr* copy_until_assign ( Octstr os,
long *  pos 
)
static

Definition at line 104 of file smasi_pdu.c.

References octstr_copy, octstr_get_cstr, octstr_len(), octstr_search_char(), and warning().

105 {
106  long nul;
107  Octstr *data;
108 
109  nul = octstr_search_char(os, '=', *pos);
110  if (nul == -1 && (octstr_len(os) - *pos) > 1) {
111  warning(0, "SMASI: Garbage at end of parameter list: %s", octstr_get_cstr(os));
112  *pos = octstr_len(os);
113  return NULL;
114  }
115  data = octstr_copy(os, *pos, nul - *pos);
116  *pos = nul + 1;
117  return data;
118 }
#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:1010
void warning(int err, const char *fmt,...)
Definition: log.c:624
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
static Octstr* copy_until_coma ( Octstr os,
long *  pos 
)
static

Definition at line 88 of file smasi_pdu.c.

References octstr_copy, octstr_get_cstr, octstr_search_char(), and warning().

89 {
90  long nul;
91  Octstr *data;
92 
93  nul = octstr_search_char(os, ',', *pos);
94  if (nul == -1) {
95  warning(0, "SMASI: Parameter without value or value not properly terminated: %s", octstr_get_cstr(os));
96  return NULL;
97  }
98  data = octstr_copy(os, *pos, nul - *pos);
99  *pos = nul + 1;
100  return data;
101 }
#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:1010
void warning(int err, const char *fmt,...)
Definition: log.c:624
Definition: octstr.c:118
static Octstr* decode_type ( Octstr os)
static

Definition at line 68 of file smasi_pdu.c.

References octstr_copy, and octstr_search_char().

Referenced by smasi_pdu_unpack().

69 {
70  long p1, p2;
71  Octstr *temp;
72 
73  if ((p2 = octstr_search_char(os, ':', 0)) == -1)
74  return NULL;
75 
76  if ((p1 = octstr_search_char(os, '!', 0)) != -1 && p1 < p2) {
77  p1++;
78  } else {
79  p1 = 0;
80  }
81 
82  temp = octstr_copy(os, p1, p2 - p1);
83 
84  return temp;
85 }
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1010
Definition: octstr.c:118
static void skip_until_after_colon ( Octstr os,
long *  pos 
)
static

Definition at line 121 of file smasi_pdu.c.

References colon, octstr_get_cstr, octstr_search_char(), and warning().

Referenced by smasi_pdu_unpack().

122 {
123  long colon = octstr_search_char(os, ':', *pos);
124 
125  if (colon == -1) warning(0, "SMASI: No colon after SMASI PDU name: %s", octstr_get_cstr(os));
126 
127  *pos = colon + 1;
128 
129 }
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1010
void warning(int err, const char *fmt,...)
Definition: log.c:624
static Octstr * colon
Definition: smsc_smasi.c:218
SMASI_PDU* smasi_pdu_create ( unsigned long  type)

Definition at line 132 of file smasi_pdu.c.

References SMASI_PDU::type, type, and warning().

Referenced by handle_pdu(), msg_to_pdu(), open_connection(), send_enquire_link(), send_logoff(), and smasi_pdu_unpack().

133 {
134  SMASI_PDU *pdu;
135 
136  pdu = gw_malloc(sizeof(*pdu));
137  pdu->type = type;
138 
139  switch (type) {
140  #define NONTERMINATED(name) p->name = NULL;
141  #define COMATERMINATED(name) p->name = NULL;
142  #define PDU(name, id, fields) \
143  case id: { \
144  struct name *p = &pdu->u.name; \
145  pdu->type_name = #name; \
146  pdu->needs_hyphen = (id < SMASI_HYPHEN_ID ? 1 : 0); \
147  fields \
148  } break;
149  #include "smasi_pdu.def"
150  default:
151  warning(0, "Unknown SMASI_PDU type, internal error.");
152  gw_free(pdu);
153  return NULL;
154  }
155 
156  return pdu;
157 }
unsigned long type
Definition: smasi_pdu.h:85
int type
Definition: smsc_cimd2.c:215
void warning(int err, const char *fmt,...)
Definition: log.c:624
void smasi_pdu_destroy ( SMASI_PDU pdu)

Definition at line 160 of file smasi_pdu.c.

References error(), and SMASI_PDU::type.

Referenced by handle_pdu(), open_connection(), send_enquire_link(), send_logoff(), send_messages(), and smasi_thread().

161 {
162  if (pdu == NULL)
163  return;
164 
165  switch (pdu->type) {
166  #define NONTERMINATED(name) octstr_destroy(p->name);
167  #define COMATERMINATED(name) octstr_destroy(p->name);
168  #define PDU(name, id, fields) \
169  case id: { struct name *p = &pdu->u.name; fields } break;
170  #include "smasi_pdu.def"
171  default:
172  error(0, "Unknown SMASI_PDU type, internal error while destroying.");
173  }
174  gw_free(pdu);
175 }
void error(int err, const char *fmt,...)
Definition: log.c:612
unsigned long type
Definition: smasi_pdu.h:85
void smasi_pdu_dump ( SMASI_PDU pdu)

Definition at line 280 of file smasi_pdu.c.

References debug(), SMASI_PDU::type, SMASI_PDU::type_name, and warning().

Referenced by dump_pdu().

281 {
282  debug("sms.smasi", 0, "SMASI PDU %p dump:", (void *) pdu);
283  debug("sms.smasi", 0, " type_name: %s", pdu->type_name);
284  switch (pdu->type) {
285  #define NONTERMINATED(name) p = *(&p);
286  #define COMATERMINATED(name) \
287  octstr_dump_short(p->name, 2, #name);
288  #define PDU(name, id, fields) \
289  case id: { struct name *p = &pdu->u.name; fields } break;
290  #include "smasi_pdu.def"
291  default:
292  warning(0, "Unknown SMASI_PDU type, internal error.");
293  break;
294  }
295  debug("sms.smasi", 0, "SMASI PDU dump ends.");
296 }
const char * type_name
Definition: smasi_pdu.h:86
unsigned long type
Definition: smasi_pdu.h:85
void warning(int err, const char *fmt,...)
Definition: log.c:624
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
Octstr* smasi_pdu_pack ( SMASI_PDU pdu)

Definition at line 178 of file smasi_pdu.c.

References error(), SMASI_PDU::needs_hyphen, octstr_append_char(), octstr_append_cstr(), octstr_create, octstr_destroy(), octstr_insert(), SMASI_PDU::type, and SMASI_PDU::type_name.

Referenced by send_enquire_link(), send_logoff(), and send_pdu().

179 {
180  Octstr *os;
181  Octstr *temp;
182 
183  os = octstr_create("");
184 
185  /*
186  * Fix lengths of octet string fields.
187  */
188  switch (pdu->type) {
189  #define NONTERMINATED(name) p = *(&p);
190  #define COMATERMINATED(name) p = *(&p);
191  #define PDU(name, id, fields) \
192  case id: { struct name *p = &pdu->u.name; fields } break;
193  #include "smasi_pdu.def"
194  default:
195  error(0, "Unknown SMASI_PDU type, internal error while packing.");
196  }
197 
198  switch (pdu->type) {
199  #define NONTERMINATED(name) p = *(&p);
200  #define COMATERMINATED(name) \
201  if (p->name != NULL) { octstr_append_cstr(os, #name); \
202  octstr_append_char(os, '='); \
203  octstr_append(os, p->name); \
204  octstr_append_char(os, ','); }
205  #define PDU(name, id, fields) \
206  case id: { struct name *p = &pdu->u.name; fields } break;
207  #include "smasi_pdu.def"
208  default:
209  error(0, "Unknown SMASI_PDU type, internal error while packing.");
210  }
211 
212  octstr_append_char(os, '\n');
213  temp = pdu->needs_hyphen ? octstr_create("!") : octstr_create("");
214  octstr_append_cstr(temp, pdu->type_name);
215  octstr_append_char(temp, ':');
216  octstr_insert(os, temp, 0);
217  octstr_destroy(temp);
218 
219  return os;
220 }
void error(int err, const char *fmt,...)
Definition: log.c:612
unsigned int needs_hyphen
Definition: smasi_pdu.h:87
const char * type_name
Definition: smasi_pdu.h:86
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1515
unsigned long type
Definition: smasi_pdu.h:85
void octstr_append_cstr(Octstr *ostr, const char *cstr)
Definition: octstr.c:1509
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1301
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
Definition: octstr.c:118
Octstr* smasi_pdu_read ( Connection conn)

Definition at line 299 of file smasi_pdu.c.

References conn_read_line().

Referenced by read_pdu().

300 {
301  Octstr *line;
302 
303  line = conn_read_line(conn); /* read one line */
304  return line;
305 }
Octstr * conn_read_line(Connection *conn)
Definition: conn.c:1126
Definition: octstr.c:118
SMASI_PDU* smasi_pdu_unpack ( Octstr data_without_len)

Definition at line 223 of file smasi_pdu.c.

References decode_type(), octstr_destroy(), octstr_get_cstr, skip_until_after_colon(), smasi_pdu_create(), type, and warning().

Referenced by read_pdu().

224 {
225  SMASI_PDU *pdu;
226  char *type_name;
227  Octstr *temp;
228  long pos;
229  unsigned long type = 0;
230 
231  /* extract the PDU type identifier */
232  temp = decode_type(data_without_len);
233  type_name = (temp ? octstr_get_cstr(temp) : "");
234 
235  if (strcmp(type_name, "dummy") == 0) type = 0;
236  #define NONTERMINATED(name) p = *(&p);
237  #define COMATERMINATED(name) p = *(&p);
238  #define PDU(name, id, fields) \
239  else if (strcmp(type_name, #name) == 0) type = id;
240  #include "smasi_pdu.def"
241  else warning(0, "unknown SMASI PDU type");
242 
243  pdu = smasi_pdu_create(type);
244  if (pdu == NULL) return NULL;
245 
246  pos = 0;
247  skip_until_after_colon(data_without_len, &pos);
248 
249  switch (type) {
250  #define NONTERMINATED(name) p = *(&p);
251  #define COMATERMINATED(name) \
252  if (octstr_str_compare(field_name, #name) == 0 && field_value != NULL) \
253  p->name = octstr_duplicate(field_value);
254  #define PDU(name, id, fields) \
255  case id: { \
256  Octstr * field_name = NULL; \
257  Octstr * field_value = NULL; \
258  struct name *p = &pdu->u.name; \
259  while (pos < octstr_len(data_without_len)) { \
260  field_name = copy_until_assign(data_without_len, &pos); \
261  if (field_name == NULL) break; \
262  field_value = copy_until_coma(data_without_len, &pos); \
263  if (field_value == NULL) continue; \
264  fields \
265  octstr_destroy(field_name); \
266  octstr_destroy(field_value); \
267  } \
268  } break;
269  #include "smasi_pdu.def"
270  default:
271  warning(0, "Unknown SMASI_PDU type, internal error while unpacking.");
272  }
273 
274  octstr_destroy(temp);
275 
276  return pdu;
277 }
static Octstr * decode_type(Octstr *os)
Definition: smasi_pdu.c:68
int type
Definition: smsc_cimd2.c:215
SMASI_PDU * smasi_pdu_create(unsigned long type)
Definition: smasi_pdu.c:132
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static void skip_until_after_colon(Octstr *os, long *pos)
Definition: smasi_pdu.c:121
void warning(int err, const char *fmt,...)
Definition: log.c:624
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: octstr.c:118
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.