В своей программе ответ сохраняю в переменную типа CString, затем вывожу на RichEdit. Получается так
+CPBR: 2, "09xxxx6453", 129, ""
в последних кавычках должно быть имя абонента русскими буквами, с английским текстом все ОК. Проверял стандартным виндовым HyperTerminal'ом — в нем то-же "".
Подскажите, что можно сделать ?
P.S. смотрел команду +CSCS, но не очень понял что там за кодировки, кроме "PCCP437".
Здравствуйте, AndreySol, Вы писали:
AS>В своей программе ответ сохраняю в переменную типа CString, затем вывожу на RichEdit. Получается так AS>+CPBR: 2, "09xxxx6453", 129, "" AS>в последних кавычках должно быть имя абонента русскими буквами, с английским текстом все ОК. Проверял стандартным виндовым HyperTerminal'ом — в нем то-же "". AS>Подскажите, что можно сделать ?
AS>P.S. смотрел команду +CSCS, но не очень понял что там за кодировки, кроме "PCCP437".
Там может быть много кодировок. Какие поддерживаются можно узнать послав запрос:
AT+CSCS=?
и получив например ответ:
+CSCS: ("8859-1","8859-A","8859-C","8859-H","ASCII","GSM","KSC5601","UCS2","UTF8")
после чего можно попросить аппарат выдавать в нужной кодировке, например:
AT+CSCS="UTF8"
Но это ищё ничего не гарантирует. Например телефоны SAMSUNG могут быть выдавать непечатаемые символы — первый и последний
Первый символ может быть номер 2 в кодовой таблице
И когда ты это присваиваешь это строке CString то как она там это запомнит... -)
У моего китайца список кодировок: "IRA", "GSM", "HEX", "PCCP437", "8859-1", "UCS2", "UCS2_0X81". Понятно сразу что "PCCP437" не подойдет т.к. в 437 кодовой странице нет русских символов. Насчет остальных ничего не понял, хотя пытался читать про них — все на англицком, а я с ним не очень.
K>И когда ты это присваиваешь строке CString то как она там это запомнит... -)
Вот в этом наверное и проблема. Может что-то другое нуно вместо CString ?
Здравствуйте, AndreySol, Вы писали:
AS>Здравствуйте, kiborg:
AS>У моего китайца список кодировок: "IRA", "GSM", "HEX", "PCCP437", "8859-1", "UCS2", "UCS2_0X81". Понятно сразу что "PCCP437" не подойдет т.к. в 437 кодовой странице нет русских символов. Насчет остальных ничего не понял, хотя пытался читать про них — все на англицком, а я с ним не очень.
K>>И когда ты это присваиваешь строке CString то как она там это запомнит... -)
AS>Вот в этом наверное и проблема. Может что-то другое нуно вместо CString ?
Смело выбирай "UCS2". Это упрощенный двухбайтовый Unicode (UTF-16). Сам найдешь про Unicode. В чем разница между UTF и UCS
Выбрав эту кодировку в ответ должна приходить примерно такая строка:
+CPBR: 1,"067409180",129,"0047007000720073002D041E043A04300437002C"
Соответственно каждые 2 байта (4 символа HEX строки) преобразовать в отдельный символ UCS2
0047 0070 0072 0073 002D
У меня вот такая функция
GString GString::HexCharToString(/*[in]*/GString &str)
{
GString s_temp;
unsigned int data;
wchar_t buf;
for (ULONG i = 0; i < str.Length(); i+=4)
{
//buf = *str[i];
data = HexToInt(*str[i]);
data = (wchar_t)((data << 4) | HexToInt(*str[i+1]));
buf = HexToInt(*str[i+2]);
buf = (wchar_t)((buf << 4) | HexToInt(*str[i+3]));
s_temp += (wchar_t)((data << 8) | buf);
}
return s_temp;
}
Только замени GString на CString, потому как это GString это мой класс строки.
Здравствуйте, AndreySol, Вы писали:
AS>В своей программе ответ сохраняю в переменную типа CString, затем вывожу на RichEdit. Получается так AS>+CPBR: 2, "09xxxx6453", 129, "" AS>в последних кавычках должно быть имя абонента русскими буквами, с английским текстом все ОК. Проверял стандартным виндовым HyperTerminal'ом — в нем то-же "". AS>Подскажите, что можно сделать ?
AT+CSCS="UCS2"
AS>P.S. смотрел команду +CSCS, но не очень понял что там за кодировки, кроме "PCCP437".
Здравствуйте, AndreySol, Вы писали:
AS>А можно еще до кучи и Вашу реализацию HexToInt ?
Вызывается до вызова функции декодирования SMS в PDU (которая ожидает всё же бинарные данные, а не длинный хекс, полученные в ответ на AT+CMGR):
/* декодировать HEX-строку в двоичную на месте (HEX портится),
* возвращается число декодированных байтов или -1 при ошибке декодирования */
int hex2bin(char *hex)
{
unsigned n, count;
unsigned char *b;
b=(unsigned char*)hex; count=0;
while (1) {
while (*hex && isspace(*hex)) hex++; /* пропуск пробелов */
if (!*hex) return count; /* конец строки */
if (sscanf(hex, "%2x", &n)!=1) return -1;
*b++=n, hex+=2, count++;
}
return -1;
}
Потом для декодированного массива вызывается эта функция (из функции разбора SMS в PDU):
/* декодировать текст из UCS2 в `msg' с длиной `size' в БАЙТАХ
* (в бинарном виде) в `text' в wchar_t*. возвращается число
* декодированных СИМВОЛОВ (не байтов!), без учёта завершающего нуля. */
uint_fast8_t ucs2towcs(wchar_t *text, const char *msg, uint_fast8_t size)
{
unsigned code;
uint_fast8_t n;
n=0;
while (size>=2) {
code=(msg[0])<<8 | msg[1];
#if (WCHAR_MAX < 256)
/* код для микроконтроллера где wchar_t на самом деле ГОСТ-кодировка в char */
if (code>=128) code-=0x360; /* convert UCS2 to ISO8859-5 */
#endif
msg+=2, size-=2;
text[n++]=code;
}
text[n]=0;
return n;
}
Говнокод. Хекс бывает в нижнем регистре, кодировка может быть (если уж до-конца придираться) вообще EBCDIC, наконец могут быть пробелы, которые неплохо бы игнорировать, да и ввиду ошибок может быть вовсе не хекс.
AS>результат — "кракозяблики MTS", т.е. русские буквы не отображаются.
Здравствуйте, AndreySol, Вы писали:
AS>Есть, вот только .... AS>результат — "кракозяблики MTS", т.е. русские буквы не отображаются.
Этот код работает.
Осталось чуть-чуть. Ты должен понимать что вот в этой строке
strReturn += (wchar_t)((data << 8) | buf);
получается символ Unicode
А присваиваешь ты его к CString. А если ты компилируешь программу не в unicode то соответственно CString не уникод версии.
переделай код вот так
K>>поставь точку останова и выполняй по шагам и увидишь что в переменной temp присваиваются русские буквы.
AS>Переделал, не присваиваются. Как были кракозяблики, так и остались.
Всё присваивается. Ты точно там где надо смотришь? В переменной temp?
Я специально создал пустой не UNICODE проект. Проверил. Всё работает.
В переменной strReturn раземеется будут кракозяблики.