+ int off,w,i,tmp=0;
+ unsigned char output[161];
+ bool UDHOK;
+
+ /* off - length of the user data header */
+ off = 0;
+
+ SMS->UDHType = GSM_NoUDH;
+
+ if (ETSI->firstbyte & 64) { /* UDH header available */
+
+ off = (ETSI->MessageText[0] + 1); /* Length of UDH header */
+
+ /* Copy UDH header into SMS->UDH */
+ for (i = 0; i < off; i++) SMS->UDH[i] = ETSI->MessageText[i];
+
+#ifdef DEBUG
+ fprintf(stdout, " UDH header available (length %i",off);
+#endif
+
+ SMS->UDHType = GSM_UnknownUDH;
+
+ i=-1;
+ while (true) {
+ i++;
+ if (UDHHeaders[i].UDHType==GSM_NoUDH) break;
+ tmp=UDHHeaders[i].Length;
+ if (tmp==SMS->UDH[0]) { //if length is the same
+
+ if (tmp==0x05) tmp=tmp-2;/*two last bytes can be different for such UDH*/
+ if (tmp==0x0b) tmp=tmp-3;/*three last bytes can be different for such UDH*/
+
+ UDHOK=true;
+ for (w=0;w<tmp;w++) {
+ if (UDHHeaders[i].Text[w]!=SMS->UDH[w+1]) {
+ UDHOK=false;
+ break;
+ }
+ }
+ if (UDHOK) {
+ SMS->UDHType=UDHHeaders[i].UDHType;
+ break;
+ }
+ }
+ }
+
+#ifdef DEBUG
+ switch (SMS->UDHType) {
+ case GSM_ConcatenatedMessages:
+ fprintf(stdout,_(", concatenated (linked) message %d/%d"),SMS->UDH[5],SMS->UDH[4]);break;
+ case GSM_DisableVoice:
+ fprintf(stdout,_(", disables voice indicator"));break;
+ case GSM_EnableVoice:
+ fprintf(stdout,_(", enables voice indicator"));break;
+ case GSM_DisableFax:
+ fprintf(stdout,_(", disables fax indicator"));break;
+ case GSM_EnableFax:
+ fprintf(stdout,_(", enables fax indicator"));break;
+ case GSM_DisableEmail:
+ fprintf(stdout,_(", disables email indicator"));break;
+ case GSM_EnableEmail:
+ fprintf(stdout,_(", enables email indicator"));break;
+ case GSM_VoidSMS:
+ fprintf(stdout,_(", void SMS"));break;
+ case GSM_WAPBookmarkUDH:
+ fprintf(stdout,_(", WAP Bookmark"));break;
+ case GSM_WAPBookmarkUDHLong:
+ fprintf(stdout,_(", WAP Bookmark, part %i/%i"),SMS->UDH[11],SMS->UDH[10]);break;
+ case GSM_WAPSettingsUDH:
+ fprintf(stdout,_(", WAP Settings, part %i/%i"),SMS->UDH[11],SMS->UDH[10]);break;
+ case GSM_RingtoneUDH:
+ fprintf(stdout,_(", ringtone"));break;
+ case GSM_OpLogo:
+ fprintf(stdout,_(", GSM Operator Logo"));break;
+ case GSM_CallerIDLogo:
+ fprintf(stdout,_(", Caller Logo"));break;
+ case GSM_ProfileUDH:
+ fprintf(stdout,_(", Profile SMS, part %i/%i"),SMS->UDH[11],SMS->UDH[10]);break;
+ case GSM_CalendarNoteUDH:
+ fprintf(stdout,_(", Calendar note SMS, part %i/%i"),SMS->UDH[11],SMS->UDH[10]);break;
+ case GSM_CalendarNoteUDH2:
+ fprintf(stdout,_(", Calendar note SMS, part %i/%i"),SMS->UDH[11],SMS->UDH[10]);break;
+ case GSM_PhonebookUDH:
+ fprintf(stdout,_(", Phonebook Entry, part %i/%i"),SMS->UDH[11],SMS->UDH[10]);break;
+ default:
+ fprintf(stdout,_(", UNKNOWN"));break;
+ }
+
+ fprintf(stdout, ")\n");
+
+ hexdump(off,SMS->UDH);
+#endif
+ }
+
+ SMS->Coding = GSM_Coding_Default;
+
+ /* GSM 03.40 section 9.2.3.10 (TP-Data-Coding-Scheme) and GSM 03.38 section 4 */
+ if ((ETSI->TPDCS & 0xf4) == 0xf4) SMS->Coding=GSM_Coding_8bit;
+ if ((ETSI->TPDCS & 0x08) == 0x08) SMS->Coding=GSM_Coding_Unicode;
+
+ switch (SMS->Coding) {
+ case GSM_Coding_Default:
+ w=(7-off)%7;
+ if (w<0) w=(14-off)%14;
+
+ SMS->Length=ETSI->TPUDL - (off*8 + w) / 7;
+
+ tmp=GSM_UnpackEightBitsToSeven(w,ETSI->TPUDL-off, SMS->Length, ETSI->MessageText+off, output);
+
+#ifdef DEBUG
+ fprintf(stdout, " 7 bit SMS, body is (length %i): ",SMS->Length);
+#endif /* DEBUG */
+
+ DecodeDefault (SMS->MessageText, output, SMS->Length);
+
+#ifdef DEBUG
+ fprintf(stdout, "%s\n",SMS->MessageText);
+#endif
+
+ break;
+ case GSM_Coding_8bit:
+ SMS->Length=ETSI->TPUDL - off;
+
+ memcpy(SMS->MessageText,ETSI->MessageText+off,SMS->Length);
+
+#ifdef DEBUG
+ fprintf(stdout, " 8 bit SMS, body is (length %i)\n",SMS->Length);
+ hexdump(SMS->Length,SMS->MessageText);
+#endif /* DEBUG */
+
+ break;
+ case GSM_Coding_Unicode:
+ SMS->Length=(ETSI->TPUDL - off) / 2;
+
+#ifdef DEBUG
+ fprintf(stdout, " 7 bit SMS, body is (length %i), Unicode coding: ",SMS->Length);
+ for (i=0; i<SMS->Length;i++) {
+ fprintf(stdout, "[%02x %02x]", ETSI->MessageText[off+i*2] , ETSI->MessageText[off+i*2+1]);
+ }
+ fprintf(stdout, "\n");
+#endif /* DEBUG */
+
+ /* here we decode "special" chars */
+ for (i=0; i<SMS->Length;i++) {
+ if (ETSI->MessageText[off+i*2] ==0x00 &&
+ ETSI->MessageText[off+i*2+1]==0x01)
+ ETSI->MessageText[off+i*2+1]='~'; //enables/disables blinking
+ if (ETSI->MessageText[off+i*2] ==0x00 &&
+ ETSI->MessageText[off+i*2+1]==0x00)
+ ETSI->MessageText[off+i*2+1]='`'; //hides rest ot contents
+ }
+
+ DecodeUnicode (SMS->MessageText, ETSI->MessageText+off, SMS->Length);
+
+ break;
+ }
+
+ return GE_NONE;