📄 wap_push_pap_compiler.c
字号:
}/* * Stores values of enumeration fields of a pap control message to wap event e. */static int set_attribute_value(Octstr *element_name, Octstr *attr_value, Octstr *attr_name, WAPEvent **e){ int ret; ret = -2; if (octstr_compare(element_name, octstr_imm("push-message")) == 0) { if (octstr_compare(attr_name, octstr_imm("progress-notes-requested")) == 0) (**e).u.Push_Message.progress_notes_requested = (ret = parse_requirement(attr_value)) >= 0 ? ret : 0; } else if (octstr_compare(element_name, octstr_imm("quality-of-service")) == 0) { if (octstr_compare(attr_name, octstr_imm("priority")) == 0) (**e).u.Push_Message.priority = (ret = parse_priority(attr_value)) >= 0 ? ret : 0; else if (octstr_compare(attr_name, octstr_imm("delivery-method")) == 0) (**e).u.Push_Message.delivery_method = (ret = parse_delivery_method(attr_value)) >= 0 ? ret : 0; else if (octstr_compare(attr_name, octstr_imm("network-required")) == 0) (**e).u.Push_Message.network_required = (ret = parse_requirement(attr_value)) >= 0 ? ret : 0; else if (octstr_compare(attr_name, octstr_imm("bearer-required")) == 0) (**e).u.Push_Message.bearer_required = (ret = parse_requirement(attr_value)) >= 0 ? ret : 0; } return ret;}/* * We must recognize status class and treat unrecognized codes as a x000 code, * as required by pap, 9.13, p 27. */static int parse_code(Octstr *attr_value){ long attr_as_number, len; size_t i; Octstr *ros; for (i = 0; i < NUM_CODES; i++) { ros = octstr_format("%d", pap_codes[i]); if (octstr_compare(attr_value, ros) == 0) { octstr_destroy(ros); return pap_codes[i]; } octstr_destroy(ros); } warning(0, "PAP COMPILER: parse_code: no such return code, reversing to" " x000 code"); len = octstr_parse_long(&attr_as_number, attr_value, 0, 10); if (attr_as_number >= PAP_OK && attr_as_number < PAP_BAD_REQUEST) { attr_as_number = PAP_OK; } else if (attr_as_number >= PAP_BAD_REQUEST && attr_as_number < PAP_INTERNAL_SERVER_ERROR) { attr_as_number = PAP_BAD_REQUEST; } else if (attr_as_number >= PAP_INTERNAL_SERVER_ERROR && attr_as_number < PAP_SERVICE_FAILURE) { attr_as_number = PAP_INTERNAL_SERVER_ERROR; } else if (attr_as_number >= PAP_SERVICE_FAILURE && attr_as_number < PAP_CLIENT_ABORTED) { attr_as_number = PAP_SERVICE_FAILURE; } else { attr_as_number = PAP_CLIENT_ABORTED; } return attr_as_number;}static Octstr *parse_bearer(Octstr *attr_value){ size_t i; Octstr *ros; for (i = 0; i < NUM_BEARER_TYPES; i++) { if (octstr_case_compare(attr_value, ros = octstr_imm(pap_bearer_types[i])) == 0) return ros; } warning(0, "no such bearer"); return NULL;}static Octstr *parse_network(Octstr *attr_value){ size_t i; Octstr *ros; for (i = 0; i < NUM_NETWORK_TYPES; i++) { if (octstr_case_compare(attr_value, ros = octstr_imm(pap_network_types[i])) == 0) { return ros; } } warning(0, "no such network"); return NULL;}/* * Used for attributes accepting logical values. */static int parse_requirement(Octstr *attr_value){ long attr_as_number; attr_as_number = -2; if (octstr_case_compare(attr_value, octstr_imm("false")) == 0) attr_as_number = PAP_FALSE; else if (octstr_case_compare(attr_value, octstr_imm("true")) == 0) attr_as_number = PAP_TRUE; else warning(0, "in a requirement, value not a truth value"); return attr_as_number;}/* * Priority is defined in pap, chapter 9.2.2. */static int parse_priority(Octstr *attr_value){ long attr_as_number; attr_as_number = -2; if (octstr_case_compare(attr_value, octstr_imm("high")) == 0) attr_as_number = PAP_HIGH; else if (octstr_case_compare(attr_value, octstr_imm("medium")) == 0) attr_as_number = PAP_MEDIUM; else if (octstr_case_compare(attr_value, octstr_imm("low")) == 0) attr_as_number = PAP_LOW; else warning(0, "illegal priority"); return attr_as_number;}/* * Delivery-method is defined in pap, chapter 9.2.2. */static int parse_delivery_method(Octstr *attr_value){ long attr_as_number; attr_as_number = -2; if (octstr_case_compare(attr_value, octstr_imm("confirmed")) == 0) attr_as_number = PAP_CONFIRMED; else if (octstr_case_compare(attr_value, octstr_imm("preferconfirmed")) == 0) attr_as_number = PAP_PREFERCONFIRMED; else if (octstr_case_compare(attr_value, octstr_imm("unconfirmed")) == 0) attr_as_number = PAP_UNCONFIRMED; else if (octstr_case_compare(attr_value, octstr_imm("notspecified")) == 0) attr_as_number = PAP_NOT_SPECIFIED; else warning(0, "illegal delivery method"); return attr_as_number;}/* * PAP states are defined in ppg, chapter 6. */static int parse_state(Octstr *attr_value){ long attr_as_number; attr_as_number = -2; if (octstr_case_compare(attr_value, octstr_imm("undeliverable")) == 0) attr_as_number = PAP_UNDELIVERABLE; else if (octstr_case_compare(attr_value, octstr_imm("pending")) == 0) attr_as_number = PAP_PENDING; else if (octstr_case_compare(attr_value, octstr_imm("expired")) == 0) attr_as_number = PAP_EXPIRED; else if (octstr_case_compare(attr_value, octstr_imm("delivered")) == 0) attr_as_number = PAP_DELIVERED; else if (octstr_case_compare(attr_value, octstr_imm("aborted")) == 0) attr_as_number = PAP_ABORTED; else if (octstr_case_compare(attr_value, octstr_imm("timeout")) == 0) attr_as_number = PAP_TIMEOUT; else if (octstr_case_compare(attr_value, octstr_imm("cancelled")) == 0) attr_as_number = PAP_CANCELLED; else warning(0, "illegal ppg state"); return attr_as_number;}/* * Check legality of pap client address attribute and transform it to the * client address usable in Kannel wap address tuple data type. The grammar * for client address is specified in ppg, chapter 7.1. * * Output: the address type of the client address * Returns: 0, when success * -1, a non-implemented pap feature requested by pi * -2, address parsing error */int parse_address(Octstr **address, long *type_of_address){ long pos; Octstr *copy; pos = octstr_len(*address) - 1;/* * Delete first separator, if there is one. This will help our parsing later. */ if (octstr_get_char(*address, 0) == '/') octstr_delete(*address, 0, 1);/* * WAP-209, chapter 8 states that addresses with telephone numbers * should not have a ppg specifier. WAP-151 grammar, however, makes it * mandatory. Best way to solve this contradiction seems to be regarding * ppg specifier optional - MMSC is very important type of pi. */ if (octstr_search_char(*address, '@', 0) >= 0) { if ((pos = parse_ppg_specifier(address, pos)) < 0) return -2; } if ((pos = parse_wappush_client_address(address, pos, type_of_address)) == -2) { warning(0, "illegal client address"); return -2; } else if (pos == -1) { warning(0, "unimplemented feature"); return -1; } info(0, "client address was <%s>, accepted", octstr_get_cstr(copy = octstr_duplicate(*address))); octstr_destroy(copy); return pos;}/* * Output: the type of the client address */static long parse_wappush_client_address(Octstr **address, long pos, long *type_of_address){ if ((pos = parse_client_specifier(address, pos, type_of_address)) < 0) { return pos; } pos = parse_constant("WAPPUSH", address, pos); return pos;}/* * We are not interested of ppg specifier, but we must check its format, * if we find it - it is optional. */static long parse_ppg_specifier(Octstr **address, long pos){ if (pos >= 0) { pos = parse_dom_fragment(address, pos); } while (octstr_get_char(*address, pos) != '@' && pos >= 0) { if (octstr_get_char(*address, pos) == '.') { octstr_delete(*address, pos, 1); --pos; } else { return -2; } pos = parse_dom_fragment(address, pos); } pos = drop_character(address, pos); if (octstr_get_char(*address, pos) == '/' && pos >= 0) { octstr_delete(*address, pos, 1); if (pos > 0) --pos; } if (pos < 0) { return -2; } return pos;}/* * Output: the type of a client address. * Return a negative value, when error, positive (the position of the parsing * cursor) otherwise. */static long parse_client_specifier(Octstr **address, long pos, long *type_of_address){ Octstr *type_value; type_value = octstr_create(""); if ((pos = parse_type(address, &type_value, pos)) < 0) { goto parse_error; } pos = drop_character(address, pos); if ((pos = parse_constant("/TYPE", address, pos)) < 0) { debug("wap.push.pap.compiler", 0, "PAP COMPILER: constant TYPE" " missing from the client address"); goto parse_error; } if (octstr_case_compare(type_value, octstr_imm("USER")) == 0) { *type_of_address = ADDR_USER; goto not_implemented; } if ((pos = parse_ext_qualifiers(address, pos, type_value)) < 0) { goto parse_error; } if (octstr_case_compare(type_value, octstr_imm("PLMN")) == 0) { *type_of_address = ADDR_PLMN; pos = parse_global_phone_number(address, pos); } else if (octstr_case_compare(type_value, octstr_imm("IPv4")) == 0) { *type_of_address = ADDR_IPV4; pos = parse_ipv4(address, pos); } else if (octstr_case_compare(type_value, octstr_imm("IPv6")) == 0) { *type_of_address = ADDR_IPV6; pos = parse_ipv6(address, pos); } else if (wina_bearer_identifier(type_value)) { *type_of_address = ADDR_WINA; pos = parse_escaped_value(address, pos); } else { debug("wap.push.pap.compiler", 0, "PAP COMPILER: wrong address type" " in the client address"); goto parse_error; } octstr_destroy(type_value); return pos;not_implemented: octstr_destroy(type_value); return -1;parse_error: octstr_destroy(type_value); return -2;}/* * XXX We have a kludge here. WAP-249-PPGService-20010713-a defines in * section 6.1 the constant strings "WAPPUSH" and "TYPE" in upper-case. * But in the examples of section 6.2 they use lower-case too. Some PI * vendors (ie. Jatayuu's MMSC) have implemented lower-case in their PAP * documents. So we'll support this too for sake of operatibility -- st. */static long parse_constant(const char *field_name, Octstr **address, long pos){ size_t i, size; Octstr *nameos; nameos = octstr_format("%s", field_name); size = octstr_len(nameos); i = 0; /* convert both to lower case, see above note */ octstr_convert_range(nameos, 0, octstr_len(nameos), tolower); octstr_convert_range(*address, 0, octstr_len(*address), tolower); while (octstr_get_char(*address, pos - i) == octstr_get_char(nameos, size-1 - i) && i < size) { ++i; } while ((octstr_len(*address) > 0) && octstr_get_char(*address, pos) != octstr_get_char(nameos, 0) && pos >= 0) { pos = drop_character(address, pos); } pos = drop_character(address, pos); if (pos < 0 || i != size) { debug("wap.push.pap.compiler", 0, "parse_constant: unparsable" " constant %s", field_name); octstr_destroy(nameos); return -2; } octstr_destroy(nameos); return pos;}static long parse_dom_fragment(Octstr **address, long pos){ unsigned char c; if (pos >= 0) { if (isalnum(octstr_get_char(*address, pos))) { pos = drop_character(address, pos); } else return -2; } while ((c = octstr_get_char(*address, pos)) != '@' && octstr_get_char(*address, pos) != '.' && pos >= 0) { if (isalnum(c) || c == '-') {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -