Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
wap_push_ppg.c File Reference
#include <time.h>
#include <ctype.h>
#include "wap_push_ppg.h"
#include "wap/wap_events.h"
#include "wap/wsp_caps.h"
#include "wml_compiler.h"
#include "wap-appl.h"
#include "wap/wsp.h"
#include "wap/wsp_strings.h"
#include "wap_push_si_compiler.h"
#include "wap_push_sl_compiler.h"
#include "wap_push_pap_compiler.h"
#include "wap_push_pap_mime.h"
#include "wap_push_ppg_pushuser.h"
#include "wap_ppg_session_machine.def"
#include "wap_ppg_push_machine.def"

Go to the source code of this file.

Data Structures

struct  content
 
struct  PAPEvent
 
struct  description_t
 

Macros

#define DEFAULT_PPG_URL   "/wappush"
 
#define INTEGER(name)   m->name = 0;
 
#define OCTSTR(name)   m->name = NULL;
 
#define ADDRTUPLE(name)   m->name = NULL;
 
#define PUSHMACHINES(name)   m->name = gwlist_create();
 
#define CAPABILITIES(name)   m->name = NULL;
 
#define MACHINE(fields)   fields
 
#define OCTSTR(name)   octstr_destroy(sm->name);
 
#define ADDRTUPLE(name)   wap_addr_tuple_destroy(sm->name);
 
#define INTEGER(name)   sm->name = 0;
 
#define PUSHMACHINES(name)   push_machines_list_destroy(sm->name);
 
#define CAPABILITIES(name)   wsp_cap_destroy_list(sm->name);
 
#define MACHINE(fields)   fields
 
#define INTEGER(name)   m->name = 0;
 
#define OCTSTR(name)   m->name = NULL;
 
#define OPTIONAL_OCTSTR(name)   m->name = NULL;
 
#define ADDRTUPLE(name)   m->name = NULL;
 
#define CAPABILITIES   m->name = NULL;
 
#define HTTPHEADER(name)   m->name = NULL;
 
#define MACHINE(fields)   fields
 
#define OCTSTR(name)   octstr_destroy(pm->name);
 
#define OPTIONAL_OCTSTR(name)   octstr_destroy(pm->name);
 
#define INTEGER(name)
 
#define ADDRTUPLE(name)   wap_addr_tuple_destroy(pm->name);
 
#define CAPABILITIES(name)   wap_cap_destroy_list(pm->name);
 
#define HTTPHEADER(name)   http_destroy_headers(pm->name);
 
#define MACHINE(fields)   fields
 
#define NUM_CONVERTERS   ((long) (sizeof(converters) / sizeof(converters[0])))
 
#define NUM_EXTRACTORS   ((long) (sizeof(extractors) / sizeof(extractors[0])))
 
#define NUMBER_OF_BEARERS   sizeof(bearers)/sizeof(bearers[0])
 
#define NUMBER_OF_NETWORKS   sizeof(networks)/sizeof(networks[0])
 
#define NUMBER_OF_WINA_URIS   sizeof(wina_uri)/sizeof(wina_uri[0])
 

Typedefs

typedef struct PAPEvent PAPEvent
 
typedef struct description_t description_t
 

Enumerations

enum  { TIME_EXPIRED = 0, TIME_TOO_EARLY = 1, NO_CONSTRAINTS = 2 }
 
enum  {
  DEFAULT_HTTP_PORT = 8080, NO_HTTPS_PORT = -1, DEFAULT_NUMBER_OF_PUSHES = 100, PI_TRUSTED = 1,
  SSL_CONNECTION_OFF = 0, DEFAULT_NUMBER_OF_USERS = 1024, USER_CONFIGURATION_NOT_ADDED = 0
}
 
enum  { USER_CONFIGURATION_ADDED = 1 }
 
enum  { limbo, running, terminating }
 
enum  { TYPE_HTTP = 0, TYPE_HTTPS = 1 }
 

Functions

static void ota_read_thread (void *arg)
 
static void http_read_thread (void *arg)
 
static void handle_internal_event (WAPEvent *e)
 
static void pap_request_thread (void *arg)
 
static int handle_push_message (HTTPClient **c, WAPEvent *ppg_event, int status)
 
static PAPEventpap_event_create (Octstr *ip, Octstr *url, List *push_headers, Octstr *mime_content, List *cgivars, HTTPClient *client)
 
static void pap_event_destroy (PAPEvent *p)
 
static void pap_event_destroy_item (void *p)
 
static void pap_event_unpack (PAPEvent *p, Octstr **ip, Octstr **url, List **push_headers, Octstr **mime_content, List **cgivars, HTTPClient **client)
 
static PPGSessionMachinesession_machine_create (WAPAddrTuple *tuple, WAPEvent *e)
 
static void session_machine_destroy (void *p)
 
static PPGPushMachinepush_machine_create (WAPEvent *e, WAPAddrTuple *tuple)
 
static void push_machine_destroy (void *pm)
 
static void push_machines_list_destroy (List *pl)
 
static void create_session (WAPEvent *e, PPGPushMachine *pm)
 
static void request_confirmed_push (long last, PPGPushMachine *pm, PPGSessionMachine *sm)
 
static void request_unit_push (long last, PPGPushMachine *pm)
 
static void request_push (long last, PPGPushMachine *sm)
 
static int response_push_connection (WAPEvent *e, PPGSessionMachine *sm)
 
static HTTPClientresponse_push_message (PPGPushMachine *pm, long code, int status)
 
static PPGSessionMachinesession_find_using_pi_client_address (Octstr *addr)
 
static PPGPushMachinefind_ppg_push_machine_using_pid (PPGSessionMachine *sm, long pid)
 
static PPGPushMachinefind_ppg_push_machine_using_pi_push_id (PPGSessionMachine *sm, Octstr *pi_push_id)
 
static PPGPushMachinefind_unit_ppg_push_machine_using_pi_push_id (Octstr *pi_push_id)
 
static int push_has_pi_push_id (void *a, void *b)
 
static int push_has_pid (void *a, void *b)
 
static int session_has_pi_client_address (void *a, void *b)
 
static int session_has_addr (void *a, void *b)
 
static int session_has_sid (void *a, void *b)
 
static int check_capabilities (List *requested, List *assumed)
 
static int transform_message (WAPEvent **e, WAPAddrTuple **tuple, List *push_headers, int connected, Octstr **type)
 
static long check_x_wap_application_id_header (List **push_headers)
 
static int pap_convert_content (struct content *content)
 
static int pap_get_content (struct content *content)
 
static int select_bearer_network (WAPEvent **e)
 
static int delivery_time_constraints (WAPEvent *e, PPGPushMachine *pm)
 
static void deliver_confirmed_push (long last, PPGPushMachine *pm, PPGSessionMachine *sm)
 
static PPGPushMachinedeliver_unit_push (long last, PPGPushMachine *pm, PPGSessionMachine *sm, int session_exists)
 
static int store_push_data (PPGPushMachine **pm, PPGSessionMachine *sm, WAPEvent *e, WAPAddrTuple *tuple, int cless)
 
static PPGPushMachineupdate_push_data_with_attribute (PPGSessionMachine **sm, PPGPushMachine *pm, long reason, long status)
 
static void remove_push_data (PPGSessionMachine *sm, PPGPushMachine *pm, int cless)
 
static void remove_session_data (PPGSessionMachine *sm, int status)
 
static void remove_pushless_session (PPGSessionMachine *sm)
 
static PPGSessionMachinestore_session_data (PPGSessionMachine *sm, WAPEvent *e, WAPAddrTuple *tuple, int *session_exists)
 
static PPGSessionMachineupdate_session_data_with_headers (PPGSessionMachine *sm, PPGPushMachine *pm)
 
static void deliver_pending_pushes (PPGSessionMachine *sm, int last)
 
static PPGPushMachineabort_delivery (PPGSessionMachine *sm, int status)
 
static PPGSessionMachineupdate_session_data (PPGSessionMachine *sm, long sid, long port, List *caps)
 
static int confirmation_requested (WAPEvent *e)
 
static int cless_accepted (WAPEvent *e, PPGSessionMachine *sm)
 
static int headers_acceptable (List *push_headers, Octstr **content_header)
 
static int type_is (Octstr *content_header, char *required_type)
 
static int get_mime_boundary (List *push_headers, Octstr *content_header, Octstr **boundary)
 
static void change_header_value (List **push_headers, char *name, char *value)
 
static void remove_mime_headers (List **push_headers)
 
static void remove_link_headers (List **push_headers)
 
static void remove_x_kannel_headers (List **push_headers)
 
static void send_bad_message_response (HTTPClient **c, Octstr *body_fragment, int code, int status)
 
static HTTPClientsend_push_response (WAPEvent *e, int status)
 
static void send_to_pi (HTTPClient **c, Octstr *reply_body, int status)
 
static void tell_fatal_error (HTTPClient **c, WAPEvent *e, Octstr *url, int status, int code)
 
static int read_ppg_config (Cfg *cfg)
 
static int ip_allowed_by_ppg (Octstr *ip)
 
static Octstrconvert_wml_to_wmlc (struct content *content)
 
static Octstrconvert_si_to_sic (struct content *content)
 
static Octstrconvert_sl_to_slc (struct content *content)
 
static Octstrset_smsc_id (List *headers, Octstr *username, int trusted_pi)
 
static Octstrset_dlr_url (List *headers, Octstr *username, int trusted_pi)
 
static long set_dlr_mask (List *headers, Octstr *dlr_url)
 
static Octstrset_smsbox_id (List *headers, Octstr *username, int trusted_pi)
 
static Octstrset_service_name (void)
 
static Octstrset_time (void)
 
static int deliver_before_test_cleared (Octstr *before, struct tm now)
 
static int deliver_after_test_cleared (Octstr *after, struct tm now)
 
static void session_machine_assert (PPGSessionMachine *sm)
 
static void push_machine_assert (PPGPushMachine *pm)
 
static Octstrtell_ppg_name (void)
 
static Octstrdescribe_code (long code)
 
static long ota_abort_to_pap (long reason)
 
static int content_transformable (List *push_headers)
 
static WAPAddrTupleset_addr_tuple (Octstr *address, long cliport, long servport, long address_type, List *push_headers)
 
static WAPAddrTupleaddr_tuple_change_cliport (WAPAddrTuple *tuple, long port)
 
static void initialize_time_item_array (long time_data[], struct tm now)
 
static int date_item_compare (Octstr *before, long time_data, long pos)
 
static long parse_appid_header (Octstr **assigned_code)
 
static Octstrescape_fragment (Octstr *fragment)
 
static int coriented_deliverable (long code)
 
static int is_phone_number (long type_of_address)
 
static void replace_octstr_char (Octstr *os1, Octstr *os2, long *pos)
 
void wap_push_ppg_init (wap_dispatch_func_t *ota_dispatch, wap_dispatch_func_t *appl_dispatch, Cfg *cfg)
 
void wap_push_ppg_shutdown (void)
 
void wap_push_ppg_dispatch_event (WAPEvent *e)
 
PPGSessionMachinewap_push_ppg_have_push_session_for (WAPAddrTuple *tuple)
 
PPGSessionMachinewap_push_ppg_have_push_session_for_sid (long sid)
 
static Octstrextract_base64 (struct content *content)
 

Variables

static enum { ... }  run_status = limbo
 
static Listppg_queue = NULL
 
static Listpap_queue = NULL
 
static Listppg_machines = NULL
 
static Listppg_unit_pushes = NULL
 
static Counterpush_id_counter = NULL
 
static Dicthttp_clients = NULL
 
static Dicturls = NULL
 
static wap_dispatch_func_tdispatch_to_ota
 
static wap_dispatch_func_tdispatch_to_appl
 
static Octstrppg_url = NULL
 
static long ppg_port = DEFAULT_HTTP_PORT
 
static long number_of_pushes = DEFAULT_NUMBER_OF_PUSHES
 
static int trusted_pi = PI_TRUSTED
 
static long number_of_users = DEFAULT_NUMBER_OF_USERS
 
static Octstrppg_deny_ip = NULL
 
static Octstrppg_allow_ip = NULL
 
static int user_configuration = USER_CONFIGURATION_NOT_ADDED
 
static Octstrglobal_sender = NULL
 
static Octstrppg_default_smsc = NULL
 
static Octstrppg_dlr_url = NULL
 
static Octstrppg_smsbox_id = NULL
 
static Octstrservice_name = NULL
 
struct {
   char *   type
 
   char *   result_type
 
   Octstr *(*   convert )(struct content *)
 
converters []
 
struct {
   char *   transfer_encoding
 
   Octstr *(*   extract )(struct content *)
 
extractors []
 
static char * bearers []
 
static char * networks []
 
static description_t pap_desc []
 
static size_t desc_tab_size = sizeof(pap_desc) / sizeof(pap_desc[0])
 
static char * wina_uri []
 

Macro Definition Documentation

#define ADDRTUPLE (   name)    m->name = NULL;
#define ADDRTUPLE (   name)    wap_addr_tuple_destroy(sm->name);
#define ADDRTUPLE (   name)    m->name = NULL;
#define ADDRTUPLE (   name)    wap_addr_tuple_destroy(pm->name);
#define CAPABILITIES (   name)    m->name = NULL;
#define CAPABILITIES (   name)    wsp_cap_destroy_list(sm->name);
#define CAPABILITIES   m->name = NULL;
#define CAPABILITIES (   name)    wap_cap_destroy_list(pm->name);
#define DEFAULT_PPG_URL   "/wappush"

Definition at line 113 of file wap_push_ppg.c.

#define HTTPHEADER (   name)    m->name = NULL;
#define HTTPHEADER (   name)    http_destroy_headers(pm->name);
#define INTEGER (   name)    m->name = 0;
#define INTEGER (   name)    sm->name = 0;
#define INTEGER (   name)    m->name = 0;
#define INTEGER (   name)
#define MACHINE (   fields)    fields
#define MACHINE (   fields)    fields
#define MACHINE (   fields)    fields
#define MACHINE (   fields)    fields
#define NUM_CONVERTERS   ((long) (sizeof(converters) / sizeof(converters[0])))

Definition at line 1991 of file wap_push_ppg.c.

Referenced by pap_convert_content().

#define NUM_EXTRACTORS   ((long) (sizeof(extractors) / sizeof(extractors[0])))

Definition at line 2001 of file wap_push_ppg.c.

Referenced by pap_get_content().

#define NUMBER_OF_BEARERS   sizeof(bearers)/sizeof(bearers[0])

Definition at line 2070 of file wap_push_ppg.c.

Referenced by select_bearer_network().

#define NUMBER_OF_NETWORKS   sizeof(networks)/sizeof(networks[0])

Definition at line 2084 of file wap_push_ppg.c.

Referenced by select_bearer_network().

#define NUMBER_OF_WINA_URIS   sizeof(wina_uri)/sizeof(wina_uri[0])

Definition at line 2834 of file wap_push_ppg.c.

Referenced by parse_appid_header().

#define OCTSTR (   name)    m->name = NULL;
#define OCTSTR (   name)    octstr_destroy(sm->name);
#define OCTSTR (   name)    m->name = NULL;
#define OCTSTR (   name)    octstr_destroy(pm->name);
#define OPTIONAL_OCTSTR (   name)    m->name = NULL;
#define OPTIONAL_OCTSTR (   name)    octstr_destroy(pm->name);
#define PUSHMACHINES (   name)    m->name = gwlist_create();
#define PUSHMACHINES (   name)    push_machines_list_destroy(sm->name);

Typedef Documentation

typedef struct description_t description_t

Definition at line 2206 of file wap_push_ppg.c.

typedef struct PAPEvent PAPEvent

Definition at line 216 of file wap_push_ppg.c.

Enumeration Type Documentation

anonymous enum
Enumerator
TIME_EXPIRED 
TIME_TOO_EARLY 
NO_CONSTRAINTS 

Definition at line 92 of file wap_push_ppg.c.

anonymous enum
Enumerator
DEFAULT_HTTP_PORT 
NO_HTTPS_PORT 
DEFAULT_NUMBER_OF_PUSHES 
PI_TRUSTED 
SSL_CONNECTION_OFF 
DEFAULT_NUMBER_OF_USERS 
USER_CONFIGURATION_NOT_ADDED 

Definition at line 101 of file wap_push_ppg.c.

anonymous enum
Enumerator
USER_CONFIGURATION_ADDED 

Definition at line 111 of file wap_push_ppg.c.

anonymous enum
Enumerator
limbo 
running 
terminating 

Definition at line 128 of file wap_push_ppg.c.

static enum @39 run_status
anonymous enum
Enumerator
TYPE_HTTP 
TYPE_HTTPS 

Definition at line 392 of file wap_push_ppg.c.

392  {
393  TYPE_HTTP = 0,
394  TYPE_HTTPS = 1
395 };

Function Documentation

static PPGPushMachine * abort_delivery ( PPGSessionMachine sm,
int  status 
)
static

Definition at line 2385 of file wap_push_ppg.c.

References code, gwlist_get(), gwlist_len(), PAP_ABORT_USERPND, PAP_ABORTED, PAP_CAPABILITIES_MISMATCH, push_machine_assert(), description_t::reason, remove_push_data(), response_push_message(), session_machine_assert(), and update_push_data_with_attribute().

Referenced by handle_internal_event().

2386 {
2387  PPGPushMachine *pm;
2388  long reason,
2389  code;
2390 
2392 
2393  pm = NULL;
2394  reason = PAP_ABORT_USERPND;
2396 
2397  while (gwlist_len(sm->push_machines) > 0) {
2398  pm = gwlist_get(sm->push_machines, 0);
2399  push_machine_assert(pm);
2400 
2401  pm = update_push_data_with_attribute(&sm, pm, reason, PAP_ABORTED);
2402  response_push_message(pm, code, status);
2403 
2404  remove_push_data(sm, pm, sm == NULL);
2405  }
2406 
2407  return pm;
2408 }
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
int code
Definition: smsc_cimd2.c:346
static void remove_push_data(PPGSessionMachine *sm, PPGPushMachine *pm, int cless)
static void push_machine_assert(PPGPushMachine *pm)
static PPGPushMachine * update_push_data_with_attribute(PPGSessionMachine **sm, PPGPushMachine *pm, long reason, long status)
static HTTPClient * response_push_message(PPGPushMachine *pm, long code, int status)
static void session_machine_assert(PPGSessionMachine *sm)
static WAPAddrTuple * addr_tuple_change_cliport ( WAPAddrTuple tuple,
long  port 
)
static

Definition at line 2882 of file wap_push_ppg.c.

References WAPAddr::address, WAPAddrTuple::local, WAPAddr::port, WAPAddrTuple::remote, and wap_addr_tuple_create().

Referenced by create_session().

2883 {
2884  WAPAddrTuple *dubble;
2885 
2886  if (tuple == NULL)
2887  return NULL;
2888 
2889  dubble = wap_addr_tuple_create(tuple->remote->address,
2890  port,
2891  tuple->local->address,
2892  tuple->local->port);
2893 
2894  return dubble;
2895 }
Definition: http.c:1998
Octstr * address
Definition: wap_addr.h:68
WAPAddr * local
Definition: wap_addr.h:74
long port
Definition: wap_addr.h:70
WAPAddr * remote
Definition: wap_addr.h:74
WAPAddrTuple * wap_addr_tuple_create(Octstr *rmt_addr, long rmt_port, Octstr *lcl_addr, long lcl_port)
Definition: wap_addr.c:96
static void change_header_value ( List **  push_headers,
char *  name,
char *  value 
)
static

Definition at line 2991 of file wap_push_ppg.c.

References http_header_add(), and http_header_remove_all().

Referenced by pap_request_thread(), and transform_message().

2992 {
2993  http_header_remove_all(*push_headers, name);
2994  http_header_add(*push_headers, name, value);
2995 }
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
char * name
Definition: smsc_cimd2.c:212
long http_header_remove_all(List *headers, char *name)
Definition: http.c:3112
static int check_capabilities ( List requested,
List assumed 
)
static

Definition at line 1691 of file wap_push_ppg.c.

Referenced by response_push_connection().

1692 {
1693  int is_capable;
1694 
1695  is_capable = 1;
1696 
1697  return is_capable;
1698 }
static long check_x_wap_application_id_header ( List **  push_headers)
static

Definition at line 1858 of file wap_push_ppg.c.

References http_header_add(), http_header_find_first, http_header_remove_all(), octstr_destroy(), octstr_format(), octstr_get_cstr, and parse_appid_header().

Referenced by handle_push_message().

1859 {
1860  Octstr *appid_content;
1861  long coded_value;
1862  Octstr *cos;
1863 
1864  if (*push_headers == NULL)
1865  return -2;
1866 
1867  appid_content = http_header_find_first(*push_headers,
1868  "X-WAP-Application-Id");
1869 
1870  if (appid_content == NULL) {
1871  octstr_destroy(appid_content);
1872  return -1;
1873  }
1874 
1875  if ((coded_value = parse_appid_header(&appid_content)) < 0) {
1876  octstr_destroy(appid_content);
1877  return -2;
1878  }
1879 
1880  if (coded_value == 2) {
1881  octstr_destroy(appid_content);
1882  http_header_remove_all(*push_headers, "X-WAP-Application-Id");
1883  return -1;
1884  }
1885 
1886  cos = octstr_format("%ld", coded_value);
1887  http_header_remove_all(*push_headers, "X-WAP-Application-Id");
1888  http_header_add(*push_headers, "X-WAP-Application-Id", octstr_get_cstr(cos));
1889 
1890  octstr_destroy(appid_content);
1891  octstr_destroy(cos);
1892 
1893  return coded_value;
1894 }
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
static long parse_appid_header(Octstr **assigned_code)
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define http_header_find_first(headers, name)
Definition: http.h:592
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: octstr.c:118
long http_header_remove_all(List *headers, char *name)
Definition: http.c:3112
static int cless_accepted ( WAPEvent e,
PPGSessionMachine sm 
)
static

Definition at line 2659 of file wap_push_ppg.c.

References gw_assert(), PAP_NOT_SPECIFIED, PAP_UNCONFIRMED, WAPEvent::type, and WAPEvent::u.

Referenced by handle_push_message().

2660 {
2661  gw_assert(e->type == Push_Message);
2662  return (e->u.Push_Message.delivery_method == PAP_UNCONFIRMED ||
2663  e->u.Push_Message.delivery_method == PAP_NOT_SPECIFIED) &&
2664  (sm == NULL);
2665 }
gw_assert(wtls_machine->packet_to_send!=NULL)
WAPEventName type
Definition: wap_events.h:88
union WAPEvent::@87 u
static int confirmation_requested ( WAPEvent e)
static

Definition at line 2483 of file wap_push_ppg.c.

References gw_assert(), PAP_CONFIRMED, PAP_PREFERCONFIRMED, WAPEvent::type, and WAPEvent::u.

Referenced by handle_push_message().

2484 {
2485  gw_assert(e->type == Push_Message);
2486 
2487  return e->u.Push_Message.delivery_method == PAP_CONFIRMED ||
2488  e->u.Push_Message.delivery_method == PAP_PREFERCONFIRMED;
2489 }
gw_assert(wtls_machine->packet_to_send!=NULL)
WAPEventName type
Definition: wap_events.h:88
union WAPEvent::@87 u
static int content_transformable ( List push_headers)
static

Definition at line 1899 of file wap_push_ppg.c.

References gw_assert(), gwlist_len(), http_destroy_headers(), http_header_find_all(), http_header_get(), octstr_compare(), octstr_destroy(), and octstr_imm().

Referenced by transform_message().

1900 {
1901  List *cache_directives;
1902  long i;
1903  Octstr *header_name,
1904  *header_value;
1905 
1906  gw_assert(push_headers);
1907 
1908  cache_directives = http_header_find_all(push_headers, "Cache-Control");
1909  if (gwlist_len(cache_directives) == 0) {
1910  http_destroy_headers(cache_directives);
1911  return 1;
1912  }
1913 
1914  i = 0;
1915  while (i < gwlist_len(cache_directives)) {
1916  http_header_get(cache_directives, i, &header_name, &header_value);
1917  if (octstr_compare(header_value, octstr_imm("no-transform")) == 0) {
1918  http_destroy_headers(cache_directives);
1919  octstr_destroy(header_name);
1920  octstr_destroy(header_value);
1921  return 0;
1922  }
1923  ++i;
1924  }
1925 
1926  http_destroy_headers(cache_directives);
1927  octstr_destroy(header_name);
1928  octstr_destroy(header_value);
1929 
1930  return 1;
1931 }
List * http_header_find_all(List *headers, char *name)
Definition: http.c:3092
void http_header_get(List *headers, long i, Octstr **name, Octstr **value)
Definition: http.c:2879
long gwlist_len(List *list)
Definition: list.c:166
void http_destroy_headers(List *headers)
Definition: http.c:2856
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
gw_assert(wtls_machine->packet_to_send!=NULL)
Definition: octstr.c:118
Definition: list.c:102
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
static Octstr * convert_si_to_sic ( struct content content)
static

Definition at line 1947 of file wap_push_ppg.c.

References content::body, content::charset, si_compile(), and warning().

1948 {
1949  Octstr *sic;
1950 
1951  if (si_compile(content->body, content->charset, &sic) == 0)
1952  return sic;
1953  warning(0, "PPG: si compilation failed");
1954  return NULL;
1955 }
int si_compile(Octstr *si_doc, Octstr *charset, Octstr **si_binary)
Octstr * body
Definition: wap-appl.c:144
void warning(int err, const char *fmt,...)
Definition: log.c:624
Definition: octstr.c:118
Octstr * charset
Definition: wap-appl.c:146
static Octstr * convert_sl_to_slc ( struct content content)
static

Definition at line 1957 of file wap_push_ppg.c.

References content::body, content::charset, sl_compile(), and warning().

1958 {
1959  Octstr *slc;
1960 
1961  if (sl_compile(content->body, content->charset, &slc) == 0)
1962  return slc;
1963  warning(0, "PPG: sl compilation failed");
1964  return NULL;
1965 }
int sl_compile(Octstr *sl_doc, Octstr *charset, Octstr **sl_binary)
Octstr * body
Definition: wap-appl.c:144
void warning(int err, const char *fmt,...)
Definition: log.c:624
Definition: octstr.c:118
Octstr * charset
Definition: wap-appl.c:146
static Octstr * convert_wml_to_wmlc ( struct content content)
static

Definition at line 1937 of file wap_push_ppg.c.

References content::body, content::charset, warning(), and wml_compile().

1938 {
1939  Octstr *wmlc;
1940 
1941  if (wml_compile(content->body, content->charset, &wmlc, NULL) == 0)
1942  return wmlc;
1943  warning(0, "PPG: wml compilation failed");
1944  return NULL;
1945 }
Octstr * body
Definition: wap-appl.c:144
int wml_compile(Octstr *wml_text, Octstr *charset, Octstr **wml_binary, Octstr *version)
Definition: wml_compiler.c:360
void warning(int err, const char *fmt,...)
Definition: log.c:624
Definition: octstr.c:118
Octstr * charset
Definition: wap-appl.c:146
static int coriented_deliverable ( long  code)
static

Definition at line 2670 of file wap_push_ppg.c.

Referenced by handle_push_message().

2671 {
2672  return appid_code > -1;
2673 }
static void create_session ( WAPEvent e,
PPGPushMachine pm 
)
static

Definition at line 1476 of file wap_push_ppg.c.

References addr_tuple_change_cliport(), CONNECTIONLESS_PUSH_CLIPORT, dispatch_to_ota, dlr_url, gw_assert(), http_header_duplicate(), octstr_duplicate, PAPEvent::push_headers, push_machine_assert(), service_name, smsbox_id, smsc_id, WAPEvent::type, WAPEvent::u, and wap_event_create.

Referenced by handle_push_message().

1477 {
1478  WAPEvent *ota_event;
1479  List *push_headers;
1480  Octstr *smsc_id;
1481  Octstr *dlr_url;
1482  Octstr *smsbox_id;
1484 
1485  gw_assert(e->type == Push_Message);
1486  push_machine_assert(pm);
1487 
1488  push_headers = http_header_duplicate(e->u.Push_Message.push_headers);
1489  smsc_id = octstr_duplicate(e->u.Push_Message.smsc_id);
1490  dlr_url = octstr_duplicate(e->u.Push_Message.dlr_url);
1491  smsbox_id = octstr_duplicate(e->u.Push_Message.smsbox_id);
1492  service_name = octstr_duplicate(e->u.Push_Message.service_name);
1493 
1494  ota_event = wap_event_create(Pom_SessionRequest_Req);
1495  ota_event->u.Pom_SessionRequest_Req.addr_tuple =
1496  addr_tuple_change_cliport(pm->addr_tuple,
1498  ota_event->u.Pom_SessionRequest_Req.push_headers = push_headers;
1499  ota_event->u.Pom_SessionRequest_Req.push_id = pm->push_id;
1500  ota_event->u.Pom_SessionRequest_Req.address_type = pm->address_type;
1501  if (smsc_id != NULL)
1502  ota_event->u.Pom_SessionRequest_Req.smsc_id = smsc_id;
1503  else
1504  ota_event->u.Pom_SessionRequest_Req.smsc_id = NULL;
1505  if (dlr_url != NULL)
1506  ota_event->u.Pom_SessionRequest_Req.dlr_url = dlr_url;
1507  else
1508  ota_event->u.Pom_SessionRequest_Req.dlr_url = NULL;
1509  ota_event->u.Pom_SessionRequest_Req.dlr_mask = e->u.Push_Message.dlr_mask;
1510  if (smsbox_id != NULL)
1511  ota_event->u.Pom_SessionRequest_Req.smsbox_id = smsbox_id;
1512  else
1513  ota_event->u.Pom_SessionRequest_Req.smsbox_id = NULL;
1514  ota_event->u.Pom_SessionRequest_Req.service_name = service_name;
1515 
1516  dispatch_to_ota(ota_event);
1517 }
static Octstr * service_name
Definition: wap_push_ppg.c:205
static void push_machine_assert(PPGPushMachine *pm)
static Octstr * smsbox_id
Definition: smsbox.c:120
static Octstr * dlr_url
Definition: test_ppg.c:107
static wap_dispatch_func_t * dispatch_to_ota
Definition: wap_push_ppg.c:176
#define octstr_duplicate(ostr)
Definition: octstr.h:187
static Octstr * smsc_id
Definition: mtbatch.c:98
static WAPAddrTuple * addr_tuple_change_cliport(WAPAddrTuple *tuple, long port)
#define wap_event_create(type)
Definition: wap_events.h:107
gw_assert(wtls_machine->packet_to_send!=NULL)
Definition: octstr.c:118
WAPEventName type
Definition: wap_events.h:88
List * http_header_duplicate(List *headers)
Definition: http.c:2946
union WAPEvent::@87 u
Definition: list.c:102
static int date_item_compare ( Octstr before,
long  time_data,
long  pos 
)
static

Definition at line 2692 of file wap_push_ppg.c.

References octstr_parse_long().

Referenced by deliver_after_test_cleared(), and deliver_before_test_cleared().

2693 {
2694  long data;
2695 
2696  if (octstr_parse_long(&data, condition, pos, 10) < 0) {
2697  return 0;
2698  }
2699  if (data < time_data) {
2700  return -1;
2701  }
2702  if (data > time_data) {
2703  return 1;
2704  }
2705 
2706  return 0;
2707 }
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
Definition: octstr.c:747
static int deliver_after_test_cleared ( Octstr after,
struct tm  now 
)
static

Definition at line 2741 of file wap_push_ppg.c.

References date_item_compare(), initialize_time_item_array(), and octstr_len().

Referenced by delivery_time_constraints().

2742 {
2743  long time_data[6];
2744  long j;
2745 
2746  if (after == NULL)
2747  return 1;
2748 
2749  initialize_time_item_array(time_data, now);
2750  if (date_item_compare(after, time_data[0], 0) == -1)
2751  return 1;
2752  if (date_item_compare(after, time_data[0], 0) == 1)
2753  return 0;
2754 
2755  for (j = 5; j < octstr_len(after); j += 3) {
2756  if (date_item_compare(after, time_data[(j-5)/3 + 1], j) == -1)
2757  return 1;
2758  if (date_item_compare(after, time_data[(j-5)/3 + 1], j) == 1)
2759  return 0;
2760  }
2761 
2762  return 0;
2763 }
static int date_item_compare(Octstr *before, long time_data, long pos)
static void initialize_time_item_array(long time_data[], struct tm now)
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
static int deliver_before_test_cleared ( Octstr before,
struct tm  now 
)
static

Definition at line 2713 of file wap_push_ppg.c.

References date_item_compare(), initialize_time_item_array(), and octstr_len().

Referenced by delivery_time_constraints().

2714 {
2715  long time_data[6];
2716  long j;
2717 
2718  if (before == NULL)
2719  return 1;
2720 
2721  initialize_time_item_array(time_data, now);
2722  if (date_item_compare(before, time_data[0], 0) == 1)
2723  return 1;
2724  if (date_item_compare(before, time_data[0], 0) == -1)
2725  return 0;
2726 
2727  for (j = 5; j < octstr_len(before); j += 3) {
2728  if (date_item_compare(before, time_data[(j-5)/3 + 1], j) == 1)
2729  return 1;
2730  if (date_item_compare(before, time_data[(j-5)/3 + 1], j) == -1)
2731  return 0;
2732  }
2733 
2734  return 0;
2735 }
static int date_item_compare(Octstr *before, long time_data, long pos)
static void initialize_time_item_array(long time_data[], struct tm now)
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
static void deliver_confirmed_push ( long  last,
PPGPushMachine pm,
PPGSessionMachine sm 
)
static

Definition at line 2322 of file wap_push_ppg.c.

References request_confirmed_push().

Referenced by handle_push_message().

2324 {
2325  request_confirmed_push(last, pm, sm);
2326 }
static void request_confirmed_push(long last, PPGPushMachine *pm, PPGSessionMachine *sm)
static void deliver_pending_pushes ( PPGSessionMachine sm,
int  last 
)
static

Definition at line 2356 of file wap_push_ppg.c.

References gw_assert(), gwlist_get(), gwlist_len(), PAP_DELIVERED1, PAP_UNCONFIRMED, push_machine_assert(), remove_push_data(), request_confirmed_push(), request_push(), session_machine_assert(), and update_push_data_with_attribute().

Referenced by handle_internal_event().

2357 {
2358  PPGPushMachine *pm;
2359  long i;
2360 
2362  gw_assert(gwlist_len(sm->push_machines) > 0);
2363 
2364  i = 0;
2365  while (i < gwlist_len(sm->push_machines)) {
2366  pm = gwlist_get(sm->push_machines, i);
2367  push_machine_assert(pm);
2368 
2369  if (pm->delivery_method == PAP_UNCONFIRMED) {
2370  request_push(last, pm);
2372  PAP_DELIVERED1);
2373  remove_push_data(sm, pm, sm == NULL);
2374  } else {
2375  request_confirmed_push(last, pm, sm);
2376  ++i;
2377  }
2378  }
2379 }
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
static void remove_push_data(PPGSessionMachine *sm, PPGPushMachine *pm, int cless)
static void request_confirmed_push(long last, PPGPushMachine *pm, PPGSessionMachine *sm)
static void push_machine_assert(PPGPushMachine *pm)
static PPGPushMachine * update_push_data_with_attribute(PPGSessionMachine **sm, PPGPushMachine *pm, long reason, long status)
static void request_push(long last, PPGPushMachine *sm)
static void session_machine_assert(PPGSessionMachine *sm)
gw_assert(wtls_machine->packet_to_send!=NULL)
static PPGPushMachine * deliver_unit_push ( long  last,
PPGPushMachine pm,
PPGSessionMachine sm,
int  session_exists 
)
static

Definition at line 2335 of file wap_push_ppg.c.

References info(), PAP_DELIVERED1, PAP_UNCONFIRMED, push_machine_assert(), request_push(), request_unit_push(), and update_push_data_with_attribute().

Referenced by handle_push_message().

2337 {
2338  push_machine_assert(pm);
2339 
2340  if (!session_exists)
2341  request_unit_push(last, pm);
2342  else
2343  request_push(last, pm);
2344 
2346  PAP_DELIVERED1);
2347  info(0, "PPG: unconfirmed push delivered to OTA");
2348 
2349  return pm;
2350 }
void info(int err, const char *fmt,...)
Definition: log.c:636
static void request_unit_push(long last, PPGPushMachine *pm)
static void push_machine_assert(PPGPushMachine *pm)
static PPGPushMachine * update_push_data_with_attribute(PPGSessionMachine **sm, PPGPushMachine *pm, long reason, long status)
static void request_push(long last, PPGPushMachine *sm)
static int delivery_time_constraints ( WAPEvent e,
PPGPushMachine pm 
)
static

Definition at line 2171 of file wap_push_ppg.c.

References debug(), deliver_after_test_cleared(), deliver_before_test_cleared(), gw_assert(), gw_gmtime(), info(), WAPEvent::type, and WAPEvent::u.

Referenced by handle_push_message().

2172 {
2173  Octstr *before,
2174  *after;
2175  struct tm now;
2176 
2177  gw_assert(e->type == Push_Message);
2178 
2179  before = e->u.Push_Message.deliver_before_timestamp;
2180  after = pm->deliver_after_timestamp;
2181  now = gw_gmtime(time(NULL));
2182 
2183  if (!deliver_before_test_cleared(before, now)) {
2184  info(0, "PPG: delivery deadline expired, dropping the push message");
2185  return 0;
2186  }
2187 
2188  if (!deliver_after_test_cleared(after, now)) {
2189  debug("wap.push.ppg", 0, "PPG: too early to push the message,"
2190  " waiting");
2191  return 1;
2192  }
2193 
2194  return 2;
2195 }
void info(int err, const char *fmt,...)
Definition: log.c:636
struct tm gw_gmtime(time_t t)
Definition: protected.c:137
static int deliver_before_test_cleared(Octstr *before, struct tm now)
gw_assert(wtls_machine->packet_to_send!=NULL)
static int deliver_after_test_cleared(Octstr *after, struct tm now)
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
WAPEventName type
Definition: wap_events.h:88
union WAPEvent::@87 u
static Octstr * describe_code ( long  code)
static

Definition at line 2238 of file wap_push_ppg.c.

References desc_tab_size, description, octstr_create, octstr_imm(), and description_t::reason.

Referenced by response_push_message(), tell_fatal_error(), and update_push_data_with_attribute().

2239 {
2240  Octstr *desc;
2241  size_t i;
2242 
2243  for (i = 0; i < desc_tab_size; i++) {
2244  if (pap_desc[i].reason == code) {
2245  desc = octstr_create(pap_desc[i].description);
2246  return desc;
2247  }
2248  }
2249 
2250  return octstr_imm("unknown PAP code");
2251 }
int code
Definition: smsc_cimd2.c:346
char * description
Definition: ws.c:100
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
static size_t desc_tab_size
#define octstr_create(cstr)
Definition: octstr.h:125
Definition: octstr.c:118
static description_t pap_desc[]
static Octstr * escape_fragment ( Octstr fragment)
static

Definition at line 3223 of file wap_push_ppg.c.

References octstr_get_char(), octstr_imm(), octstr_len(), and replace_octstr_char().

Referenced by send_bad_message_response().

3224 {
3225  long i;
3226  int c;
3227 
3228  i = 0;
3229  while (i < octstr_len(fragment)) {
3230  if ((c = octstr_get_char(fragment, i)) == '"') {
3231  replace_octstr_char(fragment, octstr_imm("&quot;"), &i);
3232  } else if (c == '<') {
3233  replace_octstr_char(fragment, octstr_imm("&lt;"), &i);
3234  } else if (c == '>') {
3235  replace_octstr_char(fragment, octstr_imm("&gt;"), &i);
3236  } else if (c == '&') {
3237  replace_octstr_char(fragment, octstr_imm("&amp;"), &i);
3238  }
3239  ++i;
3240  }
3241 
3242  return fragment;
3243 }
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
static void replace_octstr_char(Octstr *os1, Octstr *os2, long *pos)
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
static Octstr* extract_base64 ( struct content content)
static

Definition at line 1968 of file wap_push_ppg.c.

References content::body, octstr_base64_to_binary(), and octstr_duplicate.

1969 {
1970  Octstr *orig = octstr_duplicate(content->body);
1972  return orig;
1973 }
Octstr * body
Definition: wap-appl.c:144
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void octstr_base64_to_binary(Octstr *ostr)
Definition: octstr.c:661
Definition: octstr.c:118
static PPGPushMachine * find_ppg_push_machine_using_pi_push_id ( PPGSessionMachine sm,
Octstr pi_push_id 
)
static

Definition at line 2526 of file wap_push_ppg.c.

References gw_assert(), gwlist_search(), push_has_pi_push_id(), and session_machine_assert().

Referenced by store_push_data().

2528 {
2529  PPGPushMachine *pm;
2530 
2531  gw_assert(pi_push_id);
2533 
2534  pm = gwlist_search(sm->push_machines, pi_push_id, push_has_pi_push_id);
2535 
2536  return pm;
2537 }
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
Definition: list.c:486
static void session_machine_assert(PPGSessionMachine *sm)
gw_assert(wtls_machine->packet_to_send!=NULL)
static int push_has_pi_push_id(void *a, void *b)
static PPGPushMachine * find_ppg_push_machine_using_pid ( PPGSessionMachine sm,
long  pid 
)
static

Definition at line 2502 of file wap_push_ppg.c.

References gw_assert(), gwlist_search(), push_has_pid(), and session_machine_assert().

Referenced by handle_internal_event().

2504 {
2505  PPGPushMachine *pm;
2506 
2507  gw_assert(pid >= 0);
2509 
2510  pm = gwlist_search(sm->push_machines, &pid, push_has_pid);
2511 
2512  return pm;
2513 }
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
Definition: list.c:486
static int push_has_pid(void *a, void *b)
static void session_machine_assert(PPGSessionMachine *sm)
gw_assert(wtls_machine->packet_to_send!=NULL)
static PPGPushMachine * find_unit_ppg_push_machine_using_pi_push_id ( Octstr pi_push_id)
static

Definition at line 2539 of file wap_push_ppg.c.

References gw_assert(), gwlist_search(), and push_has_pi_push_id().

Referenced by store_push_data().

2541 {
2542  PPGPushMachine *pm;
2543 
2544  gw_assert(pi_push_id);
2546 
2547  return pm;
2548 }
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
Definition: list.c:486
static List * ppg_unit_pushes
Definition: wap_push_ppg.c:149
gw_assert(wtls_machine->packet_to_send!=NULL)
static int push_has_pi_push_id(void *a, void *b)
static int get_mime_boundary ( List push_headers,
Octstr content_header,
Octstr **  boundary 
)
static

Definition at line 2959 of file wap_push_ppg.c.

References octstr_case_search(), octstr_copy, octstr_get_char(), octstr_imm(), octstr_len(), and warning().

Referenced by pap_request_thread().

2961 {
2962  long pos;
2963  Octstr *bos;
2964  int c, quoted = 0;
2965  long bstart;
2966 
2967  pos = 0;
2968  if ((pos = octstr_case_search(content_header,
2969  bos = octstr_imm("boundary="), 0)) < 0) {
2970  warning(0, "PPG: get_mime_boundary: no boundary specified");
2971  return -1;
2972  }
2973 
2974  pos += octstr_len(bos);
2975  if (octstr_get_char(content_header, pos) == '"') {
2976  ++pos;
2977  quoted = 1;
2978  }
2979 
2980  bstart = pos;
2981  while ((c = octstr_get_char(content_header, pos)) != -1) {
2982  if (c == ';' || (quoted && c == '"') || (!quoted && c == ' '))
2983  break;
2984  ++pos;
2985  }
2986  *boundary = octstr_copy(content_header, bstart, pos - bstart);
2987 
2988  return 0;
2989 }
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
long octstr_case_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1100
void warning(int err, const char *fmt,...)
Definition: log.c:624
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
static void handle_internal_event ( WAPEvent e)
static

Definition at line 1199 of file wap_push_ppg.c.

References abort_delivery(), debug(), deliver_pending_pushes(), find_ppg_push_machine_using_pid(), HTTP_OK, NOT_LAST, PAP_ABORTED, PAP_CONFIRMED, PAP_DELIVERED2, WAPAddr::port, port, push_machine_assert(), WAPAddrTuple::remote, remove_push_data(), remove_session_data(), response_push_connection(), session_machine_assert(), WAPEvent::type, WAPEvent::u, update_push_data_with_attribute(), update_session_data(), wap_event_destroy(), wap_event_dump(), wap_push_ppg_have_push_session_for(), and wap_push_ppg_have_push_session_for_sid().

Referenced by ota_read_thread().

1200 {
1201  long sid,
1202  pid,
1203  reason,
1204  port;
1205  int http_status;
1206  PPGPushMachine *pm;
1207  PPGSessionMachine *sm;
1208  WAPAddrTuple *tuple;
1209  List *caps;
1210 
1211  http_status = HTTP_OK;
1212  switch (e->type) {
1213 /*
1214  * Pap, Chapter 11.1.3 states that if client is incapable, we should abort the
1215  * push and inform PI. We do this here.
1216  * In addition, we store session id used as an alias for address tuple and do
1217  * all pushes pending for this initiator (or abort them).
1218  */
1219  case Pom_Connect_Ind:
1220  debug("wap.push.ppg", 0, "PPG: handle_internal_event: connect"
1221  " indication from OTA");
1222  sid = e->u.Pom_Connect_Ind.session_id;
1223  tuple = e->u.Pom_Connect_Ind.addr_tuple;
1224  port = tuple->remote->port;
1225  caps = e->u.Pom_Connect_Ind.requested_capabilities;
1226 
1228  sm = update_session_data(sm, sid, port, caps);
1229 
1230  if (!response_push_connection(e, sm)) {
1231  pm = abort_delivery(sm, http_status);
1232  wap_event_destroy(e);
1233  return;
1234  }
1235 
1236 /*
1237  * hard-coded until we have bearer control implemented
1238  */
1240  wap_event_destroy(e);
1241  break;
1242 
1243  case Pom_Disconnect_Ind:
1244  debug("wap.push.ppg", 0, "PPG: handle_internal_event: disconnect"
1245  " indication from OTA");
1247  e->u.Pom_Disconnect_Ind.session_handle);
1248  remove_session_data(sm, http_status);
1249  wap_event_destroy(e);
1250  break;
1251 
1252 /*
1253  * Only the client can close a session. So we leave session open, even when
1254  * there are no active pushes. Note that we do not store PAP attribute very
1255  * long time. Point is that result notification message, if asked, will rep-
1256  * ort this fact to PI, after which there is no need to store it any more.
1257  */
1258  case Po_ConfirmedPush_Cnf:
1259  debug("wap.push.ppg", 0, "PPG: handle_internal_event: push"
1260  " confirmation from OTA");
1261  sid = e->u.Po_ConfirmedPush_Cnf.session_handle;
1262  pid = e->u.Po_ConfirmedPush_Cnf.server_push_id;
1263 
1265  pm = find_ppg_push_machine_using_pid(sm, pid);
1267  PAP_DELIVERED2);
1268  wap_event_destroy(e);
1269  remove_push_data(sm, pm, 0);
1270  break;
1271 
1272 /*
1273  * Again, PAP attribute will be reported to PI by using result notification.
1274  */
1275  case Po_PushAbort_Ind:
1276  debug("wap.push.ppg", 0, "PPG: handle_internal_event: abort"
1277  " indication from OTA");
1278  sid = e->u.Po_PushAbort_Ind.session_handle;
1279  pid = e->u.Po_PushAbort_Ind.push_id;
1280 
1282  pm = find_ppg_push_machine_using_pid(sm, pid);
1284  push_machine_assert(pm);
1285  reason = e->u.Po_PushAbort_Ind.reason;
1286  pm = update_push_data_with_attribute(&sm, pm, reason, PAP_ABORTED);
1287  remove_session_data(sm, http_status);
1288  wap_event_destroy(e);
1289  break;
1290 
1291 /*
1292  * FIXME TRU: Add timeout (a mandatory feature!)
1293  */
1294  default:
1295  debug("wap.ppg", 0, "PPG: handle_internal_event: an unhandled event");
1296  wap_event_dump(e);
1297  wap_event_destroy(e);
1298  break;
1299  }
1300 }
PPGSessionMachine * wap_push_ppg_have_push_session_for(WAPAddrTuple *tuple)
Definition: wap_push_ppg.c:488
static int response_push_connection(WAPEvent *e, PPGSessionMachine *sm)
static void remove_push_data(PPGSessionMachine *sm, PPGPushMachine *pm, int cless)
static void push_machine_assert(PPGPushMachine *pm)
static PPGPushMachine * update_push_data_with_attribute(PPGSessionMachine **sm, PPGPushMachine *pm, long reason, long status)
void wap_event_dump(WAPEvent *event)
Definition: wap_events.c:181
static int port
Definition: fakesmsc.c:120
Definition: http.h:142
static PPGPushMachine * abort_delivery(PPGSessionMachine *sm, int status)
long port
Definition: wap_addr.h:70
static void session_machine_assert(PPGSessionMachine *sm)
static PPGPushMachine * find_ppg_push_machine_using_pid(PPGSessionMachine *sm, long pid)
WAPAddr * remote
Definition: wap_addr.h:74
static void deliver_pending_pushes(PPGSessionMachine *sm, int last)
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static void remove_session_data(PPGSessionMachine *sm, int status)
WAPEventName type
Definition: wap_events.h:88
union WAPEvent::@87 u
static PPGSessionMachine * update_session_data(PPGSessionMachine *sm, long sid, long port, List *caps)
Definition: list.c:102
void wap_event_destroy(WAPEvent *event)
Definition: wap_events.c:102
PPGSessionMachine * wap_push_ppg_have_push_session_for_sid(long sid)
Definition: wap_push_ppg.c:503
static int handle_push_message ( HTTPClient **  c,
WAPEvent ppg_event,
int  status 
)
static

Definition at line 1054 of file wap_push_ppg.c.

References check_x_wap_application_id_header(), cless_accepted(), confirmation_requested(), coriented_deliverable(), create_session(), deliver_confirmed_push(), deliver_unit_push(), delivery_time_constraints(), http_header_mark_transformation(), http_header_remove_all(), info(), NO_CONSTRAINTS, NOT_LAST, octstr_destroy(), PAP_ACCEPTED_FOR_PROCESSING, PAP_ADDRESS_ERROR, PAP_BAD_REQUEST, PAP_DUPLICATE_PUSH_ID, PAP_EXPIRED, PAP_FORBIDDEN, PAP_PENDING, PAP_REQUIRED_BEARER_NOT_AVAILABLE, PAP_TRANSFORMATION_FAILURE, PAP_UNDELIVERABLE1, PAP_UNDELIVERABLE2, PAPEvent::push_headers, remove_push_data(), remove_pushless_session(), response_push_message(), select_bearer_network(), session_find_using_pi_client_address(), store_push_data(), store_session_data(), TIME_EXPIRED, TIME_TOO_EARLY, transform_message(), type, WAPEvent::u, update_push_data_with_attribute(), update_session_data_with_headers(), wap_addr_tuple_destroy(), wap_event_destroy(), and warning().

Referenced by pap_request_thread().

1055 {
1056  int cless,
1057  session_exists,
1058  bearer_supported,
1059  dummy,
1060  constraints,
1061  message_transformable,
1062  coriented_possible;
1063 
1064  long coded_appid_value;
1065 
1066  PPGPushMachine *pm;
1067  PPGSessionMachine *sm;
1068  WAPAddrTuple *tuple=NULL;
1069  Octstr *cliaddr=NULL;
1070  Octstr *type=NULL;
1071 
1072  List *push_headers;
1073 
1074  push_headers = e->u.Push_Message.push_headers;
1075  cliaddr = e->u.Push_Message.address_value;
1076  session_exists = 0;
1077 
1079  coded_appid_value = check_x_wap_application_id_header(&push_headers);
1080  cless = cless_accepted(e, sm);
1081  message_transformable = transform_message(&e, &tuple, push_headers, cless,
1082  &type);
1083 
1084  if (!sm && !cless) {
1085  sm = store_session_data(sm, e, tuple, &session_exists);
1086  }
1087 
1088  if (!store_push_data(&pm, sm, e, tuple, cless)) {
1089  warning(0, "PPG: handle_push_message: duplicate push id");
1091  goto no_start;
1092  }
1093 
1094  if (!message_transformable) {
1095  pm = update_push_data_with_attribute(&sm, pm,
1097  if (tuple != NULL)
1099  else
1101  goto no_transformation;
1102  }
1103 
1104  dummy = 0;
1105  pm = update_push_data_with_attribute(&sm, pm, dummy, PAP_PENDING);
1106 
1107  bearer_supported = select_bearer_network(&e);
1108  if (!bearer_supported) {
1109  pm = update_push_data_with_attribute(&sm, pm, dummy,
1112  goto no_start;
1113  }
1114 
1115  if ((constraints = delivery_time_constraints(e, pm)) == TIME_EXPIRED) {
1117  PAP_EXPIRED);
1119  goto no_start;
1120  }
1121 
1122 /*
1123  * If time is to early for delivering the push message, we do not remove push
1124  * data. We response PI here, so that "accepted for processing" means "no
1125  * error messages to come".
1126  */
1127 
1129  info(0, "PPG: handle_push_message: push message accepted for processing");
1130 
1131  if (constraints == TIME_TOO_EARLY)
1132  goto store_push;
1133 
1134  if (constraints == NO_CONSTRAINTS) {
1135  http_header_mark_transformation(pm->push_headers, pm->push_data, type);
1136  if (sm)
1137  sm = update_session_data_with_headers(sm, pm);
1138 
1139  if (!confirmation_requested(e)) {
1140  pm = deliver_unit_push(NOT_LAST, pm, sm, session_exists);
1141  goto unit_push_delivered;
1142  }
1143 
1144  if (session_exists) {
1145  deliver_confirmed_push(NOT_LAST, pm, sm);
1146  } else {
1147  coriented_possible = coriented_deliverable(coded_appid_value);
1148  http_header_remove_all(e->u.Push_Message.push_headers,
1149  "Content-Type");
1150  if (coriented_possible) {
1151  create_session(e, pm);
1152  } else {
1153  warning(0, "PPG: handle_push_message: wrong app id for confirmed"
1154  " push session creation");
1156  }
1157  }
1158  }
1159 
1160  wap_addr_tuple_destroy(tuple);
1161  octstr_destroy(type);
1162  wap_event_destroy(e);
1163  return 1;
1164 
1165 unit_push_delivered:
1166  wap_addr_tuple_destroy(tuple);
1167  remove_push_data(sm, pm, cless);
1168  octstr_destroy(type);
1169  wap_event_destroy(e);
1170  return 1;
1171 
1172 store_push:
1173  wap_addr_tuple_destroy(tuple);
1174  octstr_destroy(type);
1175  wap_event_destroy(e);
1176  return 1;
1177 
1178 no_transformation:
1179  wap_addr_tuple_destroy(tuple);
1180  remove_push_data(sm, pm, cless);
1181  if (sm)
1183  wap_event_destroy(e);
1184  return 0;
1185 
1186 no_start:
1187  wap_addr_tuple_destroy(tuple);
1188  octstr_destroy(type);
1189  remove_push_data(sm, pm, cless);
1190  if (sm)
1192  wap_event_destroy(e);
1193  return 1;
1194 }
static int confirmation_requested(WAPEvent *e)
void info(int err, const char *fmt,...)
Definition: log.c:636
static int cless_accepted(WAPEvent *e, PPGSessionMachine *sm)
static int transform_message(WAPEvent **e, WAPAddrTuple **tuple, List *push_headers, int connected, Octstr **type)
static void deliver_confirmed_push(long last, PPGPushMachine *pm, PPGSessionMachine *sm)
static long check_x_wap_application_id_header(List **push_headers)
static void remove_push_data(PPGSessionMachine *sm, PPGPushMachine *pm, int cless)
static void remove_pushless_session(PPGSessionMachine *sm)
static PPGPushMachine * update_push_data_with_attribute(PPGSessionMachine **sm, PPGPushMachine *pm, long reason, long status)
void http_header_mark_transformation(List *headers, Octstr *new_body, Octstr *new_type)
Definition: http.c:3180
static int select_bearer_network(WAPEvent **e)
static int store_push_data(PPGPushMachine **pm, PPGSessionMachine *sm, WAPEvent *e, WAPAddrTuple *tuple, int cless)
static PPGSessionMachine * session_find_using_pi_client_address(Octstr *addr)
static HTTPClient * response_push_message(PPGPushMachine *pm, long code, int status)
static PPGSessionMachine * store_session_data(PPGSessionMachine *sm, WAPEvent *e, WAPAddrTuple *tuple, int *session_exists)
void warning(int err, const char *fmt,...)
Definition: log.c:624
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
void wap_addr_tuple_destroy(WAPAddrTuple *tuple)
Definition: wap_addr.c:108
static int delivery_time_constraints(WAPEvent *e, PPGPushMachine *pm)
static int coriented_deliverable(long code)
static PPGPushMachine * deliver_unit_push(long last, PPGPushMachine *pm, PPGSessionMachine *sm, int session_exists)
Definition: octstr.c:118
long http_header_remove_all(List *headers, char *name)
Definition: http.c:3112
static void create_session(WAPEvent *e, PPGPushMachine *pm)
Definition: list.c:102
void wap_event_destroy(WAPEvent *event)
Definition: wap_events.c:102
static PPGSessionMachine * update_session_data_with_headers(PPGSessionMachine *sm, PPGPushMachine *pm)
char * type
static int headers_acceptable ( List push_headers,
Octstr **  content_header 
)
static

Definition at line 2904 of file wap_push_ppg.c.

References error(), gw_assert(), http_header_find_first, octstr_format(), type_is(), and warning().

Referenced by pap_request_thread().

2905 {
2906  gw_assert(push_headers);
2907  *content_header = http_header_find_first(push_headers, "Content-Type");
2908 
2909  if (*content_header == NULL) {
2910  *content_header = octstr_format("%s", "no content type header found");
2911  goto error;
2912  }
2913 
2914  if (!type_is(*content_header, "multipart/related")) {
2915  goto error;
2916  }
2917 
2918  if (!type_is(*content_header, "application/xml")) {
2919  goto error;
2920  }
2921 
2922  return 1;
2923 
2924 error:
2925  warning(0, "PPG: headers_acceptable: got unacceptable push headers");
2926  return 0;
2927 }
void error(int err, const char *fmt,...)
Definition: log.c:612
static int type_is(Octstr *content_header, char *required_type)
#define http_header_find_first(headers, name)
Definition: http.h:592
void warning(int err, const char *fmt,...)
Definition: log.c:624
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
gw_assert(wtls_machine->packet_to_send!=NULL)
static void http_read_thread ( void *  arg)
static

Definition at line 688 of file wap_push_ppg.c.

References PAPEvent::cgivars, client(), gwlist_produce(), http_accept_request(), PAPEvent::ip, PAPEvent::mime_content, pap_event_create(), ppg_port, PAPEvent::push_headers, run_status, running, and url.

Referenced by wap_push_ppg_init(), and wap_push_ppg_shutdown().

689 {
690  PAPEvent *p;
691  Octstr *ip;
692  Octstr *url;
693  List *push_headers;
694  Octstr *mime_content;
695  List *cgivars;
697 
698  while (run_status == running) {
699  client = http_accept_request(ppg_port, &ip, &url, &push_headers,
700  &mime_content, &cgivars);
701  if (client == NULL)
702  break;
703 
704  p = pap_event_create(ip, url, push_headers, mime_content, cgivars,
705  client);
707  }
708 }
void gwlist_produce(List *list, void *item)
Definition: list.c:411
static void client(int port)
Definition: test_udp.c:77
static enum @39 run_status
HTTPClient * http_accept_request(int port, Octstr **client_ip, Octstr **url, List **headers, Octstr **body, List **cgivars)
Definition: http.c:2574
static long ppg_port
Definition: wap_push_ppg.c:185
Definition: octstr.c:118
static PAPEvent * pap_event_create(Octstr *ip, Octstr *url, List *push_headers, Octstr *mime_content, List *cgivars, HTTPClient *client)
Definition: wap_push_ppg.c:646
static List * pap_queue
Definition: wap_push_ppg.c:138
static Octstr * url
Definition: test_xmlrpc.c:84
Definition: list.c:102
static void initialize_time_item_array ( long  time_data[],
struct tm  now 
)
static

Definition at line 2682 of file wap_push_ppg.c.

Referenced by deliver_after_test_cleared(), and deliver_before_test_cleared().

2683 {
2684  time_data[0] = now.tm_year + 1900;
2685  time_data[1] = now.tm_mon + 1;
2686  time_data[2] = now.tm_mday;
2687  time_data[3] = now.tm_hour;
2688  time_data[4] = now.tm_min;
2689  time_data[5] = now.tm_sec;
2690 }
static int ip_allowed_by_ppg ( Octstr ip)
static

Definition at line 586 of file wap_push_ppg.c.

References debug(), error(), octstr_compare(), octstr_imm(), panic, trusted_pi, wap_push_ppg_pushuser_search_ip_from_wildcarded_list(), and warning().

Referenced by pap_request_thread().

587 {
588  if (ip == NULL)
589  return 0;
590 
591  if (trusted_pi)
592  return 1;
593 
594  if (ppg_deny_ip == NULL && ppg_allow_ip == NULL) {
595  warning(0, "Your ppg core configuration lacks allowed and denied"
596  " ip lists");
597  return 1;
598  }
599 
600  if (ppg_deny_ip)
601  if (octstr_compare(ppg_deny_ip, octstr_imm("*.*.*.*")) == 0) {
602  panic(0, "Your ppg core configuration deny all ips, exiting");
603  return 0;
604  }
605 
606  if (ppg_allow_ip)
607  if (octstr_compare(ppg_allow_ip, octstr_imm("*.*.*.*")) == 0) {
608  warning(0, "Your ppg core configuration allow all ips");
609  return 1;
610  }
611 
612  if (ppg_deny_ip)
614  octstr_imm(";"), octstr_imm("."))) {
615  error(0, "ip found from denied list");
616  return 0;
617  }
618 
619  if (ppg_allow_ip)
621  octstr_imm(";"), octstr_imm("."))) {
622  debug("wap.push.ppg.pushuser", 0, "PPG: ip_allowed_by_ppg: ip found"
623  " from allowed list");
624  return 1;
625  }
626 
627  warning(0, "did not found ip from any of core lists, deny it");
628  return 0;
629 }
void error(int err, const char *fmt,...)
Definition: log.c:612
static Octstr * ppg_allow_ip
Definition: wap_push_ppg.c:195
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
int wap_push_ppg_pushuser_search_ip_from_wildcarded_list(Octstr *haystack, Octstr *needle, Octstr *gwlist_sep, Octstr *ip_sep)
void warning(int err, const char *fmt,...)
Definition: log.c:624
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
#define panic
Definition: log.h:87
static Octstr * ppg_deny_ip
Definition: wap_push_ppg.c:194
static int trusted_pi
Definition: wap_push_ppg.c:192
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
static int is_phone_number ( long  type_of_address)
static

