- GSM_Error error = GE_NONE;
-
- /* Standard Header: */
- memcpy(frame + llayout.UserDataHeader, "\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9\x00\x00\x00\x00\x00\x00", 24);
-
- /* Reply Path */
- if (llayout.ReplyViaSameSMSC > -1) {
- if (SMS->ReplyViaSameSMSC) frame[llayout.ReplyViaSameSMSC] |= 0x80;
- }
-
- /* User Data Header Indicator */
- if (llayout.UserDataHeader > -1) {
- if (SMS->UDH_No) frame[llayout.UserDataHeader] |= 0x40;
- }
-
- /* Status (Delivery) Report Request */
- if (llayout.Report > -1) {
- if (SMS->Report) frame[llayout.Report] |= 0x20;
- }
-
- /* Validity Period Format: mask - 0x00, 0x10, 0x08, 0x18 */
- if (llayout.Validity > -1) {
- frame[llayout.Validity] |= ((SMS->Validity.VPF & 0x03) << 3);
- }
-
- /* Reject Duplicates */
- if (llayout.RejectDuplicates > -1) {
- if (SMS->RejectDuplicates) frame[llayout.RejectDuplicates] |= 0x04;
- }
-
- /* Message Type is already set */
-
- /* Message Reference */
- /* Can we set this? */
-
- /* Protocol Identifier */
- /* FIXME: allow to change this in better way.
- currently only 0x5f == `Return Call Message' is used */
- if (llayout.PID > -1) {
- if (SMS->PID) frame[llayout.PID] = SMS->PID;
- }
-
- /* Data Coding Scheme */
- if (llayout.DataCodingScheme > -1) {
- switch (SMS->DCS.Type) {
- case SMS_GeneralDataCoding:
- if (SMS->DCS.u.General.Compressed) frame[llayout.DataCodingScheme] |= 0x20;
- if (SMS->DCS.u.General.Class) frame[llayout.DataCodingScheme] |= (0x10 | (SMS->DCS.u.General.Class - 1));
- frame[llayout.DataCodingScheme] |= ((SMS->DCS.u.General.Alphabet & 0x03) << 2);
- break;
- case SMS_MessageWaiting:
- if (SMS->DCS.u.MessageWaiting.Discard) frame[llayout.DataCodingScheme] |= 0xc0;
- else if (SMS->DCS.u.MessageWaiting.Alphabet == SMS_UCS2) frame[llayout.DataCodingScheme] |= 0xe0;
- else frame[llayout.DataCodingScheme] |= 0xd0;
- if (SMS->DCS.u.MessageWaiting.Active) frame[llayout.DataCodingScheme] |= 0x80;
- frame[llayout.DataCodingScheme] |= (SMS->DCS.u.MessageWaiting.Type & 0x03);
- break;
- default:
- dprintf("Wrong Data Coding Scheme (DCS) format\n");
- return GE_SMSWRONGFORMAT;
- }
- }
-
- /* Destination Address */
- if (llayout.RemoteNumber > -1) {
- frame[llayout.RemoteNumber] = SemiOctetPack(SMS->RemoteNumber.number, frame + llayout.RemoteNumber + 1, SMS->RemoteNumber.type);
- }
-
- /* Validity Period */
- switch (SMS->Validity.VPF) {
- case SMS_EnhancedFormat:
- break;
- case SMS_RelativeFormat:
- break;
- case SMS_AbsoluteFormat:
- break;
- default:
- break;
- }
-
- return error;
+ 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;