/* (c) 2006 by Michal Cihar */ /** * \file atobex.c * @author Michal Čihař */ /** * @addtogroup Phone * @{ */ /** * \defgroup SEPhone Sony-Ericsson phones communication * High level functions for communication with Sony-Ericsson phones. * * This module heavily uses \ref ATPhone and \ref OBEXPhone modules. * * @{ */ #include "../../gsmstate.h" #ifdef GSM_ENABLE_ATOBEX #ifdef GSM_ENABLE_ATGEN #include #include #include "../../gsmcomon.h" #include "../../misc/coding/coding.h" #include "../../misc/misc.h" #include "../pfunc.h" #include "../at/atfunc.h" #include "../at/sonyericsson.h" #include "../obex/obexfunc.h" #include "atobex.h" extern GSM_Reply_Function ATOBEXReplyFunctions[]; /** * Ensures phone and Gammu protocol are switched to AT commands mode. */ GSM_Error ATOBEX_SetATMode(GSM_StateMachine *s) { GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; GSM_Error error; /* Aren't we in OBEX mode? */ if (Priv->Mode == ATOBEX_ModeAT) return ERR_NONE; smprintf(s, "Terminating OBEX\n"); /* Disconnect from OBEX service */ error = OBEXGEN_Disconnect(s); if (error != ERR_NONE) return error; /* Terminate OBEX protocol */ error = s->Protocol.Functions->Terminate(s); if (error != ERR_NONE) return error; /* Switch to AT protocol */ smprintf(s, "Changing protocol to AT\n"); s->Protocol.Functions = &ATProtocol; s->Phone.Functions->ReplyFunctions = ATGENReplyFunctions; Priv->Mode = ATOBEX_ModeAT; /* Terminate SQWE Obex mode */ if (Priv->HasOBEX == ATOBEX_OBEX_SQWE) { sleep(1); error = GSM_WaitFor (s, "+++", 3, 0x00, 100, ID_IncomingFrame); if (error != ERR_NONE) return error; } /* Give Samsung phones some time to recover from protocol switch */ if (Priv->HasOBEX == ATOBEX_OBEX_MOBEX || Priv->HasOBEX == ATOBEX_OBEX_TSSPCSW) { sleep(2); } /* Initialise AT protocol */ error = s->Protocol.Functions->Initialise(s); if (error != ERR_NONE) return error; return ERR_NONE; } /** * Ensures phone and Gammu protocol are in OBEX mode, in IrMC service * if requrested. */ GSM_Error ATOBEX_SetOBEXMode(GSM_StateMachine *s, OBEX_Service service) { GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; GSM_Error error; /* Is OBEX mode supported? */ if (Priv->HasOBEX == ATOBEX_OBEX_None) { return ERR_NOTSUPPORTED; } /* Are we already in OBEX mode? */ if (Priv->Mode == ATOBEX_ModeOBEX) { /* We can not safely switch service, we need to disconnect instead */ if (s->Phone.Data.Priv.OBEXGEN.Service == service) { return ERR_NONE; } else { error = ATOBEX_SetATMode(s); } if (error != ERR_NONE) return error; } smprintf(s, "Changing to OBEX mode\n"); /* Switch phone to OBEX */ error = ERR_NOTSUPPORTED; switch (Priv->HasOBEX) { case ATOBEX_OBEX_CPROT0: /* 3GPP TS 27.007 standard */ error = GSM_WaitFor (s, "AT+CPROT=0\r", 11, 0x00, 100, ID_SetOBEX); break; case ATOBEX_OBEX_EOBEX: /* Sony-Ericsson extension */ error = GSM_WaitFor (s, "AT*EOBEX\r", 9, 0x00, 100, ID_SetOBEX); break; case ATOBEX_OBEX_MODE22: /* Motorola extension */ error = GSM_WaitFor (s, "AT+MODE=22\r", 11, 0x00, 20, ID_SetOBEX); break; case ATOBEX_OBEX_XLNK: /* Sharp extension */ error = GSM_WaitFor (s, "AT+XLNK\r", 8, 0x00, 20, ID_SetOBEX); break; case ATOBEX_OBEX_SQWE: /* Siemens extension */ error = GSM_WaitFor (s, "AT^SQWE=3\r", 10, 0x00, 20, ID_SetOBEX); break; case ATOBEX_OBEX_MOBEX: /* Samsung extension */ error = GSM_WaitFor (s, "AT+SYNCML=MOBEXSTART\r", 21, 0x00, 20, ID_SetOBEX); break; case ATOBEX_OBEX_TSSPCSW: /* Samsung extension */ error = GSM_WaitFor (s, "AT$TSSPCSW=1\r", 13, 0x00, 20, ID_SetOBEX); break; case ATOBEX_OBEX_None: break; } if (error != ERR_NONE) return error; /* Tell OBEX module it has no service selected */ s->Phone.Data.Priv.OBEXGEN.Service = 0; smprintf(s, "Changing protocol to OBEX\n"); /* Stop AT protocol */ error = s->Protocol.Functions->Terminate(s); if (error != ERR_NONE) return error; /* Need some sleep before starting talk in OBEX */ sleep(1); /* Switch to OBEX protocol and initialise it */ s->Protocol.Functions = &OBEXProtocol; s->Phone.Functions->ReplyFunctions = OBEXGENReplyFunctions; /* Initialise protocol */ error = s->Protocol.Functions->Initialise(s); if (error != ERR_NONE) { /* Revert back to AT */ s->Protocol.Functions = &ATProtocol; return error; } /* Remember our state */ Priv->Mode = ATOBEX_ModeOBEX; /* Choose appropriate connection type (we need different for filesystem and for IrMC) */ smprintf(s, "Setting service %d\n", service); error = OBEXGEN_Connect(s, service); if (error != ERR_NONE) return error; return ERR_NONE; } /** * Initialises Sony-Ericsson module internals and calls AT module init. */ GSM_Error ATOBEX_Initialise(GSM_StateMachine *s) { GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; GSM_Phone_ATGENData *PrivAT = &s->Phone.Data.Priv.ATGEN; GSM_Error error; Priv->Mode = ATOBEX_ModeAT; Priv->EBCAFailed = FALSE; /* We might receive incoming event */ s->Phone.Data.BatteryCharge = NULL; /* Init OBEX module also */ error = OBEXGEN_InitialiseVars(s); if (error != ERR_NONE) return error; /* This can be filled in by AT module init */ Priv->HasOBEX = ATOBEX_OBEX_None; Priv->DataService = OBEX_None; /* Init AT module */ /* This also enables ATOBEX_OBEX_CPROT0 if available */ error = ATGEN_Initialise(s); if (error != ERR_NONE) return error; /* Does phone have support for AT+MODE=22 switching? */ if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_MODE22)) { Priv->HasOBEX = ATOBEX_OBEX_MODE22; Priv->DataService = OBEX_IRMC; } else if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_XLNK)) { Priv->HasOBEX = ATOBEX_OBEX_XLNK; Priv->DataService = OBEX_IRMC; } else if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SQWE)) { Priv->HasOBEX = ATOBEX_OBEX_SQWE; Priv->DataService = OBEX_IRMC; } else if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CPROT)) { Priv->HasOBEX = ATOBEX_OBEX_CPROT0; Priv->DataService = OBEX_IRMC; } else if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_MOBEX)) { Priv->HasOBEX = ATOBEX_OBEX_MOBEX; Priv->DataService = OBEX_m_OBEX; } else if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TSSPCSW)) { Priv->HasOBEX = ATOBEX_OBEX_TSSPCSW; Priv->DataService = OBEX_m_OBEX; } else { if (PrivAT->Mode) { smprintf(s, "Guessed mode style switching\n"); Priv->HasOBEX = ATOBEX_OBEX_MODE22; Priv->DataService = OBEX_IRMC; } } /* Do we have OBEX capability? */ if (Priv->HasOBEX == ATOBEX_OBEX_None) { error = GSM_WaitFor (s, "AT*EOBEX=?\r", 11, 0x00, 4, ID_SetOBEX); if (error == ERR_NONE) { Priv->HasOBEX = ATOBEX_OBEX_EOBEX; Priv->DataService = OBEX_IRMC; } } return ERR_NONE; } /** * Switch to AT mode and calls AT module termination procedure. */ GSM_Error ATOBEX_Terminate(GSM_StateMachine *s) { GSM_Error error; error = ATOBEX_SetATMode(s); if (error != ERR_NONE) return error; OBEXGEN_FreeVars(s); return ATGEN_Terminate(s); } /** * Dispatches message to correct dispatcher according to active protocol */ GSM_Error ATOBEX_DispatchMessage(GSM_StateMachine *s) { if (s->Phone.Data.Priv.ATOBEX.Mode == ATOBEX_ModeOBEX) { return GSM_DispatchMessage(s); } else { return ATGEN_DispatchMessage(s); } } /** * We receive product code over AT commands, so we can easily use it */ GSM_Error ATOBEX_GetProductCode(GSM_StateMachine *s, char *value) { strcpy(value, s->Phone.Data.Model); return ERR_NONE; } /** * \defgroup SEAT Wrapper functions for using AT module functionality * \ingroup SEPhone * @{ */ GSM_Error ATOBEX_GetIMEI (GSM_StateMachine *s) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetIMEI(s); } GSM_Error ATOBEX_GetFirmware(GSM_StateMachine *s) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetFirmware(s); } GSM_Error ATOBEX_GetModel(GSM_StateMachine *s) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetModel(s); } GSM_Error ATOBEX_GetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetDateTime(s, date_time); } GSM_Error ATOBEX_GetSMS(GSM_StateMachine *s, GSM_MultiSMSMessage *sms) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetSMS(s, sms); } GSM_Error ATOBEX_DeleteSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_DeleteSMS(s, sms); } GSM_Error ATOBEX_AddSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_AddSMS(s, sms); } GSM_Error ATOBEX_GetSignalStrength(GSM_StateMachine *s, GSM_SignalQuality *sig) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetSignalQuality(s, sig); } GSM_Error ATOBEX_GetSMSFolders(GSM_StateMachine *s, GSM_SMSFolders *folders) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetSMSFolders(s, folders); } GSM_Error ATOBEX_GetNextSMS(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, gboolean start) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetNextSMS(s, sms, start); } GSM_Error ATOBEX_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *status) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetSMSStatus(s, status); } GSM_Error ATOBEX_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_DialVoice(s, number, ShowNumber); } GSM_Error ATOBEX_DialService(GSM_StateMachine *s, char *number) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_DialService(s, number); } GSM_Error ATOBEX_AnswerCall(GSM_StateMachine *s, int ID, gboolean all) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_AnswerCall(s,ID,all); } GSM_Error ATOBEX_GetNetworkInfo(GSM_StateMachine *s, GSM_NetworkInfo *netinfo) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetNetworkInfo(s, netinfo); } GSM_Error ATOBEX_GetDisplayStatus(GSM_StateMachine *s, GSM_DisplayFeatures *features) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetDisplayStatus(s, features); } GSM_Error ATOBEX_SetAutoNetworkLogin(GSM_StateMachine *s) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetAutoNetworkLogin(s); } GSM_Error ATOBEX_PressKey(GSM_StateMachine *s, GSM_KeyCode Key, gboolean Press) { GSM_Error error; /** * @todo Implement completely using AT*EKEY */ if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_PressKey(s, Key, Press); } GSM_Error ATOBEX_Reset(GSM_StateMachine *s, gboolean hard) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_Reset(s, hard); } GSM_Error ATOBEX_CancelCall(GSM_StateMachine *s, int ID, gboolean all) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_CancelCall(s,ID,all); } GSM_Error ATOBEX_SendSavedSMS(GSM_StateMachine *s, int Folder, int Location) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SendSavedSMS(s, Folder, Location); } GSM_Error ATOBEX_SendSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SendSMS(s, sms); } GSM_Error ATOBEX_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetDateTime(s, date_time); } GSM_Error ATOBEX_SetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetSMSC(s, smsc); } GSM_Error ATOBEX_GetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetSMSC(s, smsc); } GSM_Error ATOBEX_EnterSecurityCode(GSM_StateMachine *s, GSM_SecurityCode *Code) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_EnterSecurityCode(s, Code); } GSM_Error ATOBEX_GetSecurityStatus(GSM_StateMachine *s, GSM_SecurityCodeType *Status) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetSecurityStatus(s, Status); } GSM_Error ATOBEX_ResetPhoneSettings(GSM_StateMachine *s, GSM_ResetSettingsType Type) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_ResetPhoneSettings(s, Type); } GSM_Error ATOBEX_SendDTMF(GSM_StateMachine *s, char *sequence) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SendDTMF(s, sequence); } GSM_Error ATOBEX_GetSIMIMSI(GSM_StateMachine *s, char *IMSI) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetSIMIMSI(s, IMSI); } GSM_Error ATOBEX_SetIncomingCall (GSM_StateMachine *s, gboolean enable) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetIncomingCall(s, enable); } GSM_Error ATOBEX_SetIncomingCB (GSM_StateMachine *s, gboolean enable) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetIncomingCB(s, enable); } GSM_Error ATOBEX_SetIncomingSMS (GSM_StateMachine *s, gboolean enable) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetIncomingSMS(s, enable); } GSM_Error ATOBEX_SetFastSMSSending(GSM_StateMachine *s, gboolean enable) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetFastSMSSending(s, enable); } GSM_Error ATOBEX_GetManufacturer(GSM_StateMachine *s) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetManufacturer(s); } GSM_Error ATOBEX_GetAlarm(GSM_StateMachine *s, GSM_Alarm *Alarm) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetAlarm(s, Alarm); } GSM_Error ATOBEX_SetAlarm(GSM_StateMachine *s, GSM_Alarm *Alarm) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetAlarm(s, Alarm); } GSM_Error ATOBEX_SetIncomingUSSD(GSM_StateMachine *s, gboolean enable) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetIncomingUSSD(s, enable); } GSM_Error ATOBEX_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, gboolean PhoneRingtone) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetRingtone(s, Ringtone, PhoneRingtone); } GSM_Error ATOBEX_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetRingtone(s, Ringtone, maxlength); } GSM_Error ATOBEX_SetPower(GSM_StateMachine *s, gboolean on) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetPower(s, on); } GSM_Error ATOBEX_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetBitmap(s, Bitmap); } GSM_Error ATOBEX_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetBitmap(s, Bitmap); } /*@}*/ /** * \defgroup SEOBEX OBEX native functions for filesystem * \ingroup SEPhone * @{ */ GSM_Error ATOBEX_AddFilePart(GSM_StateMachine *s, GSM_File *File, size_t *Pos, int *Handle) { GSM_Error error; error = ATOBEX_SetOBEXMode(s, OBEX_BrowsingFolders); if (error != ERR_NONE) { return error; } return OBEXGEN_AddFilePart(s, File, Pos, Handle); } GSM_Error ATOBEX_SendFilePart(GSM_StateMachine *s, GSM_File *File, size_t *Pos, int *Handle) { GSM_Error error; error = ATOBEX_SetOBEXMode(s, OBEX_None); if (error != ERR_NONE) { return error; } return OBEXGEN_SendFilePart(s, File, Pos, Handle); } GSM_Error ATOBEX_GetFilePart(GSM_StateMachine *s, GSM_File *File, int *Handle, size_t *Size) { GSM_Error error; error = ATOBEX_SetOBEXMode(s, OBEX_BrowsingFolders); if (error != ERR_NONE) { return error; } return OBEXGEN_GetFilePart(s, File, Handle, Size); } GSM_Error ATOBEX_GetNextFileFolder(GSM_StateMachine *s, GSM_File *File, gboolean start) { GSM_Error error; error = ATOBEX_SetOBEXMode(s, OBEX_BrowsingFolders); if (error != ERR_NONE) { return error; } return OBEXGEN_GetNextFileFolder(s, File, start); } GSM_Error ATOBEX_DeleteFile(GSM_StateMachine *s, unsigned char *ID) { GSM_Error error; error = ATOBEX_SetOBEXMode(s, OBEX_BrowsingFolders); if (error != ERR_NONE) { return error; } return OBEXGEN_DeleteFile(s, ID); } GSM_Error ATOBEX_AddFolder(GSM_StateMachine *s, GSM_File *File) { GSM_Error error; error = ATOBEX_SetOBEXMode(s, OBEX_BrowsingFolders); if (error != ERR_NONE) { return error; } return OBEXGEN_AddFolder(s, File); } /*@}*/ static int ATOBEX_UseObex (GSM_StateMachine *s, GSM_MemoryType type) { GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; if (type == MEM_ME) { return 1; } if (type != MEM_SM) { return 0; } if (Priv->HasOBEX == ATOBEX_OBEX_MOBEX || Priv->HasOBEX == ATOBEX_OBEX_TSSPCSW) { return 1; } return 0; } /** * \defgroup SEATIrMC Mixed AT mode/IrMC functions * \ingroup SEPhone * @{ */ GSM_Error ATOBEX_GetMemoryStatus(GSM_StateMachine *s, GSM_MemoryStatus *Status) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; if (ATOBEX_UseObex (s, Status->MemoryType)) { error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { goto atgen; } return OBEXGEN_GetMemoryStatus(s, Status); } atgen: error = ATOBEX_SetATMode(s); if (error != ERR_NONE) { return error; } return ATGEN_GetMemoryStatus(s, Status); } GSM_Error ATOBEX_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; if (ATOBEX_UseObex (s, entry->MemoryType)) { error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { goto atgen; } return OBEXGEN_GetMemory(s, entry); } atgen: error = ATOBEX_SetATMode(s); if (error != ERR_NONE) { return error; } return ATGEN_GetMemory(s, entry); } GSM_Error ATOBEX_GetNextMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry, gboolean start) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; if (ATOBEX_UseObex (s, entry->MemoryType)) { error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { goto atgen; } return OBEXGEN_GetNextMemory(s, entry, start); } atgen: error = ATOBEX_SetATMode(s); if (error != ERR_NONE) { return error; } return ATGEN_GetNextMemory(s, entry, start); } GSM_Error ATOBEX_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; if (ATOBEX_UseObex (s, entry->MemoryType)) { error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { goto atgen; } return OBEXGEN_SetMemory(s, entry); } atgen: error = ATOBEX_SetATMode(s); if (error != ERR_NONE) { return error; } return ATGEN_SetMemory(s, entry); } GSM_Error ATOBEX_AddMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; if (ATOBEX_UseObex (s, entry->MemoryType)) { error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { goto atgen; } return OBEXGEN_AddMemory(s, entry); } atgen: error = ATOBEX_SetATMode(s); if (error != ERR_NONE) { return error; } return ATGEN_AddMemory(s, entry); } GSM_Error ATOBEX_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; if (ATOBEX_UseObex (s, entry->MemoryType)) { error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { goto atgen; } return OBEXGEN_DeleteMemory(s, entry); } atgen: error = ATOBEX_SetATMode(s); if (error != ERR_NONE) { return error; } return ATGEN_DeleteMemory(s, entry); } GSM_Error ATOBEX_DeleteAllMemory(GSM_StateMachine *s, GSM_MemoryType type) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; if (ATOBEX_UseObex (s, type)) { error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { goto atgen; } return OBEXGEN_DeleteAllMemory(s, type); } atgen: error = ATOBEX_SetATMode(s); if (error != ERR_NONE) { return error; } return ATGEN_DeleteAllMemory(s, type); } /*@}*/ /** * \defgroup SEIrMC Native IrMC functions using OBEX connection * \ingroup SEPhone * @{ */ GSM_Error ATOBEX_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_GetTodoStatus(s, status); } GSM_Error ATOBEX_GetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_GetTodo(s, ToDo); } GSM_Error ATOBEX_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, gboolean start) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_GetNextTodo(s, ToDo, start); } GSM_Error ATOBEX_DeleteAllToDo (GSM_StateMachine *s) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_DeleteAllTodo(s); } GSM_Error ATOBEX_AddToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_AddTodo(s, ToDo); } GSM_Error ATOBEX_SetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_SetTodo(s, ToDo); } GSM_Error ATOBEX_DeleteToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_DeleteTodo(s, ToDo); } GSM_Error ATOBEX_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *status) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_GetCalendarStatus(s, status); } GSM_Error ATOBEX_GetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_GetCalendar(s, Note); } GSM_Error ATOBEX_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, gboolean start) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_GetNextCalendar(s, Note, start); } GSM_Error ATOBEX_DeleteCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_DeleteCalendar(s, Note); } GSM_Error ATOBEX_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_AddCalendar(s, Note); } GSM_Error ATOBEX_SetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_SetCalendar(s, Note); } GSM_Error ATOBEX_DeleteAllCalendar (GSM_StateMachine *s) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_DeleteAllCalendar(s); } GSM_Error ATOBEX_GetNoteStatus(GSM_StateMachine *s, GSM_ToDoStatus *status) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_GetNoteStatus(s, status); } GSM_Error ATOBEX_GetNote (GSM_StateMachine *s, GSM_NoteEntry *Note) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_GetNote(s, Note); } GSM_Error ATOBEX_GetNextNote(GSM_StateMachine *s, GSM_NoteEntry *Note, gboolean start) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_GetNextNote(s, Note, start); } GSM_Error ATOBEX_DeleteAllNotes(GSM_StateMachine *s) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_DeleteAllNotes(s); } GSM_Error ATOBEX_AddNote (GSM_StateMachine *s, GSM_NoteEntry *Note) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_AddNote(s, Note); } GSM_Error ATOBEX_SetNote (GSM_StateMachine *s, GSM_NoteEntry *Note) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_SetNote(s, Note); } GSM_Error ATOBEX_DeleteNote (GSM_StateMachine *s, GSM_NoteEntry *Note) { GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; error = ATOBEX_SetOBEXMode(s, Priv->DataService); if (error != ERR_NONE) { return error; } return OBEXGEN_DeleteNote(s, Note); } /*@}*/ /** * \defgroup SENativeAT Native AT mode functions * \ingroup SEPhone * @{ */ /** * \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_Error ATOBEX_ReplyGetDateLocale(GSM_Protocol_Message *msg, GSM_StateMachine *s) { GSM_Locale *locale = s->Phone.Data.Locale; int format; char *pos; switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: smprintf(s, "Date settings received\n"); pos = strstr(msg->Buffer, "*ESDF:"); if (pos == NULL) return ERR_UNKNOWNRESPONSE; format = atoi(pos + 7); 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; } return ERR_NONE; default:return ERR_NOTSUPPORTED; } } /** * \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_Error ATOBEX_ReplyGetTimeLocale(GSM_Protocol_Message *msg, GSM_StateMachine *s) { int format; char *pos; switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: smprintf(s, "Time settings received\n"); pos = strstr(msg->Buffer, "*ESTF:"); if (pos == NULL) return ERR_UNKNOWNRESPONSE; format = atoi(pos + 7); switch (format) { case 1: case 2: s->Phone.Data.Locale->AMPMTime=(format==2); return ERR_NONE; default:return ERR_UNKNOWNRESPONSE; } default: return ERR_NOTSUPPORTED; } } /** * \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_Error ATOBEX_GetLocale(GSM_StateMachine *s, GSM_Locale *locale) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return 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); } /** * \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_Error ATOBEX_SetLocale(GSM_StateMachine *s, GSM_Locale *locale) { /* this is not yet supported by gammu.c */ int format=0; char req[12]; GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; 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"); error = GSM_WaitFor (s, req, strlen(req), 0x00, 3, ID_SetLocale); if (error!=ERR_NONE) return error; 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); } GSM_Error ATOBEX_ReplyGetFileSystemStatus(GSM_Protocol_Message *msg, GSM_StateMachine *s) { GSM_Error error; switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: error = ATGEN_ParseReply(s, GetLineString(msg->Buffer, &s->Phone.Data.Priv.ATGEN.Lines, 2), "*EMEM: @i, @i, @i, @i, @i", &s->Phone.Data.FileSystemStatus->Free, &s->Phone.Data.FileSystemStatus->Used, &s->Phone.Data.FileSystemStatus->UsedImages, &s->Phone.Data.FileSystemStatus->UsedSounds, &s->Phone.Data.FileSystemStatus->UsedThemes ); if (error == ERR_NONE) { /* This is actually total */ s->Phone.Data.FileSystemStatus->Used -= s->Phone.Data.FileSystemStatus->Free; return ERR_NONE; } return error; default: return ERR_NOTSUPPORTED; } } GSM_Error ATOBEX_GetFileSystemStatus(GSM_StateMachine *s, GSM_FileSystemStatus *Status) { GSM_Error error; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; s->Phone.Data.FileSystemStatus = Status; return GSM_WaitFor (s, "AT*EMEM\r", 8, 0x00, 3, ID_FileSystemStatus); } GSM_Error ATOBEX_ReplyGetBatteryCharge(GSM_Protocol_Message *msg, GSM_StateMachine *s) { int tmp, ncapacity, method, state; int vbat1, vbat2, vbat3, vbat4; GSM_Error error; GSM_BatteryCharge *bat = s->Phone.Data.BatteryCharge; if (bat == NULL) { smprintf(s, "Battery status received, but not requested right now\n"); return ERR_NONE; } smprintf(s, "Battery status received\n"); /* Parse version 4 reply */ error = ATGEN_ParseReply(s, msg->Buffer, "*EBCA: @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i\xd\xa", &bat->BatteryVoltage, /* vbat */ &bat->ChargeVoltage, /* dcio */ &bat->ChargeCurrent, /* iocharge */ &bat->PhoneCurrent, /* iphone */ &bat->BatteryTemperature, /* tempbattery */ &bat->PhoneTemperature, /* tempphone */ &method, /* chargingmethod, used to determine battery type */ &state, /* chargestate */ &bat->BatteryCapacity, /* remcapacity */ &bat->BatteryPercent, /* remcapacitypercent */ &tmp, /* powerdissipation */ &tmp, /* noccycles */ &tmp, /* nosostimer */ &tmp /* suspensioncause */ ); /* Did we suceed? */ if (error == ERR_NONE) { /* Posprocess fields that need it */ bat->ChargeCurrent /= 10; bat->PhoneCurrent /= 10; switch (method) { case 0: bat->BatteryType = GSM_BatteryLiPol; break; case 1: bat->BatteryType = GSM_BatteryLiIon; break; case 2: bat->BatteryType = GSM_BatteryNiMH; break; default: bat->BatteryType = GSM_BatteryUnknown; break; } switch (state) { case 7: bat->ChargeState = GSM_BatteryPowered; break; case 2: bat->ChargeState = GSM_BatteryCharging; break; case 0: case 3: case 4: case 5: case 15: bat->ChargeState = GSM_BatteryConnected; break; case 8: bat->ChargeState = GSM_BatteryFull; break; } s->Phone.Data.BatteryCharge = NULL; return ERR_NONE; } /* Parse version 2 reply */ error = ATGEN_ParseReply(s, msg->Buffer, "*EBCA: @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i\xd\xa", &vbat1, /* vbat1 */ &vbat2, /* vbat2 */ &vbat3, /* vbat3 */ &vbat4, /* vbat4 */ &method, /* btype */ &bat->ChargeVoltage, /* dcio */ &bat->ChargeCurrent, /* iocharge */ &bat->PhoneCurrent, /* iphone */ &tmp, /* acapacity */ &tmp, /* ccapacity */ &tmp, /* pcapacity */ &ncapacity, /* ncapacity */ &bat->BatteryTemperature, /* tempbattery */ &bat->PhoneTemperature, /* tempphone */ &state, /* chargestate */ &bat->BatteryPercent, /* remcapacitypercent */ &tmp, /* cycles */ &tmp, /* ipulse */ &tmp, /* ibattery */ &tmp, /* ChTempMax */ &tmp, /* ChTempMin */ &tmp, /* MainChTempMax */ &tmp, /* MainChTempMin */ &tmp, /* FlatVTimer */ &tmp, /* DV */ &tmp, /* DT */ &tmp /* D2V */ ); /* Did we suceed? */ if (error == ERR_NONE) { /* Posprocess fields that need it */ if (vbat4 > 0) { bat->BatteryVoltage = vbat4; } else if (vbat3 > 0) { bat->BatteryVoltage = vbat3; } else if (vbat2 > 0) { bat->BatteryVoltage = vbat2; } else if (vbat1 > 0) { bat->BatteryVoltage = vbat1; } bat->ChargeVoltage *= 10; switch (method) { case 0: bat->BatteryType = GSM_BatteryNiMH; break; case 1: bat->BatteryType = GSM_BatteryLiIon; break; case 2: default: bat->BatteryType = GSM_BatteryUnknown; break; } switch (state) { case 3: bat->ChargeState = GSM_BatteryPowered; break; case 0: case 1: case 2: bat->ChargeState = GSM_BatteryCharging; break; case 4: case 5: case 6: case 7: case 8: bat->ChargeState = GSM_BatteryFull; break; } /* Calculate remaining capacity */ bat->BatteryCapacity = 1000 * ncapacity / bat->BatteryPercent; s->Phone.Data.BatteryCharge = NULL; return ERR_NONE; } smprintf(s, "Unsupported battery status format, you're welcome to help with implementation\n"); s->Phone.Data.BatteryCharge = NULL; return ERR_NOTIMPLEMENTED; } GSM_Error ATOBEX_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge *bat) { GSM_Error error, error2; int i = 0; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; s->Phone.Data.BatteryCharge = bat; if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; /* Go to AT if EBCA does not work */ if (Priv->EBCAFailed) { return ATGEN_GetBatteryCharge(s, bat); } /* Now try ericsson extended reporting */ error = GSM_WaitFor (s, "AT*EBCA=1\r", 10, 0x00, 3, ID_GetBatteryCharge); if (error != ERR_NONE) { Priv->EBCAFailed = TRUE; /* Ty ATGEN state */ return ATGEN_GetBatteryCharge(s, bat); } /* Wait for async phone reply */ while (s->Phone.Data.BatteryCharge != NULL) { error = GSM_WaitFor (s, "AT\r", 3, 0x00, 3, ID_GetBatteryCharge); smprintf(s, "Loop %d, error %d\n", i, error); if (i == 20) break; if (error != ERR_NONE) { break; } i++; } /* Disable reading information */ error2 = GSM_WaitFor (s, "AT*EBCA=0\r", 10, 0x00, 3, ID_GetBatteryCharge); if (error2 != ERR_NONE) { return error; } /* If something failed, do AT way */ if (error != ERR_NONE) { return ATGEN_GetBatteryCharge(s, bat); } /* Did we timeout? */ if (i == 20) return ERR_TIMEOUT; return error; } /*@}*/ GSM_Phone_Functions ATOBEXPhone = { /* There is much more SE phones which support this! */ "sonyericsson|ericsson|atobex", ATGENReplyFunctions, NOTSUPPORTED, /* Install */ ATOBEX_Initialise, ATOBEX_Terminate, ATOBEX_DispatchMessage, NOTSUPPORTED, /* ShowStartInfo */ ATOBEX_GetManufacturer, ATOBEX_GetModel, ATOBEX_GetFirmware, ATOBEX_GetIMEI, NOTSUPPORTED, /* GetOriginalIMEI */ NOTSUPPORTED, /* GetManufactureMonth */ ATOBEX_GetProductCode, NOTSUPPORTED, /* GetHardware */ NOTSUPPORTED, /* GetPPM */ ATOBEX_GetSIMIMSI, ATOBEX_GetDateTime, ATOBEX_SetDateTime, ATOBEX_GetAlarm, ATOBEX_SetAlarm, ATOBEX_GetLocale, ATOBEX_SetLocale, ATOBEX_PressKey, ATOBEX_Reset, ATOBEX_ResetPhoneSettings, ATOBEX_EnterSecurityCode, ATOBEX_GetSecurityStatus, ATOBEX_GetDisplayStatus, ATOBEX_SetAutoNetworkLogin, ATOBEX_GetBatteryCharge, ATOBEX_GetSignalStrength, ATOBEX_GetNetworkInfo, NOTSUPPORTED, /* GetCategory */ NOTSUPPORTED, /* AddCategory */ NOTSUPPORTED, /* GetCategoryStatus */ ATOBEX_GetMemoryStatus, ATOBEX_GetMemory, ATOBEX_GetNextMemory, ATOBEX_SetMemory, ATOBEX_AddMemory, ATOBEX_DeleteMemory, ATOBEX_DeleteAllMemory, NOTSUPPORTED, /* GetSpeedDial */ NOTSUPPORTED, /* SetSpeedDial */ ATOBEX_GetSMSC, ATOBEX_SetSMSC, ATOBEX_GetSMSStatus, ATOBEX_GetSMS, ATOBEX_GetNextSMS, NOTSUPPORTED, /* SetSMS */ ATOBEX_AddSMS, ATOBEX_DeleteSMS, ATOBEX_SendSMS, ATOBEX_SendSavedSMS, ATOBEX_SetFastSMSSending, ATOBEX_SetIncomingSMS, ATOBEX_SetIncomingCB, ATOBEX_GetSMSFolders, NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ ATOBEX_DialVoice, ATOBEX_DialService, ATOBEX_AnswerCall, ATOBEX_CancelCall, NOTSUPPORTED, /* HoldCall */ NOTSUPPORTED, /* UnholdCall */ NOTSUPPORTED, /* ConferenceCall */ NOTSUPPORTED, /* SplitCall */ NOTSUPPORTED, /* TransferCall */ NOTSUPPORTED, /* SwitchCall */ NOTSUPPORTED, /* GetCallDivert */ NOTSUPPORTED, /* SetCallDivert */ NOTSUPPORTED, /* CancelAllDiverts */ ATOBEX_SetIncomingCall, ATOBEX_SetIncomingUSSD, ATOBEX_SendDTMF, ATOBEX_GetRingtone, ATOBEX_SetRingtone, NOTSUPPORTED, /* GetRingtonesInfo */ NOTSUPPORTED, /* DeleteUserRingtones */ NOTSUPPORTED, /* PlayTone */ NOTSUPPORTED, /* GetWAPBookmark */ NOTSUPPORTED, /* SetWAPBookmark */ NOTSUPPORTED, /* DeleteWAPBookmark */ NOTSUPPORTED, /* GetWAPSettings */ NOTSUPPORTED, /* SetWAPSettings */ NOTSUPPORTED, /* GetSyncMLSettings */ NOTSUPPORTED, /* SetSyncMLSettings */ NOTSUPPORTED, /* GetChatSettings */ NOTSUPPORTED, /* SetChatSettings */ NOTSUPPORTED, /* GetMMSSettings */ NOTSUPPORTED, /* SetMMSSettings */ NOTSUPPORTED, /* GetMMSFolders */ NOTSUPPORTED, /* GetNextMMSFileInfo */ ATOBEX_GetBitmap, ATOBEX_SetBitmap, ATOBEX_GetToDoStatus, ATOBEX_GetToDo, ATOBEX_GetNextToDo, ATOBEX_SetToDo, ATOBEX_AddToDo, ATOBEX_DeleteToDo, ATOBEX_DeleteAllToDo, ATOBEX_GetCalendarStatus, ATOBEX_GetCalendar, ATOBEX_GetNextCalendar, ATOBEX_SetCalendar, ATOBEX_AddCalendar, ATOBEX_DeleteCalendar, ATOBEX_DeleteAllCalendar, NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ ATOBEX_GetNoteStatus, ATOBEX_GetNote, ATOBEX_GetNextNote, ATOBEX_SetNote, ATOBEX_AddNote, ATOBEX_DeleteNote, ATOBEX_DeleteAllNotes, NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ ATOBEX_GetNextFileFolder, NOTSUPPORTED, /* GetFolderListing */ NOTSUPPORTED, /* GetNextRootFolder */ NOTSUPPORTED, /* SetFileAttributes */ ATOBEX_GetFilePart, ATOBEX_AddFilePart, ATOBEX_SendFilePart, ATOBEX_GetFileSystemStatus, ATOBEX_DeleteFile, ATOBEX_AddFolder, ATOBEX_DeleteFile, /* DeleteFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ NOTSUPPORTED, /* SetGPRSAccessPoint */ SONYERICSSON_GetScreenshot, /* GetScreenshot */ ATOBEX_SetPower, NOTSUPPORTED /* PostConnect */ }; #endif #endif /*@}*/ /*@}*/ /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */