1 #define _GNU_SOURCE /* For strcasestr */
13 #include "../helper/locales.h"
18 #include "../helper/formats.h"
23 #include "../helper/message-display.h"
24 #include "../helper/memory-display.h"
25 #include "../helper/message-cmdline.h"
26 #include "../helper/printing.h"
27 #include "../helper/string.h"
28 #include "../helper/cmdline.h"
30 volatile gboolean wasincomingsms
= FALSE
;
31 volatile int num_replies
= 0;
33 GSM_MultiSMSMessage IncomingSMSData
;
35 void IncomingSMS(GSM_StateMachine
*sm UNUSED
, GSM_SMSMessage
*sms
, void *user_data
)
37 printf("%s\n", _("SMS message received"));
41 printf("%s\n", _("We already have one pending, ignoring this one!"));
45 wasincomingsms
= TRUE
;
46 IncomingSMSData
.SMS
[0] = *sms
;
47 IncomingSMSData
.Number
= 1;
50 void DisplayIncomingSMS(void)
52 GSM_SMSFolders folders
;
55 if (IncomingSMSData
.SMS
[0].State
== 0) {
56 error
=GSM_GetSMSFolders(gsm
, &folders
);
59 error
=GSM_GetSMS(gsm
, &IncomingSMSData
);
63 printf(_("Location %i\n"),IncomingSMSData
.SMS
[0].Location
);
64 printf("%s\n", _("Empty"));
69 PrintSMSLocation(&IncomingSMSData
.SMS
[0], &folders
);
72 DisplayMultiSMSInfo(&IncomingSMSData
,FALSE
,FALSE
,NULL
, gsm
);
73 wasincomingsms
= FALSE
;
76 void IncomingCB(GSM_StateMachine
*sm UNUSED
, GSM_CBMessage
*CB
, void *user_data
)
78 printf("%s\n", _("CB message received"));
79 printf(_("Channel %i, text \"%s\"\n"),CB
->Channel
,DecodeUnicodeConsole(CB
->Text
));
83 void IncomingUSSD(GSM_StateMachine
*sm UNUSED
, GSM_USSDMessage
*ussd
, void *user_data
)
85 printf("%s\n", _("USSD received"));
86 printf(LISTFORMAT
, _("Status"));
88 switch(ussd
->Status
) {
89 case USSD_NoActionNeeded
:
90 printf("%s\n", _("No action needed"));
92 case USSD_ActionNeeded
:
93 printf("%s\n", _("Action needed"));
96 printf("%s\n", _("Terminated"));
98 case USSD_AnotherClient
:
99 printf("%s\n", _("Another client replied"));
101 case USSD_NotSupported
:
102 printf("%s\n", _("Not supported"));
105 printf("%s\n", _("Timeout"));
111 printf("%s\n", _("Unknown"));
114 printf(LISTFORMAT
"\"%s\"\n", _("Service reply"), DecodeUnicodeConsole(ussd
->Text
));
118 void IncomingUSSD2(GSM_StateMachine
*sm
, GSM_USSDMessage
*ussd
, void * user_data
)
120 IncomingUSSD(sm
, ussd
, user_data
);
124 void GetUSSD(int argc UNUSED
, char *argv
[])
132 signal(SIGINT
, interrupt
);
133 fprintf(stderr
, "%s\n", _("Press Ctrl+C to break..."));
136 GSM_SetIncomingUSSDCallback(gsm
, IncomingUSSD2
, NULL
);
138 error
=GSM_SetIncomingUSSD(gsm
,TRUE
);
141 error
=GSM_DialService(gsm
, argv
[2]);
142 /* Fallback to voice call, it can work with some phones */
143 if (error
== ERR_NOTIMPLEMENTED
|| error
== ERR_NOTSUPPORTED
) {
144 error
=GSM_DialVoice(gsm
, argv
[2], GSM_CALL_DefaultNumberPresence
);
150 last_reply
= time(NULL
);
152 if (num_replies
!= last_replies
) {
153 last_replies
= num_replies
;
154 last_reply
= time(NULL
);
155 } else if (num_replies
== 0 && difftime(time(NULL
), last_reply
) > 60) {
156 /* Wait one minute for reply */
158 } else if (num_replies
> 0 && difftime(time(NULL
), last_reply
) > 30) {
159 /* Wait for consequent replies for 30 seconds */
162 GSM_ReadDevice(gsm
, FALSE
);
165 error
=GSM_SetIncomingUSSD(gsm
, FALSE
);
171 void SetSMSC(int argc
, char *argv
[])
176 smsc
.Location
= GetInt(argv
[2]);
177 if (smsc
.Location
< 1) {
178 printf_err(_("Invalid SMSC location: %s\n"), argv
[2]);
183 error
= GSM_GetSMSC(gsm
, &smsc
);
186 EncodeUnicode(smsc
.Number
, argv
[3], strlen(argv
[3]));
188 error
= GSM_SetSMSC(gsm
, &smsc
);
194 void GetSMSC(int argc
, char *argv
[])
198 int start
=0, stop
=0, i
=0;
204 GetStartStop(&start
, &stop
, 2, argc
, argv
);
209 for (i
=start
;i
<=stop
;i
++) {
212 error
=GSM_GetSMSC(gsm
, &smsc
);
215 printf(LISTFORMAT
"%d\n", _("Location"), smsc
.Location
);
217 if (UnicodeLength(smsc
.Name
) != 0) {
218 printf(LISTFORMAT
"\"%s\"\n", _("Name"),DecodeUnicodeConsole(smsc
.Name
));
220 printf(LISTFORMAT
"\"%s\"\n", _("Number"),DecodeUnicodeConsole(smsc
.Number
));
221 printf(LISTFORMAT
"\"%s\"\n", _("Default number"),DecodeUnicodeConsole(smsc
.DefaultNumber
));
223 printf(LISTFORMAT
, _("Format"));
224 switch (smsc
.Format
) {
225 case SMS_FORMAT_Text
: printf("%s", _("Text")); break;
226 case SMS_FORMAT_Fax
: printf("%s", _("Fax")); break;
227 case SMS_FORMAT_Email
: printf("%s", _("Email")); break;
228 case SMS_FORMAT_Pager
: printf("%s", _("Pager")); break;
232 printf(LISTFORMAT
, _("Validity"));
234 switch (smsc
.Validity
.Relative
) {
235 case SMS_VALID_1_Hour
:
238 case SMS_VALID_6_Hours
:
241 case SMS_VALID_1_Day
:
244 case SMS_VALID_3_Days
:
247 case SMS_VALID_1_Week
:
250 case SMS_VALID_Max_Time
:
251 printf("%s", _("Maximum time"));
254 /* Typecasting is here needed to silent GCC warning.
255 * Validity usually fits in some unsigned type so it is always >= 0 */
256 if ((int)smsc
.Validity
.Relative
>= 0 && smsc
.Validity
.Relative
<= 143) {
257 PRINTMINUTES((smsc
.Validity
.Relative
+ 1) * 5);
258 } else if (smsc
.Validity
.Relative
>= 144 && smsc
.Validity
.Relative
<= 167) {
259 PRINTMINUTES(12 * 60 + (smsc
.Validity
.Relative
- 143) * 30);
260 } else if (smsc
.Validity
.Relative
>= 168 && smsc
.Validity
.Relative
<= 196) {
261 PRINTDAYS(smsc
.Validity
.Relative
- 166);
262 } else if (smsc
.Validity
.Relative
>= 197 && smsc
.Validity
.Relative
<= 255) {
263 PRINTWEEKS(smsc
.Validity
.Relative
- 192);
272 void GetSMS(int argc
, char *argv
[])
275 GSM_MultiSMSMessage sms
;
276 GSM_SMSFolders folders
;
277 int start
=0, stop
=0, j
=0;
280 GetStartStop(&start
, &stop
, 3, argc
, argv
);
281 folder
= GetInt(argv
[2]);
285 error
=GSM_GetSMSFolders(gsm
, &folders
);
288 for (j
= start
; j
<= stop
; j
++) {
289 sms
.SMS
[0].Folder
= folder
;
290 sms
.SMS
[0].Location
= j
;
292 error
=GSM_GetSMS(gsm
, &sms
);
295 printf(_("Location %i\n"),sms
.SMS
[0].Location
);
296 printf("%s\n", _("Empty"));
300 PrintSMSLocation(&sms
.SMS
[0], &folders
);
301 DisplayMultiSMSInfo(&sms
,FALSE
,FALSE
,NULL
, gsm
);
308 void DeleteSMS(int argc
, char *argv
[])
312 int start
=0, stop
=0, i
=0;
314 sms
.Folder
= GetInt(argv
[2]);
316 GetStartStop(&start
, &stop
, 3, argc
, argv
);
320 for (i
=start
;i
<=stop
;i
++) {
322 error
=GSM_DeleteSMS(gsm
, &sms
);
328 void GetAllSMS(int argc
, char *argv
[])
331 GSM_MultiSMSMessage sms
;
332 GSM_SMSFolders folders
;
333 gboolean start
= TRUE
;
334 int smsnum
=0,smspos
=0;
335 #ifndef GSM_ENABLE_BACKUP
336 void *BackupPtr
= NULL
;
338 GSM_Backup
*BackupPtr
= NULL
;
341 GSM_ClearBackup(&Backup
);
346 sms
.SMS
[0].Location
= 0;
350 #ifdef GSM_ENABLE_BACKUP
351 if (argc
== 3 && strcasecmp(argv
[2],"-pbk") == 0) {
352 ReadPhonebook(Backup
.PhonePhonebook
, MEM_ME
, NULL
, GSM_BACKUP_MAX_PHONEPHONEBOOK
, NULL
, TRUE
);
353 ReadPhonebook(Backup
.SIMPhonebook
, MEM_SM
, NULL
, GSM_BACKUP_MAX_SIMPHONEBOOK
, NULL
, TRUE
);
357 error
=GSM_GetSMSFolders(gsm
, &folders
);
360 while (error
== ERR_NONE
) {
361 sms
.SMS
[0].Folder
=0x00;
362 error
=GSM_GetNextSMS(gsm
, &sms
, start
);
368 fprintf(stderr
, "\n%s\n", _("Corrupted message, skipping"));
374 PrintSMSLocation(&sms
.SMS
[0], &folders
);
377 DisplayMultiSMSInfo(&sms
, FALSE
, FALSE
, BackupPtr
, gsm
);
382 printf(_("%i SMS parts in %i SMS sequences"),smsnum
,smspos
);
386 #ifdef GSM_ENABLE_BACKUP
387 GSM_FreeBackup(&Backup
);
392 void GetEachSMS(int argc
, char *argv
[])
395 GSM_MultiSMSMessage
*GetSMSData
[GSM_PHONE_MAXSMSINFOLDER
],*SortedSMS
[GSM_PHONE_MAXSMSINFOLDER
],sms
;
396 GSM_SMSFolders folders
;
397 gboolean start
=TRUE
, ems
=TRUE
;
398 int GetSMSNumber
=0,i
=0,j
=0,smsnum
=0,smspos
=0;
399 #ifndef GSM_ENABLE_BACKUP
400 void *BackupPtr
= NULL
;
402 GSM_Backup
*BackupPtr
= NULL
;
405 GSM_ClearBackup(&Backup
);
410 sms
.SMS
[0].Location
= 0;
412 GetSMSData
[0] = NULL
;
416 #ifdef GSM_ENABLE_BACKUP
417 if (argc
== 3 && strcasecmp(argv
[2],"-pbk") == 0) {
418 ReadPhonebook(Backup
.PhonePhonebook
, MEM_ME
, NULL
, GSM_BACKUP_MAX_PHONEPHONEBOOK
, NULL
, TRUE
);
419 ReadPhonebook(Backup
.SIMPhonebook
, MEM_SM
, NULL
, GSM_BACKUP_MAX_SIMPHONEBOOK
, NULL
, TRUE
);
423 error
=GSM_GetSMSFolders(gsm
, &folders
);
426 fprintf(stderr
, LISTFORMAT
, _("Reading"));
428 while (error
== ERR_NONE
) {
429 if (GetSMSNumber
==GSM_PHONE_MAXSMSINFOLDER
-1) {
430 fprintf(stderr
, "\n%s\n", _("SMS counter overflow"));
433 sms
.SMS
[0].Folder
=0x00;
434 error
=GSM_GetNextSMS(gsm
, &sms
, start
);
440 fprintf(stderr
, "\n%s\n", _("Corrupted message, skipping"));
445 GetSMSData
[GetSMSNumber
] = malloc(sizeof(GSM_MultiSMSMessage
));
447 if (GetSMSData
[GetSMSNumber
] == NULL
) Print_Error(ERR_MOREMEMORY
);
448 GetSMSData
[GetSMSNumber
+1] = NULL
;
449 memcpy(GetSMSData
[GetSMSNumber
],&sms
,sizeof(GSM_MultiSMSMessage
));
456 fprintf(stderr
,"\n");
459 error
= GSM_LinkSMS(GSM_GetDebug(gsm
), GetSMSData
, SortedSMS
, ems
);
464 while(GetSMSData
[i
] != NULL
) {
466 GetSMSData
[i
] = NULL
;
472 while(SortedSMS
[i
] != NULL
) {
475 for (j
=0;j
<SortedSMS
[i
]->Number
;j
++) {
478 if ((j
==0) || (j
!=0 && SortedSMS
[i
]->SMS
[j
].Location
!= SortedSMS
[i
]->SMS
[j
-1].Location
)) {
479 PrintSMSLocation(&SortedSMS
[i
]->SMS
[j
], &folders
);
482 DisplayMultiSMSInfo(SortedSMS
[i
], TRUE
, ems
, BackupPtr
, gsm
);
489 #ifdef GSM_ENABLE_BACKUP
490 GSM_FreeBackup(&Backup
);
494 printf(_("%i SMS parts in %i SMS sequences"),smsnum
,smspos
);
500 void GetSMSFolders(int argc UNUSED
, char *argv
[] UNUSED
)
503 GSM_SMSFolders folders
;
508 error
=GSM_GetSMSFolders(gsm
,&folders
);
511 for (i
=0;i
<folders
.Number
;i
++) {
512 printf("%i. \"%30s\"",i
+1,DecodeUnicodeConsole(folders
.Folder
[i
].Name
));
514 switch(folders
.Folder
[i
].Memory
) {
515 case MEM_SM
: printf("%s", _(", SIM memory")); break;
516 case MEM_ME
: printf("%s", _(", phone memory")); break;
517 case MEM_MT
: printf("%s", _(", phone or SIM memory")); break;
520 if (folders
.Folder
[i
].InboxFolder
) printf("%s", _(", Inbox folder"));
521 if (folders
.Folder
[i
].OutboxFolder
) printf("%s", _(", Outbox folder"));
528 #define SEND_SAVE_SMS_BUFFER_SIZE 10000
532 void SendSMSStatus (GSM_StateMachine
*sm
, int status
, int MessageReference
, void *user_data
)
534 smprintf(gsm
, "Sent SMS on device: \"%s\"\n", GSM_GetConfig(sm
, -1)->Device
);
537 printf("%s", _("..OK"));
538 SMSStatus
= ERR_NONE
;
540 printf(_("..error %i"),status
);
541 SMSStatus
= ERR_UNKNOWN
;
543 printf(_(", message reference=%d"),MessageReference
);
548 void SendSaveDisplaySMS(int argc
, char *argv
[])
551 GSM_MultiSMSMessage sms
;
552 GSM_Message_Type type
;
553 GSM_SMSFolders folders
;
556 if (strcasestr(argv
[1], "savesms") != NULL
) {
558 } else if (strcasestr(argv
[1], "sendsmsdsms") != NULL
) {
560 } else if (strcasestr(argv
[1], "sendsms") != NULL
) {
562 } else if (strcasestr(argv
[1], "displaysms") != NULL
) {
570 error
= CreateMessage(&type
, &sms
, argc
, 2, argv
, gsm
);
575 for (i
= 0; i
< sms
.Number
; i
++) {
576 printf(LISTFORMAT
"%i\n", _("Message number"), i
);
577 error
= DisplaySMSFrame(&sms
.SMS
[i
], gsm
);
581 printf(LISTFORMAT
"%i\n", _("Number of messages"), sms
.Number
);
585 error
= GSM_GetSMSFolders(gsm
, &folders
);
588 if (type
== SMS_SendSaved
) {
589 GSM_SetSendSMSStatusCallback(gsm
, SendSMSStatus
, NULL
);
591 signal(SIGINT
, interrupt
);
592 fprintf(stderr
, "%s\n", _("If you want break, press Ctrl+C..."));
596 for (i
=0;i
<sms
.Number
;i
++) {
597 printf(_("Saving SMS %i/%i\n"),i
+1,sms
.Number
);
598 error
= GSM_AddSMS(gsm
, &sms
.SMS
[i
]);
600 printf(_("Saved in folder number %d \"%s\", location %i"),
602 DecodeUnicodeConsole(folders
.Folder
[sms
.SMS
[i
].Folder
-1].Name
),
603 sms
.SMS
[i
].Location
);
604 if (sms
.SMS
[i
].Memory
== MEM_SM
) {
605 printf(", %s\n", _("SIM"));
607 printf(", %s\n", _("phone"));
610 if (type
== SMS_SendSaved
) {
611 printf(_("Sending sms from folder \"%s\", location %i\n"),
612 DecodeUnicodeString(folders
.Folder
[sms
.SMS
[i
].Folder
-1].Name
),sms
.SMS
[i
].Location
);
614 SMSStatus
= ERR_TIMEOUT
;
615 error
= GSM_SendSavedSMS(gsm
, 0, sms
.SMS
[i
].Location
);
617 printf("%s", _("....waiting for network answer"));
621 GSM_ReadDevice(gsm
,TRUE
);
622 if (SMSStatus
== ERR_UNKNOWN
) {
623 Print_Error(SMSStatus
);
625 if (SMSStatus
== ERR_NONE
) break;
631 signal(SIGINT
, interrupt
);
632 fprintf(stderr
, "%s\n", _("If you want break, press Ctrl+C..."));
635 GSM_SetSendSMSStatusCallback(gsm
, SendSMSStatus
, NULL
);
637 for (i
=0;i
<sms
.Number
;i
++) {
638 printf(_("Sending SMS %i/%i"),i
+1,sms
.Number
);
640 SMSStatus
= ERR_TIMEOUT
;
641 error
=GSM_SendSMS(gsm
, &sms
.SMS
[i
]);
643 printf("%s", _("....waiting for network answer"));
647 GSM_ReadDevice(gsm
,TRUE
);
649 if (SMSStatus
== ERR_UNKNOWN
) {
650 Print_Error(SMSStatus
);
652 if (SMSStatus
== ERR_NONE
) break;
657 printf_err("%s", _("Something went wrong, uknown message operation!\n"));
663 void AddSMSFolder(int argc UNUSED
, char *argv
[])
665 unsigned char buffer
[200];
670 EncodeUnicode(buffer
,argv
[2],strlen(argv
[2]));
671 error
=GSM_AddSMSFolder(gsm
,buffer
);
677 void DeleteAllSMS(int argc
, char *argv
[])
679 GSM_MultiSMSMessage sms
;
680 GSM_SMSFolders folders
;
682 gboolean start
= TRUE
;
687 error
=GSM_GetSMSFolders(gsm
, &folders
);
690 GetStartStop(&foldernum
, NULL
, 2, argc
, argv
);
692 if (foldernum
> folders
.Number
) {
693 printf(_("Too high folder number (max. %i)\n"),folders
.Number
);
699 printf(_("Deleting SMS from \"%s\" folder: "),DecodeUnicodeConsole(folders
.Folder
[foldernum
-1].Name
));
702 while (error
== ERR_NONE
) {
703 sms
.SMS
[0].Folder
=0x00;
704 error
=GSM_GetNextSMS(gsm
, &sms
, start
);
710 fprintf(stderr
, "\n%s\n", _("Corrupted message, skipping"));
715 if (sms
.SMS
[0].Folder
== foldernum
) {
716 sms
.SMS
[0].Folder
=0x00;
717 error
=GSM_DeleteSMS(gsm
, &sms
.SMS
[0]);
731 /* How should editor hadle tabs in this file? Add editor commands here.
732 * vim: noexpandtab sw=8 ts=8 sts=8: