Kannel: Open Source WAP and SMS gateway  svn-r5335
wtp_pack.c
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 includPd with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software eveloped by the
23  * Kann†l 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  * wtp_pack.c - WTP message packing module implementation
59  *
60  * By Aarno Syvänen for WapIT Ltd.
61  */
62 
63 #include "gwlib/gwlib.h"
64 #include "wtp_pack.h"
65 #include "wtp_pdu.h"
66 
67 
68 /*
69  * Readable names for octets
70  */
71 enum {
76 };
77 
78 /*
79  * Types of header information added by the user (TPIs, or transportation
80  * information items).
81  */
82 enum {
83  ERROR_DATA = 0x00,
84  INFO_DATA = 0x01,
85  OPTION = 0x02,
87  SDU_BOUNDARY = 0x04,
89 };
90 
91 /*****************************************************************************
92  *
93  * Prototypes of internal functions
94  */
95 
96 /*
97  * WTP defines SendTID and RcvTID. We should use SendTID in all PDUs
98  * we send. The RcvTID is the one we got from the initial Invoke and
99  * is the one we expect on all future PDUs for this machine.
100  * SendTID is always RcvTID xor 0x8000.
101  *
102  * Note that when we are the Initiator, for example with WSP PUSH,
103  * we must still store the RcvTID in machine->tid, to be consistent
104  * with the current code. So we'll choose the SendTID and then calculate
105  * the RcvTID.
106  */
107 static unsigned short send_tid(unsigned short tid);
108 
109 /*****************************************************************************
110  *
111  * EXTERNAL FUNCTIONS:
112  *
113  */
114 
116 {
117  WAPEvent *dgram = NULL;
118  WTP_PDU *pdu = NULL;
119 
120  gw_assert(event->type == TR_Invoke_Req);
121  pdu = wtp_pdu_create(Invoke);
122  pdu->u.Invoke.con = 0;
123  pdu->u.Invoke.gtr = 1;
124  pdu->u.Invoke.ttr = 1;
125  pdu->u.Invoke.rid = 0;
126  pdu->u.Invoke.version = 0;
127  pdu->u.Invoke.tid = send_tid(machine->tid);
128  pdu->u.Invoke.tidnew = machine->tidnew;
129  pdu->u.Invoke.user_data =
130  octstr_duplicate(event->u.TR_Invoke_Req.user_data);
131  pdu->u.Invoke.class = event->u.TR_Invoke_Req.tcl;
132  pdu->u.Invoke.uack = event->u.TR_Invoke_Req.up_flag;
133 
134  dgram = wap_event_create(T_DUnitdata_Req);
135  dgram->u.T_DUnitdata_Req.addr_tuple =
136  wap_addr_tuple_duplicate(machine->addr_tuple);
137  dgram->u.T_DUnitdata_Req.user_data = wtp_pdu_pack(pdu);
138  wtp_pdu_destroy(pdu);
139 
140  return dgram;
141 }
142 
144 {
145  WAPEvent *dgram = NULL;
146  WTP_PDU *pdu = NULL;
147 
148  gw_assert(event->type == TR_Result_Req);
149  pdu = wtp_pdu_create(Result);
150  pdu->u.Result.con = 0;
151  pdu->u.Result.gtr = 1;
152  pdu->u.Result.ttr = 1;
153  pdu->u.Result.rid = 0;
154  pdu->u.Result.tid = send_tid(machine->tid);
155  pdu->u.Result.user_data =
156  octstr_duplicate(event->u.TR_Result_Req.user_data);
157 
158  dgram = wap_event_create(T_DUnitdata_Req);
159  dgram->u.T_DUnitdata_Req.addr_tuple =
160  wap_addr_tuple_duplicate(machine->addr_tuple);
161  dgram->u.T_DUnitdata_Req.user_data = wtp_pdu_pack(pdu);
162  wtp_pdu_destroy(pdu);
163 
164  return dgram;
165 }
166 
168 {
169  WAPEvent *dgram = NULL;
170  WTP_PDU *pdu = NULL;
171  Octstr *data = NULL;
172  int gtr, ttr;
173 
174  gw_assert(machine->sar && machine->sar->data);
175 
176  if (psn > machine->sar->nsegm)
177  return dgram;
178 
179  ttr = psn == machine->sar->nsegm ? 1 : 0;
180  gtr = ttr ? 0 : (psn+1)%SAR_GROUP_LEN ? 0 : 1;
181 
182  if (gtr || ttr)
183  machine->sar->tr = 1;
184 
185  data = octstr_copy(machine->sar->data,psn*SAR_SEGM_SIZE,SAR_SEGM_SIZE);
186 
187  if (!psn) {
188  pdu = wtp_pdu_create(Result);
189  pdu->u.Result.con = 0;
190  pdu->u.Result.gtr = gtr;
191  pdu->u.Result.ttr = ttr;
192  pdu->u.Result.rid = 0;
193  pdu->u.Result.tid = send_tid(machine->tid);
194  pdu->u.Result.user_data = data;
195  } else {
196  pdu = wtp_pdu_create(Segmented_result);
197  pdu->u.Segmented_result.con = 0;
198  pdu->u.Segmented_result.gtr = gtr;
199  pdu->u.Segmented_result.ttr = ttr;
200  pdu->u.Segmented_result.rid = 0;
201  pdu->u.Segmented_result.tid = send_tid(machine->tid);
202  pdu->u.Segmented_result.psn = psn;
203  pdu->u.Segmented_result.user_data = data;
204  }
205 
206  dgram = wap_event_create(T_DUnitdata_Req);
207  dgram->u.T_DUnitdata_Req.addr_tuple =
208  wap_addr_tuple_duplicate(machine->addr_tuple);
209  dgram->u.T_DUnitdata_Req.user_data = wtp_pdu_pack(pdu);
210  wtp_pdu_destroy(pdu);
211 
212  return dgram;
213 }
214 
215 void wtp_pack_set_rid(WAPEvent *dgram, long rid)
216 {
217  gw_assert(dgram != NULL);
218  gw_assert(dgram->type == T_DUnitdata_Req);
219 
220  octstr_set_bits(dgram->u.T_DUnitdata_Req.user_data, 7, 1, rid);
221 }
222 
223 WAPEvent *wtp_pack_abort(long abort_type, long abort_reason, long tid,
224  WAPAddrTuple *address)
225 {
226  WAPEvent *dgram;
227  WTP_PDU *pdu;
228 
229  pdu = wtp_pdu_create(Abort);
230  pdu->u.Abort.con = 0;
231  pdu->u.Abort.abort_type = abort_type;
232  pdu->u.Abort.tid = send_tid(tid);
233  pdu->u.Abort.abort_reason = abort_reason;
234 
235  dgram = wap_event_create(T_DUnitdata_Req);
236  dgram->u.T_DUnitdata_Req.addr_tuple = wap_addr_tuple_duplicate(address);
237  dgram->u.T_DUnitdata_Req.user_data = wtp_pdu_pack(pdu);
238  wtp_pdu_destroy(pdu);
239 
240  return dgram;
241 }
242 
243 WAPEvent *wtp_pack_ack(long ack_type, int rid_flag, long tid,
244  WAPAddrTuple *address)
245 {
246  WAPEvent *dgram = NULL;
247  WTP_PDU *pdu;
248 
249  pdu = wtp_pdu_create(Ack);
250  pdu->u.Ack.con = 0;
251  pdu->u.Ack.tidverify = ack_type;
252  pdu->u.Ack.rid = rid_flag;
253  pdu->u.Ack.tid = send_tid(tid);
254 
255  dgram = wap_event_create(T_DUnitdata_Req);
256  dgram->u.T_DUnitdata_Req.addr_tuple = wap_addr_tuple_duplicate(address);
257  dgram->u.T_DUnitdata_Req.user_data = wtp_pdu_pack(pdu);
258  wtp_pdu_destroy(pdu);
259 
260  return dgram;
261 }
262 
263 WAPEvent *wtp_pack_sar_ack(long ack_type, long tid, WAPAddrTuple *address, int psn)
264 {
265  WAPEvent *dgram = NULL;
266  WTP_PDU *pdu;
267  unsigned char cpsn = psn;
268 
269  pdu = wtp_pdu_create(Ack);
270  pdu->u.Ack.con = 1;
271  pdu->u.Ack.tidverify = ack_type;
272  pdu->u.Ack.rid = 0;
273  pdu->u.Ack.tid = send_tid(tid);
274 
275  wtp_pdu_append_tpi(pdu, 3, octstr_create_from_data((char*) &cpsn, 1));
276 
277  dgram = wap_event_create(T_DUnitdata_Req);
278  dgram->u.T_DUnitdata_Req.addr_tuple = wap_addr_tuple_duplicate(address);
279  dgram->u.T_DUnitdata_Req.user_data = wtp_pdu_pack(pdu);
280  wtp_pdu_destroy(pdu);
281 
282  return dgram;
283 }
284 
285 /****************************************************************************
286  *
287  * INTERNAL FUNCTIONS:
288  *
289  */
290 
291 static unsigned short send_tid(unsigned short tid)
292 {
293  return tid ^ 0x8000;
294 }
295 
296 /****************************************************************************/
297 
298 
299 
300 
301 
302 
303 
304 
WAPEvent * wtp_pack_sar_result(WTPRespMachine *machine, int psn)
Definition: wtp_pack.c:167
WTP_PDU * wtp_pdu_create(int type)
Definition: wtp_pdu.c:67
void wtp_pdu_append_tpi(WTP_PDU *pdu, int type, Octstr *data)
Definition: wtp_pdu.c:153
gw_assert(wtls_machine->packet_to_send !=NULL)
static unsigned short send_tid(unsigned short tid)
Definition: wtp_pack.c:291
void octstr_set_bits(Octstr *ostr, long bitpos, int numbits, unsigned long value)
Definition: octstr.c:1849
void wtp_pack_set_rid(WAPEvent *dgram, long rid)
Definition: wtp_pack.c:215
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
Definition: wap_addr.c:125
WAPEvent * wtp_pack_sar_ack(long ack_type, long tid, WAPAddrTuple *address, int psn)
Definition: wtp_pack.c:263
#define SAR_SEGM_SIZE
Definition: fakewap.c:221
WAPEvent * wtp_pack_result(WTPRespMachine *machine, WAPEvent *event)
Definition: wtp_pack.c:143
union wtp_pdu::@107 u
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define wap_event_create(type)
Definition: wap_events.h:107
#define SAR_GROUP_LEN
Definition: fakewap.c:222
WAPEvent * wtp_pack_ack(long ack_type, int rid_flag, long tid, WAPAddrTuple *address)
Definition: wtp_pack.c:243
Definition: octstr.c:118
WAPEvent * wtp_pack_invoke(WTPInitMachine *machine, WAPEvent *event)
Definition: wtp_pack.c:115
WAPEventName type
Definition: wap_events.h:88
Octstr * wtp_pdu_pack(WTP_PDU *pdu)
Definition: wtp_pdu.c:388
WAPEvent * wtp_pack_abort(long abort_type, long abort_reason, long tid, WAPAddrTuple *address)
Definition: wtp_pack.c:223
void wtp_pdu_destroy(WTP_PDU *pdu)
Definition: wtp_pdu.c:104
union WAPEvent::@87 u
#define octstr_create_from_data(data, len)
Definition: octstr.h:134
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.