diff --git a/debian/patches/sipwise/tcap.patch b/debian/patches/sipwise/tcap.patch index 7977b5a65..9b4766a3d 100644 --- a/debian/patches/sipwise/tcap.patch +++ b/debian/patches/sipwise/tcap.patch @@ -12,7 +12,7 @@ +include ../../Makefile.modules --- /dev/null +++ b/modules/tcap/tcap_mod.c -@@ -0,0 +1,179 @@ +@@ -0,0 +1,294 @@ +#include +#include +#include @@ -35,6 +35,7 @@ +static int mod_init(void); +static int tcap_extract_f(sip_msg_t *msg, char *su, char *sq); +static int inap_extract_f(sip_msg_t *msg, char *su, char *sq); ++static int isup_decode_number_f(sip_msg_t *msg, char *su, char *sq); + + + @@ -43,6 +44,8 @@ + fixup_spve_str, 0, ANY_ROUTE}, + {"inap_extract", (cmd_function)inap_extract_f, 2, + fixup_spve_str, 0, ANY_ROUTE}, ++ {"isup_decode_number", (cmd_function)isup_decode_number_f, 2, ++ fixup_spve_str, 0, ANY_ROUTE}, + {0,} +}; + @@ -113,7 +116,7 @@ + return -1; +} + -+static int copy_output(sip_msg_t *msg, char *su, char *sq, struct output_buffer *out) { ++static int copy_output(sip_msg_t *msg, char *sq, char *outbuf, int outlen) { + const char *err; + pv_spec_t *avp_spec = NULL; + str *s; @@ -134,8 +137,8 @@ + + memset(&avp_val, 0, sizeof(avp_val)); + avp_val.flags = PV_VAL_STR; -+ avp_val.rs.s = out->buf; -+ avp_val.rs.len = out->used; ++ avp_val.rs.s = outbuf; ++ avp_val.rs.len = outlen; + err = "Failed to set return AVP"; + if (avp_spec->setf(msg, &avp_spec->pvp, EQ_T, &avp_val) < 0) + goto error; @@ -161,7 +164,7 @@ + if (tcap_extract(body.s, body.len, spec.s, &out)) + goto error; + -+ if (copy_output(msg, su, sq, &out)) ++ if (copy_output(msg, sq, out.buf, out.used)) + return -1; + + return 1; @@ -184,10 +187,122 @@ + if (inap_extract(body.s, body.len, spec.s, &out)) + goto error; + -+ if (copy_output(msg, su, sq, &out)) ++ if (copy_output(msg, sq, out.buf, out.used)) ++ return -1; ++ ++ return 1; ++error: ++ LM_ERR("inap_extract_f() error: %s\n", err); ++ return -1; ++} ++ ++ ++ ++static inline char phone_digit(unsigned char d) { ++ switch (d) { ++ case 0: ++ case 1: ++ case 2: ++ case 3: ++ case 4: ++ case 5: ++ case 6: ++ case 7: ++ case 8: ++ case 9: ++ return '0' + d; ++ case 11: ++ return '*'; ++ case 12: ++ return '#'; ++ case 15: ++ return 'F'; ++ default: ++ return '?'; ++ } ++} ++ ++ ++static int isup_decode_number_f(sip_msg_t *msg, char *su, char *sq) { ++ const char *err; ++ char *pi; ++ str inp; ++ unsigned char raw[32], *pr; ++ int rawlen, odd; ++ char num[64]; ++ ++ err = "Error fixing up first parameter"; ++ if (fixup_get_svalue(msg, (gparam_p) su, &inp)) ++ goto error; ++ err = "Invalid encoded number"; ++ if (inp.len < 5) /* min: 2 octets */ ++ goto error; ++ err = "Input too long"; ++ if (inp.len > 92) /* 31 * 2 + 30 */ ++ goto error; ++ ++ /* input is a hex encoded octet string, separated by spaces */ ++ ++ pr = raw; ++ rawlen = 0; ++ pi = inp.s; ++ while (1) { ++ if (!*pi) ++ break; ++ ++ err = "Invalid hex encoded string"; ++ if (*pi >= '0' && *pi <= '9') ++ *pr = (*pi - '0') << 4; ++ else if (*pi >= 'A' && *pi <= 'F') ++ *pr = (*pi - 'A' + 10) << 4; ++ else if (*pi >= 'a' && *pi <= 'f') ++ *pr = (*pi - 'a' + 10) << 4; ++ else ++ goto error; ++ ++ pi++; ++ ++ if (*pi >= '0' && *pi <= '9') ++ *pr |= (*pi - '0'); ++ else if (*pi >= 'A' && *pi <= 'F') ++ *pr |= (*pi - 'A' + 10); ++ else if (*pi >= 'a' && *pi <= 'f') ++ *pr |= (*pi - 'a' + 10); ++ else ++ goto error; ++ ++ rawlen++; ++ pr++; ++ ++ pi++; ++ if (!*pi) ++ break; ++ if (*pi != ' ') ++ goto error; ++ } ++ ++ odd = raw[0] & 0x80; ++ err = "Invalid encoding"; ++ if (odd && rawlen == 2) ++ goto error; ++ ++ pi = num; ++ pr = raw + 2; ++ rawlen -= 2; ++ while (rawlen) { ++ *(pi++) = phone_digit(*pr & 0xf); ++ *(pi++) = phone_digit(*pr >> 4); ++ rawlen--; ++ } ++ ++ if (odd) ++ pi--; ++ ++ if (copy_output(msg, sq, num, pi - num)) + return -1; + + return 1; ++ +error: + LM_ERR("inap_extract_f() error: %s\n", err); + return -1;