Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
dlr_mem.c
Go to the documentation of this file.
1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2016 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/dlr_mem.c
59  *
60  * Implementation of handling delivery reports (DLRs)
61  * in memory
62  *
63  * Andreas Fink <andreas@fink.org>, 18.08.2001
64  * Stipe Tolj <stolj@wapme.de>, 22.03.2002
65  * Alexander Malysh <a.malysh@centrium.de> 2003
66  */
67 
68 #include "gwlib/gwlib.h"
69 #include "dlr_p.h"
70 
71 /*
72  * This is the global list where all messages being sent out are being kept track
73  * of his list is looked up once a delivery report comes in
74  */
76 static RWLock rwlock;
77 
78 /*
79  * Destroy dlr_waiting_list.
80  */
81 static void dlr_mem_shutdown()
82 {
83  gw_rwlock_wrlock(&rwlock);
85  gw_rwlock_unlock(&rwlock);
86  gw_rwlock_destroy(&rwlock);
87 }
88 
89 /*
90  * Get count of dlr messages waiting.
91  */
92 static long dlr_mem_messages(void)
93 {
94  return gwlist_len(dlr_waiting_list);
95 }
96 
97 static void dlr_mem_flush(void)
98 {
99  long i;
100  long len;
101 
102  gw_rwlock_wrlock(&rwlock);
103  len = gwlist_len(dlr_waiting_list);
104  for (i = 0; i < len; i++) {
105  struct dlr_entry *dlr = gwlist_get(dlr_waiting_list, 0);
106  gwlist_delete(dlr_waiting_list, 0, 1);
107  dlr_entry_destroy(dlr);
108  }
109  gw_rwlock_unlock(&rwlock);
110 }
111 
112 /*
113  * add struct dlr_entry to list
114  */
115 static void dlr_mem_add(struct dlr_entry *dlr)
116 {
117  gw_rwlock_wrlock(&rwlock);
118  gwlist_append(dlr_waiting_list,dlr);
119  gw_rwlock_unlock(&rwlock);
120 }
121 
122 /*
123  * Private compare function
124  * Return 0 if entry match and 1 if not.
125  */
126 static int dlr_mem_entry_match(struct dlr_entry *dlr, const Octstr *smsc, const Octstr *ts, const Octstr *dst)
127 {
128  /* XXX: check destination addr too, because e.g. for UCP is not enough to check only
129  * smsc and timestamp (timestamp is even without milliseconds)
130  */
131  if (dst){
132  long pos = octstr_len(dlr->destination) - octstr_len(dst);
133 
134  if (pos < 0)
135  return 1;
136 
137  if (octstr_compare(dlr->smsc, smsc) == 0 && octstr_compare(dlr->timestamp, ts) == 0 && octstr_search(dlr->destination, dst, pos) != -1)
138  return 0;
139  } else if (octstr_compare(dlr->smsc, smsc) == 0 && octstr_compare(dlr->timestamp, ts) == 0)
140  return 0;
141 
142  return 1;
143 }
144 
145 /*
146  * Find matching entry and return copy of it, otherwise NULL
147  */
148 static struct dlr_entry *dlr_mem_get(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
149 {
150  long i;
151  long len;
152  struct dlr_entry *dlr = NULL, *ret = NULL;
153 
154  gw_rwlock_rdlock(&rwlock);
155  len = gwlist_len(dlr_waiting_list);
156  for (i=0; i < len; i++) {
157  dlr = gwlist_get(dlr_waiting_list, i);
158 
159  if (dlr_mem_entry_match(dlr, smsc, ts, dst) == 0) {
160  ret = dlr_entry_duplicate(dlr);
161  break;
162  }
163  }
164  gw_rwlock_unlock(&rwlock);
165 
166  /* we couldnt find a matching entry */
167  return ret;
168 }
169 
170 /*
171  * Remove matching entry
172  */
173 static void dlr_mem_remove(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
174 {
175  long i;
176  long len;
177  struct dlr_entry *dlr = NULL;
178 
179  gw_rwlock_wrlock(&rwlock);
180  len = gwlist_len(dlr_waiting_list);
181  for (i=0; i < len; i++) {
182  dlr = gwlist_get(dlr_waiting_list, i);
183 
184  if (dlr_mem_entry_match(dlr, smsc, ts, dst) == 0) {
185  gwlist_delete(dlr_waiting_list, i, 1);
186  dlr_entry_destroy(dlr);
187  break;
188  }
189  }
190  gw_rwlock_unlock(&rwlock);
191 }
192 
193 static struct dlr_storage handles = {
194  .type = "internal",
195  .dlr_add = dlr_mem_add,
196  .dlr_get = dlr_mem_get,
197  .dlr_remove = dlr_mem_remove,
198  .dlr_shutdown = dlr_mem_shutdown,
199  .dlr_messages = dlr_mem_messages,
200  .dlr_flush = dlr_mem_flush
201 };
202 
203 /*
204  * Initialize dlr_waiting_list and return out storage handles.
205  */
207 {
208  dlr_waiting_list = gwlist_create();
209  gw_rwlock_init_static(&rwlock);
210 
211  return &handles;
212 }
const char * type
Definition: dlr_p.h:112
void gwlist_append(List *list, void *item)
Definition: list.c:179
struct dlr_entry * dlr_entry_duplicate(const struct dlr_entry *dlr)
Definition: dlr.c:119
long gwlist_len(List *list)
Definition: list.c:166
void gw_rwlock_destroy(RWLock *lock)
Definition: gw-rwlock.c:112
static struct dlr_storage handles
Definition: dlr_mem.c:193
int gw_rwlock_wrlock(RWLock *lock)
Definition: gw-rwlock.c:177
void * gwlist_get(List *list, long pos)
Definition: list.c:292
static void dlr_mem_flush(void)
Definition: dlr_mem.c:97
static void dlr_mem_add(struct dlr_entry *dlr)
Definition: dlr_mem.c:115
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1068
struct dlr_storage * dlr_init_mem(Cfg *cfg)
Definition: dlr_mem.c:206
int gw_rwlock_rdlock(RWLock *lock)
Definition: gw-rwlock.c:134
void gwlist_item_destructor_t(void *item)
Definition: list.h:129
Definition: cfg.c:164
static long dlr_mem_messages(void)
Definition: dlr_mem.c:92
void gwlist_delete(List *list, long pos, long count)
Definition: list.c:232
static void dlr_mem_shutdown()
Definition: dlr_mem.c:81
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
Octstr * timestamp
Definition: dlr_p.h:80
static void dlr_mem_remove(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
Definition: dlr_mem.c:173
static Cfg * cfg
Definition: smsbox.c:115
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Octstr * destination
Definition: dlr_p.h:82
Definition: octstr.c:118
void dlr_entry_destroy(struct dlr_entry *dlr)
Definition: dlr.c:142
static int dlr_mem_entry_match(struct dlr_entry *dlr, const Octstr *smsc, const Octstr *ts, const Octstr *dst)
Definition: dlr_mem.c:126
#define gwlist_create()
Definition: list.h:136
static RWLock rwlock
Definition: dlr_mem.c:76
Definition: dlr_p.h:78
Octstr * smsc
Definition: dlr_p.h:79
void gw_rwlock_init_static(RWLock *lock)
Definition: gw-rwlock.c:96
static List * dlr_waiting_list
Definition: dlr_mem.c:75
Definition: list.c:102
static struct dlr_entry * dlr_mem_get(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
Definition: dlr_mem.c:148
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.