Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
wap_push_ota.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  * Wap_push_ota.c: implementation of push related requests of OTA protocol
59  *
60  * This module implements requirement primitives of WAP-189-PushOTA-20000217-a
61  * (hereafter called ota).
62  * In addition, WAP-203-WSP-20000504-a (wsp) is referred.
63  *
64  * This module forwards push requests made by the wap_push_ppg module to
65  * connected or connectionless session services.
66  * Indications (for confirmed push, push abort and disconnect, e.g., in the
67  * case of unability to create a session) of OTA protocol are done for wap_
68  * push_ppg module by a module common with pull, wap-appl.
69  *
70  * Note that push header encoding and decoding are divided into two parts:
71  * first decoding and encoding numeric values and then packing these values
72  * into WSP format and unpacking them from WSP format. This module contains
73  * decoding part.
74  *
75  * By Aarno Syvšnen for Wapit Ltd and Global Networks Inc.
76  */
77 
78 #include <errno.h>
79 
80 #include "wap_push_ota.h"
81 #include "gwlib/gwlib.h"
82 #include "wap/wsp.h"
83 #include "wap/wsp_strings.h"
84 #include "wap/wsp_pdu.h"
85 
86 /**************************************************************************
87  *
88  * Internal data structures
89  */
90 
91 /*
92  * Give the status of the push ota module:
93  *
94  * limbo
95  * not running at all
96  * running
97  * operating normally
98  * terminating
99  * waiting for operations to terminate, returning to limbo
100  */
102 
103 /*
104  * Bearerbox address for the phone (it needs to know who it is talking with)
105  */
109 };
111 
113 
114 static List *ota_queue = NULL;
115 
118 
119 /**************************************************************************
120  *
121  * Prototypes of internal functions
122  */
123 
124 static void main_thread(void *arg);
125 static void handle_ota_event(WAPEvent *e);
126 static void make_session_request(WAPEvent *e);
127 static void make_push_request(WAPEvent *e);
128 static void make_confirmed_push_request(WAPEvent *e);
129 static void make_unit_push_request(WAPEvent *e);
130 static void abort_push(WAPEvent *e);
131 
132 /*
133  * Add push flag into push headers. Push flag is defined in PushOTA, p. 17-18.
134  */
135 static List *add_push_flag(WAPEvent *e);
136 
137 /*
138  * When server is requesting a session with a client, content type and applic-
139  * ation headers must be present (this behaviour is defined in PushOTA, p. 14).
140  * We check headers for them and add them if they are not already present.
141  */
142 static void check_session_request_headers(List *headers);
143 
144 /*
145  * Contact points and application ids in the push initiator are packed into a
146  * specific structure, being like WSP PDUs.
147  */
148 static Octstr *pack_sia(List *headers);
149 static void flags_assert(WAPEvent *e);
150 static void reason_assert(long reason);
151 static Octstr *pack_server_address(void);
152 static Octstr *pack_appid_list(List *headers);
153 
154 /*
155  * Returns bearerbox ip address. Resolve it, if the address is localhost.
156  */
157 static Octstr *name(Octstr *os);
160 
161 /***************************************************************************
162  *
163  * EXTERNAL FUNCTIONS
164  */
165 
167  wap_dispatch_func_t *wsp_unit_dispatch)
168 {
169  ota_queue = gwlist_create();
170  gwlist_add_producer(ota_queue);
171 
172  dispatch_to_wsp = wsp_dispatch;
173  dispatch_to_wsp_unit = wsp_unit_dispatch;
174 
175  bearerbox = bearerbox_address_create();
176 
180 }
181 
183 {
186  gwlist_remove_producer(ota_queue);
188 
190  bearerbox_address_destroy(bearerbox);
191 }
192 
194 {
196  gwlist_produce(ota_queue, e);
197 }
198 
199 /*
200  * Sets bearerbox address, used for push contact point. Resolve address local-
201  * host before assignment.
202  */
204 {
205  gw_assert(in);
206 
207  mutex_lock(bearerbox->mutex);
208  bearerbox->address = name(in);
209  mutex_unlock(bearerbox->mutex);
210 }
211 
212 /**************************************************************************
213  *
214  * INTERNAL FUNCTIONS
215  */
216 
217 static void main_thread(void *arg)
218 {
219  WAPEvent *e;
220 
221  while (run_status == running && (e = gwlist_consume(ota_queue)) != NULL) {
222  handle_ota_event(e);
223  }
224 
225 }
226 
227 static void handle_ota_event(WAPEvent *e)
228 {
229  debug("wap.push.ota", 0, "OTA: event arrived");
230 
231  switch (e->type) {
232  case Pom_SessionRequest_Req:
234  break;
235 
236  case Po_Push_Req:
238  break;
239 
240  case Po_ConfirmedPush_Req:
242  break;
243 
244  case Po_Unit_Push_Req:
246  break;
247 
248  case Po_PushAbort_Req:
249  abort_push(e);
250  break;
251 
252  default:
253  debug("wap.push.ota", 0, "OTA: unhandled event");
254  wap_event_dump(e);
255  break;
256  }
257 
259 }
260 
262 {
263  WAPEvent *wsp_event;
264  List *appid_headers, *push_headers;
265 
266  gw_assert(e->type == Pom_SessionRequest_Req);
267  push_headers = e->u.Pom_SessionRequest_Req.push_headers;
268 
269  check_session_request_headers(push_headers);
270 
271  wsp_event = wap_event_create(S_Unit_Push_Req);
272  wsp_event->u.S_Unit_Push_Req.address_type =
273  e->u.Pom_SessionRequest_Req.address_type;
274  if (e->u.Pom_SessionRequest_Req.smsc_id != NULL)
275  wsp_event->u.S_Unit_Push_Req.smsc_id =
276  octstr_duplicate(e->u.Pom_SessionRequest_Req.smsc_id);
277  else
278  wsp_event->u.S_Unit_Push_Req.smsc_id = NULL;
279  if (e->u.Pom_SessionRequest_Req.dlr_url != NULL)
280  wsp_event->u.S_Unit_Push_Req.dlr_url =
281  octstr_duplicate(e->u.Pom_SessionRequest_Req.dlr_url);
282  else
283  wsp_event->u.S_Unit_Push_Req.dlr_url = NULL;
284  wsp_event->u.S_Unit_Push_Req.dlr_mask = e->u.Pom_SessionRequest_Req.dlr_mask;
285  if (e->u.Pom_SessionRequest_Req.smsbox_id != NULL)
286  wsp_event->u.S_Unit_Push_Req.smsbox_id =
287  octstr_duplicate(e->u.Pom_SessionRequest_Req.smsbox_id);
288  else
289  wsp_event->u.S_Unit_Push_Req.smsbox_id = NULL;
290  wsp_event->u.S_Unit_Push_Req.service_name =
291  octstr_duplicate(e->u.Pom_SessionRequest_Req.service_name);
292 
293  wsp_event->u.S_Unit_Push_Req.push_id =
294  e->u.Pom_SessionRequest_Req.push_id;
295  wsp_event->u.S_Unit_Push_Req.addr_tuple =
296  wap_addr_tuple_duplicate(e->u.Pom_SessionRequest_Req.addr_tuple);
297  wsp_event->u.S_Unit_Push_Req.push_headers =
298  http_header_duplicate(push_headers);
299 
300  appid_headers = http_header_find_all(push_headers, "X-WAP-Application-Id");
301  wsp_event->u.S_Unit_Push_Req.push_body = pack_sia(appid_headers);
302 
303  debug("wap.push.ota", 0, "OTA: making a connectionless session request for"
304  " creating a session");
305 
306  dispatch_to_wsp_unit(wsp_event);
307 }
308 
310 {
311  WAPEvent *wsp_event;
312  List *push_headers;
313 
314  gw_assert(e->type == Po_Push_Req);
315  push_headers = add_push_flag(e);
316 
317  wsp_event = wap_event_create(S_Push_Req);
318  wsp_event->u.S_Push_Req.push_headers = push_headers;
319  if (e->u.Po_Push_Req.push_body != NULL)
320  wsp_event->u.S_Push_Req.push_body =
321  octstr_duplicate(e->u.Po_Push_Req.push_body);
322  else
323  wsp_event->u.S_Push_Req.push_body = NULL;
324  wsp_event->u.S_Push_Req.session_id = e->u.Po_Push_Req.session_handle;
325 
326  dispatch_to_wsp(wsp_event);
327 }
328 
330 {
331  WAPEvent *wsp_event;
332  List *push_headers;
333 
334  gw_assert(e->type == Po_ConfirmedPush_Req);
335  push_headers = add_push_flag(e);
336 
337  wsp_event = wap_event_create(S_ConfirmedPush_Req);
338  wsp_event->u.S_ConfirmedPush_Req.server_push_id =
339  e->u.Po_ConfirmedPush_Req.server_push_id;
340  wsp_event->u.S_ConfirmedPush_Req.push_headers = push_headers;
341 
342  if (e->u.Po_ConfirmedPush_Req.push_body != NULL)
343  wsp_event->u.S_ConfirmedPush_Req.push_body =
344  octstr_duplicate(e->u.Po_ConfirmedPush_Req.push_body);
345  else
346  wsp_event->u.S_ConfirmedPush_Req.push_body = NULL;
347 
348  wsp_event->u.S_ConfirmedPush_Req.session_id =
349  e->u.Po_ConfirmedPush_Req.session_handle;
350  debug("wap.push.ota", 0, "OTA: making confirmed push request to wsp");
351 
352  dispatch_to_wsp(wsp_event);
353 }
354 
356 {
357  WAPEvent *wsp_event;
358  List *push_headers;
359  Octstr *smsc_id;
360  Octstr *dlr_url;
361  Octstr *smsbox_id;
362  Octstr *push_body;
364 
365  gw_assert(e->type == Po_Unit_Push_Req);
366  gw_assert(e->u.Po_Unit_Push_Req.addr_tuple);
367  gw_assert(e->u.Po_Unit_Push_Req.service_name);
368 
369  smsc_id = octstr_duplicate(e->u.Po_Unit_Push_Req.smsc_id);
370  dlr_url = octstr_duplicate(e->u.Po_Unit_Push_Req.dlr_url);
371  smsbox_id = octstr_duplicate(e->u.Po_Unit_Push_Req.smsbox_id);
372  push_body = octstr_duplicate(e->u.Po_Unit_Push_Req.push_body);
373  service_name = octstr_duplicate(e->u.Po_Unit_Push_Req.service_name);
374  push_headers = add_push_flag(e);
375 
376  wsp_event = wap_event_create(S_Unit_Push_Req);
377  wsp_event->u.S_Unit_Push_Req.addr_tuple =
378  wap_addr_tuple_duplicate(e->u.Po_Unit_Push_Req.addr_tuple);
379  wsp_event->u.S_Unit_Push_Req.push_id = e->u.Po_Unit_Push_Req.push_id;
380  wsp_event->u.S_Unit_Push_Req.push_headers = push_headers;
381 
382  wsp_event->u.S_Unit_Push_Req.address_type =
383  e->u.Po_Unit_Push_Req.address_type;
384  if (smsc_id != NULL)
385  wsp_event->u.S_Unit_Push_Req.smsc_id = smsc_id;
386  else
387  wsp_event->u.S_Unit_Push_Req.smsc_id = NULL;
388  if (dlr_url != NULL)
389  wsp_event->u.S_Unit_Push_Req.dlr_url = dlr_url;
390  else
391  wsp_event->u.S_Unit_Push_Req.dlr_url = NULL;
392  wsp_event->u.S_Unit_Push_Req.dlr_mask = e->u.Po_Unit_Push_Req.dlr_mask;
393  if (smsbox_id != NULL)
394  wsp_event->u.S_Unit_Push_Req.smsbox_id = smsbox_id;
395  else
396  wsp_event->u.S_Unit_Push_Req.smsbox_id = NULL;
397  wsp_event->u.S_Unit_Push_Req.service_name = service_name;
398  if (push_body != NULL)
399  wsp_event->u.S_Unit_Push_Req.push_body = push_body;
400  else
401  wsp_event->u.S_Unit_Push_Req.push_body = NULL;
402 
403  dispatch_to_wsp_unit(wsp_event);
404  debug("wap.push.ota", 0, "OTA: made connectionless session service"
405  " request");
406 }
407 
408 static void abort_push(WAPEvent *e)
409 {
410  WAPEvent *wsp_event;
411  long reason;
412 
413  reason = e->u.Po_PushAbort_Req.reason;
414  gw_assert(e->type == Po_PushAbort_Req);
415  reason_assert(reason);
416 
417  wsp_event = wap_event_create(S_PushAbort_Req);
418  wsp_event->u.S_PushAbort_Req.push_id = e->u.Po_PushAbort_Req.push_id;
419  wsp_event->u.S_PushAbort_Req.reason = reason;
420  wsp_event->u.S_PushAbort_Req.session_handle =
421  e->u.Po_PushAbort_Req.session_id;
422 
423  dispatch_to_wsp(wsp_event);
424 }
425 
426 /*
427  * Add push flag into push headers. Push flag is defined in ota, p. 17-18.
428  * If there is no flags set, no Push-Flag header is added.
429  */
431 {
432  int push_flag,
433  trusted,
434  authenticated,
435  last;
436 
437  Octstr *buf;
438  List *headers;
439 
440  flags_assert(e);
441 
442  if (e->type == Po_Unit_Push_Req) {
443  trusted = e->u.Po_Unit_Push_Req.trusted << 1;
444  authenticated = e->u.Po_Unit_Push_Req.authenticated;
445  last = e->u.Po_Unit_Push_Req.last << 2;
446 
447  headers = http_header_duplicate(e->u.Po_Unit_Push_Req.push_headers);
448 
449  } else if (e->type == Po_Push_Req) {
450  trusted = e->u.Po_Push_Req.trusted << 1;
451  authenticated = e->u.Po_Push_Req.authenticated;
452  last = e->u.Po_Push_Req.last << 2;
453 
454  headers = http_header_duplicate(e->u.Po_Push_Req.push_headers);
455 
456  } else if (e->type == Po_ConfirmedPush_Req) {
457  trusted = e->u.Po_ConfirmedPush_Req.trusted << 1;
458  authenticated = e->u.Po_ConfirmedPush_Req.authenticated;
459  last = e->u.Po_ConfirmedPush_Req.last << 2;
460 
461  headers = http_header_duplicate(
462  e->u.Po_ConfirmedPush_Req.push_headers);
463 
464  } else {
465  debug("wap.ota", 0, "OTA: no push flag when the event is: \n");
466  wap_event_dump(e);
467  return NULL;
468  }
469 
470  push_flag = 0;
471  push_flag = push_flag | authenticated | trusted | last;
472 
473  if (push_flag) {
474  buf = octstr_format("%d", push_flag);
475  http_header_add(headers, "Push-Flag", octstr_get_cstr(buf));
476  octstr_destroy(buf);
477  }
478 
479  return headers;
480 }
481 
482 static void flags_assert(WAPEvent *e)
483 {
484  if (e->type == Po_Unit_Push_Req) {
485  gw_assert(e->u.Po_Unit_Push_Req.trusted == 0 ||
486  e->u.Po_Unit_Push_Req.trusted == 1);
487  gw_assert(e->u.Po_Unit_Push_Req.authenticated == 0 ||
488  e->u.Po_Unit_Push_Req.authenticated == 1);
489  gw_assert(e->u.Po_Unit_Push_Req.last == 0 ||
490  e->u.Po_Unit_Push_Req.last == 1);
491 
492  } else if (e->type == Po_Push_Req) {
493  gw_assert(e->u.Po_Push_Req.trusted == 0 ||
494  e->u.Po_Push_Req.trusted == 1);
495  gw_assert(e->u.Po_Push_Req.authenticated == 0 ||
496  e->u.Po_Push_Req.authenticated == 1);
497  gw_assert(e->u.Po_Push_Req.last == 0 ||
498  e->u.Po_Push_Req.last == 1);
499 
500  } else if (e->type == Po_ConfirmedPush_Req) {
501  gw_assert(e->u.Po_ConfirmedPush_Req.trusted == 0 ||
502  e->u.Po_ConfirmedPush_Req.trusted == 1);
503  gw_assert(e->u.Po_ConfirmedPush_Req.authenticated == 0 ||
504  e->u.Po_ConfirmedPush_Req.authenticated == 1);
505  gw_assert(e->u.Po_ConfirmedPush_Req.last == 0 ||
506  e->u.Po_ConfirmedPush_Req.last == 1);
507  }
508 }
509 
510 /*
511  * Accepted reasons are defined in ota 6.3.3.
512  */
513 static void reason_assert(long reason)
514 {
515  gw_assert(reason == WSP_ABORT_USERREQ || reason == WSP_ABORT_USERRFS ||
516  reason == WSP_ABORT_USERPND || reason == WSP_ABORT_USERDCR ||
517  reason == WSP_ABORT_USERDCU);
518 }
519 
520 /*
521  * When server is requesting a session with a client, content type and applic-
522  * ation headers must be present (this behaviour is defined in ota, p. 14).
523  * We check headers for them and add them if they are not already present.
524  * X-WAP-Application-Id has been added by ppg module.
525  */
526 static void check_session_request_headers(List *headers)
527 {
528  if (!http_type_accepted(headers, "application/wnd.wap.sia"))
529  http_header_add(headers, "Content-Type", "application/vnd.wap.sia");
530 }
531 
532 /*
533  * Pack contact points and application id list into sia content type. It is
534  * defined in ota, p. 18.
535  */
536 static Octstr *pack_sia(List *headers)
537 {
538  Octstr *sia_content;
539  WSP_PDU *pdu;
540 
541  pdu = wsp_pdu_create(sia);
542 
543  pdu->u.sia.version = CURRENT_VERSION;
544  pdu->u.sia.application_id_list = pack_appid_list(headers);
545  pdu->u.sia.contactpoints = pack_server_address();
546  sia_content = wsp_pdu_pack(pdu);
547 
548  wsp_pdu_destroy(pdu);
549  http_destroy_headers(headers);
550 
551  return sia_content;
552 }
553 
554 /*
555  * Input: List of headers containing only X-Wap-Application-Id headers, values
556  * being numeric application id codes. (Ppg module does coding of the header
557  * value part of the X-WAP-Application-Id header).
558  * Output: Octstr containing them in a byte list (one id per byte).
559  *
560  * Returns: Octstr containing headers, if succesfull, otherwise an empty
561  * octstr.
562  */
563 static Octstr *pack_appid_list(List *headers)
564 {
565  Octstr *appid_os,
566  *header_name,
567  *header_value;
568  long i;
569  size_t len;
570 
571  i = 0;
572  appid_os = octstr_create("");
573  len = (size_t) gwlist_len(headers);
574 
575  gw_assert(len);
576 
577  while (i < len) {
578  http_header_get(headers, i, &header_name, &header_value);
579  gw_assert(octstr_compare(header_name,
580  octstr_imm("X-WAP-Application-Id")) == 0);
581  octstr_format_append(appid_os, "%S", header_value);
582  octstr_destroy(header_name);
583  octstr_destroy(header_value);
584  ++i;
585  }
586 
587  return appid_os;
588 }
589 
590 /*
591  * NB: This data includes bearer information. We use IPv4 values. Address Type
592  * is defined in wsp, table 16, p. 65
593  */
595 {
596  Octstr *address,
597  *ip_address;
598  unsigned char address_len;
599  long port;
600  int bearer_type;
601 
602  bearer_type = GSM_CSD_IPV4;
603  port = CONNECTED_PORT;
604 
605  mutex_lock(bearerbox->mutex);
606  ip_address = octstr_duplicate(bearerbox->address);
607  address_len = octstr_len(bearerbox->address);
608  mutex_unlock(bearerbox->mutex);
609 
610  address = octstr_create("");
611  octstr_append_char(address, address_len);
612  octstr_set_bits(address, 0, 1, 1); /* bearer type included */
613  octstr_set_bits(address, 1, 1, 1); /* port number included */
614  octstr_append_char(address, bearer_type);
615  octstr_append_decimal(address, port);
616  octstr_append(address, ip_address);
617  octstr_destroy(ip_address);
618 
619  return address;
620 }
621 
622 /*
623  * Returns bearerbox ip address. Resolve it, if the address is localhost. Do
624  * not panic here. Even if we cannot do push, we still can do pull.
625  */
626 static Octstr *name(Octstr *in)
627 {
628  if (octstr_compare(in, octstr_imm("localhost")) != 0)
629  return octstr_duplicate(in);
630  else
632 }
633 
635 {
636  BearerboxAddress *ba;
637 
638  ba = gw_malloc(sizeof(BearerboxAddress));
639  ba->mutex = mutex_create();
640  ba->address = NULL;
641 
642  return ba;
643 }
644 
646 {
647  if (ba == NULL)
648  return;
649 
650  octstr_destroy(ba->address);
651  mutex_destroy(ba->mutex);
652  gw_free(ba);
653 }
654 
655 
static Octstr * pack_appid_list(List *headers)
Definition: wap_push_ota.c:563
static Octstr * service_name
Definition: wap_push_ppg.c:205
static void make_push_request(WAPEvent *e)
Definition: wap_push_ota.c:309
List * http_header_find_all(List *headers, char *name)
Definition: http.c:3092
union wsp_pdu::@89 u
void http_header_get(List *headers, long i, Octstr **name, Octstr **value)
Definition: http.c:2879
void wap_push_ota_dispatch_event(WAPEvent *e)
Definition: wap_push_ota.c:193
static void abort_push(WAPEvent *e)
Definition: wap_push_ota.c:408
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
wap_dispatch_func_t * dispatch_to_wsp_unit
Definition: wap_push_ota.c:117
#define mutex_unlock(m)
Definition: thread.h:136
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1502
void gwlist_produce(List *list, void *item)
Definition: list.c:411
wap_dispatch_func_t * dispatch_to_wsp
Definition: wap_push_ota.c:116
long gwlist_len(List *list)
Definition: list.c:166
#define mutex_create()
Definition: thread.h:96
void octstr_set_bits(Octstr *ostr, long bitpos, int numbits, unsigned long value)
Definition: octstr.c:1847
static enum @32 run_status
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1515
static List * add_push_flag(WAPEvent *e)
Definition: wap_push_ota.c:430
static void make_unit_push_request(WAPEvent *e)
Definition: wap_push_ota.c:355
Octstr * wsp_pdu_pack(WSP_PDU *pdu)
Definition: wsp_pdu.c:271
static void make_session_request(WAPEvent *e)
Definition: wap_push_ota.c:261
static void check_session_request_headers(List *headers)
Definition: wap_push_ota.c:526
static void handle_ota_event(WAPEvent *e)
Definition: wap_push_ota.c:227
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void wap_event_dump(WAPEvent *event)
Definition: wap_events.c:181
void gwthread_join_every(gwthread_func_t *func)
static Octstr * smsbox_id
Definition: smsbox.c:120
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
Definition: wap_addr.c:125
void http_destroy_headers(List *headers)
Definition: http.c:2856
WSP_PDU * wsp_pdu_create(int type)
Definition: wsp_pdu.c:68
static int port
Definition: fakesmsc.c:120
static Octstr * pack_server_address(void)
Definition: wap_push_ota.c:594
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
void wap_push_ota_init(wap_dispatch_func_t *wsp_dispatch, wap_dispatch_func_t *wsp_unit_dispatch)
Definition: wap_push_ota.c:166
static Octstr * dlr_url
Definition: test_ppg.c:107
void gwlist_remove_producer(List *list)
Definition: list.c:401
void wap_event_destroy_item(void *event)
Definition: wap_events.c:130
#define octstr_duplicate(ostr)
Definition: octstr.h:187
static Octstr * smsc_id
Definition: mtbatch.c:98
static void flags_assert(WAPEvent *e)
Definition: wap_push_ota.c:482
#define wap_event_create(type)
Definition: wap_events.h:107
static BearerboxAddress * bearerbox_address_create(void)
Definition: wap_push_ota.c:634
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
static void bearerbox_address_destroy(BearerboxAddress *ba)
Definition: wap_push_ota.c:645
#define gwthread_create(func, arg)
Definition: gwthread.h:90
#define octstr_create(cstr)
Definition: octstr.h:125
gw_assert(wtls_machine->packet_to_send!=NULL)
void mutex_destroy(Mutex *mutex)
Definition: thread.c:97
static List * ota_queue
Definition: wap_push_ota.c:114
void wsp_pdu_destroy(WSP_PDU *pdu)
Definition: wsp_pdu.c:102
static void reason_assert(long reason)
Definition: wap_push_ota.c:513
static Octstr * name(Octstr *os)
Definition: wap_push_ota.c:626
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
static BearerboxAddress * bearerbox
Definition: wap_push_ota.c:112
void octstr_append_decimal(Octstr *ostr, long value)
Definition: octstr.c:1974
Octstr * get_official_ip(void)
Definition: socket.c:634
Definition: octstr.c:118
void * gwlist_consume(List *list)
Definition: list.c:427
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
#define CURRENT_VERSION
Definition: wap_push_ota.h:69
WAPEventName type
Definition: wap_events.h:88
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2505
List * http_header_duplicate(List *headers)
Definition: http.c:2946
void wap_push_ota_shutdown(void)
Definition: wap_push_ota.c:182
#define gwlist_create()
Definition: list.h:136
Definition: thread.h:76
static void make_confirmed_push_request(WAPEvent *e)
Definition: wap_push_ota.c:329
int http_type_accepted(List *headers, char *type)
Definition: http.c:3480
static void main_thread(void *arg)
Definition: wap_push_ota.c:217
void gwlist_add_producer(List *list)
Definition: list.c:383
union WAPEvent::@87 u
#define CONNECTED_PORT
Definition: wap_push_ota.h:70
void wap_push_ota_bb_address_set(Octstr *in)
Definition: wap_push_ota.c:203
#define mutex_lock(m)
Definition: thread.h:130
Definition: list.c:102
static Octstr * pack_sia(List *headers)
Definition: wap_push_ota.c:536
void wap_event_destroy(WAPEvent *event)
Definition: wap_events.c:102
void wap_dispatch_func_t(WAPEvent *event)
Definition: wap.h:85
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.