# Biblioteka interfejsu drukarki POSNET COMBO DF

### 1.0.0

Spis Treści

- Wprowadzenie
- Przepływ informacji
- Zdarzenia asynchroniczne
  - Zdarzenia asynchroniczne
- Przykładowa sekwencja poleceń
- Wykorzystanie w językach programowania
- Wersja dla systemu Linux

"SPECYFIKACJA PROTOKOŁU COMBO DF 1.01 / THERMAL 3.01 v 010"

## Wprowadzenie

Podstawowe założenia, które zostały przyjęte przy projektowaniu biblioteki dla drukarki POSNET COMBO DF są następujące:

- komunikacja za pośrednictwem RS-232, USB (VCP lub DXX)
- wielowątkowość i wielo-urządzeniowość biblioteki (brak zmiennych globalnych)
- obsługa zdarzeń asynchronicznych (zmiany statusu urządzenia)
- kolejkowanie rozkazów w celu przyspieszenia wymiany danych
- wykorzystanie z różnych języków programowania (konwencja wywołań __stdcall zgodna z WINAPI)
- minimalna zależność od systemu operacyjnego w zakresie interfejsu biblioteki - praktycznie tylko 2 funkcja są typowo dedykowane dla Windows - POS_GetEvent i POS_SetMessageParams.
- interfejs śledzenia (Ustawienie poziomu śledzenia (informacyjności) biblioteki)
- natywny port dla systemu Linux
- maksymalna zgodność API z biblioteką dla kas COMBO/NEO

Ze względu na to, że ilość rozkazów wykorzystywanych w komunikacji z drukarką jest ogromna przy projektowaniu biblioteki zrezygnowano z literalnej realizacji każdego rozkazu jako osobnej funkcji. Grupowanie rozkazów w/g rodzaju parametrów także nie jest dobrym rozwiązaniem. W tej sytuacji został zastosowany model "obiektu rozkazowego (Request)", wraz z zestawem funkcji umożliwiających ustawianie parametrów (Obsługa parametrów rozkazu).

Zastosowanie takiego rozwiązania ma dodatkową zaletę. Drobne korekty w rozkazach obsługi drukarki w tym dodanie nowych czy zmiana ilości i rodzaju parametrów nie wymagają zmian w bibliotece komunikacyjnej, a jedynie dostosowania aplikacji do tych zmian.

Po wykonaniu takiego obiektu rozkazowego przez drukarkę (por. Przepływ informacji) wyniki dostępne są w analogiczny sposób - przez zestaw funkcji pobierających je kolejno z obiektu rozkazowego.

## Przepływ informacji

W aplikacji istnieją 2 kolejki rozkazowe, pomiędzy którymi następuje przepływ danych jak w grafie poniżej.

Całość transmisji obsługiwana jest przez dwa niezależne wątki, jeden transmisyjny, drugi odbiorczy operujące na odpowiednich kolejkach rozkazów. Dodatkowo dla każdego urządzenia istnieje osobny wątek wykonujący cykliczne zapytania o status urządzenia.

## Zdarzenia asynchroniczne

Drukarka POSNET COMBO DF posiada możliwość generacji zdarzeń zmiany statusu urządzenia w sposób asynchroniczny w stosunku do wykonywanych poleceń wydawanych przez nadzorującą ją aplikację sterująco-magazynową.

Do obsługi zdarzeń w tym trybie został przygotowany zestaw funkcji opisany w module Obsługa zdarzeń asynchronicznych statusu drukarek. Aplikacja główna może zostać powiadomiona o przyjściu nowego zdarzenia za pomocą:

- zdarzenia IPC typu "Event" systemu Windows,
- komunikatu Windows wysłanego do wskazanego okna aplikacji

Aplikacja może też cyklicznie sprawdzać status urzadzenia (polling).

UWAGA: Z natury działania drukarki sprawdzenie pełnego statusu drukarki składa się z dwóch niezaleznych operacji, w związku z tym w momencie przejscia drukarki ze stanu poprawngo do stanu awarii mechanizmu drukującego wystąpią dwa kolejne zdarzenia asynchroniczne (pierwsze wskazujące zmiane statusu drukarki, drugie statusu mechanizmu).

UWAGA: Jeśli status drukarki nie wskazuje na błąd mechanizmu drukarki wartość statusu mechanizmu jest nieistotna (nieważna).

## Przykładowa sekwencja poleceń

Obsługa drukarki wymaga wykonania pewnego zestawu standardowych operacji. Poniższy opis przedstawia jedną z możliwości na przykładzie prostego paragonu. Przykład jest w języku C++, dla czytelności pominięto obsługę sytuacji wyjątkowych.

            \\ Przygotowanie i otwarcie urzadzenia
            void *hDevice=NULL;
            hDevice=POS_CreateDeviceHandle(type);
            POS_SetDebugLevel(hDevice,POSNET_DEBUG_ALL & 0xFFFFFFFE);
            POS_SetDeviceParam(hDevice,POSNET_DEV_PARAM_COMSETTINGS,(void*)"COM1,9600,8,N,1,H");
            void *hLocalDevice=POS_OpenDevice(hDevice);

            \\ Wysłanie kolejnych rozkazów paragonu
            \\ Wersja z uzupełnianiem parametrów pojedynczo
            hRequest = POS_CreateRequest(hLocalDevice,"trinit");
            POS_PushRequestParam(hRequest,"bm","1");
            POS_PostRequest(hRequest,POSNET_REQMODE_SPOOL);

            \\ Oczekiwanie na wykonanie rozkazu
            POS_WaitForRequestCompleted(hRequest,5000);

            \\ Sprawdzenie statusu wykonania
            if (POS_GetRequestStatus(hRequest) != POSNET_STATUS_OK) { OBSLUGA_BLEDU }

            \\ Usuniecie rozkazu
            POS_DestroyRequest(hRequest);

            \\ Nastepne polecenia, wersja z tworzeniem rozkazu z parametrami
            hRequest = POS_CreateRequestEx(hLocalDevice,"trline","na,Bułka Standardowa\nvt,0\npr,35");
            POS_PostRequest(hRequest,POSNET_REQMODE_SPOOL);
            POS_WaitForRequestCompleted(hRequest,5000);
            if (POS_GetRequestStatus(hRequest) != POSNET_STATUS_OK) { OBSLUGA_BLEDU }
            POS_DestroyRequest(hRequest);
            hRequest = POS_CreateRequestEx(hLocalDevice,"trpayment","ty,0\nre,0\nwa,35");
            POS_PostRequest(hRequest,POSNET_REQMODE_SPOOL);
            POS_WaitForRequestCompleted(hRequest,5000);
            if (POS_GetRequestStatus(hRequest) != POSNET_STATUS_OK) { OBSLUGA_BLEDU }
            POS_DestroyRequest(hRequest);
            hRequest = POS_CreateRequestEx(hLocalDevice,"trend","to,35\nfp,35");
            POS_PostRequest(hRequest,POSNET_REQMODE_SPOOL);
            POS_WaitForRequestCompleted(hRequest,5000);
            if (POS_GetRequestStatus(hRequest) != POSNET_STATUS_OK) { OBSLUGA_BLEDU }
            POS_DestroyRequest(hRequest);

            \\ zamkniecie urzadzenia
            POS_CloseDevice(hLocalDevice);
            POS_DestroyDeviceHandle(hDevice);

Biblioteka posiada zestaw aplikacji demonstrujących różne sekwencje poleceń dla drukarki.

- demo_lowlevel - demonstruje przykładową realizację pojedynczej transakcji (paragonu)
- demo_requests - prezentuje różne sposoby obsługi parametrów poleceń oraz sposobu wysyłania rozkazów i odbioru danych
- demo_async2 - prezentuje realizację obsługi statusu drukarki za pośrednictwem zdarzeń (Event) w systemie Windows lub semaforów dla systemu Linux
- demo_async3 - prezentuje realizację obsługi statusu drukarki za pośrednictwem funkcji typu callback
- demo_all - prezentuje około 20 różnych przydatnych sekwencji drukarki, w tym różne warianty sprzedaży, fakturę VAT, formatki, raporty i ustawienia, demo to obsługuje zdarzenia nieprzewidywane metodą pollingu za pośrednictwem funkcji POS_GetPrnDeviceStatus

Kod poszczególnych programów demonstracyjnych zawiera w komenarzach dodatkowe informacje na temat ich działania.

## Wykorzystanie w językach programowania

W wersji prototypowej biblioteka została przetestowana w:

- VisualC++ .NET 2003
- Borland C++ Builder 4
- Delphi 7
- Visual Basic for Applications (MS Excel)
- Ch (http://www.softintegration.com)

Poniżej przedstawiono przykładowy kod dla VBA.

    	Private Declare Function POS_WaitForRequestCompleted Lib "posnet.dll" (ByVal H As Long, ByVal P As Long) As Long

Podobny kod dla Delphi 7

    	function POS_WaitForRequestCompleted (hDevice : THandle; k: longint) : THandle; stdcall; external 'posnet.dll'

## Wersja dla systemu Linux

Natywny port dla systemu Linux składa się z bibliotek:

libposcmbth.so.1.0

oraz

libptypes.so.2.0.2 (http://www.melikyan.com/ptypes/)

Biblioteki te są zależne także od dostępnych na licencji LGPL bibliotek obsługujących podsystem USB:

libusb - w wersji 0.1.11+ dostępnej standardowo w większości dystrybucji (http://libusb.sourceforge.net/)

oraz

libftdi w wersji 0.7+ (http://www.intra2net.com/de/produkte/opensource/ftdi/index.php) do obsługi konwertera FTDI zastosowanego w urządzeniu.

UWAGA!!! W przypadku korzystania z trybu natywnego USB (POSNET_INTERFACE_USB) do poprawnego działania drukarki niezbędne jest zablokowanie automatycznego ładowania i usunięcie jesli jest załadowany modułu jądra ftdi_sio. W przeciwnym razie połączenie z drukarką nie będzie możliwe (w pliku logu zgłaszany będzie błąd o kodzie -5), gdyż moduł ten przejmuje kontrolę nad konwerterem FTDI tworząc wirtualny port szeregowy (/dev/ttyUSBx).

W przypadku korzystania w trybie wirtualnego portu szeregowego, sterownik ftdi_sio jest potrzebny.