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 /*
58  * gw/smsc_at.h
59  *
60  * New driver for serial connected AT based
61  * devices.
62  * 4.9.2001
63  * Andreas Fink <afink@smsrelay.com>
64  *
65  */
66 
67 #ifndef SMSC_AT2_H
68 #define SMSC_AT2_H
69 
70 #include "gwlib/gwlib.h"
71 #include "load.h"
72 
73 /* maximum data to attempt to read in one go */
74 #define	MAX_READ        1023
75 
76 /* Message types defines */
77 #define AT_DELIVER_SM   0
78 #define AT_SUBMIT_SM    1
79 #define AT_STATUS_REPORT_SM 2
80 
81 /* type of phone number defines */
82 #define PNT_UNKNOWN     0
83 #define PNT_INTER       1
84 #define PNT_NATIONAL    2
85 
86 /* The number of times to attempt to write a line should writing fail */
87 #define RETRY_WRITE 3
88 
89 /*
90  * defines for use with the so-called "SIM buffering techinique":
91  * once in how many seconds to poll the memory locations,
92  * if keepalive is _not_ set (will use keepalive time if set)
93  */
94 #define AT2_DEFAULT_SMS_POLL_INTERVAL	60
95 
96 /*
97  * Structures used in at2
98  */
99 typedef struct ModemDef {
100     Octstr *id;
101     Octstr *name;
102     Octstr *detect_string;
103     Octstr *detect_string2;
104     Octstr *init_string;
105     Octstr *reset_string;
106     long speed;
107     Octstr *enable_hwhs;
108     int	need_sleep;
109     int	no_pin;
110     int	no_smsc;
111     long sendline_sleep;
112     Octstr *keepalive_cmd;
113     int	broken;
114     Octstr *message_storage;
115     long message_start;
116     int	enable_mms;
117     int	hardware_flow_control;
118 } ModemDef;
119 
120 typedef struct PrivAT2data {
121     gw_prioqueue_t *outgoing_queue;
122     ModemDef *modem;
123     long device_thread;
124     int	shutdown; /* Internal signal to shut down */
125     Octstr *device;
126     long speed;
127     long keepalive;
128     int	fd;	/* file descriptor */
129     Octstr *ilb; /* input line buffer */
130     Octstr *lines; /* the last few lines before OK was seen */
131     Octstr *pin; /* PIN code */
132     int	pin_ready;
133     SMSCConn *conn;
134     int phase2plus;
135     Octstr *validityperiod;
136     int retry;
137     Octstr *my_number;
138     Octstr *sms_center;
139     Octstr *name;
140     Octstr *configfile;
141     Octstr *username;
142     Octstr *password;
143     Octstr *login_prompt;
144     Octstr *password_prompt;
145     int	sms_memory_poll_interval;
146     int	sms_memory_capacity;
147     int	sms_memory_usage;
148     List *pending_incoming_messages;
149     long max_error_count;
150     Octstr *rawtcp_host;
151     int rawtcp_port;
152     int is_serial; /* false if device is rawtcp */
153     int use_telnet; /* use telnet escape sequences */
154     Load *load;
155  } PrivAT2data;
156 
157 
158 /*
159  * Macro that is used inside smsc_at2.c in order to handle
160  * octstr destruction more carefully.
161  */
162 #define	O_DESTROY(a) { if(a) octstr_destroy(a); a = NULL; }
163 /*
164 #define	at2_write_ctrlz(a) at2_write(a,"\032")
165 */
166 
167 /*
168  * open the specified device using the serial line
169  */
170 static int at2_open_device(PrivAT2data *privdata);
171 
172 /*
173  * close the specified device and hence disconnect from the serial line
174  */
175 static void at2_close_device(PrivAT2data *privdata);
176 
177 /*
178  * checks if there are any incoming bytes and adds them to the line buffer
179  */
180 static void at2_read_buffer(PrivAT2data *privdata, double timeout);
181 
182 /*
183  * Looks for a full line to be read from the buffer.
184  * Returns the line and removes it from the buffer or if no full line
185  * is yet received waits until the line is there or a timeout occurs.
186  * If gt_flag is set, it is also looking for a line containing '>' even
187  * there is no CR yet.
188  */
189 static Octstr *at2_wait_line(PrivAT2data *privdata, time_t timeout, int gt_flag);
190 
191 /*
192  * Looks for a full line to be read from the buffer.
193  * Returns the line and removes it from the buffer or if no full line
194  * is yet received returns NULL. If gt_flag is set, it is also looking for
195  * a line containing > even there is no CR yet.
196  */
197 static Octstr *at2_read_line(PrivAT2data *privdata, int gt_flag, double timeout);
198 
199 /*
200  * Writes a line out to the device and adds a carriage return/linefeed to it.
201  * Returns number of characters sent.
202  */
203 static int at2_write_line(PrivAT2data *privdata, char *line);
204 static int at2_write_ctrlz(PrivAT2data *privdata);
205 static int at2_write(PrivAT2data *privdata, char *line);
206 
207 /*
208  * Clears incoming buffer
209  */
210 static void at2_flush_buffer(PrivAT2data *privdata);
211 
212 /*
213  * Initializes the device after being opened, detects the modem type,
214  * sets speed settings etc.
215  * On failure returns -1.
216  */
217 static int at2_init_device(PrivAT2data *privdata);
218 
219 /*
220  * Sends an AT command to the modem and waits for a reply
221  * Return values are:
222  *   0 = OK
223  *   1 = ERROR
224  *   2 = SIM PIN
225  *   3 = >
226  *   4 = READY
227  *   5 = CMGS
228  *  -1 = timeout occurred
229  */
230 static int at2_send_modem_command(PrivAT2data *privdata, char *cmd, time_t timeout,
231                            int greaterflag);
232 
233 /*
234  * Waits for the modem to send us something.
235  */
236 static int at2_wait_modem_command(PrivAT2data *privdata, time_t timeout,
237                            int greaterflag, int *output);
238 
239 /*
240  * Sets the serial port speed on the device
241  */
242 static void at2_set_speed(PrivAT2data *privdata, int bps);
243 
244 /*
245  * This is the main tread "sitting" on the device.
246  * Its task is to initialize the modem then wait for messages
247  * to arrive or to be sent
248  */
249 static void at2_device_thread(void *arg);
250 
251 static int at2_shutdown_cb(SMSCConn *conn, int finish_sending);
252 static long at2_queued_cb(SMSCConn *conn);
253 static void at2_start_cb(SMSCConn *conn);
254 static int at2_add_msg_cb(SMSCConn *conn, Msg *sms);
255 
256 /*
257  * Starts the whole thing up
258  */
259 int smsc_at2_create(SMSCConn *conn, CfgGroup *cfg);
260 
261 /*
262  * Extracts the first PDU in the string
263  */
264 static int at2_pdu_extract(PrivAT2data *privdata, Octstr **pdu, Octstr *line, Octstr *smsc_number);
265 
266 /*
267  * Get the numeric value of the text hex
268  */
269 static int at2_hexchar(int hexc);
270 
271 /*
272  * Decode a raw PDU into a Msg
273  */
274 static Msg *at2_pdu_decode(Octstr *data, PrivAT2data *privdata);
275 
276 /*
277  * Decode a DELIVER PDU
278  */
279 static Msg *at2_pdu_decode_deliver_sm(Octstr *data, PrivAT2data *privdata);
280 
281 /*
282  * Decode a SUBMIT-REPORT PDU
283  */
284 static Msg *at2_pdu_decode_report_sm(Octstr *data, PrivAT2data *privdata);
285 
286 /*
287  * Converts the text representation of hexa to binary
288  */
289 static Octstr *at2_convertpdu(Octstr *pdutext);
290 
291 /*
292  * Decode 7bit uncompressed user data
293  */
294 static void at2_decode7bituncompressed(Octstr *input, int len, Octstr *decoded,
295                                 int offset);
296 
297 /*
298  * Sends messages from the queue
299  */
300 static void at2_send_messages(PrivAT2data *privdata);
301 
302 /*
303  * Sends a single message.
304  * After having it sent, the msg is no longe belonging to us
305  */
306 static void at2_send_one_message(PrivAT2data *privdata, Msg *msg);
307 
308 /*
309  * Encode a Msg into a PDU
310  */
311 static Octstr *at2_pdu_encode(Msg *msg, PrivAT2data *privdata);
312 
313 /*
314  * Encode 7bit uncompressed user data into an Octstr, prefixing with <offset> 0 bits
315  */
316 static Octstr *at2_encode7bituncompressed(Octstr *input, int offset);
317 
318 /*
319  * Encode 8bit uncompressed user data into an Octstr
320  */
321 static Octstr *at2_encode8bituncompressed(Octstr *input);
322 
323 /*
324  * Code a half-byte to its text hexa representation
325  */
326 static int at2_numtext(int num);
327 
328 /*
329  * Try to detect modem speeds
330  */
331 static int at2_detect_speed(PrivAT2data *privdata);
332 
333 /*
334  * Test modem speed
335  */
336 static int at2_test_speed(PrivAT2data *privdata, long speed);
337 
338 /*
339  * Try to detect modem type
340  */
341 static int at2_detect_modem_type(PrivAT2data *privdata);
342 
343 /*
344  * Read all defined modems from the included modem definition file
345  */
346 static ModemDef *at2_read_modems(PrivAT2data *privdata, Octstr *file, Octstr *id, int idnumber);
347 
348 /*
349  * Destroy the ModemDef structure components
350  */
351 static void at2_destroy_modem(ModemDef *modem);
352 
353 /*
354  * Checks whether any messages are buffered in message storage and extract them.
355  */
356 static int at2_read_sms_memory(PrivAT2data *privdata);
357 
358 /*
359  * Memory capacity and usage check
360  */
361 static int at2_check_sms_memory(PrivAT2data *privdata);
362 
363 /*
364  * This silly thing here will just translate a "swapped nibble"
365  * pseodo Hex encoding (from PDU) into something that people can
366  * actually understand.
367  * Implementation completly ripped off Dennis Malmstrom timestamp
368  * patches against 1.0.3. Thanks Dennis!
369  */
370 static int swap_nibbles(unsigned char byte);
371 
372 /*
373  * creates a buffer with a valid PDU address field as per [GSM 03.40]
374  * from an MSISDN number
375  */
376 static Octstr *at2_format_address_field(Octstr *msisdn);
377 
378 /*
379  * Check the pending_incoming_messages queue for CMTI notifications.
380  * Every notification is parsed and the messages are read (and deleted)
381  * accordingly.
382  */
383 static void at2_read_pending_incoming_messages(PrivAT2data *privdata);
384 
385 /*
386  * Set the memory storage location of the modem by sending a +CPMS command
387  */
388 static int at2_set_message_storage(PrivAT2data *privdata, Octstr *memory_name);
389 
390 /*
391  * Reads a message from selected memory location and deletes it afterwards.
392  * returns 0 on failure and 1 on success
393  */
394 static int at2_read_delete_message(PrivAT2data *privdata, int message_number);
395 
396 /*
397  * Return appropriate error string for the given error code.
398  */
399 static const char *at2_error_string(int code);
400 
401 #endif /* SMSC_AT2_H */
402 
403