📄 pdu.c
字号:
sprintf(tmp, "%02X", udh_length); memcpy(udh, tmp, 2); } else *udh = 0; return (id == 0x00)? 1 : 2; } else { // Something else data. Get the length and skip. if (++idx >= octets) return -1; if ((i = octet2bin_check(udh +idx *2 +idx)) < 0) return -1; idx += i +1; } } return 0;}int get_concatenation(char *udh, int *message_id, int *parts, int *part){ char *tmp; int result = -1; if ((tmp = strdup(udh))) { result = get_remove_concatenation(tmp, message_id, parts, part); free(tmp); } return result;}int remove_concatenation(char *udh){ int message_id; int parts; int part; return get_remove_concatenation(udh, &message_id, &parts, &part);}// Returns a length of udh (including UDHL), -1 if error.// pdu is 0-terminated ascii(hex) pdu string with// or without spaces.int explain_udh(char *udh_type, char *pdu){ int udh_length; int idx; char *Src_Pointer; char *p; int i; char tmp[512]; char buffer[1024]; *udh_type = 0; if (strlen(pdu) >= sizeof(buffer)) return -1; strcpy(buffer, pdu); while ((p = strchr(buffer, ' '))) strcpy(p, p +1); if ((udh_length = octet2bin_check(buffer)) < 0) return -1; udh_length++; if (udh_length *2 > strlen(buffer)) return -1; sprintf(udh_type, "Length=%i", udh_length); idx = 1; while (idx < udh_length) { Src_Pointer = buffer +idx *2; p = NULL; i = octet2bin_check(Src_Pointer); switch (i) { case -1: //sprintf(strchr(udh_type, 0), ", ERROR"); return -1; // 3GPP TS 23.040 version 6.8.1 Release 6 - ETSI TS 123 040 V6.8.1 (2006-10) case 0x00: p = "Concatenated short messages, 8-bit reference number"; break; case 0x01: p = "Special SMS Message Indication"; break; case 0x02: p = "Reserved"; break; //case 0x03: p = "Value not used to avoid misinterpretation as <LF> character"; break; case 0x04: p = "Application port addressing scheme, 8 bit address"; break; case 0x05: p = "Application port addressing scheme, 16 bit address"; break; case 0x06: p = "SMSC Control Parameters"; break; case 0x07: p = "UDH Source Indicator"; break; case 0x08: p = "Concatenated short message, 16-bit reference number"; break; case 0x09: p = "Wireless Control Message Protocol"; break; case 0x0A: p = "Text Formatting"; break; case 0x0B: p = "Predefined Sound"; break; case 0x0C: p = "User Defined Sound (iMelody max 128 bytes)"; break; case 0x0D: p = "Predefined Animation"; break; case 0x0E: p = "Large Animation (16*16 times 4 = 32*4 =128 bytes)"; break; case 0x0F: p = "Small Animation (8*8 times 4 = 8*4 =32 bytes)"; break; case 0x10: p = "Large Picture (32*32 = 128 bytes)"; break; case 0x11: p = "Small Picture (16*16 = 32 bytes)"; break; case 0x12: p = "Variable Picture"; break; case 0x13: p = "User prompt indicator"; break; case 0x14: p = "Extended Object"; break; case 0x15: p = "Reused Extended Object"; break; case 0x16: p = "Compression Control"; break; case 0x17: p = "Object Distribution Indicator"; break; case 0x18: p = "Standard WVG object"; break; case 0x19: p = "Character Size WVG object"; break; case 0x1A: p = "Extended Object Data Request Command"; break; case 0x20: p = "RFC 822 E-Mail Header"; break; case 0x21: p = "Hyperlink format element"; break; case 0x22: p = "Reply Address Element"; break; case 0x23: p = "Enhanced Voice Mail Information"; break; } if (!p) { if (i >= 0x1B && i <= 0x1F) p = "Reserved for future EMS features"; else if (i >= 0x24 && i <= 0x6F) p = "Reserved for future use"; else if (i >= 0x70 && i <= 0x7F) p = "(U)SIM Toolkit Security Headers"; else if (i >= 0x80 && i <= 0x9F) p = "SME to SME specific use"; else if (i >= 0xA0 && i <= 0xBF) p = "Reserved for future use"; else if (i >= 0xC0 && i <= 0xDF) p = "SC specific use"; else if (i >= 0xE0 && i <= 0xFF) p = "Reserved for future use"; } if (!p) p = "unknown"; sprintf(tmp, ", [%.2s]%s", Src_Pointer, p); if (strlen(udh_type) + strlen(tmp) >= SIZE_UDH_TYPE) return -1; sprintf(strchr(udh_type, 0), "%s", tmp); // Next octet is length of data: if ((i = octet2bin_check(Src_Pointer +2)) < 0) return -1; if (i *2 > strlen(Src_Pointer +4)) return -1; idx += i +2; if (idx > udh_length) return -1; // Incorrect UDL or length of Information Element. } return udh_length;}/* converts a PDU-String to text, text might contain zero values! *//* the first octet is the length *//* return the length of text, -1 if there is a PDU error, -2 if PDU is too short *//* with_udh must be set already if the message has an UDH *//* this function does not detect the existance of UDH automatically. */int pdu2text(char *pdu, char *text, int *text_length, int *expected_length, int with_udh, char *udh, char *udh_type, int *errorpos) { int bitposition; int byteposition; int byteoffset; int charcounter; int bitcounter; int septets; int octets; int udhsize; int octetcounter; int skip_characters = 0; char c; char binary; int i; int result;#ifdef DEBUGMSG printf("!! pdu2text(pdu=%s,...)\n",pdu);#endif if (udh) *udh = 0; if (udh_type) *udh_type = 0; if ((septets = octet2bin_check(pdu)) < 0) { if (errorpos) *errorpos = -1 * septets -3; return (septets >= -2)? -2: -1; } if (with_udh) { // copy the data header to udh and convert to hex dump // There was at least one octet and next will give an error if there is no more data: if ((udhsize = octet2bin_check(pdu +2)) < 0) { if (errorpos) *errorpos = -1 * udhsize -3 +2; return (udhsize >= -2)? -2: -1; } i = 0; result = -1; for (octetcounter=0; octetcounter<udhsize+1; octetcounter++) { if (octetcounter *3 +3 >= SIZE_UDH_DATA) { i = octetcounter *2 +2; result = -2; break; } udh[octetcounter*3]=pdu[(octetcounter<<1)+2]; if (!isXdigit(udh[octetcounter *3])) { i = octetcounter *2 +2; if (!udh[octetcounter *3]) result = -2; break; } udh[octetcounter*3+1]=pdu[(octetcounter<<1)+3]; if (!isXdigit(udh[octetcounter *3 +1])) { i = octetcounter *2 +3; if (!udh[octetcounter *3 +1]) result = -2; break; } udh[octetcounter *3 +2] = ' '; udh[octetcounter *3 +3] = 0; } if (i) { if (errorpos) *errorpos = i; return result; } if (udh_type) if (explain_udh(udh_type, pdu +2) < 0) if (strlen(udh_type) +7 < SIZE_UDH_TYPE) sprintf(strchr(udh_type, 0), "%sERROR", (*udh_type)? ", " : ""); // Calculate how many text charcters include the UDH. // After the UDH there may follow filling bits to reach a 7bit boundary. skip_characters=(((udhsize+1)*8)+6)/7;#ifdef DEBUGMSG printf("!! septets=%i\n",septets); printf("!! udhsize=%i\n",udhsize); printf("!! skip_characters=%i\n",skip_characters);#endif } if (expected_length) *expected_length = septets -skip_characters; // Convert from 8-Bit to 7-Bit encapsulated in 8 bit // skipping storing of some characters used by UDH. // 3.1beta7: Simplified handling to allow partial decodings to be shown. octets = (septets *7 +7) /8; bitposition = 0; octetcounter = 0; for (charcounter = 0; charcounter < septets; charcounter++) { c = 0; for (bitcounter = 0; bitcounter < 7; bitcounter++) { byteposition = bitposition /8; byteoffset = bitposition %8; while (byteposition >= octetcounter && octetcounter < octets) { if ((i = octet2bin_check(pdu +(octetcounter << 1) +2)) < 0) { if (errorpos) { *errorpos = octetcounter *2 +2; if (i == -2 || i == -4) (*errorpos)++; } if (text_length) *text_length = charcounter -skip_characters; return (i >= -2)? -2: -1; } binary = i; octetcounter++; } if (binary & (1 << byteoffset)) c = c | 128; bitposition++; c = (c >> 1) & 127; // The shift fills with 1, but 0 is wanted. } if (charcounter >= skip_characters) text[charcounter -skip_characters] = c; } if (text_length) *text_length = charcounter -skip_characters; if (charcounter -skip_characters >= 0) text[charcounter -skip_characters] = 0; return charcounter -skip_characters;}int pdu2text0(char *pdu, char *text){ return pdu2text(pdu, text, 0, 0, 0, 0, 0, 0);}// Converts a PDU string to binary. Return -1 if there is a PDU error, -2 if PDU is too short.// Version > 3.0.9, > 3.1beta6 handles also udh.int pdu2binary(char* pdu, char* binary, int *data_length, int *expected_length, int with_udh, char *udh, char *udh_type, int *errorpos){ int octets; int octetcounter; int i; int udhsize = 0; int skip_octets = 0; int result; *udh = 0; *udh_type = 0; if ((octets = octet2bin_check(pdu)) < 0) { *errorpos = -1 * octets -3; return (octets >= -2)? -2: -1; } if (with_udh) { // copy the data header to udh and convert to hex dump // There was at least one octet and next will give an error if there is no more data: if ((udhsize = octet2bin_check(pdu +2)) < 0) { *errorpos = -1 * udhsize -3 +2; return (udhsize >= -2)? -2: -1; } i = 0; result = -1; for (octetcounter = 0; octetcounter < udhsize +1; octetcounter++) { if (octetcounter *3 +3 >= SIZE_UDH_DATA) { i = octetcounter *2 +2; result = -2; break; } udh[octetcounter *3] = pdu[(octetcounter << 1) +2]; if (!isXdigit(udh[octetcounter *3])) { i = octetcounter *2 +2; if (!udh[octetcounter *3]) result = -2; break; } udh[octetcounter *3 +1] = pdu[(octetcounter << 1) +3]; if (!isXdigit(udh[octetcounter *3 +1])) { i = octetcounter *2 +3; if (!udh[octetcounter *3 +1]) result = -2; break; } udh[octetcounter *3 +2] = ' '; udh[octetcounter *3 +3] = 0; } if (i) { *errorpos = i; return result; } if (udh_type) if (explain_udh(udh_type, pdu +2) < 0) if (strlen(udh_type) +7 < SIZE_UDH_TYPE) sprintf(strchr(udh_type, 0), "%sERROR", (*udh_type)? ", " : ""); skip_octets = udhsize +1; } *expected_length = octets -skip_octets; for (octetcounter = 0; octetcounter < octets -skip_octets; octetcounter++) { if ((i = octet2bin_check(pdu +(octetcounter << 1) +2 +(skip_octets *2))) < 0) { *errorpos = octetcounter *2 +2 +(skip_octets *2); if (i == -2 || i == -4) (*errorpos)++; *data_length = octetcounter; return (i >= -2)? -2: -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -