Kannel: Open Source WAP and SMS gateway  svn-r5335
ota_compiler.c File Reference
#include <ctype.h>
#include <inttypes.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"
#include "xml_definitions.h"

Go to the source code of this file.

Data Structures

struct  ota_2table_t
 
struct  ota_3table_t
 

Macros

#define NUMBER_OF_ELEMENTS   sizeof(ota_elements)/sizeof(ota_elements[0])
 
#define NUMBER_OF_SYNCSETTINGS_ELEMENTS   sizeof(ota_syncsettings_elements)/sizeof(ota_syncsettings_elements[0])
 
#define NUMBER_OF_ATTRIBUTES   sizeof(ota_attributes)/sizeof(ota_attributes[0])
 
#define OMA_VALUE_TAG   0x06
 
#define NUMBER_OF_OMA_ATTRIBUTES   sizeof(oma_ota_attributes)/sizeof(oma_ota_attributes[0])
 

Typedefs

typedef struct ota_2table_t ota_2table_t
 
typedef struct ota_3table_t ota_3table_t
 

Functions

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)
 
int ota_compile (Octstr *ota_doc, Octstr *charset, Octstr **ota_binary)
 
static int parse_ota_syncsettings (xmlNodePtr node, simple_binary_t **otabxml)
 

Variables

static ota_2table_t ota_elements []
 
static ota_2table_t ota_syncsettings_elements []
 
static ota_3table_t ota_attributes []
 
static ota_3table_t oma_ota_attributes []
 

Macro Definition Documentation

◆ NUMBER_OF_ATTRIBUTES

#define NUMBER_OF_ATTRIBUTES   sizeof(ota_attributes)/sizeof(ota_attributes[0])

Definition at line 229 of file ota_compiler.c.

Referenced by parse_attribute().

◆ NUMBER_OF_ELEMENTS

#define NUMBER_OF_ELEMENTS   sizeof(ota_elements)/sizeof(ota_elements[0])

Definition at line 133 of file ota_compiler.c.

Referenced by parse_element().

◆ NUMBER_OF_OMA_ATTRIBUTES

#define NUMBER_OF_OMA_ATTRIBUTES   sizeof(oma_ota_attributes)/sizeof(oma_ota_attributes[0])

Definition at line 453 of file ota_compiler.c.

Referenced by parse_attribute().

◆ NUMBER_OF_SYNCSETTINGS_ELEMENTS

#define NUMBER_OF_SYNCSETTINGS_ELEMENTS   sizeof(ota_syncsettings_elements)/sizeof(ota_syncsettings_elements[0])

Definition at line 161 of file ota_compiler.c.

Referenced by parse_ota_syncsettings().

◆ OMA_VALUE_TAG

#define OMA_VALUE_TAG   0x06

Definition at line 451 of file ota_compiler.c.

Referenced by parse_attribute().

Typedef Documentation

◆ ota_2table_t

typedef struct ota_2table_t ota_2table_t

Definition at line 105 of file ota_compiler.c.

◆ ota_3table_t

typedef struct ota_3table_t ota_3table_t

Definition at line 118 of file ota_compiler.c.

Function Documentation

◆ ota_compile()

int ota_compile ( Octstr ota_doc,
Octstr charset,
Octstr **  ota_binary 
)

Definition at line 473 of file ota_compiler.c.

References charset, error(), octstr_create, octstr_destroy(), octstr_get_cstr, octstr_len(), octstr_shrink_blanks(), octstr_strip_blanks(), parse_document(), set_charset(), simple_binary_create(), simple_binary_destroy(), simple_binary_output(), and size.

Referenced by main(), and ota_pack_message().

474 {
475  simple_binary_t *otabxml;
476  int ret;
477  xmlDocPtr pDoc;
478  size_t size;
479  char *ota_c_text;
480 
481  *ota_binary = octstr_create("");
482  otabxml = simple_binary_create();
483 
484  octstr_strip_blanks(ota_doc);
485  octstr_shrink_blanks(ota_doc);
486  set_charset(ota_doc, charset);
487  size = octstr_len(ota_doc);
488  ota_c_text = octstr_get_cstr(ota_doc);
489  pDoc = xmlParseMemory(ota_c_text, size);
490 
491  ret = 0;
492  if (pDoc) {
493  ret = parse_document(pDoc, charset, &otabxml);
494  simple_binary_output(*ota_binary, otabxml);
495  xmlFreeDoc(pDoc);
496  } else {
497  xmlFreeDoc(pDoc);
498  octstr_destroy(*ota_binary);
499  simple_binary_destroy(otabxml);
500  error(0, "OTA: No document to parse. Probably an error in OTA source");
501  return -1;
502  }
503 
504  simple_binary_destroy(otabxml);
505 
506  return ret;
507 }
void error(int err, const char *fmt,...)
Definition: log.c:648
int size
Definition: wsasm.c:84
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1346
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * charset
Definition: test_ota.c:68
void simple_binary_destroy(simple_binary_t *binary)
Definition: xml_shared.c:298
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
void simple_binary_output(Octstr *os, simple_binary_t *binary)
Definition: xml_shared.c:311
static int parse_document(xmlDocPtr document, Octstr *charset, simple_binary_t **ota_binary)
Definition: ota_compiler.c:518
void set_charset(Octstr *document, Octstr *charset)
Definition: xml_shared.c:111
simple_binary_t * simple_binary_create(void)
Definition: xml_shared.c:284
void octstr_shrink_blanks(Octstr *text)
Definition: octstr.c:1433

◆ parse_attribute()

static int parse_attribute ( xmlAttrPtr  attr,
simple_binary_t **  otabxml 
)
static

Definition at line 749 of file ota_compiler.c.

References ota_3table_t::code_page, create_octstr_from_node, error(), name, NUMBER_OF_ATTRIBUTES, NUMBER_OF_OMA_ATTRIBUTES, octstr_case_compare(), octstr_compare(), octstr_create, octstr_destroy(), octstr_get_cstr, octstr_imm(), oma_ota_attributes, OMA_VALUE_TAG, ota_attributes, output_char(), parse_inline_string(), ota_3table_t::token, ota_3table_t::value, and warning().

Referenced by parse_element().

750 {
751  Octstr *name, *value, *valueos, *nameos;
752  unsigned char ota_hex;
753  size_t i, limit;
754  ota_3table_t *alist;
755 
756  name = octstr_create((char *)attr->name);
757 
758  if (attr->children != NULL)
759  value = create_octstr_from_node((char *)attr->children);
760  else
761  value = NULL;
762 
763  if (value == NULL)
764  goto error;
765 
766  /* OMA has it's own dedicated public ID, so use this */
767  if ((*otabxml)->public_id == 0x0B) {
768  alist = oma_ota_attributes;
769  limit = NUMBER_OF_OMA_ATTRIBUTES;
770  } else {
771  alist = ota_attributes;
772  limit = NUMBER_OF_ATTRIBUTES;
773  }
774 
775  i = 0;
776  valueos = NULL;
777  nameos = NULL;
778  while (i < limit) {
779  nameos = octstr_imm(alist[i].name);
780  if (octstr_case_compare(name, nameos) == 0) {
781  if (alist[i].value != NULL) {
782  valueos = octstr_imm(alist[i].value);
783  }
784  if (octstr_case_compare(value, valueos) == 0) {
785  break;
786  }
787  if (octstr_compare(valueos, octstr_imm("INLINE")) == 0) {
788  break;
789  }
790  }
791  ++i;
792  }
793 
794  if (i == limit) {
795  warning(0, "OTA compiler: Unknown attribute '%s' in OTA source, "
796  "with value '%s'.",
798  goto error;
799  }
800 
801  ota_hex = alist[i].token;
802  /* if not inline used */
803  if (octstr_compare(valueos, octstr_imm("INLINE")) != 0) {
804  /* Switch code page. */
805  if (alist[i].code_page != (*otabxml)->code_page) {
806  output_char(0, otabxml);
807  output_char(alist[i].code_page, otabxml);
808  (*otabxml)->code_page = alist[i].code_page;
809  }
810  /* if OMA add value tag */
811  if ((*otabxml)->public_id == 0x0B && name
812  && octstr_case_compare(name, octstr_imm("value")) == 0)
813  output_char(OMA_VALUE_TAG, otabxml);
814  output_char(ota_hex, otabxml);
815  } else {
816  /* Switch code page. */
817  if (alist[i].code_page != (*otabxml)->code_page) {
818  output_char(0, otabxml);
819  output_char(alist[i].code_page, otabxml);
820  (*otabxml)->code_page = alist[i].code_page;
821  }
822  output_char(ota_hex, otabxml);
823  parse_inline_string(value, otabxml);
824  }
825 
827  octstr_destroy(value);
828  return 0;
829 
830 error:
832  octstr_destroy(value);
833  return -1;
834 }
void error(int err, const char *fmt,...)
Definition: log.c:648
#define NUMBER_OF_ATTRIBUTES
Definition: ota_compiler.c:229
static ota_3table_t ota_attributes[]
Definition: ota_compiler.c:172
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static ota_3table_t oma_ota_attributes[]
Definition: ota_compiler.c:237
#define OMA_VALUE_TAG
Definition: ota_compiler.c:451
void parse_inline_string(Octstr *temp, simple_binary_t **binary)
Definition: xml_shared.c:339
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
char * name
Definition: smsc_cimd2.c:212
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:903
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
Definition: octstr.c:118
unsigned char code_page
Definition: ota_compiler.c:115
#define NUMBER_OF_OMA_ATTRIBUTES
Definition: ota_compiler.c:453
void output_char(int byte, simple_binary_t **binary)
Definition: xml_shared.c:326
#define create_octstr_from_node(node)
unsigned char token
Definition: ota_compiler.c:114
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ parse_document()

static int parse_document ( xmlDocPtr  document,
Octstr charset,
simple_binary_t **  ota_binary 
)
static

Definition at line 518 of file ota_compiler.c.

References charset, octstr_create, octstr_destroy(), parse_charset(), and parse_node().

Referenced by ota_compile().

520 {
521  xmlNodePtr node;
522 
523  if (document->intSubset && document->intSubset->ExternalID
524  && strcmp((char *)document->intSubset->ExternalID, "-//WAPFORUM//DTD PROV 1.0//EN") == 0) {
525  /* OMA ProvCont */
526  (*otabxml)->wbxml_version = 0x03; /* WBXML Version number 1.3 */
527  (*otabxml)->public_id = 0x0B; /* Public id for this kind of doc */
528  } else {
529  /* OTA */
530  (*otabxml)->wbxml_version = 0x01; /* WBXML Version number 1.1 */
531  (*otabxml)->public_id = 0x01; /* Public id for an unknown document type */
532  }
533  (*otabxml)->code_page = 0;
534 
535  charset = octstr_create("UTF-8");
536  (*otabxml)->charset = parse_charset(charset);
538 
539  node = xmlDocGetRootElement(document);
540  return parse_node(node, otabxml);
541 }
Octstr * charset
Definition: test_ota.c:68
static int parse_node(xmlNodePtr node, simple_binary_t **otabxml)
Definition: ota_compiler.c:550
int parse_charset(Octstr *os)
Definition: xml_shared.c:189
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125

◆ parse_element()

static int parse_element ( xmlNodePtr  node,
simple_binary_t **  otabxml 
)
static

Definition at line 674 of file ota_compiler.c.

References element_check_content(), name, NUMBER_OF_ELEMENTS, octstr_case_compare(), octstr_create, octstr_destroy(), octstr_duplicate, octstr_get_cstr, octstr_imm(), octstr_len(), octstr_search_char(), ota_elements, output_char(), output_octet_string(), parse_attribute(), parse_end(), parse_ota_syncsettings(), ota_2table_t::token, warning(), WBXML_CONTENT_BIT, and WBXML_LITERAL.

Referenced by parse_node().

675 {
676  Octstr *name;
677  size_t i;
678  unsigned char status_bits, ota_hex;
679  int add_end_tag, syncstat;
680  xmlAttrPtr attribute;
681 
682  /* if compiling a syncsettings document there's no need to
683  continue with the parsing of ota or oma tags. */
684  syncstat = -1;
685  if (octstr_search_char((**otabxml).binary, 0x55, 0) == 0) {
686  syncstat = parse_ota_syncsettings(node, otabxml);
687  if (syncstat >= 0) {
688  return syncstat;
689  }
690  }
691 
692  name = octstr_create((char *)node->name);
693  if (octstr_len(name) == 0) {
695  return -1;
696  }
697 
698  i = 0;
699  while (i < NUMBER_OF_ELEMENTS) {
701  break;
702  ++i;
703  }
704 
705  status_bits = 0x00;
706  ota_hex = 0x00;
707  add_end_tag = 0;
708 
709  if (i != NUMBER_OF_ELEMENTS) {
710  ota_hex = ota_elements[i].token;
711  if ((status_bits = element_check_content(node)) > 0) {
712  ota_hex = ota_hex | status_bits;
713  if ((status_bits & WBXML_CONTENT_BIT) == WBXML_CONTENT_BIT)
714  add_end_tag = 1;
715  }
716  output_char(ota_hex, otabxml);
717  } else {
718  warning(0, "OTA compiler: Unknown tag '%s' in OTA source", octstr_get_cstr(name));
719  ota_hex = WBXML_LITERAL;
720  if ((status_bits = element_check_content(node)) > 0) {
721  ota_hex = ota_hex | status_bits;
722  /* If this node has children, the end tag must be added after them. */
723  if ((status_bits & WBXML_CONTENT_BIT) == WBXML_CONTENT_BIT)
724  add_end_tag = 1;
725  }
726  output_char(ota_hex, otabxml);
728  }
729 
730  if (node->properties != NULL) {
731  attribute = node->properties;
732  while (attribute != NULL) {
733  parse_attribute(attribute, otabxml);
734  attribute = attribute->next;
735  }
736  parse_end(otabxml);
737  }
738 
740  return add_end_tag;
741 }
void output_octet_string(Octstr *os, simple_binary_t **sibxml)
Definition: xml_shared.c:349
unsigned char element_check_content(xmlNodePtr node)
Definition: xml_shared.c:242
unsigned char token
Definition: ota_compiler.c:102
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static ota_2table_t ota_elements[]
Definition: ota_compiler.c:125
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
#define WBXML_LITERAL
#define octstr_duplicate(ostr)
Definition: octstr.h:187
char * name
Definition: smsc_cimd2.c:212
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:903
static int parse_attribute(xmlAttrPtr attr, simple_binary_t **otabxml)
Definition: ota_compiler.c:749
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
static int parse_ota_syncsettings(xmlNodePtr node, simple_binary_t **otabxml)
Definition: ota_compiler.c:610
#define NUMBER_OF_ELEMENTS
Definition: ota_compiler.c:133
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
void parse_end(simple_binary_t **binary)
Definition: xml_shared.c:321
void output_char(int byte, simple_binary_t **binary)
Definition: xml_shared.c:326
#define WBXML_CONTENT_BIT

◆ parse_node()

static int parse_node ( xmlNodePtr  node,
simple_binary_t **  otabxml 
)
static

Definition at line 550 of file ota_compiler.c.

References error(), parse_element(), parse_end(), and warning().

Referenced by parse_document().

551 {
552  int status = 0;
553 
554  /* Call for the parser function of the node type. */
555  switch (node->type) {
556  case XML_ELEMENT_NODE:
557  status = parse_element(node, otabxml);
558  break;
559  case XML_TEXT_NODE:
560  case XML_COMMENT_NODE:
561  case XML_PI_NODE:
562  /* Text nodes, comments and PIs are ignored. */
563  break;
564  /*
565  * XML has also many other node types, these are not needed with
566  * OTA. Therefore they are assumed to be an error.
567  */
568  default:
569  error(0, "OTA compiler: Unknown XML node in the OTA source.");
570  return -1;
571  break;
572  }
573 
574  /*
575  * If node is an element with content, it will need an end tag after it's
576  * children. The status for it is returned by parse_element.
577  */
578  switch (status) {
579  case 0:
580  if (node->children != NULL && parse_node(node->children, otabxml) == -1)
581  return -1;
582  break;
583  case 1:
584  if (node->children != NULL && parse_node(node->children, otabxml) == -1)
585  return -1;
586  parse_end(otabxml);
587  break;
588  case -1: /* Something went wrong in the parsing. */
589  return -1;
590  break;
591  default:
592  warning(0,"OTA compiler: Undefined return value in a parse function.");
593  return -1;
594  break;
595  }
596 
597  if (node->next != NULL && parse_node(node->next, otabxml) == -1)
598  return -1;
599 
600  return 0;
601 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static int parse_node(xmlNodePtr node, simple_binary_t **otabxml)
Definition: ota_compiler.c:550
void warning(int err, const char *fmt,...)
Definition: log.c:660
static int parse_element(xmlNodePtr node, simple_binary_t **otabxml)
Definition: ota_compiler.c:674
void parse_end(simple_binary_t **binary)
Definition: xml_shared.c:321

◆ parse_ota_syncsettings()

static int parse_ota_syncsettings ( xmlNodePtr  node,
simple_binary_t **  otabxml 
)
static

Definition at line 610 of file ota_compiler.c.

References content, element_check_content(), error(), name, NUMBER_OF_SYNCSETTINGS_ELEMENTS, octstr_case_compare(), octstr_create, octstr_destroy(), octstr_get_cstr, octstr_imm(), octstr_len(), only_blanks(), ota_syncsettings_elements, output_char(), parse_inline_string(), ota_2table_t::token, token, warning(), and WBXML_CONTENT_BIT.

Referenced by parse_element().

611 {
612  Octstr *name, *content;
613  unsigned char status_bits, ota_hex;
614  int add_end_tag;
615  size_t i;
616 
617  name = NULL;
618  content = NULL;
619  name = octstr_create((char *)node->name);
620  if (octstr_len(name) == 0) {
621  goto error;
622  }
623 
624  i = 0;
625  while (i < NUMBER_OF_SYNCSETTINGS_ELEMENTS) {
627  break;
628  ++i;
629  }
630 
632  goto error;
633  }
634 
635  ota_hex = ota_syncsettings_elements[i].token;
637 
638  /* if the node has CDATA content output it.
639  * Else expect child tags */
640  if (!only_blanks((char *)node->children->content)) {
641  content = octstr_create((char *)node->children->content);
642  parse_inline_string(content, otabxml);
643  }
644 
645  add_end_tag = 0;
646  if ((status_bits = element_check_content(node)) > 0) {
647  ota_hex = ota_hex | status_bits;
648  /* If this node has children, the end tag must be added after them. */
649  if ((status_bits & WBXML_CONTENT_BIT) == WBXML_CONTENT_BIT) {
650  add_end_tag = 1;
651  }
652  }
653 
656  return add_end_tag;
657 
658  error:
659  warning(0, "OTA compiler: Unknown tag '%s' in OTA SyncSettings source",
663  return -1;
664 }
void error(int err, const char *fmt,...)
Definition: log.c:648
unsigned char element_check_content(xmlNodePtr node)
Definition: xml_shared.c:242
unsigned char token
Definition: ota_compiler.c:102
#define NUMBER_OF_SYNCSETTINGS_ELEMENTS
Definition: ota_compiler.c:161
static ota_2table_t ota_syncsettings_elements[]
Definition: ota_compiler.c:139
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void parse_inline_string(Octstr *temp, simple_binary_t **binary)
Definition: xml_shared.c:339
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
int token
Definition: wslexer.c:159
char * name
Definition: smsc_cimd2.c:212
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:903
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
int only_blanks(const char *text)
Definition: xml_shared.c:171
void output_char(int byte, simple_binary_t **binary)
Definition: xml_shared.c:326
#define WBXML_CONTENT_BIT
static Octstr * content
Definition: mtbatch.c:87

Variable Documentation

◆ oma_ota_attributes

ota_3table_t oma_ota_attributes[]
static

Definition at line 237 of file ota_compiler.c.

Referenced by parse_attribute().

◆ ota_attributes

ota_3table_t ota_attributes[]
static

Definition at line 172 of file ota_compiler.c.

Referenced by parse_attribute().

◆ ota_elements

ota_2table_t ota_elements[]
static
Initial value:
= {
{ "SYNCSETTINGS", 0x15 },
{ "WAP-PROVISIONINGDOC", 0x05 },
{ "CHARACTERISTIC-LIST", 0x05 },
{ "CHARACTERISTIC", 0x06 },
{ "PARM", 0x07 }
}

Definition at line 125 of file ota_compiler.c.

Referenced by parse_element().

◆ ota_syncsettings_elements

ota_2table_t ota_syncsettings_elements[]
static
Initial value:
= {
{ "Addr", 0x45 },
{ "AddrType", 0x46 },
{ "Auth", 0x47 },
{ "AuthLevel", 0x48 },
{ "AuthScheme", 0x49 },
{ "Bearer", 0x4A },
{ "ConRef", 0x4B },
{ "ConType", 0x4C },
{ "Cred", 0x4D },
{ "CTType", 0x4E },
{ "CTVer", 0x4F },
{ "HostAddr", 0x50 },
{ "Name", 0x51 },
{ "Port", 0x52 },
{ "RefID", 0x53 },
{ "RemoteDB", 0x54 },
{ "URI", 0x56 },
{ "Username", 0x57 },
{ "Version", 0x58 }
}

Definition at line 139 of file ota_compiler.c.

Referenced by parse_ota_syncsettings().

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.