ota_compiler.c
资源名称:gateway-1.2.1 [点击查看]
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:11k
源码类别:
手机WAP编程
开发平台:
WINDOWS
- /*
- * ota_compiler.c: Tokenizes an ota settings or bookmarks document. DTD is
- * defined in Over The Air Settings Specification (hereafter called ota),
- * chapter 6. (See http://www.americas.nokia.com/messaging/default.asp)
- *
- * By Aarno Syv鋘en for Wiral Ltd
- */
- #include <ctype.h>
- #include <libxml/xmlmemory.h>
- #include <libxml/tree.h>
- #include <libxml/debugXML.h>
- #include <libxml/encoding.h>
- #include "shared.h"
- #include "xml_shared.h"
- #include "ota_compiler.h"
- /****************************************************************************
- *
- * Global variables
- *
- * Two token table types, one and two token fields
- */
- struct ota_2table_t {
- char *name;
- unsigned char token;
- };
- typedef struct ota_2table_t ota_2table_t;
- /*
- * Ota tokenizes whole of attribute value, or uses an inline string. See ota,
- * chapter 8.2.
- */
- struct ota_3table_t {
- char *name;
- char *value;
- unsigned char token;
- };
- typedef struct ota_3table_t ota_3table_t;
- /*
- * Elements from tag code page zero. These are defined in ota, chapter 8.1.
- */
- static ota_2table_t ota_elements[] = {
- { "CHARACTERISTIC-LIST", 0x05 },
- { "CHARACTERISTIC", 0x06 },
- { "PARM", 0x07 }
- };
- #define NUMBER_OF_ELEMENTS sizeof(ota_elements)/sizeof(ota_elements[0])
- /*
- * Attribute names and values from code page zero. These are defined in ota,
- * chapter 8.2. Some values are presented as inline strings; in this case
- * value "INLINE" is used. (Note a quirk: there is an attribute with name
- * "VALUE".)
- *
- * For a documentation of the single attributes see gw/ota_prov_attr.h.
- */
- static ota_3table_t ota_attributes[] = {
- { "TYPE", "ADDRESS", 0x06 },
- { "TYPE", "URL", 0x07 },
- { "TYPE", "MMSURL", 0x7c },
- { "TYPE", "NAME", 0x08 },
- { "TYPE", "ID", 0x7d },
- { "TYPE", "BOOKMARK", 0x7f },
- { "NAME", "BEARER", 0x12 },
- { "NAME", "PROXY", 0x13 },
- { "NAME", "PORT", 0x14 },
- { "NAME", "NAME", 0x15 },
- { "NAME", "PROXY_TYPE", 0x16 },
- { "NAME", "URL", 0x17 },
- { "NAME", "PROXY_AUTHNAME", 0x18 },
- { "NAME", "PROXY_AUTHSECRET", 0x19 },
- { "NAME", "SMS_SMSC_ADDRESS", 0x1a },
- { "NAME", "USSD_SERVICE_CODE", 0x1b },
- { "NAME", "GPRS_ACCESSPOINTNAME", 0x1c },
- { "NAME", "PPP_LOGINTYPE", 0x1d },
- { "NAME", "PROXY_LOGINTYPE", 0x1e },
- { "NAME", "CSD_DIALSTRING", 0x21 },
- { "NAME", "CSD_CALLTYPE", 0x28 },
- { "NAME", "CSD_CALLSPEED", 0x29 },
- { "NAME", "PPP_AUTHTYPE", 0x22 },
- { "NAME", "PPP_AUTHNAME", 0x23 },
- { "NAME", "PPP_AUTHSECRET", 0x24 },
- { "NAME", "ISP_NAME", 0x7e },
- { "NAME", "INLINE", 0x10 },
- { "VALUE", "GSM/CSD", 0x45 },
- { "VALUE", "GSM/SMS", 0x46 },
- { "VALUE", "GSM/USSD", 0x47 },
- { "VALUE", "IS-136/CSD", 0x48 },
- { "VALUE", "GPRS", 0x49 },
- { "VALUE", "9200", 0x60 },
- { "VALUE", "9201", 0x61 },
- { "VALUE", "9202", 0x62 },
- { "VALUE", "9203", 0x63 },
- { "VALUE", "AUTOMATIC", 0x64 },
- { "VALUE", "MANUAL", 0x65 },
- { "VALUE", "AUTO", 0x6a },
- { "VALUE", "9600", 0x6b },
- { "VALUE", "14400", 0x6c },
- { "VALUE", "19200", 0x6d },
- { "VALUE", "28800", 0x6e },
- { "VALUE", "38400", 0x6f },
- { "VALUE", "PAP", 0x70 },
- { "VALUE", "CHAP", 0x71 },
- { "VALUE", "ANALOGUE", 0x72 },
- { "VALUE", "ISDN", 0x73 },
- { "VALUE", "43200", 0x74 },
- { "VALUE", "57600", 0x75 },
- { "VALUE", "MSISDN_NO", 0x76 },
- { "VALUE", "IPV4", 0x77 },
- { "VALUE", "MS_CHAP", 0x78 },
- { "VALUE", "INLINE", 0x11 }
- };
- #define NUMBER_OF_ATTRIBUTES sizeof(ota_attributes)/sizeof(ota_attributes[0])
- #include "xml_definitions.h"
- /****************************************************************************
- *
- * Prototypes of internal functions. Note that 'Ptr' means here '*'.
- */
- static int parse_document(xmlDocPtr document, Octstr *charset,
- simple_binary_t **ota_binary);
- static int parse_node(xmlNodePtr node, simple_binary_t **otabxml);
- static int parse_element(xmlNodePtr node, simple_binary_t **otabxml);
- static int parse_attribute(xmlAttrPtr attr, simple_binary_t **otabxml);
- static int use_inline_string(Octstr *valueos);
- /***************************************************************************
- *
- * Implementation of the external function
- */
- int ota_compile(Octstr *ota_doc, Octstr *charset, Octstr **ota_binary)
- {
- simple_binary_t *otabxml;
- int ret;
- xmlDocPtr pDoc;
- size_t size;
- char *ota_c_text;
- *ota_binary = octstr_create("");
- otabxml = simple_binary_create();
- octstr_strip_blanks(ota_doc);
- octstr_shrink_blanks(ota_doc);
- set_charset(ota_doc, charset);
- size = octstr_len(ota_doc);
- ota_c_text = octstr_get_cstr(ota_doc);
- pDoc = xmlParseMemory(ota_c_text, size);
- ret = 0;
- if (pDoc) {
- ret = parse_document(pDoc, charset, &otabxml);
- simple_binary_output(*ota_binary, otabxml);
- xmlFreeDoc(pDoc);
- } else {
- xmlFreeDoc(pDoc);
- octstr_destroy(*ota_binary);
- simple_binary_destroy(otabxml);
- error(0, "OTA: No document to parse. Probably an error in OTA source");
- return -1;
- }
- simple_binary_destroy(otabxml);
- return ret;
- }
- /*****************************************************************************
- *
- * Implementation of internal functions
- *
- * Parse document node. Store wbmxl version number and character set into the
- * start of the document. There are no wapforum public identifier for ota.
- * FIXME: Add parse_prologue!
- */
- static int parse_document(xmlDocPtr document, Octstr *charset,
- simple_binary_t **otabxml)
- {
- xmlNodePtr node;
- (*otabxml)->wbxml_version = 0x01; /* WBXML Version number 1.1 */
- (*otabxml)->public_id = 0x01; /* Public id for an unknown document type */
- charset = octstr_create("UTF-8");
- (*otabxml)->charset = parse_charset(charset);
- octstr_destroy(charset);
- node = xmlDocGetRootElement(document);
- return parse_node(node, otabxml);
- }
- /*
- * The recursive parsing function for the parsing tree. Function checks the
- * type of the node, calls for the right parse function for the type, then
- * calls itself for the first child of the current node if there's one and
- * after that calls itself for the next child on the list.
- */
- static int parse_node(xmlNodePtr node, simple_binary_t **otabxml)
- {
- int status = 0;
- /* Call for the parser function of the node type. */
- switch (node->type) {
- case XML_ELEMENT_NODE:
- status = parse_element(node, otabxml);
- break;
- case XML_TEXT_NODE:
- case XML_COMMENT_NODE:
- case XML_PI_NODE:
- /* Text nodes, comments and PIs are ignored. */
- break;
- /*
- * XML has also many other node types, these are not needed with
- * OTA. Therefore they are assumed to be an error.
- */
- default:
- error(0, "OTA compiler: Unknown XML node in the OTA source.");
- return -1;
- break;
- }
- /*
- * If node is an element with content, it will need an end tag after it's
- * children. The status for it is returned by parse_element.
- */
- switch (status) {
- case 0:
- if (node->children != NULL)
- if (parse_node(node->children, otabxml) == -1)
- return -1;
- break;
- case 1:
- if (node->children != NULL)
- if (parse_node(node->children, otabxml) == -1)
- return -1;
- parse_end(otabxml);
- break;
- case -1: /* Something went wrong in the parsing. */
- return -1;
- default:
- warning(0,"OTA compiler: undefined return value in a parse function.");
- return -1;
- break;
- }
- if (node->next != NULL)
- if (parse_node(node->next, otabxml) == -1)
- return -1;
- return 0;
- }
- /*
- * Parse an element node. Check if there is a token for an element tag; if not
- * output the element as a string, else output the token. After that, call
- * attribute parsing functions
- * Returns: 1, add an end tag (element node has no children)
- * 0, do not add an end tag (it has children)
- * -1, an error occurred
- */
- static int parse_element(xmlNodePtr node, simple_binary_t **otabxml)
- {
- Octstr *name;
- size_t i;
- unsigned char status_bits,
- ota_hex;
- int add_end_tag;
- xmlAttrPtr attribute;
- name = octstr_create(node->name);
- if (octstr_len(name) == 0) {
- octstr_destroy(name);
- return -1;
- }
- i = 0;
- while (i < NUMBER_OF_ELEMENTS) {
- if (octstr_compare(name, octstr_imm(ota_elements[i].name)) == 0)
- break;
- ++i;
- }
- status_bits = 0x00;
- ota_hex = 0x00;
- add_end_tag = 0;
- if (i != NUMBER_OF_ELEMENTS) {
- ota_hex = ota_elements[i].token;
- if ((status_bits = element_check_content(node)) > 0) {
- ota_hex = ota_hex | status_bits;
- if ((status_bits & WBXML_CONTENT_BIT) == WBXML_CONTENT_BIT)
- add_end_tag = 1;
- }
- output_char(ota_hex, otabxml);
- } else {
- warning(0, "unknown tag %s in OTA source", octstr_get_cstr(name));
- ota_hex = WBXML_LITERAL;
- if ((status_bits = element_check_content(node)) > 0) {
- ota_hex = ota_hex | status_bits;
- /* If this node has children, the end tag must be added after
- them. */
- if ((status_bits & WBXML_CONTENT_BIT) == WBXML_CONTENT_BIT)
- add_end_tag = 1;
- }
- output_char(ota_hex, otabxml);
- output_octet_string(octstr_duplicate(name), otabxml);
- }
- if (node->properties != NULL) {
- attribute = node->properties;
- while (attribute != NULL) {
- parse_attribute(attribute, otabxml);
- attribute = attribute->next;
- }
- parse_end(otabxml);
- }
- octstr_destroy(name);
- return add_end_tag;
- }
- /*
- * Tokenises an attribute, and in most cases, its value. (Some values are re-
- * presented as an inline string). Tokenisation is based on tables in ota,
- * chapters 8.1 and 8.2.
- * Returns 0 when success, -1 when error.
- */
- static int parse_attribute(xmlAttrPtr attr, simple_binary_t **otabxml)
- {
- Octstr *name,
- *value,
- *valueos,
- *nameos;
- unsigned char ota_hex;
- size_t i;
- name = octstr_create(attr->name);
- if (attr->children != NULL)
- value = create_octstr_from_node(attr->children);
- else
- value = NULL;
- if (value == NULL)
- goto error;
- i = 0;
- valueos = NULL;
- nameos = NULL;
- while (i < NUMBER_OF_ATTRIBUTES) {
- nameos = octstr_imm(ota_attributes[i].name);
- if (octstr_compare(name, nameos) == 0) {
- if (ota_attributes[i].value != NULL) {
- valueos = octstr_imm(ota_attributes[i].value);
- }
- if (octstr_compare(value, valueos) == 0) {
- break;
- }
- if (octstr_compare(valueos, octstr_imm("INLINE")) == 0) {
- break;
- }
- }
- ++i;
- }
- if (i == NUMBER_OF_ATTRIBUTES) {
- warning(0, "unknown attribute %s in OTA source",
- octstr_get_cstr(name));
- warning(0, "its value being %s", octstr_get_cstr(value));
- goto error;
- }
- ota_hex = ota_attributes[i].token;
- if (!use_inline_string(valueos)) {
- output_char(ota_hex, otabxml);
- } else {
- output_char(ota_hex, otabxml);
- parse_inline_string(value, otabxml);
- }
- octstr_destroy(name);
- octstr_destroy(value);
- return 0;
- error:
- octstr_destroy(name);
- octstr_destroy(value);
- return -1;
- }
- static int use_inline_string(Octstr *valueos)
- {
- return octstr_compare(valueos, octstr_imm("INLINE")) == 0;
- }