Definition at line 3245 of file wap_push_ppg.c.

References ADDR_PLMN.

Referenced by pap_request_thread().

3246 {
3247  return address_type == ADDR_PLMN;
3248 }
static char * address_type(long type_of_address)
static long ota_abort_to_pap ( long  reason)
static

Definition at line 2645 of file wap_push_ppg.c.

References description_t::reason.

Referenced by update_push_data_with_attribute().

2646 {
2647  long offset;
2648 
2649  offset = reason - 0xEA;
2650  reason = 5026 + offset;
2651 
2652  return reason;
2653 }
static void ota_read_thread ( void *  arg)
static

Definition at line 634 of file wap_push_ppg.c.

References gwlist_consume(), handle_internal_event(), run_status, and running.

Referenced by wap_push_ppg_init(), and wap_push_ppg_shutdown().

635 {
636  WAPEvent *e;
637 
638  while (run_status == running && (e = gwlist_consume(ppg_queue)) != NULL) {
640  }
641 }
static List * ppg_queue
Definition: wap_push_ppg.c:133
static enum @39 run_status
void * gwlist_consume(List *list)
Definition: list.c:427
static void handle_internal_event(WAPEvent *e)
static int pap_convert_content ( struct content content)
static

Definition at line 2007 of file wap_push_ppg.c.

References content::body, converters, NUM_CONVERTERS, octstr_compare(), octstr_create, octstr_destroy(), octstr_imm(), result_type, content::type, and type.

Referenced by transform_message().

2008 {
2009  long i;
2010  Octstr *new_body;
2011 
2012  for (i = 0; i < NUM_CONVERTERS; i++) {
2013  if (octstr_compare(content->type,
2014  octstr_imm(converters[i].type)) == 0) {
2015  new_body = converters[i].convert(content);
2016  if (new_body == NULL)
2017  return 0;
2018  octstr_destroy(content->body);
2019  content->body = new_body;
2020  octstr_destroy(content->type);
2021  content->type = octstr_create(converters[i].result_type);
2022  return 1;
2023  }
2024  }
2025 
2026  return 1;
2027 }
Octstr * body
Definition: wap-appl.c:144
static struct @41 converters[]
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Octstr * type
Definition: wap-appl.c:145
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
#define NUM_CONVERTERS
Definition: octstr.c:118
char * type
char * result_type
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
static PAPEvent * pap_event_create ( Octstr ip,
Octstr url,
List push_headers,
Octstr mime_content,
List cgivars,
HTTPClient client 
)
static

Definition at line 646 of file wap_push_ppg.c.

References PAPEvent::cgivars, client(), PAPEvent::client, PAPEvent::ip, PAPEvent::mime_content, PAPEvent::push_headers, url, and PAPEvent::url.

Referenced by http_read_thread().

649 {
650  PAPEvent *p;
651 
652  p = gw_malloc(sizeof(PAPEvent));
653  p->ip = ip;
654  p->url = url;
655  p->push_headers = push_headers;
656  p->mime_content = mime_content;
657  p->cgivars = cgivars;
658  p->client = client;
659 
660  return p;
661 }
List * push_headers
Definition: wap_push_ppg.c:211
static void client(int port)
Definition: test_udp.c:77
Octstr * ip
Definition: wap_push_ppg.c:209
List * cgivars
Definition: wap_push_ppg.c:213
Octstr * mime_content
Definition: wap_push_ppg.c:212
Octstr * url
Definition: wap_push_ppg.c:210
static Octstr * url
Definition: test_xmlrpc.c:84
HTTPClient * client
Definition: wap_push_ppg.c:208
static void pap_event_destroy ( PAPEvent p)
static

Definition at line 663 of file wap_push_ppg.c.

Referenced by pap_event_destroy_item(), and pap_request_thread().

664 {
665  if (p == NULL)
666  return;
667 
668  gw_free(p);
669 }
static void pap_event_destroy_item ( void *  p)
static

Definition at line 671 of file wap_push_ppg.c.

References pap_event_destroy().

Referenced by wap_push_ppg_shutdown().

672 {
674 }
static void pap_event_destroy(PAPEvent *p)
Definition: wap_push_ppg.c:663
static void pap_event_unpack ( PAPEvent p,
Octstr **  ip,
Octstr **  url,
List **  push_headers,
Octstr **  mime_content,
List **  cgivars,
HTTPClient **  client 
)
static

Definition at line 676 of file wap_push_ppg.c.

References PAPEvent::cgivars, PAPEvent::client, PAPEvent::ip, PAPEvent::mime_content, PAPEvent::push_headers, and PAPEvent::url.

Referenced by pap_request_thread().

679 {
680  *ip = p->ip;
681  *url = p->url;
682  *push_headers = p->push_headers;
683  *mime_content = p->mime_content;
684  *cgivars = p->cgivars;
685  *client = p->client;
686 }
List * push_headers
Definition: wap_push_ppg.c:211
Octstr * ip
Definition: wap_push_ppg.c:209
List * cgivars
Definition: wap_push_ppg.c:213
Octstr * mime_content
Definition: wap_push_ppg.c:212
Octstr * url
Definition: wap_push_ppg.c:210
HTTPClient * client
Definition: wap_push_ppg.c:208
static int pap_get_content ( struct content content)
static

Definition at line 2034 of file wap_push_ppg.c.

References content::body, extractors, NUM_EXTRACTORS, octstr_case_compare(), octstr_destroy(), octstr_imm(), transfer_encoding, and content::type.

Referenced by transform_message().

2035 {
2036  long i;
2037  Octstr *new_body;
2038 
2039  for (i = 0; i < NUM_EXTRACTORS; i++) {
2040  if (octstr_case_compare(content->type,
2042 
2043  new_body = extractors[i].extract(content);
2044  if (new_body == NULL)
2045  return 0;
2046  octstr_destroy(content->body);
2047  content->body = new_body;
2048  octstr_destroy(content->type);
2049  content->type = NULL;
2050  return 1;
2051  }
2052  }
2053 
2054  return 1;
2055 }
#define NUM_EXTRACTORS
static struct @42 extractors[]
Octstr * body
Definition: wap-appl.c:144
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Octstr * type
Definition: wap-appl.c:145
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:901
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: octstr.c:118
char * transfer_encoding
static void pap_request_thread ( void *  arg)
static

Definition at line 746 of file wap_push_ppg.c.

References boundary, PAPEvent::cgivars, change_header_value(), client(), content_header, debug(), dict_put(), dict_put_once(), dlr_url, error(), get_mime_boundary(), gw_assert(), gwlist_consume(), handle_push_message(), headers_acceptable(), HTTP_ACCEPTED, http_append_headers(), http_close_client(), http_destroy_cgiargs(), http_destroy_headers(), http_header_duplicate(), http_header_remove_all(), HTTP_NOT_FOUND, http_remove_hop_headers(), http_send_reply(), HTTP_UNAUTHORIZED, info(), ip_allowed_by_ppg(), is_phone_number(), mime_parse(), octstr_compare(), octstr_destroy(), octstr_duplicate, octstr_format(), octstr_get_cstr, octstr_imm(), octstr_len(), PAP_BAD_REQUEST, pap_compile(), PAP_DUPLICATE_PUSH_ID, pap_event_destroy(), pap_event_unpack(), PAP_FORBIDDEN, push_data, PAPEvent::push_headers, remove_link_headers(), remove_mime_headers(), remove_x_kannel_headers(), run_status, running, send_bad_message_response(), set_dlr_mask(), set_dlr_url(), set_service_name(), set_smsbox_id(), set_smsc_id(), tell_fatal_error(), trusted_pi, WAPEvent::u, user_configuration, username, wap_push_ppg_pushuser_authenticate(), wap_push_ppg_pushuser_client_phone_number_acceptable(), and warning().

Referenced by wap_push_ppg_init(), and wap_push_ppg_shutdown().

747 {
748  WAPEvent *ppg_event;
749  PAPEvent *p;
750  size_t push_len;
751  Octstr *pap_content = NULL;
752  Octstr *push_data = NULL;
753  Octstr *rdf_content = NULL;
754  Octstr *mime_content = NULL;
755  Octstr *plos = NULL; /* a temporary variable*/
756  Octstr *boundary = NULL;
757  Octstr *content_header = NULL; /* Content-Type MIME header */
758  Octstr *url = NULL;
759  Octstr *ip = NULL;
760  Octstr *not_found = NULL;
761  Octstr *username = NULL;
762  int compiler_status,
763  http_status;
764  List *push_headers, /* MIME headers themselves */
765  *content_headers, /* Headers from the content entity, see
766  pap chapters 8.2, 13.1. Rfc 2045
767  grammar calls these MIME-part-hea-
768  ders */
769  *cgivars;
771  Octstr *dlr_url;
772 
773  http_status = 0;
774  url = ip = mime_content = username = NULL;
775 
776  while (run_status == running && (p = gwlist_consume(pap_queue)) != NULL) {
777 
778  http_status = HTTP_NOT_FOUND;
779  pap_event_unpack(p, &ip, &url, &push_headers, &mime_content,
780  &cgivars, &client);
781 
782  if (octstr_compare(url, ppg_url) != 0) {
783  error(0, "Request <%s> from <%s>: service not found",
784  octstr_get_cstr(url), octstr_get_cstr(ip));
785  debug("wap.push.ppg", 0, "your configuration uses %s",
787  not_found = octstr_imm("Service not specified\n");
788  http_send_reply(client, http_status, push_headers, not_found);
789  goto ferror;
790  }
791 
792  http_status = HTTP_UNAUTHORIZED;
793 
794  if (!ip_allowed_by_ppg(ip)) {
795  error(0, "Request <%s> from <%s>: ip forbidden, closing the"
796  " client", octstr_get_cstr(url), octstr_get_cstr(ip));
797  http_close_client(client);
798  goto ferror;
799  }
800 
801  if (!trusted_pi && user_configuration) {
802  if (!wap_push_ppg_pushuser_authenticate(client, cgivars, ip,
803  push_headers, &username)) {
804  error(0, "Request <%s> from <%s>: authorisation failure",
805  octstr_get_cstr(url), octstr_get_cstr(ip));
806  goto ferror;
807  }
808  } else { /* J�rg, this wont disappear again */
809  username = octstr_imm("");
810  }
811 
812  http_status = HTTP_ACCEPTED;
813  info(0, "PPG: Accept request <%s> from <%s>", octstr_get_cstr(url),
814  octstr_get_cstr(ip));
815 
816  if (octstr_len(mime_content) == 0) {
817  warning(0, "PPG: No MIME content received, the request"
818  " unacceptable");
819  send_bad_message_response(&client, octstr_imm("No MIME content"),
820  PAP_BAD_REQUEST, http_status);
821  if (client == NULL)
822  break;
823  goto ferror;
824  }
825 
826  if (!push_headers) {
827  warning(0, "PPG: No push headers received , the request"
828  " unacceptable");
829  send_bad_message_response(&client, octstr_imm("No push headers"),
830  PAP_BAD_REQUEST, http_status);
831  if (client == NULL)
832  break;
833  goto ferror;
834  }
835  octstr_destroy(ip);
836 
837  http_remove_hop_headers(push_headers);
838  remove_mime_headers(&push_headers);
839  remove_link_headers(&push_headers);
840 
841  if (!headers_acceptable(push_headers, &content_header)) {
842  warning(0, "PPG: Unparsable push headers, the request"
843  " unacceptable");
844  send_bad_message_response(&client, content_header, PAP_BAD_REQUEST,
845  http_status);
846  if (client == NULL)
847  break;
848  goto herror;
849  }
850 
851  if (get_mime_boundary(push_headers, content_header, &boundary) == -1) {
852  warning(0, "PPG: No MIME boundary, the request unacceptable");
853  send_bad_message_response(&client, content_header, PAP_BAD_REQUEST,
854  http_status);
855  if (client == NULL)
856  break;
857  goto berror;
858  }
859 
860  gw_assert(mime_content);
861  if (!mime_parse(boundary, mime_content, &pap_content, &push_data,
862  &content_headers, &rdf_content)) {
863  send_bad_message_response(&client, mime_content, PAP_BAD_REQUEST,
864  http_status);
865  if (client == NULL)
866  break;
867  warning(0, "PPG: unable to parse mime content, the request"
868  " unacceptable");
869  goto clean;
870  } else {
871  debug("wap.push.ppg", 0, "PPG: http_read_thread: pap multipart"
872  " accepted");
873  }
874 
875  push_len = octstr_len(push_data);
876  http_header_remove_all(push_headers, "Content-Type");
877  http_append_headers(push_headers, content_headers);
878  change_header_value(&push_headers, "Content-Length",
879  octstr_get_cstr(plos = octstr_format("%d", push_len)));
880  octstr_destroy(plos);
881  octstr_destroy(content_header);
882  http_destroy_headers(content_headers);
883 
884  ppg_event = NULL;
885  if ((compiler_status = pap_compile(pap_content, &ppg_event)) == -2) {
886  send_bad_message_response(&client, pap_content, PAP_BAD_REQUEST,
887  http_status);
888  if (client == NULL)
889  break;
890  warning(0, "PPG: pap control entity erroneous, the request"
891  " unacceptable");
892  goto no_compile;
893  } else if (compiler_status == -1) {
894  send_bad_message_response(&client, pap_content, PAP_BAD_REQUEST,
895  http_status);
896  if (client == NULL)
897  break;
898  warning(0, "PPG: non implemented pap feature requested, the"
899  " request unacceptable");
900  goto no_compile;
901  } else {
903  ppg_event->u.Push_Message.pi_push_id, client)) {
904  warning(0, "PPG: duplicate push id, the request unacceptable");
905  tell_fatal_error(&client, ppg_event, url, http_status,
907  if (client == NULL)
908  break;
909  goto not_acceptable;
910  }
911 
912  dict_put(urls, ppg_event->u.Push_Message.pi_push_id, url);
913 
914  if (is_phone_number(ppg_event->u.Push_Message.address_type)) {
915  if (!trusted_pi && user_configuration &&
917  username, ppg_event->u.Push_Message.address_value)) {
918  tell_fatal_error(&client, ppg_event, url, http_status,
919  PAP_FORBIDDEN);
920  if (client == NULL)
921  break;
922  goto not_acceptable;
923  }
924  }
925 
926  debug("wap.push.ppg", 0, "PPG: http_read_thread: pap control"
927  " entity compiled ok");
928  ppg_event->u.Push_Message.push_data = octstr_duplicate(push_data);
929  ppg_event->u.Push_Message.smsc_id = set_smsc_id(push_headers, username,
930  trusted_pi);
931  dlr_url = set_dlr_url(push_headers, username, trusted_pi);
932  ppg_event->u.Push_Message.dlr_url = dlr_url;
933  ppg_event->u.Push_Message.dlr_mask = set_dlr_mask(push_headers, dlr_url);
934  ppg_event->u.Push_Message.smsbox_id = set_smsbox_id(push_headers, username,
935  trusted_pi);
936  ppg_event->u.Push_Message.service_name = set_service_name();
937  remove_x_kannel_headers(&push_headers);
938  ppg_event->u.Push_Message.push_headers = http_header_duplicate(push_headers);
939 
940  if (!handle_push_message(&client, ppg_event, http_status)) {
941  if (client == NULL)
942  break;
943  goto no_transform;
944  }
945  }
946 
948  http_destroy_headers(push_headers);
949  http_destroy_cgiargs(cgivars);
950  octstr_destroy(username);
951  octstr_destroy(mime_content);
952  octstr_destroy(pap_content);
953  octstr_destroy(push_data);
954  octstr_destroy(rdf_content);
955  octstr_destroy(boundary);
956  boundary = rdf_content = push_data = pap_content = mime_content = username = NULL;
957  continue;
958 
959 no_transform:
961  http_destroy_headers(push_headers);
962  http_destroy_cgiargs(cgivars);
963  octstr_destroy(username);
964  octstr_destroy(mime_content);
965  octstr_destroy(pap_content);
966  octstr_destroy(push_data);
967  octstr_destroy(rdf_content);
968  octstr_destroy(boundary);
969  boundary = rdf_content = push_data = pap_content = mime_content = username = NULL;
970  continue;
971 
972 no_compile:
974  http_destroy_headers(push_headers);
975  http_destroy_cgiargs(cgivars);
976  octstr_destroy(username);
977  octstr_destroy(mime_content);
978  octstr_destroy(push_data);
979  octstr_destroy(rdf_content);
980  octstr_destroy(boundary);
981  octstr_destroy(url);
982  url = boundary = rdf_content = push_data = mime_content = username = NULL;
983  continue;
984 
985 not_acceptable:
987  http_destroy_headers(push_headers);
988  http_destroy_cgiargs(cgivars);
989  octstr_destroy(username);
990  octstr_destroy(mime_content);
991  octstr_destroy(pap_content);
992  octstr_destroy(push_data);
993  octstr_destroy(rdf_content);
994  octstr_destroy(boundary);
995  octstr_destroy(url);
996  url = boundary = rdf_content = push_data = pap_content = mime_content = username = NULL;
997  continue;
998 
999 clean:
1000  pap_event_destroy(p);
1001  http_destroy_headers(push_headers);
1002  http_destroy_headers(content_headers);
1003  octstr_destroy(pap_content);
1004  octstr_destroy(push_data);
1005  octstr_destroy(rdf_content);
1006  octstr_destroy(content_header);
1007  octstr_destroy(boundary);
1008  octstr_destroy(url);
1009  url = boundary = content_header = rdf_content = push_data = pap_content = NULL;
1010  continue;
1011 
1012 ferror:
1013  pap_event_destroy(p);
1014  http_destroy_headers(push_headers);
1015  http_destroy_cgiargs(cgivars);
1016  octstr_destroy(username);
1017  octstr_destroy(url);
1018  octstr_destroy(ip);
1019  octstr_destroy(mime_content);
1020  mime_content = ip = url = username = NULL;
1021  continue;
1022 
1023 herror:
1024  pap_event_destroy(p);
1025  http_destroy_headers(push_headers);
1026  http_destroy_cgiargs(cgivars);
1027  octstr_destroy(username);
1028  octstr_destroy(url);
1029  url = username = NULL;
1030  continue;
1031 
1032 berror:
1033  pap_event_destroy(p);
1034  http_destroy_headers(push_headers);
1035  http_destroy_cgiargs(cgivars);
1036  octstr_destroy(username);
1037  octstr_destroy(mime_content);
1038  octstr_destroy(content_header);
1039  octstr_destroy(boundary);
1040  octstr_destroy(url);
1041  url = boundary = content_header = mime_content = username = NULL;
1042  continue;
1043  }
1044 }
static int headers_acceptable(List *push_headers, Octstr **content_header)
void error(int err, const char *fmt,...)
Definition: log.c:612
static void remove_x_kannel_headers(List **push_headers)
void info(int err, const char *fmt,...)
Definition: log.c:636
static int is_phone_number(long type_of_address)
static char ** push_data
Definition: test_ppg.c:96
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
void http_close_client(HTTPClient *client)
Definition: http.c:2735
static Octstr * set_smsbox_id(List *headers, Octstr *username, int trusted_pi)
static void tell_fatal_error(HTTPClient **c, WAPEvent *e, Octstr *url, int status, int code)
static void client(int port)
Definition: test_udp.c:77
static Octstr * ppg_url
Definition: wap_push_ppg.c:184
static char * boundary
Definition: test_ppg.c:97
static enum @39 run_status
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static int user_configuration
Definition: wap_push_ppg.c:196
unsigned char * username
Definition: test_cimd2.c:99
void http_destroy_headers(List *headers)
Definition: http.c:2856
static void remove_mime_headers(List **push_headers)
static Octstr * content_header
Definition: test_ppg.c:101
void http_destroy_cgiargs(List *args)
Definition: http.c:2795
void http_append_headers(List *to, List *from)
Definition: http.c:3029
void http_send_reply(HTTPClient *client, int status, List *headers, Octstr *body)
Definition: http.c:2671
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
static Dict * urls
Definition: wap_push_ppg.c:165
static Dict * http_clients
Definition: wap_push_ppg.c:160
static void change_header_value(List **push_headers, char *name, char *value)
static void send_bad_message_response(HTTPClient **c, Octstr *body_fragment, int code, int status)
static Octstr * dlr_url
Definition: test_ppg.c:107
static Octstr * set_service_name(void)
#define octstr_duplicate(ostr)
Definition: octstr.h:187
static int ip_allowed_by_ppg(Octstr *ip)
Definition: wap_push_ppg.c:586
int wap_push_ppg_pushuser_client_phone_number_acceptable(Octstr *username, Octstr *number)
static void pap_event_destroy(PAPEvent *p)
Definition: wap_push_ppg.c:663
static Octstr * set_smsc_id(List *headers, Octstr *username, int trusted_pi)
void warning(int err, const char *fmt,...)
Definition: log.c:624
void http_remove_hop_headers(List *headers)
Definition: http.c:3138
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
gw_assert(wtls_machine->packet_to_send!=NULL)
static long set_dlr_mask(List *headers, Octstr *dlr_url)
int wap_push_ppg_pushuser_authenticate(HTTPClient *c, List *cgivars, Octstr *ip, List *push_headers, Octstr **username)
static void pap_event_unpack(PAPEvent *p, Octstr **ip, Octstr **url, List **push_headers, Octstr **mime_content, List **cgivars, HTTPClient **client)
Definition: wap_push_ppg.c:676
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
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
static void remove_link_headers(List **push_headers)
long http_header_remove_all(List *headers, char *name)
Definition: http.c:3112
List * http_header_duplicate(List *headers)
Definition: http.c:2946
static List * pap_queue
Definition: wap_push_ppg.c:138
int dict_put_once(Dict *dict, Octstr *key, void *value)
Definition: dict.c:271
static int trusted_pi
Definition: wap_push_ppg.c:192
static Octstr * set_dlr_url(List *headers, Octstr *username, int trusted_pi)
union WAPEvent::@87 u
static int get_mime_boundary(List *push_headers, Octstr *content_header, Octstr **boundary)
static Octstr * url
Definition: test_xmlrpc.c:84
Definition: list.c:102
int mime_parse(Octstr *boundary, Octstr *mime_content, Octstr **pap_content, Octstr **push_data, List **content_headers, Octstr **rdf_content)
int pap_compile(Octstr *pap_content, WAPEvent **e)
static int handle_push_message(HTTPClient **c, WAPEvent *ppg_event, int status)
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
static long parse_appid_header ( Octstr **  assigned_code)
static

