wrong character in the GSM 03.38 table (ç for Ç)
[gammu.git] / helper / message-display.c
blobafb3a3d1af15b6689d63e8c4a595918b06b75d2e
1 #define _GNU_SOURCE /* For strcasestr */
2 #include <string.h>
3 #include <stdarg.h>
4 #include <signal.h>
5 #include <stdlib.h>
6 #include <ctype.h>
7 #ifdef WIN32
8 # include <io.h>
9 #else
10 # include <unistd.h>
11 #endif
13 #include "../helper/locales.h"
15 #include "message-display.h"
16 #include "memory-display.h"
17 #include "formats.h"
19 #include <gammu.h>
21 /**
22 * Prints location information about message.
24 void PrintSMSLocation(const GSM_SMSMessage *sms, const GSM_SMSFolders *folders)
26 printf(_("Location %i, folder \"%s\""),
27 sms->Location,
28 DecodeUnicodeConsole(folders->Folder[sms->Folder - 1].Name)
31 switch (sms->Memory) {
32 case MEM_SM:
33 printf(", %s", _("SIM memory"));
34 break;
35 case MEM_ME:
36 printf(", %s", _("phone memory"));
37 break;
38 case MEM_MT:
39 printf(", %s", _("phone or SIM memory"));
40 break;
41 default:
42 break;
45 if (sms->InboxFolder) {
46 printf(", %s", _("Inbox folder"));
49 printf("\n");
52 /**
53 * Searches for memory entry in NULL terminated entries list.
55 const GSM_MemoryEntry *SearchPhoneNumber(const unsigned char *number, const GSM_MemoryEntry **List, int *pos)
57 int i;
58 for (i = 0; List[i] != NULL; i++) {
59 for (*pos = 0; *pos < List[i]->EntriesNum; (*pos)++) {
60 switch (List[i]->Entries[*pos].EntryType) {
61 case PBK_Number_General:
62 case PBK_Number_Mobile:
63 case PBK_Number_Fax:
64 case PBK_Number_Pager:
65 case PBK_Number_Other:
66 if (mywstrncmp(List[i]->Entries[*pos].Text,number,-1)) {
67 return List[i];
69 default:
70 break;
74 return NULL;
77 /**
78 * Prints single phone number optionally showing name of contact from backup data.
80 #ifdef GSM_ENABLE_BACKUP
81 void PrintPhoneNumber(const unsigned char *number, const GSM_Backup *Info)
82 #else
83 void PrintPhoneNumber(const unsigned char *number, const void *Info)
84 #endif
86 #ifdef GSM_ENABLE_BACKUP
87 const GSM_MemoryEntry *pbk;
88 int pos;
89 #endif
91 printf("\"%s\"", DecodeUnicodeConsole(number));
93 if (Info == NULL) return;
95 #ifdef GSM_ENABLE_BACKUP
96 /* First try phone phonebook */
97 pbk = SearchPhoneNumber(number, (const GSM_MemoryEntry **)Info->PhonePhonebook, &pos);
98 if (pbk == NULL) {
99 /* Fall back to SIM */
100 pbk = SearchPhoneNumber(number, (const GSM_MemoryEntry **)Info->SIMPhonebook, &pos);
103 /* Nothing found */
104 if (pbk == NULL) return;
106 /* Print name */
107 printf("%s", DecodeUnicodeConsole(GSM_PhonebookGetEntryName(pbk)));
109 /* Print phone type */
110 switch (pbk->Entries[pos].EntryType) {
111 case PBK_Number_Mobile:
112 printf(" (%s)", _("mobile"));
113 break;
114 case PBK_Number_Fax:
115 printf(" (%s)", _("fax"));
116 break;
117 case PBK_Number_Pager:
118 printf(" (%s)", _("pager"));
119 break;
120 case PBK_Number_General:
121 printf(" (%s)", _("general"));
122 break;
123 default:
124 break;
126 switch (pbk->Entries[pos].Location) {
127 case PBK_Location_Home:
128 printf(" [%s]", _("home"));
129 break;
130 case PBK_Location_Work:
131 printf(" [%s]", _("work"));
132 break;
133 case PBK_Location_Unknown:
134 break;
136 #endif
139 void DisplayMessageHex(GSM_SMSMessage *sms) {
140 size_t len;
141 char *hexbuf;
143 len = strlen(sms->Text);
144 hexbuf = malloc(len * 2 + 1);
145 printf("%s\n", _("8 bit SMS, cannot be displayed here"));
146 if (hexbuf == NULL) {
147 return;
149 EncodeHexBin(hexbuf, sms->Text, len);
150 printf("(hex: %s)\n", hexbuf);
151 free(hexbuf);
154 #ifdef GSM_ENABLE_BACKUP
155 void DisplaySingleSMSInfo(GSM_SMSMessage *sms, gboolean displaytext, gboolean displayudh, const GSM_Backup *Info)
156 #else
157 void DisplaySingleSMSInfo(GSM_SMSMessage *sms, gboolean displaytext, gboolean displayudh, const void *Info)
158 #endif
160 GSM_SiemensOTASMSInfo SiemensOTA;
161 int i;
163 switch (sms->PDU) {
164 case SMS_Status_Report:
165 printf("%s\n", _("SMS status report"));
167 printf(LISTFORMAT, _("Status"));
168 switch (sms->State) {
169 case SMS_Sent : printf("%s", _("Sent")); break;
170 case SMS_Read : printf("%s", _("Read")); break;
171 case SMS_UnRead : printf("%s", _("UnRead")); break;
172 case SMS_UnSent : printf("%s", _("UnSent")); break;
174 printf("\n");
176 printf(LISTFORMAT, _("Remote number"));
177 PrintPhoneNumber(sms->Number, Info);
178 printf("\n");
180 printf(LISTFORMAT "%d\n", _("Reference number"),sms->MessageReference);
181 printf(LISTFORMAT "%s\n", _("Sent"),OSDateTime(sms->DateTime,TRUE));
182 printf(LISTFORMAT "\"%s\"\n", _("SMSC number"),DecodeUnicodeConsole(sms->SMSC.Number));
183 printf(LISTFORMAT "%s\n", _("SMSC response"),OSDateTime(sms->SMSCTime,TRUE));
184 printf(LISTFORMAT "%s\n", _("Delivery status"),DecodeUnicodeConsole(sms->Text));
185 printf(LISTFORMAT, _("Details"));
186 if (sms->DeliveryStatus & 0x40) {
187 if (sms->DeliveryStatus & 0x20) {
188 printf("%s", _("Temporary error, "));
189 } else {
190 printf("%s", _("Permanent error, "));
192 } else if (sms->DeliveryStatus & 0x20) {
193 printf("%s", _("Temporary error, "));
195 switch (sms->DeliveryStatus) {
196 case 0x00: printf("%s", _("SM received by the SME")); break;
197 case 0x01: printf("%s", _("SM forwarded by the SC to the SME but the SC is unable to confirm delivery"));break;
198 case 0x02: printf("%s", _("SM replaced by the SC")); break;
199 case 0x20: printf("%s", _("Congestion")); break;
200 case 0x21: printf("%s", _("SME busy")); break;
201 case 0x22: printf("%s", _("No response from SME")); break;
202 case 0x23: printf("%s", _("Service rejected")); break;
203 case 0x24: printf("%s", _("Quality of service not available")); break;
204 case 0x25: printf("%s", _("Error in SME")); break;
205 case 0x40: printf("%s", _("Remote procedure error")); break;
206 case 0x41: printf("%s", _("Incompatibile destination")); break;
207 case 0x42: printf("%s", _("Connection rejected by SME")); break;
208 case 0x43: printf("%s", _("Not obtainable")); break;
209 case 0x44: printf("%s", _("Quality of service not available")); break;
210 case 0x45: printf("%s", _("No internetworking available")); break;
211 case 0x46: printf("%s", _("SM Validity Period Expired")); break;
212 case 0x47: printf("%s", _("SM deleted by originating SME")); break;
213 case 0x48: printf("%s", _("SM Deleted by SC Administration")); break;
214 case 0x49: printf("%s", _("SM does not exist")); break;
215 case 0x60: printf("%s", _("Congestion")); break;
216 case 0x61: printf("%s", _("SME busy")); break;
217 case 0x62: printf("%s", _("No response from SME")); break;
218 case 0x63: printf("%s", _("Service rejected")); break;
219 case 0x64: printf("%s", _("Quality of service not available")); break;
220 case 0x65: printf("%s", _("Error in SME")); break;
221 default : printf(_("Reserved/Specific to SC: %x"),sms->DeliveryStatus); break;
223 printf("\n");
224 break;
225 case SMS_Deliver:
226 printf("%s\n", _("SMS message"));
227 if (sms->State==SMS_UnSent && sms->Memory==MEM_ME) {
228 printf(LISTFORMAT "%s\n", _("Saved"), OSDateTime(sms->DateTime,TRUE));
229 } else {
230 printf(LISTFORMAT "\"%s\"", _("SMSC number"), DecodeUnicodeConsole(sms->SMSC.Number));
231 if (sms->ReplyViaSameSMSC) printf("%s", _(" (set for reply)"));
232 printf("\n");
233 printf(LISTFORMAT "%s\n", _("Sent"), OSDateTime(sms->DateTime,TRUE));
235 /* No break. The only difference for SMS_Deliver and SMS_Submit is,
236 * that SMS_Deliver contains additional data. We wrote them and then go
237 * for data shared with SMS_Submit
239 case SMS_Submit:
240 if (sms->ReplaceMessage != 0) printf(LISTFORMAT "%i\n", _("SMS replacing ID"),sms->ReplaceMessage);
241 /* If we went here from "case SMS_Deliver", we don't write "SMS Message" */
242 if (sms->PDU==SMS_Submit) {
243 printf("%s\n", _("SMS message"));
244 if (sms->State == SMS_Sent) {
245 printf(LISTFORMAT "%d\n", _("Reference number"),sms->MessageReference);
247 if (CheckDate(&(sms->DateTime)) && CheckTime(&(sms->DateTime))) {
248 printf(LISTFORMAT "%s\n", _("Sent"), OSDateTime(sms->DateTime,TRUE));
251 if (sms->Name[0] != 0x00 || sms->Name[1] != 0x00) {
252 printf(LISTFORMAT "\"%s\"\n", _("Name"),DecodeUnicodeConsole(sms->Name));
254 if (sms->Class != -1) {
255 printf(LISTFORMAT "%i\n", _("Class"),sms->Class);
257 printf(LISTFORMAT, _("Coding"));
258 switch (sms->Coding) {
259 case SMS_Coding_Unicode_No_Compression :
260 printf("%s", _("Unicode (no compression)"));
261 break;
262 case SMS_Coding_Unicode_Compression :
263 printf("%s", _("Unicode (compression)"));
264 break;
265 case SMS_Coding_Default_No_Compression :
266 printf("%s", _("Default GSM alphabet (no compression)"));
267 break;
268 case SMS_Coding_Default_Compression :
269 printf("%s", _("Default GSM alphabet (compression)"));
270 break;
271 case SMS_Coding_8bit :
272 /* l10n: 8-bit message coding */
273 printf("%s", _("8-bit"));
274 break;
276 printf("\n");
277 if (sms->State==SMS_UnSent && sms->Memory==MEM_ME) {
278 } else {
279 printf(LISTFORMAT, ngettext("Remote number", "Remote numbers", sms->OtherNumbersNum + 1));
280 PrintPhoneNumber(sms->Number, Info);
281 for (i=0;i<sms->OtherNumbersNum;i++) {
282 printf(", ");
283 PrintPhoneNumber(sms->OtherNumbers[i], Info);
285 printf("\n");
287 printf(LISTFORMAT, _("Status"));
288 switch (sms->State) {
289 case SMS_Sent : printf("%s", _("Sent")); break;
290 case SMS_Read : printf("%s", _("Read")); break;
291 case SMS_UnRead : printf("%s", _("UnRead")); break;
292 case SMS_UnSent : printf("%s", _("UnSent")); break;
294 printf("\n");
295 if (sms->UDH.Type != UDH_NoUDH) {
296 printf(LISTFORMAT, _("User Data Header"));
297 switch (sms->UDH.Type) {
298 case UDH_ConcatenatedMessages : printf("%s", _("Concatenated (linked) message")); break;
299 case UDH_ConcatenatedMessages16bit : printf("%s", _("Concatenated (linked) message")); break;
300 case UDH_DisableVoice : printf("%s", _("Disables voice indicator")); break;
301 case UDH_EnableVoice : printf("%s", _("Enables voice indicator")); break;
302 case UDH_DisableFax : printf("%s", _("Disables fax indicator")); break;
303 case UDH_EnableFax : printf("%s", _("Enables fax indicator")); break;
304 case UDH_DisableEmail : printf("%s", _("Disables email indicator")); break;
305 case UDH_EnableEmail : printf("%s", _("Enables email indicator")); break;
306 case UDH_VoidSMS : printf("%s", _("Void SMS")); break;
307 case UDH_NokiaWAP : printf("%s", _("Nokia WAP bookmark")); break;
308 case UDH_NokiaOperatorLogoLong : printf("%s", _("Nokia operator logo")); break;
309 case UDH_NokiaWAPLong : printf("%s", _("Nokia WAP bookmark or WAP/MMS settings")); break;
310 case UDH_NokiaRingtone : printf("%s", _("Nokia ringtone")); break;
311 case UDH_NokiaRingtoneLong : printf("%s", _("Nokia ringtone")); break;
312 case UDH_NokiaOperatorLogo : printf("%s", _("Nokia GSM operator logo")); break;
313 case UDH_NokiaCallerLogo : printf("%s", _("Nokia caller logo")); break;
314 case UDH_NokiaProfileLong : printf("%s", _("Nokia profile")); break;
315 case UDH_NokiaCalendarLong : printf("%s", _("Nokia calendar note")); break;
316 case UDH_NokiaPhonebookLong : printf("%s", _("Nokia phonebook entry")); break;
317 case UDH_UserUDH : printf("%s", _("User UDH")); break;
318 case UDH_MMSIndicatorLong : printf("%s", _("MMS indicator")); break;
319 case UDH_NoUDH: break;
321 if (sms->UDH.Type != UDH_NoUDH) {
322 if (sms->UDH.ID8bit != -1) printf(_(", ID (8 bit) %i"),sms->UDH.ID8bit);
323 if (sms->UDH.ID16bit != -1) printf(_(", ID (16 bit) %i"),sms->UDH.ID16bit);
324 if (sms->UDH.PartNumber != -1 && sms->UDH.AllParts != -1) {
325 if (displayudh) {
326 printf(_(", part %i of %i"),sms->UDH.PartNumber,sms->UDH.AllParts);
327 } else {
328 printf(_(", %i parts"),sms->UDH.AllParts);
332 printf("\n");
334 if (displaytext) {
335 printf("\n");
336 if (sms->Coding != SMS_Coding_8bit) {
337 printf("%s\n", DecodeUnicodeConsole(sms->Text));
338 } else if (GSM_DecodeSiemensOTASMS(GSM_GetGlobalDebug(), &SiemensOTA, sms)) {
339 printf("%s\n", _("Siemens file"));
340 } else {
341 DisplayMessageHex(sms);
344 break;
345 #ifndef CHECK_CASES
346 default:
347 printf(_("Unknown PDU type: 0x%x\n"), sms->PDU);
348 break;
349 #endif
351 fflush(stdout);
354 #ifdef GSM_ENABLE_BACKUP
355 void DisplayMultiSMSInfo (GSM_MultiSMSMessage *sms, gboolean eachsms, gboolean ems, const GSM_Backup *Info, GSM_StateMachine *sm)
356 #else
357 void DisplayMultiSMSInfo (GSM_MultiSMSMessage *sms, gboolean eachsms, gboolean ems, const void *Info, GSM_StateMachine *sm)
358 #endif
360 GSM_SiemensOTASMSInfo SiemensOTA;
361 GSM_MultiPartSMSInfo SMSInfo;
362 gboolean RetVal,udhinfo=TRUE;
363 int j,i;
364 size_t Pos;
365 GSM_MemoryEntry pbk;
366 GSM_Error error;
368 /* GSM_DecodeMultiPartSMS returns if decoded SMS content correctly */
369 RetVal = GSM_DecodeMultiPartSMS(GSM_GetGlobalDebug(), &SMSInfo,sms,ems);
371 if (eachsms) {
372 if (GSM_DecodeSiemensOTASMS(GSM_GetGlobalDebug(), &SiemensOTA,&sms->SMS[0])) udhinfo = FALSE;
373 if (sms->SMS[0].UDH.Type != UDH_NoUDH && sms->SMS[0].UDH.AllParts == sms->Number) udhinfo = FALSE;
374 if (RetVal && !udhinfo) {
375 DisplaySingleSMSInfo(&(sms->SMS[0]),FALSE,FALSE,Info);
376 printf("\n");
377 } else {
378 for (j=0;j<sms->Number;j++) {
379 DisplaySingleSMSInfo(&(sms->SMS[j]),!RetVal,udhinfo,Info);
380 printf("\n");
383 } else {
384 for (j=0;j<sms->Number;j++) {
385 DisplaySingleSMSInfo(&(sms->SMS[j]),!RetVal,TRUE,Info);
386 printf("\n");
389 if (!RetVal) {
390 GSM_FreeMultiPartSMSInfo(&SMSInfo);
391 return;
394 if (SMSInfo.Unknown) printf("%s\n\n", _("Some details were ignored (unknown or not implemented in decoding functions)"));
396 for (i=0;i<SMSInfo.EntriesNum;i++) {
397 switch (SMSInfo.Entries[i].ID) {
398 case SMS_SiemensFile:
399 printf("%s", _("Siemens OTA file"));
400 if (strstr(DecodeUnicodeString(SMSInfo.Entries[i].File->Name),".vcf")) {
401 printf("%s\n", _(" - VCARD"));
402 SMSInfo.Entries[i].File->Buffer = realloc(SMSInfo.Entries[i].File->Buffer,1+SMSInfo.Entries[i].File->Used);
403 SMSInfo.Entries[i].File->Buffer[SMSInfo.Entries[i].File->Used] = 0;
404 SMSInfo.Entries[i].File->Used += 1;
405 Pos = 0;
406 error = GSM_DecodeVCARD(GSM_GetGlobalDebug(), SMSInfo.Entries[i].File->Buffer, &Pos, &pbk, Nokia_VCard21);
407 if (error == ERR_NONE) {
408 PrintMemoryEntry(&pbk, sm);
410 } else {
411 printf("\n");
413 break;
414 case SMS_NokiaRingtone:
415 printf(_("Ringtone \"%s\"\n"),DecodeUnicodeConsole(SMSInfo.Entries[i].Ringtone->Name));
416 GSM_SaveRingtoneRttl(stdout,SMSInfo.Entries[i].Ringtone);
417 printf("\n");
418 #if 0
419 /* Disabled for now */
420 if (answer_yes("%s", _("Do you want to play it?")))
421 GSM_PlayRingtone(*SMSInfo.Entries[i].Ringtone);
422 #endif
423 break;
424 case SMS_NokiaCallerLogo:
425 printf("%s\n\n", _("Caller logo"));
426 GSM_PrintBitmap(stdout,&SMSInfo.Entries[i].Bitmap->Bitmap[0]);
427 break;
428 case SMS_NokiaOperatorLogo:
429 printf(_("Operator logo for %s network"),
430 SMSInfo.Entries[i].Bitmap->Bitmap[0].NetworkCode);
431 printf(" (%s",
432 DecodeUnicodeConsole(GSM_GetNetworkName(SMSInfo.Entries[i].Bitmap->Bitmap[0].NetworkCode)));
433 printf(", %s)",
434 DecodeUnicodeConsole(GSM_GetCountryName(SMSInfo.Entries[i].Bitmap->Bitmap[0].NetworkCode)));
435 printf("\n\n");
436 GSM_PrintBitmap(stdout,&SMSInfo.Entries[i].Bitmap->Bitmap[0]);
437 break;
438 case SMS_NokiaScreenSaverLong:
439 printf("%s\n", _("Screen saver"));
440 GSM_PrintBitmap(stdout,&SMSInfo.Entries[i].Bitmap->Bitmap[0]);
441 break;
442 case SMS_NokiaPictureImageLong:
443 printf("%s\n", _("Picture"));
444 if (UnicodeLength(SMSInfo.Entries[i].Bitmap->Bitmap[0].Text) != 0)
445 printf(LISTFORMAT "\"%s\"\n\n", _("Text"),DecodeUnicodeConsole(SMSInfo.Entries[i].Bitmap->Bitmap[0].Text));
446 GSM_PrintBitmap(stdout,&SMSInfo.Entries[i].Bitmap->Bitmap[0]);
447 break;
448 case SMS_NokiaProfileLong:
449 printf("%s\n", _("Profile"));
450 GSM_PrintBitmap(stdout,&SMSInfo.Entries[i].Bitmap->Bitmap[0]);
451 break;
452 case SMS_ConcatenatedTextLong:
453 case SMS_ConcatenatedAutoTextLong:
454 case SMS_ConcatenatedTextLong16bit:
455 case SMS_ConcatenatedAutoTextLong16bit:
456 case SMS_NokiaVCARD21Long:
457 case SMS_NokiaVCALENDAR10Long:
458 if (SMSInfo.Entries[i].Buffer == NULL) printf("\n");
459 else printf("%s\n",DecodeUnicodeConsole(SMSInfo.Entries[i].Buffer));
460 break;
461 case SMS_EMSFixedBitmap:
462 case SMS_EMSVariableBitmap:
463 GSM_PrintBitmap(stdout,&SMSInfo.Entries[i].Bitmap->Bitmap[0]);
464 break;
465 case SMS_EMSAnimation:
466 /* Can't show animation, we show first frame */
467 GSM_PrintBitmap(stdout,&SMSInfo.Entries[i].Bitmap->Bitmap[0]);
468 break;
469 case SMS_EMSPredefinedSound:
470 printf("\n" LISTFORMAT "%i\n", _("EMS sound ID"),SMSInfo.Entries[i].Number);
471 break;
472 case SMS_EMSPredefinedAnimation:
473 printf("\n" LISTFORMAT "%i\n", _("EMS animation ID"),SMSInfo.Entries[i].Number);
474 break;
475 case SMS_MMSIndicatorLong:
476 printf(LISTFORMAT "%s\n", _("Sender"),SMSInfo.Entries[i].MMSIndicator->Sender);
477 printf(LISTFORMAT "%s\n", _("Subject"),SMSInfo.Entries[i].MMSIndicator->Title);
478 printf(LISTFORMAT "%s\n", _("Address"),SMSInfo.Entries[i].MMSIndicator->Address);
479 printf(LISTFORMAT "%li\n", _("Message size"), (long)SMSInfo.Entries[i].MMSIndicator->MessageSize);
480 break;
481 case SMS_Text:
482 case SMS_NokiaRingtoneLong:
483 case SMS_NokiaOperatorLogoLong:
484 case SMS_NokiaWAPBookmarkLong:
485 case SMS_NokiaWAPSettingsLong:
486 case SMS_NokiaMMSSettingsLong:
487 case SMS_NokiaVCARD10Long:
488 case SMS_NokiaVTODOLong:
489 case SMS_VCARD10Long:
490 case SMS_VCARD21Long:
491 case SMS_DisableVoice:
492 case SMS_DisableFax:
493 case SMS_DisableEmail:
494 case SMS_EnableVoice:
495 case SMS_EnableFax:
496 case SMS_EnableEmail:
497 case SMS_VoidSMS:
498 case SMS_EMSSound10:
499 case SMS_EMSSound12:
500 case SMS_EMSSonyEricssonSound:
501 case SMS_EMSSound10Long:
502 case SMS_EMSSound12Long:
503 case SMS_EMSSonyEricssonSoundLong:
504 case SMS_EMSVariableBitmapLong:
505 case SMS_WAPIndicatorLong:
506 case SMS_AlcatelMonoBitmapLong:
507 case SMS_AlcatelMonoAnimationLong:
508 case SMS_AlcatelSMSTemplateName:
509 #ifndef CHECK_CASES
510 default:
511 #endif
512 printf("%s\n", _("Error"));
513 break;
516 printf("\n");
517 fflush(stdout);
518 GSM_FreeMultiPartSMSInfo(&SMSInfo);
522 GSM_Error DisplaySMSFrame(GSM_SMSMessage *SMS, GSM_StateMachine *sm)
524 GSM_Error error;
525 int i, length, current = 0;
526 unsigned char req[1000], buffer[1000], hexreq[1000];
527 unsigned char hexmsg[1000], hexudh[1000];
529 error=PHONE_EncodeSMSFrame(sm,SMS,buffer,PHONE_SMSSubmit,&length,TRUE);
530 if (error != ERR_NONE) {
531 return error;
533 length = length - PHONE_SMSSubmit.Text;
535 for(i=SMS->UDH.Length;i<length;i++) {
536 req[i-SMS->UDH.Length]=buffer[PHONE_SMSSubmit.Text+i];
538 EncodeHexBin(hexmsg, req, MAX(0, length-SMS->UDH.Length));
540 for(i=0;i<SMS->UDH.Length;i++) {
541 req[i]=buffer[PHONE_SMSSubmit.Text+i];
543 EncodeHexBin(hexudh, req, SMS->UDH.Length);
545 printf(LISTFORMAT "%s\n", _("Data PDU"), hexmsg);
546 printf(LISTFORMAT "%d\n", _("Number of bits"),
547 (buffer[PHONE_SMSSubmit.TPUDL]-SMS->UDH.Length)*8);
548 printf(LISTFORMAT "%s\n", _("UDH"), hexudh);
550 for (i=0;i<buffer[PHONE_SMSSubmit.SMSCNumber]+1;i++) {
551 req[current++]=buffer[PHONE_SMSSubmit.SMSCNumber+i];
553 req[current++]=buffer[PHONE_SMSSubmit.firstbyte];
554 req[current++]=buffer[PHONE_SMSSubmit.TPMR];
555 for (i=0;i<((buffer[PHONE_SMSSubmit.Number]+1)/2+1)+1;i++) {
556 req[current++]=buffer[PHONE_SMSSubmit.Number+i];
558 req[current++]=buffer[PHONE_SMSSubmit.TPPID];
559 req[current++]=buffer[PHONE_SMSSubmit.TPDCS];
560 req[current++]=buffer[PHONE_SMSSubmit.TPVP];
561 req[current++]=buffer[PHONE_SMSSubmit.TPUDL];
562 for(i=0;i<length;i++) req[current++]=buffer[PHONE_SMSSubmit.Text+i];
563 EncodeHexBin(hexreq, req, current);
564 printf(LISTFORMAT "%s\n", _("Whole PDU"), hexreq);
565 printf("\n");
566 fflush(stdout);
567 return ERR_NONE;
570 /* How should editor hadle tabs in this file? Add editor commands here.
571 * vim: noexpandtab sw=8 ts=8 sts=8: