Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
smsc_ois.c File Reference
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "smsc.h"
#include "smsc_p.h"
#include "gwlib/gwlib.h"
#include "sms.h"

Go to the source code of this file.

Data Structures

struct  ois_listentry
 

Macros

#define SAY(d, s)   { if (d<=ois_debug_level) debug("bb.sms.ois",0,s); }
 
#define SAY2(d, s, t)   { if (d<=ois_debug_level) debug("bb.sms.ois",0,s,t); }
 
#define SAY3(d, s, t, u)   { if (d<=ois_debug_level) debug("bb.sms.ois",0,s,t,u); }
 
#define IOTRACE(x, s, l)   SAY3(1,"%s [%s]",x,ois_debug_str(s,l))
 
#define BUFLEN   (511) /* sure enough for ois messages */
 
#define OIS_OPEN_WAITTIME   (15) /* seconds, waiting for banners */
 
#define OIS_MESSAGE_WAITTIME   (30) /* seconds, until closing idle connection */
 
#define OIS_WAITTIME   (999999) /* microseconds, waiting for banners at a time */
 
#define OIS_NOWAIT   (0) /* microseconds, not waiting */
 
#define MAXCOUNTER   (10000) /* ois message id */
 
#define EOL   ('\r') /* ois definition for the eol */
 
#define OIS_FLAG_DEBUG   (0x000f)
 
#define OIS_FLAG_ERROR   (0x0100)
 
#define OIS_FLAG_NOBANNER   (0x0200)
 
#define OIS_FLAG_MULTIPLE_CALL   (0x0400)
 
#define OIS_FLAG_CLOSED   (0x0800)
 

Typedefs

typedef struct ois_listentry ois_listentry
 

Enumerations

enum  dcs_body_type { DCS_GSM_TEXT = 0, DCS_OCTET_DATA = 4 }
 

Functions

static int ois_open_listener (SMSCenter *smsc)
 
static int ois_open_sender (SMSCenter *smsc)
 
static int ois_open_receiver (SMSCenter *smsc)
 
static void ois_disconnect_all (SMSCenter *smsc)
 
static void ois_disconnect (SMSCenter *smsc)
 
static int ois_read_into_buffer (SMSCenter *smsc, long wait_usec)
 
static int ois_check_input (SMSCenter *smsc, long wait_usec)
 
static int ois_check_incoming (SMSCenter *smsc, long wait_usec)
 
static void ois_append_to_list (ois_listentry **head, Msg *msg)
 
static int ois_int_to_i4 (char *raw, int nbr)
 
static int ois_increment_counter (void)
 
static int ois_submit_sm_invoke (SMSCenter *smsc, const Msg *msg)
 
static int ois_encode_submit_sm_invoke (char *str, const Msg *msg)
 
static int ois_append_msisdn (char *raw, const Msg *msg)
 
static int ois_append_sme_reference_number (char *raw)
 
static int ois_append_priority (char *raw)
 
static int ois_append_originating_address (char *raw)
 
static int ois_append_validity_period (char *raw)
 
static int ois_append_data_coding_scheme (char *raw, const Msg *msg)
 
static int ois_append_status_report_request (char *raw)
 
static int ois_append_protocol_id (char *raw)
 
static int ois_append_submission_options (char *raw, const Msg *msg)
 
static int ois_append_sm_text (char *raw, const Msg *msg)
 
static int ois_submit_sm_result (SMSCenter *smsc, const char *buffer)
 
static int ois_decode_submit_sm_result (int *code, const char *str)
 
static int ois_deliver_sm_invoke (SMSCenter *smsc, const char *buffer)
 
static int ois_decode_deliver_sm_invoke (Msg *msg, const char *str)
 
static int ois_check_deliver_sm_invoke (const char *str)
 
static int ois_adjust_destination_address (Msg *msg, const char *raw)
 
static int ois_ignore_smsc_reference_number (const char *raw)
 
static int ois_adjust_originating_address (Msg *msg, const char *raw)
 
static int ois_adjust_data_coding_scheme (Msg *msg, const char *raw)
 
static int ois_ignore_protocol_id (const char *raw)
 
static int ois_adjust_additional_information (Msg *msg, const char *raw)
 
static int ois_adjust_sm_text (Msg *msg, const char *raw)
 
static int ois_ignore_time (const char *raw)
 
static int ois_deliver_sm_result (SMSCenter *smsc, int result, const char *str)
 
static int ois_encode_deliver_sm_result (char *str, int result)
 
static int ois_expand_gsm7 (char *raw8, const char *raw7, int len)
 
static int ois_expand_gsm7_to_bits (char *bits, const char *raw7, int len)
 
static char ois_expand_gsm7_from_bits (const char *bits, int pos)
 
static int ois_convert_to_ia5 (char *str, const char *raw, int len)
 
static int ois_convert_from_ia5 (char *raw, const char *str)
 
static int ois_convert_to_iso88591 (char *raw, int len)
 
static int ois_extract_msg_from_buffer (char *str, SMSCenter *smsc)
 
static int ois_extract_line_from_buffer (char *str, SMSCenter *smsc)
 
static void ois_swap_buffering (SMSCenter *smsc)
 
static const char * ois_debug_str (const char *raw, int len)
 
SMSCenterois_open (int receiveport, const char *hostname, int port, int debug_level)
 
int ois_close (SMSCenter *smsc)
 
int ois_reopen (SMSCenter *smsc)
 
int ois_pending_smsmessage (SMSCenter *smsc)
 
int ois_submit_msg (SMSCenter *smsc, const Msg *msg)
 
int ois_receive_msg (SMSCenter *smsc, Msg **msg)
 
void ois_delete_queue (SMSCenter *smsc)
 

Variables

int ois_debug_level = 0
 
static int ois_counter = 0
 

Macro Definition Documentation

#define EOL   ('\r') /* ois definition for the eol */
#define IOTRACE (   x,
  s,
 
)    SAY3(1,"%s [%s]",x,ois_debug_str(s,l))
#define MAXCOUNTER   (10000) /* ois message id */

Definition at line 152 of file smsc_ois.c.

Referenced by ois_increment_counter().

#define OIS_FLAG_CLOSED   (0x0800)

Definition at line 164 of file smsc_ois.c.

Referenced by ois_read_into_buffer().

#define OIS_FLAG_DEBUG   (0x000f)
#define OIS_FLAG_ERROR   (0x0100)
#define OIS_FLAG_MULTIPLE_CALL   (0x0400)

Definition at line 163 of file smsc_ois.c.

Referenced by ois_check_incoming().

#define OIS_FLAG_NOBANNER   (0x0200)

Definition at line 162 of file smsc_ois.c.

Referenced by ois_open_listener(), and ois_open_sender().

#define OIS_MESSAGE_WAITTIME   (30) /* seconds, until closing idle connection */

Definition at line 149 of file smsc_ois.c.

Referenced by ois_check_input().

#define OIS_NOWAIT   (0) /* microseconds, not waiting */

Definition at line 151 of file smsc_ois.c.

Referenced by ois_pending_smsmessage().

#define OIS_OPEN_WAITTIME   (15) /* seconds, waiting for banners */

Definition at line 148 of file smsc_ois.c.

Referenced by ois_open_sender().

#define OIS_WAITTIME   (999999) /* microseconds, waiting for banners at a time */

Definition at line 150 of file smsc_ois.c.

Referenced by ois_open_sender().

#define SAY3 (   d,
  s,
  t,
 
)    { if (d<=ois_debug_level) debug("bb.sms.ois",0,s,t,u); }

Definition at line 143 of file smsc_ois.c.

Typedef Documentation

typedef struct ois_listentry ois_listentry

Enumeration Type Documentation

Enumerator
DCS_GSM_TEXT 
DCS_OCTET_DATA 

Definition at line 128 of file smsc_ois.c.

128  {
129  DCS_GSM_TEXT = 0,
130  DCS_OCTET_DATA = 4 /* flag_8bit */
131 };

Function Documentation

static int ois_adjust_additional_information ( Msg msg,
const char *  raw 
)
static

Definition at line 1251 of file smsc_ois.c.

References SAY.

Referenced by ois_decode_deliver_sm_invoke().

1252 {
1253  SAY(3, "ois_adjust_additional_information");
1254 
1255  /* we're using this variable temporarily:
1256  * ois_adjust_sm_text will set the correct value */
1257  msg->sms.mclass = raw[0] & 0xff;
1258 
1259  return 1;
1260 }
#define SAY(d, s)
Definition: smsc_ois.c:141
static int ois_adjust_data_coding_scheme ( Msg msg,
const char *  raw 
)
static

Definition at line 1232 of file smsc_ois.c.

References SAY.

Referenced by ois_decode_deliver_sm_invoke().

1233 {
1234  SAY(3, "ois_adjust_data_coding_scheme");
1235 
1236  /* we're using this variable temporarily:
1237  * ois_adjust_sm_text will set the correct value */
1238 
1239  msg->sms.coding = (raw[0] & 0xff) + 1;
1240 
1241  return 1;
1242 }
#define SAY(d, s)
Definition: smsc_ois.c:141
static int ois_adjust_destination_address ( Msg msg,
const char *  raw 
)
static

Definition at line 1191 of file smsc_ois.c.

References octstr_create_from_data, and SAY.

Referenced by ois_decode_deliver_sm_invoke().

1192 {
1193  int len;
1194 
1195  SAY(3, "ois_adjust_destination_address");
1196 
1197  len = raw[0] & 0xff;
1198  msg->sms.receiver = octstr_create_from_data(&raw[1+2], len-2);
1199 
1200  return 1 + len;
1201 }
#define SAY(d, s)
Definition: smsc_ois.c:141
#define octstr_create_from_data(data, len)
Definition: octstr.h:134
static int ois_adjust_originating_address ( Msg msg,
const char *  raw 
)
static

Definition at line 1220 of file smsc_ois.c.

References octstr_create_from_data, and SAY.

Referenced by ois_decode_deliver_sm_invoke().

1221 {
1222  int len;
1223 
1224  SAY(3, "ois_adjust_originating_address");
1225 
1226  len = raw[0] & 0xff;
1227  msg->sms.sender = octstr_create_from_data(&raw[1+2], len-2);
1228 
1229  return 1 + len;
1230 }
#define SAY(d, s)
Definition: smsc_ois.c:141
#define octstr_create_from_data(data, len)
Definition: octstr.h:134
static int ois_adjust_sm_text ( Msg msg,
const char *  raw 
)
static

Definition at line 1262 of file smsc_ois.c.

References BUFLEN, DC_7BIT, DC_8BIT, IOTRACE, MC_UNDEF, octstr_create, octstr_create_from_data, octstr_get_cstr, octstr_len(), ois_convert_to_iso88591(), ois_expand_gsm7(), and SAY.

Referenced by ois_decode_deliver_sm_invoke().

