00001 /* ==================================================================== 00002 * The Kannel Software License, Version 1.0 00003 * 00004 * Copyright (c) 2001-2008 Kannel Group 00005 * Copyright (c) 1998-2001 WapIT Ltd. 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 00012 * 1. Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * 00015 * 2. Redistributions in binary form must reproduce the above copyright 00016 * notice, this list of conditions and the following disclaimer in 00017 * the documentation and/or other materials provided with the 00018 * distribution. 00019 * 00020 * 3. The end-user documentation included with the redistribution, 00021 * if any, must include the following acknowledgment: 00022 * "This product includes software developed by the 00023 * Kannel Group (http://www.kannel.org/)." 00024 * Alternately, this acknowledgment may appear in the software itself, 00025 * if and wherever such third-party acknowledgments normally appear. 00026 * 00027 * 4. The names "Kannel" and "Kannel Group" must not be used to 00028 * endorse or promote products derived from this software without 00029 * prior written permission. For written permission, please 00030 * contact org@kannel.org. 00031 * 00032 * 5. Products derived from this software may not be called "Kannel", 00033 * nor may "Kannel" appear in their name, without prior written 00034 * permission of the Kannel Group. 00035 * 00036 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 00037 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00038 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00039 * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS 00040 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 00041 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00042 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 00043 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00044 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 00045 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 00046 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00047 * ==================================================================== 00048 * 00049 * This software consists of voluntary contributions made by many 00050 * individuals on behalf of the Kannel Group. For more information on 00051 * the Kannel Group, please see <http://www.kannel.org/>. 00052 * 00053 * Portions of this software are based upon software originally written at 00054 * WapIT Ltd., Helsinki, Finland for the Kannel project. 00055 */ 00056 00057 #ifndef SMSCCONN_P_H 00058 #define SMSCCONN_P_H 00059 00060 /* SMSC Connection private header 00061 * 00062 * Defines internal private structure 00063 * 00064 * Kalle Marjola 2000 for project Kannel 00065 * 00066 00067 ADDING AND WORKING OF NEW SMS CENTER CONNECTIONS: 00068 00069 These are guidelines and rules for adding new SMSC Connections to 00070 Kannel. See file bb_smscconn_cb.h for callback function prototypes. 00071 00072 An SMSC Connection handler is free-formed module which only has the following 00073 rules: 00074 00075 1) Each new SMSC Connection MUST implement function 00076 smsc_xxx_create(SMSCConn *conn, CfgGrp *cfg), which: 00077 00078 a) SHOULD NOT block (XXX) 00079 b) MUST warn about any configuration group variables it does 00080 not support (XXX) 00081 c) MUST set up send_msg dynamic function to handle messages 00082 to-be-sent. This function MAY NOT block. This function MAY 00083 NOT destroy or alter the supplied message, but instead copy 00084 it if need to be stored 00085 d) CAN set up private shutdown function, which MAY NOT block 00086 e) SHOULD set private function to return number of queued messages 00087 to-be-sent inside the driver 00088 f) MUST set SMSCConn->name 00089 00090 2) Each SMSC Connection MUST call certain BB callback functions when 00091 certain things occur: 00092 00093 a) Each SMSC Connection MUST call callback function 00094 bb_smscconn_killed when it dies because it was put down earlier 00095 with bb_smscconn_shutdown or it simply cannot keep the connection 00096 up (wrong password etc. When killed, 00097 SMSC Connection MUST release all memory it has taken EXCEPT for 00098 the basic SMSCConn struct, which is laterwards released by the 00099 bearerbox. 00100 00101 b) When SMSC Connection receives a message from SMSC, it must 00102 create a new Msg from it and call bb_smscconn_received 00103 00104 c) When SMSC Connection has sent a message to SMSC, it MUST call 00105 callback function bb_smscconn_sent. The msg-parameter must be 00106 identical to msg supplied with smscconn_send, but it can be 00107 a duplicate of it 00108 00109 d) When SMSC Connection has failed to send a message to SMSC, it 00110 MUST call callback function bb_smscconn_send_failed with appropriate 00111 reason. The message supplied as with bb_smscconn_send 00112 00113 e) When SMSC Connection changes to SMSCCONN_ACTIVE, connection MUST 00114 call bb_smscconn_connected 00115 00116 3) SMSC Connection MUST fill up SMSCConn structure as needed to, and is 00117 responsible for any concurrency timings. SMSCConn->status MAY NOT be 00118 set to SMSCCONN_DEAD until the connection is really that. 00119 Use why_killed to make internally dead, supplied with reason. 00120 00121 If the connection is disconnected temporarily, the connection SHOULD 00122 call bb_smscconn_send_failed for each message in its internal list 00123 00124 4) When SMSC Connection shuts down (shutdown called), it MUST try to send 00125 all messages so-far relied to it to be sent if 'finish_sending' is set 00126 to non-zero. If set to 0, it MUST call bb_smscconn_send_failed 00127 for each message not yet sent. 00128 00129 After everything is ready (it can happen in different thread), before 00130 calling callback function bb_smscconn_killed it MUST release all memory it 00131 has taken except for basic SMSCConn structure, and set status to 00132 SMSCCONN_DEAD so it can be finally deleted. 00133 00134 5) Callback bb_smscconn_ready is automatically called by main 00135 smscconn_create. New implementation MAY NOT call it directly 00136 00137 6) SMSC Connection driver must obey is_stopped/stopped variable to 00138 suspend receiving (it can still send/re-connect), or must set 00139 appropriate function calls. When connection is stopped, it is not 00140 allowed to receive any new messages 00141 */ 00142 00143 #include <signal.h> 00144 #include "gwlib/gwlib.h" 00145 #include "gwlib/regex.h" 00146 #include "smscconn.h" 00147 00148 struct smscconn { 00149 /* variables set by appropriate SMSCConn driver */ 00150 smscconn_status_t status; /* see smscconn.h */ 00151 int load; /* load factor, 0 = no load */ 00152 smscconn_killed_t why_killed; /* time to die with reason, set when 00153 * shutdown called */ 00154 time_t connect_time; /* When connection to SMSC was established */ 00155 00156 Mutex *flow_mutex; /* used to lock SMSCConn structure (both 00157 * in smscconn.c and specific driver) */ 00158 00159 /* connection specific counters (created in smscconn.c, updated 00160 * by callback functions in bb_smscconn.c, NOT used by specific driver) */ 00161 Counter *received; 00162 Counter *sent; 00163 Counter *failed; 00164 00165 /* SMSCConn variables set in smscconn.c */ 00166 volatile sig_atomic_t is_stopped; 00167 00168 Octstr *name; /* Descriptive name filled from connection info */ 00169 Octstr *id; /* Abstract name specified in configuration and 00170 used for logging and routing */ 00171 List *allowed_smsc_id; 00172 List *denied_smsc_id; 00173 List *preferred_smsc_id; 00174 regex_t *allowed_smsc_id_regex; 00175 regex_t *denied_smsc_id_regex; 00176 regex_t *preferred_smsc_id_regex; 00177 00178 Octstr *allowed_prefix; 00179 regex_t *allowed_prefix_regex; 00180 Octstr *denied_prefix; 00181 regex_t *denied_prefix_regex; 00182 Octstr *preferred_prefix; 00183 regex_t *preferred_prefix_regex; 00184 Octstr *unified_prefix; 00185 00186 Octstr *our_host; /* local device IP to bind for TCP communication */ 00187 00188 /* Our smsc specific log-file data */ 00189 Octstr *log_file; 00190 long log_level; 00191 int log_idx; /* index position within the global logfiles[] array in gwlib/log.c */ 00192 00193 long reconnect_delay; /* delay in seconds while re-connect attempts */ 00194 00195 int alt_dcs; /* use alternate DCS 0xFX */ 00196 00197 double throughput; /* message thoughput per sec. to be delivered to SMSC */ 00198 00199 /* Stores rerouting information for this specific smsc-id */ 00200 int reroute; /* simply turn MO into MT and process internally */ 00201 Dict *reroute_by_receiver; /* reroute receiver numbers to specific smsc-ids */ 00202 Octstr *reroute_to_smsc; /* define a smsc-id to reroute to */ 00203 int reroute_dlr; /* should DLR's are rereouted too? */ 00204 00205 long max_sms_octets; /* max allowed octets for this SMSC */ 00206 00207 /* XXX: move rest global data from Smsc here 00208 */ 00209 00210 /* pointers set by specific driver, but initiated to NULL by smscconn. 00211 * Note that flow_mutex is always locked before these functions are 00212 * called, and released after execution returns from them */ 00213 00214 /* pointer to function called when smscconn_shutdown called. 00215 * Note that this function is not needed always. If set, this 00216 * function MUST set why_killed */ 00217 int (*shutdown) (SMSCConn *conn, int finish_sending); 00218 00219 /* pointer to function called when a new message is needed to be sent. 00220 * MAY NOT block. Connection MAY NOT use msg directly after it has 00221 * returned from this function, but must instead duplicate it if need to. 00222 */ 00223 int (*send_msg) (SMSCConn *conn, Msg *msg); 00224 00225 /* pointer to function which returns current number of queued 00226 * messages to-be-sent. The function CAN also set load factor directly 00227 * to SMSCConn structure (above) */ 00228 long (*queued) (SMSCConn *conn); 00229 00230 /* pointers to functions called when connection started/stopped 00231 * (suspend/resume), if not NULL */ 00232 00233 void (*start_conn) (SMSCConn *conn); 00234 void (*stop_conn) (SMSCConn *conn); 00235 00236 00237 void *data; /* SMSC specific stuff */ 00238 }; 00239 00240 /* 00241 * Initializers for various SMSC connection implementations, 00242 * each should take same arguments and return an int, 00243 * which is 0 for okay and -1 for error. 00244 * 00245 * Each function is responsible for setting up all dynamic 00246 * function pointers at SMSCConn structure and starting up any 00247 * threads it might need. 00248 * 00249 * If conn->is_stopped is set (!= 0), create function MUST set 00250 * its internal state as stopped, so that laterwards called 00251 * smscconn_start works fine (and until it is called, no messages 00252 * are received) 00253 */ 00254 00255 /* generic wrapper for old SMSC implementations (uses old smsc.h). 00256 * Responsible file: smsc/smsc_wrapper.c */ 00257 int smsc_wrapper_create(SMSCConn *conn, CfgGroup *cfg); 00258 00259 /* Responsible file: smsc/smsc_fake.c */ 00260 int smsc_fake_create(SMSCConn *conn, CfgGroup *cfg); 00261 00262 /* Responsible file: smsc/smsc_cimd2.c */ 00263 int smsc_cimd2_create(SMSCConn *conn, CfgGroup *cfg); 00264 00265 /* Responsible file: smsc/smsc_emi.c */ 00266 int smsc_emi2_create(SMSCConn *conn, CfgGroup *cfg); 00267 00268 /* Responsible file: smsc/smsc_http.c */ 00269 int smsc_http_create(SMSCConn *conn, CfgGroup *cfg); 00270 00271 /* Responsible file: smsc/smsc_smpp.c */ 00272 int smsc_smpp_create(SMSCConn *conn, CfgGroup *cfg); 00273 00274 /* Responsible file: smsc/smsc_cgw.c */ 00275 int smsc_cgw_create(SMSCConn *conn, CfgGroup *cfg); 00276 00277 /* Responsible file: smsc/smsc_at.c. */ 00278 int smsc_at2_create(SMSCConn *conn, CfgGroup *cfg); 00279 00280 /* Responsible file: smsc/smsc_smasi.c */ 00281 int smsc_smasi_create(SMSCConn *conn, CfgGroup *cfg); 00282 00283 /* Responsible file: smsc/smsc_oisd.c */ 00284 int smsc_oisd_create(SMSCConn *conn, CfgGroup *cfg); 00285 00286 /* ADD NEW CREATE FUNCTIONS HERE 00287 * 00288 * int smsc_xxx_create(SMSCConn *conn, CfgGroup *cfg); 00289 */ 00290 00291 00292 #endif