iso8583(3) FreeBSD Library Functions Manual iso8583(3) NAME ISO8583_List, ISO8583_Take, ISO8583_Mark, ISO8583_Test, ISO8583_Val, ISO8583_Ref, ISO8583_Asn, ISO8583_Cpy, ISO8583_Free, ISO8583_Save -- Про- цедуры для работы с сообщениями в формате ISO 8583. LIBRARY ISO 8583 composer/decomposer (libiso8583, -liso8583) SYNOPSIS #include #include #include const ISO8583_Package *ISO8583_Take(char *nm); ISO8583_Pack * ISO8583_Mark(u_int32_t flags, const ISO8583_Package *package, u_char *in, size_t msz, char *tzname); int ISO8583_Test(ISO8583_Pack *pack, int fno, u_int32_t mode); u_int64_t ISO8583_Val(ISO8583_Pack *pack, int fno); char * ISO8583_Ref(ISO8583_Pack *pack, int fno); int ISO8583_Asn(ISO8583_Pack *pack, int fno, u_int64_t val); int ISO8583_Cpy(ISO8583_Pack *pack, int fno, u_char *vly, ssize_t len); void ISO8583_Free(ISO8583_Pack **pack); void ISO8583_Save(ISO8583_Pack **pack); #include #include #include #include int ISO8583_List(int first, int len, FILE *prt); DESCRIPTION Каждый формат сообщения в библиотеке имеет имя, представленное строкой. Функция ISO8583_Take() по этому имени выдает ссылку на описание формата. Эту ссылку можно использовать в ISO8583_Mark() параметр package. Функция ISO8583_Mark() создает описатель сообщения ISO 8583 со ссылкой на это сообщение in внутри, если не NULL, или с местом для формирования сообщения размером msz, если не 0, или с размером из flags, если не 0. Если не задано ни само сообщение ISO 8583, ни размер места для него, то выделяется одна страница. Если сообщение задано, то в описателе созда- ется разметка для быстрого доступа к отдельным полям этого сообщения. package задает описатель формата сообщения ISO 8583, этот описатель можно составить самостоятельно или взять один из готовых в массиве ISO8583_Packages. Посмотреть список этих описателей можно при помощи утилиты iso8583(3). Вновь созданное сообщение обязательно надо проинициализировать записью в нулевое поле типа сообщения, а потом в первое поле записать 0, и только после этого можно записывать в остальные поля строго по увеличению номера поля. При этом процедуры ISO8583_Asn() и ISO8583_Cpy() сами отмечают добавленные поля в поле BitMap (с номером поля 1). Результат процедуры ISO8583_Test() зависит от параметра mode. Если он равен ISO8583_STAT, то функция оценивает поле fno сообщения ISO 8583 на предмет наличия и свойства его. Если же mode == ISO8583_SIZE, то резуль- татом является реальная длинна поля в байтах. ISO8583_Val() возвращает содержимое поля fno, если оно представимо чис- лом. ISO8583_Ref() возвращает содержимое поля fno в виде ссылки на строку. После использования результата его нужно free(3). Возможности получить результат в виде ссылки на строку может и не быть, в этом случае ISO8583_Ref() возвращает NULL и надо пользоваться ISO8583_Val(). ISO8583_Asn() присваивает полю fno значение val. Разрешено присваивать только такие значения, которые не меняют размера сообщения ISO 8583 или с fno большим, чем номер любого уже имеющиегося в сообщении поля при нали- чии места для удлиннения сообщения. Если pack был создан ISO8583_Mark() из готового сообщения, то места для расширения там нет. ISO8583_Cpy() присваивает полю fno значение из строки vly. Ограничения на присвоение такие же, как и для ISO8583_Asn(). ISO8583_Free() освобождает память из под размеченного ISO8583_Mark() объ- екта, при этом сообщение ISO 8583, если оно было создано при вызове ISO8583_Mark(), тоже освобождается. Если такое сообщение надо сохранить, то надо вместо ISO8583_Free() использовать ISO8583_Save(). ISO8583_List() выводит в файл prt список поддерживаемых форматов сообще- ний, начиная с first не более len форматов. Биты параметра flags: #define ISO8583_MSZ 0x0000FFFF #define BLIN_VER1 0x01000000 #define BLIN_VER2 0x02000000 ISO8583_MSZ Задает размер пространства для создаваемого сообщения ISO 8583, если нет более приоритетных указателей размера. BLIN_VER1 включает печать сообщений в stderr об ошибках при выполнении описанных здесь функций. BLIN_VER2 и выше предназначены для отладки. Остальные биты должны быть установлены в 0. IMPLEMENTATION NOTES В текущем состоянии пакет реализует только то, что оказалось необходимо в конкретной ситуации, но я постарался не закрыть возможность развития с сохранением совместимости. Новые форматы сообщений надо добавлять в paunck.c, при добалении новых форматов данных ISO8583_E_MAX в iso8583.h Representations менять, остальные значения оттуда должны оставаться неиз- менными. Таблица codex[] с программами обработки форматов находится в codec.c, функции для оценки длинны полей сообщения в len.cc, функции для оценки значения сообщения в val.cc, вывод значения в строку - ref.cc, присваивание значения полю сообщения - asn.cc, процедуры копирования поля в сообщение лежат в cpy.cc. Типы полей: ISO8583_B_LITERAL Двоичное число, не более 64 бита, размещено начиная со старшего байта. Длинна в описателе задает коли- чество байтов. ISO8583_I_CHAR Последовательность предопределенной длинны из бай- тов. Длинна в описателе задает количество байтов. ISO8583_B_LLCHAR Байт с двухсимвольной в двоично-десятичном виде длинной, за которой следуют байты в указанном коли- честве. Длинна в описателе задает максимальное зна- чение в байте длинны. ISO8583_B_LLLCHAR Не реализовано. ISO8583_B_NUMERIC Число в двоично-десятичном виде. Длинна в описателе задает количество цифр. Если эта длинна нечетная, то не используются старшие 4 разряда первого байта. ISO8583_B_NUMERICl Число в двоично-десятичном виде. Длинна в описателе задает количество цифр. Если эта длинна нечетная, то не используются младшие 4 разряда последнего байта. ISO8583_B_LLNUM Байт с двухсимвольной в двоично-десятичном виде длинной, за которой следуют двоично-десятичные цифры в указанном количестве. Если эта длинна нечетная, то не используются старшие 4 разряда первого байта. Длинна в описателе задает максимальное значение в байте длинны. ISO8583_B_LLNUMl Байт с двухсимвольной в двоично-десятичном виде длинной, за которой следуют двоично-десятичные цифры в указанном количестве. Если эта длинна нечетная, то не используются младшие 4 разряда последнего байта. Длинна в описателе задает максимальное зна- чение в байте длинны. ISO8583_B_TIME Правая часть от времени UTC в виде CCYYMMDDHHMMSS (столетие, год, месяц, день, час, минута, секунда, все по 2 двоично-десятичных цифры) на общую длинну в цифрах, которая задана в описателе. Длинна не может быть нечетной или больше 14. ISO8583_B_DATE Левая часть от времени UTC в виде YYMMDDHHMMSS (год, месяц, день, час, минута, секунда, все по 2 двоично- десятичных цифры) на общую длинну в цифрах, которая задана в описателе. Длинна не может быть нечетной или больше 12. ISO8583_B_DATET Правая часть от времени UTC в виде CCYYMMDD (столе- тие, год, месяц, день, все по 2 двоично-десятичных цифры) на общую длинну в цифрах, которая задана в описателе. Длинна не может быть нечетной или больше 8. ISO8583_B_BINARY Не реализовано. ISO8583_B_LLBINARY Не реализовано. ISO8583_B_LLLBINARY Не реализовано. ISO8583_B_TIMEl То же, что и ISO8583_B_TIME, но время локальное. ISO8583_B_DATEl То же, что и ISO8583_B_DATE, но время локальное. ISO8583_B_DATETl То же, что и ISO8583_B_DATET, но время локальное. RETURN VALUES ISO8583_Mark() возвращает ссылку на структуру: typedef struct { u_int32_t flags; /* Тут хранятся заданные при вызове */ /* и используемые библиотекой биты. */ u_int32_t totlen; /* Размер сообщения ISO 8583 */ time_t now; /* Время создания */ char *tz; /* Time Zone */ size_t msz; /* Размер места для сообщения ISO 8583 */ const ISO8583_Package *package; /* Описатель сообщения ISO 8583 */ u_char *refo[]; /* Ссылки на начала полей сообщения */ } ISO8583_Pack; Биты результата вызова ISO8583_Test() таковы: #define ISO8583_PRES 1 #define ISO8583_VALU 2 #define ISO8583_REFU 4 ISO8583_PRES Заданное поле существует. ISO8583_VALU Значение заданного поля можно получить вызовом ISO8583_Val(). ISO8583_REFU Значение заданного поля можно получить вызовом ISO8583_Ref(). ISO8583_Val() возвращает значение поля, если представимо числом, или 0. ISO8583_Ref() возвращает значение поля в виде строки, или NULL. ISO8583_Asn() и ISO8583_Cpy() возвращают длинну записанного или добавлен- ного поля, или 0 при ошибке. ISO8583_List() возвращает количество выведенных форматов. EXAMPLES Просмотр готового сообщения: if (!(pack = ISO8583_Mark(0, thispck, in, 0))) { обработка ошибки } for (c = 0; c < pack->package->bound; c++) { if (pack->refo[c]) { if ((ISO8583_Test(pack, c) & ISO8583_PRES | ISO8583_VALU) == ISO8583_PRES | ISO8583_VALU) { printf(" Val=%lld", ISO8583_Val(pack, c)); } r = ISO8583_Ref(pack, c); if (r) printf(" Ref= printf(" %s0, thispck[c].description); free(r); } } } Создание нового сообщения: if (!(pack = ISO8583_Mark(0, thispck, NULL, 0))) { обработка ошибки } if (!(ISO8583_Asn(pack, 0, 100))) { обработка ошибки } if (!(ISO8583_Asn(pack, 1, 0))) { обработка ошибки } ERRORS ISO8583_Mark() при ошибке возвращает NULL вместо ссылки на структуру с разобранной строкой и устанавливает errno: [EINVAL] Неверный параметр. [ENOMEM] Нет памяти. [EFAULT] An argument address referenced invalid memory. ISO8583_Asn() и ISO8583_Cpy() при ошибке возвращают 0 и устанавливает errno: [EINVAL] Неверный параметр. [EOVERFLOW] Параметр не помещается в отведенное место. SEE ALSO iso8583(1). STANDARDS Возможно, эта библиотека реализует мизерную часть стандарта ISO 8583. А может, и того нет. HISTORY Начало библиотеке было положено осенью 2005. AUTHOR Aleksandr A. Babaylov (aka @BABOLO) <.@babolo.ru> http://www.babolo.ru/ BUGS В формате обмена с Экспобанком все времена описаны как UTC. Это ошибка. По крайней мере в 07 поле время локальное вместо UTC. В структуре сооб- щения предусмотрено место для зоны, но использование его не реализовано сейчас. Более того, нет ясности, локальное для кого время там должно быть. Эта библиотека только начата и в ней описаны только те преобразования и форматы, которые мне встретились в жизни. Остальные дописывайте и присы- лайте. Документация ни к черту. FreeBSD 7.2 08 November 2005 FreeBSD 7.2