1263 {
1264  int msglen7, msglen8;
1265  char buffer[BUFLEN+1];
1266 
1267  SAY(3, "ois_adjust_sm_text");
1268 
1269  /* calculate lengths */
1270 
1271  msglen7 = raw[0] & 0xff;
1272  msglen8 = raw[1] & 0xff;
1273 
1274  /* copy text, note: flag contains temporarily the raw type description */
1275 
1276  switch ((msg->sms.coding - 1) & 0xff) {
1277  case 0x00: /* gsm7 */
1278  ois_expand_gsm7(buffer, &raw[2], msglen7);
1279  ois_convert_to_iso88591(buffer, msglen7);
1280  if (msg->sms.mclass & 0x02) { /* XXX mclass temporarily */
1281  msg->sms.msgdata = octstr_create("");
1282  msg->sms.udhdata = octstr_create_from_data(buffer, msglen7);
1283  } else {
1284  msg->sms.msgdata = octstr_create_from_data(buffer, msglen7);
1285  msg->sms.udhdata = octstr_create("");
1286  }
1287  msg->sms.coding = DC_7BIT;
1288  break;
1289  case 0x0f: /* ia5 */
1290  memcpy(buffer, &raw[2], msglen8);
1291  ois_convert_to_iso88591(buffer, msglen8);
1292  if (msg->sms.mclass & 0x02) { /* XXX mclass temporarily */
1293  msg->sms.msgdata = octstr_create("");
1294  msg->sms.udhdata = octstr_create_from_data(buffer, msglen8);
1295  } else {
1296  msg->sms.msgdata = octstr_create_from_data(buffer, msglen8);
1297  msg->sms.udhdata = octstr_create("");
1298  }
1299  msg->sms.coding = DC_7BIT;
1300  break;
1301  default: /* 0xf4, 0xf5, 0xf6, 0xf7; 8bit to disp, mem, sim or term */
1302  if (msg->sms.mclass & 0x02) { /* XXX mclass temporarily */
1303  msg->sms.msgdata = octstr_create("");
1304  msg->sms.udhdata = octstr_create_from_data(&raw[2], msglen8);
1305  } else {
1306  msg->sms.msgdata = octstr_create_from_data(&raw[2], msglen8);
1307  msg->sms.udhdata = octstr_create("");
1308  }
1309  msg->sms.coding = DC_8BIT;
1310  break;
1311  }
1312  msg->sms.mclass = MC_UNDEF;
1313 
1314  if (octstr_len(msg->sms.udhdata)) {
1315  IOTRACE("decoded udh", octstr_get_cstr(msg->sms.udhdata),
1316  octstr_len(msg->sms.udhdata));
1317  } else {
1318  IOTRACE("decoded", octstr_get_cstr(msg->sms.msgdata),
1319  octstr_len(msg->sms.msgdata));
1320  }
1321 
1322  return 2 + msglen8;
1323 }
#define DC_8BIT
Definition: sms.h:111
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define SAY(d, s)
Definition: smsc_ois.c:141
static int ois_convert_to_iso88591(char *raw, int len)
Definition: smsc_ois.c:1537
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
#define BUFLEN
Definition: smsc_ois.c:147
#define MC_UNDEF
Definition: sms.h:93
#define IOTRACE(x, s, l)
Definition: smsc_ois.c:144
static int ois_expand_gsm7(char *raw8, const char *raw7, int len)
Definition: smsc_ois.c:1387
#define octstr_create_from_data(data, len)
Definition: octstr.h:134
#define DC_7BIT
Definition: sms.h:110
static int ois_append_data_coding_scheme ( char *  raw,
const Msg msg 
)
static

Definition at line 944 of file smsc_ois.c.

References DC_8BIT, DCS_OCTET_DATA, and SAY.

Referenced by ois_encode_submit_sm_invoke().

945 {
946  SAY(3, "ois_append_data_coding_scheme");
947 
948  /* 0x0f is a special code for ASCII text, the SMSC will convert
949  * this to GSM and set the DCS to 0.
950  * FIXME: Convert to GSM ourselves and use DCS_GSM_TEXT.
951  * FIXME: use fields_to_dcs and try to support DC_UCS2 too ;) */
952  raw[0] = (char) (msg->sms.coding == DC_8BIT ? DCS_OCTET_DATA : 0x0f);
953  return 1;
954 }
#define DC_8BIT
Definition: sms.h:111
#define SAY(d, s)
Definition: smsc_ois.c:141
static int ois_append_msisdn ( char *  raw,
const Msg msg 
)
static

Definition at line 894 of file smsc_ois.c.

References octstr_get_cstr, octstr_len(), and SAY.

Referenced by ois_encode_submit_sm_invoke().

895 {
896  int len;
897 
898  SAY(3, "ois_append_msisdn");
899 
900  len = octstr_len(msg->sms.receiver);
901  raw[0] = (char) len;
902  memcpy(&raw[1], octstr_get_cstr(msg->sms.receiver), len);
903  return 1 + len;
904 }
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define SAY(d, s)
Definition: smsc_ois.c:141
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
static int ois_append_originating_address ( char *  raw)
static

Definition at line 924 of file smsc_ois.c.

References SAY.

Referenced by ois_encode_submit_sm_invoke().

925 {
926  SAY(3, "ois_append_originating_address");
927 
928  raw[0] = (char) 2; /* length */
929  raw[1] = 'A'; /* A3=address type, actual address is unnecessary */
930  raw[2] = '3';
931 
932  return 3;
933 }
#define SAY(d, s)
Definition: smsc_ois.c:141
static int ois_append_priority ( char *  raw)
static

Definition at line 916 of file smsc_ois.c.

References SAY.

Referenced by ois_encode_submit_sm_invoke().

917 {
918  SAY(3, "ois_append_priority");
919 
920  raw[0] = (char) 1; /* 0=high, 1=normal */
921  return 1;
922 }
#define SAY(d, s)
Definition: smsc_ois.c:141
static int ois_append_protocol_id ( char *  raw)
static

Definition at line 964 of file smsc_ois.c.

References SAY.

Referenced by ois_encode_submit_sm_invoke().

965 {
966  SAY(3, "ois_append_protocol_id");
967 
968  raw[0] = (char) 0; /* 0=default */
969  return 1;
970 }
#define SAY(d, s)
Definition: smsc_ois.c:141
static int ois_append_sm_text ( char *  raw,
const Msg msg 
)
static

Definition at line 988 of file smsc_ois.c.

References charset_utf8_to_gsm(), DC_7BIT, DC_UNDEF, IOTRACE, octstr_get_cstr, octstr_len(), and SAY.

Referenced by ois_encode_submit_sm_invoke().

989 {
990  int udhlen7, udhlen8;
991  int msglen7, msglen8;
992  int len;
993 
994  SAY(3, "ois_append_sm_text");
995 
996  if (msg->sms.coding == DC_7BIT || msg->sms.coding == DC_UNDEF) {
997  charset_utf8_to_gsm(msg->sms.udhdata);
998  charset_utf8_to_gsm(msg->sms.msgdata);
999  }
1000 
1001 
1002  /* calculate lengths */
1003 
1004  udhlen8 = octstr_len(msg->sms.udhdata);
1005  msglen8 = octstr_len(msg->sms.msgdata);
1006 
1007  udhlen7 = udhlen8;
1008  msglen7 = msglen8;
1009  len = udhlen8 + msglen8;
1010 
1011  /* copy text */
1012 
1013  raw[0] = (char) (len);
1014  raw[1] = (char) (udhlen7 + msglen7);
1015  memcpy(&raw[2], octstr_get_cstr(msg->sms.udhdata), udhlen8);
1016  memcpy(&raw[2+udhlen8], octstr_get_cstr(msg->sms.msgdata), msglen8);
1017 
1018  IOTRACE("encoding", &raw[2], len);
1019 
1020  return 2 + len;
1021 }
void charset_utf8_to_gsm(Octstr *ostr)
Definition: charset.c:288
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define SAY(d, s)
Definition: smsc_ois.c:141
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
#define DC_UNDEF
Definition: sms.h:109
#define IOTRACE(x, s, l)
Definition: smsc_ois.c:144
#define DC_7BIT
Definition: sms.h:110
static int ois_append_sme_reference_number ( char *  raw)
static

Definition at line 906 of file smsc_ois.c.

References ois_counter, ois_int_to_i4(), and SAY.

Referenced by ois_encode_submit_sm_invoke().

907 {
908  SAY(3, "ois_append_sme_reference_number");
909 
910  /* 1=key, 2=not key (OIS 4.5) */
911  /* or 1=reject duplicates, 2=allow duplicates (OIS 5.0) */
912  raw[0] = (char) 2;
913  return 1 + ois_int_to_i4(&raw[1], ois_counter);
914 }
#define SAY(d, s)
Definition: smsc_ois.c:141
static int ois_int_to_i4(char *raw, int nbr)
Definition: smsc_ois.c:786
static int ois_counter
Definition: smsc_ois.c:166
static int ois_append_status_report_request ( char *  raw)
static

Definition at line 956 of file smsc_ois.c.

References SAY.

Referenced by ois_encode_submit_sm_invoke().

957 {
958  SAY(3, "ois_append_status_report_request");
959 
960  raw[0] = (char) 0x00; /* bit field, bit 0=abandoned, bit 2=delivered */
961  return 1;
962 }
#define SAY(d, s)
Definition: smsc_ois.c:141
static int ois_append_submission_options ( char *  raw,
const Msg msg 
)
static

Definition at line 972 of file smsc_ois.c.

References DC_8BIT, octstr_len(), and SAY.

Referenced by ois_encode_submit_sm_invoke().

973 {
974  SAY(3, "ois_append_submission_options");
975 
976  /* bit field, bit 0=reply path, bit 1=udh, bits 3-4=dcs interpretation */
977  raw[0] = (char) 0x00;
978  if (octstr_len(msg->sms.udhdata)) {
979  raw[0] |= (char) 0x02;
980  }
981  if (msg->sms.coding == DC_8BIT) { /* XXX and UCS-2? */
982  raw[0] |= (char) 0x10;
983  }
984  return 1;
985 }
#define DC_8BIT
Definition: sms.h:111
#define SAY(d, s)
Definition: smsc_ois.c:141
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
static void ois_append_to_list ( ois_listentry **  head,
Msg msg 
)
static

Definition at line 764 of file smsc_ois.c.

References msg, ois_listentry::msg, ois_listentry::next, and SAY.

Referenced by ois_deliver_sm_invoke().

765 {
766  ois_listentry *item;
767  ois_listentry *tail;
768 
769  SAY(2, "ois_append_to_list");
770 
771  item = gw_malloc(sizeof(ois_listentry));
772  item->next = NULL;
773  item->msg = msg;
774 
775  if (*head == NULL) {
776  *head = item;
777  } else { /* not so bright algorithm, but ok with relatively short lists */
778  for (tail = *head; tail->next != NULL; tail = tail->next) ;
779  tail->next = item;
780  }
781  return;
782 }
struct ois_listentry * next
Definition: smsc_ois.c:156
#define SAY(d, s)
Definition: smsc_ois.c:141
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static int ois_append_validity_period ( char *  raw)
static

Definition at line 935 of file smsc_ois.c.

References SAY.

Referenced by ois_encode_submit_sm_invoke().

936 {
937  SAY(3, "ois_append_validity_period");
938 
939  raw[0] = (char) 2; /* 0=none, 1=absolute, 2=relative */
940  raw[1] = (char) 1; /* relative, (v+1)*5 minutes, v<144 */
941  return 2;
942 }
#define SAY(d, s)
Definition: smsc_ois.c:141
static int ois_check_deliver_sm_invoke ( const char *  str)
static

Definition at line 1153 of file smsc_ois.c.

References BUFLEN, EOL, error(), and SAY.

Referenced by ois_decode_deliver_sm_invoke().

1154 {
1155  int buflen;
1156  char buffer[BUFLEN+1];
1157  int count;
1158 
1159  SAY(3, "ois_check_deliver_sm_invoke");
1160 
1161  /* check the (initial) header and trailer */
1162 
1163  buflen = strlen(str) - 1;
1164  if (buflen < 7 || str[0] != 'M' || (str[1] & 0x50) != 0x50
1165  || str[buflen] != EOL) {
1166  goto error;
1167  }
1168 
1169  count = str[1] & 0x0f;
1170  while (--count >= 0)
1171  {
1172  /* check the additional header */
1173 
1174  sprintf(buffer, "%c%c%c%.4s",
1175  EOL,
1176  'M', /* deliver sm invoke */
1177  (char)(0x60|count), /* ia5 encoding, additional part */
1178  &str[2]);
1179  if (strstr(str, buffer) == NULL) {
1180  goto error;
1181  }
1182  }
1183 
1184  return 0;
1185 
1186  error:
1187  return -1;
1188 }
void error(int err, const char *fmt,...)
Definition: log.c:612
#define SAY(d, s)
Definition: smsc_ois.c:141
#define EOL
Definition: smsc_ois.c:153
#define BUFLEN
Definition: smsc_ois.c:147
static int ois_check_incoming ( SMSCenter smsc,
long  wait_usec 
)
static

Definition at line 721 of file smsc_ois.c.

References debug(), error(), OIS_FLAG_ERROR, OIS_FLAG_MULTIPLE_CALL, SMSCenter::ois_flags, SMSCenter::ois_listening_socket, ois_open_receiver(), SAY, and SMSCenter::socket.

Referenced by ois_pending_smsmessage().

722 {
723  fd_set read_fd;
724  struct timeval tv;
725  int ret;
726 
727  SAY(8, "ois_check_incoming");
728 
729  tv.tv_sec = 0;
730  tv.tv_usec = wait_usec;
731 
732  FD_ZERO(&read_fd);
733  FD_SET(smsc->ois_listening_socket, &read_fd);
734  ret = select(smsc->ois_listening_socket + 1, &read_fd, NULL, NULL, &tv);
735  if (ret == -1) {
736  if (errno == EINTR || errno == EAGAIN) {
737  return 0;
738  } else {
739  error(errno, "ois_check_incoming: select failed");
740  smsc->ois_flags |= OIS_FLAG_ERROR;
741  return -1;
742  }
743  } else if (ret == 0) {
744  return 0;
745  }
746 
747  /* if we end up here, someone is trying to connect */
748 
749  if (smsc->socket != -1) {
750  if ((smsc->ois_flags & OIS_FLAG_MULTIPLE_CALL) == 0) {
751  /* if you see lots of these, maybe we should accept */
752  /* multiple incoming connections at a time... */
753  debug("bb.sms.ois", 0, "letting an incoming call to wait until the old one disconnects");
755  }
756  return 0;
757  }
758 
760  return ois_open_receiver(smsc);
761 }
void error(int err, const char *fmt,...)
Definition: log.c:612
int ois_flags
Definition: smsc_p.h:175
#define SAY(d, s)
Definition: smsc_ois.c:141
#define OIS_FLAG_ERROR
Definition: smsc_ois.c:161
int ois_listening_socket
Definition: smsc_p.h:176
int socket
Definition: smsc_p.h:115
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static int ois_open_receiver(SMSCenter *smsc)
Definition: smsc_ois.c:539
#define OIS_FLAG_MULTIPLE_CALL
Definition: smsc_ois.c:163
static int ois_check_input ( SMSCenter smsc,
long  wait_usec 
)
static

Definition at line 644 of file smsc_ois.c.

References BUFLEN, debug(), error(), IOTRACE, SMSCenter::ois_ack_debt, SMSCenter::ois_alive, ois_debug_str(), ois_deliver_sm_invoke(), ois_deliver_sm_result(), ois_disconnect(), ois_extract_msg_from_buffer(), OIS_FLAG_ERROR, SMSCenter::ois_flags, OIS_MESSAGE_WAITTIME, ois_read_into_buffer(), SMSCenter::ois_received_mo, ois_submit_sm_result(), SAY, SMSCenter::socket, and warning().

Referenced by ois_pending_smsmessage().

645 {
646  char buffer[BUFLEN+1];
647  time_t now;
648  int ret;
649 
650  SAY(8, "ois_check_input");
651 
652  ret = ois_read_into_buffer(smsc, wait_usec);
653  if (ret < 0) {
654  goto error;
655  }
656 
657  ret = ois_extract_msg_from_buffer(buffer, smsc);
658  if (ret > 0) {
659  IOTRACE("received", buffer, ret);
660  switch (buffer[0]) {
661  case 's':
662  ret = ois_submit_sm_result(smsc, buffer);
663  if (ret > 0) {
664  warning(0, "ois_check_input: submit sm result signals (%d)...", ret);
665  } else if (ret < 0) {
666  error(0, "ois_check_input: invalid submit sm result");
667  goto error;
668  }
669  --smsc->ois_ack_debt;
670  time(&smsc->ois_alive);
671  break;
672  case 'M':
673  ret = ois_deliver_sm_invoke(smsc, buffer);
674  if (ret >= 0) {
675  ret = ois_deliver_sm_result(smsc, ret, buffer);
676  if (ret < 0) {
677  goto error;
678  }
679  } else {
680  error(0, "ois_check_input: invalid deliver sm invoke");
681  goto error;
682  }
683  time(&smsc->ois_alive);
684  break;
685  default:
686  warning(0, "ois_check_input: unexpected message [%s]...",
687  ois_debug_str(buffer, ret));
688  break;
689  }
690  } else {
691  if (smsc->socket != -1) {
692  time(&now);
693  if ((now - smsc->ois_alive) > OIS_MESSAGE_WAITTIME) {
694  debug("bb.sms.ois", 0, "closing an idle connection");
695  SAY(4, "ois_check_input: ois_disconnect");
696  ois_disconnect(smsc);
697  }
698  }
699  }
700 
701  if (ret < 0) {
702  error(0, "ois_check_input: malformatted message [%s]",
703  ois_debug_str(buffer, -ret));
704  goto error;
705  }
706 
707  if (smsc->ois_received_mo != NULL ||
708  (smsc->ois_flags & OIS_FLAG_ERROR) != 0) {
709  SAY(2, "ois_check_input has something");
710  return 1; /* at least one message in the queue or an error pending */
711  } else {
712  return 0; /* no messages this time */
713  }
714 
715  error:
716  smsc->ois_flags |= OIS_FLAG_ERROR;
717  return 1;
718 }
int ois_ack_debt
Definition: smsc_p.h:174
void error(int err, const char *fmt,...)
Definition: log.c:612
int ois_flags
Definition: smsc_p.h:175
#define SAY(d, s)
Definition: smsc_ois.c:141
void * ois_received_mo
Definition: smsc_p.h:173
static const char * ois_debug_str(const char *raw, int len)
Definition: smsc_ois.c:1709
#define OIS_FLAG_ERROR
Definition: smsc_ois.c:161
static int ois_submit_sm_result(SMSCenter *smsc, const char *buffer)
Definition: smsc_ois.c:1024
static int ois_extract_msg_from_buffer(char *str, SMSCenter *smsc)
Definition: smsc_ois.c:1577
static int ois_deliver_sm_invoke(SMSCenter *smsc, const char *buffer)
Definition: smsc_ois.c:1073
static void ois_disconnect(SMSCenter *smsc)
Definition: smsc_ois.c:595
void warning(int err, const char *fmt,...)
Definition: log.c:624
static int ois_read_into_buffer(SMSCenter *smsc, long wait_usec)
Definition: smsc_ois.c:609
int socket
Definition: smsc_p.h:115
#define BUFLEN
Definition: smsc_ois.c:147
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static int ois_deliver_sm_result(SMSCenter *smsc, int result, const char *str)
Definition: smsc_ois.c:1339
#define IOTRACE(x, s, l)
Definition: smsc_ois.c:144
#define OIS_MESSAGE_WAITTIME
Definition: smsc_ois.c:149
time_t ois_alive
Definition: smsc_p.h:171
int ois_close ( SMSCenter smsc)

Definition at line 263 of file smsc_ois.c.

References SMSCenter::buflen, ois_debug_level, ois_disconnect_all(), OIS_FLAG_DEBUG, SMSCenter::ois_flags, ois_swap_buffering(), SAY, SMSC_TYPE_OIS, smscenter_remove_from_buffer(), SMSCenter::type, and warning().

Referenced by ois_open_listener(), ois_reopen(), and smsc_close().

264 {
266  SAY(2, "ois_close");
267 
268  if (smsc->type != SMSC_TYPE_OIS) {
269  warning(0, "ois_close: closing a not-ois connection...");
270  }
271 
272  ois_swap_buffering(smsc);
274  ois_swap_buffering(smsc);
276  SAY(4, "ois_close: ois_disconnect_all");
277  ois_disconnect_all(smsc);
278 
279  return 0;
280 }
int ois_debug_level
Definition: smsc_ois.c:136
static void ois_swap_buffering(SMSCenter *smsc)
Definition: smsc_ois.c:1668
int ois_flags
Definition: smsc_p.h:175
size_t buflen
Definition: smsc_p.h:186
#define SAY(d, s)
Definition: smsc_ois.c:141
void smscenter_remove_from_buffer(SMSCenter *smsc, size_t n)
Definition: smsc.c:412
void warning(int err, const char *fmt,...)
Definition: log.c:624
#define OIS_FLAG_DEBUG
Definition: smsc_ois.c:160
static void ois_disconnect_all(SMSCenter *smsc)
Definition: smsc_ois.c:574
int type
Definition: smsc_p.h:93
static int ois_convert_from_ia5 ( char *  raw,
const char *  str 
)
static

Definition at line 1483 of file smsc_ois.c.

References ois_debug_str(), SAY, and SAY2.

Referenced by ois_decode_deliver_sm_invoke(), and ois_decode_submit_sm_result().

1484 {
1485  int j;
1486  int i;
1487  int ch;
1488 
1489  SAY(3, "ois_convert_from_ia5");
1490 
1491  for (j = i = 0; ; ++i) {
1492  ch = str[i] & 0xff;
1493  if (ch < 0x20 || 0x7f <= ch) {
1494  break;
1495  } else if (ch == 0x5c) {
1496  ch = str[++i] & 0xff;
1497  if (ch == 0x5c || ch == 0x5e || ch == 0x60 || ch == 0x7e) {
1498  raw[j++] = (char) ch;
1499  } else {
1500  break;
1501  }
1502  } else if (ch == 0x5e) {
1503  ch = str[++i] & 0xff;
1504  if (0x40 <= ch && ch < 0x60) {
1505  raw[j++] = (char) ch - 0x40;
1506  } else if (ch == 0x7e) {
1507  raw[j++] = (char) 0x7f;
1508  } else {
1509  break;
1510  }
1511  } else if (ch == 0x60) {
1512  ch = str[++i] & 0xff;
1513  if (0x20 <= ch && ch < 0x7f) {
1514  raw[j++] = (char) ch + 0x80;
1515  } else {
1516  break;
1517  }
1518  } else if (ch == 0x7e) {
1519  ch = str[++i] & 0xff;
1520  if (0x40 <= ch && ch < 0x60) {
1521  raw[j++] = (char) ch + 0x40;
1522  } else if (ch == 0x7e) {
1523  raw[j++] = (char) 0xff;
1524  } else {
1525  break;
1526  }
1527  } else { /* 0x20 <= ch && ch < 0x7f */
1528  raw[j++] = (char) ch;
1529  }
1530  }
1531 
1532  SAY2(5, "ois_convert_from_ia5 gave [%s]", ois_debug_str(raw, j));
1533  return j;
1534 }
#define SAY(d, s)
Definition: smsc_ois.c:141
static const char * ois_debug_str(const char *raw, int len)
Definition: smsc_ois.c:1709
#define SAY2(d, s, t)
Definition: smsc_ois.c:142
static int ois_convert_to_ia5 ( char *  str,
const char *  raw,
int  len 
)
static

Definition at line 1444 of file smsc_ois.c.

References ois_debug_str(), and SAY2.

Referenced by ois_encode_deliver_sm_result(), and ois_encode_submit_sm_invoke().

1445 {
1446  int j;
1447  int i;
1448  int ch;
1449 
1450  SAY2(3, "ois_convert_to_ia5 len=%d", len);
1451 
1452  for (j = i = 0; i < len; ++i) {
1453  ch = raw[i] & 0xff;
1454  if (ch == 0x5c || ch == 0x5e || ch == 0x60 || ch == 0x7e) {
1455  str[j++] = (char) 0x5c;
1456  str[j++] = (char) ch;
1457  } else if (0x20 <= ch && ch < 0x7f) {
1458  str[j++] = (char) ch;
1459  } else if (0x00 <= ch && ch < 0x20) {
1460  str[j++] = (char) 0x5e;
1461  str[j++] = (char) ch + 0x40;
1462  } else if (0xa0 <= ch && ch < 0xff) {
1463  str[j++] = (char) 0x60;
1464  str[j++] = (char) ch - 0x80;
1465  } else if (0x80 <= ch && ch < 0xa0) {
1466  str[j++] = (char) 0x7e;
1467  str[j++] = (char) ch - 0x40;
1468  } else if (ch == 0x7f) {
1469  str[j++] = (char) 0x5e;
1470  str[j++] = (char) 0x7e;
1471  } else { /* ch == 0xff */
1472  str[j++] = (char) 0x7e;
1473  str[j++] = (char) 0x7e;
1474  }
1475  }
1476 
1477  str[j] = '\0';
1478  SAY2(5, "ois_convert_to_ia5 gave [%s]", ois_debug_str(str, j));
1479  return j;
1480 }
static const char * ois_debug_str(const char *raw, int len)
Definition: smsc_ois.c:1709
#define SAY2(d, s, t)
Definition: smsc_ois.c:142
static int ois_convert_to_iso88591 ( char *  raw,
int  len 
)
static

Definition at line 1537 of file smsc_ois.c.

References ois_debug_str(), and SAY2.

Referenced by ois_adjust_sm_text().

1538 {
1539  /* a best effort 1-to-1 conversion according to ois appendix a */
1540 
1541  static const char gsm_to_iso88591[] = {
1542  '@', 0xa3,'$', 0xa5,0xe8,0xe9,0xf9,0xec, /* 0x00 - 0x07 */
1543  0xf2,0xc7,'\n',0xd8,0xf8,'\r',0xc5,0xe5, /* 0x08 - 0x0f */
1544  'D', ' ', 'F', 'G', 'L', 'W', 'P', 'Y', /* 0x10 - 0x17, poor! */
1545  'Y', 'S', 'X', ' ', 0xc6,0xe6,'b', 0xc9, /* 0x18 - 0x1f, poor! */
1546  ' ', '!', '"', '#', 0xa4, '%', '&', '\'',/* 0x20 - 0x27 */
1547  '(', ')', '*', '+', ',', '-', '.', '/', /* 0x28 - 0x2f */
1548  '0', '1', '2', '3', '4', '5', '6', '7', /* 0x30 - 0x37 */
1549  '8', '9', ':', ';', '<', '=', '>', '?', /* 0x38 - 0x3f */
1550  0xa1,'A', 'B', 'C', 'D', 'E', 'F', 'G', /* 0x40 - 0x47 */
1551  'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* 0x48 - 0x4f */
1552  'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 0x50 - 0x57 */
1553  'X', 'Y', 'Z', 0xc4,0xd6,0xd1,0xdc,0xa7, /* 0x58 - 0x5f */
1554  0xbf,'a', 'b', 'c', 'd', 'e', 'f', 'g', /* 0x60 - 0x67 */
1555  'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', /* 0x68 - 0x6f */
1556  'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* 0x70 - 0x77 */
1557  'x', 'y', 'z', 0xe4,0xf6,0xf1,0xfc,0xe0 /* 0x78 - 0x7f */
1558  };
1559 
1560  int i;
1561 
1562  SAY2(3, "ois_convert_to_iso88591 len=%d", len);
1563 
1564  for (i = 0; i < len; ++i) {
1565  raw[i] = gsm_to_iso88591[raw[i] & 0x7f];
1566  }
1567 
1568  SAY2(5, "ois_convert_to_iso88591 gave [%s]", ois_debug_str(raw, i));
1569  return i;
1570 }
static const char * ois_debug_str(const char *raw, int len)
Definition: smsc_ois.c:1709
#define SAY2(d, s, t)
Definition: smsc_ois.c:142
static const char * ois_debug_str ( const char *  raw,
int  len 
)
static

Definition at line 1709 of file smsc_ois.c.

References BUFLEN.

Referenced by ois_check_input(), ois_convert_from_ia5(), ois_convert_to_ia5(), ois_convert_to_iso88591(), ois_expand_gsm7(), and ois_open_sender().

1710 {
1711  static const char hex[] = "0123456789abcdef";
1712  static char str[4*(BUFLEN+1)+1];
1713  int pos;
1714  int ch;
1715  int i;
1716 
1717  pos = 0;
1718  for (i = 0; i < len; ++i) {
1719  ch = raw[i] & 0xff;
1720  if (0x20 <= ch && ch < 0x7f && ch != 0x5c) {
1721  str[pos++] = (char) ch;
1722  } else {
1723  str[pos++] = '\\';
1724  str[pos++] = 'x';
1725  str[pos++] = hex[ch/16];
1726  str[pos++] = hex[ch%16];
1727  }
1728  }
1729  str[pos] = '\0';
1730  return str;
1731 }
#define BUFLEN
Definition: smsc_ois.c:147
static int ois_decode_deliver_sm_invoke ( Msg msg,
const char *  str 
)
static

Definition at line 1099 of file smsc_ois.c.

References BUFLEN, EOL, error(), ois_adjust_additional_information(), ois_adjust_data_coding_scheme(), ois_adjust_destination_address(), ois_adjust_originating_address(), ois_adjust_sm_text(), ois_check_deliver_sm_invoke(), ois_convert_from_ia5(), ois_ignore_protocol_id(), ois_ignore_smsc_reference_number(), ois_ignore_time(), and SAY.

Referenced by ois_deliver_sm_invoke().

1100 {
1101  char body[BUFLEN+1];
1102  char raw[BUFLEN];
1103  int len;
1104  int i;
1105  int pos;
1106  int ret;
1107 
1108  SAY(3, "ois_decode_deliver_sm_invoke");
1109 
1110  ret = ois_check_deliver_sm_invoke(str);
1111  if (ret < 0) {
1112  goto error;
1113  }
1114 
1115  /* extract body */
1116 
1117  len = strlen(str);
1118  for (pos = 0, i = 6; i < len; ++i) {
1119  if (str[i] != EOL) {
1120  body[pos++] = str[i];
1121  } else {
1122  i += 6;
1123  }
1124  }
1125  body[pos] = '\0';
1126  memset(raw, '\0', sizeof(raw));
1127  len = ois_convert_from_ia5(raw, body);
1128 
1129  /* adjust msg values */
1130 
1131  pos = 0;
1132  pos += ois_adjust_destination_address(msg, &raw[pos]);
1133  pos += ois_ignore_smsc_reference_number(&raw[pos]);
1134  pos += ois_adjust_originating_address(msg, &raw[pos]);
1135  pos += ois_adjust_data_coding_scheme(msg, &raw[pos]);
1136  pos += ois_ignore_protocol_id(&raw[pos]);
1137  pos += ois_adjust_additional_information(msg, &raw[pos]);
1138  pos += ois_adjust_sm_text(msg, &raw[pos]);
1139  pos += ois_ignore_time(&raw[pos]); /* accept time */
1140  pos += ois_ignore_time(&raw[pos]); /* invoke time */
1141  if (pos != len) {
1142  error(0, "ois_decode_deliver_sm_invoke: message parsing error (%d!=%d)",
1143  pos, len);
1144  goto error;
1145  }
1146  return 0;
1147 
1148  error:
1149  return -1;
1150 }
void error(int err, const char *fmt,...)
Definition: log.c:612
static int ois_ignore_smsc_reference_number(const char *raw)
Definition: smsc_ois.c:1203
static int ois_adjust_sm_text(Msg *msg, const char *raw)
Definition: smsc_ois.c:1262
static int ois_adjust_additional_information(Msg *msg, const char *raw)
Definition: smsc_ois.c:1251
static int ois_ignore_time(const char *raw)
Definition: smsc_ois.c:1326
#define SAY(d, s)
Definition: smsc_ois.c:141
#define EOL
Definition: smsc_ois.c:153
static int ois_convert_from_ia5(char *raw, const char *str)
Definition: smsc_ois.c:1483
static int ois_ignore_protocol_id(const char *raw)
Definition: smsc_ois.c:1244
static int ois_check_deliver_sm_invoke(const char *str)
Definition: smsc_ois.c:1153
#define BUFLEN
Definition: smsc_ois.c:147
static int ois_adjust_destination_address(Msg *msg, const char *raw)
Definition: smsc_ois.c:1191
static int ois_adjust_data_coding_scheme(Msg *msg, const char *raw)
Definition: smsc_ois.c:1232
static int ois_adjust_originating_address(Msg *msg, const char *raw)
Definition: smsc_ois.c:1220
static int ois_decode_submit_sm_result ( int *  code,
const char *  str 
)
static

Definition at line 1043 of file smsc_ois.c.

References BUFLEN, EOL, error(), ois_convert_from_ia5(), and SAY.

Referenced by ois_submit_sm_result().

1044 {
1045  int buflen;
1046  char raw[BUFLEN];
1047  int len;
1048 
1049  SAY(3, "ois_decode_submit_sm_result");
1050 
1051  buflen = strlen(str) - 1;
1052  if (buflen < 7 || str[0] != 's' || str[1] != 0x50 || str[buflen] != EOL) {
1053  goto error;
1054  }
1055 
1056  len = ois_convert_from_ia5(raw, &str[6]);
1057  if (len <= 0) {
1058  goto error;
1059  }
1060 
1061  *code = raw[0];
1062  *code &= 0xff;
1063 
1064  /* there is smsc reference number and accept time, but we ignore them */
1065 
1066  return 0;
1067 
1068  error:
1069  return -1;
1070 }
void error(int err, const char *fmt,...)
Definition: log.c:612
int code
Definition: smsc_cimd2.c:346
#define SAY(d, s)
Definition: smsc_ois.c:141
#define EOL
Definition: smsc_ois.c:153
static int ois_convert_from_ia5(char *raw, const char *str)
Definition: smsc_ois.c:1483
#define BUFLEN
Definition: smsc_ois.c:147
void ois_delete_queue ( SMSCenter smsc)

Definition at line 423 of file smsc_ois.c.

References msg, ois_debug_level, OIS_FLAG_DEBUG, SMSCenter::ois_flags, ois_receive_msg(), and SAY.

Referenced by smscenter_destruct().

