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