Kannel: Open Source WAP and SMS gateway  svn-r5335
smsc_at.h
Go to the documentation of this file.
1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2018 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 {
106  long speed;
109  int no_pin;
110  int no_smsc;
113  int broken;
118 } ModemDef;
119 
120 typedef struct PrivAT2data {
124  int shutdown; /* Internal signal to shut down */
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 */
136  int retry;
152  int is_serial; /* false if device is rawtcp */
153  int use_telnet; /* use telnet escape sequences */
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  */
171 
172 /*
173  * close the specified device and hence disconnect from the serial line
174  */
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);
205 static int at2_write(PrivAT2data *privdata, char *line);
206 
207 /*
208  * Clears incoming buffer
209  */
211 
212 /*
213  * Initializes the device after being opened, detects the modem type,
214  * sets speed settings etc.
215  * On failure returns -1.
216  */
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  */
280 
281 /*
282  * Decode a SUBMIT-REPORT PDU
283  */
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  */
301 
302 /*
303  * Sends a single message.
304  * After having it sent, the msg is no longe belonging to us
305  */
307 
308 /*
309  * Encode a Msg into a PDU
310  */
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  */
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  */
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  */
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  */
357 
358 /*
359  * Memory capacity and usage check
360  */
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  */
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 
Octstr * detect_string2
Definition: smsc_at.h:103
static Octstr * at2_convertpdu(Octstr *pdutext)
long device_thread
Definition: smsc_at.h:123
static int at2_numtext(int num)
static int at2_open_device(PrivAT2data *privdata)
static ModemDef * at2_read_modems(PrivAT2data *privdata, Octstr *file, Octstr *id, int idnumber)
Octstr * my_number
Definition: smsc_at.h:137
Octstr * ilb
Definition: smsc_at.h:129
Octstr * password_prompt
Definition: smsc_at.h:144
gw_prioqueue_t * outgoing_queue
Definition: smsc_at.h:121
static int at2_write_line(PrivAT2data *privdata, char *line)
static Msg * at2_pdu_decode_report_sm(Octstr *data, PrivAT2data *privdata)
static int at2_test_speed(PrivAT2data *privdata, long speed)
int use_telnet
Definition: smsc_at.h:153
struct ModemDef ModemDef
int no_pin
Definition: smsc_at.h:109
static int at2_detect_modem_type(PrivAT2data *privdata)
int retry
Definition: smsc_at.h:136
long keepalive
Definition: smsc_at.h:127
int code
Definition: smsc_cimd2.c:346
int smsc_at2_create(SMSCConn *conn, CfgGroup *cfg)
Definition: smsc_at.c:1519
Octstr * init_string
Definition: smsc_at.h:104
static long at2_queued_cb(SMSCConn *conn)
int sms_memory_capacity
Definition: smsc_at.h:146
static int at2_read_delete_message(PrivAT2data *privdata, int message_number)
Octstr * login_prompt
Definition: smsc_at.h:143
static int at2_check_sms_memory(PrivAT2data *privdata)
static Cfg * cfg
Definition: opensmppbox.c:95
ModemDef * modem
Definition: smsc_at.h:122
Octstr * configfile
Definition: smsc_at.h:140
int phase2plus
Definition: smsc_at.h:134
int hardware_flow_control
Definition: smsc_at.h:117
FILE * file
Definition: log.c:169
Octstr * pin
Definition: smsc_at.h:131
Octstr * validityperiod
Definition: smsc_at.h:135
int shutdown
Definition: smsc_at.h:124
static Octstr * at2_encode8bituncompressed(Octstr *input)
static int at2_read_sms_memory(PrivAT2data *privdata)
static Msg * at2_pdu_decode_deliver_sm(Octstr *data, PrivAT2data *privdata)
static void at2_flush_buffer(PrivAT2data *privdata)
int sms_memory_poll_interval
Definition: smsc_at.h:145
static int at2_init_device(PrivAT2data *privdata)
int pin_ready
Definition: smsc_at.h:132
static int at2_shutdown_cb(SMSCConn *conn, int finish_sending)
static int at2_write(PrivAT2data *privdata, char *line)
int broken
Definition: smsc_at.h:113
long speed
Definition: smsc_at.h:126
Definition: msg.h:79
static int swap_nibbles(unsigned char byte)
static const char * at2_error_string(int code)
int rawtcp_port
Definition: smsc_at.h:151
Octstr * reset_string
Definition: smsc_at.h:105
static int at2_detect_speed(PrivAT2data *privdata)
Octstr * message_storage
Definition: smsc_at.h:114
static void at2_read_pending_incoming_messages(PrivAT2data *privdata)
static void at2_close_device(PrivAT2data *privdata)
long speed
Definition: smsc_at.h:106
static int at2_set_message_storage(PrivAT2data *privdata, Octstr *memory_name)
Octstr * detect_string
Definition: smsc_at.h:102
long message_start
Definition: smsc_at.h:115
static Octstr * at2_wait_line(PrivAT2data *privdata, time_t timeout, int gt_flag)
Octstr * sms_center
Definition: smsc_at.h:138
int is_serial
Definition: smsc_at.h:152
long sendline_sleep
Definition: smsc_at.h:111
static int at2_add_msg_cb(SMSCConn *conn, Msg *sms)
static void at2_send_one_message(PrivAT2data *privdata, Msg *msg)
int sms_memory_usage
Definition: smsc_at.h:147
static Octstr * at2_pdu_encode(Msg *msg, PrivAT2data *privdata)
static Octstr * at2_format_address_field(Octstr *msisdn)
Octstr * name
Definition: smsc_at.h:101
long max_error_count
Definition: smsc_at.h:149
static int at2_hexchar(int hexc)
static void at2_send_messages(PrivAT2data *privdata)
Octstr * rawtcp_host
Definition: smsc_at.h:150
static int at2_send_modem_command(PrivAT2data *privdata, char *cmd, time_t timeout, int greaterflag)
Octstr * id
Definition: smsc_at.h:100
Octstr * enable_hwhs
Definition: smsc_at.h:107
Octstr * name
Definition: smsc_at.h:139
Octstr * lines
Definition: smsc_at.h:130
Definition: octstr.c:118
static Octstr * at2_read_line(PrivAT2data *privdata, int gt_flag, double timeout)
List * pending_incoming_messages
Definition: smsc_at.h:148
static void at2_set_speed(PrivAT2data *privdata, int bps)
int need_sleep
Definition: smsc_at.h:108
static int at2_wait_modem_command(PrivAT2data *privdata, time_t timeout, int greaterflag, int *output)
static Msg * at2_pdu_decode(Octstr *data, PrivAT2data *privdata)
static int at2_write_ctrlz(PrivAT2data *privdata)
Definition: cfg.c:73
static void at2_device_thread(void *arg)
Octstr * keepalive_cmd
Definition: smsc_at.h:112
Definition: load.c:76
static Octstr * at2_encode7bituncompressed(Octstr *input, int offset)
Octstr * password
Definition: smsc_at.h:142
static void at2_destroy_modem(ModemDef *modem)
static void at2_read_buffer(PrivAT2data *privdata, double timeout)
struct PrivAT2data PrivAT2data
static int at2_pdu_extract(PrivAT2data *privdata, Octstr **pdu, Octstr *line, Octstr *smsc_number)
Octstr * device
Definition: smsc_at.h:125
static void at2_start_cb(SMSCConn *conn)
static void at2_decode7bituncompressed(Octstr *input, int len, Octstr *decoded, int offset)
Octstr * username
Definition: smsc_at.h:141
int enable_mms
Definition: smsc_at.h:116
Load * load
Definition: smsc_at.h:154
Definition: list.c:102
SMSCConn * conn
Definition: smsc_at.h:133
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
int no_smsc
Definition: smsc_at.h:110
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.