1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2014 Kannel Group
5  * Copyright (c) 1998-2001 WapIT Ltd.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  *    if any, must include the following acknowledgment:
22  *       "This product includes software developed by the
23  *        Kannel Group (http://www.kannel.org/)."
24  *    Alternately, this acknowledgment may appear in the software itself,
25  *    if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Kannel" and "Kannel Group" must not be used to
28  *    endorse or promote products derived from this software without
29  *    prior written permission. For written permission, please
30  *    contact org@kannel.org.
31  *
32  * 5. Products derived from this software may not be called "Kannel",
33  *    nor may "Kannel" appear in their name, without prior written
34  *    permission of the Kannel Group.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS
40  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
41  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
42  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
46  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Kannel Group.  For more information on
51  * the Kannel Group, please see <http://www.kannel.org/>.
52  *
53  * Portions of this software are based upon software originally written at
54  * WapIT Ltd., Helsinki, Finland for the Kannel project.
55  */
56 
57 /* Driver for CIMD 2 SMS centres.
58  * Copyright 2000  WapIT Oy Ltd.
59  * Author: Richard Braakman
60  *
61  * Upgrade to SMSCConn API: 2002 Kalle Marjola / 2003 Angel Fradejas
62  */
63 
64 /* TODO: Check checksums on incoming packets */
65 /* TODO: Leading or trailing spaces are not allowed on parameters
66  * "user identity" and "password".  Check this. */
67 /* TODO: Try to use the "More messages to send" flag */
68 
69 /* This code is based on the CIMD 2 spec, version 2-0 en.
70  * All USSD-specific parts have been left out, since we only want to
71  * communicate with SMSC's.
72  *
73  * I found one contradiction in the spec:
74  *
75  * - The definition of Integer parameters specifies decimal digits only,
76  *   but at least one Integer parameter (Validity Period Relative) can
77  *   be negative.  I assume that this means a leading - is valid.
78  */
79 
80 #include <ctype.h>
81 #include <time.h>
82 #include <errno.h>
83 #include <limits.h>
84 #include <string.h>
85 
86 #include <unistd.h>
87 
88 #include "gwlib/gwlib.h"
89 #include "smscconn.h"
90 #include "smscconn_p.h"
91 #include "bb_smscconn_cb.h"
92 
93 #include "shared.h"
94 #include "sms.h"
95 #include "dlr.h"
96 
97 
98 typedef struct privdata {
99     Octstr  *username;
100     Octstr  *password;
101     Octstr  *host;
102     long    port;
103     long    our_port;
104     long    keepalive;
105     Octstr  *my_number;
106     int no_dlr;
107 
108     int     socket;
109     int     send_seq;
110     int     receive_seq;
111 
112     Octstr  *inbuffer;
113     List    *received;
114 
115     time_t  next_ping;
116 
117     List *outgoing_queue;
118     SMSCConn *conn;
119     int io_thread;
120     int quitting;
121     List *stopped; /* list-trick for suspend/isolate */
122 
123 } PrivData;
124 
125 
126 
127 /* Microseconds before giving up on a request */
128 #define RESPONSE_TIMEOUT (60 * 1000000)
129 
130 /* Textual names for the operation codes defined by the CIMD 2 spec. */
131 /* If you make changes here, also change the operation table. */
132 enum {
133     /* Requests from client */
134     LOGIN = 1,
135     LOGOUT = 2,
136     SUBMIT_MESSAGE = 3,
137     ENQUIRE_MESSAGE_STATUS = 4,
138     DELIVERY_REQUEST = 5,
139     CANCEL_MESSAGE = 6,
140     SET_REQ = 8,
141     GET_REQ = 9,
142 
143     /* Requests from server */
144     DELIVER_MESSAGE = 20,
145     DELIVER_STATUS_REPORT = 23,
146 
147     /* Requests from either */
148     ALIVE = 40,
149 
150     /* Not a request; add to any request to make it a response */
151     RESPONSE = 50,
152 
153     /* Responses not related to requests */
154     GENERAL_ERROR_RESPONSE = 98,
155     NACK = 99
156 };
157 
158 /* Textual names for the parameters defined by the CIMD 2 spec. */
159 /* If you make changes here, also change the parameter table. */
160 enum {
161     P_USER_IDENTITY = 10,
162     P_PASSWORD = 11,
163     P_DESTINATION_ADDRESS = 21,
164     P_ORIGINATING_ADDRESS = 23,
165     P_ORIGINATING_IMSI = 26,
166     P_ALPHANUMERIC_ORIGINATING_ADDRESS = 27,
167     P_ORIGINATED_VISITED_MSC = 28,
168     P_DATA_CODING_SCHEME = 30,
169     P_USER_DATA_HEADER = 32,
170     P_USER_DATA = 33,
171     P_USER_DATA_BINARY = 34,
172     P_MORE_MESSAGES_TO_SEND = 44,
173     P_VALIDITY_PERIOD_RELATIVE = 50,
174     P_VALIDITY_PERIOD_ABSOLUTE = 51,
175     P_PROTOCOL_IDENTIFIER = 52,
176     P_FIRST_DELIVERY_TIME_RELATIVE = 53,
177     P_FIRST_DELIVERY_TIME_ABSOLUTE = 54,
178     P_REPLY_PATH = 55,
179     P_STATUS_REPORT_REQUEST = 56,
180     P_CANCEL_ENABLED = 58,
181     P_CANCEL_MODE = 59,
182     P_MC_TIMESTAMP = 60,
183     P_STATUS_CODE = 61,
184     P_STATUS_ERROR_CODE = 62,
185     P_DISCHARGE_TIME = 63,
186     P_TARIFF_CLASS = 64,
187     P_SERVICE_DESCRIPTION = 65,
188     P_MESSAGE_COUNT = 66,
189     P_PRIORITY = 67,
190     P_DELIVERY_REQUEST_MODE = 68,
191     P_SERVICE_CENTER_ADDRESS = 69,
192     P_GET_PARAMETER = 500,
193     P_MC_TIME = 501,
194     P_ERROR_CODE = 900,
195     P_ERROR_TEXT = 901
196 };
197 
198 /***************************************************************************/
199 /* Table of properties of the parameters defined by CIMD 2, and some       */
200 /* functions to look up fields.                                            */
201 /***************************************************************************/
202 
203 /* Parameter types, internal.  CIMD 2 spec considers P_TIME to be "Integer"
204  * and P_SMS to be "User Data". */
205 enum { P_INT, P_STRING, P_ADDRESS, P_TIME, P_HEX, P_SMS };
206 
207 /* Information about the parameters defined by the CIMD 2 spec.
208  * Used for warning about invalid incoming messages, and for validating
209  * outgoing messages. */
210 static const struct
211 {
212     char *name;
213     int number;
214     int maxlen;
215     int type;  /* P_ values */
216     int minval, maxval;  /* For P_INT */
217 }
218 parameters[] = {
219     { "user identity", P_USER_IDENTITY, 32, P_STRING },
220     { "password", P_PASSWORD, 32, P_STRING },
221     { "destination address", P_DESTINATION_ADDRESS, 20, P_ADDRESS },
222     { "originating address", P_ORIGINATING_ADDRESS, 20, P_ADDRESS },
223     /* IMSI is International Mobile Subscriber Identity number */
224     { "originating IMSI", P_ORIGINATING_IMSI, 20, P_ADDRESS },
225     { "alphanumeric originating address", P_ALPHANUMERIC_ORIGINATING_ADDRESS, 11, P_STRING },
226     { "originated visited MSC", P_ORIGINATED_VISITED_MSC, 20, P_ADDRESS },
227     { "data coding scheme", P_DATA_CODING_SCHEME, 3, P_INT, 0, 255 },
228     { "user data header", P_USER_DATA_HEADER, 280, P_HEX },
229     { "user data", P_USER_DATA, 480, P_SMS },
230     { "user data binary", P_USER_DATA_BINARY, 280, P_HEX },
231     { "more messages to send", P_MORE_MESSAGES_TO_SEND, 1, P_INT, 0, 1 },
232     { "validity period relative", P_VALIDITY_PERIOD_RELATIVE, 3, P_INT, -1, 255 },
233     { "validity period absolute", P_VALIDITY_PERIOD_ABSOLUTE, 12, P_TIME },
234     { "protocol identifier", P_PROTOCOL_IDENTIFIER, 3, P_INT, 0, 255 },
235     { "first delivery time relative", P_FIRST_DELIVERY_TIME_RELATIVE, 3, P_INT, -1, 255 },
236     { "first delivery time absolute", P_FIRST_DELIVERY_TIME_ABSOLUTE, 12, P_TIME },
237     { "reply path", P_REPLY_PATH, 1, P_INT, 0, 1 },
238     { "status report request", P_STATUS_REPORT_REQUEST, 2, P_INT, 0, 63 },
239     { "cancel enabled", P_CANCEL_ENABLED, 1, P_INT, 0, 1 },
240     { "cancel mode", P_CANCEL_MODE, 1, P_INT, 0, 2 },
241     { "service centre timestamp", P_MC_TIMESTAMP, 12, P_TIME },
242     { "status code", P_STATUS_CODE, 2, P_INT, 0, 9 },
243     { "status error code", P_STATUS_ERROR_CODE, 3, P_INT, 0, 999 },
244     { "discharge time", P_DISCHARGE_TIME, 12, P_TIME },
245     { "tariff class", P_TARIFF_CLASS, 2, P_INT, 0, 99 },
246     { "service description", P_SERVICE_DESCRIPTION, 2, P_INT, 0, 9 },
247     { "message count", P_MESSAGE_COUNT, 3, P_INT, 0, 999 },
248     { "priority", P_PRIORITY, 1, P_INT, 1, 9 },
249     { "delivery request mode", P_DELIVERY_REQUEST_MODE, 1, P_INT, 0, 2 },
250     { "service center address", P_SERVICE_CENTER_ADDRESS, 20, P_ADDRESS },
251     { "get parameter", P_GET_PARAMETER, 3, P_INT, 501, 999 },
252     { "MC time", P_MC_TIME, 12, P_TIME },
253     { "error code", P_ERROR_CODE, 3, P_INT, 0, 999 },
254     { "error text", P_ERROR_TEXT, 64, P_STRING },
255     { NULL }
256 };
257 
258 /* Return the index in the parameters array for this parameter id.
259  * Return -1 if it is not found. */
parm_index(int parmno)260 static int parm_index(int parmno)
261 {
262     int i;
263 
264     for (i = 0; parameters[i].name != NULL; i++) {
265         if (parameters[i].number == parmno)
266             return i;
267     }
268 
269     return -1;
270 }
271 
272 #ifndef NO_GWASSERT
273 /* Return the type of this parameter id.  Return -1 if the id is unknown. */
parm_type(int parmno)274 static int parm_type(int parmno)
275 {
276     int i = parm_index(parmno);
277 
278     if (i < 0)
279         return -1;
280 
281     return parameters[i].type;
282 }
283 #endif
284 
285 /* Return the max length for this parameter id.
286  * Return -1 if the id is unknown. */
parm_maxlen(int parmno)287 static int parm_maxlen(int parmno)
288 {
289     int i = parm_index(parmno);
290 
291     if (i < 0)
292         return -1;
293 
294     return parameters[i].maxlen;
295 }
296 
parm_name(int parmno)297 static const char *parm_name(int parmno)
298 {
299     int i = parm_index(parmno);
300 
301     if (i < 0)
302         return NULL;
303 
304     return parameters[i].name;
305 }
306 
307 #ifndef NO_GWASSERT
308 /* Return 1 if the value for this (Integer) parameter is in range.
309  * Return 0 otherwise.  Return -1 if the parameter was not found.  */
parm_in_range(int parmno,long value)310 static int parm_in_range(int parmno, long value)
311 {
312     int i;
313 
314     i = parm_index(parmno);
315 
316     if (i < 0)
317         return -1;
318 
319     return (value >= parameters[i].minval && value <= parameters[i].maxval);
320 }
321 #endif
322 
323 /* Helper function to check P_ADDRESS type */
isphonedigit(int c)324 static int isphonedigit(int c)
325 {
326     return isdigit(c) || c == '+' || c == '-';
327 }
328 
parm_valid_address(Octstr * value)329 static int parm_valid_address(Octstr *value)
330 {
331     return octstr_check_range(value, 0, octstr_len(value), isphonedigit);
332 }
333 
334 /***************************************************************************/
335 /* Some functions to look up information about operation codes             */
336 /***************************************************************************/
337 
338 static int operation_find(int operation);
339 static Octstr *operation_name(int operation);
340 static int operation_can_send(int operation);
341 static int operation_can_receive(int operation);
342 
343 static const struct
344 {
345     char *name;
346     int code;
347     int can_send;
348     int can_receive;
349 }
350 operations[] = {
351     { "Login", LOGIN, 1, 0 },
352     { "Logout", LOGOUT, 1, 0 },
353     { "Submit message", SUBMIT_MESSAGE, 1, 0 },
354     { "Enquire message status", ENQUIRE_MESSAGE_STATUS, 1, 0 },
355     { "Delivery request", DELIVERY_REQUEST, 1, 0 },
356     { "Cancel message", CANCEL_MESSAGE, 1, 0 },
357     { "Set parameter", SET_REQ, 1, 0 },
358     { "Get parameter", GET_REQ, 1, 0 },
359 
360     { "Deliver message", DELIVER_MESSAGE, 0, 1 },
361     { "Deliver status report", DELIVER_STATUS_REPORT, 0, 1 },
362 
363     { "Alive", ALIVE, 1, 1 },
364 
365     { "NACK", NACK, 1, 1 },
366     { "General error response", GENERAL_ERROR_RESPONSE, 0, 1 },
367 
368     { NULL, 0, 0, 0 }
369 };
370 
operation_find(int operation)371 static int operation_find(int operation)
372 {
373     int i;
374 
375     for (i = 0; operations[i].name != NULL; i++) {
376         if (operations[i].code == operation)
377             return i;
378     }
379 
380     return -1;
381 }
382 
383 /* Return a human-readable representation of this operation code */
operation_name(int operation)384 static Octstr *operation_name(int operation)
385 {
386     int i;
387 
388     i = operation_find(operation);
389     if (i >= 0)
390         return octstr_create(operations[i].name);
391 
392     if (operation >= RESPONSE) {
393         i = operation_find(operation - RESPONSE);
394         if (i >= 0) {
395             Octstr *name = octstr_create(operations[i].name);
396             octstr_append_cstr(name, " response");
397             return name;
398         }
399     }
400 
401     /* Put the operation number here when we have octstr_format */
402     return octstr_create("(unknown)");
403 }
404 
405 /* Return true if a CIMD2 client may send this operation */
operation_can_send(int operation)406 static int operation_can_send(int operation)
407 {
408     int i = operation_find(operation);
409 
410     if (i >= 0)
411         return operations[i].can_send;
412 
413     /* If we can receive the request, then we can send the response. */
414     if (operation >= RESPONSE)
415         return operation_can_receive(operation - RESPONSE);
416 
417     return 0;
418 }
419 
420 
421 /* Return true if a CIMD2 server may send this operation */
operation_can_receive(int operation)422 static int operation_can_receive(int operation)
423 {
424     int i = operation_find(operation);
425 
426     if (i >= 0)
427         return operations[i].can_receive;
428 
429     /* If we can send the request, then we can receive the response. */
430     if (operation >= RESPONSE)
431         return operation_can_send(operation - RESPONSE);
432 
433     return 0;
434 }
435 
436 /***************************************************************************/
437 /* Packet encoding/decoding functions.  They handle packets at the octet   */
438 /* level, and know nothing of the network.                                 */
439 /***************************************************************************/
440 
441 struct packet
442 {
443     /* operation and seq are -1 if their value could not be parsed */
444     int operation;
445     int seq;   /* Sequence number */
446     Octstr *data;   /* Encoded packet */
447     /* CIMD 2 packet structure is so simple that packet information is
448      * stored as a valid encoded packet, and decoded as necessary.
449      * Exceptions: operation code and sequence number are also stored
450      * as ints for speed, and the checksum is not added until the packet
451      * is about to be sent.  Since checksums are optional, the packet
452      * is still valid without a checksum.
453      *
454      * The sequence number is kept at 0 until it's time to actually
455      * send the packet, so that the send functions have control over
456      * the sequence numbers.
457      */
458 };
459 
460 /* These are the separators defined by the CIMD 2 spec */
461 #define STX 2   /* Start of packet */
462 #define ETX 3   /* End of packet */
463 #define TAB 9   /* End of parameter */
464 
465 /* The same separators, in string form */
466 #define STX_str "\02"
467 #define ETX_str "\03"
468 #define TAB_str "\011"
469 
470 /* A reminder that packets are created without a valid sequence number */
471 #define BOGUS_SEQUENCE 0
472 
473 static Msg *cimd2_accept_delivery_report_message(struct packet *request,
474 						 SMSCConn *conn);
475 /* Look for the STX OO:SSS TAB header defined by CIMD 2, where OO is the
476  * operation code in two decimals and SSS is the sequence number in three
477  * decimals.  Leave the results in the proper fields of the packet.
478  * Try to make sense of headers that don't fit this pattern; validating
479  * the packet format is not our job. */
packet_parse_header(struct packet * packet)480 static void packet_parse_header(struct packet *packet)
481 {
482     int pos;
483     long number;
484 
485     /* Set default values, in case we can't parse the fields */
486     packet->operation = -1;
487     packet->seq = -1;
488 
489     pos = octstr_parse_long(&number, packet->data, 1, 10);
490     if (pos < 0)
491         return;
492     packet->operation = number;
493 
494     if (octstr_get_char(packet->data, pos++) != ':')
495         return;
496 
497     pos = octstr_parse_long(&number, packet->data, pos, 10);
498     if (pos < 0)
499         return;
500     packet->seq = number;
501 }
502 
503 
504 /* Accept an Octstr containing one packet, build a struct packet around
505  * it, and return that struct.  The Octstr is stored in the struct.
506  * No error checking is done here yet. */
packet_parse(Octstr * packet_data)507 static struct packet *packet_parse(Octstr *packet_data)
508 {
509     struct packet *packet;
510 
511     packet = gw_malloc(sizeof(*packet));
512     packet->data = packet_data;
513 
514     /* Fill in packet->operation and packet->seq */
515     packet_parse_header(packet);
516 
517     return packet;
518 }
519 
520 /* Deallocate this packet */
packet_destroy(struct packet * packet)521 static void packet_destroy(struct packet *packet)
522 {
523     if (packet != NULL) {
524         octstr_destroy(packet->data);
525         gw_free(packet);
526     }
527 }
528 
529 /* Find the first packet in "in", delete it from "in", and return it as
530  * a struct.  Return NULL if "in" contains no packet.  Always delete
531  * leading non-packet data from "in".  (The CIMD 2 spec says we should
532  * ignore any data between the packet markers). */
packet_extract(Octstr * in,SMSCConn * conn)533 static struct packet *packet_extract(Octstr *in, SMSCConn *conn)
534 {
535     int stx, etx;
536     Octstr *packet;
537 
538     /* Find STX, and delete everything up to it */
539     stx = octstr_search_char(in, STX, 0);
540     if (stx < 0) {
541         octstr_delete(in, 0, octstr_len(in));
542         return NULL;
543     } else {
544         octstr_delete(in, 0, stx);
545     }
546 
547     /* STX is now in position 0.  Find ETX. */
548     etx = octstr_search_char(in, ETX, 1);
549     if (etx < 0)
550         return NULL;
551 
552     /* What shall we do with STX data... STX data... ETX?
553      * Either skip to the second STX, or assume an ETX marker before
554      * the STX.  Doing the latter has a chance of succeeding, and
555      * will at least allow good logging of the error. */
556     stx = octstr_search_char(in, STX, 1);
557     if (stx >= 0 && stx < etx) {
558         warning(0, "CIMD2[%s]: packet without end marker",
559                 octstr_get_cstr(conn->id));
560         packet = octstr_copy(in, 0, stx);
561         octstr_delete(in, 0, stx);
562         octstr_append_cstr(packet, ETX_str);
563     } else {
564         /* Normal case. Copy packet, and cut it from the source. */
565         packet = octstr_copy(in, 0, etx + 1);
566         octstr_delete(in, 0, etx + 1);
567     }
568 
569     return packet_parse(packet);
570 }
571 
572 /* The get_parm functions always return the first parameter with the
573  * correct id.  There is only one case where the spec allows multiple
574  * parameters with the same id, and that is when an SMS has multiple
575  * destination addresses.  We only support one destination address anyway. */
576 
577 /* Look for the first parameter with id 'parmno' and return its value.
578  * Return NULL if the parameter was not found. */
packet_get_parm(struct packet * packet,int parmno)579 static Octstr *packet_get_parm(struct packet *packet, int parmno)
580 {
581     long pos, next;
582     long valuepos;
583     long number;
584 
585     gw_assert(packet != NULL);
586     pos = octstr_search_char(packet->data, TAB, 0);
587     if (pos < 0)
588         return NULL;  /* Bad packet, nothing we can do */
589 
590     /* Parameters have a tab on each end.  If we don't find the
591      * closing tab, we're at the checksum, so we stop. */
592     for ( ;
593           (next = octstr_search_char(packet->data, TAB, pos + 1)) >= 0;
594           pos = next) {
595         if (octstr_parse_long(&number, packet->data, pos + 1, 10) < 0)
596             continue;
597         if (number != parmno)
598             continue;
599         valuepos = octstr_search_char(packet->data, ':', pos + 1);
600         if (valuepos < 0)
601             continue;  /* badly formatted parm */
602         valuepos++;  /* skip the ':' */
603 
604         /* Found the right parameter */
605         return octstr_copy(packet->data, valuepos, next - valuepos);
606     }
607 
608     return NULL;
609 }
610 
611 
612 /* Look for an Integer parameter with id 'parmno' in the packet and
613  * return its value.  Return INT_MIN if the parameter was not found.
614  * (Unfortunately, -1 is a valid parameter value for at least one
615  * parameter.) */
packet_get_int_parm(struct packet * packet,int parmno)616 static long packet_get_int_parm(struct packet *packet, int parmno)
617 {
618     Octstr *valuestr = NULL;
619     long value;
620 
621     /* Our code should never even try a bad parameter access. */
622     gw_assert(parm_type(parmno) == P_INT);
623 
624     valuestr = packet_get_parm(packet, parmno);
625     if (!valuestr)
626         goto error;
627 
628     if (octstr_parse_long(&value, valuestr, 0, 10) < 0)
629         goto error;
630 
631     octstr_destroy(valuestr);
632     return value;
633 
634 error:
635     octstr_destroy(valuestr);
636     return INT_MIN;
637 }
638 
639 /* Look for a String parameter with id 'parmno' in the packet and
640  * return its value.  Return NULL if the parameter was not found.
641  * No translations are done on the value. */
packet_get_string_parm(struct packet * packet,int parmno)642 static Octstr *packet_get_string_parm(struct packet *packet, int parmno)
643 {
644     /* Our code should never even try a bad parameter access. */
645     gw_assert(parm_type(parmno) == P_STRING);
646 
647     return packet_get_parm(packet, parmno);
648 }
649 
650 /* Look for an Address parameter with id 'parmno' in the packet and
651  * return its value.  Return NULL if the parameter was not found.
652  * No translations are done on the value. */
packet_get_address_parm(struct packet * packet,int parmno)653 static Octstr *packet_get_address_parm(struct packet *packet, int parmno)
654 {
655     /* Our code should never even try a bad parameter access. */
656     gw_assert(parm_type(parmno) == P_ADDRESS);
657 
658     return packet_get_parm(packet, parmno);
659 }
660 
661 /* Look for an SMS parameter with id 'parmno' in the packet and return its
662  * value.  Return NULL if the parameter was not found.  No translations
663  * are done on the value, so it will be in the ISO-Latin-1 character set
664  * with CIMD2-specific escapes. */
packet_get_sms_parm(struct packet * packet,int parmno)665 static Octstr *packet_get_sms_parm(struct packet *packet, int parmno)
666 {
667     /* Our code should never even try a bad parameter access. */
668     gw_assert(parm_type(parmno) == P_SMS);
669 
670     return packet_get_parm(packet, parmno);
671 }
672 
673 /* There is no packet_get_time_parm because the CIMD 2 timestamp
674  * format is useless.  It's in the local time of the MC, with
675  * a 2-digit year and no DST information.  We can do without.
676  */
677 
678 /* Look for a Hex parameter with id 'parmno' in the packet and return
679  * its value.  Return NULL if the parameter was not found.  The value
680  * is de-hexed. */
packet_get_hex_parm(struct packet * packet,int parmno)681 static Octstr *packet_get_hex_parm(struct packet *packet, int parmno)
682 {
683     Octstr *value = NULL;
684 
685     /* Our code should never even try a bad parameter access. */
686     gw_assert(parm_type(parmno) == P_HEX);
687 
688     value = packet_get_parm(packet, parmno);
689     if (!value)
690         goto error;
691 
692     if (octstr_hex_to_binary(value) < 0)
693         goto error;
694 
695     return value;
696 
697 error:
698     octstr_destroy(value);
699     return NULL;
700 }
701 
702 
703 /* Check if the header is according to CIMD 2 spec, generating log
704  * entries as necessary.  Return -1 if anything was wrong, otherwise 0. */
packet_check_header(struct packet * packet,SMSCConn * conn)705 static int packet_check_header(struct packet *packet, SMSCConn *conn)
706 {
707     Octstr *data;
708 
709     gw_assert(packet != NULL);
710     data = packet->data;
711 
712     /* The header must have a two-digit operation code, a colon,
713      * and a three-digit sequence number, followed by a tab.
714      * (CIMD2, 3.1) */
715     if (octstr_len(data) < 8 ||
716         !octstr_check_range(data, 1, 2, gw_isdigit) ||
717         octstr_get_char(data, 3) != ':' ||
718         !octstr_check_range(data, 4, 3, gw_isdigit) ||
719         octstr_get_char(data, 7) != TAB) {
720         warning(0, "CIMD2[%s]: packet header in wrong format",
721                 octstr_get_cstr(conn->id));
722         return -1;
723     }
724 
725     return 0;
726 }
727 
packet_check_parameter(struct packet * packet,long pos,long len,SMSCConn * conn)728 static int packet_check_parameter(struct packet *packet, long pos, long len, SMSCConn *conn)
729 {
730     Octstr *data;
731     long parm;
732     long dpos, dlen;
733     int negative;
734     long value;
735     int i;
736     int errors = 0;
737 
738     gw_assert(packet != NULL);
739     data = packet->data;
740 
741     /* The parameter header should be TAB, followed by a three-digit
742      * parameter number, a colon, and the data.  We already know about
743      * the tab. */
744 
745     if (len < 5 ||
746         !octstr_check_range(data, pos + 1, 3, gw_isdigit) ||
747         octstr_get_char(data, pos + 4) != ':') {
748         warning(0, "CIMD2[%s]: parameter at offset %ld in wrong format",
749                 octstr_get_cstr(conn->id),
750                 pos);
751         errors++;
752     }
753 
754     /* If we can't parse a parameter number, there's nothing more
755      * that we can check. */
756     dpos = octstr_parse_long(&parm, data, pos + 1, 10);
757     if (dpos < 0)
758         return -1;
759     if (octstr_get_char(data, dpos) == ':')
760         dpos++;
761     dlen = len - (dpos - pos);
762     /* dlen can not go negative because octstr_parse_long must have
763      * been stopped by the TAB at the end of the parameter data. */
764     gw_assert(dlen >= 0);
765 
766     i = parm_index(parm);
767 
768     if (i < 0) {
769         warning(0, "CIMD2[%s]: packet contains unknown parameter %ld",
770                 octstr_get_cstr(conn->id),
771                 parm);
772         return -1;
773     }
774 
775     if (dlen > parameters[i].maxlen) {
776         warning(0, "CIMD2[%s]: packet has '%s' parameter with length %ld, spec says max %d",
777                 octstr_get_cstr(conn->id),
778                 parameters[i].name, len, parameters[i].maxlen);
779         errors++;
780     }
781 
782     switch (parameters[i].type) {
783     case P_INT:
784         /* Allow a leading - */
785         negative = (octstr_get_char(data, dpos) == '-');
786         if (!octstr_check_range(data, dpos + negative,
787                                 dlen - negative, gw_isdigit)) {
788             warning(0, "CIMD2[%s]: packet has '%s' parameter with non-integer contents",
789                     octstr_get_cstr(conn->id),
790                     parameters[i].name);
791             errors++;
792         }
793         if (octstr_parse_long(&value, data, dpos, 10) >= 0 &&
794             (value < parameters[i].minval || value > parameters[i].maxval)) {
795             warning(0, "CIMD2[%s]: packet has '%s' parameter out of range (value %ld, min %d, max %d)",
796                     octstr_get_cstr(conn->id),
797                     parameters[i].name, value,
798                     parameters[i].minval, parameters[i].maxval);
799             errors++;
800         }
801         break;
802     case P_TIME:
803         if (!octstr_check_range(data, dpos, dlen, gw_isdigit)) {
804             warning(0, "CIMD2[%s]: packet has '%s' parameter with non-digit contents",
805                     octstr_get_cstr(conn->id),
806                     parameters[i].name);
807             errors++;
808         }
809         break;
810     case P_ADDRESS:
811         if (!octstr_check_range(data, dpos, dlen, isphonedigit)) {
812             warning(0, "CIMD2[%s]: packet has '%s' parameter with non phone number contents",
813                     octstr_get_cstr(conn->id),
814                     parameters[i].name);
815             errors++;
816         }
817         break;
818     case P_HEX:
819         if (!octstr_check_range(data, dpos, dlen, gw_isxdigit)) {
820             warning(0, "CIMD2[%s]: packet has '%s' parameter with non-hex contents",
821                     octstr_get_cstr(conn->id),
822                     parameters[i].name);
823             errors++;
824         }
825         if (dlen % 2 != 0) {
826             warning(0, "CIMD2[%s]: packet has odd-length '%s' parameter",
827                     octstr_get_cstr(conn->id),
828                     parameters[i].name);
829             errors++;
830         }
831         break;
832     case P_SMS:
833     case P_STRING:  /* nothing to check */
834         break;
835     }
836 
837     if (errors > 0)
838         return -1;
839     return 0;
840 }
841 
842 
843 /* Check the packet against the CIMD 2 spec, generating log entries as
844  * necessary. Return -1 if anything was wrong, otherwise 0. */
845 /* TODO: Check if parameters found actually belong in the packet type */
packet_check(struct packet * packet,SMSCConn * conn)846 static int packet_check(struct packet *packet, SMSCConn *conn)
847 {
848     int errors = 0;
849     long pos, next;
850     Octstr *data;
851 
852     gw_assert(packet != NULL);
853     data = packet->data;
854 
855     if (octstr_search_char(data, 0, 0) >= 0) {
856         /* CIMD2 spec does not allow NUL bytes in a packet */
857         warning(0, "CIMD2[%s]: packet contains NULs",
858                 octstr_get_cstr(conn->id));
859         errors++;
860     }
861 
862     /* Assume the packet starts with STX and ends with ETX,
863      * because we parsed it that way in the first place. */
864 
865     errors += (packet_check_header(packet,conn) < 0);
866 
867     /* Parameters are separated by tabs.  After the last parameter
868      * there is a tab, an optional two-digit checksum, and the ETX.
869      * Check each parameter in turn, by skipping from tab to tab.
870      */
871     /* Start at the first tab, wherever it is, so that we can still
872      * check parameters if the header was weird. */
873     pos = octstr_search_char(data, TAB, 0);
874     for ( ; pos >= 0; pos = next) {
875         next = octstr_search_char(data, TAB, pos + 1);
876         if (next >= 0) {
877             errors += (packet_check_parameter(packet, pos, next - pos, conn) < 0);
878         } else {
879             /* Check if the checksum has the right format.  Don't
880              * check the sum itself here, that will be done in a
881              * separate call later. */
882             /* There are two valid formats: TAB ETX (no checksum)
883              * and TAB digit digit ETX.  We already know the TAB
884              * and the ETX are there. */
885             if (!(octstr_len(data) - pos == 2 ||
886                   (octstr_len(data) - pos == 4 &&
887                    octstr_check_range(data, pos + 1, 2, gw_isxdigit)))) {
888                 warning(0, "CIMD2[%s]: packet checksum in wrong format",
889                         octstr_get_cstr(conn->id));
890                 errors++;
891             }
892         }
893     }
894 
895 
896     if (errors > 0) {
897         octstr_dump(packet->data, 0);
898         return -1;
899     }
900 
901     return 0;
902 }
903 
packet_check_can_receive(struct packet * packet,SMSCConn * conn)904 static void packet_check_can_receive(struct packet *packet, SMSCConn *conn)
905 {
906     gw_assert(packet != NULL);
907 
908     if (!operation_can_receive(packet->operation)) {
909         Octstr *name = operation_name(packet->operation);
910         warning(0, "CIMD2[%s]: SMSC sent us %s request",
911                 octstr_get_cstr(conn->id),
912                 octstr_get_cstr(name));
913         octstr_destroy(name);
914     }
915 }
916 
917 /* Table of known error codes */
918 static struct
919 {
920     int code;
921     char *text;
922 }
923 cimd2_errors[] = {
924     { 0, "No error" },
925     { 1, "Unexpected operation" },
926     { 2, "Syntax error" },
927     { 3, "Unsupported parameter error" },
928     { 4, "Connection to message center lost" },
929     { 5, "No response from message center" },
930     { 6, "General system error" },
931     { 7, "Cannot find information" },
932     { 8, "Parameter formatting error" },
933     { 9, "Requested operation failed" },
934     /* LOGIN error codes */
935     { 100, "Invalid login" },
936     { 101, "Incorrect access type" },
937     { 102, "Too many users with this login id" },
938     { 103, "Login refused by message center" },
939     /* SUBMIT MESSAGE error codes */
940     { 300, "Incorrect destination address" },
941     { 301, "Incorrect number of destination addresses" },
942     { 302, "Syntax error in user data parameter" },
943     { 303, "Incorrect bin/head/normal user data parameter combination" },
944     { 304, "Incorrect data coding scheme parameter usage" },
945     { 305, "Incorrect validity period parameters usage" },
946     { 306, "Incorrect originator address usage" },
947     { 307, "Incorrect pid paramterer usage" },
948     { 308, "Incorrect first delivery parameter usage" },
949     { 309, "Incorrect reply path usage" },
950     { 310, "Incorrect status report request parameter usage" },
951     { 311, "Incorrect cancel enabled parameter usage" },
952     { 312, "Incorrect priority parameter usage" },
953     { 313, "Incorrect tariff class parameter usage" },
954     { 314, "Incorrect service description parameter usage" },
955     { 315, "Incorrect transport type parameter usage" },
956     { 316, "Incorrect message type parameter usage" },
957     { 318, "Incorrect mms parameter usage" },
958     { 319, "Incorrect operation timer parameter usage" },
959     /* ENQUIRE MESSAGE STATUS error codes */
960     { 400, "Incorrect address parameter usage" },
961     { 401, "Incorrect scts parameter usage" },
962     /* DELIVERY REQUEST error codes */
963     { 500, "Incorrect scts parameter usage" },
964     { 501, "Incorrect mode parameter usage" },
965     { 502, "Incorrect parameter combination" },
966     /* CANCEL MESSAGE error codes */
967     { 600, "Incorrect scts parameter usage" },
968     { 601, "Incorrect address parameter usage" },
969     { 602, "Incorrect mode parameter usage" },
970     { 603, "Incorrect parameter combination" },
971     /* SET error codes */
972     { 800, "Changing password failed" },
973     { 801, "Changing password not allowed" },
974     /* GET error codes */
975     { 900, "Unsupported item requested" },
976     { -1, NULL }
977 };
978 
packet_display_error(struct packet * packet,SMSCConn * conn)979 static int packet_display_error(struct packet *packet, SMSCConn *conn)
980 {
981     int code;
982     Octstr *text = NULL;
983     Octstr *opname = NULL;
984 
985     code = packet_get_int_parm(packet, P_ERROR_CODE);
986     text = packet_get_string_parm(packet, P_ERROR_TEXT);
987 
988     if (code <= 0) {
989         octstr_destroy(text);
990         return 0;
991     }
992 
993     if (text == NULL) {
994         /* No error text.  Try to find it in the table. */
995         int i;
996         for (i = 0; cimd2_errors[i].text != NULL; i++) {
997             if (cimd2_errors[i].code == code) {
998                 text = octstr_create(cimd2_errors[i].text);
999                 break;
1000             }
1001         }
1002     }
1003 
1004     if (text == NULL) {
1005         /* Still no error text.  Make one up. */
1006         text = octstr_create("Unknown error");
1007     }
1008 
1009     opname = operation_name(packet->operation);
1010     error(0, "CIMD2[%s]: %s contained error message:",
1011           octstr_get_cstr(conn->id),
1012           octstr_get_cstr(opname));
1013     error(0, "code %03d: %s", code, octstr_get_cstr(text));
1014     octstr_destroy(opname);
1015     octstr_destroy(text);
1016     return code;
1017 }
1018 
1019 /* Table of special combinations, for convert_gsm_to_latin1. */
1020 /* Each cimd1, cimd2 pair is mapped to a character in the GSM default
1021  * character set. */
1022 static const struct
1023 {
1024     unsigned char cimd1, cimd2;
1025     unsigned char gsm;
1026 }
1027 cimd_combinations[] = {
1028     { 'O', 'a', 0 },     /* @ */
1029     { 'L', '-', 1 },     /* Pounds sterling */
1030     { 'Y', '-', 3 },     /* Yen */
1031     { 'e', '`', 4 },     /* egrave */
1032     { 'e', '\'', 5 },    /* eacute */
1033     { 'u', '`', 6 },     /* ugrave */
1034     { 'i', '`', 7 },     /* igrave */
1035     { 'o', '`', 8 },     /* ograve */
1036     { 'C', ',', 9 },     /* C cedilla */
1037     { 'O', '/', 11 },    /* Oslash */
1038     { 'o', '/', 12 },    /* oslash */
1039     { 'A', '*', 14 },    /* Aring */
1040     { 'a', '*', 15 },    /* aring */
1041     { 'g', 'd', 16 },    /* greek delta */
1042     { '-', '-', 17 },    /* underscore */
1043     { 'g', 'f', 18 },    /* greek phi */
1044     { 'g', 'g', 19 },    /* greek gamma */
1045     { 'g', 'l', 20 },    /* greek lambda */
1046     { 'g', 'o', 21 },    /* greek omega */
1047     { 'g', 'p', 22 },    /* greek pi */
1048     { 'g', 'i', 23 },    /* greek psi */
1049     { 'g', 's', 24 },    /* greek sigma */
1050     { 'g', 't', 25 },    /* greek theta */
1051     { 'g', 'x', 26 },    /* greek xi */
1052     { 'X', 'X', 27 },    /* escape */
1053     { 'A', 'E', 28 },    /* AE ligature */
1054     { 'a', 'e', 29 },    /* ae ligature */
1055     { 's', 's', 30 },    /* german double s */
1056     { 'E', '\'', 31 },   /* Eacute */
1057     { 'q', 'q', '"' },
1058     { 'o', 'x', 36 },    /* international currency symbol */
1059     { '!', '!', 64 },    /* inverted ! */
1060     { 'A', '"', 91 },    /* Adieresis */
1061     { 'O', '"', 92 },    /* Odieresis */
1062     { 'N', '~', 93 },    /* N tilde */
1063     { 'U', '"', 94 },    /* Udieresis */
1064     { 's', 'o', 95 },    /* section mark */
1065     { '?', '?', 96 },    /* inverted ? */
1066     { 'a', '"', 123 },   /* adieresis */
1067     { 'o', '"', 124 },   /* odieresis */
1068     { 'n', '~', 125 },   /* n tilde */
1069     { 'u', '"', 126 },   /* udieresis */
1070     { 'a', '`', 127 },   /* agrave */
1071     { 0, 0, 0 }
1072 };
1073 
1074 
1075 /* Convert text in the CIMD2 User Data format to the GSM default
1076  * character set.
1077  * CIMD2 allows 8-bit characters in this format; they map directly
1078  * to the corresponding ISO-8859-1 characters.  Since we are heading
1079  * toward that character set in the end, we don't bother converting
1080  * those to GSM. */
convert_cimd2_to_gsm(Octstr * text,SMSCConn * conn)1081 static void convert_cimd2_to_gsm(Octstr *text, SMSCConn *conn)
1082 {
1083     long pos, len;
1084     int cimd1, cimd2;
1085     int c;
1086     int i;
1087 
1088     /* CIMD2 uses four single-character mappings that do not map
1089      * to themselves:
1090      * '@' from 64 to 0, '$' from 36 to 2, ']' from 93 to 14 (A-ring),
1091      * and '}' from 125 to 15 (a-ring).
1092      * Other than those, we only have to worry about the escape
1093      * sequences introduced by _ (underscore).
1094      */
1095 
1096     len = octstr_len(text);
1097     for (pos = 0; pos < len; pos++) {
1098         c = octstr_get_char(text, pos);
1099         if (c == '@')
1100             octstr_set_char(text, pos, 0);
1101         else if (c == '$')
1102             octstr_set_char(text, pos, 2);
1103         else if (c == ']')
1104             octstr_set_char(text, pos, 14);
1105         else if (c == '}')
1106             octstr_set_char(text, pos, 15);
1107         else if (c == '_' && pos + 2 < len) {
1108             cimd1 = octstr_get_char(text, pos + 1);
1109             cimd2 = octstr_get_char(text, pos + 2);
1110             for (i = 0; cimd_combinations[i].cimd1 != 0; i++) {
1111                 if (cimd_combinations[i].cimd1 == cimd1 &&
1112                     cimd_combinations[i].cimd2 == cimd2)
1113                     break;
1114             }
1115             if (cimd_combinations[i].cimd1 == 0)
1116                 warning(0, "CIMD2[%s]: Encountered unknown "
1117                         "escape code _%c%c, ignoring.",
1118                         octstr_get_cstr(conn->id),
1119                         cimd1, cimd2);
1120             else {
1121                 octstr_delete(text, pos, 2);
1122                 octstr_set_char(text, pos, cimd_combinations[i].gsm);
1123                 len = octstr_len(text);
1124             }
1125         }
1126     }
1127 }
1128 
1129 
1130 /* Convert text in the GSM default character set to the CIMD2 User Data
1131  * format, which is a representation of the GSM default character set
1132  * in the lower 7 bits of ISO-8859-1.  (8-bit characters are also
1133  * allowed, but it's just as easy not to use them.) */
convert_gsm_to_cimd2(Octstr * text)1134 static void convert_gsm_to_cimd2(Octstr *text)
1135 {
1136     long pos, len;
1137 
1138     len = octstr_len(text);
1139     for (pos = 0; pos < len; pos++) {
1140         int c, i;
1141 
1142         c = octstr_get_char(text, pos);
1143         /* If c is not in the GSM alphabet at this point,
1144          * the caller did something badly wrong. */
1145         gw_assert(c >= 0);
1146         gw_assert(c < 128);
1147 
1148         for (i = 0; cimd_combinations[i].cimd1 != 0; i++) {
1149             if (cimd_combinations[i].gsm == c)
1150                 break;
1151         }
1152 
1153         if (cimd_combinations[i].gsm == c) {
1154             /* Escape sequence */
1155             octstr_insert_data(text, pos, "_ ", 2);
1156             pos += 2;
1157             len += 2;
1158             octstr_set_char(text, pos - 1, cimd_combinations[i].cimd1);
1159             octstr_set_char(text, pos, cimd_combinations[i].cimd2);
1160         } else if (c == 2) {
1161             /* The dollar sign is the only GSM character that
1162             	 * does not have a CIMD escape sequence and does not
1163              * map to itself. */
1164             octstr_set_char(text, pos, '$');
1165         }
1166     }
1167 }
1168 
1169 
1170 /***************************************************************************/
1171 /* Packet encoding functions.  They do not allow the creation of invalid   */
1172 /* CIMD 2 packets.                                                         */
1173 /***************************************************************************/
1174 
1175 /* Build a new packet struct with this operation code and sequence number. */
packet_create(int operation,int seq)1176 static struct packet *packet_create(int operation, int seq)
1177 {
1178     struct packet *packet;
1179     char minpacket[sizeof("sOO:SSSte")];
1180 
1181     packet = gw_malloc(sizeof(*packet));
1182     packet->operation = operation;
1183     packet->seq = seq;
1184     sprintf(minpacket, STX_str "%02d:%03d" TAB_str ETX_str, operation, seq);
1185     packet->data = octstr_create(minpacket);
1186 
1187     return packet;
1188 }
1189 
1190 /* Add a parameter to the end of packet */
packet_add_parm(struct packet * packet,int parmtype,int parmno,Octstr * value,SMSCConn * conn)1191 static void packet_add_parm(struct packet *packet, int parmtype,
1192                             int parmno, Octstr *value, SMSCConn *conn)
1193 {
1194     char parmh[sizeof("tPPP:")];
1195     long position;
1196     long len;
1197     int copied = 0;
1198 
1199     len = octstr_len(value);
1200 
1201     gw_assert(packet != NULL);
1202     gw_assert(parm_type(parmno) == parmtype);
1203 
1204     if (len > parm_maxlen(parmno)) {
1205         warning(0, "CIMD2[%s]: %s parameter too long, truncating from "
1206                 "%ld to %ld characters",
1207                 octstr_get_cstr(conn->id),
1208                 parm_name(parmno),
1209                 len,
1210                 (long) parm_maxlen(parmno));
1211         value = octstr_copy(value, 0, parm_maxlen(parmno));
1212         copied = 1;
1213     }
1214 
1215     /* There's a TAB and ETX at the end; insert it before those.
1216      * The new parameter will come with a new starting TAB. */
1217     position = octstr_len(packet->data) - 2;
1218 
1219     sprintf(parmh, TAB_str "%03d:", parmno);
1220     octstr_insert_data(packet->data, position, parmh, strlen(parmh));
1221     octstr_insert(packet->data, value, position + strlen(parmh));
1222     if (copied)
1223         octstr_destroy(value);
1224 }
1225 
1226 /* Add a String parameter to the packet */
packet_add_string_parm(struct packet * packet,int parmno,Octstr * value,SMSCConn * conn)1227 static void packet_add_string_parm(struct packet *packet, int parmno, Octstr *value, SMSCConn *conn)
1228 {
1229     packet_add_parm(packet, P_STRING, parmno, value, conn);
1230 }
1231 
1232 /* Add an Address parameter to the packet */
packet_add_address_parm(struct packet * packet,int parmno,Octstr * value,SMSCConn * conn)1233 static void packet_add_address_parm(struct packet *packet, int parmno, Octstr *value, SMSCConn *conn)
1234 {
1235     gw_assert(octstr_check_range(value, 0, octstr_len(value), isphonedigit));
1236     packet_add_parm(packet, P_ADDRESS, parmno, value, conn);
1237 }
1238 
1239 /* Add an SMS parameter to the packet.  The caller is expected to have done
1240  * the translation to the GSM character set already.  */
packet_add_sms_parm(struct packet * packet,int parmno,Octstr * value,SMSCConn * conn)1241 static void packet_add_sms_parm(struct packet *packet, int parmno, Octstr *value, SMSCConn *conn)
1242 {
1243     packet_add_parm(packet, P_SMS, parmno, value, conn);
1244 }
1245 
1246 /* There is no function for adding a Time parameter to the packet, because
1247  * the format makes Time parameters useless for us.  If you find that you
1248  * need to use them, then also add code for querying the SMS center timestamp
1249  * and using that for synchronization.  And beware of DST changes. */
1250 
1251 /* Add a Hexadecimal parameter to the packet */
packet_add_hex_parm(struct packet * packet,int parmno,Octstr * value,SMSCConn * conn)1252 static void packet_add_hex_parm(struct packet *packet, int parmno, Octstr *value, SMSCConn *conn)
1253 {
1254     value = octstr_duplicate(value);
1255     octstr_binary_to_hex(value, 1);   /* 1 for uppercase hex, i.e. A .. F */
1256     packet_add_parm(packet, P_HEX, parmno, value, conn);
1257     octstr_destroy(value);
1258 }
1259 
1260 /* Add an Integer parameter to the packet */
packet_add_int_parm(struct packet * packet,int parmno,long value,SMSCConn * conn)1261 static void packet_add_int_parm(struct packet *packet, int parmno, long value, SMSCConn *conn)
1262 {
1263     char buf[128];
1264     Octstr *valuestr;
1265 
1266     gw_assert(parm_in_range(parmno, value));
1267 
1268     sprintf(buf, "%ld", value);
1269     valuestr = octstr_create(buf);
1270     packet_add_parm(packet, P_INT, parmno, valuestr, conn);
1271     octstr_destroy(valuestr);
1272 }
1273 
packet_set_checksum(struct packet * packet)1274 static void packet_set_checksum(struct packet *packet)
1275 {
1276     Octstr *data;
1277     int checksum;
1278     long pos, len;
1279     char buf[16];
1280 
1281     gw_assert(packet != NULL);
1282 
1283     data = packet->data;
1284     if (octstr_get_char(data, octstr_len(data) - 2) != TAB) {
1285         /* Packet already has checksum; kill it. */
1286         octstr_delete(data, octstr_len(data) - 3, 2);
1287     }
1288 
1289     gw_assert(octstr_get_char(data, octstr_len(data) - 2) == TAB);
1290 
1291     /* Sum all the way up to the last TAB */
1292     checksum = 0;
1293     for (pos = 0, len = octstr_len(data); pos < len - 1; pos++) {
1294         checksum += octstr_get_char(data, pos);
1295         checksum &= 0xff;
1296     }
1297 
1298     sprintf(buf, "%02X", checksum);
1299     octstr_insert_data(data, len - 1, buf, 2);
1300 }
1301 
packet_set_sequence(struct packet * packet,int seq)1302 static void packet_set_sequence(struct packet *packet, int seq)
1303 {
1304     char buf[16];
1305 
1306     gw_assert(packet != NULL);
1307     gw_assert(seq >= 0);
1308     gw_assert(seq < 256);
1309 
1310     sprintf(buf, "%03d", seq);
1311 
1312     /* Start at 4 to skip the <STX> ZZ: part of the header. */
1313     octstr_set_char(packet->data, 4, buf[0]);
1314     octstr_set_char(packet->data, 5, buf[1]);
1315     octstr_set_char(packet->data, 6, buf[2]);
1316     packet->seq = seq;
1317 }
1318 
packet_encode_message(Msg * msg,Octstr * sender_prefix,SMSCConn * conn)1319 static struct packet *packet_encode_message(Msg *msg, Octstr *sender_prefix, SMSCConn *conn)
1320 {
1321     struct packet *packet;
1322     PrivData *pdata = conn->data;
1323     Octstr *text;
1324     int spaceleft;
1325     long truncated;
1326     int dcs = 0;
1327     int setvalidity = 0;
1328 
1329     gw_assert(msg != NULL);
1330     gw_assert(msg->type == sms);
1331     gw_assert(msg->sms.receiver != NULL);
1332 
1333     dcs = fields_to_dcs(msg, (msg->sms.alt_dcs != -1 ?
1334         msg->sms.alt_dcs : conn->alt_dcs));
1335     if (msg->sms.sender == NULL)
1336         msg->sms.sender = octstr_create("");
1337 
1338     if (!parm_valid_address(msg->sms.receiver)) {
1339         warning(0, "CIMD2[%s]: non-digits in destination phone number '%s', discarded",
1340                 octstr_get_cstr(conn->id),
1341                 octstr_get_cstr(msg->sms.receiver));
1342         return NULL;
1343     }
1344 
1345     packet = packet_create(SUBMIT_MESSAGE, BOGUS_SEQUENCE);
1346 
1347     packet_add_address_parm(packet, P_DESTINATION_ADDRESS, msg->sms.receiver, conn);
1348 
1349     /* CIMD2 interprets the originating address as a sub-address to
1350      * our connection number (so if the connection is "400" and we
1351      * fill in "600" as the sender number, the user sees "400600").
1352      * Since we have no way to ask what this number is, it has to
1353      * be configured. */
1354 
1355     /* Quick and dirty check to see if we are using alphanumeric sender */
1356     if (parm_valid_address(msg->sms.sender)) {
1357         /* We are not, so send in the usual way */
1358         /* Speed up the default case */
1359         if (octstr_len(sender_prefix) == 0) {
1360             packet_add_address_parm(packet, P_ORIGINATING_ADDRESS,msg->sms.sender, conn);
1361         }
1362         else if (octstr_compare(sender_prefix, octstr_imm("never")) != 0) {
1363             if (octstr_ncompare(sender_prefix, msg->sms.sender,
1364                                 octstr_len(sender_prefix)) == 0) {
1365                 Octstr *sender;
1366                 sender = octstr_copy(msg->sms.sender,
1367                                      octstr_len(sender_prefix), octstr_len(msg->sms.sender));
1368                 packet_add_address_parm(packet, P_ORIGINATING_ADDRESS, sender, conn);
1369                 octstr_destroy(sender);
1370             } else {
1371                 warning(0, "CIMD2[%s]: Sending message with originating address <%s>, "
1372                         "which does not start with the sender-prefix.",
1373                         octstr_get_cstr(conn->id),
1374                         octstr_get_cstr(msg->sms.sender));
1375             }
1376         }
1377     }
1378     else {
1379         /* The test above to check if sender was all digits failed, so assume we want alphanumeric sender */
1380         packet_add_string_parm(packet, P_ALPHANUMERIC_ORIGINATING_ADDRESS,msg->sms.sender, conn);
1381     }
1382 
1383     /* Add the validity period if necessary.  This sets the relative validity
1384      * period as this is the description of the "validity" parameter of the
1385      * sendsms interface.
1386      *
1387      * Convert from minutes to GSM 03.40 specification (section 9.2.3.12).
1388      * 0-143   = 0 to 12 hours in 5 minute increments.
1389      * 144-167 = 12hrs30min to 24hrs in 30 minute increments.
1390      * 168-196 = 2days to 30days in 1 day increments.
1391      * 197-255 = 5weeks to 63weeks in 1 week increments.
1392      *
1393      * This code was copied from smsc_at2.c.
1394      */
1395     if (msg->sms.validity != MSG_PARAM_UNDEFINED) {
1396         long val = (msg->sms.validity - time(NULL)) / 60;
1397         if (val > 635040)
1398             setvalidity = 255;
1399         if (val >= 50400 && val <= 635040)
1400             setvalidity = (val - 1) / 7 / 24 / 60 + 192 + 1;
1401         if (val > 43200 && val < 50400)
1402             setvalidity = 197;
1403         if (val >= 2880 && val <= 43200)
1404             setvalidity = (val - 1) / 24 / 60 + 166 + 1;
1405         if (val > 1440 && val < 2880)
1406             setvalidity = 168;
1407         if (val >= 750 && val <= 1440)
1408             setvalidity = (val - 720 - 1) / 30 + 143 + 1;
1409         if (val > 720 && val < 750)
1410             setvalidity = 144;
1411         if (val >= 5 && val <= 720)
1412             setvalidity = (val - 1) / 5 - 1 + 1;
1413         if (val < 5)
1414             setvalidity = 0;
1415 
1416         packet_add_int_parm(packet, P_VALIDITY_PERIOD_RELATIVE, setvalidity, conn);
1417     }
1418 
1419     /* Explicitly ask not to get status reports.
1420      * If we do not do this, the server's default might be to
1421      * send status reports in some cases, and we don't do anything
1422      * with those reports anyway. */
1423     /* ask for the delivery reports if needed*/
1424 
1425     if (!pdata->no_dlr)
1426         if (DLR_IS_SUCCESS_OR_FAIL(msg->sms.dlr_mask))
1427             packet_add_int_parm(packet, P_STATUS_REPORT_REQUEST, 14, conn);
1428     	else
1429             packet_add_int_parm(packet, P_STATUS_REPORT_REQUEST, 0, conn);
1430     else if( pdata->no_dlr && DLR_IS_SUCCESS_OR_FAIL(msg->sms.dlr_mask))
1431     	warning(0, "CIMD2[%s]: dlr request make no sense while no-dlr set to true",
1432     		 octstr_get_cstr(conn->id));
1433 
1434     /* Turn off reply path as default.
1435      * This avoids phones automatically asking for a reply
1436      */
1437     if (msg->sms.rpi > 0)
1438 	packet_add_int_parm(packet, P_REPLY_PATH, 1, conn);
1439     else
1440     	packet_add_int_parm(packet, P_REPLY_PATH, 0, conn);
1441 
1442     /* Use binfo to set the tariff class */
1443     if (octstr_len(msg->sms.binfo))
1444 	packet_add_parm(packet, P_INT, P_TARIFF_CLASS, msg->sms.binfo, conn);
1445 
1446     /* Set the protocol identifier if requested */
1447     if (msg->sms.pid > 0)
1448         packet_add_int_parm(packet, P_PROTOCOL_IDENTIFIER, msg->sms.pid, conn);
1449 
1450 	/* If there are more messages to the same destination, then set the
1451 	* More Messages to Send flag. This allow faster delivery of many messages
1452 	* to the same destination
1453 	*/
1454     if (msg->sms.msg_left > 0)
1455         packet_add_int_parm(packet, P_MORE_MESSAGES_TO_SEND, 1, conn);
1456     else
1457         packet_add_int_parm(packet, P_MORE_MESSAGES_TO_SEND, 0, conn);
1458 
1459     truncated = 0;
1460 
1461     spaceleft = 140;
1462     if (octstr_len(msg->sms.udhdata)) {
1463         /* udhdata will be truncated and warned about if
1464          * it does not fit. */
1465         packet_add_hex_parm(packet, P_USER_DATA_HEADER, msg->sms.udhdata, conn);
1466     }
1467     if (msg->sms.coding == DC_7BIT || msg->sms.coding == DC_UNDEF)
1468         spaceleft = spaceleft * 8 / 7;
1469     if (spaceleft < 0)
1470         spaceleft = 0;
1471 
1472     text = octstr_duplicate(msg->sms.msgdata);
1473 
1474     if (octstr_len(text) > 0 && spaceleft == 0) {
1475         warning(0, "CIMD2[%s]: message filled up with UDH, no room for message text",
1476                 octstr_get_cstr(conn->id));
1477     } else if (msg->sms.coding == DC_8BIT || msg->sms.coding == DC_UCS2) {
1478         if (octstr_len(text) > spaceleft) {
1479             truncated = octstr_len(text) - spaceleft;
1480             octstr_truncate(text, spaceleft);
1481         }
1482         packet_add_hex_parm(packet, P_USER_DATA_BINARY, text, conn);
1483     } else {
1484         /* Going from latin1 to GSM to CIMD2 may seem like a
1485          * detour, but it's the only way to get all the escape
1486          * codes right. */
1487         charset_utf8_to_gsm(text);
1488         truncated = charset_gsm_truncate(text, spaceleft);
1489         convert_gsm_to_cimd2(text);
1490         packet_add_sms_parm(packet, P_USER_DATA, text, conn);
1491     }
1492 
1493     if (dcs != 0)
1494         packet_add_int_parm(packet, P_DATA_CODING_SCHEME, dcs, conn);
1495 
1496     if (truncated > 0) {
1497         warning(0, "CIMD2[%s]: truncating message text to fit in %d characters.",
1498                 octstr_get_cstr(conn->id),
1499                 spaceleft);
1500     }
1501 
1502     octstr_destroy(text);
1503     return packet;
1504 }
1505 
1506 /***************************************************************************/
1507 /* Protocol functions.  These implement various transactions.              */
1508 /***************************************************************************/
1509 
1510 /* Give this packet a proper sequence number for sending. */
packet_set_send_sequence(struct packet * packet,PrivData * pdata)1511 static void packet_set_send_sequence(struct packet *packet, PrivData *pdata)
1512 {
1513     gw_assert(pdata != NULL);
1514     /* LOGIN packets always have sequence number 001 */
1515     if (packet->operation == LOGIN)
1516         pdata->send_seq = 1;
1517     /* Send sequence numbers are always odd, receiving are always even */
1518     gw_assert(pdata->send_seq % 2 == 1);
1519 
1520     packet_set_sequence(packet, pdata->send_seq);
1521     pdata->send_seq += 2;
1522     if (pdata->send_seq > 256)
1523         pdata->send_seq = 1;
1524 }
1525 
cimd2_get_packet(PrivData * pdata,Octstr ** ts)1526 static struct packet *cimd2_get_packet(PrivData *pdata, Octstr **ts)
1527 {
1528     struct packet *packet = NULL;
1529 
1530     gw_assert(pdata != NULL);
1531 
1532     /* If packet is already available, don't try to read anything */
1533     packet = packet_extract(pdata->inbuffer, pdata->conn);
1534 
1535     while (packet == NULL) {
1536         if (read_available(pdata->socket, RESPONSE_TIMEOUT) != 1) {
1537             warning(0, "CIMD2[%s]: SMSC is not responding",
1538                     octstr_get_cstr(pdata->conn->id));
1539             return NULL;
1540         }
1541 
1542         if (octstr_append_from_socket(pdata->inbuffer, pdata->socket) <= 0) {
1543             error(0, "CIMD2[%s]: cimd2_get_packet: read failed",
1544                   octstr_get_cstr(pdata->conn->id));
1545             return NULL;
1546         }
1547 
1548         packet = packet_extract(pdata->inbuffer, pdata->conn);
1549     }
1550 
1551     packet_check(packet,pdata->conn);
1552     packet_check_can_receive(packet,pdata->conn);
1553     debug("bb.sms.cimd2", 0, "CIMD2[%s]: received: <%s>",
1554           octstr_get_cstr(pdata->conn->id),
1555           octstr_get_cstr(packet->data));
1556     if (ts)
1557         *ts = packet_get_parm(packet,P_MC_TIMESTAMP);
1558 
1559     if (pdata->keepalive > 0)
1560         pdata->next_ping = time(NULL) + pdata->keepalive;
1561 
1562     return packet;
1563 }
1564 
1565 /* Acknowledge a request.  The CIMD 2 spec only defines positive responses
1566  * to the server, because the server is perfect. */
cimd2_send_response(struct packet * request,PrivData * pdata)1567 static void cimd2_send_response(struct packet *request, PrivData *pdata)
1568 {
1569     struct packet *response;
1570 
1571     gw_assert(request != NULL);
1572     gw_assert(request->operation < RESPONSE);
1573 
1574     response = packet_create(request->operation + RESPONSE, request->seq);
1575     packet_set_checksum(response);
1576 
1577     debug("bb.sms.cimd2", 0, "CIMD2[%s]: sending <%s>",
1578           octstr_get_cstr(pdata->conn->id),
1579           octstr_get_cstr(response->data));
1580 
1581     /* Don't check errors here because if there is something
1582      * wrong with the socket, the main loop will detect it. */
1583     octstr_write_to_socket(pdata->socket, response->data);
1584 
1585     packet_destroy(response);
1586 }
1587 
cimd2_accept_message(struct packet * request,SMSCConn * conn)1588 static Msg *cimd2_accept_message(struct packet *request, SMSCConn *conn)
1589 {
1590     Msg *message = NULL;
1591     Octstr *destination = NULL;
1592     Octstr *origin = NULL;
1593     Octstr *UDH = NULL;
1594     Octstr *text = NULL;
1595     int DCS;
1596 
1597     /* See GSM 03.38.  The bit patterns we can handle are:
1598      *   000xyyxx  Uncompressed text, yy indicates alphabet.
1599      *                   yy = 00, default alphabet
1600      *                   yy = 01, 8-bit data
1601      *                   yy = 10, UCS-2
1602      *                   yy = 11, reserved
1603      *   1111xyxx  Data, y indicates alphabet.
1604      *                   y = 0, default alphabet
1605      *                   y = 1, 8-bit data
1606      */
1607     DCS = packet_get_int_parm(request, P_DATA_CODING_SCHEME);
1608 
1609     destination = packet_get_address_parm(request, P_DESTINATION_ADDRESS);
1610     origin = packet_get_address_parm(request, P_ORIGINATING_ADDRESS);
1611     UDH = packet_get_hex_parm(request, P_USER_DATA_HEADER);
1612     /* Text is either in User Data or User Data Binary field. */
1613     text = packet_get_sms_parm(request, P_USER_DATA);
1614     if (text != NULL) {
1615         convert_cimd2_to_gsm(text,conn);
1616         charset_gsm_to_utf8(text);
1617     } else {
1618         /*
1619          * FIXME: If DCS indicates GSM charset, and we get it in binary,
1620          * then it's probably bit-packed.  We'll have to undo it because
1621          * our "charset_gsm" means one gsm character per octet.  This is
1622          * not currently supported. -- RB
1623          */
1624         text = packet_get_hex_parm(request, P_USER_DATA_BINARY);
1625     }
1626 
1627     /* Code elsewhere in the gateway always expects the sender and
1628      * receiver fields to be filled, so we discard messages that
1629      * lack them.  If they should not be discarded, then the code
1630      * handling sms messages should be reviewed.  -- RB */
1631     if (!destination || octstr_len(destination) == 0) {
1632         info(0, "CIMD2[%s]: Got SMS without receiver, discarding.",
1633               octstr_get_cstr(conn->id));
1634         goto error;
1635     }
1636     if (!origin || octstr_len(origin) == 0) {
1637         info(0, "CIMD2[%s]: Got SMS without sender, discarding.",
1638               octstr_get_cstr(conn->id));
1639         goto error;
1640     }
1641 
1642     if (!text && (!UDH || octstr_len(UDH) == 0)) {
1643         info(0, "CIMD2[%s]: Got empty SMS, ignoring.",
1644               octstr_get_cstr(conn->id));
1645         goto error;
1646     }
1647 
1648     message = msg_create(sms);
1649     if (! dcs_to_fields(&message, DCS)) {
1650 	/* XXX Should reject this message ? */
1651         debug("bb.sms.cimd2", 0, "CIMD2[%s]: Invalid DCS",
1652               octstr_get_cstr(conn->id));
1653 	dcs_to_fields(&message, 0);
1654     }
1655     time(&message->sms.time);
1656     message->sms.sender = origin;
1657     message->sms.receiver = destination;
1658     if (UDH) {
1659         message->sms.udhdata = UDH;
1660     }
1661     message->sms.msgdata = text;
1662     return message;
1663 
1664 error:
1665     msg_destroy(message);
1666     octstr_destroy(destination);
1667     octstr_destroy(origin);
1668     octstr_destroy(UDH);
1669     octstr_destroy(text);
1670     return NULL;
1671 }
1672 
1673 /* Deal with a request from the CIMD2 server, and acknowledge it. */
cimd2_handle_request(struct packet * request,SMSCConn * conn)1674 static void cimd2_handle_request(struct packet *request, SMSCConn *conn)
1675 {
1676     PrivData *pdata = conn->data;
1677     Msg *message = NULL;
1678 
1679     if ((request->seq == 254 && pdata->receive_seq == 0) ||
1680             request->seq == pdata->receive_seq - 2) {
1681         warning(0, "CIMD2[%s]: request had same sequence number as previous.",
1682                 octstr_get_cstr(conn->id));
1683     }
1684     else {
1685         pdata->receive_seq = request->seq + 2;
1686         if (pdata->receive_seq > 254)
1687             pdata->receive_seq = 0;
1688 
1689         if (request->operation == DELIVER_STATUS_REPORT) {
1690             message = cimd2_accept_delivery_report_message(request, conn);
1691             if (message)
1692                 gwlist_append(pdata->received, message);
1693         }
1694         else if (request->operation == DELIVER_MESSAGE) {
1695             message = cimd2_accept_message(request,conn);
1696             if (message)
1697                 gwlist_append(pdata->received, message);
1698         }
1699     }
1700 
1701     cimd2_send_response(request, pdata);
1702 }
1703 
1704 /* Send a request and wait for the ack.  If the other side responds with
1705  * an error code, attempt to correct and retry.
1706  * If other packets arrive while we wait for the ack, handle them.
1707  *
1708  * Return -1 if the SMSC refused the request.  Return -2 for other
1709  * errors, such as being unable to send the request at all.  If the
1710  * function returns -2, the caller would do well to try to reopen the
1711  * connection.
1712  *
1713  * The SMSCenter must be already open.
1714  *
1715  * TODO: This function has grown large and complex.  Break it up
1716  * into smaller pieces.
1717  */
cimd2_request(struct packet * request,SMSCConn * conn,Octstr ** ts)1718 static int cimd2_request(struct packet *request, SMSCConn *conn, Octstr **ts)
1719 {
1720     PrivData *pdata = conn->data;
1721     int ret;
1722     struct packet *reply = NULL;
1723     int errorcode;
1724     int tries = 0;
1725 
1726     gw_assert(pdata != NULL);
1727     gw_assert(request != NULL);
1728     gw_assert(operation_can_send(request->operation));
1729 
1730     if (pdata->socket < 0) {
1731         warning(0, "CIMD2[%s]: cimd2_request: socket not open.",
1732                 octstr_get_cstr(conn->id));
1733         return -2;
1734     }
1735 
1736 retransmit:
1737     packet_set_send_sequence(request, pdata);
1738     packet_set_checksum(request);
1739 
1740     debug("bb.sms.cimd2", 0, "CIMD2[%s]: sending <%s>",
1741           octstr_get_cstr(conn->id),
1742           octstr_get_cstr(request->data));
1743 
1744     ret = octstr_write_to_socket(pdata->socket, request->data);
1745     if (ret < 0)
1746         goto io_error;
1747 
1748 next_reply:
1749     packet_destroy(reply);  /* destroy old, if any */
1750     reply = cimd2_get_packet(pdata, ts);
1751     if (!reply)
1752         goto io_error;
1753 
1754     errorcode = packet_display_error(reply,conn);
1755 
1756     if (reply->operation == NACK) {
1757         warning(0, "CIMD2[%s]: received NACK",
1758                 octstr_get_cstr(conn->id));
1759         octstr_dump(reply->data, 0);
1760         /* Correct sequence number if server says it was wrong,
1761          * but only if server's number is sane. */
1762         if (reply->seq != request->seq && (reply->seq % 2) == 1) {
1763             warning(0, "CIMD2[%s]: correcting sequence number from %ld to %ld.",
1764                     octstr_get_cstr(conn->id),
1765                     (long) pdata->send_seq,
1766                     (long) reply->seq);
1767             pdata->send_seq = reply->seq;
1768         }
1769         goto retry;
1770     }
1771 
1772     if (reply->operation == GENERAL_ERROR_RESPONSE) {
1773         error(0, "CIMD2[%s]: received general error response",
1774               octstr_get_cstr(conn->id));
1775         goto io_error;
1776     }
1777 
1778     /* The server sent us a request.  Handle it, then wait for
1779      * a new reply. */
1780     if (reply->operation < RESPONSE) {
1781         cimd2_handle_request(reply, conn);
1782         goto next_reply;
1783     }
1784 
1785     if (reply->seq != request->seq) {
1786         /* We got a response to a different request number than
1787          * what we send.  Strange. */
1788         warning(0, "CIMD2[%s]: response had unexpected sequence number; ignoring.",
1789                 octstr_get_cstr(conn->id));
1790         goto next_reply;
1791     }
1792 
1793     if (reply->operation != request->operation + RESPONSE) {
1794         /* We got a response that didn't match our request */
1795         Octstr *request_name = operation_name(request->operation);
1796         Octstr *reply_name = operation_name(reply->operation);
1797         warning(0, "CIMD2[%s]: %s request got a %s",
1798                 octstr_get_cstr(conn->id),
1799                 octstr_get_cstr(request_name),
1800                 octstr_get_cstr(reply_name));
1801 
1802         octstr_destroy(request_name);
1803         octstr_destroy(reply_name);
1804         octstr_dump(reply->data, 0);
1805         goto retry;
1806     }
1807 
1808     if (errorcode > 0)
1809         goto error;
1810 
1811     /* The reply passed all the checks... looks like the SMSC accepted
1812      * our request! */
1813     packet_destroy(reply);
1814     return 0;
1815 
1816 io_error:
1817     packet_destroy(reply);
1818     return -2;
1819 
1820 error:
1821     packet_destroy(reply);
1822     return -1;
1823 
1824 retry:
1825     if (++tries < 3) {
1826         warning(0, "CIMD2[%s]: Retransmitting (take %d)",
1827                 octstr_get_cstr(conn->id),
1828                 tries);
1829         goto retransmit;
1830     }
1831     warning(0, "CIMD2[%s]: Giving up.",
1832             octstr_get_cstr(conn->id));
1833     goto io_error;
1834 }
1835 
1836 /* Close the SMSC socket without fanfare. */
cimd2_close_socket(PrivData * pdata)1837 static void cimd2_close_socket(PrivData *pdata)
1838 {
1839     gw_assert(pdata != NULL);
1840 
1841     if (pdata->socket < 0)
1842         return;
1843 
1844     if (close(pdata->socket) < 0)
1845         warning(errno, "CIMD2[%s]: error closing socket",
1846                 octstr_get_cstr(pdata->conn->id));
1847     pdata->socket = -1;
1848 }
1849 
1850 /* Open a socket to the SMSC, send a login packet, and wait for ack.
1851  * This may block.  Return 0 for success, or -1 for failure. */
1852 /* Make sure the socket is closed before calling this function, otherwise
1853  * we will leak fd's. */
cimd2_login(SMSCConn * conn)1854 static int cimd2_login(SMSCConn *conn)
1855 {
1856     PrivData *pdata = conn->data;
1857     int ret;
1858     struct packet *packet = NULL;
1859 
1860     gw_assert(pdata != NULL);
1861 
1862     if (pdata->socket >= 0) {
1863         warning(0, "CIMD2[%s]: login: socket was already open; closing",
1864                 octstr_get_cstr(conn->id));
1865         cimd2_close_socket(pdata);
1866     }
1867 
1868     pdata->socket = tcpip_connect_to_server_with_port(
1869                                             octstr_get_cstr(pdata->host),
1870                                             pdata->port,
1871                                             pdata->our_port,
1872                                             (conn->our_host ? octstr_get_cstr(conn->our_host) : NULL));
1873     if (pdata->socket != -1) {
1874 
1875         packet = packet_create(LOGIN, BOGUS_SEQUENCE);
1876         packet_add_string_parm(packet, P_USER_IDENTITY, pdata->username, conn);
1877         packet_add_string_parm(packet, P_PASSWORD, pdata->password, conn);
1878 
1879         ret = cimd2_request(packet, conn, NULL);
1880 
1881         if (ret >= 0) {
1882             packet_destroy(packet);
1883             info(0, "CIMD2[%s] logged in.",
1884                  octstr_get_cstr(conn->id));
1885             return 0;
1886         }
1887     }
1888     error(0, "CIMD2[%s] login failed.",
1889           octstr_get_cstr(conn->id));
1890     cimd2_close_socket(pdata);
1891     packet_destroy(packet);
1892     return -1;
1893 }
1894 
cimd2_logout(SMSCConn * conn)1895 static void cimd2_logout(SMSCConn *conn)
1896 {
1897     struct packet *packet = NULL;
1898     int ret;
1899 
1900     packet = packet_create(LOGOUT, BOGUS_SEQUENCE);
1901 
1902     /* TODO: Don't wait very long for a response in this case. */
1903     ret = cimd2_request(packet, conn, NULL);
1904 
1905     if (ret == 0) {
1906         info(0, "CIMD2[%s] logged out.",
1907              octstr_get_cstr(conn->id));
1908     }
1909     packet_destroy(packet);
1910 }
1911 
cimd2_send_alive(SMSCConn * conn)1912 static int cimd2_send_alive(SMSCConn *conn)
1913 {
1914     struct packet *packet = NULL;
1915     int ret;
1916 
1917     packet = packet_create(ALIVE, BOGUS_SEQUENCE);
1918     ret = cimd2_request(packet, conn, NULL);
1919     packet_destroy(packet);
1920 
1921     if (ret < 0)
1922         warning(0, "CIMD2[%s]: SMSC not alive.",
1923                 octstr_get_cstr(conn->id));
1924 
1925     return ret;
1926 }
1927 
1928 
cimd2_destroy(PrivData * pdata)1929 static void cimd2_destroy(PrivData *pdata)
1930 {
1931     int discarded;
1932 
1933     if (pdata == NULL)
1934         return;
1935 
1936     octstr_destroy(pdata->host);
1937     octstr_destroy(pdata->username);
1938     octstr_destroy(pdata->password);
1939     octstr_destroy(pdata->inbuffer);
1940     octstr_destroy(pdata->my_number);
1941 
1942     discarded = gwlist_len(pdata->received);
1943     if (discarded > 0)
1944         warning(0, "CIMD2[%s]: discarded %d received messages",
1945                 octstr_get_cstr(pdata->conn->id),
1946                 discarded);
1947 
1948     gwlist_destroy(pdata->received, msg_destroy_item);
1949     gwlist_destroy(pdata->outgoing_queue, NULL);
1950     gwlist_destroy(pdata->stopped, NULL);
1951 
1952     gw_free(pdata);
1953 }
1954 
1955 
cimd2_submit_msg(SMSCConn * conn,Msg * msg)1956 static int cimd2_submit_msg(SMSCConn *conn, Msg *msg)
1957 {
1958     PrivData *pdata = conn->data;
1959     struct packet *packet;
1960     Octstr *ts = NULL;
1961     int ret;
1962 
1963     gw_assert(pdata != NULL);
1964     debug("bb.sms.cimd2", 0, "CIMD2[%s]: sending message",
1965         octstr_get_cstr(conn->id));
1966 
1967     packet = packet_encode_message(msg, pdata->my_number,conn);
1968     if (!packet) {
1969         /* This is a protocol error. Does this help? I doubt..
1970          * But nevermind that.
1971          */
1972         bb_smscconn_send_failed(conn, msg,
1973 	            SMSCCONN_FAILED_MALFORMED, octstr_create("MALFORMED"));
1974         return -1;
1975     }
1976 
1977     ret = cimd2_request(packet, conn, &ts);
1978     if ((ret == 0) && (ts) && DLR_IS_SUCCESS_OR_FAIL(msg->sms.dlr_mask) && !pdata->no_dlr) {
1979         dlr_add(conn->name, ts, msg, 1);
1980     }
1981     octstr_destroy(ts);
1982     packet_destroy(packet);
1983 
1984     if (ret == -1) {
1985         bb_smscconn_send_failed(conn, msg,
1986 	            SMSCCONN_FAILED_REJECTED, octstr_create("REJECTED"));
1987     }
1988     else if (ret == -2) {
1989         cimd2_close_socket(pdata);
1990         bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_TEMPORARILY, NULL);
1991         mutex_lock(conn->flow_mutex);
1992         conn->status = SMSCCONN_DISCONNECTED;
1993         mutex_unlock(conn->flow_mutex);
1994     }
1995     else {
1996         bb_smscconn_sent(conn,msg, NULL);
1997     }
1998 
1999     return ret;
2000 }
2001 
cimd2_receive_msg(SMSCConn * conn,Msg ** msg)2002 static int cimd2_receive_msg(SMSCConn *conn, Msg **msg)
2003 {
2004     PrivData *pdata = conn->data;
2005     long ret;
2006     struct packet *packet;
2007 
2008     gw_assert(pdata != NULL);
2009 
2010     if (gwlist_len(pdata->received) > 0) {
2011         *msg = gwlist_consume(pdata->received);
2012         return 1;
2013     }
2014 
2015     if (pdata->socket < 0) {
2016         /* XXX We have to assume that smsc_send_message is
2017          * currently trying to reopen, so we have to make
2018          * this thread wait.  It should be done in a nicer
2019          * way. */
2020         return 0;
2021     }
2022 
2023     ret = read_available(pdata->socket, 0);
2024     if (ret == 0) {
2025         if (pdata->keepalive > 0 && pdata->next_ping < time(NULL)) {
2026             if (cimd2_send_alive(conn) < 0)
2027 		return -1;
2028         }
2029         return 0;
2030     }
2031 
2032     if (ret < 0) {
2033         warning(errno, "CIMD2[%s]: cimd2_receive_msg: read_available failed",
2034                 octstr_get_cstr(conn->id));
2035         return -1;
2036     }
2037 
2038     /* We have some data waiting... see if it is an sms delivery. */
2039     ret = octstr_append_from_socket(pdata->inbuffer, pdata->socket);
2040 
2041     if (ret == 0) {
2042         warning(0, "CIMD2[%s]: cimd2_receive_msg: service center closed connection.",
2043                 octstr_get_cstr(conn->id));
2044         return -1;
2045     }
2046     if (ret < 0) {
2047         warning(0, "CIMD2[%s]: cimd2_receive_msg: read failed",
2048                 octstr_get_cstr(conn->id));
2049         return -1;
2050     }
2051 
2052 
2053     for (;;) {
2054         packet = packet_extract(pdata->inbuffer,conn);
2055         if (!packet)
2056             break;
2057 
2058         packet_check(packet,conn);
2059         packet_check_can_receive(packet,conn);
2060         debug("bb.sms.cimd2", 0, "CIMD2[%s]: received: <%s>",
2061               octstr_get_cstr(pdata->conn->id),
2062               octstr_get_cstr(packet->data));
2063 
2064         if (packet->operation < RESPONSE)
2065             cimd2_handle_request(packet, conn);
2066         else {
2067             error(0, "CIMD2[%s]: cimd2_receive_msg: unexpected response packet",
2068                 octstr_get_cstr(conn->id));
2069             octstr_dump(packet->data, 0);
2070         }
2071 
2072         packet_destroy(packet);
2073     }
2074 
2075     if (gwlist_len(pdata->received) > 0) {
2076 	*msg = gwlist_consume(pdata->received);
2077         return 1;
2078     }
2079     return 0;
2080 }
2081 
2082 
2083 
cimd2_accept_delivery_report_message(struct packet * request,SMSCConn * conn)2084 static Msg *cimd2_accept_delivery_report_message(struct packet *request,
2085 						 SMSCConn *conn)
2086 {
2087     Msg *msg = NULL;
2088     Octstr *destination = NULL;
2089     Octstr *timestamp = NULL;
2090     Octstr *statuscode = NULL;
2091     int st_code;
2092     int code;
2093 
2094     destination = packet_get_parm(request, P_DESTINATION_ADDRESS);
2095     timestamp = packet_get_parm(request, P_MC_TIMESTAMP);
2096     statuscode = packet_get_parm(request, P_STATUS_CODE);
2097 
2098     st_code = atoi(octstr_get_cstr(statuscode));
2099 
2100     switch(st_code)
2101     {
2102     case 2:  /* validity period expired */
2103     case 3:  /* delivery failed */
2104     case 6: /* last no response */
2105     case 7: /* message cancelled */
2106     case 8: /* message deleted */
2107     case 9: /* message deleted by cancel */
2108 	code = DLR_FAIL;
2109     	break;
2110     case 4: /* delivery successful */
2111     	code = DLR_SUCCESS;
2112     	break;
2113     default:
2114         code = 0;
2115     }
2116     if(code)
2117         msg = dlr_find(conn->name, timestamp, destination, code, 1);
2118     else
2119         msg = NULL;
2120 
2121     /* recode the body into msgdata */
2122     if (msg) {
2123         msg->sms.msgdata = packet_get_parm(request, P_USER_DATA);
2124         if (!msg->sms.msgdata) {
2125             msg->sms.msgdata = statuscode;
2126             statuscode = NULL;
2127         }
2128     }
2129 
2130     octstr_destroy(statuscode);
2131     octstr_destroy(destination);
2132     octstr_destroy(timestamp);
2133 
2134     return msg;
2135  }
2136 
sms_receive(SMSCConn * conn)2137 static Msg *sms_receive(SMSCConn *conn)
2138 {
2139     PrivData *pdata = conn->data;
2140     int ret;
2141     Msg *newmsg = NULL;
2142 
2143     ret = cimd2_receive_msg(conn, &newmsg);
2144     if (ret == 1) {
2145         /* if any smsc_id available, use it */
2146         newmsg->sms.smsc_id = octstr_duplicate(conn->id);
2147         return newmsg;
2148     }
2149     else if (ret == 0) { /* no message, just retry... */
2150         return NULL;
2151     }
2152     /* error. reconnect. */
2153     msg_destroy(newmsg);
2154     mutex_lock(conn->flow_mutex);
2155     cimd2_close_socket(pdata);
2156     conn->status = SMSCCONN_DISCONNECTED;
2157     mutex_unlock(conn->flow_mutex);
2158     return NULL;
2159 }
2160 
2161 
io_thread(void * arg)2162 static void io_thread (void *arg)
2163 {
2164     Msg       *msg;
2165     SMSCConn  *conn = arg;
2166     PrivData *pdata = conn->data;
2167     double    sleep = 0.0001;
2168 
2169     /* Make sure we log into our own log-file if defined */
2170     log_thread_to(conn->log_idx);
2171 
2172     /* remove messages from SMSC until we are killed */
2173     while (!pdata->quitting) {
2174 
2175         gwlist_consume(pdata->stopped); /* block here if suspended/isolated */
2176 
2177         /* check that connection is active */
2178         if (conn->status != SMSCCONN_ACTIVE) {
2179             if (cimd2_login(conn) != 0) {
2180                 error(0, "CIMD2[%s]: Couldn't connect to SMSC (retrying in %ld seconds).",
2181                       octstr_get_cstr(conn->id),
2182                       conn->reconnect_delay);
2183                 gwthread_sleep(conn->reconnect_delay);
2184                 mutex_lock(conn->flow_mutex);
2185                 conn->status = SMSCCONN_RECONNECTING;
2186                 mutex_unlock(conn->flow_mutex);
2187                 continue;
2188             }
2189             mutex_lock(conn->flow_mutex);
2190             conn->status = SMSCCONN_ACTIVE;
2191             conn->connect_time = time(NULL);
2192             bb_smscconn_connected(conn);
2193             mutex_unlock(conn->flow_mutex);
2194         }
2195 
2196         /* receive messages */
2197         do {
2198             msg = sms_receive(conn);
2199             if (msg) {
2200                 sleep = 0;
2201                 debug("bb.sms.cimd2", 0, "CIMD2[%s]: new message received",
2202                       octstr_get_cstr(conn->id));
2203                 bb_smscconn_receive(conn, msg);
2204             }
2205         } while (msg);
2206 
2207         /* send messages */
2208         do {
2209             msg = gwlist_extract_first(pdata->outgoing_queue);
2210             if (msg) {
2211                 sleep = 0;
2212                 if (cimd2_submit_msg(conn,msg) != 0) break;
2213             }
2214         } while (msg);
2215 
2216         if (sleep > 0) {
2217 
2218             /* note that this implementations means that we sleep even
2219              * when we fail connection.. but time is very short, anyway
2220              */
2221             gwthread_sleep(sleep);
2222             /* gradually sleep longer and longer times until something starts to
2223              * happen - this of course reduces response time, but that's better than
2224              * extensive CPU usage when it is not used
2225              */
2226             sleep *= 2;
2227             if (sleep >= 2.0)
2228                 sleep = 1.999999;
2229         }
2230         else {
2231             sleep = 0.0001;
2232         }
2233     }
2234 }
2235 
2236 
cimd2_add_msg_cb(SMSCConn * conn,Msg * sms)2237 static int cimd2_add_msg_cb (SMSCConn *conn, Msg *sms)
2238 {
2239     PrivData *pdata = conn->data;
2240     Msg *copy;
2241 
2242     copy = msg_duplicate(sms);
2243     gwlist_produce(pdata->outgoing_queue, copy);
2244     gwthread_wakeup(pdata->io_thread);
2245 
2246     return 0;
2247 }
2248 
2249 
cimd2_shutdown_cb(SMSCConn * conn,int finish_sending)2250 static int cimd2_shutdown_cb (SMSCConn *conn, int finish_sending)
2251 {
2252     PrivData *pdata = conn->data;
2253 
2254     debug("bb.sms", 0, "Shutting down SMSCConn CIMD2 %s (%s)",
2255           octstr_get_cstr(conn->id),
2256           finish_sending ? "slow" : "instant");
2257 
2258     /* Documentation claims this would have been done by smscconn.c,
2259        but isn't when this code is being written. */
2260     conn->why_killed = SMSCCONN_KILLED_SHUTDOWN;
2261     pdata->quitting = 1;     /* Separate from why_killed to avoid locking, as
2262                               * why_killed may be changed from outside? */
2263 
2264     if (finish_sending == 0) {
2265         Msg *msg;
2266         while ((msg = gwlist_extract_first(pdata->outgoing_queue)) != NULL) {
2267             bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL);
2268         }
2269     }
2270 
2271     cimd2_logout(conn);
2272     if (conn->is_stopped) {
2273         gwlist_remove_producer(pdata->stopped);
2274         conn->is_stopped = 0;
2275     }
2276 
2277     if (pdata->io_thread != -1) {
2278         gwthread_wakeup(pdata->io_thread);
2279         gwthread_join(pdata->io_thread);
2280     }
2281 
2282     cimd2_close_socket(pdata);
2283     cimd2_destroy(pdata);
2284 
2285     debug("bb.sms", 0, "SMSCConn CIMD2 %s shut down.",
2286           octstr_get_cstr(conn->id));
2287     conn->status = SMSCCONN_DEAD;
2288     bb_smscconn_killed();
2289     return 0;
2290 }
2291 
cimd2_start_cb(SMSCConn * conn)2292 static void cimd2_start_cb (SMSCConn *conn)
2293 {
2294     PrivData *pdata = conn->data;
2295 
2296     gwlist_remove_producer(pdata->stopped);
2297     /* in case there are messages in the buffer already */
2298     gwthread_wakeup(pdata->io_thread);
2299     debug("bb.sms", 0, "SMSCConn CIMD2 %s, start called",
2300           octstr_get_cstr(conn->id));
2301 }
2302 
cimd2_stop_cb(SMSCConn * conn)2303 static void cimd2_stop_cb (SMSCConn *conn)
2304 {
2305     PrivData *pdata = conn->data;
2306     gwlist_add_producer(pdata->stopped);
2307     debug("bb.sms", 0, "SMSCConn CIMD2 %s, stop called",
2308           octstr_get_cstr(conn->id));
2309 }
2310 
cimd2_queued_cb(SMSCConn * conn)2311 static long cimd2_queued_cb (SMSCConn *conn)
2312 {
2313     PrivData *pdata = conn->data;
2314     conn->load = (pdata ? (conn->status != SMSCCONN_DEAD ?
2315                   gwlist_len(pdata->outgoing_queue) : 0) : 0);
2316     return conn->load;
2317 }
2318 
smsc_cimd2_create(SMSCConn * conn,CfgGroup * grp)2319 int smsc_cimd2_create(SMSCConn *conn, CfgGroup *grp)
2320 {
2321     PrivData *pdata;
2322     int ok;
2323     int maxlen;
2324 
2325     pdata = gw_malloc(sizeof(PrivData));
2326     conn->data = pdata;
2327     pdata->conn = conn;
2328 
2329     pdata->no_dlr = 0;
2330     pdata->quitting = 0;
2331     pdata->socket = -1;
2332     pdata->received = gwlist_create();
2333     pdata->inbuffer = octstr_create("");
2334     pdata->send_seq = 1;
2335     pdata->receive_seq = 0;
2336     pdata->outgoing_queue = gwlist_create();
2337     pdata->stopped = gwlist_create();
2338     gwlist_add_producer(pdata->outgoing_queue);
2339 
2340     if (conn->is_stopped)
2341       gwlist_add_producer(pdata->stopped);
2342 
2343     pdata->host = cfg_get(grp, octstr_imm("host"));
2344     if (cfg_get_integer(&(pdata->port), grp, octstr_imm("port")) == -1)
2345       pdata->port = 0;
2346     if (cfg_get_integer(&(pdata->our_port), grp, octstr_imm("our-port")) == -1)
2347       pdata->our_port = 0;
2348     pdata->username = cfg_get(grp, octstr_imm("smsc-username"));
2349     pdata->password = cfg_get(grp, octstr_imm("smsc-password"));
2350     pdata->my_number = cfg_get(grp, octstr_imm("my-number"));
2351     if (cfg_get_integer(&(pdata->keepalive), grp,octstr_imm("keepalive")) == -1)
2352         pdata->keepalive = 0;
2353 
2354     cfg_get_bool(&pdata->no_dlr, grp, octstr_imm("no-dlr"));
2355 
2356     /* Check that config is OK */
2357     ok = 1;
2358     if (pdata->host == NULL) {
2359         error(0,"CIMD2[%s]: Configuration file doesn't specify host",
2360               octstr_get_cstr(conn->id));
2361         ok = 0;
2362     }
2363     if (pdata->port == 0) {
2364         error(0,"CIMD2[%s]: Configuration file doesn't specify port",
2365               octstr_get_cstr(conn->id));
2366         ok = 0;
2367     }
2368     if (pdata->username == NULL) {
2369         error(0, "CIMD2[%s]: Configuration file doesn't specify username.",
2370               octstr_get_cstr(conn->id));
2371         ok = 0;
2372     }
2373     if (pdata->password == NULL) {
2374         error(0, "CIMD2[%s]: Configuration file doesn't specify password.",
2375               octstr_get_cstr(conn->id));
2376         ok = 0;
2377     }
2378 
2379     if (!ok) {
2380         cimd2_destroy(pdata);
2381         return -1;
2382     }
2383 
2384     conn->name = octstr_format("CIMD2:%s:%d:%s",
2385                      octstr_get_cstr(pdata->host),
2386                      pdata->port,
2387                      octstr_get_cstr(pdata->username));
2388 
2389 
2390     if (pdata->keepalive > 0) {
2391       debug("bb.sms.cimd2", 0, "CIMD2[%s]: Keepalive set to %ld seconds",
2392             octstr_get_cstr(conn->id),
2393             pdata->keepalive);
2394         pdata->next_ping = time(NULL) + pdata->keepalive;
2395     }
2396 
2397     maxlen = parm_maxlen(P_USER_IDENTITY);
2398     if (octstr_len(pdata->username) > maxlen) {
2399         octstr_truncate(pdata->username, maxlen);
2400         warning(0, "CIMD2[%s]: Truncating username to %d chars",
2401                 octstr_get_cstr(conn->id),
2402                 maxlen);
2403     }
2404 
2405     maxlen = parm_maxlen(P_PASSWORD);
2406     if (octstr_len(pdata->password) > maxlen) {
2407         octstr_truncate(pdata->password, maxlen);
2408         warning(0, "CIMD2[%s]: Truncating password to %d chars",
2409                 octstr_get_cstr(conn->id),
2410                 maxlen);
2411     }
2412 
2413     pdata->io_thread = gwthread_create(io_thread, conn);
2414 
2415     if (pdata->io_thread == -1) {
2416 
2417         error(0,"CIMD2[%s]: Couldn't start I/O thread.",
2418               octstr_get_cstr(conn->id));
2419         pdata->quitting = 1;
2420         gwthread_wakeup(pdata->io_thread);
2421         gwthread_join(pdata->io_thread);
2422         cimd2_destroy(pdata);
2423         return -1;
2424     }
2425 
2426     conn->send_msg = cimd2_add_msg_cb;
2427     conn->shutdown = cimd2_shutdown_cb;
2428     conn->queued = cimd2_queued_cb;
2429     conn->start_conn = cimd2_start_cb;
2430     conn->stop_conn = cimd2_stop_cb;
2431 
2432     return 0;
2433 }
2434 
2435