424 {
425  Msg *msg;
426 
428  SAY(2, "ois_delete_queue");
429 
430  while (ois_receive_msg(smsc, &msg) > 0) {
431  gw_free(msg);
432  }
433  return;
434 }
int ois_debug_level
Definition: smsc_ois.c:136
int ois_receive_msg(SMSCenter *smsc, Msg **msg)
Definition: smsc_ois.c:396
int ois_flags
Definition: smsc_p.h:175
#define SAY(d, s)
Definition: smsc_ois.c:141
Definition: msg.h:79
#define OIS_FLAG_DEBUG
Definition: smsc_ois.c:160
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static int ois_deliver_sm_invoke ( SMSCenter smsc,
const char *  buffer 
)
static

Definition at line 1073 of file smsc_ois.c.

References error(), mo, msg, msg_create, msg_destroy(), ois_append_to_list(), ois_decode_deliver_sm_invoke(), SMSCenter::ois_received_mo, and SAY.

Referenced by ois_check_input().

1074 {
1075  Msg *msg;
1076  int ret;
1077  ois_listentry **mo;
1078 
1079  SAY(2, "ois_deliver_sm_invoke");
1080 
1081  msg = msg_create(sms);
1082 
1083  ret = ois_decode_deliver_sm_invoke(msg, buffer);
1084  if (ret < 0) {
1085  goto error;
1086  }
1087 
1088  mo = (ois_listentry **)&smsc->ois_received_mo;
1089  ois_append_to_list(mo, msg);
1090 
1091  return 0;
1092 
1093  error:
1094  msg_destroy(msg);
1095  return -1;
1096 }
void error(int err, const char *fmt,...)
Definition: log.c:612
Definition: msg.h:106
#define msg_create(type)
Definition: msg.h:136
#define SAY(d, s)
Definition: smsc_ois.c:141
void * ois_received_mo
Definition: smsc_p.h:173
static int ois_decode_deliver_sm_invoke(Msg *msg, const char *str)
Definition: smsc_ois.c:1099
Definition: msg.h:79
static void ois_append_to_list(ois_listentry **head, Msg *msg)
Definition: smsc_ois.c:764
void msg_destroy(Msg *msg)
Definition: msg.c:132
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static int ois_deliver_sm_result ( SMSCenter smsc,
int  result,
const char *  str 
)
static

Definition at line 1339 of file smsc_ois.c.

References BUFLEN, EOL, error(), IOTRACE, ois_encode_deliver_sm_result(), SAY, SMSCenter::socket, and write_to_socket().

Referenced by ois_check_input().

1340 {
1341  char body[BUFLEN+1];
1342  char buffer[BUFLEN+1];
1343  int ret;
1344 
1345  SAY(2, "ois_deliver_sm_result");
1346 
1347  /* construct a message */
1348 
1349  ois_encode_deliver_sm_result(body, result);
1350 
1351  /* first and only part */
1352 
1353  sprintf(buffer, "%c%c%.4s%.121s%c",
1354  'm', /* deliver sm result */
1355  (char)(0x50), /* ia5 encoding, the only part */
1356  &str[2],
1357  &body[0],
1358  EOL);
1359 
1360  IOTRACE("sending", buffer, strlen(buffer));
1361  ret = write_to_socket(smsc->socket, buffer);
1362  if (ret < 0) {
1363  goto error;
1364  }
1365 
1366  return 0;
1367 
1368  error:
1369  return -1;
1370 }
void error(int err, const char *fmt,...)
Definition: log.c:612
static int ois_encode_deliver_sm_result(char *str, int result)
Definition: smsc_ois.c:1373
#define SAY(d, s)
Definition: smsc_ois.c:141
#define EOL
Definition: smsc_ois.c:153
int write_to_socket(int socket, char *str)
Definition: socket.c:345
int socket
Definition: smsc_p.h:115
#define BUFLEN
Definition: smsc_ois.c:147
#define IOTRACE(x, s, l)
Definition: smsc_ois.c:144
static void ois_disconnect ( SMSCenter smsc)
static

Definition at line 595 of file smsc_ois.c.

References SAY2, SMSCenter::socket, and warning().

Referenced by ois_check_input(), ois_disconnect_all(), ois_open_sender(), ois_read_into_buffer(), and ois_submit_msg().

596 {
597  SAY2(2, "ois_disconnect fd=%d", smsc->socket);
598 
599  if (smsc->socket != -1) {
600  if (close(smsc->socket) == -1) {
601  warning(errno, "ois_disconnect: close failed...");
602  }
603  smsc->socket = -1;
604  }
605  return;
606 }
#define SAY2(d, s, t)
Definition: smsc_ois.c:142
void warning(int err, const char *fmt,...)
Definition: log.c:624
int socket
Definition: smsc_p.h:115
static void ois_disconnect_all ( SMSCenter smsc)
static

Definition at line 574 of file smsc_ois.c.

References ois_disconnect(), SMSCenter::ois_listening_socket, ois_swap_buffering(), SAY, SAY2, and warning().

Referenced by ois_close().

575 {
576  SAY2(2, "ois_disconnect_all fd=%d", smsc->ois_listening_socket);
577 
578  ois_swap_buffering(smsc);
579  SAY(4, "ois_disconnect_all: ois_disconnect");
580  ois_disconnect(smsc); /* smsc->socket */
581  ois_swap_buffering(smsc);
582  SAY(4, "ois_disconnect_all: ois_disconnect");
583  ois_disconnect(smsc); /* smsc->socket */
584 
585  if (smsc->ois_listening_socket != -1) {
586  if (close(smsc->ois_listening_socket) == -1) {
587  warning(errno, "ois_disconnect_all: close failed...");
588  }
589  smsc->ois_listening_socket = -1;
590  }
591  return;
592 }
static void ois_swap_buffering(SMSCenter *smsc)
Definition: smsc_ois.c:1668
#define SAY(d, s)
Definition: smsc_ois.c:141
#define SAY2(d, s, t)
Definition: smsc_ois.c:142
int ois_listening_socket
Definition: smsc_p.h:176
static void ois_disconnect(SMSCenter *smsc)
Definition: smsc_ois.c:595
void warning(int err, const char *fmt,...)
Definition: log.c:624
static int ois_encode_deliver_sm_result ( char *  str,
int  result 
)
static

Definition at line 1373 of file smsc_ois.c.

References ois_convert_to_ia5(), and SAY.

Referenced by ois_deliver_sm_result().

1374 {
1375  char raw[4];
1376 
1377  SAY(3, "ois_encode_deliver_sm_result");
1378 
1379  /* construct the deliver sm result body content */
1380 
1381  raw[0] = (char) result;
1382 
1383  return ois_convert_to_ia5(str, raw, 1);
1384 }
static int ois_convert_to_ia5(char *str, const char *raw, int len)
Definition: smsc_ois.c:1444
#define SAY(d, s)
Definition: smsc_ois.c:141
static int ois_encode_submit_sm_invoke ( char *  str,
const Msg msg 
)
static

Definition at line 868 of file smsc_ois.c.

References BUFLEN, ois_append_data_coding_scheme(), ois_append_msisdn(), ois_append_originating_address(), ois_append_priority(), ois_append_protocol_id(), ois_append_sm_text(), ois_append_sme_reference_number(), ois_append_status_report_request(), ois_append_submission_options(), ois_append_validity_period(), ois_convert_to_ia5(), and SAY.

Referenced by ois_submit_sm_invoke().

869 {
870  char raw[BUFLEN];
871  int pos;
872  int ret;
873 
874  SAY(3, "ois_encode_submit_sm_invoke");
875 
876  /* construct the submit sm invoke body content */
877 
878  pos = 0;
879  pos += ois_append_msisdn(&raw[pos], msg);
880  pos += ois_append_sme_reference_number(&raw[pos]);
881  pos += ois_append_priority(&raw[pos]);
882  pos += ois_append_originating_address(&raw[pos]);
883  pos += ois_append_validity_period(&raw[pos]);
884  pos += ois_append_data_coding_scheme(&raw[pos], msg);
885  pos += ois_append_status_report_request(&raw[pos]);
886  pos += ois_append_protocol_id(&raw[pos]);
887  pos += ois_append_submission_options(&raw[pos], msg);
888  pos += ois_append_sm_text(&raw[pos], msg);
889 
890  ret = ois_convert_to_ia5(str, raw, pos);
891  return ret;
892 }
static int ois_append_data_coding_scheme(char *raw, const Msg *msg)
Definition: smsc_ois.c:944
static int ois_convert_to_ia5(char *str, const char *raw, int len)
Definition: smsc_ois.c:1444
static int ois_append_priority(char *raw)
Definition: smsc_ois.c:916
#define SAY(d, s)
Definition: smsc_ois.c:141
static int ois_append_originating_address(char *raw)
Definition: smsc_ois.c:924
static int ois_append_validity_period(char *raw)
Definition: smsc_ois.c:935
static int ois_append_sme_reference_number(char *raw)
Definition: smsc_ois.c:906
static int ois_append_sm_text(char *raw, const Msg *msg)
Definition: smsc_ois.c:988
static int ois_append_msisdn(char *raw, const Msg *msg)
Definition: smsc_ois.c:894
#define BUFLEN
Definition: smsc_ois.c:147
static int ois_append_protocol_id(char *raw)
Definition: smsc_ois.c:964
static int ois_append_status_report_request(char *raw)
Definition: smsc_ois.c:956
static int ois_append_submission_options(char *raw, const Msg *msg)
Definition: smsc_ois.c:972
static int ois_expand_gsm7 ( char *  raw8,
const char *  raw7,
int  len 
)
static

Definition at line 1387 of file smsc_ois.c.

References BUFLEN, ois_debug_str(), ois_expand_gsm7_from_bits(), ois_expand_gsm7_to_bits(), and SAY2.

Referenced by ois_adjust_sm_text().

1388 {
1389  int i;
1390  char bits[8*(BUFLEN+1)];
1391 
1392  SAY2(3, "ois_expand_gsm7 len=%d", len);
1393 
1394  /* yeah, there are also better algorithms, but... */
1395  /* well, at least this is fairly portable and ok for small messages... */
1396 
1397  ois_expand_gsm7_to_bits(bits, raw7, len);
1398  for (i = 0; i < len; ++i) {
1399  raw8[i] = ois_expand_gsm7_from_bits(bits, i);
1400  }
1401 
1402  SAY2(5, "ois_expand_gsm7 gave [%s]", ois_debug_str(raw8, i));
1403  return i;
1404 }
static char ois_expand_gsm7_from_bits(const char *bits, int pos)
Definition: smsc_ois.c:1426
static int ois_expand_gsm7_to_bits(char *bits, const char *raw7, int len)
Definition: smsc_ois.c:1406
static const char * ois_debug_str(const char *raw, int len)
Definition: smsc_ois.c:1709
#define SAY2(d, s, t)
Definition: smsc_ois.c:142
#define BUFLEN
Definition: smsc_ois.c:147
static char ois_expand_gsm7_from_bits ( const char *  bits,
int  pos 
)
static

Definition at line 1426 of file smsc_ois.c.

References SAY2.

Referenced by ois_expand_gsm7().

1427 {
1428  int i;
1429  char ch;
1430 
1431  SAY2(8, "ois_expand_gsm7_from_bits pos=%d", pos);
1432 
1433  pos *= 7; /* septet position in bits */
1434  ch = '\0';
1435  for (i = 6; i >= 0; --i) {
1436  ch <<= 1;
1437  ch |= bits[pos+i];
1438  }
1439 
1440  return ch;
1441 }
#define SAY2(d, s, t)
Definition: smsc_ois.c:142
static int ois_expand_gsm7_to_bits ( char *  bits,
const char *  raw7,
int  len 
)
static

Definition at line 1406 of file smsc_ois.c.

References SAY.

Referenced by ois_expand_gsm7().

1407 {
1408  int i, j, k;
1409  char ch;
1410 
1411  SAY(3, "ois_expand_gsm7_to_bits");
1412 
1413  len *= 7; /* number of bits in the gms 7-bit msg */
1414 
1415  for (j = i = 0; j < len; ++i) {
1416  ch = raw7[i];
1417  for (k = 0; k < 8; ++k) {
1418  bits[j++] = (char) (ch & 0x01);
1419  ch >>= 1;
1420  }
1421  }
1422 
1423  return j;
1424 }
#define SAY(d, s)
Definition: smsc_ois.c:141
static int ois_extract_line_from_buffer ( char *  str,
SMSCenter smsc 
)
static

Definition at line 1641 of file smsc_ois.c.

References SMSCenter::buffer, SMSCenter::buflen, SAY2, and smscenter_remove_from_buffer().

Referenced by ois_open_sender().

1642 {
1643  int len;
1644 
1645  SAY2(3, "ois_extract_line_from_buffer buflen=%ld", (long)smsc->buflen);
1646 
1647  str[0] = '\0';
1648 
1649  for (len = 0; (size_t) len < smsc->buflen && smsc->buffer[len] != '\n';
1650  ++len) ;
1651 
1652  if ((size_t) len >= smsc->buflen) {
1653  return 0;
1654  } else {
1655  ++len;
1656  }
1657 
1658  /* the buffer contains a line */
1659 
1660  memcpy(str, smsc->buffer, len);
1661  str[len] = '\0';
1662  smscenter_remove_from_buffer(smsc, len); /* just the line */
1663 
1664  return len;
1665 }
size_t buflen
Definition: smsc_p.h:186
#define SAY2(d, s, t)
Definition: smsc_ois.c:142
void smscenter_remove_from_buffer(SMSCenter *smsc, size_t n)
Definition: smsc.c:412
char * buffer
Definition: smsc_p.h:184
static int ois_extract_msg_from_buffer ( char *  str,
SMSCenter smsc 
)
static

Definition at line 1577 of file smsc_ois.c.

References SMSCenter::buffer, BUFLEN, SMSCenter::buflen, EOL, error(), SAY2, and smscenter_remove_from_buffer().

Referenced by ois_check_input().

1578 {
1579  int len;
1580  int count;
1581 
1582  SAY2(8, "ois_extract_msg_from_buffer buflen=%ld", (long)smsc->buflen);
1583 
1584  str[0] = '\0';
1585 
1586  if (smsc->buflen < 7) { /* 7 = 6 + 1 */
1587  return 0; /* we don't have a message yet */
1588  }
1589 
1590  if (strchr("SRDATECQLMPOVsrdatecqlmpov", smsc->buffer[0]) == NULL
1591  || (smsc->buffer[1] & 0xf0) != 0x50) {
1592 
1593  goto error;
1594  }
1595 
1596  /* a valid message type, find the end of the message */
1597 
1598  count = smsc->buffer[1] & 0x0f;
1599  for (len = 0; (size_t) len < smsc->buflen; ++len) {
1600  if (smsc->buffer[len] == EOL) {
1601  if (--count < 0) {
1602  ++len;
1603  break;
1604  }
1605  }
1606  }
1607 
1608  if (count >= 0) { /* we don't have all the pieces */
1609  if (len < BUFLEN) {
1610  return 0; /* ...but maybe later */
1611  }
1612  goto error;
1613  }
1614 
1615  /* the buffer contains a promising message candidate */
1616 
1617  memcpy(str, smsc->buffer, len);
1618  str[len] = '\0';
1619  smscenter_remove_from_buffer(smsc, len); /* just the message */
1620 
1621  return len;
1622 
1623  error:
1624  for (len = 0; (size_t) len < smsc->buflen && smsc->buffer[len] != EOL;
1625  ++len) ;
1626  if (len > BUFLEN) len = BUFLEN;
1627 
1628  memcpy(str, smsc->buffer, len);
1629  str[len] = '\0';
1630  smscenter_remove_from_buffer(smsc, smsc->buflen); /* everything */
1631 
1632  return -len;
1633 }
void error(int err, const char *fmt,...)
Definition: log.c:612
size_t buflen
Definition: smsc_p.h:186
#define EOL
Definition: smsc_ois.c:153
#define SAY2(d, s, t)
Definition: smsc_ois.c:142
void smscenter_remove_from_buffer(SMSCenter *smsc, size_t n)
Definition: smsc.c:412
#define BUFLEN
Definition: smsc_ois.c:147
char * buffer
Definition: smsc_p.h:184
static int ois_ignore_protocol_id ( const char *  raw)
static

Definition at line 1244 of file smsc_ois.c.

References SAY.

Referenced by ois_decode_deliver_sm_invoke().

1245 {
1246  SAY(3, "ois_ignore_protocol_id");
1247 
1248  return 1;
1249 }
#define SAY(d, s)
Definition: smsc_ois.c:141
static int ois_ignore_smsc_reference_number ( const char *  raw)
static

Definition at line 1203 of file smsc_ois.c.

References SAY.

Referenced by ois_decode_deliver_sm_invoke().

1204 {
1205  int value;
1206 
1207  SAY(3, "ois_ignore_smsc_reference_number");
1208 
1209  value = raw[3] & 0xff;
1210  value <<= 8;
1211  value |= raw[2] & 0xff;
1212  value <<= 8;
1213  value |= raw[1] & 0xff;
1214  value <<= 8;
1215  value |= raw[0] & 0xff;
1216 
1217  return 4;
1218 }
#define SAY(d, s)
Definition: smsc_ois.c:141
static int ois_ignore_time ( const char *  raw)
static

Definition at line 1326 of file smsc_ois.c.

References SAY.

Referenced by ois_decode_deliver_sm_invoke().

1327 {
1328  char str[15];
1329 
1330  SAY(3, "ois_ignore_time");
1331 
1332  strncpy(str, raw, 14); str[14] = '\0';
1333 
1334  return 14;
1335 }
#define SAY(d, s)
Definition: smsc_ois.c:141
static int ois_increment_counter ( void  )
static

Definition at line 799 of file smsc_ois.c.

References MAXCOUNTER, ois_counter, and SAY.

Referenced by ois_submit_sm_invoke().

800 {
801  SAY(3, "ois_increment_counter");
802 
804  return ois_counter;
805 }
#define SAY(d, s)
Definition: smsc_ois.c:141
#define MAXCOUNTER
Definition: smsc_ois.c:152
static int ois_counter
Definition: smsc_ois.c:166
static int ois_int_to_i4 ( char *  raw,
int  nbr 
)
static

Definition at line 786 of file smsc_ois.c.

References SAY.

Referenced by ois_append_sme_reference_number().

787 {
788  int pos;
789 
790  SAY(3, "ois_int_to_i4");
791 
792  for (pos = 0; pos < 4; ++pos) {
793  raw[pos] = (char)(nbr % 0x100);
794  nbr /= 0x100;
795  }
796  return 4;
797 }
#define SAY(d, s)
Definition: smsc_ois.c:141
SMSCenter* ois_open ( int  receiveport,
const char *  hostname,
int  port,
int  debug_level 
)

Definition at line 222 of file smsc_ois.c.

References error(), SMSCenter::hostname, SMSCenter::name, ois_debug_level, OIS_FLAG_DEBUG, SMSCenter::ois_flags, ois_open_listener(), port, SMSCenter::port, SMSCenter::receive_port, SAY, SMSC_TYPE_OIS, smscenter_construct(), smscenter_destruct(), and SMSCenter::type.

Referenced by smsc_open().

223 {
224  SMSCenter *smsc;
225  int ret;
226 
227  ois_debug_level = debug_level & OIS_FLAG_DEBUG;
228  SAY(2, "ois_open");
229 
230  /* create a SMSCenter structure */
231 
232  smsc = smscenter_construct();
233  if (smsc == NULL) {
234  goto error;
235  }
236 
237  smsc->type = SMSC_TYPE_OIS;
238  smsc->receive_port = receiveport;
239  smsc->hostname = gw_strdup(hostname);
240  smsc->port = port;
241  smsc->ois_flags = ois_debug_level;
242 
243  ret = ois_open_listener(smsc);
244  if (ret < 0) {
245  goto error;
246  }
247  sprintf(smsc->name, "OIS:TCP/X.25-Translator:localhost:%d:TCP:%.512s:%d",
248  smsc->receive_port, smsc->hostname, smsc->port);
249 
250  return smsc;
251 
252  error:
253  error(0, "ois_open: could not open");
254  smscenter_destruct(smsc);
255  return NULL;
256 }
void error(int err, const char *fmt,...)
Definition: log.c:612
int ois_debug_level
Definition: smsc_ois.c:136
int ois_flags
Definition: smsc_p.h:175
#define SAY(d, s)
Definition: smsc_ois.c:141
int receive_port
Definition: smsc_p.h:123
static int port
Definition: fakesmsc.c:120
int port
Definition: smsc_p.h:122
SMSCenter * smscenter_construct(void)
Definition: smsc.c:101
void smscenter_destruct(SMSCenter *smsc)
Definition: smsc.c:168
Octstr * hostname
Definition: fakewap.c:232
static int ois_open_listener(SMSCenter *smsc)
Definition: smsc_ois.c:448
#define OIS_FLAG_DEBUG
Definition: smsc_ois.c:160
int type
Definition: smsc_p.h:93
char name[1024]
Definition: smsc_p.h:96
char * hostname
Definition: smsc_p.h:121
static int ois_open_listener ( SMSCenter smsc)
static

Definition at line 448 of file smsc_ois.c.

References error(), make_server_socket(), SMSCenter::ois_alive, SMSCenter::ois_alive2, ois_close(), OIS_FLAG_ERROR, OIS_FLAG_NOBANNER, SMSCenter::ois_flags, SMSCenter::ois_listening_socket, SMSCenter::receive_port, SAY, SAY2, and socket_set_blocking().

Referenced by ois_open(), and ois_reopen().

449 {
450  SAY(2, "ois_open_listener");
451 
453  NULL);
454  /* XXX add interface_name if required */
455  if (smsc->ois_listening_socket < 0) {
456  goto error;
457  }
458  if (socket_set_blocking(smsc->ois_listening_socket, 0) < 0) {
459  ois_close(smsc);
460  goto error;
461  }
462  smsc->ois_flags &= ~OIS_FLAG_ERROR;
463  smsc->ois_flags &= ~OIS_FLAG_NOBANNER;
464  smsc->ois_alive2 = time(&smsc->ois_alive);
465 
466  SAY2(2, "ois_open_listener fd=%d", smsc->ois_listening_socket);
467  return 0;
468 
469  error:
470  error(0, "ois_open_listener: failed to open listening socket");
471  return -1;
472 }
void error(int err, const char *fmt,...)
Definition: log.c:612
int socket_set_blocking(int fd, int blocking)
Definition: socket.c:368
int ois_flags
Definition: smsc_p.h:175
#define SAY(d, s)
Definition: smsc_ois.c:141
int receive_port
Definition: smsc_p.h:123
#define OIS_FLAG_ERROR
Definition: smsc_ois.c:161
int ois_close(SMSCenter *smsc)
Definition: smsc_ois.c:263
#define SAY2(d, s, t)
Definition: smsc_ois.c:142
int ois_listening_socket
Definition: smsc_p.h:176
int make_server_socket(int port, const char *interface_name)
Definition: socket.c:93
time_t ois_alive2
Definition: smsc_p.h:172
#define OIS_FLAG_NOBANNER
Definition: smsc_ois.c:162
time_t ois_alive
Definition: smsc_p.h:171
static int ois_open_receiver ( SMSCenter smsc)
static

Definition at line 539 of file smsc_ois.c.

References debug(), error(), gw_netaddr_to_octstr(), octstr_destroy(), octstr_get_cstr, SMSCenter::ois_alive, OIS_FLAG_ERROR, SMSCenter::ois_flags, SMSCenter::ois_listening_socket, SAY, SAY2, and SMSCenter::socket.

Referenced by ois_check_incoming().

540 {
541  struct sockaddr_in addr;
542  int addrlen;
543  Octstr *os;
544 
545  SAY(2, "ois_open_receiver");
546 
547  /* the listening socket should be non-blocking... */
548 
549  addrlen = sizeof(addr);
550  smsc->socket = accept(smsc->ois_listening_socket,
551  (struct sockaddr *)&addr, (socklen_t *)&addrlen);
552  if (smsc->socket == -1) {
553  if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
554  /* || errno == ECONNABORTED || errno == EPROTO) -Kalle 6.7 */
555  {
556  return 0;
557  } else {
558  error(errno, "ois_open_receiver: accept failed");
559  smsc->ois_flags |= OIS_FLAG_ERROR;
560  return -1;
561  }
562  }
563 
564  SAY2(2, "ois_open_receiver fd=%d", smsc->socket);
565  os = gw_netaddr_to_octstr(AF_INET, &addr.sin_addr);
566  debug("bb.sms.ois", 0, "connection from host %s port %hu",
567  octstr_get_cstr(os), ntohs(addr.sin_port));
568  octstr_destroy(os);
569  time(&smsc->ois_alive);
570  return 0;
571 }
void error(int err, const char *fmt,...)
Definition: log.c:612
int ois_flags
Definition: smsc_p.h:175
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define SAY(d, s)
Definition: smsc_ois.c:141
#define OIS_FLAG_ERROR
Definition: smsc_ois.c:161
#define SAY2(d, s, t)
Definition: smsc_ois.c:142
int ois_listening_socket
Definition: smsc_p.h:176
Octstr * gw_netaddr_to_octstr(int af, void *src)
Definition: socket.c:677
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
int socket
Definition: smsc_p.h:115
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
int socklen_t
Definition: socket.h:73
time_t ois_alive
Definition: smsc_p.h:171
static int ois_open_sender ( SMSCenter smsc)
static

Definition at line 475 of file smsc_ois.c.

References SMSCenter::buffer, BUFLEN, SMSCenter::buflen, debug(), error(), SMSCenter::hostname, SMSCenter::ois_ack_debt, SMSCenter::ois_alive, ois_debug_str(), ois_disconnect(), ois_extract_line_from_buffer(), OIS_FLAG_NOBANNER, SMSCenter::ois_flags, OIS_OPEN_WAITTIME, ois_read_into_buffer(), OIS_WAITTIME, SMSCenter::port, SAY, SAY2, SMSCenter::socket, and tcpip_connect_to_server().

Referenced by ois_submit_msg().

476 {
477  int ret;
478  char buffer[BUFLEN+1];
479  time_t now;
480  time_t beginning;
481 
482  SAY(2, "ois_open_sender");
483  debug("bb.sms.ois", 0, "connecting to host %s port %d",
484  smsc->hostname, smsc->port);
485 
486  time(&beginning);
487  smsc->socket = tcpip_connect_to_server(smsc->hostname, smsc->port,
488  NULL);
489  /* XXX add interface_name if required */
490  if (smsc->socket < 0) {
491  return -1;
492  } else {
493  smsc->buflen = 0;
494  time(&smsc->ois_alive);
495  smsc->ois_ack_debt = 0;
496  }
497 
498  SAY2(2, "ois_open_sender fd=%d", smsc->socket);
499  if (smsc->ois_flags & OIS_FLAG_NOBANNER) {
500  return 0;
501  }
502 
503  buffer[0] = '\0';
504  for (time(&now); (now - beginning) < OIS_OPEN_WAITTIME; time(&now)) {
505  ret = ois_read_into_buffer(smsc, OIS_WAITTIME);
506  if (ret < 0) {
507  goto error;
508  }
509 
510  if (smsc->buflen == 0) {
511  /* assume that the router is in the quiet mode */
512  /* there will be no banners */
513  smsc->ois_flags |= OIS_FLAG_NOBANNER;
514  debug("bb.sms.ois", 0, "assuming that %s:%d is in the quiet mode",
515  smsc->hostname, smsc->port);
516  return 0;
517  }
518  ret = ois_extract_line_from_buffer(buffer, smsc);
519  if (ret > 0) {
520  if (strncmp(buffer, "Trying", 6) == 0 &&
521  strstr(buffer, "...Open\r\n") != NULL) {
522  time(&smsc->ois_alive);
523  return 0;
524  } else {
525  break;
526  }
527  }
528  }
529 
530  error:
531  SAY(4, "ois_open_sender: ois_disconnect in error");
532  ois_disconnect(smsc);
533  error(0, "ois_open_sender: failed to connect [%s%s]",
534  buffer, ois_debug_str(smsc->buffer, smsc->buflen));
535  return -1;
536 }
int ois_ack_debt
Definition: smsc_p.h:174
void error(int err, const char *fmt,...)
Definition: log.c:612
int tcpip_connect_to_server(char *hostname, int port, const char *source_addr)
Definition: socket.c:149
int ois_flags
Definition: smsc_p.h:175
static int ois_extract_line_from_buffer(char *str, SMSCenter *smsc)
Definition: smsc_ois.c:1641
size_t buflen
Definition: smsc_p.h:186
#define OIS_WAITTIME
Definition: smsc_ois.c:150
#define SAY(d, s)
Definition: smsc_ois.c:141
static const char * ois_debug_str(const char *raw, int len)
Definition: smsc_ois.c:1709
#define OIS_OPEN_WAITTIME
Definition: smsc_ois.c:148
#define SAY2(d, s, t)
Definition: smsc_ois.c:142
int port
Definition: smsc_p.h:122
static void ois_disconnect(SMSCenter *smsc)
Definition: smsc_ois.c:595
static int ois_read_into_buffer(SMSCenter *smsc, long wait_usec)
Definition: smsc_ois.c:609
int socket
Definition: smsc_p.h:115
#define BUFLEN
Definition: smsc_ois.c:147
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
char * buffer
Definition: smsc_p.h:184
#define OIS_FLAG_NOBANNER
Definition: smsc_ois.c:162
char * hostname
Definition: smsc_p.h:121
time_t ois_alive
Definition: smsc_p.h:171
int ois_pending_smsmessage ( SMSCenter smsc)

Definition at line 318 of file smsc_ois.c.

References SMSCenter::ois_ack_debt, ois_check_incoming(), ois_check_input(), ois_debug_level, OIS_FLAG_DEBUG, SMSCenter::ois_flags, OIS_NOWAIT, SMSCenter::ois_socket, ois_swap_buffering(), SAY, SMSCenter::socket, and warning().

Referenced by smscenter_pending_smsmessage().

319 {
320  int ret;
321 
323  SAY(8, "ois_pending_smsmessage");
324 
325  ret = ois_check_incoming(smsc, OIS_NOWAIT);
326  if (ret == 0 && smsc->socket != -1) {
327  ret = ois_check_input(smsc, OIS_NOWAIT);
328  }
329  if (ret == 0 && smsc->ois_socket != -1) {
330  ois_swap_buffering(smsc);
331  ret = ois_check_input(smsc, OIS_NOWAIT);
332  ois_swap_buffering(smsc);
333  if (smsc->ois_socket == -1 && smsc->ois_ack_debt != 0) {
334  warning(0, "ois_pending_smsmessage: missing %d ack(s)...",
335  smsc->ois_ack_debt);
336  }
337  }
338  return ret;
339 }
int ois_ack_debt
Definition: smsc_p.h:174
int ois_debug_level
Definition: smsc_ois.c:136
static void ois_swap_buffering(SMSCenter *smsc)
Definition: smsc_ois.c:1668
static int ois_check_input(SMSCenter *smsc, long wait_usec)
Definition: smsc_ois.c:644
int ois_flags
Definition: smsc_p.h:175
static int ois_check_incoming(SMSCenter *smsc, long wait_usec)
Definition: smsc_ois.c:721
#define SAY(d, s)
Definition: smsc_ois.c:141
void warning(int err, const char *fmt,...)
Definition: log.c:624
#define OIS_FLAG_DEBUG
Definition: smsc_ois.c:160
int socket
Definition: smsc_p.h:115
#define OIS_NOWAIT
Definition: smsc_ois.c:151
int ois_socket
Definition: smsc_p.h:177
static int ois_read_into_buffer ( SMSCenter smsc,
long  wait_usec 
)
static

Definition at line 609 of file smsc_ois.c.

References SMSCenter::buflen, debug(), SMSCenter::ois_alive, ois_disconnect(), OIS_FLAG_CLOSED, SMSCenter::ois_flags, read_available(), SAY, smscenter_read_into_buffer(), and SMSCenter::socket.

Referenced by ois_check_input(), and ois_open_sender().

610 {
611  int ret;
612 
613  SAY(8, "ois_read_into_buffer");
614 
615  if (smsc->socket == -1) {
616  if ((smsc->ois_flags & OIS_FLAG_CLOSED) == 0) {
617  debug("bb.sms.ois", 0, "attempting to read from a closed socket");
618  smsc->ois_flags |= OIS_FLAG_CLOSED;
619  }
620  return 0;
621  } else {
622  smsc->ois_flags &= ~OIS_FLAG_CLOSED;
623  }
624 
625  ret = read_available(smsc->socket, wait_usec);
626  if (ret > 0) {
627  time(&smsc->ois_alive);
628  ret = smscenter_read_into_buffer(smsc);
629  if (ret > 0 || (ret == 0 && smsc->buflen > 0)) {
630  SAY(2, "ois_read_into_buffer got something");
631  } else if (ret == 0) {
632  if (smsc->buflen > 0) {
633  SAY(2, "ois_read_into_buffer has something");
634  ret = 1;
635  }
636  SAY(4, "ois_read_into_buffer: ois_disconnect");
637  ois_disconnect(smsc);
638  }
639  }
640  return ret;
641 }
#define OIS_FLAG_CLOSED
Definition: smsc_ois.c:164
int ois_flags
Definition: smsc_p.h:175
size_t buflen
Definition: smsc_p.h:186
int smscenter_read_into_buffer(SMSCenter *smsc)
Definition: smsc.c:348
#define SAY(d, s)
Definition: smsc_ois.c:141
static void ois_disconnect(SMSCenter *smsc)
Definition: smsc_ois.c:595
int socket
Definition: smsc_p.h:115
int read_available(int fd, long wait_usec)
Definition: socket.c:406
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
time_t ois_alive
Definition: smsc_p.h:171
int ois_receive_msg ( SMSCenter smsc,
Msg **  msg 
)

Definition at line 396 of file smsc_ois.c.

References ois_listentry::msg, ois_listentry::next, ois_debug_level, OIS_FLAG_DEBUG, OIS_FLAG_ERROR, SMSCenter::ois_flags, SMSCenter::ois_received_mo, and SAY.

Referenced by ois_delete_queue(), and smscenter_receive_msg().

397 {
398  ois_listentry *item;
399 
401  SAY(2, "ois_receive_msg");
402 
403  item = smsc->ois_received_mo;
404  if (item == NULL) { /* no mo messages */
405  if ((smsc->ois_flags & OIS_FLAG_ERROR) == 0) {
406  return 0; /* should actually not happen */
407  } else {
408  return -1; /* error pending, reopen? */
409  }
410  } else { /* we have a message waiting */
411  smsc->ois_received_mo = item->next;
412  *msg = item->msg;
413  gw_free(item);
414  return 1; /* got the message */
415  }
416 }
int ois_debug_level
Definition: smsc_ois.c:136
struct ois_listentry * next
Definition: smsc_ois.c:156
int ois_flags
Definition: smsc_p.h:175
#define SAY(d, s)
Definition: smsc_ois.c:141
void * ois_received_mo
Definition: smsc_p.h:173
#define OIS_FLAG_ERROR
Definition: smsc_ois.c:161
#define OIS_FLAG_DEBUG
Definition: smsc_ois.c:160
int ois_reopen ( SMSCenter smsc)

Definition at line 287 of file smsc_ois.c.

References error(), ois_close(), ois_debug_level, OIS_FLAG_DEBUG, SMSCenter::ois_flags, ois_open_listener(), SAY, SMSC_TYPE_OIS, and SMSCenter::type.

Referenced by smsc_reopen().

288 {
289  int ret;
290 
292  SAY(2, "ois_reopen");
293 
294  ois_close(smsc);
295 
296  if (smsc->type == SMSC_TYPE_OIS) {
297  ret = ois_open_listener(smsc);
298  if (ret < 0) {
299  goto error;
300  }
301  } else {
302  error(0, "ois_reopen: wrong smsc type");
303  goto error;
304  }
305  return 0;
306 
307  error:
308  error(0, "ois_reopen: could not open");
309  return -1;
310 }
void error(int err, const char *fmt,...)
Definition: log.c:612
int ois_debug_level
Definition: smsc_ois.c:136
int ois_flags
Definition: smsc_p.h:175
#define SAY(d, s)
Definition: smsc_ois.c:141
int ois_close(SMSCenter *smsc)
Definition: smsc_ois.c:263
static int ois_open_listener(SMSCenter *smsc)
Definition: smsc_ois.c:448
#define OIS_FLAG_DEBUG
Definition: smsc_ois.c:160
int type
Definition: smsc_p.h:93
int ois_submit_msg ( SMSCenter smsc,
const Msg msg 
)

Definition at line 346 of file smsc_ois.c.

References error(), SMSCenter::ois_ack_debt, SMSCenter::ois_alive, ois_debug_level, ois_disconnect(), OIS_FLAG_DEBUG, SMSCenter::ois_flags, ois_open_sender(), ois_submit_sm_invoke(), ois_swap_buffering(), SAY, SMSCenter::socket, and warning().

Referenced by smscenter_submit_msg().

347 {
348  int ret;
349 
351  SAY(2, "ois_submit_msg");
352  ois_swap_buffering(smsc);
353 
354  if (msg_type((Msg *)msg) != sms) {
355  error(0, "ois_submit_msg: can not handle message types other than smart_msg");
356  goto error;
357  }
358 
359  if (smsc->socket == -1) {
360  ret = ois_open_sender(smsc);
361  if (ret < 0) {
362  goto error;
363  }
364  }
365 
366  ret = ois_submit_sm_invoke(smsc, msg);
367  if (ret < 0) {
368  goto error_close;
369  }
370 
371  ++smsc->ois_ack_debt;
372  time(&smsc->ois_alive);
373  ret = 0;
374  goto out;
375 
376  error_close:
377  if (smsc->ois_ack_debt != 0) {
378  warning(0, "ois_submit_msg: missing %d ack(s)...",
379  smsc->ois_ack_debt);
380  }
381  SAY(4, "ois_submit_msg: ois_disconnect in error_close");
382  ois_disconnect(smsc);
383  error:
384  SAY(2, "ois_submit_msg error");
385  ret = -1;
386  out:
387  ois_swap_buffering(smsc);
388  return ret;
389 }
int ois_ack_debt
Definition: smsc_p.h:174
void error(int err, const char *fmt,...)
Definition: log.c:612
int ois_debug_level
Definition: smsc_ois.c:136
static void ois_swap_buffering(SMSCenter *smsc)
Definition: smsc_ois.c:1668
static int ois_open_sender(SMSCenter *smsc)
Definition: smsc_ois.c:475
int ois_flags
Definition: smsc_p.h:175
msg_type
Definition: msg.h:73
#define SAY(d, s)
Definition: smsc_ois.c:141
Definition: msg.h:79
static void ois_disconnect(SMSCenter *smsc)
Definition: smsc_ois.c:595
void warning(int err, const char *fmt,...)
Definition: log.c:624
#define OIS_FLAG_DEBUG
Definition: smsc_ois.c:160
int socket
Definition: smsc_p.h:115
static int ois_submit_sm_invoke(SMSCenter *smsc, const Msg *msg)
Definition: smsc_ois.c:808
time_t ois_alive
Definition: smsc_p.h:171
static int ois_submit_sm_invoke ( SMSCenter smsc,
const Msg msg 
)
static

Definition at line 808 of file smsc_ois.c.

References BUFLEN, EOL, error(), IOTRACE, ois_counter, ois_encode_submit_sm_invoke(), ois_increment_counter(), SAY, SMSCenter::socket, and write_to_socket().

Referenced by ois_submit_msg().

809 {
810  char body[BUFLEN+1];
811  char buffer[BUFLEN+1];
812  int len;
813  int count;
814  int i;
815  int ret;
816 
817  SAY(2, "ois_submit_sm_invoke");
818 
819  /* construct a message */
820 
821  ois_increment_counter(); /* once per invoke */
822  len = ois_encode_submit_sm_invoke(body, msg);
823 
824  /* the x.25 gear should be capable to fragment large messages, but... */
825  /* let's just use an explicit 128 byte blocks */
826 
827  count = (len-1) / 121; /* 121 = 128 - 6 - 1 */
828 
829  /* first part */
830 
831  sprintf(buffer, "%c%c%04d%.121s%c",
832  'S', /* submit sm invoke */
833  (char)(0x50|count), /* ia5 encoding, first part */
834  ois_counter,
835  &body[0],
836  EOL);
837  IOTRACE("sending", buffer, strlen(buffer));
838  ret = write_to_socket(smsc->socket, buffer);
839  if (ret < 0) {
840  goto error;
841  }
842 
843  /* additional parts */
844 
845  for (i = 1; i <= count; ++i) {
846  sprintf(buffer, "%c%c%04d%.121s%c",
847  'S', /* submit sm invoke */
848  (char)(0x60|(count-i)), /* ia5, additional part */
849  ois_counter,
850  &body[i*121],
851  EOL);
852  IOTRACE("sending", buffer, strlen(buffer));
853  ret = write_to_socket(smsc->socket, buffer);
854  if (ret < 0) {
855  goto error;
856  }
857  }
858 
859  SAY(2, "ois_submit_sm_invoke ok");
860  return 0;
861 
862  error:
863  SAY(2, "ois_submit_sm_invoke error");
864  return -1;
865 }
void error(int err, const char *fmt,...)
Definition: log.c:612
#define SAY(d, s)
Definition: smsc_ois.c:141
#define EOL
Definition: smsc_ois.c:153
int write_to_socket(int socket, char *str)
Definition: socket.c:345
static int ois_encode_submit_sm_invoke(char *str, const Msg *msg)
Definition: smsc_ois.c:868
int socket
Definition: smsc_p.h:115
static int ois_increment_counter(void)
Definition: smsc_ois.c:799
#define BUFLEN
Definition: smsc_ois.c:147
static int ois_counter
Definition: smsc_ois.c:166
#define IOTRACE(x, s, l)
Definition: smsc_ois.c:144
static int ois_submit_sm_result ( SMSCenter smsc,
const char *  buffer 
)
static

Definition at line 1024 of file smsc_ois.c.

References error(), ois_decode_submit_sm_result(), and SAY.

Referenced by ois_check_input().

1025 {
1026  int status;
1027  int ret;
1028 
1029  SAY(2, "ois_submit_sm_result");
1030 
1031  ret = ois_decode_submit_sm_result(&status, buffer);
1032  if (ret < 0) {
1033  goto error;
1034  }
1035 
1036  return status;
1037 
1038  error:
1039  return -1;
1040 }
void error(int err, const char *fmt,...)
Definition: log.c:612
static int ois_decode_submit_sm_result(int *code, const char *str)
Definition: smsc_ois.c:1043
#define SAY(d, s)
Definition: smsc_ois.c:141
static void ois_swap_buffering ( SMSCenter smsc)
static

Definition at line 1668 of file smsc_ois.c.

References SMSCenter::buffer, SMSCenter::buflen, SMSCenter::bufsize, SMSCenter::ois_alive, SMSCenter::ois_alive2, SMSCenter::ois_buffer, SMSCenter::ois_buflen, SMSCenter::ois_bufsize, SMSCenter::ois_socket, SAY, and SMSCenter::socket.

Referenced by ois_close(), ois_disconnect_all(), ois_pending_smsmessage(), and ois_submit_msg().

1669 {
1670  time_t alive;
1671  int socket;
1672  char *buffer;
1673  size_t bufsize;
1674  size_t buflen;
1675 
1676  SAY(8, "ois_swap_buffering");
1677 
1678  if (smsc->ois_bufsize == 0) {
1679  smsc->ois_buflen = 0;
1680  smsc->ois_bufsize = smsc->bufsize;
1681  smsc->ois_buffer = gw_malloc(smsc->ois_bufsize);
1682  memset(smsc->ois_buffer, 0, smsc->ois_bufsize);
1683  }
1684 
1685  alive = smsc->ois_alive;
1686  smsc->ois_alive = smsc->ois_alive2;
1687  smsc->ois_alive2 = alive;
1688 
1689  socket = smsc->socket;
1690  smsc->socket = smsc->ois_socket;
1691  smsc->ois_socket = socket;
1692 
1693  buffer = smsc->buffer;
1694  smsc->buffer = smsc->ois_buffer;
1695  smsc->ois_buffer = buffer;
1696 
1697  buflen = smsc->buflen;
1698  smsc->buflen = smsc->ois_buflen;
1699  smsc->ois_buflen = buflen;
1700 
1701  bufsize = smsc->bufsize;
1702  smsc->bufsize = smsc->ois_bufsize;
1703  smsc->ois_bufsize = bufsize;
1704 
1705  return;
1706 }
size_t bufsize
Definition: smsc_p.h:185
size_t ois_bufsize
Definition: smsc_p.h:179
size_t buflen
Definition: smsc_p.h:186
#define SAY(d, s)
Definition: smsc_ois.c:141
int socket
Definition: smsc_p.h:115
size_t ois_buflen
Definition: smsc_p.h:180
char * ois_buffer
Definition: smsc_p.h:178
time_t ois_alive2
Definition: smsc_p.h:172
char * buffer
Definition: smsc_p.h:184
int ois_socket
Definition: smsc_p.h:177
time_t ois_alive
Definition: smsc_p.h:171

Variable Documentation

int ois_counter = 0
static
int ois_debug_level = 0
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.