summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/phone/at
Side-by-side diff
Diffstat (limited to 'gammu/emb/common/phone/at') (more/less context) (ignore whitespace changes)
-rw-r--r--gammu/emb/common/phone/at/atgen.c295
-rw-r--r--gammu/emb/common/phone/at/atgen.h8
-rw-r--r--gammu/emb/common/phone/at/samsung.c447
-rw-r--r--gammu/emb/common/phone/at/samsung.h16
-rw-r--r--gammu/emb/common/phone/at/siemens.c74
-rw-r--r--gammu/emb/common/phone/at/sonyeric.c141
6 files changed, 874 insertions, 107 deletions
diff --git a/gammu/emb/common/phone/at/atgen.c b/gammu/emb/common/phone/at/atgen.c
index 1834f15..ba23eb2 100644
--- a/gammu/emb/common/phone/at/atgen.c
+++ b/gammu/emb/common/phone/at/atgen.c
@@ -9,43 +9,23 @@
#include <ctype.h>
#include "../../gsmcomon.h"
#include "../../misc/coding/coding.h"
#include "../../service/sms/gsmsms.h"
#include "../pfunc.h"
+
#include "atgen.h"
+#include "samsung.h"
+#include "siemens.h"
+#include "sonyeric.h"
+
#ifdef GSM_ENABLE_ALCATEL
-extern GSM_Error ALCATEL_ProtocolVersionReply (GSM_Protocol_Message msg, GSM_StateMachine *s);
+GSM_Error ALCATEL_ProtocolVersionReply (GSM_Protocol_Message, GSM_StateMachine *);
#endif
-extern GSM_Error ATGEN_CMS35ReplyGetBitmap (GSM_Protocol_Message msg, GSM_StateMachine *s);
-extern GSM_Error ATGEN_CMS35ReplySetBitmap (GSM_Protocol_Message msg, GSM_StateMachine *s);
-extern GSM_Error ATGEN_CMS35ReplyGetRingtone (GSM_Protocol_Message msg, GSM_StateMachine *s);
-extern GSM_Error ATGEN_CMS35ReplySetRingtone (GSM_Protocol_Message msg, GSM_StateMachine *s);
-extern GSM_Error ATGEN_CMS35ReplyGetNextCal (GSM_Protocol_Message msg, GSM_StateMachine *s);
-extern GSM_Error ATGEN_CMS35ReplySetCalendar (GSM_Protocol_Message msg, GSM_StateMachine *s);
-extern GSM_Error ATGEN_CMS35ReplyDeleteCalendar (GSM_Protocol_Message msg, GSM_StateMachine *s);
-extern GSM_Error ATGEN_SL45ReplyGetMemory (GSM_Protocol_Message msg, GSM_StateMachine *s);
-
-extern GSM_Error ATGEN_GetRingtone (GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone);
-extern GSM_Error ATGEN_SetRingtone (GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength);
-extern GSM_Error ATGEN_GetBitmap (GSM_StateMachine *s, GSM_Bitmap *Bitmap);
-extern GSM_Error ATGEN_SetBitmap (GSM_StateMachine *s, GSM_Bitmap *Bitmap);
-extern GSM_Error SIEMENS_GetNextCalendar (GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start);
-extern GSM_Error SIEMENS_AddCalendarNote (GSM_StateMachine *s, GSM_CalendarEntry *Note);
-extern GSM_Error SIEMENS_DelCalendarNote (GSM_StateMachine *s, GSM_CalendarEntry *Note);
-
-extern GSM_Error SONYERIC_GetNextCalendar (GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start);
-extern GSM_Error SONYERIC_GetNextToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool start);
-extern GSM_Error SONYERIC_GetToDoStatus (GSM_StateMachine *s, GSM_ToDoStatus *status);
-extern GSM_Error SONYERIC_AddCalendarNote (GSM_StateMachine *s, GSM_CalendarEntry *Note);
-extern GSM_Error SONYERIC_AddToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo);
-extern GSM_Error SONYERIC_DeleteAllToDo (GSM_StateMachine *s);
-extern GSM_Error SONYERIC_DelCalendarNote (GSM_StateMachine *s, GSM_CalendarEntry *Note);
-extern GSM_Error SONYERIC_GetCalendarStatus (GSM_StateMachine *s, GSM_CalendarStatus *Status);
typedef struct {
int Number;
char Text[60];
} ATErrorCode;
@@ -172,12 +152,14 @@ GSM_Error ATGEN_HandleCMEError(GSM_StateMachine *s)
smprintf(s, "CME Error %i, no description available\n", Priv->ErrorCode);
} else {
smprintf(s, "CME Error %i: \"%s\"\n", Priv->ErrorCode, Priv->ErrorText);
}
/* For error codes descriptions see table a bit above */
switch (Priv->ErrorCode) {
+ case -1:
+ return ERR_EMPTY;
case 3:
return ERR_PERMISSION;
case 4:
return ERR_NOTSUPPORTED;
case 5:
case 11:
@@ -253,14 +235,22 @@ int ATGEN_ExtractOneParameter(unsigned char *input, unsigned char *output)
position++;
return position;
}
void ATGEN_DecodeDateTime(GSM_DateTime *dt, unsigned char *input)
{
- dt->Year=2000+(*input-'0')*10; input++;
+ /* Samsung phones report year as %d instead of %02d */
+ if (input[2] == '/') {
+ dt->Year=(*input-'0')*10;
+ input++;
+ } else {
+ dt->Year=0;
+ }
+
dt->Year=dt->Year+(*input-'0'); input++;
+ dt->Year+=2000;
input++;
dt->Month=(*input-'0')*10; input++;
dt->Month=dt->Month+(*input-'0'); input++;
input++;
@@ -319,12 +309,24 @@ GSM_Error ATGEN_DispatchMessage(GSM_StateMachine *s)
ErrorCodes = CMEErrorCodes;
}
if (!strncmp(line,"+CMS ERROR:",11)) {
Priv->ReplyState = AT_Reply_CMSError;
ErrorCodes = CMSErrorCodes;
}
+
+ /* FIXME: Samsung phones can answer +CME ERROR:-1 meaning empty location */
+ if (Priv->ReplyState == AT_Reply_CMEError && Priv->Manufacturer == AT_Samsung) {
+ err = line + 11;
+ Priv->ErrorCode = atoi(err);
+
+ if (Priv->ErrorCode == -1) {
+ Priv->ErrorText = "[Samsung] Empty location";
+ return GSM_DispatchMessage(s);
+ }
+ }
+
if (Priv->ReplyState == AT_Reply_CMEError || Priv->ReplyState == AT_Reply_CMSError) {
j = 0;
/* One char behind +CM[SE] ERROR */
err = line + 12;
while (err[j] && !isalnum(err[j])) j++;
if (isdigit(err[j])) {
@@ -367,12 +369,48 @@ GSM_Error ATGEN_GenericReply(GSM_Protocol_Message msg, GSM_StateMachine *s)
default:
break;
}
return ERR_UNKNOWNRESPONSE;
}
+GSM_Error ATGEN_ReplyGetUSSD(GSM_Protocol_Message msg, GSM_StateMachine *s)
+{
+ unsigned char buffer[2000],buffer2[4000];
+ int i = 10;
+
+ /* Ugly hack */
+ while (msg.Buffer[i]!=13) i++;
+ i = i - 6;
+ memcpy(buffer,msg.Buffer+10,i-11);
+ buffer[i-11] = 0x00;
+
+ smprintf(s, "USSD reply: \"%s\"\n",buffer);
+
+ if (s->Phone.Data.EnableIncomingUSSD && s->User.IncomingUSSD!=NULL) {
+ EncodeUnicode(buffer2,buffer,strlen(buffer));
+ s->User.IncomingUSSD(s->CurrentConfig->Device, buffer2);
+ }
+
+ return ERR_NONE;
+}
+
+GSM_Error ATGEN_SetIncomingUSSD(GSM_StateMachine *s, bool enable)
+{
+ GSM_Error error;
+
+ if (enable) {
+ smprintf(s, "Enabling incoming USSD\n");
+ error=GSM_WaitFor (s, "AT+CUSD=1\r", 10, 0x00, 3, ID_SetUSSD);
+ } else {
+ smprintf(s, "Disabling incoming USSD\n");
+ error=GSM_WaitFor (s, "AT+CUSD=0\r", 10, 0x00, 3, ID_SetUSSD);
+ }
+ if (error==ERR_NONE) s->Phone.Data.EnableIncomingUSSD = enable;
+ return error;
+}
+
GSM_Error ATGEN_ReplyGetModel(GSM_Protocol_Message msg, GSM_StateMachine *s)
{
GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
GSM_Phone_Data *Data = &s->Phone.Data;
if (s->Phone.Data.Priv.ATGEN.ReplyState != AT_Reply_OK) return ERR_NOTSUPPORTED;
@@ -391,16 +429,18 @@ GSM_Error ATGEN_ReplyGetModel(GSM_Protocol_Message msg, GSM_StateMachine *s)
if (Data->ModelInfo->number[0] != 0) strcpy(Data->Model,Data->ModelInfo->number);
if (strstr(msg.Buffer,"Nokia")) Priv->Manufacturer = AT_Nokia;
else if (strstr(msg.Buffer,"M20")) Priv->Manufacturer = AT_Siemens;
else if (strstr(msg.Buffer,"MC35")) Priv->Manufacturer = AT_Siemens;
+ else if (strstr(msg.Buffer,"TC35")) Priv->Manufacturer = AT_Siemens;
else if (strstr(msg.Buffer, "iPAQ")) Priv->Manufacturer = AT_HP;
if (strstr(msg.Buffer,"M20")) strcpy(Data->Model,"M20");
else if (strstr(msg.Buffer,"MC35")) strcpy(Data->Model,"MC35");
+ else if (strstr(msg.Buffer,"TC35")) strcpy(Data->Model,"TC35");
else if (strstr(msg.Buffer, "iPAQ")) strcpy(Data->Model,"iPAQ");
} else {
smprintf(s, "WARNING: Model name too long, increase MAX_MODEL_LENGTH to at least %zd\n", strlen(GetLineString(msg.Buffer, Priv->Lines, 2)));
}
return ERR_NONE;
@@ -478,12 +518,17 @@ GSM_Error ATGEN_ReplyGetManufacturer(GSM_Protocol_Message msg, GSM_StateMachine
}
if (strstr(msg.Buffer,"SAGEM")) {
smprintf(s, "Sagem\n");
strcpy(s->Phone.Data.Manufacturer,"Sagem");
Priv->Manufacturer = AT_Sagem;
}
+ if (strstr(msg.Buffer,"Samsung")) {
+ smprintf(s, "Samsung\n");
+ strcpy(s->Phone.Data.Manufacturer,"Samsung");
+ Priv->Manufacturer = AT_Samsung;
+ }
return ERR_NONE;
case AT_Reply_CMSError:
return ATGEN_HandleCMSError(s);
default:
break;
}
@@ -671,22 +716,32 @@ GSM_Error ATGEN_ReplyGetSMSMemories(GSM_Protocol_Message msg, GSM_StateMachine *
* We need to get from this supported memories. For this case
* we assume, that just appearence of memory makes it
* available for everything. Then we need to find out whether
* phone supports writing to memory. This is done by searching
* for "), (", which will appear between lists.
*/
- s->Phone.Data.Priv.ATGEN.CanSaveSMS = (strstr(msg.Buffer, "), (") != NULL);
+ s->Phone.Data.Priv.ATGEN.CanSaveSMS = false;
+ if (strstr(msg.Buffer, "), (") != NULL || strstr(msg.Buffer, "),(") != NULL) {
+ s->Phone.Data.Priv.ATGEN.CanSaveSMS = true;
+ }
+
if (strstr(msg.Buffer, "\"SM\"") != NULL) s->Phone.Data.Priv.ATGEN.SIMSMSMemory = AT_AVAILABLE;
else s->Phone.Data.Priv.ATGEN.SIMSMSMemory = AT_NOTAVAILABLE;
+
if (strstr(msg.Buffer, "\"ME\"") != NULL) s->Phone.Data.Priv.ATGEN.PhoneSMSMemory = AT_AVAILABLE;
else s->Phone.Data.Priv.ATGEN.PhoneSMSMemory = AT_NOTAVAILABLE;
- smprintf(s, "Available SMS memories received, ME = %d, SM = %d\n", s->Phone.Data.Priv.ATGEN.PhoneSMSMemory, s->Phone.Data.Priv.ATGEN.SIMSMSMemory);
+
+ smprintf(s, "Available SMS memories received, ME = %d, SM = %d, cansavesms =", s->Phone.Data.Priv.ATGEN.PhoneSMSMemory, s->Phone.Data.Priv.ATGEN.SIMSMSMemory);
+ if (s->Phone.Data.Priv.ATGEN.CanSaveSMS) smprintf(s, "true");
+ smprintf(s, "\n");
return ERR_NONE;
case AT_Reply_Error:
case AT_Reply_CMSError:
return ATGEN_HandleCMSError(s);
+ case AT_Reply_CMEError:
+ return ATGEN_HandleCMEError(s);
default:
return ERR_UNKNOWNRESPONSE;
}
}
GSM_Error ATGEN_GetSMSMemories(GSM_StateMachine *s)
@@ -855,14 +910,15 @@ GSM_Error ATGEN_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s
}
DecodeHexBin (buffer, GetLineString(msg.Buffer,Priv->Lines,3), strlen(GetLineString(msg.Buffer,Priv->Lines,3)));
/* Siemens MC35 (only ?) */
if (strstr(msg.Buffer,"+CMGR: 0,,0")!=NULL) return ERR_EMPTY;
/* Siemens M20 */
if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_M20SMS)) {
- if (buffer[1]!=NUMBER_UNKNOWN && buffer[1]!=NUMBER_INTERNATIONAL &&
- buffer[1]!=NUMBER_ALPHANUMERIC) {
+ /* we check for the most often visible */
+ if (buffer[1]!=NUMBER_UNKNOWN_NUMBERING_PLAN_ISDN && buffer[1]!=NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN &&
+ buffer[1]!=NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN) {
/* Seems to be Delivery Report */
smprintf(s, "SMS type - status report (M20 style)\n");
sms->PDU = SMS_Status_Report;
sms->Folder = 1; /*INBOX SIM*/
sms->InboxFolder = true;
@@ -891,13 +947,13 @@ GSM_Error ATGEN_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s
} else {
sms->Folder = 3; /*INBOX ME*/
}
sms->InboxFolder = true;
current2=((buffer[current])+1)/2+1;
if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_M20SMS)) {
- if (buffer[current+1]==NUMBER_ALPHANUMERIC) {
+ if (buffer[current+1]==NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN) {
smprintf(s, "Trying to read alphanumeric number\n");
for(i=0;i<4;i++) smsframe[PHONE_SMSDeliver.Number+i]=buffer[current++];
current+=6;
for(i=0;i<current2-3;i++) smsframe[PHONE_SMSDeliver.Number+i+4]=buffer[current++];
} else {
for(i=0;i<current2+1;i++) smsframe[PHONE_SMSDeliver.Number+i]=buffer[current++];
@@ -922,13 +978,13 @@ GSM_Error ATGEN_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s
sms->Folder = 4; /*OUTBOX ME*/
}
sms->InboxFolder = false;
smsframe[PHONE_SMSSubmit.TPMR] = buffer[current++];
current2=((buffer[current])+1)/2+1;
if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_M20SMS)) {
- if (buffer[current+1]==NUMBER_ALPHANUMERIC) {
+ if (buffer[current+1]==NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN) {
smprintf(s, "Trying to read alphanumeric number\n");
for(i=0;i<4;i++) smsframe[PHONE_SMSSubmit.Number+i]=buffer[current++];
current+=6;
for(i=0;i<current2-3;i++) smsframe[PHONE_SMSSubmit.Number+i+4]=buffer[current++];
} else {
for(i=0;i<current2+1;i++) smsframe[PHONE_SMSSubmit.Number+i]=buffer[current++];
@@ -946,13 +1002,13 @@ GSM_Error ATGEN_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s
return ERR_NONE;
case 0x02:
smprintf(s, "SMS type - status report\n");
sms->PDU = SMS_Status_Report;
sms->Folder = 1; /*INBOX SIM*/
sms->InboxFolder = true;
- smprintf(s, "TPMR is %02x\n",buffer[current]);
+ smprintf(s, "TPMR is %d\n",buffer[current]);
smsframe[PHONE_SMSStatusReport.TPMR] = buffer[current++];
current2=((buffer[current])+1)/2+1;
for(i=0;i<current2+1;i++) smsframe[PHONE_SMSStatusReport.Number+i]=buffer[current++];
for(i=0;i<7;i++) smsframe[PHONE_SMSStatusReport.DateTime+i]=buffer[current++];
for(i=0;i<7;i++) smsframe[PHONE_SMSStatusReport.SMSCTime+i]=buffer[current++];
smsframe[PHONE_SMSStatusReport.TPStatus]=buffer[current];
@@ -1637,23 +1693,23 @@ GSM_Error ATGEN_ReplySendSMS(GSM_Protocol_Message msg, GSM_StateMachine *s)
}
switch (Priv->ReplyState) {
case AT_Reply_OK:
smprintf(s, "SMS sent OK\n");
if (s->User.SendSMSStatus!=NULL) {
- start = strstr(msg.Buffer, "+CMGW: ");
+ start = strstr(msg.Buffer, "+CMGS: ");
if (start != NULL) {
s->User.SendSMSStatus(s->CurrentConfig->Device,0,atoi(start+7));
} else {
- s->User.SendSMSStatus(s->CurrentConfig->Device,0,0);
+ s->User.SendSMSStatus(s->CurrentConfig->Device,0,-1);
}
}
return ERR_NONE;
case AT_Reply_CMSError:
smprintf(s, "Error %i\n",Priv->ErrorCode);
- if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,Priv->ErrorCode,0);
+ if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,Priv->ErrorCode,-1);
return ATGEN_HandleCMSError(s);
case AT_Reply_Error:
return ERR_UNKNOWN;
default:
return ERR_UNKNOWNRESPONSE;
}
@@ -1784,12 +1840,25 @@ GSM_Error ATGEN_GetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm)
s->Phone.Data.Alarm = alarm;
smprintf(s, "Getting alarm\n");
return GSM_WaitFor (s, "AT+CALA?\r", 9, 0x00, 4, ID_GetAlarm);
}
+/* R320 only takes HH:MM. Do other phones understand full date? */
+GSM_Error ATGEN_SetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm)
+{
+ char req[20];
+
+ if (alarm->Location != 1) return ERR_INVALIDLOCATION;
+
+ sprintf(req, "AT+CALA=\"%02i:%02i\"\r",alarm->DateTime.Hour,alarm->DateTime.Minute);
+
+ smprintf(s, "Setting Alarm\n");
+ return GSM_WaitFor (s, req, strlen(req), 0x00, 3, ID_SetAlarm);
+}
+
GSM_Error ATGEN_ReplyGetSMSC(GSM_Protocol_Message msg, GSM_StateMachine *s)
{
GSM_SMSC *SMSC = s->Phone.Data.SMSC;
int current;
int len;
unsigned char buffer[100];
@@ -2199,12 +2268,14 @@ GSM_Error ATGEN_GetMemoryInfo(GSM_StateMachine *s, GSM_MemoryStatus *Status, GSM
Priv->MemorySize = 0;
Priv->TextLength = 0;
Priv->NumberLength = 0;
error = GSM_WaitFor (s, "AT+CPBR=?\r", 10, 0x00, 4, ID_GetMemoryStatus);
+ if (Priv->Manufacturer == AT_Samsung)
+ error = GSM_WaitFor (s, "", 0, 0x00, 4, ID_GetMemoryStatus);
if (error != ERR_NONE) return error;
if (NeededInfo == AT_Total || NeededInfo == AT_Sizes || NeededInfo == AT_First) return ERR_NONE;
smprintf(s, "Getting memory status by reading values\n");
s->Phone.Data.MemoryStatus = Status;
@@ -2265,12 +2336,18 @@ GSM_Error ATGEN_SetPBKCharset(GSM_StateMachine *s, bool PreferUnicode)
if (!PreferUnicode && (Priv->PBKCharset!=AT_PBK_UCS2 || Priv->NonUCS2CharsetFailed)) return ERR_NONE;
}
error=ATGEN_GetManufacturer(s);
if (error != ERR_NONE) return error;
+ /* Samsung (and Sagem?) phones use only PCCP437? */
+ if (Priv->Manufacturer == AT_Samsung) {
+ Priv->PBKCharset = AT_PBK_PCCP437;
+ return ERR_NONE;
+ }
+
if (PreferUnicode && !Priv->UCS2CharsetFailed) {
smprintf(s, "Setting charset to UCS2\n");
error=GSM_WaitFor (s, "AT+CSCS=\"UCS2\"\r", 15, 0x00, 3, ID_SetMemoryCharset);
if (error == ERR_NONE) {
Priv->PBKCharset = AT_PBK_UCS2;
return ERR_NONE;
@@ -2382,13 +2459,43 @@ GSM_Error ATGEN_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s)
case AT_PBK_GSM:
DecodeDefault(Memory->Entries[1].Text,buffer+1,strlen(buffer)-2,false,NULL);
break;
case AT_PBK_UCS2:
DecodeHexUnicode(Memory->Entries[1].Text,buffer+1,strlen(buffer+1) - 1);
break;
+ case AT_PBK_PCCP437:
+ /* FIXME: correctly decode PCCP437 */
+ DecodeDefault(Memory->Entries[1].Text,buffer+1,strlen(buffer)-2,false,NULL);
+ break;
+ }
+
+ /* Samsung number type */
+ if (Priv->Manufacturer == AT_Samsung) {
+ int type;
+
+ pos += ATGEN_ExtractOneParameter(pos, buffer);
+ smprintf(s, "Number type: %s\n",buffer);
+ type = strtoul(buffer, NULL, 0);
+ switch (type) {
+ case 0:
+ Memory->Entries[0].EntryType = PBK_Number_Mobile;
+ break;
+ case 1:
+ Memory->Entries[0].EntryType = PBK_Number_Work;
+ break;
+ case 2:
+ Memory->Entries[0].EntryType = PBK_Number_Home;
+ break;
+ case 3:
+ Memory->Entries[0].EntryType = PBK_Text_Email;
+ break;
+ default:
+ Memory->Entries[0].EntryType = PBK_Number_General;
+ }
}
+
return ERR_NONE;
case AT_Reply_CMEError:
return ATGEN_HandleCMEError(s);
case AT_Reply_Error:
smprintf(s, "Error - too high location ?\n");
return ERR_INVALIDLOCATION;
@@ -2559,12 +2666,14 @@ GSM_Error ATGEN_ReplyEnterSecurityCode(GSM_Protocol_Message msg, GSM_StateMachin
return ERR_NONE;
case AT_Reply_Error:
smprintf(s, "Incorrect security code\n");
return ERR_SECURITYERROR;
case AT_Reply_CMSError:
return ATGEN_HandleCMSError(s);
+ case AT_Reply_CMEError:
+ return ATGEN_HandleCMEError(s);
default:
break;
}
return ERR_UNKNOWNRESPONSE;
}
@@ -2921,12 +3030,18 @@ GSM_Error ATGEN_PrivSetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
EncodeDefault(name, entry->Entries[Name].Text, &len, true, NULL);
break;
case AT_PBK_UCS2:
EncodeHexUnicode(name, entry->Entries[Name].Text, UnicodeLength(entry->Entries[Name].Text));
len = strlen(name);
break;
+ case AT_PBK_PCCP437:
+ /* FIXME: correctly decode PCCP437 */
+ smprintf(s, "str: %s\n", DecodeUnicodeString(entry->Entries[Name].Text));
+ len = UnicodeLength(entry->Entries[Name].Text);
+ EncodeDefault(name, entry->Entries[Name].Text, &len, true, NULL);
+ break;
}
} else {
smprintf(s, "WARNING: No usable name found!\n");
len = 0;
}
@@ -3249,12 +3364,49 @@ GSM_Error ATGEN_DelCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note)
if (Priv->Manufacturer==AT_Siemens) return SIEMENS_DelCalendarNote(s, Note);
if (Priv->Manufacturer==AT_Ericsson) return SONYERIC_DelCalendarNote(s, Note);
return ERR_NOTSUPPORTED;
}
+
+GSM_Error ATGEN_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
+{
+ GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
+
+ if (Priv->Manufacturer==AT_Siemens) return SIEMENS_GetBitmap(s, Bitmap);
+ if (Priv->Manufacturer==AT_Samsung) return SAMSUNG_GetBitmap(s, Bitmap);
+ return ERR_NOTSUPPORTED;
+}
+
+GSM_Error ATGEN_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
+{
+ GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
+
+ if (Priv->Manufacturer==AT_Siemens) return SIEMENS_SetBitmap(s, Bitmap);
+ if (Priv->Manufacturer==AT_Samsung) return SAMSUNG_SetBitmap(s, Bitmap);
+ return ERR_NOTSUPPORTED;
+}
+
+GSM_Error ATGEN_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone)
+{
+ GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
+
+ if (Priv->Manufacturer==AT_Siemens) return SIEMENS_GetRingtone(s, Ringtone, PhoneRingtone);
+ if (Priv->Manufacturer==AT_Samsung) return SAMSUNG_GetRingtone(s, Ringtone, PhoneRingtone);
+ return ERR_NOTSUPPORTED;
+}
+
+GSM_Error ATGEN_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength)
+{
+ GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
+
+ if (Priv->Manufacturer==AT_Siemens) return SIEMENS_SetRingtone(s, Ringtone, maxlength);
+ if (Priv->Manufacturer==AT_Samsung) return SAMSUNG_SetRingtone(s, Ringtone, maxlength);
+ return ERR_NOTSUPPORTED;
+}
+
GSM_Error ATGEN_PressKey(GSM_StateMachine *s, GSM_KeyCode Key, bool Press)
{
GSM_Error error;
unsigned char Frame[] = "AT+CKPD=\"?\"\r";
if (Press) {
@@ -3343,12 +3495,23 @@ GSM_Error ATGEN_SetIncomingCB(GSM_StateMachine *s, bool enable)
return ERR_NONE;
#else
return ERR_SOURCENOTAVAILABLE;
#endif
}
+GSM_Error ATGEN_SetFastSMSSending(GSM_StateMachine *s, bool enable)
+{
+ if (enable) {
+ smprintf(s, "Enabling fast SMS sending\n");
+ return GSM_WaitFor(s, "AT+CMMS=2\r", 10, 0x00, 4, ID_SetFastSMSSending);
+ } else {
+ smprintf(s, "Disabling fast SMS sending\n");
+ return GSM_WaitFor(s, "AT+CMMS=0\r", 10, 0x00, 4, ID_SetFastSMSSending);
+ }
+}
+
GSM_Error ATGEN_IncomingSMSInfo(GSM_Protocol_Message msg, GSM_StateMachine *s)
{
smprintf(s, "Incoming SMS\n");
return ERR_NONE;
}
@@ -3421,20 +3584,37 @@ GSM_Error ATGEN_SetIncomingSMS(GSM_StateMachine *s, bool enable)
return GSM_WaitFor(s, "AT+CNMI=3,0\r", 12, 0x00, 4, ID_SetIncomingSMS);
}
}
return ERR_NONE;
}
+GSM_Error ATGEN_GetLocale(GSM_StateMachine *s, GSM_Locale *locale)
+{
+ if (s->Phone.Data.Priv.ATGEN.Manufacturer==AT_Ericsson) return ERICSSON_GetLocale(s,locale);
+ return ERR_NOTSUPPORTED;
+}
+
+GSM_Error ATGEN_SetLocale(GSM_StateMachine *s, GSM_Locale *locale)
+{
+ if (s->Phone.Data.Priv.ATGEN.Manufacturer==AT_Ericsson) return ERICSSON_SetLocale(s,locale);
+ return ERR_NOTSUPPORTED;
+}
+
GSM_Reply_Function ATGENReplyFunctions[] = {
{ATGEN_GenericReply, "AT\r" ,0x00,0x00,ID_IncomingFrame },
{ATGEN_GenericReply, "ATE1" ,0x00,0x00,ID_EnableEcho },
{ATGEN_GenericReply, "AT+CMEE=" ,0x00,0x00,ID_EnableErrorInfo },
{ATGEN_GenericReply, "AT+CKPD=" ,0x00,0x00,ID_PressKey },
{ATGEN_ReplyGetSIMIMSI, "AT+CIMI" ,0x00,0x00,ID_GetSIMIMSI },
{ATGEN_GenericReply, "AT*EOBEX" ,0x00,0x00,ID_SetOBEX },
+{ERICSSON_ReplyGetDateLocale, "*ESDF:" ,0x00,0x00,ID_GetLocale },
+{ERICSSON_ReplyGetTimeLocale, "*ESTF:" ,0x00,0x00,ID_GetLocale },
+{ATGEN_GenericReply, "AT*ESDF=" ,0x00,0x00,ID_SetLocale },
+{ATGEN_GenericReply, "AT*ESTF=" ,0x00,0x00,ID_SetLocale },
+
#ifdef GSM_ENABLE_CELLBROADCAST
{ATGEN_ReplyIncomingCB, "+CBM:" ,0x00,0x00,ID_IncomingFrame },
{ATGEN_GenericReply, "AT+CNMI" ,0x00,0x00,ID_SetIncomingCB },
#endif
{ATGEN_IncomingBattery, "_OBS:" ,0x00,0x00,ID_IncomingFrame },
@@ -3459,19 +3639,21 @@ GSM_Reply_Function ATGENReplyFunctions[] = {
{ATGEN_GenericReply, "AT+CSMP" ,0x00,0x00,ID_SetSMSParameters },
{ATGEN_GenericReply, "AT+CSCA" ,0x00,0x00,ID_SetSMSC },
{ATGEN_ReplyGetSMSC, "AT+CSCA?" ,0x00,0x00,ID_GetSMSC },
{ATGEN_ReplyDeleteSMSMessage, "AT+CMGD" ,0x00,0x00,ID_DeleteSMSMessage },
{ATGEN_GenericReply, "ATE1" ,0x00,0x00,ID_SetSMSParameters },
{ATGEN_GenericReply, "\x1b\x0D" ,0x00,0x00,ID_SetSMSParameters },
+{ATGEN_GenericReply, "AT+CMMS" ,0x00,0x00,ID_SetFastSMSSending },
{ATGEN_IncomingSMSInfo, "+CMTI:" ,0x00,0x00,ID_IncomingFrame },
{ATGEN_IncomingSMSDeliver, "+CMT:" ,0x00,0x00,ID_IncomingFrame },
{ATGEN_IncomingSMSReport, "+CDS:" ,0x00,0x00,ID_IncomingFrame },
{ATGEN_IncomingSMSCInfo, "^SCN:" ,0x00,0x00,ID_IncomingFrame },
{ATGEN_ReplyGetDateTime_Alarm, "AT+CCLK?" ,0x00,0x00,ID_GetDateTime },
{ATGEN_GenericReply, "AT+CCLK=" ,0x00,0x00,ID_SetDateTime },
+{ATGEN_GenericReply, "AT+CALA=" ,0x00,0x00,ID_SetAlarm },
{ATGEN_ReplyGetDateTime_Alarm, "AT+CALA?" ,0x00,0x00,ID_GetAlarm },
{ATGEN_ReplyGetNetworkLAC_CID, "AT+CREG?" ,0x00,0x00,ID_GetNetworkInfo },
{ATGEN_GenericReply, "AT+CREG=2" ,0x00,0x00,ID_GetNetworkInfo },
{ATGEN_GenericReply, "AT+COPS=" ,0x00,0x00,ID_GetNetworkInfo },
{ATGEN_GenericReply, "AT+COPS=" ,0x00,0x00,ID_SetAutoNetworkLogin},
@@ -3481,49 +3663,59 @@ GSM_Reply_Function ATGENReplyFunctions[] = {
{ATGEN_IncomingGPRS, "+CGREG:" ,0x00,0x00,ID_IncomingFrame },
{ATGEN_ReplyGetNetworkLAC_CID, "+CREG:" ,0x00,0x00,ID_IncomingFrame },
{ATGEN_ReplyGetPBKMemories, "AT+CPBS=?" ,0x00,0x00,ID_SetMemoryType },
{ATGEN_GenericReply, "AT+CPBS=" ,0x00,0x00,ID_SetMemoryType },
{ATGEN_ReplyGetCPBSMemoryStatus,"AT+CPBS?" ,0x00,0x00,ID_GetMemoryStatus },
+// /* Samsung phones reply +CPBR: after OK --claudio*/
{ATGEN_ReplyGetCPBRMemoryInfo, "AT+CPBR=?" ,0x00,0x00,ID_GetMemoryStatus },
+{ATGEN_ReplyGetCPBRMemoryInfo, "+CPBR:" ,0x00,0x00,ID_GetMemoryStatus },
{ATGEN_ReplyGetCPBRMemoryStatus,"AT+CPBR=" ,0x00,0x00,ID_GetMemoryStatus },
{ATGEN_GenericReply, "AT+CSCS=" ,0x00,0x00,ID_SetMemoryCharset },
{ATGEN_ReplyGetMemory, "AT+CPBR=" ,0x00,0x00,ID_GetMemory },
{ATGEN_GenericReply, "AT^SBNR=?" ,0x00,0x00,ID_GetMemory },
-{ATGEN_SL45ReplyGetMemory, "AT^SBNR" ,0x00,0x00,ID_GetMemory },
+{SIEMENS_ReplyGetMemory, "AT^SBNR" ,0x00,0x00,ID_GetMemory },
{ATGEN_ReplySetMemory, "AT+CPBW" ,0x00,0x00,ID_SetMemory },
-{ATGEN_CMS35ReplyGetBitmap, "AT^SBNR=\"bmp\"" ,0x00,0x00,ID_GetBitmap },
-{ATGEN_CMS35ReplySetBitmap, "AT^SBNW=\"bmp\"" ,0x00,0x00,ID_SetBitmap },
+{SIEMENS_ReplyGetBitmap, "AT^SBNR=\"bmp\"" ,0x00,0x00,ID_GetBitmap },
+{SIEMENS_ReplySetBitmap, "AT^SBNW=\"bmp\"" ,0x00,0x00,ID_SetBitmap },
-{ATGEN_CMS35ReplyGetRingtone, "AT^SBNR=\"mid\"" ,0x00,0x00,ID_GetRingtone },
-{ATGEN_CMS35ReplySetRingtone, "AT^SBNW=\"mid\"" ,0x00,0x00,ID_SetRingtone },
+{SIEMENS_ReplyGetRingtone, "AT^SBNR=\"mid\"" ,0x00,0x00,ID_GetRingtone },
+{SIEMENS_ReplySetRingtone, "AT^SBNW=\"mid\"" ,0x00,0x00,ID_SetRingtone },
-{ATGEN_CMS35ReplyGetNextCal, "AT^SBNR=\"vcs\"" ,0x00,0x00,ID_GetCalendarNote },
-{ATGEN_CMS35ReplySetCalendar, "AT^SBNW=\"vcs\"" ,0x00,0x00,ID_SetCalendarNote },
-{ATGEN_CMS35ReplyDeleteCalendar,"AT^SBNW=\"vcs\"" ,0x00,0x00,ID_DeleteCalendarNote },
+{SIEMENS_ReplyGetNextCalendar, "AT^SBNR=\"vcs\"" ,0x00,0x00,ID_GetCalendarNote },
+{SIEMENS_ReplyAddCalendarNote, "AT^SBNW=\"vcs\"" ,0x00,0x00,ID_SetCalendarNote },
+{SIEMENS_ReplyDelCalendarNote, "AT^SBNW=\"vcs\"" ,0x00,0x00,ID_DeleteCalendarNote },
{ATGEN_ReplyEnterSecurityCode, "AT+CPIN=" ,0x00,0x00,ID_EnterSecurityCode },
{ATGEN_ReplyEnterSecurityCode, "AT+CPIN2=" ,0x00,0x00,ID_EnterSecurityCode },
{ATGEN_ReplyGetSecurityStatus, "AT+CPIN?" ,0x00,0x00,ID_GetSecurityStatus },
{ATGEN_ReplyOK, "OK" ,0x00,0x00,ID_IncomingFrame },
{ATGEN_GenericReply, "AT+VTS" ,0x00,0x00,ID_SendDTMF },
{ATGEN_ReplyCancelCall, "AT+CHUP" ,0x00,0x00,ID_CancelCall },
{ATGEN_ReplyDialVoice, "ATDT" ,0x00,0x00,ID_DialVoice },
{ATGEN_ReplyCancelCall, "ATH" ,0x00,0x00,ID_CancelCall },
+{ATGEN_GenericReply, "AT+CUSD" ,0x00,0x00,ID_SetUSSD },
+{ATGEN_ReplyGetUSSD, "+CUSD" ,0x00,0x00,ID_IncomingFrame },
{ATGEN_GenericReply, "AT+CLIP=1" ,0x00,0x00,ID_IncomingFrame },
{ATGEN_ReplyIncomingCallInfo, "+CLIP" ,0x00,0x00,ID_IncomingFrame },
{ATGEN_ReplyIncomingCallInfo, "+COLP" ,0x00,0x00,ID_IncomingFrame },
{ATGEN_ReplyIncomingCallInfo, "RING" ,0x00,0x00,ID_IncomingFrame },
{ATGEN_ReplyIncomingCallInfo, "NO CARRIER" ,0x00,0x00,ID_IncomingFrame },
{ATGEN_ReplyReset, "AT^SRESET" ,0x00,0x00,ID_Reset },
{ATGEN_ReplyReset, "AT+CFUN=1,1" ,0x00,0x00,ID_Reset },
{ATGEN_ReplyResetPhoneSettings, "AT&F" ,0x00,0x00,ID_ResetPhoneSettings },
+{SAMSUNG_ReplyGetBitmap, "AT+IMGR=" ,0x00,0x00,ID_GetBitmap },
+{SAMSUNG_ReplySetBitmap, "SDNDCRC =" ,0x00,0x00,ID_SetBitmap },
+
+{SAMSUNG_ReplyGetRingtone, "AT+MELR=" ,0x00,0x00,ID_GetRingtone },
+{SAMSUNG_ReplySetRingtone, "SDNDCRC =" ,0x00,0x00,ID_SetRingtone },
+
#ifdef GSM_ENABLE_ALCATEL
/* Why do I give Alcatel specific things here? It's simple, Alcatel needs
* some AT commands to start it's binary mode, so this needs to be in AT
* related stuff.
*
* XXX: AT+IFC could later move outside this ifdef, because it is not Alcatel
@@ -3535,13 +3727,13 @@ GSM_Reply_Function ATGENReplyFunctions[] = {
#endif
{NULL, "\x00" ,0x00,0x00,ID_None }
};
GSM_Phone_Functions ATGENPhone = {
- "A2D|iPAQ|at|M20|S25|MC35|C35i|5110|5130|5190|5210|6110|6130|6150|6190|6210|6250|6310|6310i|6510|7110|8210|8250|8290|8310|8390|8850|8855|8890|8910|9110|9210",
+ "A2D|iPAQ|at|M20|S25|MC35|TC35|C35i|S300|5110|5130|5190|5210|6110|6130|6150|6190|6210|6250|6310|6310i|6510|7110|8210|8250|8290|8310|8390|8850|8855|8890|8910|9110|9210",
ATGENReplyFunctions,
ATGEN_Initialise,
ATGEN_Terminate,
ATGEN_DispatchMessage,
NOTSUPPORTED, /* ShowStartInfo */
ATGEN_GetManufacturer,
@@ -3554,15 +3746,15 @@ GSM_Phone_Functions ATGENPhone = {
NOTSUPPORTED, /* GetHardware */
NOTSUPPORTED, /* GetPPM */
ATGEN_GetSIMIMSI,
ATGEN_GetDateTime,
ATGEN_SetDateTime,
ATGEN_GetAlarm,
- NOTIMPLEMENTED, /* SetAlarm */
- NOTSUPPORTED, /* GetLocale */
- NOTSUPPORTED, /* SetLocale */
+ ATGEN_SetAlarm,
+ ATGEN_GetLocale,
+ ATGEN_SetLocale,
ATGEN_PressKey,
ATGEN_Reset,
ATGEN_ResetPhoneSettings,
ATGEN_EnterSecurityCode,
ATGEN_GetSecurityStatus,
ATGEN_GetDisplayStatus,
@@ -3589,12 +3781,13 @@ GSM_Phone_Functions ATGENPhone = {
ATGEN_GetNextSMS,
NOTSUPPORTED, /* SetSMS */
ATGEN_AddSMS,
ATGEN_DeleteSMS,
ATGEN_SendSMS,
ATGEN_SendSavedSMS,
+ ATGEN_SetFastSMSSending,
ATGEN_SetIncomingSMS,
ATGEN_SetIncomingCB,
ATGEN_GetSMSFolders,
NOTSUPPORTED, /* AddSMSFolder */
NOTSUPPORTED, /* DeleteSMSFolder */
ATGEN_DialVoice,
@@ -3607,13 +3800,13 @@ GSM_Phone_Functions ATGENPhone = {
NOTSUPPORTED, /* TransferCall */
NOTSUPPORTED, /* SwitchCall */
NOTSUPPORTED, /* GetCallDivert */
NOTSUPPORTED, /* SetCallDivert */
NOTSUPPORTED, /* CancelAllDiverts */
NONEFUNCTION, /* SetIncomingCall */
- NOTSUPPORTED, /* SetIncomingUSSD */
+ ATGEN_SetIncomingUSSD,
ATGEN_SendDTMF,
ATGEN_GetRingtone,
ATGEN_SetRingtone,
NOTSUPPORTED, /* GetRingtonesInfo */
NOTSUPPORTED, /* DeleteUserRingtones */
NOTSUPPORTED, /* PlayTone */
@@ -3643,13 +3836,13 @@ GSM_Phone_Functions ATGENPhone = {
NOTIMPLEMENTED, /* SetCalendar */
ATGEN_AddCalendarNote,
ATGEN_DelCalendarNote,
NOTIMPLEMENTED, /* DeleteAllCalendar */
NOTSUPPORTED, /* GetCalendarSettings */
NOTSUPPORTED, /* SetCalendarSettings */
- NOTSUPPORTED, /* GetNote */
+ NOTSUPPORTED, /* GetNextNote */
NOTSUPPORTED, /* GetProfile */
NOTSUPPORTED, /* SetProfile */
NOTSUPPORTED, /* GetFMStation */
NOTSUPPORTED, /* SetFMStation */
NOTSUPPORTED, /* ClearFMStations */
NOTSUPPORTED, /* GetNextFileFolder */
diff --git a/gammu/emb/common/phone/at/atgen.h b/gammu/emb/common/phone/at/atgen.h
index 0e08ee4..bb5c559 100644
--- a/gammu/emb/common/phone/at/atgen.h
+++ b/gammu/emb/common/phone/at/atgen.h
@@ -39,19 +39,21 @@ typedef enum {
AT_Alcatel,
AT_Siemens,
AT_HP,
AT_Falcom,
AT_Ericsson,
AT_Sagem,
+ AT_Samsung,
AT_Unknown
} GSM_AT_Manufacturer;
typedef enum {
AT_PBK_HEX = 1,
AT_PBK_GSM,
- AT_PBK_UCS2
+ AT_PBK_UCS2,
+ AT_PBK_PCCP437
} GSM_AT_PBK_Charset;
typedef enum {
AT_AVAILABLE = 1,
AT_NOTAVAILABLE
} GSM_AT_SMSMemory;
@@ -100,11 +102,15 @@ typedef struct {
GSM_AT_SMS_Modes SMSMode; /* PDU or TEXT mode for SMS ? */
bool OBEX;
GSM_File file;
} GSM_Phone_ATGENData;
+GSM_Error ATGEN_HandleCMSError (GSM_StateMachine *);
+GSM_Error ATGEN_HandleCMEError (GSM_StateMachine *);
+GSM_Error ATGEN_DispatchMessage (GSM_StateMachine *);
+
#endif
/* How should editor hadle tabs in this file? Add editor commands here.
* vim: noexpandtab sw=8 ts=8 sts=8:
*/
diff --git a/gammu/emb/common/phone/at/samsung.c b/gammu/emb/common/phone/at/samsung.c
new file mode 100644
index 0000000..55a42e5
--- a/dev/null
+++ b/gammu/emb/common/phone/at/samsung.c
@@ -0,0 +1,447 @@
+/* Samsung-specific functions
+ * Copyright (C) 2004 Claudio Matsuoka <cmatsuoka@gmail.com>
+ * Tested with S300 only!
+ */
+
+#include "../../gsmstate.h"
+
+#ifdef GSM_ENABLE_ATGEN
+
+#include <string.h>
+#include <time.h>
+#include <ctype.h>
+
+#include "../../misc/coding/coding.h"
+#include "../../gsmcomon.h"
+#include "../../service/sms/gsmsms.h"
+#include "../pfunc.h"
+
+#include "atgen.h"
+#include "samsung.h"
+
+/* Binary frame size */
+#define BLKSZ 1024
+
+struct ModelRes {
+ char *model;
+ int width;
+ int height;
+};
+
+static struct ModelRes modres[] = {
+ { "S100", 128, 128 },
+ { "S200", 128, 113 },
+ { "S300", 128, 97 },
+ { "S500", 128, 128 },
+ { "T100", 128, 128 },
+ { "E700", 128, 128 },
+ { NULL, 0, 0 }
+};
+
+/*
+ * CRC functions from the Granch SBNI12 Linux driver by
+ * Denis I. Timofeev <timofeev@granch.ru>
+ */
+static unsigned int crc32tab[] = {
+ 0xD202EF8D, 0xA505DF1B, 0x3C0C8EA1, 0x4B0BBE37,
+ 0xD56F2B94, 0xA2681B02, 0x3B614AB8, 0x4C667A2E,
+ 0xDCD967BF, 0xABDE5729, 0x32D70693, 0x45D03605,
+ 0xDBB4A3A6, 0xACB39330, 0x35BAC28A, 0x42BDF21C,
+ 0xCFB5FFE9, 0xB8B2CF7F, 0x21BB9EC5, 0x56BCAE53,
+ 0xC8D83BF0, 0xBFDF0B66, 0x26D65ADC, 0x51D16A4A,
+ 0xC16E77DB, 0xB669474D, 0x2F6016F7, 0x58672661,
+ 0xC603B3C2, 0xB1048354, 0x280DD2EE, 0x5F0AE278,
+ 0xE96CCF45, 0x9E6BFFD3, 0x0762AE69, 0x70659EFF,
+ 0xEE010B5C, 0x99063BCA, 0x000F6A70, 0x77085AE6,
+ 0xE7B74777, 0x90B077E1, 0x09B9265B, 0x7EBE16CD,
+ 0xE0DA836E, 0x97DDB3F8, 0x0ED4E242, 0x79D3D2D4,
+ 0xF4DBDF21, 0x83DCEFB7, 0x1AD5BE0D, 0x6DD28E9B,
+ 0xF3B61B38, 0x84B12BAE, 0x1DB87A14, 0x6ABF4A82,
+ 0xFA005713, 0x8D076785, 0x140E363F, 0x630906A9,
+ 0xFD6D930A, 0x8A6AA39C, 0x1363F226, 0x6464C2B0,
+ 0xA4DEAE1D, 0xD3D99E8B, 0x4AD0CF31, 0x3DD7FFA7,
+ 0xA3B36A04, 0xD4B45A92, 0x4DBD0B28, 0x3ABA3BBE,
+ 0xAA05262F, 0xDD0216B9, 0x440B4703, 0x330C7795,
+ 0xAD68E236, 0xDA6FD2A0, 0x4366831A, 0x3461B38C,
+ 0xB969BE79, 0xCE6E8EEF, 0x5767DF55, 0x2060EFC3,
+ 0xBE047A60, 0xC9034AF6, 0x500A1B4C, 0x270D2BDA,
+ 0xB7B2364B, 0xC0B506DD, 0x59BC5767, 0x2EBB67F1,
+ 0xB0DFF252, 0xC7D8C2C4, 0x5ED1937E, 0x29D6A3E8,
+ 0x9FB08ED5, 0xE8B7BE43, 0x71BEEFF9, 0x06B9DF6F,
+ 0x98DD4ACC, 0xEFDA7A5A, 0x76D32BE0, 0x01D41B76,
+ 0x916B06E7, 0xE66C3671, 0x7F6567CB, 0x0862575D,
+ 0x9606C2FE, 0xE101F268, 0x7808A3D2, 0x0F0F9344,
+ 0x82079EB1, 0xF500AE27, 0x6C09FF9D, 0x1B0ECF0B,
+ 0x856A5AA8, 0xF26D6A3E, 0x6B643B84, 0x1C630B12,
+ 0x8CDC1683, 0xFBDB2615, 0x62D277AF, 0x15D54739,
+ 0x8BB1D29A, 0xFCB6E20C, 0x65BFB3B6, 0x12B88320,
+ 0x3FBA6CAD, 0x48BD5C3B, 0xD1B40D81, 0xA6B33D17,
+ 0x38D7A8B4, 0x4FD09822, 0xD6D9C998, 0xA1DEF90E,
+ 0x3161E49F, 0x4666D409, 0xDF6F85B3, 0xA868B525,
+ 0x360C2086, 0x410B1010, 0xD80241AA, 0xAF05713C,
+ 0x220D7CC9, 0x550A4C5F, 0xCC031DE5, 0xBB042D73,
+ 0x2560B8D0, 0x52678846, 0xCB6ED9FC, 0xBC69E96A,
+ 0x2CD6F4FB, 0x5BD1C46D, 0xC2D895D7, 0xB5DFA541,
+ 0x2BBB30E2, 0x5CBC0074, 0xC5B551CE, 0xB2B26158,
+ 0x04D44C65, 0x73D37CF3, 0xEADA2D49, 0x9DDD1DDF,
+ 0x03B9887C, 0x74BEB8EA, 0xEDB7E950, 0x9AB0D9C6,
+ 0x0A0FC457, 0x7D08F4C1, 0xE401A57B, 0x930695ED,
+ 0x0D62004E, 0x7A6530D8, 0xE36C6162, 0x946B51F4,
+ 0x19635C01, 0x6E646C97, 0xF76D3D2D, 0x806A0DBB,
+ 0x1E0E9818, 0x6909A88E, 0xF000F934, 0x8707C9A2,
+ 0x17B8D433, 0x60BFE4A5, 0xF9B6B51F, 0x8EB18589,
+ 0x10D5102A, 0x67D220BC, 0xFEDB7106, 0x89DC4190,
+ 0x49662D3D, 0x3E611DAB, 0xA7684C11, 0xD06F7C87,
+ 0x4E0BE924, 0x390CD9B2, 0xA0058808, 0xD702B89E,
+ 0x47BDA50F, 0x30BA9599, 0xA9B3C423, 0xDEB4F4B5,
+ 0x40D06116, 0x37D75180, 0xAEDE003A, 0xD9D930AC,
+ 0x54D13D59, 0x23D60DCF, 0xBADF5C75, 0xCDD86CE3,
+ 0x53BCF940, 0x24BBC9D6, 0xBDB2986C, 0xCAB5A8FA,
+ 0x5A0AB56B, 0x2D0D85FD, 0xB404D447, 0xC303E4D1,
+ 0x5D677172, 0x2A6041E4, 0xB369105E, 0xC46E20C8,
+ 0x72080DF5, 0x050F3D63, 0x9C066CD9, 0xEB015C4F,
+ 0x7565C9EC, 0x0262F97A, 0x9B6BA8C0, 0xEC6C9856,
+ 0x7CD385C7, 0x0BD4B551, 0x92DDE4EB, 0xE5DAD47D,
+ 0x7BBE41DE, 0x0CB97148, 0x95B020F2, 0xE2B71064,
+ 0x6FBF1D91, 0x18B82D07, 0x81B17CBD, 0xF6B64C2B,
+ 0x68D2D988, 0x1FD5E91E, 0x86DCB8A4, 0xF1DB8832,
+ 0x616495A3, 0x1663A535, 0x8F6AF48F, 0xF86DC419,
+ 0x660951BA, 0x110E612C, 0x88073096, 0xFF000000
+};
+
+static unsigned int GetCRC(char *data, int size)
+{
+ unsigned int crc = 0;
+
+ while (size--)
+ crc = crc32tab[(crc ^ *data++) & 0xff] ^ ((crc >> 8) & 0x00FFFFFF);
+
+ return crc;
+}
+
+/*
+ * Frame transfer
+ */
+
+static GSM_Error WaitFor(GSM_StateMachine *s, char *t, int ttl)
+{
+ char readbuf[100];
+ int n;
+ unsigned int sec;
+ GSM_DateTime Date;
+
+ GSM_GetCurrentDateTime (&Date);
+ sec = Date.Second;
+
+ n = s->Device.Functions->ReadDevice(s, readbuf, 80);
+ readbuf[n] = 0;
+ while (strstr(readbuf, t) == NULL && (sec + ttl) >= Date.Second) {
+ my_sleep(5000);
+ n = s->Device.Functions->ReadDevice(s, readbuf, 80);
+ readbuf[n] = 0;
+ GSM_GetCurrentDateTime (&Date);
+ }
+
+ return (sec + ttl) >= Date.Second ? ERR_NONE : ERR_TIMEOUT;
+}
+
+static GSM_Error SetSamsungFrame(GSM_StateMachine *s, unsigned char *buff, int size, GSM_Phone_RequestID id)
+{
+ GSM_Phone_Data *Phone = &s->Phone.Data;
+ GSM_Error error;
+ int i, count;
+
+ count = size / BLKSZ;
+
+ for (i = 0; i < count; i++) {
+ error = WaitFor(s, ">", 4);
+ if (error!=ERR_NONE) return error;
+
+ error = s->Protocol.Functions->WriteMessage(s,
+ buff + i * BLKSZ, BLKSZ, 0x00);
+ if (error!=ERR_NONE) return error;
+ }
+
+ error = WaitFor(s, ">", 4);
+ if (error!=ERR_NONE) return error;
+ error = s->Protocol.Functions->WriteMessage(s,
+ buff + i * BLKSZ, size%BLKSZ, 0x00);
+ if (error!=ERR_NONE) return error;
+
+ error = GSM_WaitFor(s, "", 0, 0x00, 4, id);
+ if (error!=ERR_NONE) return error;
+
+ return Phone->DispatchError;
+}
+
+/* Answer format for binary data transfer
+ *
+ * SDNDCRC = 0xa : RECEIVECRC = 0xcbf53a1c : BINSIZE = 5
+ * CRCERR
+ */
+static GSM_Error ReplySetSamsungFrame(GSM_Protocol_Message msg, GSM_StateMachine *s)
+{
+ unsigned long txcrc, rxcrc;
+ int binsize;
+ char *pos;
+
+ /* Parse SDNDCRC */
+ pos = strchr(msg.Buffer, '=');
+ if (!pos) return ERR_UNKNOWN;
+ pos++;
+ txcrc = strtoul(pos, NULL, 0);
+ smprintf(s, "Sent CRC : 0x%lx\n", txcrc);
+
+ /* Parse RECEIVECRC */
+ pos = strchr(pos, '=');
+ if (!pos) return ERR_UNKNOWN;
+ pos++;
+ rxcrc = strtoul(pos, NULL, 0);
+ smprintf(s, "Reveived CRC : 0x%lx\n", rxcrc);
+
+ /* Parse BINSIZE */
+ pos = strchr(pos, '=');
+ if (!pos) return ERR_UNKNOWN;
+ pos++;
+ binsize = strtoul(pos, NULL, 0);
+ smprintf(s, "Binary size : %d\n", binsize);
+
+ return txcrc == rxcrc ? ERR_NONE : ERR_WRONGCRC;
+}
+
+/*
+ * Bitmaps
+ */
+
+GSM_Error SAMSUNG_ReplyGetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s)
+{
+ GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
+ unsigned char buffer[32];
+ char *pos;
+ int location, count;
+
+ switch (Priv->ReplyState) {
+ case AT_Reply_OK:
+ smprintf(s, "Bitmap info received\n");
+ /* Parse +IMGR:location,name,0,0,0,0 */
+
+ /* Parse location */
+ pos = strchr(msg.Buffer, ':');
+ if (!pos) return ERR_UNKNOWN;
+ pos++;
+ location = atoi(pos);
+ smprintf(s, "Location : %d\n", location);
+
+ /* Parse name */
+ pos = strchr(pos, '"');
+ if (!pos) return ERR_UNKNOWN;
+ pos++;
+ for (count = 0; count < 31; count++) {
+ if (pos[count] == '"')
+ break;
+ buffer[count] = pos[count];
+ }
+ buffer[count] = 0;
+ smprintf(s, "Name : %s\n", buffer);
+ s->Phone.Data.Bitmap->Name = malloc((strlen(buffer) + 1) * 2);
+ if (s->Phone.Data.Bitmap->Name == NULL)
+ return ERR_MOREMEMORY;
+ EncodeUnicode(s->Phone.Data.Bitmap->Name, buffer, strlen(buffer));
+
+ s->Phone.Data.Bitmap->Location = location;
+
+ return ERR_NONE;
+ case AT_Reply_Error:
+ return ERR_UNKNOWN;
+ case AT_Reply_CMSError:
+ return ATGEN_HandleCMSError(s);
+ case AT_Reply_CMEError:
+ return ATGEN_HandleCMEError(s);
+ default:
+ return ERR_UNKNOWNRESPONSE;
+ }
+}
+
+GSM_Error SAMSUNG_ReplySetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s)
+{
+ smprintf(s, "Bitmap sent\n");
+ return ReplySetSamsungFrame(msg, s);
+}
+
+GSM_Error SAMSUNG_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
+{
+ unsigned char req[100];
+
+ s->Phone.Data.Bitmap=Bitmap;
+ smprintf(s, "Getting bitmap\n");
+ sprintf(req, "AT+IMGR=%d\r", Bitmap->Location-1);
+ return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetBitmap);
+}
+
+GSM_Error SAMSUNG_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
+{
+ unsigned char req[100];
+ unsigned long crc;
+ GSM_Error error;
+ char name[50], *dot, *model;
+ GSM_Phone_Data *Data = &s->Phone.Data;
+ int i;
+
+ s->Phone.Data.Bitmap = Bitmap;
+ smprintf(s, "Setting bitmap\n");
+
+ if (Bitmap->Type != GSM_PictureBinary) {
+ smprintf(s, "Invalid picture type\n");
+ return ERR_INVALIDDATA;
+ }
+
+ if (Bitmap->BinaryPic.Type != PICTURE_GIF) {
+ smprintf(s, "Invalid binary picture type\n");
+ return ERR_INVALIDDATA;
+ }
+
+ /* Check if picture size matches phone model */
+ model = GetModelData(NULL,Data->Model,NULL)->model;
+ smprintf(s, "Checking picture size for %s\n", model);
+ for (i = 0; modres[i].model; i++) {
+ if (!strcmp(model, modres[i].model)) {
+ if (Bitmap->BitmapWidth != modres[i].width ||
+ Bitmap->BitmapHeight != modres[i].height) {
+ smprintf(s, "Model %s must use %d x %d picture size\n",
+ modres[i].model, modres[i].width,
+ modres[i].height);
+ return ERR_INVALIDDATA;
+ }
+ break;
+ }
+ }
+ if (modres[i].model == NULL) {
+ smprintf(s, "Model \"%s\" is not supported.\n", Data->Model);
+ return ERR_NOTSUPPORTED;
+ }
+
+ crc = GetCRC(Bitmap->BinaryPic.Buffer, Bitmap->BinaryPic.Length);
+
+ /* Remove extension from file name */
+ strncpy(name, DecodeUnicodeString(Bitmap->Name), 50);
+ if ((dot = strrchr(name, '.')) != NULL)
+ *dot = 0;
+
+ sprintf(req, "AT+IMGW=0,\"%s\",2,0,0,0,0,100,%d,%u\r", name,
+ Bitmap->BinaryPic.Length, (unsigned int)crc);
+
+ error = s->Protocol.Functions->WriteMessage(s, req, strlen(req), 0x00);
+ if (error!=ERR_NONE) return error;
+
+ return SetSamsungFrame(s, Bitmap->BinaryPic.Buffer,
+ Bitmap->BinaryPic.Length, ID_SetBitmap);
+}
+
+/*
+ * Ringtones
+ */
+
+GSM_Error SAMSUNG_ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s)
+{
+ GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
+ unsigned char buffer[32];
+ char *pos;
+ int location, length, count;
+
+ switch (Priv->ReplyState) {
+ case AT_Reply_OK:
+ smprintf(s, "Ringtone info received\n");
+ /* Parse +MELR:location,name,size */
+
+ /* Parse location */
+ pos = strchr(msg.Buffer, ':');
+ if (!pos) return ERR_UNKNOWN;
+ pos++;
+ location = atoi(pos);
+ smprintf(s, "Location : %d\n", location);
+
+ /* Parse name */
+ pos = strchr(pos, '"');
+ if (!pos) return ERR_UNKNOWN;
+ pos++;
+ /* Ringtone.Name size is 20 chars */
+ for (count = 0; count < 19; count++) {
+ if (pos[count] == '"')
+ break;
+ buffer[count] = pos[count];
+ }
+ buffer[count] = 0;
+ smprintf(s, "Name : %s\n", buffer);
+ EncodeUnicode(s->Phone.Data.Ringtone->Name,buffer,strlen(buffer));
+
+ /* Parse ringtone length */
+ pos = strchr(pos, ',');
+ if (!pos) return ERR_UNKNOWN;
+ pos++;
+ length = atoi(pos);
+ smprintf(s, "Length : %d\n", length);
+
+ /* S300 ringtones are always MMF */
+ s->Phone.Data.Ringtone->Format = RING_MMF;
+ s->Phone.Data.Ringtone->Location = location;
+ s->Phone.Data.Ringtone->BinaryTone.Length = length;
+
+ return ERR_NONE;
+ case AT_Reply_Error:
+ return ERR_UNKNOWN;
+ case AT_Reply_CMSError:
+ return ATGEN_HandleCMSError(s);
+ case AT_Reply_CMEError:
+ return ATGEN_HandleCMEError(s);
+ default:
+ return ERR_UNKNOWNRESPONSE;
+ }
+}
+
+GSM_Error SAMSUNG_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone)
+{
+ unsigned char req[100];
+
+ s->Phone.Data.Ringtone = Ringtone;
+ smprintf(s, "Getting ringtone\n");
+ sprintf(req, "AT+MELR=%d\r", Ringtone->Location-1);
+ return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetRingtone);
+}
+
+GSM_Error SAMSUNG_ReplySetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s)
+{
+ smprintf(s, "Ringtone sent\n");
+ return ReplySetSamsungFrame(msg, s);
+}
+
+GSM_Error SAMSUNG_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength)
+{
+ unsigned char req[100];
+ unsigned long crc;
+ GSM_Error error;
+ char name[50], *dot;
+
+ s->Phone.Data.Ringtone = Ringtone;
+ smprintf(s, "Setting ringtone\n");
+
+ if (Ringtone->Format != RING_MMF) {
+ smprintf(s, "Not MMF ringtone\n");
+ return ERR_INVALIDDATA;
+ }
+
+ /* Remove extension from file name */
+ strncpy(name, DecodeUnicodeString(Ringtone->Name), 50);
+ if ((dot = strrchr(name, '.')) != NULL) *dot = 0;
+
+ crc = GetCRC(Ringtone->BinaryTone.Buffer, Ringtone->BinaryTone.Length);
+ sprintf(req, "AT+MELW=0,\"%s\",4,%d,%u\r", name,
+ Ringtone->BinaryTone.Length, (unsigned int)crc);
+
+ error = s->Protocol.Functions->WriteMessage(s, req, strlen(req), 0x00);
+ if (error!=ERR_NONE) return error;
+
+ return SetSamsungFrame(s, Ringtone->BinaryTone.Buffer,
+ Ringtone->BinaryTone.Length, ID_SetRingtone);
+}
+
+#endif
diff --git a/gammu/emb/common/phone/at/samsung.h b/gammu/emb/common/phone/at/samsung.h
new file mode 100644
index 0000000..3b2947c
--- a/dev/null
+++ b/gammu/emb/common/phone/at/samsung.h
@@ -0,0 +1,16 @@
+#ifndef samsung_h
+#define samsung_h
+
+#include "../../gsmstate.h"
+
+GSM_Error SAMSUNG_ReplyGetRingtone (GSM_Protocol_Message, GSM_StateMachine *);
+GSM_Error SAMSUNG_ReplySetRingtone (GSM_Protocol_Message, GSM_StateMachine *);
+GSM_Error SAMSUNG_ReplyGetBitmap (GSM_Protocol_Message, GSM_StateMachine *);
+GSM_Error SAMSUNG_ReplySetBitmap (GSM_Protocol_Message, GSM_StateMachine *);
+GSM_Error SAMSUNG_GetRingtone (GSM_StateMachine *, GSM_Ringtone *, bool);
+GSM_Error SAMSUNG_SetRingtone (GSM_StateMachine *, GSM_Ringtone *, int *);
+GSM_Error SAMSUNG_GetBitmap (GSM_StateMachine *, GSM_Bitmap *);
+GSM_Error SAMSUNG_SetBitmap (GSM_StateMachine *, GSM_Bitmap *);
+GSM_Error SAMSUNG_GetCallLogs (GSM_StateMachine *, GSM_MemoryEntry *, int);
+
+#endif
diff --git a/gammu/emb/common/phone/at/siemens.c b/gammu/emb/common/phone/at/siemens.c
index ab7dd2c..7f66cf8 100644
--- a/gammu/emb/common/phone/at/siemens.c
+++ b/gammu/emb/common/phone/at/siemens.c
@@ -10,31 +10,17 @@
#include "../../misc/coding/coding.h"
#include "../../gsmcomon.h"
#include "../../service/sms/gsmsms.h"
#include "../pfunc.h"
-extern GSM_Error ATGEN_HandleCMSError(GSM_StateMachine *s);
+#include "atgen.h"
+#include "siemens.h"
-GSM_Error ATGEN_CMS35ReplySetFunction (GSM_Protocol_Message msg, GSM_StateMachine *s,char *function)
-{
- if (s->Protocol.Data.AT.EditMode) {
- s->Protocol.Data.AT.EditMode = false;
- return ERR_NONE;
- }
- dbgprintf ("Written %s",function);
- if (s->Phone.Data.Priv.ATGEN.ReplyState == AT_Reply_OK){
- dbgprintf (" - OK\n");
- return ERR_NONE;
- } else {
- dbgprintf (" - error\n");
- return ERR_UNKNOWN;
- }
-}
-GSM_Error GetSiemensFrame(GSM_Protocol_Message msg, GSM_StateMachine *s, char *templ,
+static GSM_Error GetSiemensFrame(GSM_Protocol_Message msg, GSM_StateMachine *s, char *templ,
unsigned char *buffer, int *len)
{
GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
int i=2, pos=0, length=0;
unsigned char buf[512];
@@ -54,13 +40,13 @@ GSM_Error GetSiemensFrame(GSM_Protocol_Message msg, GSM_StateMachine *s, char *t
i++;
}
*len = pos;
return ERR_NONE;
}
-GSM_Error SetSiemensFrame (GSM_StateMachine *s, unsigned char *buff, char *templ,
+static GSM_Error SetSiemensFrame (GSM_StateMachine *s, unsigned char *buff, char *templ,
int Location, GSM_Phone_RequestID RequestID, int len)
{
GSM_Phone_Data *Phone = &s->Phone.Data;
GSM_Error error;
unsigned char req[20],req1[512],hexreq[2096];
int MaxFrame,CurrentFrame,size,sz,pos=0;
@@ -87,13 +73,13 @@ GSM_Error SetSiemensFrame (GSM_StateMachine *s, unsigned char *buff, char *templ
error = GSM_WaitForOnce(s, NULL, 0x00, 0x00, 4);
if (error == ERR_TIMEOUT) return error;
}
return Phone->DispatchError;
}
-GSM_Error ATGEN_CMS35ReplyGetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s)
+GSM_Error SIEMENS_ReplyGetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s)
{
unsigned char buffer[4096];
int length;
GSM_Error error;
error = GetSiemensFrame(msg,s,"bmp",buffer,&length);
@@ -101,50 +87,64 @@ GSM_Error ATGEN_CMS35ReplyGetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *
dbgprintf ("Operator logo received lenght=%i\n",length);
error = BMP2Bitmap (buffer,NULL,s->Phone.Data.Bitmap);
if (error==ERR_NONE) return error;
else return ERR_UNKNOWN;
}
-GSM_Error ATGEN_CMS35ReplySetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s)
+GSM_Error SIEMENS_ReplySetFunction (GSM_Protocol_Message msg, GSM_StateMachine *s,char *function)
{
- return ATGEN_CMS35ReplySetFunction (msg, s, "Operator Logo");
+ if (s->Protocol.Data.AT.EditMode) {
+ s->Protocol.Data.AT.EditMode = false;
+ return ERR_NONE;
+ }
+ dbgprintf ("Written %s",function);
+ if (s->Phone.Data.Priv.ATGEN.ReplyState == AT_Reply_OK){
+ dbgprintf (" - OK\n");
+ return ERR_NONE;
+ } else {
+ dbgprintf (" - error\n");
+ return ERR_UNKNOWN;
+ }
}
-GSM_Error ATGEN_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
+GSM_Error SIEMENS_ReplySetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s)
+{
+ return SIEMENS_ReplySetFunction (msg, s, "Operator Logo");
+}
+
+GSM_Error SIEMENS_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
{
unsigned char req[32];
- if (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED;
if (Bitmap->Type!=GSM_OperatorLogo) return ERR_NOTSUPPORTED;
if (Bitmap->Location-1 < 0) Bitmap->Location++;
s->Phone.Data.Bitmap=Bitmap;
sprintf(req, "AT^SBNR=\"bmp\",%i\r", Bitmap->Location-1);
smprintf(s, "Getting Bitmap\n");
return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetBitmap);
}
-GSM_Error ATGEN_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
+GSM_Error SIEMENS_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
{
unsigned char buffer[4096];
int length;
GSM_Error error;
- if (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED;
if (Bitmap->Type!=GSM_OperatorLogo) return ERR_NOTSUPPORTED;
error = Bitmap2BMP (buffer,NULL,Bitmap);
if (error!=ERR_NONE) return error;
length = 0x100 * buffer[3] + buffer[2];
buffer[58]=0xff; buffer[59]=0xff; buffer[60]=0xff;
if (Bitmap->Location-1 < 0) Bitmap->Location++;
s->Phone.Data.Bitmap=Bitmap;
return SetSiemensFrame(s, buffer,"bmp",Bitmap->Location-1,
ID_SetBitmap,length);
}
-GSM_Error ATGEN_CMS35ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s)
+GSM_Error SIEMENS_ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s)
{
unsigned char buffer[32];
int length;
GSM_Error error;
error = GetSiemensFrame(msg,s,"mid",s->Phone.Data.Ringtone->NokiaBinary.Frame,&length);
@@ -155,45 +155,41 @@ GSM_Error ATGEN_CMS35ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachine
s->Phone.Data.Ringtone->NokiaBinary.Length = length;
sprintf(buffer,"Individual");
EncodeUnicode (s->Phone.Data.Ringtone->Name,buffer,strlen(buffer));
return ERR_NONE;
}
-GSM_Error ATGEN_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone)
+GSM_Error SIEMENS_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone)
{
unsigned char req[32];
- if (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED;
-
s->Phone.Data.Ringtone=Ringtone;
sprintf(req, "AT^SBNR=\"mid\",%i\r", Ringtone->Location-1);
smprintf(s, "Getting RingTone\n");
return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetRingtone);
}
-GSM_Error ATGEN_CMS35ReplySetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s)
+GSM_Error SIEMENS_ReplySetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s)
{
- return ATGEN_CMS35ReplySetFunction (msg, s, "Ringtone");
+ return SIEMENS_ReplySetFunction (msg, s, "Ringtone");
}
-GSM_Error ATGEN_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength)
+GSM_Error SIEMENS_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength)
{
GSM_Phone_Data *Phone = &s->Phone.Data;
- if (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED;
-
if (Ringtone->Location==255) Ringtone->Location=1;
if (Ringtone->Location-1 > 1) return ERR_INVALIDLOCATION;
s->Phone.Data.Ringtone = Ringtone;
Phone->Ringtone = Ringtone;
return SetSiemensFrame(s, Ringtone->NokiaBinary.Frame,"mid",Ringtone->Location-1,
ID_SetRingtone,Ringtone->NokiaBinary.Length);
}
-GSM_Error ATGEN_CMS35ReplyGetNextCal(GSM_Protocol_Message msg, GSM_StateMachine *s)
+GSM_Error SIEMENS_ReplyGetNextCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s)
{
GSM_Phone_Data *Data = &s->Phone.Data;
GSM_CalendarEntry *Calendar = Data->Cal;
GSM_ToDoEntry ToDo;
GSM_Error error;
unsigned char buffer[354];
@@ -232,18 +228,18 @@ GSM_Error SIEMENS_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note,
if (Location > MAX_VCALENDAR_LOCATION) return ERR_EMPTY;
if (error==ERR_NONE) return error;
}
return error;
}
-GSM_Error ATGEN_CMS35ReplySetCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s)
+GSM_Error SIEMENS_ReplyAddCalendarNote(GSM_Protocol_Message msg, GSM_StateMachine *s)
{
- return ATGEN_CMS35ReplySetFunction (msg, s, "Calendar Note");
+ return SIEMENS_ReplySetFunction (msg, s, "Calendar Note");
}
-GSM_Error ATGEN_CMS35ReplyDeleteCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s)
+GSM_Error SIEMENS_ReplyDelCalendarNote(GSM_Protocol_Message msg, GSM_StateMachine *s)
{
GSM_Phone_Data *Data = &s->Phone.Data;
if (Data->Cal->Location > MAX_VCALENDAR_LOCATION) return ERR_UNKNOWN;
if (Data->Priv.ATGEN.ReplyState== AT_Reply_OK) {
@@ -280,13 +276,13 @@ GSM_Error SIEMENS_AddCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note)
error=GSM_EncodeVCALENDAR(req,&size,Note,true,Siemens_VCalendar);
return SetSiemensFrame (s,req,"vcs",Note->Location,ID_SetCalendarNote,size);
}
/* (c) by Timo Teras */
-GSM_Error ATGEN_SL45ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s)
+GSM_Error SIEMENS_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s)
{
#ifndef ENABLE_LGPL
GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
GSM_MemoryEntry *Memory = s->Phone.Data.Memory;
unsigned char buffer[500],buffer2[500];
diff --git a/gammu/emb/common/phone/at/sonyeric.c b/gammu/emb/common/phone/at/sonyeric.c
index 4b2670a..8eeb39b 100644
--- a/gammu/emb/common/phone/at/sonyeric.c
+++ b/gammu/emb/common/phone/at/sonyeric.c
@@ -8,23 +8,21 @@
#include <time.h>
#include <ctype.h>
#include "../../gsmcomon.h"
#include "../../misc/coding/coding.h"
-extern GSM_Reply_Function ATGENReplyFunctions[];
-extern GSM_Error ATGEN_DispatchMessage (GSM_StateMachine *s);
+#include "atgen.h"
+#include "sonyeric.h"
#ifdef GSM_ENABLE_OBEXGEN
-extern GSM_Reply_Function OBEXGENReplyFunctions[];
-extern GSM_Error OBEXGEN_GetFilePart (GSM_StateMachine *s, GSM_File *File);
-extern GSM_Error OBEXGEN_AddFilePart (GSM_StateMachine *s, GSM_File *File, int *Pos);
-extern GSM_Error OBEXGEN_Disconnect (GSM_StateMachine *s);
+#include "../obex/obexgen.h"
-#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX)
+extern GSM_Reply_Function OBEXGENReplyFunctions[];
+extern GSM_Reply_Function ATGENReplyFunctions[];
static GSM_Error SONYERIC_SetOBEXMode(GSM_StateMachine *s)
{
GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
GSM_Error error;
@@ -123,13 +121,13 @@ static GSM_Error SONYERIC_SetFile(GSM_StateMachine *s, unsigned char *FileName,
}
#endif
GSM_Error SONYERIC_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start)
{
-#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX)
+#ifdef GSM_ENABLE_OBEXGEN
GSM_Error error;
GSM_ToDoEntry ToDo;
int Pos, num, Loc;
GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
if (start) {
@@ -159,13 +157,13 @@ GSM_Error SONYERIC_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note,
return ERR_SOURCENOTAVAILABLE;
#endif
}
GSM_Error SONYERIC_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool start)
{
-#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX)
+#ifdef GSM_ENABLE_OBEXGEN
GSM_Error error;
GSM_CalendarEntry Calendar;
int Pos, num, Loc;
GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
if (Priv->Manufacturer!=AT_Ericsson) return ERR_NOTSUPPORTED;
@@ -198,13 +196,13 @@ GSM_Error SONYERIC_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool st
return ERR_SOURCENOTAVAILABLE;
#endif
}
GSM_Error SONYERIC_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status)
{
-#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX)
+#ifdef GSM_ENABLE_OBEXGEN
GSM_Error error;
GSM_ToDoEntry ToDo;
GSM_CalendarEntry Calendar;
int Pos;
GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
@@ -229,13 +227,13 @@ GSM_Error SONYERIC_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status)
return ERR_SOURCENOTAVAILABLE;
#endif
}
GSM_Error SONYERIC_AddCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note)
{
-#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX)
+#ifdef GSM_ENABLE_OBEXGEN
unsigned char req[5000];
int size=0;
smprintf(s,"Adding calendar note\n");
GSM_EncodeVCALENDAR(req,&size,Note,true,SonyEricsson_VCalendar);
@@ -245,13 +243,13 @@ GSM_Error SONYERIC_AddCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note)
return ERR_SOURCENOTAVAILABLE;
#endif
}
GSM_Error SONYERIC_AddToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
{
-#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX)
+#ifdef GSM_ENABLE_OBEXGEN
GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
unsigned char req[5000];
int size=0;
if (Priv->Manufacturer!=AT_Ericsson) return ERR_NOTSUPPORTED;
@@ -264,13 +262,13 @@ GSM_Error SONYERIC_AddToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
return ERR_SOURCENOTAVAILABLE;
#endif
}
GSM_Error SONYERIC_DeleteAllToDo(GSM_StateMachine *s)
{
-#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX)
+#ifdef GSM_ENABLE_OBEXGEN
GSM_Error error;
int Pos,Level = 0,Used;
unsigned char *Buf;
GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
unsigned char Line[2000];
@@ -316,13 +314,13 @@ GSM_Error SONYERIC_DeleteAllToDo(GSM_StateMachine *s)
return ERR_SOURCENOTAVAILABLE;
#endif
}
GSM_Error SONYERIC_DelCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note)
{
-#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX)
+#ifdef GSM_ENABLE_OBEXGEN
GSM_Error error;
int Pos,Level = 0,Loc=0,Used;
GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
unsigned char Line[2000];
unsigned char *Buf;
@@ -371,13 +369,13 @@ GSM_Error SONYERIC_DelCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note)
return ERR_SOURCENOTAVAILABLE;
#endif
}
GSM_Error SONYERIC_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *Status)
{
-#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX)
+#ifdef GSM_ENABLE_OBEXGEN
GSM_Error error;
GSM_ToDoEntry ToDo;
GSM_CalendarEntry Calendar;
int Pos;
GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
@@ -400,12 +398,123 @@ GSM_Error SONYERIC_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *St
return ERR_NONE;
#else
return ERR_SOURCENOTAVAILABLE;
#endif
}
-#endif
+GSM_Error ERICSSON_ReplyGetDateLocale(GSM_Protocol_Message msg, GSM_StateMachine *s)
+{ /* Author: Peter Ondraska, based on code by Marcin Wiacek and Michal Cihar
+ License: Whatever the current maintainer of gammulib chooses, as long as there
+ is an easy way to obtain the source under GPL, otherwise the author's parts
+ of this function are GPL 2.0.
+ */
+ GSM_Locale *locale = s->Phone.Data.Locale;
+ char format;
+
+ switch (s->Phone.Data.Priv.ATGEN.ReplyState) {
+ case AT_Reply_OK:
+ smprintf(s, "Date settings received\n");
+ format=atoi(msg.Buffer);
+ switch (format) {
+ case 0: locale->DateFormat = GSM_Date_OFF;
+ locale->DateSeparator = 0;
+ break;
+ case 1: locale->DateFormat = GSM_Date_DDMMMYY;
+ locale->DateSeparator = '-';
+ break;
+ case 2: locale->DateFormat = GSM_Date_DDMMYY;
+ locale->DateSeparator = '-';
+ break;
+ case 3: locale->DateFormat = GSM_Date_MMDDYY;
+ locale->DateSeparator = '/';
+ break;
+ case 4: locale->DateFormat = GSM_Date_DDMMYY;
+ locale->DateSeparator = '/';
+ break;
+ case 5: locale->DateFormat = GSM_Date_DDMMYY;
+ locale->DateSeparator = '.';
+ break;
+ case 6: locale->DateFormat = GSM_Date_YYMMDD;
+ locale->DateSeparator = 0;
+ break;
+ case 7: locale->DateFormat = GSM_Date_YYMMDD;
+ locale->DateSeparator = '-';
+ break;
+ default:return ERR_UNKNOWNRESPONSE;
+ }
+ default:
+ return ERR_NOTSUPPORTED;
+ }
+}
+
+GSM_Error ERICSSON_ReplyGetTimeLocale(GSM_Protocol_Message msg, GSM_StateMachine *s)
+{ /* Author: Peter Ondraska
+ License: Whatever the current maintainer of gammulib chooses, as long as there
+ is an easy way to obtain the source under GPL, otherwise the author's parts
+ of this function are GPL 2.0.
+ */
+ char format;
+
+ switch (s->Phone.Data.Priv.ATGEN.ReplyState) {
+ case AT_Reply_OK:
+ smprintf(s, "Time settings received\n");
+ format=atoi(msg.Buffer);
+ switch (format) {
+ case 1:
+ case 2: s->Phone.Data.Locale->AMPMTime=(format==2);
+ return ERR_NONE;
+ default:return ERR_UNKNOWNRESPONSE;
+ }
+ default: return ERR_NOTSUPPORTED;
+ }
+}
+
+GSM_Error ERICSSON_GetLocale(GSM_StateMachine *s, GSM_Locale *locale)
+{
+ GSM_Error error;
+
+ s->Phone.Data.Locale = locale;
+
+ smprintf(s, "Getting date format\n");
+ error=GSM_WaitFor (s, "AT+ESDF?\r", 9, 0x00, 3, ID_GetLocale);
+ if (error!=ERR_NONE) return error;
+
+ smprintf(s, "Getting time format\n");
+ return GSM_WaitFor (s, "AT+ESTF?\r", 9, 0x00, 3, ID_GetLocale);
+}
+
+
+GSM_Error ERICSSON_SetLocale(GSM_StateMachine *s, GSM_Locale *locale)
+{ /* Author: Peter Ondraska
+ License: Whatever the current maintainer of gammulib chooses, as long as there
+ is an easy way to obtain the source under GPL, otherwise the author's parts
+ of this function are GPL 2.0.
+ */
+ /* this is not yet supported by gammu.c */
+ int format=0;
+ char req[12];
+
+ if (locale->DateFormat==GSM_Date_OFF) { format=0; } else
+ if ((locale->DateFormat==GSM_Date_DDMMMYY)&&(locale->DateSeparator=='-')) { format=1; } else
+ if ((locale->DateFormat==GSM_Date_DDMMYY)&&(locale->DateSeparator=='-')) { format=2; } else
+ if ((locale->DateFormat==GSM_Date_MMDDYY)&&(locale->DateSeparator=='/')) { format=3; } else
+ if ((locale->DateFormat==GSM_Date_DDMMYY)&&(locale->DateSeparator=='/')) { format=4; } else
+ if ((locale->DateFormat==GSM_Date_DDMMYY)&&(locale->DateSeparator=='.')) { format=5; } else
+ if ((locale->DateFormat==GSM_Date_YYMMDD)&&(locale->DateSeparator==0)) { format=6; } else
+ if ((locale->DateFormat==GSM_Date_YYMMDD)&&(locale->DateSeparator=='-')) { format=7; }
+ else { return ERR_NOTSUPPORTED; } /* ERR_WRONGINPUT */
+
+ sprintf(req,"AT+ESDF=%i\r",format);
+ smprintf(s, "Setting date format\n");
+ return GSM_WaitFor (s, req, strlen(req), 0x00, 3, ID_SetLocale);
+
+ if (locale->AMPMTime) { format=2; } else { format=1; }
+ sprintf(req,"AT+ESTF=%i\r",format);
+ smprintf(s, "Setting time format\n");
+ return GSM_WaitFor (s, req, strlen(req), 0x00, 3, ID_SetLocale);
+}
+
#endif
/* How should editor hadle tabs in this file? Add editor commands here.
* vim: noexpandtab sw=8 ts=8 sts=8:
*/