Definition at line 2845 of file wap_push_ppg.c.

References NUMBER_OF_WINA_URIS, octstr_case_search(), octstr_delete(), octstr_destroy(), octstr_format(), octstr_imm(), octstr_len(), and octstr_search().

Referenced by check_x_wap_application_id_header().

2846 {
2847  long pos,
2848  coded_value;
2849  size_t i;
2850 
2851  if ((pos = octstr_search(*appid_content, octstr_imm(";"), 0)) >= 0) {
2852  octstr_delete(*appid_content, pos,
2853  octstr_len(octstr_imm(";app-encoding=")));
2854  octstr_delete(*appid_content, 0, pos); /* the URI part */
2855  return -1;
2856  }
2857 
2858  i = 0;
2859  while (i < NUMBER_OF_WINA_URIS) {
2860  if ((pos = octstr_case_search(*appid_content,
2861  octstr_imm(wina_uri[i]), 0)) >= 0)
2862  break;
2863  ++i;
2864  }
2865 
2866  if (i == NUMBER_OF_WINA_URIS) {
2867  octstr_destroy(*appid_content);
2868  *appid_content = octstr_format("%ld", 2); /* assigned number */
2869  return -1; /* for wml ua */
2870  }
2871 
2872  octstr_delete(*appid_content, 0, pos); /* again the URI */
2873  if ((coded_value = wsp_string_to_application_id(*appid_content)) >= 0) {
2874  octstr_destroy(*appid_content);
2875  *appid_content = octstr_format("%ld", coded_value);
2876  return coded_value;
2877  }
2878 
2879  return -1;
2880 }
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1068
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
static char * wina_uri[]
long octstr_case_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1100
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
#define NUMBER_OF_WINA_URIS
static int push_has_pi_push_id ( void *  a,
void *  b 
)
static

Definition at line 2515 of file wap_push_ppg.c.

References octstr_compare().

Referenced by find_ppg_push_machine_using_pi_push_id(), and find_unit_ppg_push_machine_using_pi_push_id().

2516 {
2517  Octstr *pi_push_id;
2518  PPGPushMachine *pm;
2519 
2520  pi_push_id = b;
2521  pm = a;
2522 
2523  return octstr_compare(pm->pi_push_id, pi_push_id) == 0;
2524 }
Definition: octstr.c:118
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
static int push_has_pid ( void *  a,
void *  b 
)
static

Definition at line 2491 of file wap_push_ppg.c.

Referenced by find_ppg_push_machine_using_pid(), update_push_data_with_attribute(), and update_session_data_with_headers().

2492 {
2493  long *pid;
2494  PPGPushMachine *pm;
2495 
2496  pid = b;
2497  pm = a;
2498 
2499  return *pid == pm->push_id;
2500 }
static void push_machine_assert ( PPGPushMachine pm)
static

Definition at line 1727 of file wap_push_ppg.c.

References gw_assert().

Referenced by abort_delivery(), create_session(), deliver_pending_pushes(), deliver_unit_push(), handle_internal_event(), remove_push_data(), request_confirmed_push(), request_push(), request_unit_push(), response_push_message(), and update_push_data_with_attribute().

1728 {
1729  gw_assert(pm);
1730  gw_assert(pm->pi_push_id);
1731  gw_assert(pm->push_id >= 0);
1732  gw_assert(pm->session_id >= 0);
1733  gw_assert(pm->addr_tuple);
1734  gw_assert(pm->trusted == 1 || pm->trusted == 0);
1735  gw_assert(pm->authenticated == 1 || pm->authenticated == 0);
1736 }
gw_assert(wtls_machine->packet_to_send!=NULL)
static PPGPushMachine * push_machine_create ( WAPEvent e,
WAPAddrTuple tuple 
)
static

Definition at line 1362 of file wap_push_ppg.c.

References counter_increase(), debug(), http_header_duplicate(), octstr_duplicate, WAPEvent::u, and wap_addr_tuple_duplicate().

Referenced by store_push_data().

1363 {
1364  PPGPushMachine *m;
1365 
1366  m = gw_malloc(sizeof(PPGPushMachine));
1367 
1368  #define INTEGER(name) m->name = 0;
1369  #define OCTSTR(name) m->name = NULL;
1370  #define OPTIONAL_OCTSTR(name) m->name = NULL;
1371  #define ADDRTUPLE(name) m->name = NULL;
1372  #define CAPABILITIES m->name = NULL;
1373  #define HTTPHEADER(name) m->name = NULL;
1374  #define MACHINE(fields) fields
1375  #include "wap_ppg_push_machine.def"
1376 
1377  m->addr_tuple = wap_addr_tuple_duplicate(tuple);
1378  m->pi_push_id = octstr_duplicate(e->u.Push_Message.pi_push_id);
1379  m->push_id = counter_increase(push_id_counter);
1380  m->delivery_method = e->u.Push_Message.delivery_method;
1381  m->deliver_after_timestamp =
1382  octstr_duplicate(e->u.Push_Message.deliver_after_timestamp);
1383  m->priority = e->u.Push_Message.priority;
1384  m->push_headers = http_header_duplicate(e->u.Push_Message.push_headers);
1385  m->push_data = octstr_duplicate(e->u.Push_Message.push_data);
1386 
1387  m->address_type = e->u.Push_Message.address_type;
1388  if (e->u.Push_Message.smsc_id != NULL)
1389  m->smsc_id = octstr_duplicate(e->u.Push_Message.smsc_id);
1390  else
1391  m->smsc_id = NULL;
1392  if (e->u.Push_Message.dlr_url != NULL)
1393  m->dlr_url = octstr_duplicate(e->u.Push_Message.dlr_url);
1394  else
1395  m->dlr_url = NULL;
1396  m->dlr_mask = e->u.Push_Message.dlr_mask;
1397  if (e->u.Push_Message.smsbox_id != NULL)
1398  m->smsbox_id = octstr_duplicate(e->u.Push_Message.smsbox_id);
1399  else
1400  m->smsbox_id = NULL;
1401  m->service_name = octstr_duplicate(e->u.Push_Message.service_name);
1402 
1403  m->progress_notes_requested = e->u.Push_Message.progress_notes_requested;
1404  if (e->u.Push_Message.progress_notes_requested)
1405  m->ppg_notify_requested_to =
1406  octstr_duplicate(e->u.Push_Message.ppg_notify_requested_to);
1407 
1408  debug("wap.push.ppg", 0, "PPG: push machine %ld created", m->push_id);
1409 
1410  return m;
1411 }
static Counter * push_id_counter
Definition: wap_push_ppg.c:154
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
Definition: wap_addr.c:125
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
List * http_header_duplicate(List *headers)
Definition: http.c:2946
union WAPEvent::@87 u
static void push_machine_destroy ( void *  pm)
static

Definition at line 1417 of file wap_push_ppg.c.

References debug().

Referenced by push_machines_list_destroy(), remove_push_data(), and wap_push_ppg_shutdown().

1418 {
1419  PPGPushMachine *pm;
1420 
1421  if (p == NULL)
1422  return;
1423 
1424  pm = p;
1425 
1426  debug("wap.push.ppg", 0, "PPG: destroying push machine %ld",
1427  pm->push_id);
1428  #define OCTSTR(name) octstr_destroy(pm->name);
1429  #define OPTIONAL_OCTSTR(name) octstr_destroy(pm->name);
1430  #define INTEGER(name)
1431  #define ADDRTUPLE(name) wap_addr_tuple_destroy(pm->name);
1432  #define CAPABILITIES(name) wap_cap_destroy_list(pm->name);
1433  #define HTTPHEADER(name) http_destroy_headers(pm->name);
1434  #define MACHINE(fields) fields
1435  #include "wap_ppg_push_machine.def"
1436 
1437  gw_free(p);
1438 }
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static void push_machines_list_destroy ( List pl)
static

Definition at line 1440 of file wap_push_ppg.c.

References gwlist_destroy(), and push_machine_destroy().

1441 {
1442  if (machines == NULL)
1443  return;
1444 
1446 }
static void push_machine_destroy(void *pm)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static int read_ppg_config ( Cfg cfg)
static

Definition at line 523 of file wap_push_ppg.c.

References cfg_destroy(), cfg_get, cfg_get_bool(), cfg_get_integer(), cfg_get_multi_group(), cfg_get_single_group(), gwlist_destroy(), NO_HTTPS_PORT, number_of_pushes, number_of_users, octstr_destroy(), octstr_format(), octstr_imm(), panic, ppg_port, trusted_pi, USER_CONFIGURATION_ADDED, USER_CONFIGURATION_NOT_ADDED, and wap_push_ppg_pushuser_list_add().

Referenced by wap_push_ppg_init().

524 {
525  CfgGroup *grp;
526  List *list;
527 
528  if (cfg == NULL)
530 
531  grp = cfg_get_single_group(cfg, octstr_imm("ppg"));
532  if ((ppg_url = cfg_get(grp, octstr_imm("ppg-url"))) == NULL)
533  ppg_url = octstr_imm("/wappush");
534  cfg_get_integer(&ppg_port, grp, octstr_imm("ppg-port"));
535  cfg_get_integer(&number_of_pushes, grp, octstr_imm("concurrent-pushes"));
536  cfg_get_bool(&trusted_pi, grp, octstr_imm("trusted-pi"));
537  cfg_get_integer(&number_of_users, grp, octstr_imm("users"));
538  ppg_deny_ip = cfg_get(grp, octstr_imm("ppg-deny-ip"));
539  ppg_allow_ip = cfg_get(grp, octstr_imm("ppg-allow-ip"));
540  if ((global_sender = cfg_get(grp, octstr_imm("global-sender"))) == NULL)
541  global_sender = octstr_format("%s", "1234");
542  ppg_default_smsc = cfg_get(grp, octstr_imm("default-smsc"));
543  ppg_dlr_url = cfg_get(grp, octstr_imm("default-dlr-url"));
544  ppg_smsbox_id = cfg_get(grp, octstr_imm("ppg-smsbox-id"));
545  if ((service_name = cfg_get(grp, octstr_imm("service-name"))) == NULL)
546  service_name = octstr_format("%s", "ppg");
547 
548 #ifdef HAVE_LIBSSL
549  cfg_get_integer(&ppg_ssl_port, grp, octstr_imm("ppg-ssl-port"));
550  ssl_server_cert_file = cfg_get(grp, octstr_imm("ssl-server-cert-file"));
551  ssl_server_key_file = cfg_get(grp, octstr_imm("ssl-server-key-file"));
552  if (ppg_ssl_port != NO_HTTPS_PORT) {
553  if (ssl_server_cert_file == NULL || ssl_server_key_file == NULL)
554  panic(0, "cannot continue without server cert and/or key files");
555  conn_use_global_server_certkey_file(ssl_server_cert_file, ssl_server_key_file);
556  }
557  octstr_destroy(ssl_server_cert_file);
558  octstr_destroy(ssl_server_key_file);
559 #endif
560 
561  /* If pi is trusted, ignore possible user groups. */
562  if (trusted_pi) {
563  cfg_destroy(cfg);
565  }
566 
567  /* But if it is not, we cannot continue without user groups.*/
568  if ((list = cfg_get_multi_group(cfg, octstr_imm("wap-push-user")))
569  == NULL) {
570  panic(0, "No user group but ppg not trusted, stopping");
571  gwlist_destroy(list, NULL);
572  cfg_destroy(cfg);
574  }
575 
577  number_of_users)) {
578  panic(0, "unable to create users configuration list, exiting");
580  }
581 
582  cfg_destroy(cfg);
584 }
static Octstr * service_name
Definition: wap_push_ppg.c:205
static Octstr * ppg_default_smsc
Definition: wap_push_ppg.c:198
static Octstr * ppg_url
Definition: wap_push_ppg.c:184
#define cfg_get(grp, varname)
Definition: cfg.h:86
int wap_push_ppg_pushuser_list_add(List *list, long number_of_pushes, long number_of_users)
static Octstr * ppg_dlr_url
Definition: wap_push_ppg.c:203
static Octstr * ppg_allow_ip
Definition: wap_push_ppg.c:195
static long number_of_users
Definition: wap_push_ppg.c:193
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
static Octstr * global_sender
Definition: wap_push_ppg.c:197
void cfg_destroy(Cfg *cfg)
Definition: cfg.c:331
static long ppg_port
Definition: wap_push_ppg.c:185
List * cfg_get_multi_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:642
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
static long number_of_pushes
Definition: wap_push_ppg.c:191
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:756
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:739
static Octstr * ppg_smsbox_id
Definition: wap_push_ppg.c:204
#define panic
Definition: log.h:87
Definition: cfg.c:73
static Octstr * ppg_deny_ip
Definition: wap_push_ppg.c:194
static int trusted_pi
Definition: wap_push_ppg.c:192
CfgGroup * cfg_get_single_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:636
Definition: list.c:102
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static void remove_link_headers ( List **  push_headers)
static

Definition at line 3009 of file wap_push_ppg.c.

References http_header_remove_all().

Referenced by pap_request_thread().

3010 {
3011  http_header_remove_all(*push_headers, "Host");
3012 }
long http_header_remove_all(List *headers, char *name)
Definition: http.c:3112
static void remove_mime_headers ( List **  push_headers)
static

Definition at line 3001 of file wap_push_ppg.c.

References http_header_remove_all().

Referenced by pap_request_thread().

3002 {
3003  http_header_remove_all(*push_headers, "MIME-Version");
3004 }
long http_header_remove_all(List *headers, char *name)
Definition: http.c:3112
static void remove_push_data ( PPGSessionMachine sm,
PPGPushMachine pm,
int  cless 
)
static

Definition at line 2257 of file wap_push_ppg.c.

References gwlist_delete_equal(), push_machine_assert(), push_machine_destroy(), and session_machine_assert().

Referenced by abort_delivery(), deliver_pending_pushes(), handle_internal_event(), handle_push_message(), and remove_session_data().

2259 {
2260  push_machine_assert(pm);
2261 
2262  if (cless) {
2264  } else {
2266  gwlist_delete_equal(sm->push_machines, pm);
2267  }
2268 
2270 }
static void push_machine_assert(PPGPushMachine *pm)
static List * ppg_unit_pushes
Definition: wap_push_ppg.c:149
long gwlist_delete_equal(List *list, void *item)
Definition: list.c:266
static void session_machine_assert(PPGSessionMachine *sm)
static void push_machine_destroy(void *pm)
static void remove_pushless_session ( PPGSessionMachine sm)
static

Definition at line 2437 of file wap_push_ppg.c.

References gwlist_delete_equal(), gwlist_len(), session_machine_assert(), and session_machine_destroy().

Referenced by handle_push_message().

2438 {
2440 
2441  if (gwlist_len(sm->push_machines) == 0) {
2444  }
2445 }
long gwlist_len(List *list)
Definition: list.c:166
long gwlist_delete_equal(List *list, void *item)
Definition: list.c:266
static void session_machine_assert(PPGSessionMachine *sm)
static void session_machine_destroy(void *p)
static List * ppg_machines
Definition: wap_push_ppg.c:143
static void remove_session_data ( PPGSessionMachine sm,
int  status 
)
static

Definition at line 2415 of file wap_push_ppg.c.

References code, gwlist_delete_equal(), gwlist_get(), gwlist_len(), PAP_ABORT_USERPND, remove_push_data(), response_push_message(), session_machine_assert(), and session_machine_destroy().

Referenced by handle_internal_event().

2416 {
2417  long code;
2418  PPGPushMachine *pm;
2419 
2421 
2422  code = PAP_ABORT_USERPND;
2423 
2424  while (gwlist_len(sm->push_machines) > 0) {
2425  pm = gwlist_get(sm->push_machines, 0);
2426  response_push_message(pm, code, status);
2427  remove_push_data(sm, pm, sm == NULL);
2428  }
2429 
2432 }
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
int code
Definition: smsc_cimd2.c:346
static void remove_push_data(PPGSessionMachine *sm, PPGPushMachine *pm, int cless)
static HTTPClient * response_push_message(PPGPushMachine *pm, long code, int status)
long gwlist_delete_equal(List *list, void *item)
Definition: list.c:266
static void session_machine_assert(PPGSessionMachine *sm)
static void session_machine_destroy(void *p)
static List * ppg_machines
Definition: wap_push_ppg.c:143
static void remove_x_kannel_headers ( List **  push_headers)
static

Definition at line 3017 of file wap_push_ppg.c.

References http_header_remove_all().

Referenced by pap_request_thread().

3018 {
3019  http_header_remove_all(*push_headers, "X-Kannel-SMSC");
3020  http_header_remove_all(*push_headers, "X-Kannel-DLR-Url");
3021  http_header_remove_all(*push_headers, "X-Kannel-DLR-Mask");
3022  http_header_remove_all(*push_headers, "X-Kannel-Smsbox-Id");
3023 }
long http_header_remove_all(List *headers, char *name)
Definition: http.c:3112
static void replace_octstr_char ( Octstr os1,
Octstr os2,
long *  pos 
)
static

Definition at line 3250 of file wap_push_ppg.c.

References octstr_delete(), octstr_insert(), and octstr_len().

Referenced by escape_fragment().

3251 {
3252  octstr_delete(os1, *pos, 1);
3253  octstr_insert(os1, os2, *pos);
3254  *pos += octstr_len(os2) - 1;
3255 }
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1301
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
static void request_confirmed_push ( long  last,
PPGPushMachine pm,
PPGSessionMachine sm 
)
static

Definition at line 1523 of file wap_push_ppg.c.

References debug(), dispatch_to_ota, gw_assert(), http_header_duplicate(), octstr_duplicate, PAPEvent::push_headers, push_machine_assert(), session_machine_assert(), WAPEvent::u, and wap_event_create.

Referenced by deliver_confirmed_push(), and deliver_pending_pushes().

1525 {
1526  WAPEvent *ota_event;
1527  List *push_headers;
1528 
1529  gw_assert(last == 0 || last == 1);
1530  push_machine_assert(pm);
1532 
1533  push_headers = http_header_duplicate(pm->push_headers);
1534 
1535  ota_event = wap_event_create(Po_ConfirmedPush_Req);
1536  ota_event->u.Po_ConfirmedPush_Req.server_push_id = pm->push_id;
1537  ota_event->u.Po_ConfirmedPush_Req.push_headers = push_headers;
1538  ota_event->u.Po_ConfirmedPush_Req.authenticated = pm->authenticated;
1539  ota_event->u.Po_ConfirmedPush_Req.trusted = pm->trusted;
1540  ota_event->u.Po_ConfirmedPush_Req.last = last;
1541 
1542  if (pm->push_data != NULL)
1543  ota_event->u.Po_ConfirmedPush_Req.push_body =
1544  octstr_duplicate(pm->push_data);
1545  else
1546  ota_event->u.Po_ConfirmedPush_Req.push_body = NULL;
1547 
1548  ota_event->u.Po_ConfirmedPush_Req.session_handle = sm->session_id;
1549  debug("wap.push.ota", 0, "PPG: confirmed push request to OTA");
1550 
1551  dispatch_to_ota(ota_event);
1552 }
static void push_machine_assert(PPGPushMachine *pm)
static wap_dispatch_func_t * dispatch_to_ota
Definition: wap_push_ppg.c:176
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define wap_event_create(type)
Definition: wap_events.h:107
static void session_machine_assert(PPGSessionMachine *sm)
gw_assert(wtls_machine->packet_to_send!=NULL)
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
List * http_header_duplicate(List *headers)
Definition: http.c:2946
union WAPEvent::@87 u
Definition: list.c:102
static void request_push ( long  last,
PPGPushMachine sm 
)
static

Definition at line 1600 of file wap_push_ppg.c.

References debug(), dispatch_to_ota, gw_assert(), http_header_duplicate(), octstr_duplicate, PAPEvent::push_headers, push_machine_assert(), WAPEvent::u, and wap_event_create.

Referenced by deliver_pending_pushes(), and deliver_unit_push().

1601 {
1602  WAPEvent *ota_event;
1603  List *push_headers;
1604 
1605  gw_assert(last == 0 || last == 1);
1606  push_machine_assert(pm);
1607 
1608  push_headers = http_header_duplicate(pm->push_headers);
1609 
1610  ota_event = wap_event_create(Po_Push_Req);
1611  ota_event->u.Po_Push_Req.push_headers = push_headers;
1612  ota_event->u.Po_Push_Req.authenticated = pm->authenticated;
1613  ota_event->u.Po_Push_Req.trusted = pm->trusted;
1614  ota_event->u.Po_Push_Req.last = last;
1615 
1616  if (pm->push_data != NULL)
1617  ota_event->u.Po_Push_Req.push_body =
1618  octstr_duplicate(pm->push_data);
1619  else
1620  ota_event->u.Po_Push_Req.push_body = NULL;
1621 
1622  ota_event->u.Po_Push_Req.session_handle = pm->session_id;
1623  debug("wap.push.ppg", 0, "PPG: OTA request for push");
1624 
1625  dispatch_to_ota(ota_event);
1626 }
static void push_machine_assert(PPGPushMachine *pm)
static wap_dispatch_func_t * dispatch_to_ota
Definition: wap_push_ppg.c:176
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define wap_event_create(type)
Definition: wap_events.h:107
gw_assert(wtls_machine->packet_to_send!=NULL)
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
List * http_header_duplicate(List *headers)
Definition: http.c:2946
union WAPEvent::@87 u
Definition: list.c:102
static void request_unit_push ( long  last,
PPGPushMachine pm 
)
static

Definition at line 1558 of file wap_push_ppg.c.

References debug(), dispatch_to_ota, gw_assert(), http_header_duplicate(), octstr_duplicate, PAPEvent::push_headers, push_machine_assert(), WAPEvent::u, wap_addr_tuple_duplicate(), and wap_event_create.

Referenced by deliver_unit_push().

1559 {
1560  WAPEvent *ota_event;
1561  List *push_headers;
1562 
1563  gw_assert(last == 0 || last == 1);
1564  push_machine_assert(pm);
1565 
1566  push_headers = http_header_duplicate(pm->push_headers);
1567 
1568  ota_event = wap_event_create(Po_Unit_Push_Req);
1569  ota_event->u.Po_Unit_Push_Req.addr_tuple =
1570  wap_addr_tuple_duplicate(pm->addr_tuple);
1571  ota_event->u.Po_Unit_Push_Req.push_id = pm->push_id;
1572  ota_event->u.Po_Unit_Push_Req.push_headers = push_headers;
1573  ota_event->u.Po_Unit_Push_Req.authenticated = pm->authenticated;
1574  ota_event->u.Po_Unit_Push_Req.trusted = pm->trusted;
1575  ota_event->u.Po_Unit_Push_Req.last = last;
1576 
1577  ota_event->u.Po_Unit_Push_Req.address_type = pm->address_type;
1578  if (pm->smsc_id != NULL)
1579  ota_event->u.Po_Unit_Push_Req.smsc_id = octstr_duplicate(pm->smsc_id);
1580  else
1581  ota_event->u.Po_Unit_Push_Req.smsc_id = NULL;
1582  if (pm->dlr_url != NULL)
1583  ota_event->u.Po_Unit_Push_Req.dlr_url = octstr_duplicate(pm->dlr_url);
1584  else
1585  ota_event->u.Po_Unit_Push_Req.dlr_url = NULL;
1586  ota_event->u.Po_Unit_Push_Req.dlr_mask = pm->dlr_mask;
1587  if (pm->smsbox_id != NULL)
1588  ota_event->u.Po_Unit_Push_Req.smsbox_id = octstr_duplicate(pm->smsbox_id);
1589  else
1590  ota_event->u.Po_Unit_Push_Req.smsbox_id = NULL;
1591  if (pm->service_name != NULL)
1592  ota_event->u.Po_Unit_Push_Req.service_name = octstr_duplicate(pm->service_name);
1593 
1594  ota_event->u.Po_Unit_Push_Req.push_body = octstr_duplicate(pm->push_data);
1595 
1596  dispatch_to_ota(ota_event);
1597  debug("wap.push.ppg", 0, "PPG: OTA request for unit push");
1598 }
static void push_machine_assert(PPGPushMachine *pm)
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
Definition: wap_addr.c:125
static wap_dispatch_func_t * dispatch_to_ota
Definition: wap_push_ppg.c:176
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define wap_event_create(type)
Definition: wap_events.h:107
gw_assert(wtls_machine->packet_to_send!=NULL)
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
List * http_header_duplicate(List *headers)
Definition: http.c:2946
union WAPEvent::@87 u
Definition: list.c:102
static int response_push_connection ( WAPEvent e,
PPGSessionMachine sm 
)
static

Definition at line 1645 of file wap_push_ppg.c.

References check_capabilities(), dispatch_to_appl, gw_assert(), WAPEvent::type, WAPEvent::u, wap_event_create, and wsp_cap_duplicate_list().

Referenced by handle_internal_event().

1646 {
1647  WAPEvent *appl_event;
1648 
1649  gw_assert(e->type == Pom_Connect_Ind);
1650 
1651  if (sm->assumed_capabilities != NULL && check_capabilities(
1652  e->u.Pom_Connect_Ind.requested_capabilities,
1653  sm->assumed_capabilities) == 0)
1654  return 0;
1655 
1656  appl_event = wap_event_create(Pom_Connect_Res);
1657  appl_event->u.Pom_Connect_Res.negotiated_capabilities =
1658  wsp_cap_duplicate_list(e->u.Pom_Connect_Ind.requested_capabilities);
1659  appl_event->u.Pom_Connect_Res.session_id = e->u.Pom_Connect_Ind.session_id;
1660 
1661  dispatch_to_appl(appl_event);
1662 
1663  return 1;
1664 }
static int check_capabilities(List *requested, List *assumed)
List * wsp_cap_duplicate_list(List *caps_list)
Definition: wsp_caps.c:125
#define wap_event_create(type)
Definition: wap_events.h:107
gw_assert(wtls_machine->packet_to_send!=NULL)
WAPEventName type
Definition: wap_events.h:88
static wap_dispatch_func_t * dispatch_to_appl
Definition: wap_push_ppg.c:177
union WAPEvent::@87 u
static HTTPClient * response_push_message ( PPGPushMachine pm,
long  code,
int  status 
)
static

Definition at line 1671 of file wap_push_ppg.c.

References code, describe_code(), octstr_duplicate, push_machine_assert(), send_push_response(), set_time(), tell_ppg_name(), WAPEvent::u, and wap_event_create.

Referenced by abort_delivery(), handle_push_message(), and remove_session_data().

1672 {
1673  WAPEvent *e;
1674  HTTPClient *c;
1675 
1676  push_machine_assert(pm);
1677 
1678  e = wap_event_create(Push_Response);
1679  e->u.Push_Response.pi_push_id = octstr_duplicate(pm->pi_push_id);
1680  e->u.Push_Response.sender_name = tell_ppg_name();
1681  e->u.Push_Response.reply_time = set_time();
1682  e->u.Push_Response.code = code;
1683  e->u.Push_Response.desc = describe_code(code);
1684 
1685  c = send_push_response(e, status);
1686 
1687  return c;
1688 }
static HTTPClient * send_push_response(WAPEvent *e, int status)
static Octstr * describe_code(long code)
int code
Definition: smsc_cimd2.c:346
static void push_machine_assert(PPGPushMachine *pm)
static Octstr * tell_ppg_name(void)
static Octstr * set_time(void)
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define wap_event_create(type)
Definition: wap_events.h:107
union WAPEvent::@87 u
int select_bearer_network ( WAPEvent **  e)
static

Definition at line 2092 of file wap_push_ppg.c.

References gw_assert(), NUMBER_OF_BEARERS, NUMBER_OF_NETWORKS, octstr_case_compare(), and octstr_imm().

Referenced by handle_push_message().

2093 {
2094  Octstr *bearer,
2095  *network;
2096  int bearer_required,
2097  network_required;
2098  size_t i,
2099  j;
2100 
2101  gw_assert((**e).type == Push_Message);
2102 
2103  bearer_required = (**e).u.Push_Message.bearer_required;
2104  network_required = (**e).u.Push_Message.network_required;
2105  bearer = octstr_imm("Any");
2106  network = octstr_imm("Any");
2107 
2108  if (!bearer_required || !network_required)
2109  return 1;
2110 
2111  if (bearer_required)
2112  bearer = (**e).u.Push_Message.bearer;
2113  if (network_required)
2114  network = (**e).u.Push_Message.network;
2115 
2116  for (i = 0; i < NUMBER_OF_NETWORKS ; ++i) {
2117  if (octstr_case_compare(network, octstr_imm(networks[i])) == 0)
2118  break;
2119  }
2120  for (j = 0; j < NUMBER_OF_BEARERS ; ++j) {
2121  if (octstr_case_compare(bearer, octstr_imm(bearers[j])) == 0)
2122  break;
2123  }
2124  if (i == NUMBER_OF_NETWORKS || j == NUMBER_OF_BEARERS)
2125  return 0;
2126 
2127  return 1;
2128 }
static char * bearers[]
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:901
gw_assert(wtls_machine->packet_to_send!=NULL)
Definition: octstr.c:118
static char * networks[]
#define NUMBER_OF_BEARERS
#define NUMBER_OF_NETWORKS
static void send_bad_message_response ( HTTPClient **  c,
Octstr body_fragment,
int  code,
int  status 
)
static

Definition at line 3030 of file wap_push_ppg.c.

References debug(), escape_fragment(), octstr_destroy(), octstr_format(), octstr_format_append(), octstr_len(), and send_to_pi().

Referenced by pap_request_thread().

3032 {
3033  Octstr *reply_body;
3034 
3035  reply_body = octstr_format("%s",
3036  "<?xml version=\"1.0\"?>"
3037  "<!DOCTYPE pap PUBLIC \"-//WAPFORUM//DTD PAP 1.0//EN\""
3038  " \"http://www.wapforum.org/DTD/pap_1.0.dtd\">"
3039  "<pap>"
3040  "<badmessage-response code=\"");
3041  octstr_format_append(reply_body, "%d", code);
3042  octstr_format_append(reply_body, "%s", "\""
3043  " desc=\"");
3044  octstr_format_append(reply_body, "%s", "Not understood due to malformed"
3045  " syntax");
3046  octstr_format_append(reply_body, "%s", "\"");
3047 
3048  if (fragment != NULL && octstr_len(fragment) != 0) {
3049  octstr_format_append(reply_body, "%s", " bad-message-fragment=\"");
3050  octstr_format_append(reply_body, "%S", escape_fragment(fragment));
3051  octstr_format_append(reply_body, "%s", "\"");
3052  }
3053 
3054  octstr_format_append(reply_body, "%s", ">"
3055  "</badmessage-response>"
3056  "</pap>");
3057 
3058  debug("wap.push.ppg", 0, "PPG: send_bad_message_response: telling pi");
3059  send_to_pi(c, reply_body, status);
3060 
3061  octstr_destroy(fragment);
3062 }
static Octstr * escape_fragment(Octstr *fragment)
int code
Definition: smsc_cimd2.c:346
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static void send_to_pi(HTTPClient **c, Octstr *reply_body, int status)
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2505
static HTTPClient * send_push_response ( WAPEvent e,
int  status 
)
static

Definition at line 3070 of file wap_push_ppg.c.

References debug(), dict_get(), dict_remove(), gw_assert(), octstr_destroy(), octstr_format(), octstr_format_append(), send_to_pi(), WAPEvent::type, WAPEvent::u, url, and wap_event_destroy().

Referenced by response_push_message().

3071 {
3072  Octstr *reply_body,
3073  *url;
3074  HTTPClient *c;
3075 
3076  gw_assert(e->type == Push_Response);
3077  url = dict_get(urls, e->u.Push_Response.pi_push_id);
3078  dict_remove(urls, e->u.Push_Response.pi_push_id);
3079 
3080  reply_body = octstr_format("%s",
3081  "<?xml version=\"1.0\"?>"
3082  "<!DOCTYPE pap PUBLIC \"-//WAPFORUM//DTD PAP 1.0//EN\""
3083  " \"http://www.wapforum.org/DTD/pap_1.0.dtd\">"
3084  "<pap>"
3085  "<push-response push-id=\"");
3086  octstr_format_append(reply_body, "%S", e->u.Push_Response.pi_push_id);
3087  octstr_format_append(reply_body, "%s", "\"");
3088 
3089  if (e->u.Push_Response.sender_name != NULL) {
3090  octstr_format_append(reply_body, "%s",
3091  " sender-name=\"");
3092  octstr_format_append(reply_body, "%S",
3093  e->u.Push_Response.sender_name);
3094  octstr_format_append(reply_body, "%s", "\"");
3095  }
3096 
3097  if (e->u.Push_Response.reply_time != NULL) {
3098  octstr_format_append(reply_body, "%s",
3099  " reply-time=\"");
3100  octstr_format_append(reply_body, "%S",
3101  e->u.Push_Response.reply_time);
3102  octstr_format_append(reply_body, "%s", "\"");
3103  }
3104 
3105  if (url != NULL) {
3106  octstr_format_append(reply_body, "%s",
3107  " sender-address=\"");
3108  octstr_format_append(reply_body, "%S", url);
3109  octstr_format_append(reply_body, "%s", "\"");
3110  }
3111 
3112  octstr_format_append(reply_body, "%s", ">"
3113  "<response-result code =\"");
3114  octstr_format_append(reply_body, "%d", e->u.Push_Response.code);
3115  octstr_format_append(reply_body, "%s", "\"");
3116 
3117  if (e->u.Push_Response.desc != NULL) {
3118  octstr_format_append(reply_body, "%s", " desc=\"");
3119  octstr_format_append(reply_body, "%S", e->u.Push_Response.desc);
3120  octstr_format_append(reply_body, "\"");
3121  }
3122 
3123  octstr_format_append(reply_body, "%s", ">"
3124  "</response-result>"
3125  "</push-response>"
3126  "</pap>");
3127 
3128  octstr_destroy(url);
3129 
3130  c = dict_get(http_clients, e->u.Push_Response.pi_push_id);
3131  dict_remove(http_clients, e->u.Push_Response.pi_push_id);
3132 
3133  debug("wap.push.ppg", 0, "PPG: send_push_response: telling pi");
3134  send_to_pi(&c, reply_body, status);
3135 
3136  wap_event_destroy(e);
3137  return c;
3138 }
static Dict * urls
Definition: wap_push_ppg.c:165
static Dict * http_clients
Definition: wap_push_ppg.c:160
void * dict_remove(Dict *dict, Octstr *key)
Definition: dict.c:307
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
gw_assert(wtls_machine->packet_to_send!=NULL)
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static void send_to_pi(HTTPClient **c, Octstr *reply_body, int status)
WAPEventName type
Definition: wap_events.h:88
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2505
union WAPEvent::@87 u
static Octstr * url
Definition: test_xmlrpc.c:84
void wap_event_destroy(WAPEvent *event)
Definition: wap_events.c:102
static void send_to_pi ( HTTPClient **  c,
Octstr reply_body,
int  status 
)
static

Definition at line 3205 of file wap_push_ppg.c.

References http_create_empty_headers(), http_destroy_headers(), http_header_add(), http_send_reply(), and octstr_destroy().

Referenced by send_bad_message_response(), send_push_response(), and tell_fatal_error().

3205  {
3206  List *reply_headers;
3207 
3208  reply_headers = http_create_empty_headers();
3209  http_header_add(reply_headers, "Content-Type", "application/xml");
3210 
3211  if (*c != NULL)
3212  http_send_reply(*c, status, reply_headers, reply_body);
3213 
3214  octstr_destroy(reply_body);
3215  http_destroy_headers(reply_headers);
3216 }
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
void http_destroy_headers(List *headers)
Definition: http.c:2856
void http_send_reply(HTTPClient *client, int status, List *headers, Octstr *body)
Definition: http.c:2671
List * http_create_empty_headers(void)
Definition: http.c:2849
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: list.c:102
PPGSessionMachine * session_find_using_pi_client_address ( Octstr addr)
static

Definition at line 2145 of file wap_push_ppg.c.

References gwlist_search(), and session_has_pi_client_address().

Referenced by handle_push_message().

2146 {
2147  PPGSessionMachine *sm;
2148 
2150 
2151  return sm;
2152 }
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
Definition: list.c:486
static int session_has_pi_client_address(void *a, void *b)
static List * ppg_machines
Definition: wap_push_ppg.c:143
static int session_has_addr ( void *  a,
void *  b 
)
static

Definition at line 1448 of file wap_push_ppg.c.

References octstr_compare().

Referenced by wap_push_ppg_have_push_session_for().

1449 {
1450  Octstr *cliaddr;
1451  PPGSessionMachine *sm;
1452 
1453  cliaddr = b;
1454  sm = a;
1455 
1456  return octstr_compare(sm->addr_tuple->remote->address, cliaddr) == 0;
1457 }
Definition: octstr.c:118
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
static int session_has_pi_client_address ( void *  a,
void *  b 
)
static

Definition at line 2130 of file wap_push_ppg.c.

References octstr_compare().

Referenced by session_find_using_pi_client_address().

2131 {
2132  Octstr *caddr;
2133  PPGSessionMachine *sm;
2134 
2135  caddr = b;
2136  sm = a;
2137 
2138  return octstr_compare(caddr, sm->pi_client_address) == 0;
2139 }
Definition: octstr.c:118
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
static int session_has_sid ( void *  a,
void *  b 
)
static

Definition at line 1459 of file wap_push_ppg.c.

Referenced by wap_push_ppg_have_push_session_for_sid().

1460 {
1461  PPGSessionMachine *sm;
1462  long *sid;
1463 
1464  sid = b;
1465  sm = a;
1466 
1467  return *sid == sm->session_id;
1468 }
static void session_machine_assert ( PPGSessionMachine sm)
static

Definition at line 1719 of file wap_push_ppg.c.

References gw_assert().

Referenced by abort_delivery(), deliver_pending_pushes(), find_ppg_push_machine_using_pi_push_id(), find_ppg_push_machine_using_pid(), handle_internal_event(), remove_push_data(), remove_pushless_session(), remove_session_data(), request_confirmed_push(), and update_session_data().

1720 {
1721  gw_assert(sm);
1722  gw_assert(sm->session_id >= 0);
1723  gw_assert(sm->addr_tuple);
1724  gw_assert(sm->pi_client_address);
1725 }
gw_assert(wtls_machine->packet_to_send!=NULL)
static PPGSessionMachine * session_machine_create ( WAPAddrTuple tuple,
WAPEvent e 
)
static

Definition at line 1307 of file wap_push_ppg.c.

References debug(), gw_assert(), gwlist_append(), octstr_duplicate, PAP_CONFIRMED, WAPEvent::type, WAPEvent::u, wap_addr_tuple_duplicate(), and wsp_cap_duplicate_list().

Referenced by store_session_data().

1309 {
1310  PPGSessionMachine *m;
1311 
1312  gw_assert(e->type == Push_Message);
1313 
1314  m = gw_malloc(sizeof(PPGSessionMachine));
1315 
1316  #define INTEGER(name) m->name = 0;
1317  #define OCTSTR(name) m->name = NULL;
1318  #define ADDRTUPLE(name) m->name = NULL;
1319  #define PUSHMACHINES(name) m->name = gwlist_create();
1320  #define CAPABILITIES(name) m->name = NULL;
1321  #define MACHINE(fields) fields
1322  #include "wap_ppg_session_machine.def"
1323 
1324  m->pi_client_address = octstr_duplicate(e->u.Push_Message.address_value);
1325  m->addr_tuple = wap_addr_tuple_duplicate(tuple);
1326  m->assumed_capabilities =
1327  wsp_cap_duplicate_list(e->u.Push_Message.pi_capabilities);
1328  m->preferconfirmed_value = PAP_CONFIRMED;
1329 
1331  debug("wap.push.ppg", 0, "PPG: Created PPGSessionMachine %ld",
1332  m->session_id);
1333 
1334  return m;
1335 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
List * wsp_cap_duplicate_list(List *caps_list)
Definition: wsp_caps.c:125
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
Definition: wap_addr.c:125
#define octstr_duplicate(ostr)
Definition: octstr.h:187
gw_assert(wtls_machine->packet_to_send!=NULL)
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
WAPEventName type
Definition: wap_events.h:88
union WAPEvent::@87 u
static List * ppg_machines
Definition: wap_push_ppg.c:143
static void session_machine_destroy ( void *  p)
static

Definition at line 1337 of file wap_push_ppg.c.

References debug().

Referenced by remove_pushless_session(), remove_session_data(), and wap_push_ppg_shutdown().

1338 {
1339  PPGSessionMachine *sm;
1340 
1341  if (p == NULL)
1342  return;
1343 
1344  sm = p;
1345  debug("wap.push.ppg", 0, "PPG: destroying PPGSEssionMachine %ld",
1346  sm->session_id);
1347 
1348  #define OCTSTR(name) octstr_destroy(sm->name);
1349  #define ADDRTUPLE(name) wap_addr_tuple_destroy(sm->name);
1350  #define INTEGER(name) sm->name = 0;
1351  #define PUSHMACHINES(name) push_machines_list_destroy(sm->name);
1352  #define CAPABILITIES(name) wsp_cap_destroy_list(sm->name);
1353  #define MACHINE(fields) fields
1354  #include "wap_ppg_session_machine.def"
1355  gw_free(sm);
1356 }
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static WAPAddrTuple * set_addr_tuple ( Octstr address,
long  cliport,
long  servport,
long  address_type,
List push_headers 
)
static

Definition at line 2771 of file wap_push_ppg.c.

References ADDR_PLMN, from, global_sender, gw_assert(), http_header_remove_all(), http_header_value(), octstr_destroy(), octstr_imm(), and wap_addr_tuple_create().

Referenced by transform_message().

2773 {
2774  Octstr *cliaddr;
2775  Octstr *from = NULL;
2776  WAPAddrTuple *tuple;
2777 
2778  gw_assert(address);
2779 
2780  if (address_type == ADDR_PLMN) {
2781  from = http_header_value(push_headers, octstr_imm("X-Kannel-From"));
2782  cliaddr = from ? from : global_sender;
2783  } else {
2784  cliaddr = octstr_imm("0.0.0.0");
2785  }
2786 
2787  tuple = wap_addr_tuple_create(address, cliport, cliaddr, servport);
2788 
2789  octstr_destroy(from);
2790  http_header_remove_all(push_headers, "X-Kannel-From");
2791 
2792  return tuple;
2793 }
static Octstr * from
Definition: mtbatch.c:95
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
static Octstr * global_sender
Definition: wap_push_ppg.c:197
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
gw_assert(wtls_machine->packet_to_send!=NULL)
Octstr * http_header_value(List *headers, Octstr *name)
Definition: http.c:2909
Definition: octstr.c:118
long http_header_remove_all(List *headers, char *name)
Definition: http.c:3112
WAPAddrTuple * wap_addr_tuple_create(Octstr *rmt_addr, long rmt_port, Octstr *lcl_addr, long lcl_port)
Definition: wap_addr.c:96
static char * address_type(long type_of_address)
static long set_dlr_mask ( List headers,
Octstr dlr_url 
)
static

Definition at line 3314 of file wap_push_ppg.c.

References dlr_mask, http_header_value(), octstr_destroy(), octstr_imm(), octstr_len(), octstr_parse_long(), and warning().

Referenced by pap_request_thread().

3315 {
3316  Octstr *dlrmaskos;
3317  long dlr_mask;
3318  long masklen;
3319 
3320  dlrmaskos = http_header_value(headers, octstr_imm("X-Kannel-DLR-Mask"));
3321  if (dlrmaskos == NULL) {
3322  return 0;
3323  }
3324 
3325  if ((masklen = octstr_parse_long(&dlr_mask, dlrmaskos, 0, 10)) != -1 &&
3326  masklen == octstr_len(dlrmaskos) &&
3327  dlr_mask >= -1 && dlr_mask <= 31) {
3328  octstr_destroy(dlrmaskos);
3329  return dlr_mask;
3330  }
3331 
3332  warning(0, "unparsable dlr mask, rejected");
3333  octstr_destroy(dlrmaskos);
3334  return 0;
3335 }
static Octstr * dlr_mask
Definition: test_ppg.c:106
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
void warning(int err, const char *fmt,...)
Definition: log.c:624
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Octstr * http_header_value(List *headers, Octstr *name)
Definition: http.c:2909
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
Definition: octstr.c:747
static Octstr * set_dlr_url ( List headers,
Octstr username,
int  trusted_pi 
)
static

Definition at line 3291 of file wap_push_ppg.c.

References dlr_url, http_header_value(), octstr_duplicate, octstr_imm(), and wap_push_ppg_pushuser_dlr_url_get().

Referenced by pap_request_thread().

3292 {
3293  Octstr *dlr_url = NULL;
3294 
3295  dlr_url = http_header_value(headers, octstr_imm("X-Kannel-DLR-Url"));
3296  if (dlr_url) {
3297  return dlr_url;
3298  }
3299 
3300  if (!trusted_pi)
3301  dlr_url = wap_push_ppg_pushuser_dlr_url_get(username);
3302 
3303  dlr_url = dlr_url ?
3304  dlr_url : (ppg_dlr_url ? octstr_duplicate(ppg_dlr_url) : NULL);
3305 
3306  return dlr_url;
3307 }
Octstr * wap_push_ppg_pushuser_dlr_url_get(Octstr *username)
static Octstr * ppg_dlr_url
Definition: wap_push_ppg.c:203
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
static Octstr * dlr_url
Definition: test_ppg.c:107
#define octstr_duplicate(ostr)
Definition: octstr.h:187
Octstr * http_header_value(List *headers, Octstr *name)
Definition: http.c:2909
Definition: octstr.c:118
static int trusted_pi
Definition: wap_push_ppg.c:192
static Octstr * set_service_name ( void  )
static

Definition at line 3368 of file wap_push_ppg.c.

References octstr_duplicate.

Referenced by pap_request_thread().

3369 {
3371 }
static Octstr * service_name
Definition: wap_push_ppg.c:205
#define octstr_duplicate(ostr)
Definition: octstr.h:187
static Octstr * set_smsbox_id ( List headers,
Octstr username,
int  trusted_pi 
)
static

Definition at line 3346 of file wap_push_ppg.c.

References http_header_value(), octstr_duplicate, octstr_imm(), smsbox_id, and wap_push_ppg_pushuser_smsbox_id_get().

Referenced by pap_request_thread().

3347 {
3348  Octstr *smsbox_id = NULL;
3349 
3350  smsbox_id = http_header_value(headers, octstr_imm("X-Kannel-Smsbox-Id"));
3351  if (smsbox_id != NULL) {
3352  return smsbox_id;
3353  }
3354 
3355  if (!trusted_pi)
3356  smsbox_id = wap_push_ppg_pushuser_smsbox_id_get(username);
3357 
3358  smsbox_id = smsbox_id ?
3359  smsbox_id : (ppg_smsbox_id ? octstr_duplicate(ppg_smsbox_id) : NULL);
3360 
3361  return smsbox_id;
3362 
3363 }
Octstr * wap_push_ppg_pushuser_smsbox_id_get(Octstr *username)
static Octstr * smsbox_id
Definition: smsbox.c:120
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
#define octstr_duplicate(ostr)
Definition: octstr.h:187
Octstr * http_header_value(List *headers, Octstr *name)
Definition: http.c:2909
Definition: octstr.c:118
static Octstr * ppg_smsbox_id
Definition: wap_push_ppg.c:204
static int trusted_pi
Definition: wap_push_ppg.c:192
static Octstr * set_smsc_id ( List headers,
Octstr username,
int  trusted_pi 
)
static

Definition at line 3265 of file wap_push_ppg.c.

References http_header_value(), octstr_duplicate, octstr_imm(), smsc_id, and wap_push_ppg_pushuser_smsc_id_get().

Referenced by pap_request_thread().

3266 {
3267  Octstr *smsc_id = NULL;
3268 
3269  smsc_id = http_header_value(headers, octstr_imm("X-Kannel-SMSC"));
3270  if (smsc_id) {
3271  return smsc_id;
3272  }
3273 
3274  if (!trusted_pi)
3275  smsc_id = wap_push_ppg_pushuser_smsc_id_get(username);
3276 
3277  smsc_id = smsc_id ?
3278  smsc_id : (ppg_default_smsc ? octstr_duplicate(ppg_default_smsc) : NULL);
3279 
3280  return smsc_id;
3281 }
static Octstr * ppg_default_smsc
Definition: wap_push_ppg.c:198
Octstr * wap_push_ppg_pushuser_smsc_id_get(Octstr *username)
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
#define octstr_duplicate(ostr)
Definition: octstr.h:187
static Octstr * smsc_id
Definition: mtbatch.c:98
Octstr * http_header_value(List *headers, Octstr *name)
Definition: http.c:2909
Definition: octstr.c:118
static int trusted_pi
Definition: wap_push_ppg.c:192
static Octstr * set_time ( void  )
static

Definition at line 1705 of file wap_push_ppg.c.

References gw_gmtime(), and octstr_format().

Referenced by response_push_message(), tell_fatal_error(), and update_push_data_with_attribute().

1706 {
1707  Octstr *current_time;
1708  struct tm now;
1709 
1710  now = gw_gmtime(time(NULL));
1711  current_time = octstr_format("%04d-%02d-%02dT%02d:%02d:%02dZ",
1712  now.tm_year + 1900, now.tm_mon + 1,
1713  now.tm_mday, now.tm_hour, now.tm_min,
1714  now.tm_sec);
1715 
1716  return current_time;
1717 }
struct tm gw_gmtime(time_t t)
Definition: protected.c:137
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
Definition: octstr.c:118
static int store_push_data ( PPGPushMachine **  pm,
PPGSessionMachine sm,
WAPEvent e,
WAPAddrTuple tuple,
int  cless 
)
static

Definition at line 2282 of file wap_push_ppg.c.

References debug(), find_ppg_push_machine_using_pi_push_id(), find_unit_ppg_push_machine_using_pi_push_id(), gw_assert(), gwlist_append(), push_machine_create(), WAPEvent::type, and WAPEvent::u.

Referenced by handle_push_message().

2284 {
2285  Octstr *pi_push_id;
2286  int duplicate_push_id;
2287 
2288  gw_assert(e->type == Push_Message);
2289 
2290  pi_push_id = e->u.Push_Message.pi_push_id;
2291 
2292  duplicate_push_id = 0;
2293  if (((!cless) &&
2294  (find_ppg_push_machine_using_pi_push_id(sm, pi_push_id) != NULL)) ||
2295  ((cless) &&
2296  (find_unit_ppg_push_machine_using_pi_push_id(pi_push_id) != NULL)))
2297  duplicate_push_id = 1;
2298 
2299  *pm = push_machine_create(e, tuple);
2300 
2301  if (duplicate_push_id)
2302  return !duplicate_push_id;
2303 
2304  if (!cless) {
2305  gwlist_append(sm->push_machines, *pm);
2306  debug("wap.push.ppg", 0, "PPG: store_push_data: push machine %ld"
2307  " appended to push list of sm machine %ld", (*pm)->push_id,
2308  sm->session_id);
2309  } else {
2311  debug("wap.push.ppg", 0, "PPG: store_push_data: push machine %ld"
2312  " appended to unit push list", (*pm)->push_id);
2313  }
2314 
2315  return !duplicate_push_id;
2316 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
static PPGPushMachine * find_unit_ppg_push_machine_using_pi_push_id(Octstr *pi_push_id)
static List * ppg_unit_pushes
Definition: wap_push_ppg.c:149
static PPGPushMachine * push_machine_create(WAPEvent *e, WAPAddrTuple *tuple)
gw_assert(wtls_machine->packet_to_send!=NULL)
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
WAPEventName type
Definition: wap_events.h:88
union WAPEvent::@87 u
static PPGPushMachine * find_ppg_push_machine_using_pi_push_id(PPGSessionMachine *sm, Octstr *pi_push_id)
static PPGSessionMachine * store_session_data ( PPGSessionMachine sm,
WAPEvent e,
WAPAddrTuple tuple,
int *  session_exists 
)
static

Definition at line 2454 of file wap_push_ppg.c.

References gw_assert(), session_machine_create(), and WAPEvent::type.

Referenced by handle_push_message().

2456 {
2457  gw_assert(e->type == Push_Message);
2458 
2459  if (sm == NULL) {
2460  sm = session_machine_create(tuple, e);
2461  *session_exists = 0;
2462  } else
2463  *session_exists = 1;
2464 
2465  return sm;
2466 }
gw_assert(wtls_machine->packet_to_send!=NULL)
WAPEventName type
Definition: wap_events.h:88
static PPGSessionMachine * session_machine_create(WAPAddrTuple *tuple, WAPEvent *e)
static void tell_fatal_error ( HTTPClient **  c,
WAPEvent e,
Octstr url,
int  status,
int  code 
)
static

Definition at line 3145 of file wap_push_ppg.c.

References debug(), describe_code(), gw_assert(), octstr_destroy(), octstr_format(), octstr_format_append(), octstr_get_cstr, send_to_pi(), set_time(), tell_ppg_name(), WAPEvent::type, WAPEvent::u, and wap_event_destroy().

Referenced by pap_request_thread().

3147 {
3148  Octstr *reply_body,
3149  *dos, /* temporaries */
3150  *tos,
3151  *sos;
3152 
3153  gw_assert(e->type == Push_Message);
3154  reply_body = octstr_format("%s",
3155  "<?xml version=\"1.0\"?>"
3156  "<!DOCTYPE pap PUBLIC \"-//WAPFORUM//DTD PAP 1.0//EN\""
3157  " \"http://www.wapforum.org/DTD/pap_1.0.dtd\">"
3158  "<pap>"
3159  "<push-response push-id=\"");
3160  octstr_format_append(reply_body, "%S", e->u.Push_Message.pi_push_id);
3161  octstr_format_append(reply_body, "%s", "\"");
3162 
3163  octstr_format_append(reply_body, "%s",
3164  " sender-name=\"");
3165  octstr_format_append(reply_body, "%S", tos = tell_ppg_name());
3166  octstr_format_append(reply_body, "%s", "\"");
3167 
3168  octstr_format_append(reply_body, "%s",
3169  " reply-time=\"");
3170  octstr_format_append(reply_body, "%S", sos = set_time());
3171  octstr_format_append(reply_body, "%s", "\"");
3172 
3173  octstr_format_append(reply_body, "%s",
3174  " sender-address=\"");
3175  octstr_format_append(reply_body, "%S", url);
3176  octstr_format_append(reply_body, "%s", "\"");
3177 
3178  octstr_format_append(reply_body, "%s", ">"
3179  "<response-result code =\"");
3180  octstr_format_append(reply_body, "%d", code);
3181  octstr_format_append(reply_body, "%s", "\"");
3182 
3183  octstr_format_append(reply_body, "%s", " desc=\"");
3184  octstr_format_append(reply_body, "%S", dos = describe_code(code));
3185  octstr_format_append(reply_body, "\"");
3186 
3187  octstr_format_append(reply_body, "%s", ">"
3188  "</response-result>"
3189  "</push-response>"
3190  "</pap>");
3191 
3192  debug("wap.push.ppg", 0, "PPG: tell_fatal_error: %s", octstr_get_cstr(dos));
3193  send_to_pi(c, reply_body, status);
3194 
3195  octstr_destroy(dos);
3196  octstr_destroy(tos);
3197  octstr_destroy(sos);
3198  wap_event_destroy(e);
3199 }
static Octstr * describe_code(long code)
int code
Definition: smsc_cimd2.c:346
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static Octstr * tell_ppg_name(void)
static Octstr * set_time(void)
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
gw_assert(wtls_machine->packet_to_send!=NULL)
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static void send_to_pi(HTTPClient **c, Octstr *reply_body, int status)
WAPEventName type
Definition: wap_events.h:88
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2505
union WAPEvent::@87 u
void wap_event_destroy(WAPEvent *event)
Definition: wap_events.c:102
static Octstr * tell_ppg_name ( void  )
static

Definition at line 2157 of file wap_push_ppg.c.

References get_official_name(), and octstr_format().

Referenced by response_push_message(), and tell_fatal_error().

2158 {
2159  return octstr_format("%S; WAP/1.3 (" GW_NAME "/%s)", get_official_name(),
2160  GW_VERSION);
2161 }
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
Octstr * get_official_name(void)
Definition: socket.c:627
static int transform_message ( WAPEvent **  e,
WAPAddrTuple **  tuple,
List push_headers,
int  connected,
Octstr **  type 
)
static

Definition at line 1761 of file wap_push_ppg.c.

References address_type(), content::body, change_header_value(), content::charset, CONNECTED_CLIPORT, CONNECTED_SERVPORT, CONNECTIONLESS_PUSH_CLIPORT, CONNECTIONLESS_SERVPORT, content_transformable(), debug(), error(), gw_assert(), http_header_find_first, http_header_get_content_type(), octstr_destroy(), octstr_get_cstr, octstr_strip_blanks(), pap_convert_content(), pap_get_content(), set_addr_tuple(), content::type, and warning().

Referenced by handle_push_message().

1763 {
1764  int message_deliverable;
1765  struct content content;
1766  Octstr *cliaddr;
1767  long cliport,
1768  servport,
1769  address_type;
1770 
1771  gw_assert((**e).type == Push_Message);
1772  if ((**e).u.Push_Message.push_headers == NULL)
1773  goto herror;
1774 
1775  cliaddr = (**e).u.Push_Message.address_value;
1776  push_headers = (**e).u.Push_Message.push_headers;
1777 
1778  if (!cless_accepted) {
1779  cliport = CONNECTED_CLIPORT;
1780  servport = CONNECTED_SERVPORT;
1781  } else {
1782  cliport = CONNECTIONLESS_PUSH_CLIPORT;
1783  servport = CONNECTIONLESS_SERVPORT;
1784  }
1785 
1786  address_type = (**e).u.Push_Message.address_type;
1787  *tuple = set_addr_tuple(cliaddr, cliport, servport, address_type, push_headers);
1788 
1789  if (!content_transformable(push_headers))
1790  goto no_transform;
1791 
1792  content.charset = NULL;
1793  content.type = NULL;
1794 
1795  content.body = (**e).u.Push_Message.push_data;
1796  if (content.body == NULL)
1797  goto no_transform;
1798 
1799  content.type = http_header_find_first(push_headers, "Content-Transfer-Encoding");
1800  if (content.type) {
1802  debug("wap.push.ppg", 0, "PPG: Content-Transfer-Encoding is \"%s\"",
1804  message_deliverable = pap_get_content(&content);
1805 
1806  if (message_deliverable) {
1807  change_header_value(&push_headers, "Content-Transfer-Encoding",
1808  "binary");
1809  } else {
1810  goto error;
1811  }
1812  }
1813 
1816  message_deliverable = pap_convert_content(&content);
1817 
1818  if (content.type == NULL)
1819  goto error;
1820 
1821  if (message_deliverable) {
1822  *type = content.type;
1823  } else {
1824  goto error;
1825  }
1826 
1827  (**e).u.Push_Message.push_data = content.body;
1829 
1830  debug("wap.push.ppg", 0, "PPG: transform_message: push message content"
1831  " and headers valid");
1832  return 1;
1833 
1834 herror:
1835  warning(0, "PPG: transform_message: no push headers, cannot accept");
1837  return 0;
1838 
1839 error:
1840  warning(0, "PPG: transform_message: push content erroneous, cannot"
1841  " accept");
1844  return 0;
1845 
1846 no_transform:
1847  warning(0, "PPG: transform_message: push content non transformable");
1848  return 1;
1849 }
void error(int err, const char *fmt,...)
Definition: log.c:612
static int cless_accepted(WAPEvent *e, PPGSessionMachine *sm)
static int pap_get_content(struct content *content)
static int content_transformable(List *push_headers)
void http_header_get_content_type(List *headers, Octstr **type, Octstr **charset)
Definition: http.c:3202
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1344
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * body
Definition: wap-appl.c:144
static void change_header_value(List **push_headers, char *name, char *value)
static int pap_convert_content(struct content *content)
Octstr * type
Definition: wap-appl.c:145
#define http_header_find_first(headers, name)
Definition: http.h:592
void warning(int err, const char *fmt,...)
Definition: log.c:624
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
gw_assert(wtls_machine->packet_to_send!=NULL)
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
Octstr * charset
Definition: wap-appl.c:146
static WAPAddrTuple * set_addr_tuple(Octstr *address, long cliport, long servport, long address_type, List *push_headers)
static char * address_type(long type_of_address)
static int type_is ( Octstr content_header,
char *  required_type 
)
static

Definition at line 2935 of file wap_push_ppg.c.

References octstr_case_search(), octstr_destroy(), octstr_format(), and octstr_imm().

Referenced by headers_acceptable().

2936 {
2937  Octstr *quoted_type,
2938  *osname;
2939 
2940  osname = octstr_imm(name);
2941  if (octstr_case_search(content_header, osname, 0) >= 0)
2942  return 1;
2943 
2944  quoted_type = octstr_format("\"%S\"", osname);
2945 
2946  if (octstr_case_search(content_header, quoted_type, 0) >= 0) {
2947  octstr_destroy(quoted_type);
2948  return 1;
2949  }
2950 
2951  octstr_destroy(quoted_type);
2952  return 0;
2953 }
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
long octstr_case_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1100
char * name
Definition: smsc_cimd2.c:212
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Definition: octstr.c:118
static PPGPushMachine * update_push_data_with_attribute ( PPGSessionMachine **  sm,
PPGPushMachine pm,
long  reason,
long  status 
)
static

Definition at line 2557 of file wap_push_ppg.c.

References describe_code(), error(), gwlist_append(), gwlist_delete_equal(), gwlist_delete_matching(), ota_abort_to_pap(), PAP_ABORTED, PAP_BAD_REQUEST, PAP_CONFIRMED, PAP_DELIVERED, PAP_DELIVERED1, PAP_DELIVERED2, PAP_EXPIRED, PAP_PENDING, PAP_UNCONFIRMED, PAP_UNDELIVERABLE, PAP_UNDELIVERABLE1, PAP_UNDELIVERABLE2, push_has_pid(), push_machine_assert(), description_t::reason, and set_time().

Referenced by abort_delivery(), deliver_pending_pushes(), deliver_unit_push(), handle_internal_event(), and handle_push_message().

2559 {
2560  push_machine_assert(qm);
2561 
2562  switch (status) {
2563  case PAP_UNDELIVERABLE1:
2564  qm->message_state = PAP_UNDELIVERABLE;
2565  qm->code = PAP_BAD_REQUEST;
2566  break;
2567 
2568  case PAP_UNDELIVERABLE2:
2569  qm->code = reason;
2570  qm->message_state = PAP_UNDELIVERABLE;
2571  qm->desc = describe_code(reason);
2572  break;
2573 
2574  case PAP_ABORTED:
2575  qm->message_state = status;
2576  qm->code = ota_abort_to_pap(reason);
2577  qm->event_time = set_time();
2578  qm->desc = describe_code(reason);
2579  break;
2580 
2581  case PAP_DELIVERED1:
2582  qm->message_state = PAP_DELIVERED;
2583  qm->delivery_method = PAP_UNCONFIRMED;
2584  qm->event_time = set_time();
2585  break;
2586 
2587  case PAP_DELIVERED2:
2588  qm->message_state = PAP_DELIVERED;
2589  qm->delivery_method = PAP_CONFIRMED;
2590  qm->event_time = set_time();
2591  break;
2592 
2593  case PAP_EXPIRED:
2594  qm->message_state = PAP_EXPIRED;
2595  qm->event_time = set_time();
2596  qm->desc = describe_code(reason);
2597  break;
2598 
2599  case PAP_PENDING:
2600  qm->message_state = PAP_PENDING;
2601  break;
2602 
2603  default:
2604  error(0, "WAP_PUSH_PPG: update_push_data_with_attribute: Non"
2605  " existing push machine status: %ld", status);
2606  break;
2607  }
2608 
2609  if (*sm != NULL){
2610  gwlist_delete_matching((**sm).push_machines, &qm->push_id, push_has_pid);
2611  gwlist_append((**sm).push_machines, qm);
2614  } else {
2617  }
2618 
2619  return qm;
2620 }
void error(int err, const char *fmt,...)
Definition: log.c:612
static long ota_abort_to_pap(long reason)
void gwlist_append(List *list, void *item)
Definition: list.c:179
static Octstr * describe_code(long code)
static int push_has_pid(void *a, void *b)
static void push_machine_assert(PPGPushMachine *pm)
static List * ppg_unit_pushes
Definition: wap_push_ppg.c:149
static Octstr * set_time(void)
long gwlist_delete_equal(List *list, void *item)
Definition: list.c:266
long gwlist_delete_matching(List *list, void *pat, gwlist_item_matches_t *matches)
Definition: list.c:240
static List * ppg_machines
Definition: wap_push_ppg.c:143
static PPGSessionMachine * update_session_data ( PPGSessionMachine sm,
long  sid,
long  port,
List caps 
)
static

Definition at line 2625 of file wap_push_ppg.c.

References gw_assert(), gwlist_append(), gwlist_delete_equal(), port, session_machine_assert(), and wsp_cap_duplicate_list().

Referenced by handle_internal_event().

2627 {
2629  gw_assert(sid >= 0);
2630 
2631  m->session_id = sid;
2632  m->addr_tuple->remote->port = port;
2633  m->client_capabilities = wsp_cap_duplicate_list(caps);
2634 
2637 
2638  return m;
2639 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
List * wsp_cap_duplicate_list(List *caps_list)
Definition: wsp_caps.c:125
static int port
Definition: fakesmsc.c:120
long gwlist_delete_equal(List *list, void *item)
Definition: list.c:266
static void session_machine_assert(PPGSessionMachine *sm)
gw_assert(wtls_machine->packet_to_send!=NULL)
static List * ppg_machines
Definition: wap_push_ppg.c:143
static PPGSessionMachine * update_session_data_with_headers ( PPGSessionMachine sm,
PPGPushMachine pm 
)
static

Definition at line 2468 of file wap_push_ppg.c.

References gwlist_append(), gwlist_delete_matching(), and push_has_pid().

Referenced by handle_push_message().

2470 {
2471  gwlist_delete_matching(sm->push_machines, &pm->push_id, push_has_pid);
2472  gwlist_append(sm->push_machines, pm);
2473 
2474  return sm;
2475 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
static int push_has_pid(void *a, void *b)
long gwlist_delete_matching(List *list, void *pat, gwlist_item_matches_t *matches)
Definition: list.c:240
void wap_push_ppg_dispatch_event ( WAPEvent e)

Definition at line 476 of file wap_push_ppg.c.

References gw_assert(), gwlist_produce(), run_status, and running.

Referenced by confirm_push(), indicate_push_abort(), indicate_push_connection(), indicate_push_disconnect(), indicate_push_resume(), indicate_push_suspend(), and main().

477 {
480 }
void gwlist_produce(List *list, void *item)
Definition: list.c:411
static List * ppg_queue
Definition: wap_push_ppg.c:133
static enum @39 run_status
gw_assert(wtls_machine->packet_to_send!=NULL)
PPGSessionMachine* wap_push_ppg_have_push_session_for ( WAPAddrTuple tuple)

Definition at line 488 of file wap_push_ppg.c.

References WAPAddr::address, gw_assert(), gwlist_search(), WAPAddrTuple::remote, and session_has_addr().

Referenced by handle_internal_event(), and main_thread().

489 {
490  PPGSessionMachine *sm;
491 
492  gw_assert(tuple);
494 
495  return sm;
496 }
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
Definition: list.c:486
Octstr * address
Definition: wap_addr.h:68
gw_assert(wtls_machine->packet_to_send!=NULL)
static int session_has_addr(void *a, void *b)
WAPAddr * remote
Definition: wap_addr.h:74
static List * ppg_machines
Definition: wap_push_ppg.c:143
PPGSessionMachine* wap_push_ppg_have_push_session_for_sid ( long  sid)

Definition at line 503 of file wap_push_ppg.c.

References gw_assert(), gwlist_search(), and session_has_sid().

Referenced by handle_internal_event(), and main_thread().

504 {
505  PPGSessionMachine *sm;
506 
507  gw_assert(sid >= 0);
509 
510  return sm;
511 }
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
Definition: list.c:486
static int session_has_sid(void *a, void *b)
gw_assert(wtls_machine->packet_to_send!=NULL)
static List * ppg_machines
Definition: wap_push_ppg.c:143
void wap_push_ppg_init ( wap_dispatch_func_t ota_dispatch,
wap_dispatch_func_t appl_dispatch,
Cfg cfg 
)

Definition at line 397 of file wap_push_ppg.c.

References counter_create(), dict_create(), dispatch_to_appl, dispatch_to_ota, gw_assert(), gwlist_add_producer(), gwlist_create, gwthread_create, http_open_port(), http_read_thread(), limbo, NO_HTTPS_PORT, number_of_pushes, ota_read_thread(), pap_request_thread(), ppg_port, read_ppg_config(), run_status, running, TYPE_HTTP, TYPE_HTTPS, user_configuration, and USER_CONFIGURATION_NOT_ADDED.

Referenced by main().

399 {
409 
410  dispatch_to_ota = ota_dispatch;
411  dispatch_to_appl = appl_dispatch;
412 
414 #ifdef HAVE_LIBSSL
415  if (ppg_ssl_port != NO_HTTPS_PORT)
416  http_open_port(ppg_ssl_port, TYPE_HTTPS);
417 #endif
420 
425 #ifdef HAVE_LIBSSL
426  if (ppg_ssl_port != NO_HTTPS_PORT)
427  gwthread_create(https_read_thread, NULL);
428 #endif
430  }
431 }
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
static int read_ppg_config(Cfg *cfg)
Definition: wap_push_ppg.c:523
static Counter * push_id_counter
Definition: wap_push_ppg.c:154
static void http_read_thread(void *arg)
Definition: wap_push_ppg.c:688
static List * ppg_queue
Definition: wap_push_ppg.c:133
static enum @39 run_status
static List * ppg_unit_pushes
Definition: wap_push_ppg.c:149
static int user_configuration
Definition: wap_push_ppg.c:196
static Dict * urls
Definition: wap_push_ppg.c:165
static Dict * http_clients
Definition: wap_push_ppg.c:160
Counter * counter_create(void)
Definition: counter.c:94
static long ppg_port
Definition: wap_push_ppg.c:185
static wap_dispatch_func_t * dispatch_to_ota
Definition: wap_push_ppg.c:176
#define gwthread_create(func, arg)
Definition: gwthread.h:90
gw_assert(wtls_machine->packet_to_send!=NULL)
static void ota_read_thread(void *arg)
Definition: wap_push_ppg.c:634
int http_open_port(int port, int ssl)
Definition: http.c:2498
static long number_of_pushes
Definition: wap_push_ppg.c:191
static void pap_request_thread(void *arg)
Definition: wap_push_ppg.c:746
static wap_dispatch_func_t * dispatch_to_appl
Definition: wap_push_ppg.c:177
#define gwlist_create()
Definition: list.h:136
static List * pap_queue
Definition: wap_push_ppg.c:138
void gwlist_add_producer(List *list)
Definition: list.c:383
static List * ppg_machines
Definition: wap_push_ppg.c:143
void wap_push_ppg_shutdown ( void  )

Definition at line 433 of file wap_push_ppg.c.

References counter_destroy(), debug(), dict_destroy(), gw_assert(), gwlist_destroy(), gwlist_len(), gwlist_remove_producer(), gwthread_join_every(), http_close_all_ports(), http_read_thread(), NO_HTTPS_PORT, octstr_destroy(), ota_read_thread(), pap_event_destroy_item(), pap_request_thread(), push_machine_destroy(), run_status, running, session_machine_destroy(), terminating, user_configuration, USER_CONFIGURATION_NOT_ADDED, wap_event_destroy_item(), and wap_push_ppg_pushuser_list_destroy().

Referenced by main().

434 {
441  ppg_url = NULL;
453 
455 #ifdef HAVE_LIBSSL
456  if (ppg_ssl_port != NO_HTTPS_PORT)
457  gwthread_join_every(https_read_thread);
458 #endif
461 
465 
466  debug("wap.push.ppg", 0, "PPG: %ld push session machines left.",
469 
470  debug("wap_push_ppg", 0, "PPG: %ld unit pushes left",
473  }
474 }
static Octstr * service_name
Definition: wap_push_ppg.c:205
static Octstr * ppg_default_smsc
Definition: wap_push_ppg.c:198
void counter_destroy(Counter *counter)
Definition: counter.c:110
static Counter * push_id_counter
Definition: wap_push_ppg.c:154
long gwlist_len(List *list)
Definition: list.c:166
static Octstr * ppg_url
Definition: wap_push_ppg.c:184
static void http_read_thread(void *arg)
Definition: wap_push_ppg.c:688
static List * ppg_queue
Definition: wap_push_ppg.c:133
static enum @39 run_status
static Octstr * ppg_dlr_url
Definition: wap