📄 wap_push_pap_compiler.c
字号:
/* ==================================================================== * The Kannel Software License, Version 1.0 * * Copyright (c) 2001-2004 Kannel Group * Copyright (c) 1998-2001 WapIT Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Kannel Group (http://www.kannel.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Kannel" and "Kannel Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact org@kannel.org. * * 5. Products derived from this software may not be called "Kannel", * nor may "Kannel" appear in their name, without prior written * permission of the Kannel Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Kannel Group. For more information on * the Kannel Group, please see <http://www.kannel.org/>. * * Portions of this software are based upon software originally written at * WapIT Ltd., Helsinki, Finland for the Kannel project. */ /* * wap_push_pap_compiler.c - implementation of wap_push_pap_compiler.h inter- * face (compiling pap documents to Kannel WAPEvents) * * This module implements PAP document DTD and status codes, defined in * WAP-164-PAP-19991108-a (called hereafter pap), chapter 9 and * PPG client addressing (it is. parsing client address of a pap document), * defined in * WAP-151-PPGService-19990816-a (ppg), chapter 7. * * In addition, Wapforum specification WAP-200-WDP-20001212-a (wdp) is re- * ferred. * * Compiler can be used by PI or PPG (it will handle all possible PAP DTD * elements). It checks that attribute values are legal and that an element * has only legal attributes, but does not otherwise validate PAP documents * against PAP DTD. (XML validation is quite another matter, of course.) * Client address is parsed out from the relevant PAP message attribute * containing lots of additional data, see ppg, 7.1. We do not yet support * user defined addresses. * * After compiling, some semantic analysing of the resulted event, and sett- * ing some defaults (however, relying on them is quite a bad policy). In * addition changing undefined values (any) to defined ones. * * By Aarno Syv鋘en for Wapit Ltd and for Wiral Ltd. */#include <libxml/xmlmemory.h>#include <libxml/parser.h>#include <libxml/tree.h>#include <libxml/debugXML.h>#include <libxml/encoding.h>#include <ctype.h>#include <string.h>#include "shared.h"#include "wap_push_pap_compiler.h"#include "wap_push_ppg.h"/**************************************************************************** * * Global data structures * * Table for pap elements. These are defined in PAP, Chapter 9. */static char *pap_elements[] = { "pap", "push-message", "address", "quality-of-service", "push-response", "progress-note", "response-result", "cancel-message", "cancel-result", "cancel-response", "resultnotification-message", "resultnotification-response", "statusquery-message", "statusquery-response", "statusquery-result", "ccq-message", "ccq-response", "badmessage-response"};#define NUM_ELEMENTS sizeof(pap_elements)/sizeof(pap_elements[0])/* * Table for PAP attributes. These are defined in pap, Chapter 9. */struct pap_attributes_t { char *name; char *value;};typedef struct pap_attributes_t pap_attributes_t;static pap_attributes_t pap_attributes[] = { { "product-name", NULL }, { "push-id", NULL }, { "deliver-before-timestamp", NULL }, { "deliver-after-timestamp", NULL }, { "source-reference", NULL }, { "progress-notes-requested", "true" }, { "progress-notes-requested", "false" }, { "ppg-notify-requested-to", NULL }, { "address-value", NULL }, { "priority", "high" }, { "priority", "medium" }, { "priority", "low" }, { "delivery-method", "confirmed" }, { "delivery-method", "preferconfirmed" }, { "delivery-method", "unconfirmed" }, { "delivery-method", "notspecified" }, { "network", NULL }, { "network-required", "true" }, { "network-required", "false" }, { "bearer", NULL }, { "bearer-required", "true" }, { "bearer-required", "false" }, { "sender-address", NULL }, { "sender-name", NULL }, { "reply-time", NULL }, { "stage", NULL }, { "note", NULL }, { "time", NULL }, { "code", NULL }, { "desc", NULL }, { "received-time", NULL }, { "event-time", NULL }, { "message-state", NULL }, { "query-id", NULL }, { "app-id", NULL }, { "bad-message-fragment", NULL}};#define NUM_ATTRIBUTES sizeof(pap_attributes)/sizeof(pap_attributes[0])/* * Status codes are defined in pap, chapter 9.13. */static int pap_codes[] = { PAP_ACCEPTED_FOR_PROCESSING, PAP_BAD_REQUEST, PAP_FORBIDDEN, PAP_ADDRESS_ERROR, PAP_CAPABILITIES_MISMATCH, PAP_DUPLICATE_PUSH_ID, PAP_TRANSFORMATION_FAILURE, PAP_REQUIRED_BEARER_NOT_AVAILABLE, PAP_ABORT_USERPND};#define NUM_CODES sizeof(pap_codes)/sizeof(pap_codes[0])/* * Possible bearer types. These are defined in wdp, appendix C. */static char *pap_bearer_types[] = { "Any", "USSD", "SMS", "GUTS/R-Data", "CSD", "Packet Data", "GPRS", "CDPD", "FLEX", "SDS", "ReFLEX", "MPAK", "GHOST/R_DATA"};#define NUM_BEARER_TYPES sizeof(pap_bearer_types)/sizeof(pap_bearer_types[0])/* * Possible network types. These are defined in wdp, appendix C. */static char *pap_network_types[] = { "Any", "GSM", "ANSI-136", "IS-95 CDMA", "AMPS", "PDC", "IDEN", "Paging network", "PHS", "TETRA", "Mobitex",};#define NUM_NETWORK_TYPES sizeof(pap_network_types)/ \ sizeof(pap_network_types[0])/**************************************************************************** * * Prototypes of internal functions. Note that suffix 'Ptr' means '*'. */static int parse_document(xmlDocPtr doc_p, WAPEvent **e);static int parse_node(xmlNodePtr node, WAPEvent **e, long *type_of_address, int *is_any); static int parse_element(xmlNodePtr node, WAPEvent **e, long *type_of_address, int *is_any); static int parse_attribute(Octstr *element_name, xmlAttrPtr attribute, WAPEvent **e, long *type_of_address, int *is_any);static int parse_attr_value(Octstr *element_name, Octstr *attr_name, Octstr *attr_value, WAPEvent **e, long *type_of_address, int *is_any);static int set_attribute_value(Octstr *element_name, Octstr *attr_value, Octstr *attr_name, WAPEvent **e);static int return_flag(Octstr *ros);static void wap_event_accept_or_create(Octstr *element_name, WAPEvent **e);static int parse_pap_value(Octstr *attr_name, Octstr *attr_value, WAPEvent **e);static int parse_push_message_value(Octstr *attr_name, Octstr *attr_value, WAPEvent **e);static int parse_address_value(Octstr *attr_name, Octstr *attr_value, WAPEvent **e, long *type_of_address);static int parse_quality_of_service_value(Octstr *attr_name, Octstr *attr_value, WAPEvent **e, int *is_any);static int parse_push_response_value(Octstr *attr_name, Octstr *attr_value, WAPEvent **e);static int parse_progress_note_value(Octstr *attr_name, Octstr *attr_value, WAPEvent **e);static int parse_bad_message_response_value(Octstr *attr_name, Octstr *attr_value, WAPEvent **e);static int parse_response_result_value(Octstr *attr_name, Octstr *attr_value, WAPEvent **e);static int parse_code(Octstr *attr_value);static Octstr *parse_bearer(Octstr *attr_value);static Octstr *parse_network(Octstr *attr_value);static int parse_requirement(Octstr *attr_value);static int parse_priority(Octstr *attr_value);static int parse_delivery_method(Octstr *attr_value);static int parse_state(Octstr *attr_value);static long parse_wappush_client_address(Octstr **address, long pos, long *type_of_address);static long parse_ppg_specifier(Octstr **address, long pos);static long parse_client_specifier(Octstr **address, long pos, long *type_of_address);static long parse_constant(const char *field_name, Octstr **address, long pos);static long parse_dom_fragment(Octstr **address, long pos);static long drop_character(Octstr **address, long pos);static long parse_type(Octstr **address, Octstr **type_value, long pos);static long parse_ext_qualifiers(Octstr **address, long pos, Octstr *type_value);static long parse_global_phone_number(Octstr **address, long pos);static long parse_ipv4(Octstr **address, long pos);static long parse_ipv6(Octstr **address, long pos);static long parse_escaped_value(Octstr **address, long pos); static Octstr *prepend_char(Octstr *address, unsigned char c);static int qualifiers(Octstr *address, long pos, Octstr *type);static long parse_qualifier_value(Octstr **address, long pos);static long parse_qualifier_keyword(Octstr **address, long pos);static long parse_ipv4_fragment(Octstr **address, long pos);static long parse_ipv6_fragment(Octstr **address, long pos);static int wina_bearer_identifier(Octstr *type_value);static int create_peek_window(Octstr **address, long *pos);static long rest_unescaped(Octstr **address, long pos);static int issafe(Octstr **address, long pos);static long accept_safe(Octstr **address, long pos);static long accept_escaped(Octstr **address, long pos);static long handle_two_terminators (Octstr **address, long pos, unsigned char comma, unsigned char point, unsigned char c, long fragment_parsed, long fragment_length);static int uses_gsm_msisdn_address(long bearer_required, Octstr *bearer);static int uses_ipv4_address(long bearer_required, Octstr *bearer);static int uses_ipv6_address(long bearer_required, Octstr *bearer);static int event_semantically_valid(WAPEvent *e, long type_of_address);static char *address_type(long type_of_address);static void set_defaults(WAPEvent **e, long type_of_address);static void set_bearer_defaults(WAPEvent **e, long type_of_address);static void set_network_defaults(WAPEvent **e, long type_of_address);static int set_anys(WAPEvent **e, long type_of_address, int is_any);static void set_any_value(int *is_any, Octstr *attr_name, Octstr *attr_value);/* * Macro for creating an octet string from a node content. This has two * versions for different libxml node content implementation methods. */#ifdef XML_USE_BUFFER_CONTENT#define create_octstr_from_node(node) (octstr_create(node->content->content))#else#define create_octstr_from_node(node) (octstr_create(node->content))#endif/**************************************************************************** * * Compile PAP control document to a corresponding Kannel event. Checks vali- * dity of the document. The caller must initialize wap event to NULL. In add- * ition, it must free memory allocated by this function. * * After compiling, some semantic analysing of the resulted event. * * Note that entities in the DTD are parameter entities and they can appear * only in DTD (See site http://www.w3.org/TR/REC-xml, Chapter 4.1). So we do * not need to worry about them in the document itself. * * Returns 0, when success * -1, when a non-implemented pap feature is asked for * -2, when error * In addition, returns a newly created wap event corresponding the pap * control message, if success, wap event NULL otherwise. */int pap_compile(Octstr *pap_content, WAPEvent **e){ xmlDocPtr doc_p; size_t oslen; int ret; if (octstr_search_char(pap_content, '\0', 0) != -1) { warning(0, "PAP COMPILER: pap_compile: pap source contained a \\0" " character"); return -2; } octstr_strip_blanks(pap_content); oslen = octstr_len(pap_content); doc_p = xmlParseMemory(octstr_get_cstr(pap_content), oslen); if (doc_p == NULL) { goto error; } if ((ret = parse_document(doc_p, e)) < 0) { goto parserror; } xmlFreeDoc(doc_p); return 0;parserror: xmlFreeDoc(doc_p); wap_event_destroy(*e); *e = NULL; return ret;error: warning(0, "PAP COMPILER: pap_compile: parse error in pap source"); xmlFreeDoc(doc_p); wap_event_destroy(*e); *e = NULL; return -2;}/**************************************************************************** * * Implementation of internal functions * */enum { NEITHER = 0, BEARER_ANY = 1, NETWORK_ANY = 2, EITHER = 3, ERROR_ANY = 4};/* * Parse the document node of libxml syntax tree. FIXME: Add parsing of pap * version. * After parsing, some semantic analysing of the resulted event. Then set * a default network and bearer deduced from address type, if the correspond- * ing pap attribute is missing. * * Returns 0, when success * -1, when a non-implemented pap feature is requested * -2, when error * In addition, return a newly created wap event corresponding the pap * control message, if success, or partially parsed pap document, if not. Set * a field containing address type. */static int parse_document(xmlDocPtr doc_p, WAPEvent **e){ xmlNodePtr node; int ret, is_any; /* is bearer and/or network set any in qos attribute */ long type_of_address; gw_assert(doc_p); node = xmlDocGetRootElement(doc_p);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -