📄 wap_push_pap_compiler.c
字号:
is_any = NEITHER; if ((ret = parse_node(node, e, &type_of_address, &is_any)) < 0) return ret; (*e)->u.Push_Message.address_type = type_of_address; if ((ret= event_semantically_valid(*e, type_of_address)) == 0) { warning(0, "wrong type of address for requested bearer"); return -2; } else if (ret == -1) { info(0, "reverting to default bearer and network"); set_defaults(e, type_of_address); return 0; } if (!set_anys(e, type_of_address, is_any)) { warning(0, "unable to handle any values in qos"); return -2; } else { debug("wap.push.pap.compiler", 0, "using defaults instead of anys"); } wap_event_assert(*e); return 0;}static int set_anys(WAPEvent **e, long type_of_address, int is_any){ switch (is_any) { case NEITHER: return 1; case BEARER_ANY: set_bearer_defaults(e, type_of_address); return 1; case NETWORK_ANY: set_network_defaults(e, type_of_address); return 1; case EITHER: set_defaults(e, type_of_address); return 1; default: return 0; }}/* * We actually use address_type field of a wap event for cotrolling the bearer * selection. Bearer and network filed are used for debugging purposes. */static void set_defaults(WAPEvent **e, long type_of_address){ set_bearer_defaults(e, type_of_address); set_network_defaults(e, type_of_address); }static void set_bearer_defaults(WAPEvent **e, long type_of_address){ gw_assert(type_of_address == ADDR_USER || type_of_address == ADDR_PLMN || type_of_address == ADDR_IPV4 || type_of_address == ADDR_IPV6 || type_of_address == ADDR_WINA); if ((*e)->type != Push_Message) return; (*e)->u.Push_Message.bearer_required = PAP_TRUE; octstr_destroy((*e)->u.Push_Message.bearer); switch (type_of_address) { case ADDR_PLMN: (*e)->u.Push_Message.bearer = octstr_format("%s", "SMS"); break; case ADDR_IPV4: (*e)->u.Push_Message.bearer = octstr_format("%s", "CSD"); break; case ADDR_IPV6: break; }}static void set_network_defaults(WAPEvent **e, long type_of_address){ gw_assert(type_of_address == ADDR_USER || type_of_address == ADDR_PLMN || type_of_address == ADDR_IPV4 || type_of_address == ADDR_IPV6 || type_of_address == ADDR_WINA); if ((*e)->type != Push_Message) return; (*e)->u.Push_Message.network_required = PAP_TRUE; octstr_destroy((*e)->u.Push_Message.network); switch (type_of_address) { case ADDR_PLMN: (*e)->u.Push_Message.network = octstr_format("%s", "GSM"); break; case ADDR_IPV4: (*e)->u.Push_Message.network = octstr_format("%s", "GSM"); break; case ADDR_IPV6: break; }}static char *address_type(long type_of_address){ switch(type_of_address) { case ADDR_USER: return "user defined address"; case ADDR_PLMN: return "a phone number"; case ADDR_IPV4: return "a IPv4 address"; case ADDR_IPV6: return "a IPv6 address"; case ADDR_WINA: return "a WINA accepted address"; default: return "unknown address"; }}/* * Do semantic analysis, when the event was Push_Message. Do not accept an IP * address, when a non-IP bearer is requested, and a phone number, when an IP * bearer is requested. * Return 0, when event is unacceptable * 1, when it is acceptable * -1, when there are no bearer or network specified */static int event_semantically_valid(WAPEvent *e, long type_of_address){ int ret; debug("wap.push.pap.compiler", 0, "PAP COMPILER: doing semantic analysis" " for address type %s", address_type(type_of_address)); if (e->type != Push_Message) { return 1; } if (e->u.Push_Message.network_required != e->u.Push_Message.bearer_required) { debug("wap.push.pap.compiler", 0, "PAP COMPILER: network-required and" " bearer-required must have same value"); return 0; } if (type_of_address == ADDR_PLMN) { if ((ret = uses_gsm_msisdn_address( e->u.Push_Message.bearer_required, e->u.Push_Message.bearer)) == 0) { debug("wap.push.pap.compiler", 0, "PAP COMPILER: bearer does" " not accept PLMN address"); return 0; } else if (ret == -1) { debug("wap.push.pap.compiler", 0, "PAP COMPILER: network or" "bearer missing, reverting to GSM+SMS"); return -1; } else return 1; } if (type_of_address == ADDR_IPV4) { if ((ret = uses_ipv4_address(e->u.Push_Message.bearer_required, e->u.Push_Message.bearer)) == 0) { debug("wap.push.pap.compiler", 0, "PAP COMPILER: bearer does" " not accept IPv4 address"); return 0; } else if (ret == -1) { debug("wap.push.pap.compiler", 0, "PAP COMPILER: network or" " bearer missing, reverting to GSM+CSD"); return -1; } else return 1; } if (type_of_address == ADDR_IPV6) { if ((ret = uses_ipv6_address(e->u.Push_Message.bearer_required, e->u.Push_Message.bearer)) == 0) { debug("wap.push.pap.compiler", 0, "PAP COMPILER: network or" " bearer does not accept IPv6 address"); return 0; } else if (ret == -1) { debug("wap.push.pap.compiler", 0, "PAP COMPILER: network or" " bearer missing, reverting Any+Any"); return -1; } else return 1; } return 0;}/* * Bearers accepting IP addresses. These are defined in wdp, appendix c. Note * that when ipv6 bearers begin to appear, they must be added to the following * table. Currently none are specified. */static char *ip6_bearers[] = { "Any"};#define NUMBER_OF_IP6_BEARERS sizeof(ip6_bearers)/sizeof(ip6_bearers[0])static char *ip4_bearers[] = { "Any", "CSD", "Packet Data", "GPRS", "USSD"};#define NUMBER_OF_IP4_BEARERS sizeof(ip4_bearers)/sizeof(ip4_bearers[0])/* * Bearers accepting gsm msisdn addresses are defined in wdp, appendix c. We * add any, because Kannel PPG will change this to SMS. * Return -1, when there are no bearer defined * 0, when a bearer not accepting msisdn address is found * 1, when a bearer is accepting msisdn addresesses */static int uses_gsm_msisdn_address(long bearer_required, Octstr *bearer){ if (!bearer_required) return -1; if (!bearer) return 1; return (octstr_case_compare(bearer, octstr_imm("SMS")) == 0 || octstr_case_compare(bearer, octstr_imm("GHOST/R_DATA")) == 0 || octstr_case_compare(bearer, octstr_imm("Any")) == 0);}/* * Bearers accepting ipv4 addresses are defined in wdp, appendix c. * Return -1, when there are no bearer defined * 0, when a bearer not accepting ipv4 address is found * 1, when a bearer is accepting ipv4 addresesses */static int uses_ipv4_address(long bearer_required, Octstr *bearer){ long i; if (!bearer_required) { return -1; } if (!bearer) return -1; i = 0; while (i < NUMBER_OF_IP4_BEARERS) { if (octstr_case_compare(bearer, octstr_imm(ip4_bearers[i])) == 0) { return 1; } ++i; } return 0;}/* * Bearers accepting ipv6 addresses (currently *not* accepting) are defined in * wdp, appendix c. * Return -1, when there are no bearer defined * 0, when a bearer not accepting ipv6 address is found * 1, when a bearer is accepting ipv6 addresesses */static int uses_ipv6_address(long bearer_required, Octstr *bearer){ long i; if (!bearer_required) return -1; if (!bearer) return -1; i = 0; while (i < NUMBER_OF_IP6_BEARERS) { if (octstr_case_compare(bearer, octstr_imm(ip6_bearers[i])) == 0) { return 1; } ++i; } return 0;}/* * Parse node of the syntax tree. DTD, as defined in pap, chapter 9, contains * only elements (entities are restricted to DTDs). * The caller must initialize the value of is_any to 0. * * Output: a) a newly created wap event containing attributes from pap * document node, if success; partially parsed node, if not. * b) the type of of the client address * c) is bearer and/or network any * Returns 0, when success * -1, when a non-implemented feature is requested * -2, when error */static int parse_node(xmlNodePtr node, WAPEvent **e, long *type_of_address, int *is_any){ int ret; switch (node->type) { case XML_COMMENT_NODE: /* ignore text, comments and pi nodes */ case XML_PI_NODE: case XML_TEXT_NODE: break; case XML_ELEMENT_NODE: if ((ret = parse_element(node, e, type_of_address, is_any)) < 0) { return ret; } break; default: warning(0, "PAP COMPILER: parse_node: Unknown XML node in PAP source"); return -2; } if (node->children != NULL) if ((ret = parse_node(node->children, e, type_of_address, is_any)) < 0) { return ret; } if (node->next != NULL) if ((ret = parse_node(node->next, e, type_of_address, is_any)) < 0) { return ret; } return 0;}/* * Parse elements of a PAP source. * * Output: a) a newly created wap event containing attributes from the * element, if success; containing some unparsed attributes, if not. * b) the type of the client address * c) is bearer and/or network any * Returns 0, when success * -1, when a non-implemented feature is requested * -2, when error * In addition, return */static int parse_element(xmlNodePtr node, WAPEvent **e, long *type_of_address, int *is_any){ Octstr *name; xmlAttrPtr attribute; size_t i; int ret; name = octstr_create(node->name); if (octstr_len(name) == 0) { octstr_destroy(name); debug("wap.push.pap.compiler", 0, "PAP COMPILER: element name length" " zero"); return -2; } i = 0; while (i < NUM_ELEMENTS) { if (octstr_compare(name, octstr_imm(pap_elements[i])) == 0) break; ++i; } if (i == NUM_ELEMENTS) { debug("wap.push.pap.compiler", 0, "PAP COMPILER: unknown element:"); octstr_dump(name, 0); octstr_destroy(name); return -2; } if (node->properties != NULL) { attribute = node->properties; while (attribute != NULL) { if ((ret = parse_attribute(name, attribute, e, type_of_address, is_any)) < 0) { octstr_destroy(name); return ret; } attribute = attribute->next; } } octstr_destroy(name); return 0; /* If we reach this point, our node does not have any attributes left (or it had no attributes to start with). This is *not* an error. */}/* * Parse attribute updates corresponding fields of the wap event. Check that * both attribute name and value are papwise legal. If value is enumerated, * legal values are stored in the attributes table. Otherwise, call a separate * parsing function. If an attribute value is empty, use value "erroneous". * * Output: a) a newly created wap event containing parsed attribute from pap * source, if successfull, an uncomplete wap event otherwise. * b) the type of the client address * c) is bearer and/or network set any * Returns 0, when success * -1, when a non-implemented feature is requested * -2, when error */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -