diff options
Diffstat (limited to 'libgammu')
25 files changed, 235 insertions, 168 deletions
diff --git a/libgammu/device/bluetooth/blue_osx.c b/libgammu/device/bluetooth/blue_osx.c index 5adf52c..a0e09f8 100644 --- a/libgammu/device/bluetooth/blue_osx.c +++ b/libgammu/device/bluetooth/blue_osx.c @@ -175,7 +175,7 @@ GSM_Error bluetooth_close(GSM_StateMachine *s) return ERR_NONE; } -int bluetooth_write(GSM_StateMachine *s, const void *buf, size_t nbytes) +ssize_t bluetooth_write(GSM_StateMachine *s, const void *buf, size_t nbytes) { GSM_Device_BlueToothData *d = &s->Device.Data.BlueTooth; threadContext *pContext = (threadContext *)d->Data; @@ -191,7 +191,7 @@ int bluetooth_write(GSM_StateMachine *s, const void *buf, size_t nbytes) return nbytes; } -int bluetooth_read(GSM_StateMachine *s, void *buffer, size_t size) +ssize_t bluetooth_read(GSM_StateMachine *s, void *buffer, size_t size) { GSM_Device_BlueToothData *d = &s->Device.Data.BlueTooth; threadContext *pContext = (threadContext *)d->Data; diff --git a/libgammu/device/bluetooth/bluetooth.c b/libgammu/device/bluetooth/bluetooth.c index 8cbb384..ba390f9 100644 --- a/libgammu/device/bluetooth/bluetooth.c +++ b/libgammu/device/bluetooth/bluetooth.c @@ -129,12 +129,12 @@ done: } #ifndef OSX_BLUE_FOUND -int bluetooth_read(GSM_StateMachine *s, void *buf, size_t nbytes) +ssize_t bluetooth_read(GSM_StateMachine *s, void *buf, size_t nbytes) { return socket_read(s, buf, nbytes, s->Device.Data.BlueTooth.hPhone); } -int bluetooth_write(GSM_StateMachine *s, const void *buf, size_t nbytes) +ssize_t bluetooth_write(GSM_StateMachine *s, const void *buf, size_t nbytes) { return socket_write(s, buf, nbytes, s->Device.Data.BlueTooth.hPhone); } diff --git a/libgammu/device/bluetooth/bluetooth.h b/libgammu/device/bluetooth/bluetooth.h index 13e8f03..aedeeb9 100644 --- a/libgammu/device/bluetooth/bluetooth.h +++ b/libgammu/device/bluetooth/bluetooth.h @@ -11,8 +11,8 @@ typedef struct { /* These are actually implemented in backend services */ GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device); GSM_Error bluetooth_findchannel(GSM_StateMachine *s); -int bluetooth_read(GSM_StateMachine *s, void *buf, size_t nbytes); -int bluetooth_write(GSM_StateMachine *s, const void *buf, size_t nbytes); +ssize_t bluetooth_read(GSM_StateMachine *s, void *buf, size_t nbytes); +ssize_t bluetooth_write(GSM_StateMachine *s, const void *buf, size_t nbytes); GSM_Error bluetooth_close(GSM_StateMachine *s); #endif diff --git a/libgammu/device/irda/irda.c b/libgammu/device/irda/irda.c index 0aa5077..aaad998 100644 --- a/libgammu/device/irda/irda.c +++ b/libgammu/device/irda/irda.c @@ -215,12 +215,12 @@ static GSM_Error irda_open (GSM_StateMachine *s) return ERR_NONE; } -static int irda_read(GSM_StateMachine *s, void *buf, size_t nbytes) +static ssize_t irda_read(GSM_StateMachine *s, void *buf, size_t nbytes) { return socket_read(s, buf, nbytes, s->Device.Data.Irda.hPhone); } -static int irda_write(GSM_StateMachine *s, const void *buf, size_t nbytes) +static ssize_t irda_write(GSM_StateMachine *s, const void *buf, size_t nbytes) { return socket_write(s, buf, nbytes, s->Device.Data.Irda.hPhone); } diff --git a/libgammu/device/proxy/proxy.c b/libgammu/device/proxy/proxy.c index db4a496..6dc91e6 100644 --- a/libgammu/device/proxy/proxy.c +++ b/libgammu/device/proxy/proxy.c @@ -132,7 +132,7 @@ GSM_Error proxy_open(GSM_StateMachine *s) return proxy_connect(s, &s->Device.Data.Proxy, s->CurrentConfig->Device); } -int proxy_read(GSM_StateMachine *s, void *buf, size_t nbytes) +ssize_t proxy_read(GSM_StateMachine *s, void *buf, size_t nbytes) { GSM_Device_ProxyData *d = &s->Device.Data.Proxy; struct timeval timeout2; @@ -172,7 +172,7 @@ ssize_t write_nosigpipe(int fd, const void *buf, size_t len) return result; } -int proxy_write(GSM_StateMachine *s, const void *buf, size_t nbytes) +ssize_t proxy_write(GSM_StateMachine *s, const void *buf, size_t nbytes) { GSM_Device_ProxyData *d = &s->Device.Data.Proxy; int ret; diff --git a/libgammu/device/serial/ser_djg.c b/libgammu/device/serial/ser_djg.c index 1ac69f4..da0f765 100644 --- a/libgammu/device/serial/ser_djg.c +++ b/libgammu/device/serial/ser_djg.c @@ -401,7 +401,7 @@ static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed) return ERR_NONE; } -static int serial_read(GSM_StateMachine *s, char *buf, size_t nbytes) +static ssize_t serial_read(GSM_StateMachine *s, char *buf, size_t nbytes) { if(RecTail == RecHead) return 0; @@ -413,7 +413,7 @@ static int serial_read(GSM_StateMachine *s, char *buf, size_t nbytes) return 1; } -static int serial_write(GSM_StateMachine *s, char *buf, size_t nbytes) +static ssize_t serial_write(GSM_StateMachine *s, char *buf, size_t nbytes) { int i; diff --git a/libgammu/device/serial/ser_unx.c b/libgammu/device/serial/ser_unx.c index 845e5b1..c0fbd57 100644 --- a/libgammu/device/serial/ser_unx.c +++ b/libgammu/device/serial/ser_unx.c @@ -377,7 +377,7 @@ static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed) return ERR_NONE; } -static int serial_read(GSM_StateMachine *s, void *buf, size_t nbytes) +static ssize_t serial_read(GSM_StateMachine *s, void *buf, size_t nbytes) { GSM_Device_SerialData *d = &s->Device.Data.Serial; struct timeval timeout2; @@ -399,7 +399,7 @@ static int serial_read(GSM_StateMachine *s, void *buf, size_t nbytes) return actual; } -static int serial_write(GSM_StateMachine *s, const void *buf, size_t nbytes) +static ssize_t serial_write(GSM_StateMachine *s, const void *buf, size_t nbytes) { GSM_Device_SerialData *d = &s->Device.Data.Serial; int ret; diff --git a/libgammu/device/serial/ser_w32.c b/libgammu/device/serial/ser_w32.c index e177815..af8608f 100644 --- a/libgammu/device/serial/ser_w32.c +++ b/libgammu/device/serial/ser_w32.c @@ -372,7 +372,7 @@ static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed) return ERR_NONE; } -static int serial_read(GSM_StateMachine *s, void *buf, size_t nbytes) +static ssize_t serial_read(GSM_StateMachine *s, void *buf, size_t nbytes) { COMSTAT ComStat; DWORD ErrorFlags, Length, Error; @@ -428,7 +428,7 @@ end: return Length; } -static int serial_write(GSM_StateMachine *s, const void *buf, size_t nbytes) +static ssize_t serial_write(GSM_StateMachine *s, const void *buf, size_t nbytes) { DWORD BytesWritten,ErrorFlags,BytesSent=0; COMSTAT ComStat; diff --git a/libgammu/device/usb/usb.c b/libgammu/device/usb/usb.c index c58d3c9..aa839b5 100644 --- a/libgammu/device/usb/usb.c +++ b/libgammu/device/usb/usb.c @@ -465,7 +465,7 @@ GSM_Error GSM_USB_Terminate(GSM_StateMachine *s) return ERR_NONE; } -int GSM_USB_Read(GSM_StateMachine *s, void *buf, size_t nbytes) +ssize_t GSM_USB_Read(GSM_StateMachine *s, void *buf, size_t nbytes) { GSM_Device_USBData *d = &s->Device.Data.USB; int rc = LIBUSB_ERROR_TIMEOUT, ret = 0, repeat = 0; @@ -496,7 +496,7 @@ int GSM_USB_Read(GSM_StateMachine *s, void *buf, size_t nbytes) return ret; } -int GSM_USB_Write(GSM_StateMachine *s, const void *buf, size_t nbytes) +ssize_t GSM_USB_Write(GSM_StateMachine *s, const void *buf, size_t nbytes) { GSM_Device_USBData *d = &s->Device.Data.USB; int rc = LIBUSB_ERROR_TIMEOUT, ret = 0, repeat = 0; diff --git a/libgammu/gsmphones.c b/libgammu/gsmphones.c index cf7bea0..9893b94 100644 --- a/libgammu/gsmphones.c +++ b/libgammu/gsmphones.c @@ -943,6 +943,7 @@ GSM_PhoneModel allmodels[] = { /* Huawei */ {"E17X", "E17X", "", {F_NO_UCS2, 0}}, {"E220", "E220", "", {0}}, + {"E150", "E150", "", {F_SMS_LOCATION_0, F_ENCODED_USSD, F_FOUR_DIGIT_YEAR, F_RESET_AFTER_TIMEOUT, F_HUAWEI_INIT, 0}}, {"E160", "E160", "", {F_SMS_LOCATION_0, F_ENCODED_USSD, F_FOUR_DIGIT_YEAR, F_RESET_AFTER_TIMEOUT, F_HUAWEI_INIT, 0}}, {"E160E", "E160E", "", {F_SMS_LOCATION_0, F_ENCODED_USSD, F_FOUR_DIGIT_YEAR, F_RESET_AFTER_TIMEOUT, F_HUAWEI_INIT, 0}}, {"E160X", "E160X", "", {F_SMS_LOCATION_0, F_ENCODED_USSD, F_FOUR_DIGIT_YEAR, F_RESET_AFTER_TIMEOUT, F_HUAWEI_INIT, 0}}, @@ -964,8 +965,10 @@ GSM_PhoneModel allmodels[] = { {"EM770W", "EM770W", "", {F_SMS_LOCATION_0, F_ENCODED_USSD, F_FOUR_DIGIT_YEAR, F_RESET_AFTER_TIMEOUT, F_HUAWEI_INIT, 0}}, {"E3372", "E3372", "", {F_SMS_LOCATION_0, F_ENCODED_USSD, F_FOUR_DIGIT_YEAR, F_RESET_AFTER_TIMEOUT, F_HUAWEI_INIT, 0}}, {"E3276", "E3276", "", {F_SMS_LOCATION_0, F_ENCODED_USSD, F_FOUR_DIGIT_YEAR, F_RESET_AFTER_TIMEOUT, F_HUAWEI_INIT, 0}}, + {"E372", "E372", "", {F_SMS_LOCATION_0, F_ENCODED_USSD, F_FOUR_DIGIT_YEAR, F_RESET_AFTER_TIMEOUT, F_HUAWEI_INIT, 0}}, {"E398", "E398", "", {F_SMS_LOCATION_0, F_ENCODED_USSD, F_FOUR_DIGIT_YEAR, F_RESET_AFTER_TIMEOUT, F_HUAWEI_INIT, 0}}, {"E3131", "E3131", "", {F_SMS_LOCATION_0, F_ENCODED_USSD, F_FOUR_DIGIT_YEAR, F_RESET_AFTER_TIMEOUT, F_HUAWEI_INIT, 0}}, + {"K3715", "K3715", "", {F_SMS_LOCATION_0, F_ENCODED_USSD, F_FOUR_DIGIT_YEAR, F_RESET_AFTER_TIMEOUT, F_HUAWEI_INIT, 0}}, {"K3765", "K3765", "", {F_SMS_LOCATION_0, F_ENCODED_USSD, F_FOUR_DIGIT_YEAR, F_RESET_AFTER_TIMEOUT, F_HUAWEI_INIT, 0}}, {"K3770", "K3770", "", {F_SMS_LOCATION_0, F_ENCODED_USSD, F_FOUR_DIGIT_YEAR, F_RESET_AFTER_TIMEOUT, F_HUAWEI_INIT, 0}}, {"K4505", "K4505", "", {F_SMS_LOCATION_0, F_ENCODED_USSD, F_FOUR_DIGIT_YEAR, F_RESET_AFTER_TIMEOUT, F_HUAWEI_INIT, 0}}, @@ -973,6 +976,7 @@ GSM_PhoneModel allmodels[] = { /* ZTE */ {"MF100", "MF100", "", {F_ZTE_INIT, 0}}, + {"MF112", "MF112", "", {F_ZTE_INIT, 0}}, {"MF190", "MF190", "", {F_ZTE_INIT, 0}}, /* Ubinetics */ diff --git a/libgammu/gsmstate.h b/libgammu/gsmstate.h index 2ca0b21..61eb64e 100644 --- a/libgammu/gsmstate.h +++ b/libgammu/gsmstate.h @@ -249,11 +249,11 @@ typedef struct { /** * Attempts to read nbytes from device. */ - int (*ReadDevice) (GSM_StateMachine *s, void *buf, size_t nbytes); + ssize_t (*ReadDevice) (GSM_StateMachine *s, void *buf, size_t nbytes); /** * Attempts to read nbytes from device. */ - int (*WriteDevice) (GSM_StateMachine *s, const void *buf, size_t nbytes); + ssize_t (*WriteDevice) (GSM_StateMachine *s, const void *buf, size_t nbytes); } GSM_Device_Functions; #ifdef GSM_ENABLE_SERIALDEVICE @@ -345,7 +345,7 @@ typedef struct { * Writes message to device. */ GSM_Error (*WriteMessage) (GSM_StateMachine *s, unsigned const char *buffer, - int length, int type); + size_t length, int type); /** * This one is called when character is received from device. */ diff --git a/libgammu/misc/coding/coding.c b/libgammu/misc/coding/coding.c index aa033a0..7785ccd 100644 --- a/libgammu/misc/coding/coding.c +++ b/libgammu/misc/coding/coding.c @@ -235,8 +235,11 @@ void DecodeUnicode (const unsigned char *src, char *dest) if (value >= 0xD800 && value <= 0xDBFF) { second = src[(i + 1) * 2] * 256 + src[(i + 1) * 2 + 1]; if (second >= 0xDC00 && second <= 0xDFFF) { - i++; value = ((value - 0xD800) << 10) + (second - 0xDC00) + 0x010000; + i++; + } else if (second == 0) { + /* Surrogate at the end of string */ + value = 0xFFFD; /* REPLACEMENT CHARACTER */ } } o += DecodeWithUnicodeAlphabet(value, dest + o); @@ -1839,10 +1842,15 @@ gboolean EncodeUTF8QuotedPrintable(char *dest, const unsigned char *src) for (i = 0; i < len; i++) { value = src[i * 2] * 256 + src[i * 2 + 1]; /* Decode UTF-16 */ - if (value >= 0xD800 && value <= 0xDBFF && (i + 1) < len) { - second = src[(i + 1) * 2] * 256 + src[(i + 1) * 2 + 1]; - if (second >= 0xDC00 && second <= 0xDFFF) { - value = ((value - 0xD800) << 10) + (second - 0xDC00) + 0x010000; + if (value >= 0xD800 && value <= 0xDBFF) { + if ((i + 1) < len) { + second = src[(i + 1) * 2] * 256 + src[(i + 1) * 2 + 1]; + if (second >= 0xDC00 && second <= 0xDFFF) { + value = ((value - 0xD800) << 10) + (second - 0xDC00) + 0x010000; + } + } else { + /* Surrogate at the end of string */ + value = 0xFFFD; /* REPLACEMENT CHARACTER */ } } z = EncodeWithUTF8Alphabet(value, mychar); @@ -1880,11 +1888,16 @@ gboolean EncodeUTF8(char *dest, const unsigned char *src) for (i = 0; i < len; i++) { value = src[i * 2] * 256 + src[i * 2 + 1]; /* Decode UTF-16 */ - if (value >= 0xD800 && value <= 0xDBFF && (i + 1) < len) { - second = src[(i + 1) * 2] * 256 + src[(i + 1) * 2 + 1]; - if (second >= 0xDC00 && second <= 0xDFFF) { - i++; - value = ((value - 0xD800) << 10) + (second - 0xDC00) + 0x010000; + if (value >= 0xD800 && value <= 0xDBFF ) { + if ((i + 1) < len) { + second = src[(i + 1) * 2] * 256 + src[(i + 1) * 2 + 1]; + if (second >= 0xDC00 && second <= 0xDFFF) { + i++; + value = ((value - 0xD800) << 10) + (second - 0xDC00) + 0x010000; + } + } else { + /* Surrogate at the end of string */ + value = 0xFFFD; /* REPLACEMENT CHARACTER */ } } z = EncodeWithUTF8Alphabet(value, mychar); diff --git a/libgammu/phone/at/at-sms.c b/libgammu/phone/at/at-sms.c index 0cd0d65..aac34bb 100644 --- a/libgammu/phone/at/at-sms.c +++ b/libgammu/phone/at/at-sms.c @@ -2626,13 +2626,12 @@ GSM_Error ATGEN_GetCNMIMode(GSM_StateMachine *s) return error; } -GSM_Error ATGEN_SetIncomingCB(GSM_StateMachine *s, gboolean enable) +GSM_Error ATGEN_SetCNMI(GSM_StateMachine *s) { -#ifdef GSM_ENABLE_CELLBROADCAST - GSM_Error error = ERR_NONE; - GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; char buffer[100]; int length = 0; + GSM_Error error; + GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->CNMIMode == -1) { error = ATGEN_GetCNMIMode(s); @@ -2648,18 +2647,30 @@ GSM_Error ATGEN_SetIncomingCB(GSM_StateMachine *s, gboolean enable) if (Priv->CNMIBroadcastProcedure == 0) { return ERR_NOTSUPPORTED; } + + length = sprintf( + buffer, + "AT+CNMI=%d,%d,%d,%d\r", + Priv->CNMIMode, + s->Phone.Data.EnableIncomingSMS ? Priv->CNMIProcedure : 0, +#ifdef GSM_ENABLE_CELLBROADCAST + s->Phone.Data.EnableIncomingCB ? Priv->CNMIBroadcastProcedure : 0, +#else + 0, +#endif + Priv->CNMIDeliverProcedure + ); + + return ATGEN_WaitFor(s, buffer, length, 0x00, 80, ID_SetIncomingSMS); +} + + +GSM_Error ATGEN_SetIncomingCB(GSM_StateMachine *s, gboolean enable) +{ +#ifdef GSM_ENABLE_CELLBROADCAST if (s->Phone.Data.EnableIncomingCB != enable) { s->Phone.Data.EnableIncomingCB = enable; - if (enable) { - smprintf(s, "Enabling incoming CB\n"); - length = sprintf(buffer, "AT+CNMI=%d,,%d\r", Priv->CNMIMode, Priv->CNMIBroadcastProcedure); - error = ATGEN_WaitFor(s, buffer, length, 0x00, 80, ID_SetIncomingCB); - } else { - smprintf(s, "Disabling incoming CB\n"); - length = sprintf(buffer, "AT+CNMI=%d,,%d\r", Priv->CNMIMode, 0); - error = ATGEN_WaitFor(s, buffer, length, 0x00, 80, ID_SetIncomingCB); - } - return error; + return ATGEN_SetCNMI(s); } return ERR_NONE; #else @@ -2672,8 +2683,6 @@ GSM_Error ATGEN_SetIncomingSMS(GSM_StateMachine *s, gboolean enable) { GSM_Error error = ERR_NONE; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; - char buffer[100] = {'\0'}; - int length = 0; /* We will need this when incoming message, but we can not invoke AT commands there: */ if (Priv->PhoneSMSMemory == 0) { @@ -2689,63 +2698,9 @@ GSM_Error ATGEN_SetIncomingSMS(GSM_StateMachine *s, gboolean enable) return error; } } - if (Priv->CNMIMode == -1) { - error = ATGEN_GetCNMIMode(s); - - if (error != ERR_NONE) { - return error; - } - } - if (Priv->CNMIMode == 0) { - return ERR_NOTSUPPORTED; - } - if (Priv->CNMIProcedure == 0 && Priv->CNMIDeliverProcedure == 0) { - return ERR_NOTSUPPORTED; - } if (s->Phone.Data.EnableIncomingSMS != enable) { s->Phone.Data.EnableIncomingSMS = enable; - - if (enable) { - smprintf(s, "Enabling incoming SMS\n"); - - /* Delivery reports */ - if (Priv->CNMIDeliverProcedure != 0) { - length = sprintf(buffer, "AT+CNMI=%d,,,%d\r", Priv->CNMIMode, Priv->CNMIDeliverProcedure); - error = ATGEN_WaitFor(s, buffer, length, 0x00, 80, ID_SetIncomingSMS); - - if (error != ERR_NONE) { - return error; - } - } - - /* Normal messages */ - if (Priv->CNMIProcedure != 0) { - length = sprintf(buffer, "AT+CNMI=%d,%d\r", Priv->CNMIMode, Priv->CNMIProcedure); - error = ATGEN_WaitFor(s, buffer, length, 0x00, 80, ID_SetIncomingSMS); - - if (error != ERR_NONE) { - return error; - } - } - } else { - smprintf(s, "Disabling incoming SMS\n"); - - /* Delivery reports */ - length = sprintf(buffer,"AT+CNMI=%d,,,%d\r", Priv->CNMIMode, 0); - error = ATGEN_WaitFor(s, buffer, length, 0x00, 80, ID_SetIncomingSMS); - - if (error != ERR_NONE) { - return error; - } - - /* Normal messages */ - length = sprintf(buffer, "AT+CNMI=%d,%d\r", Priv->CNMIMode, 0); - error = ATGEN_WaitFor(s, buffer, length, 0x00, 80, ID_SetIncomingSMS); - - if (error != ERR_NONE) { - return error; - } - } + return ATGEN_SetCNMI(s); } return ERR_NONE; } diff --git a/libgammu/phone/at/atgen.c b/libgammu/phone/at/atgen.c index f783e65..b267204 100644 --- a/libgammu/phone/at/atgen.c +++ b/libgammu/phone/at/atgen.c @@ -1925,6 +1925,7 @@ GSM_Error ATGEN_ReplyGetManufacturer(GSM_Protocol_Message *msg, GSM_StateMachine {"Option", AT_Option}, {"Wavecom", AT_Wavecom}, {"Qualcomm", AT_Qualcomm}, + {"Telit", AT_Telit}, {"ZTE", AT_ZTE}, {"\0", 0} }; @@ -4390,53 +4391,48 @@ GSM_Error ATGEN_DialService(GSM_StateMachine *s, char *number) char *req = NULL,*encoded = NULL; unsigned char *tmp = NULL; const char format[] = "AT+CUSD=%d,\"%s\",15\r"; - size_t len = 0, sevenlen = 0; + size_t len = 0, allocsize; + len = strlen(number); /* * We need to allocate twice more memory for number here, because it * might be encoded later. */ - req = (char *)malloc(strlen(format) + (strlen(number) * 2) + 1); + allocsize = 2 * (len + 1); + req = (char *)malloc(strlen(format) + allocsize + 1); if (req == NULL) { return ERR_MOREMEMORY; } - error = ATGEN_SetCharset(s, AT_PREF_CHARSET_GSM); + /* Prefer unicode to be able to deal with unicode response */ + error = ATGEN_SetCharset(s, AT_PREF_CHARSET_UNICODE); if (error != ERR_NONE) { free(req); req = NULL; return error; } - if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_ENCODED_USSD)) { - len = strlen(number); - encoded = (char *)malloc(2 * (len + 1)); - - if (encoded == NULL) { - free(req); - req = NULL; - return ERR_MOREMEMORY; - } - tmp = (unsigned char *)malloc(len + 1); - - if (tmp == NULL) { - free(req); - free(encoded); - return ERR_MOREMEMORY; - } - sevenlen = GSM_PackSevenBitsToEight(0, number, tmp, len); - EncodeHexBin(encoded, tmp, sevenlen); + encoded = (char *)malloc(allocsize); + tmp = (unsigned char *)malloc(allocsize); + if (tmp == NULL || encoded == NULL) { + free(req); free(tmp); - tmp = NULL; - } else { - encoded = number; + free(encoded); + return ERR_MOREMEMORY; } - len = sprintf(req, format, s->Phone.Data.EnableIncomingUSSD ? 1 : 0, encoded); - - if (encoded != number) { + EncodeUnicode(tmp, number, strlen(number)); + error = ATGEN_EncodeText(s, tmp, len, encoded, allocsize, &len); + free(tmp); + if (error != ERR_NONE) { + free(req); free(encoded); - encoded = NULL; + return error; } + + len = sprintf(req, format, s->Phone.Data.EnableIncomingUSSD ? 1 : 0, encoded); + + free(encoded); + error = ATGEN_WaitFor(s, req, len, 0x00, 30, ID_GetUSSD); free(req); req = NULL; diff --git a/libgammu/phone/at/atgen.h b/libgammu/phone/at/atgen.h index e2bebe6..9932e6c 100644 --- a/libgammu/phone/at/atgen.h +++ b/libgammu/phone/at/atgen.h @@ -80,6 +80,7 @@ typedef enum { AT_Philips, AT_Huawei, AT_Qualcomm, + AT_Telit, AT_ZTE, AT_Unknown } GSM_AT_Manufacturer; diff --git a/libgammu/protocol/alcatel/alcabus.c b/libgammu/protocol/alcatel/alcabus.c index 542dd36..ea741e8 100644 --- a/libgammu/protocol/alcatel/alcabus.c +++ b/libgammu/protocol/alcatel/alcabus.c @@ -15,7 +15,7 @@ #include "../../gsmcomon.h" #include "alcabus.h" -static GSM_Error ALCABUS_WriteMessage (GSM_StateMachine *s, unsigned const char *data, int len, int type) +static GSM_Error ALCABUS_WriteMessage (GSM_StateMachine *s, unsigned const char *data, size_t len, int type) { GSM_Protocol_ALCABUSData *d = &s->Protocol.Data.ALCABUS; unsigned char buffer[1024]; diff --git a/libgammu/protocol/at/at.c b/libgammu/protocol/at/at.c index 44b6176..5adedfc 100644 --- a/libgammu/protocol/at/at.c +++ b/libgammu/protocol/at/at.c @@ -12,9 +12,10 @@ #include "at.h" static GSM_Error AT_WriteMessage (GSM_StateMachine *s, unsigned const char *buffer, - int length, int type) + size_t length, int type) { - int sent=0, write_data=0, i=0; + size_t sent=0, i=0; + ssize_t write_data=0; GSM_DumpMessageText(s, buffer, length, type); GSM_DumpMessageBinary(s, buffer, length, type); diff --git a/libgammu/protocol/nokia/fbus2.c b/libgammu/protocol/nokia/fbus2.c index 18cab9a..1add22d 100644 --- a/libgammu/protocol/nokia/fbus2.c +++ b/libgammu/protocol/nokia/fbus2.c @@ -77,7 +77,7 @@ static GSM_Error FBUS2_WriteFrame(GSM_StateMachine *s, static GSM_Error FBUS2_WriteMessage (GSM_StateMachine *s, unsigned const char *MsgBuffer, - int MsgLength, + size_t MsgLength, int MsgType) { int i=0, nom=0, togo=0, thislength=0; /* number of messages, ... */ diff --git a/libgammu/protocol/nokia/mbus2.c b/libgammu/protocol/nokia/mbus2.c index da399a8..d732b49 100644 --- a/libgammu/protocol/nokia/mbus2.c +++ b/libgammu/protocol/nokia/mbus2.c @@ -14,7 +14,7 @@ static GSM_Error MBUS2_WriteMessage (GSM_StateMachine *s, unsigned const char *MsgBuffer, - int MsgLength, + size_t MsgLength, int MsgType) { unsigned char *buffer=NULL, checksum = 0; diff --git a/libgammu/protocol/nokia/phonet.c b/libgammu/protocol/nokia/phonet.c index e8efc34..e483616 100644 --- a/libgammu/protocol/nokia/phonet.c +++ b/libgammu/protocol/nokia/phonet.c @@ -26,7 +26,7 @@ static GSM_Error PHONET_WriteMessage (GSM_StateMachine *s, unsigned const char *MsgBuffer, - int MsgLength, + size_t MsgLength, int MsgType) { unsigned char *buffer=NULL; diff --git a/libgammu/protocol/obex/obex.c b/libgammu/protocol/obex/obex.c index feff665..0d558e1 100644 --- a/libgammu/protocol/obex/obex.c +++ b/libgammu/protocol/obex/obex.c @@ -14,7 +14,7 @@ #include "obex.h" static GSM_Error OBEX_WriteMessage (GSM_StateMachine *s, unsigned const char *MsgBuffer, - int MsgLength, int type) + size_t MsgLength, int type) { unsigned char *buffer=NULL; int length=0,sent=0; diff --git a/libgammu/protocol/s60/s60.c b/libgammu/protocol/s60/s60.c index f933a3d..5df3c6d 100644 --- a/libgammu/protocol/s60/s60.c +++ b/libgammu/protocol/s60/s60.c @@ -29,7 +29,7 @@ #include "s60-ids.h" static GSM_Error S60_WriteMessage (GSM_StateMachine *s, unsigned const char *MsgBuffer, - int MsgLength, int MsgType) + size_t MsgLength, int MsgType) { unsigned char *buffer=NULL; int pos, sent, length, buflen, bufpos; diff --git a/libgammu/protocol/symbian/gnapbus.c b/libgammu/protocol/symbian/gnapbus.c index c423bc4..6c945c1 100644 --- a/libgammu/protocol/symbian/gnapbus.c +++ b/libgammu/protocol/symbian/gnapbus.c @@ -12,7 +12,7 @@ #include "gnapbus.h" static GSM_Error GNAPBUS_WriteMessage (GSM_StateMachine *s, unsigned const char *MsgBuffer, - int MsgLength, int MsgType) + size_t MsgLength, int MsgType) { unsigned char *buffer=NULL; int sent=0,length=0,i=0; diff --git a/libgammu/service/sms/gsmmulti.c b/libgammu/service/sms/gsmmulti.c index 5cb826b..c956d8a 100644 --- a/libgammu/service/sms/gsmmulti.c +++ b/libgammu/service/sms/gsmmulti.c @@ -1013,29 +1013,39 @@ gboolean GSM_DecodeMMSIndication(GSM_Debug_Info *di, Info->Entries[0].MMSIndicator->Sender[0] = 0; Info->Entries[0].MMSIndicator->Address[0] = 0; - /* First byte is transaction ID */ - /* PUSH */ + /* First byte is the WSP transaction ID */ + /* Second byte is PUSH */ if (Buffer[1] != 0x06) { - dbgprintf(di, "Unsupported transaction id: 0x%02x\n", Buffer[1]); + dbgprintf(di, "Unsupported WSP PDU type: 0x%02x\n", Buffer[1]); return FALSE; } - /* Process payload */ + /* + * WSP Push PDU follows: + * + * Buffer[2] is length of content type and headers + * Buffer[3] is start of content type + * + * Process payload after headers per + * Multimedia Messaging Service Encapsulation Protocol + */ for (i = 3 + Buffer[2]; i < Length; i++) { switch(Buffer[i]) { case 0x8c: - /* Transaction type */ + /* X-Mms-Message-Type (Transaction type) */ i++; + /* We support only m-notification-ind (130) */ if (Buffer[i] != 0x82) { dbgprintf(di, "Unsupported transaction type: 0x%02x\n", Buffer[i]); return FALSE; } break; case 0x98: - /* Message ID */ + /* X-Mms-Transaction-Id (Message ID) */ + dbgprintf(di, "Transaction ID: %s\n", Buffer + i + 1); while (Buffer[i] != 0 && i < Length) i++; break; case 0x8d: - /* MMS version */ + /* X-Mms-MMS-Version (MMS version) */ i++; if (Buffer[i] < 0x90 || Buffer[i] > 0x92) { dbgprintf(di, "Unsupported MMS version: 0x%02x\n", Buffer[i]); @@ -1043,9 +1053,11 @@ gboolean GSM_DecodeMMSIndication(GSM_Debug_Info *di, } break; case 0x89: - /* Sender */ + /* From (Sender) */ i++; + /* Length */ if (Buffer[i] == 0) continue; + /* Address-present-token */ if (Buffer[i + 1] == 0x80) { if (Buffer[i + 2] < 32) { /* String with length + encoding, we just ignore it for now */ @@ -1057,7 +1069,7 @@ gboolean GSM_DecodeMMSIndication(GSM_Debug_Info *di, i += Buffer[i]; break; case 0x96: - /* Title */ + /* Subject (Title) */ if (Buffer[i + 1] == 0x0a && Buffer[i + 2] == 0xea) { /* UTF-8 */ strcpy(Info->Entries[0].MMSIndicator->Title, Buffer + i + 3); @@ -1068,7 +1080,7 @@ gboolean GSM_DecodeMMSIndication(GSM_Debug_Info *di, } break; case 0x8a: - /* Class */ + /* X-Mms-Message-Class (Class) */ i++; switch (Buffer[i]) { case 0x80: @@ -1089,28 +1101,100 @@ gboolean GSM_DecodeMMSIndication(GSM_Debug_Info *di, } break; case 0x8e: - /* Message size */ + /* X-Mms-Message-Size (Message size) */ i++; for (j = i + 1; j < i + 1 + Buffer[i]; j++) { Info->Entries[0].MMSIndicator->MessageSize = (Info->Entries[0].MMSIndicator->MessageSize << 8) + Buffer[j]; } i += Buffer[i]; break; - case 0x88: - /* Don't know */ + case 0x83: + /* X-Mms-Content-Location (URL) */ + strcpy(Info->Entries[0].MMSIndicator->Address, Buffer + i + 1); + i += strlen(Info->Entries[0].MMSIndicator->Address) + 1; + break; + + /* Ignored variable length fields */ + case 0x87: /* X-Mms-Delivery-Time */ + case 0x88: /* X-Mms-Expiry */ + case 0x9d: /* X-Mms-Reply-Charging-Deadline */ + case 0xa0: /* X-Mms-Previously-Sent-By */ + case 0xa1: /* X-Mms-Previously-Sent-Date */ + case 0xa4: /* X-Mms-MM-Flags */ + case 0xaa: /* X-Mms-Mbox-Totals */ + case 0xac: /* X-Mms-Mbox-Quotas */ + case 0xb2: /* X-Mms-Element-Descriptor */ i++; + i += Buffer[i]; break; - case 0x81: - /* Don't know */ + + /* Ignored long integer types */ + case 0x85: /* Date */ + case 0x9f: /* X-Mms-Reply-Charging-Size */ i++; i += Buffer[i]; break; - case 0x83: - /* URL */ - strcpy(Info->Entries[0].MMSIndicator->Address, Buffer + i + 1); - i += strlen(Info->Entries[0].MMSIndicator->Address) + 1; + + /* Ignored integer types */ + case 0xad: /* X-Mms-Message-Count */ + case 0xaf: /* X-Mms-Start */ + case 0xb3: /* X-Mms-Limit */ + i++; + break; + + /* Ignored octet types */ + case 0x86: /* X-Mms-Delivery-Report */ + case 0x8f: /* X-Mms-Priority */ + case 0x90: /* X-Mms-Read-Report */ + case 0x91: /* X-Mms-Report-Allowed */ + case 0x92: /* X-Mms-Response-Status */ + case 0x94: /* X-Mms-Sender-Visibility */ + case 0x95: /* X-Mms-Status */ + case 0x99: /* X-Mms-Retrieve-Status */ + case 0x9b: /* X-Mms-Read-Status */ + case 0x9c: /* X-Mms-Reply-Charging */ + case 0xa2: /* X-Mms-Store */ + case 0xa3: /* X-Mms-MM-State */ + case 0xa5: /* X-Mms-Store-Status */ + case 0xa7: /* X-Mms-Stored */ + case 0xa8: /* X-Mms-Attributes */ + case 0xa9: /* X-Mms-Totals */ + case 0xab: /* X-Mms-Quotas */ + case 0xb1: /* X-Mms-Distribution-Indicator */ + case 0xb4: /* X-Mms-Recommended-Retrieval-Mode */ + case 0xba: /* X-Mms-Content-Class */ + case 0xbb: /* X-Mms-DRM-Content */ + case 0xbc: /* X-Mms-Adaptation-Allowed */ + case 0xbf: /* X-Mms-Cancel-Status */ + i++; + break; + + /* Ignored encoded string types */ + case 0x81: /* Bcc */ + case 0x82: /* Cc */ + case 0x84: /* Content-Type */ + case 0x97: /* To */ + case 0x93: /* X-Mms-Response-Text */ + case 0x9a: /* X-Mms-Retrieve-Text */ + case 0xa6: /* X-Mms-Store-Status-Text */ + case 0xb5: /* X-Mms-Recommended-Retrieval-Mode-Text */ + case 0xb6: /* X-Mms-Status-Text */ + while (Buffer[i] != 0 && i < Length) { + i++; + } + break; + + /* Ignored string types */ + case 0x8b: /* Message-ID */ + case 0x9e: /* X-Mms-Reply-Charging-ID */ + case 0xb7: /* X-Mms-Applic-ID */ + case 0xb8: /* X-Mms-Reply-Applic-ID */ + case 0xb9: /* X-Mms-Aux-Applic-Info */ + case 0xbd: /* X-Mms-Replace-ID */ + case 0xbe: /* X-Mms-Cancel-ID */ + i++; + i += Buffer[i]; break; - case 0x87: default: dbgprintf(di, "Unknown MMS tag: 0x%02x\n", Buffer[i]); break; diff --git a/libgammu/service/sms/gsmsms.c b/libgammu/service/sms/gsmsms.c index 275e41a..5e4b946 100644 --- a/libgammu/service/sms/gsmsms.c +++ b/libgammu/service/sms/gsmsms.c @@ -1007,11 +1007,9 @@ static int GSM_EncodeSMSFrameText(GSM_Debug_Info *di, GSM_SMSMessage *SMS, unsig GSM_Error GSM_EncodeSMSFrame(GSM_Debug_Info *di, GSM_SMSMessage *SMS, unsigned char *buffer, GSM_SMSMessageLayout Layout, int *length, gboolean clear) { - int i; - if (clear) { /* Cleaning up to the SMS text */ - for (i=0;i<Layout.Text;i++) buffer[i] = 0; + memset(buffer, 0, Layout.Text); } /* GSM 03.40 section 9.2.3.1 (TP-Message-Type-Indicator) */ @@ -1036,17 +1034,32 @@ GSM_Error GSM_EncodeSMSFrame(GSM_Debug_Info *di, GSM_SMSMessage *SMS, unsigned c if (Layout.Number!=255) { buffer[Layout.Number] = GSM_PackSemiOctetNumber(SMS->Number,buffer+(Layout.Number+1),TRUE); - smfprintf(di, "Recipient number \"%s\"\n",DecodeUnicodeString(SMS->Number)); + smfprintf(di, "Recipient number \"%s\"\n", DecodeUnicodeString(SMS->Number)); } if (Layout.SMSCNumber!=255) { - buffer[Layout.SMSCNumber]=GSM_PackSemiOctetNumber(SMS->SMSC.Number,buffer+(Layout.SMSCNumber+1), FALSE); - smfprintf(di, "SMSC number \"%s\"\n",DecodeUnicodeString(SMS->SMSC.Number)); + buffer[Layout.SMSCNumber] = GSM_PackSemiOctetNumber(SMS->SMSC.Number,buffer+(Layout.SMSCNumber+1), FALSE); + smfprintf(di, "SMSC number \"%s\"\n", DecodeUnicodeString(SMS->SMSC.Number)); } /* Message Class*/ /* GSM 03.40 section 9.2.3.10 (TP-Data-Coding-Scheme) and GSM 03.38 section 4 */ if (Layout.TPDCS != 255) { - if (SMS->Class >= 0 && SMS->Class <= 3) buffer[Layout.TPDCS] |= SMS->Class | (1 << 4); + if (SMS->Class >= 0 && SMS->Class <= 3) { + buffer[Layout.TPDCS] |= SMS->Class; + if (SMS->Coding == SMS_Coding_Unicode_No_Compression) { + /* + * Use GSM 03.38 5.3.0 as it is necessary for + * Unicode + */ + buffer[Layout.TPDCS] |= 0x10; + } else { + /* + * Use TP-DCS as specified in GSM 03.38 5.0.0 + * to be compatible with older devices + */ + buffer[Layout.TPDCS] |= 0xf0; + } + } smfprintf(di, "SMS class %i\n",SMS->Class); } @@ -1055,7 +1068,7 @@ GSM_Error GSM_EncodeSMSFrame(GSM_Debug_Info *di, GSM_SMSMessage *SMS, unsigned c /* Bits 4 and 3: 10. TP-VP field present and integer represent (relative) */ buffer[Layout.firstbyte] |= 0x10; buffer[Layout.TPVP]=((unsigned char)SMS->SMSC.Validity.Relative); - smfprintf(di, "SMS validity %02x\n",SMS->SMSC.Validity.Relative); + smfprintf(di, "SMS validity %02x\n", SMS->SMSC.Validity.Relative); } if (Layout.DateTime != 255) { @@ -1063,7 +1076,7 @@ GSM_Error GSM_EncodeSMSFrame(GSM_Debug_Info *di, GSM_SMSMessage *SMS, unsigned c } if (Layout.TPMR != 255) { - smfprintf(di, "TPMR: %02x %i\n",SMS->MessageReference,SMS->MessageReference); + smfprintf(di, "TPMR: %02x %i\n", SMS->MessageReference,SMS->MessageReference); buffer[Layout.TPMR] = SMS->MessageReference; } |