- •Пояснительная записка
- •«Разработка программного средства эмуляции pos-терминала»
- •Содержание
- •Специальный раздел
- •Технологический раздел
- •Организационно-экономический раздел
- •Раздел по производственной и экологической безопасности
- •Перечень сокращений
- •Введение
- •Специальный раздел
- •1.Специальный раздел
- •1.1.Исследовательская часть
- •1.1.1.Типы программных средств эмуляции
- •1.1.2.Обзор программных средств эмуляции Microsoft Device Emulator и Android Emulator
- •Системные требования Microsoft Device Emulator
- •1.1.3.Эмуляция аппаратных модулей pos-терминала
- •Сравнительная характеристика программных средств эмуляции
- •1.2.Конструкторская часть
- •1.2.1.Состав выполняемых функций
- •1.2.2.Требования к надежности
- •1.2.3.Требования к информационной и программной совместимости
- •1.2.4.Требования к составу и параметрам технических средств
- •1.2.5.Организация входных и выходных данных
- •1.2.6.Выбор платформы для разработки
- •1.2.7.Выбор среды разработки
- •Сравнительная характеристика средств разработки
- •1.2.8.Алгоритмы работы программного средства
- •1.2.9.Иерархия классов прикладной программы пс эт
- •1.2.10.Описание логической структуры программного средства
- •Список создаваемых специальных файлов устройств
- •1.2.11.Пользовательский интерфейс. Экранные формы
- •1.2.12.Методика и результаты испытаний программного средства
- •Технологический раздел
- •2.Технологический раздел
- •2.1.Технология программирования пс эт
- •2.1.1.Основные определения
- •2.1.2.Этапы разработки и использованная модель жизненного цикла
- •2.1.3.Объектно-ориетированный подход
- •2.2.1.Обзор возможностей языка Си
- •2.3.Разработка драйверов в ос Linux
- •2.3.1.Особенности ос Linux
- •2.3.2.Принципы работы драйверов в ос Linux
- •2.3.3.Специальные файлы устройств
- •2.3.4.Структура, инициализация и выгрузка драйверов
- •2.3.5.Отладка драйверов
- •2.4.Сценарии в ос Linux
- •2.4.1.Основы разработки сценариев на языке оболочки bash
- •2.4.2.Переменные и области видимости
- •Стандартные переменные окружения и оболочки bash
- •2.4.3.Средства ввода-вывода
- •2.4.4.Команды ветвления if-else, case
- •2.4.5.Организация циклов
- •2.4.6.Определение функций
- •2.4.7.Отладка сценариев
- •Опции запуска сценариев
- •2.4.8.Makefile – управление компиляцией
- •2.5.Использование библиотек в ос Linux
- •2.5.1.Статические и динамические библиотеки
- •2.5.2.Графическая библиотека fltk
- •Элементы библиотеки fltk
- •2.5.3.Библиотека pcsc для работы с электронными картами
- •2.5.4.Библиотека TinyXml для работы с xml-файлами
- •Основные классы библиотеки TinyXml
- •2.6.Средства отладки в ос Linux
- •2.6.1.Технологии отладки
- •2.6.2.Отладочные сообщения
- •2.6.3.Стандарт syslog
- •2.6.4.Удаленная отладка с помощью gdbserver
- •2.6.5.Отладка в среде SlickEdit 2009
- •2.7.Виды тестирования
- •2.7.1.Классификация видов тестирования
- •2.7.2.Уровни тестирования
- •2.7.3.Тестирование методом «белого» ящика
- •2.7.4.Тестирование методом «черного» ящика
- •Организационно-экономический раздел «Определение целевого сегмента рынка pos-терминалов»
- •3.Организационно-экономический раздел
- •3.1.Сегментация рынка и позиционирование товара
- •3.1.1.Разделение рынка на сегменты
- •3.1.2.Принципы рыночной сегментации
- •3.1.3.Методы выделения сегментов
- •3.1.4.Критерии рыночной сегментации
- •3.1.5.Выбор целевого рынка
- •3.1.6.Выбор целевого сегмента
- •3.1.7.Позиционирование товара
- •3.1.8.Метод Чекановского
- •3.2.Сегментация рынка платежных pos-терминалов
- •3.2.1.Особенности рынка pos-терминалов
- •3.2.2.Выделение групп конечных пользователей
- •3.2.3.Выделение основных характеристик pos-терминала «ярус»
- •3.2.4.Диаграмма Чекановского
- •3.2.5.Выбор целевого сегмента и позиционирование pos-терминала «ярус»
- •Раздел по производственной и экологической безопасности «Инженерный расчет воздухообмена на рабочем месте инженера-программиста»
- •4.Раздел по производственной и экологической безопасности
- •4.1.Введение
- •4.2.Рабочее место инженера-программиста
- •4.2.1.Особенности и характеристики
- •4.2.2.Основные опасности и вредности
- •4.2.3.Оценка тяжести труда
- •Классы условий труда по показателям тяжести трудового процесса
- •4.3.Воздухообмен в помещении
- •4.3.1.Классификация систем вентиляции
- •4.3.2.Инженерный расчет воздухообмена в зависимости от числа людей в помещении
- •4.3.3.Инженерный расчет воздухообмена по избыткам тепла
- •Значения коэффициента Кост
- •Плотность теплового потока солнечной радиации в июле, Вт/м2
- •4.3.4.Выбор вентиляционной системы
- •4.4.Пожарная безопасность
- •4.5.Экологическая безопасность (утилизация компьютеров)
- •Заключение
- •Список литературы
- •Введение
- •Назначение и условия применения пс эт
- •Состав выполняемых функций
- •Требования к надежности
- •Требования к составу и параметрам технических средств
- •Характеристика пс эт
- •Обращение к пс эт
- •Входные и выходные данные пс эт
- •Сообщения
Список литературы
Гагарина Л. Г., Зубов Н. Н., Стрижков А. В., Федотова Е. Л. Методические указания по подготовке дипломного проекта специалистов направления «Информатика и вычислительная техника» (специальность 230105.65 «Программное обеспечение вычислительной техники и автоматизированных систем») / Под редакцией Л. Г. Гагариной. – 2-е изд., доп. – М.: МИЭТ, 2005. – 64 с.: ил.
ГОСТ 2.104-68 (ЕСКД). Основные надписи.
ГОСТ 2.105-95 (ЕСКД). Общие требования к текстовым документам.
ГОСТ 2.106-68 (ЕСКД). Текстовые документы.
ГОСТ 2.316-68 (ЕСКД). Правила нанесения на чертежах надписей, технических требований и таблиц.
ГОСТ 19.106-78 (ЕСПД). Требования к программным документам, выполняемым печатным способом.
Прогаммное средство эмуляции Microsoft Device Emulator – www.microsoft.com.
Программное средство эмуляции Android Emulator – http://developer.android.com/.
Среда разработки SlickEdit – www.slickedit.com.
Среда разработки Vim – http://ru.wikipedia.org/wiki/Vim.
Среда разработки Qt Creator – http://qt.nokia.com/.
ГОСТ 19.701-90 (ИСО 5807-85). Схемы алгоритмов, программ, данных и систем.
Графическая библиотека Fast Light Toolkit (FLTK) – http://www.fltk.org/.
Роберт Лав. Разработка ядра Linux / 2-е изд., доп. – М.: 2008.
Алессандро Рубини, Джонатан Корбет. Linux Device Drivers / 2-е изд., доп. – Пер. с англ.
Костромин В. А. Основы работы в ОС Linux. – http://www.intuit.ru.
Курячий Г. В., Маслинский К. А. Операционная система Linux. – 2005, http://www.intuit.ru/.
Уэлш М., Далхаймер М., Доусон Т., Кауфман Л. Запускаем Linux. – Пер. с англ. – Спб: Символ-Плюс, 2000.
Ричард Столлман, Роланд МакГрат. Программа управления компиляцией GNU make. – 1995, http://www.opennet.ru/docs/RUS/make_compile/
Динамическое связывание в Windows и Linux – http://www.securitylab.ru.
Домашняя страница PCSC-Lite - http://pcsclite.alioth.debian.org/.
Библиотека TinyXML – http://www.grinninglizard.com/tinyxml/.
ГОСТ 19.004-80 (ЕСПД). Термины и определения.
Ричард Столмен, Роланд Пеш, Стан Шебс. Отладка с помощью GDB. Отладчик GNU уровня исходного кода / 8-я редакция, для GDB версии 5.0. – Пер. с англ. Дмитрий Сиваченко. – 2000.
Тестирование программного обеспечения - http://ru.wikipedia.org/wiki/Тестирование_программного_обеспечения.
Канер Сэм, Джек Фолк, Енг Кек Нгуен. Тестирование программного обеспечения. Фундаментальные концепции менеджмента бизнес-приложений. – Пер. с англ. – К.: Издательство «ДиаСофт», 2001. – 544 с.
Герберт Шилдт. Полный справочник по С / 4-е изд. : Пер. с англ. – М.: «Вильямс», 2002. – 704 с.: ил.
Герберт Шилдт. Полный справочник по С++ / 4-е изд. : Пер. с англ. – М.: «Вильямс», 2006. – 800 с.: ил.
Жан-Жак Ламбен. Стратегический маркетинг. Европейская перспектива. – «Наука»: 1996г.
Эванс Дж. Р., Берман Б. Маркетинг. – Москва: 2002г., 335 с.
Романов А. Н., Корлюгов Ю. Ю., Красильников С. А. Маркетинг. – Москва: 1996г., 560 с.
Каракеян В. И., Никулина И. М. Безопасность жизнедеятельности : учеб. пособие. – М.: Высшее образование, Юрайт-Издат, 2009. – 370 с. – (Основы наук).
Егель А.Э., Савченкова Е.Э., Корчагина С.Х. Расчет необходимого воздухообмена в производственных помещениях: Методические указания к выполнению раздела «Безопасность труда» в дипломных проектах. – Оренбург: ГОУ ОГУ, 2004.- 12 с.
Строительные нормы и правила. Отопление, вентиляция и кондиционирование. СНиП 2.04.05-91 / Под ред. Б.В. Баркалов, Т.И. Садовская, Е.Е. Карпис, М.В. Шувалова, 2000 - 123с.
Никулина И. М. Методические указания по выполнению домашних заданий по курсу «Безопасность жизнедеятельности». – М: МИЭТ, 2007.
ПРИЛОЖЕНИЕ 1
ТЕКСТ СЦЕНАРИЕВ ЗАПУСКА И ЗАВЕРШЕНИЯ РАБОТЫ ПС ЭТ
Сценарий запуска ПС ЭТ (start.sh):
#!/bin/bash
# Detect current directory
if [ ${0:0:1} = "/" ]; then
HERE=`dirname $0`
else
CMD=`pwd`/$0
HERE=`dirname ${CMD}`
fi
# Device nodes to create
NODES="xb kpd pin id lcd smem buzz uart0 uart1 uart2 zuart0 zuart1 zuart2 sc1 sc2 zsc1 zsc2 prn sc0 scs zsc0 zscs emcr"
# Modules to install
DRIVERS="zemul_id zemul_fb zemul_lcd zemul_mmd zemul_keypad zemul_buzz zemul_sc zemul_uart zemul_printer zemul_mcr"
echo
echo "Installing tools..."
sudo apt-get -qq install hal
sudo apt-get -qq install pcscd
sudo apt-get -qq install libfltk1.1
sudo apt-get -qq install libpcsclite1
sudo apt-get -qq install tinyxml
echo
echo "Building modules..."
if ! make --no-print-directory -C ${HERE}/drivers all; then
cd drivers/
rm -f *.ko
rm -f *.mod.c
rm -f *.mod.o
rm -f *.o
exit
fi
echo ""
echo "Loading emulation drivers..."
for DRV in ${DRIVERS}
do
sudo insmod drivers/${DRV}.ko
done
# Create keyboard device node
N=`grep -C 4 "Keypad Emulation Driver" /proc/bus/input/devices | grep "Handlers=" | sed "s/.*Handlers=.*event\(.*\)/\1/g"`
MINOR=`ls -l /dev/input/event${N} | awk '{print $5;}' | tr -d ","`
MAJOR=`ls -l /dev/input/event${N} | awk '{print $6;}'`
sudo mknod /dev/kpd c ${MINOR} ${MAJOR}
# Grab keyboard event device
KEYPAD_HAL=$(hal-find-by-property --key info.product --string "Keypad Emulation Driver")
if [ ! -z ${KEYPAD_HAL} ]
then
echo ""
echo "Ungrabbing the keypad driver from Xorg..."
sudo hal-device -r ${KEYPAD_HAL}
fi
# Create framebuffer device node
FB=`grep "LCDFB" /proc/fb | awk '{print "fb"$1;}'`
MINOR=`ls -l /dev/${FB} | awk '{print $5;}' | tr -d ","`
MAJOR=`ls -l /dev/${FB} | awk '{print $6;}'`
sudo mknod /dev/xb c ${MINOR} ${MAJOR}
echo ""
echo "Providing access to drivers..."
for NODE in ${NODES}
do
sudo chmod o+rw /dev/${NODE}
done
echo ""
sudo /etc/init.d/pcscd restart
sleep 1
echo ""
echo "Starting ZA9L emulator..."
sudo ./zemul &
Сценарий завершения работы ПС ЭТ (stop.sh):
#!/bin/bash
# Drivers to unload
UNLOADS="zemul_uart zemul_lcd zemul_fb zemul_keypad zemul_mmd zemul_printer zemul_mcr zemul_sha zemul_buzz zemul_sc zemul_id tun"
# Device nodes to remove
NODES="xb kpd pin prn emcr sha id lcd smem buzz sc0 sc1 sc2 scs zsc0 zsc1 zsc2 zscs uart0 uart1 uart2 zuart0 zuart1 zuart2"
echo ""
echo "Removing nodes..."
# For each node in list
for NODE in ${NODES}
do
# If device node exists
if ls /dev | grep -w ${NODE} >/dev/null
then
# Find and kill all applications using it
APPS=`lsof -t /dev/${NODE} | awk '{print $1}'`
for APP in ${APPS}
do
sudo kill -9 ${APP}
done
fi
# Remove device node
sudo rm -f /dev/${NODE}
done
echo ""
echo "Unloading drivers..."
for DRV in ${UNLOADS}
do
if lsmod | grep "\<${DRV}\>" >/dev/null
then
sudo rmmod ${DRV}
fi
done
echo ""
echo "Stopping PCSC daemon..."
sudo /etc/init.d/pcscd stop
ПРИЛОЖЕНИЕ 2
ФРАГМЕНТЫ ТЕКСТА ПРИКЛАДНОЙ ПРОГРАММЫ ПС ЭТ
Главное окно прикладной программы ПС ЭТ (Emulator.cpp):
//=============================================================================
// Company:
// Terminal Technologies Ltd
//
// Product:
// Zemul (POS Emulator)
//
// File Name:
// Emulator.cpp
//
// File Contents:
// Main emulator window.
//=============================================================================
#include "Emulator.hpp"
#define SCROLL 16 // Scroller width.
//-----------------------------------------------------------------------------
//! Constructor.
//!
//! \param
//! name Window header.
//-----------------------------------------------------------------------------
Emulator::Emulator( const char * name ) : EmulatorBase( name )
{
// Create main menu
menu.reset( new MenuBar( 0, 0, 100, 20 ) );
// Create printer and scrollbar for terminal board type
int start_x = gap;
//Create scroll widget
scroll.reset( new Fl_Scroll( gap, menu->h() + gap, 0, 0 ) );
//Create printer widget
prn.reset( new Printer( scroll->x() , scroll->y() ) );
//resize scrollbar
scroll->size( prn->w() + SCROLL, scroll->h() );
scroll->end();
start_x = right_of(scroll.get()) + gap;
// Create display widget
dsp.reset( new Display( start_x + 50 + gap, menu->h() + gap ) );
// Create keypad widget
kpd.reset( new MainKeypad( start_x, bottom_of(dsp.get()), 50 + gap + dsp->w() + gap + 50, 340 ) );
// Gap between smart cards
int sc_h_gap = (dsp->h() - 3*35)/2;
// Create left and write navigation panels
lnav.reset( new LeftNav( start_x, dsp->y(), 50, dsp->h() ) );
rnav.reset( new RightNav( right_of(dsp.get()), dsp->y(), 50, dsp->h() ) );
// Create EMCR area
mcr.reset( new MCR( right_of(rnav.get()), dsp->y(), 15, kpd->h() + gap + dsp->h() ) );
// Resize printer
prn->size( prn->w(), dsp->h() + gap + kpd->h() );
// Resize scroll
scroll->size( scroll->w(), prn->h() );
// Resize Emulator window
size( right_of(mcr.get()), bottom_of(kpd.get()) );
// Create Emulator config window
config.reset( new EmulatorConfig() );
config->set_modal();
// Resize Menu Bar
menu->size( w(), menu->h() );
end();
};
//-----------------------------------------------------------------------------
// Application main function.
//-----------------------------------------------------------------------------
int main(int argc, char **argv)
{
printf("\nPOS Emulator\n");
//start Emulator
boost::shared_ptr<Emulator> zemul( new Emulator( "POS Emulator" ) );
//show main window
zemul->show(argc,argv);
//run application
int ret_status = Fl::run();
return ret_status;
}
Область эмуляции принтера (Printer.cpp):
//=============================================================================
// Company:
// Terminal Technologies Ltd
//
// Product:
// Zemul (POS Emulator)
//
// File Name:
// Printer.cpp
//
// File Contents:
// Thermal printer emulation area.
//=============================================================================
#include "system.h"
#include "dev_printer.h"
#include "Printer.hpp"
#include <bitset>
#include <algorithm>
#include <boost/foreach.hpp>
#include <iostream>
//-----------------------------------------------------------------------------
//! Constructor. Initializes printer widget.
//!
//! \param
//! X X coordinate of top left corner.
//! \param
//! Y Y coordinate of top left corner.
//! \param
//! W Width.
//! \param
//! H Height.
//-----------------------------------------------------------------------------
Printer::Printer( int X, int Y, int W, int H ) : Fl_Box( X, Y, W, H, 0 ),
dev_name(std::string("/dev/"PRN_DEV)),
m_fd(0),
width(0),
lines(0),
read_rate(1000),
refresh_rate(DEFAULT_ZEMUL_RATE),
need_refresh(false)
{
if (!init()) exit(1);
//Initialize appearance
size( width, 0 );
box(FL_BORDER_BOX);
color(FL_WHITE);
align(FL_ALIGN_BOTTOM | FL_ALIGN_INSIDE);
tooltip("Right click to clear");
read_line();
refresh();
}
//-----------------------------------------------------------------------------
//! Destructor.
//-----------------------------------------------------------------------------
Printer::~Printer( void )
{
close(m_fd);
}
//-----------------------------------------------------------------------------
// Printer event handler.
// IN:
// event Event code.
// OUT:
// 1 on FL_PUSH event and 0 otherwise.
//-----------------------------------------------------------------------------
int Printer::handle( int event )
{
//mouse click event
if( event == FL_PUSH )
{
//clear Printer box on right button click
if( FL_RIGHT_MOUSE == Fl::event_button() )
{
buffer.clear();
lines = 0;
need_refresh = true;
size( w(), parent()->h() );
}
return 1;
}
return 0;
}
//-----------------------------------------------------------------------------
// Reverse all bits in string.
// IN:
// str Input string.
//-----------------------------------------------------------------------------
void Printer::reverse_bits( std::string &str )
{
std::string res_str = "";
//for each char
BOOST_FOREACH( char ch, str )
{
//create bitset for current char
std::bitset<8> bits(ch);
//convert to string
std::string s = bits.to_string();
//reverse bits
reverse( s.begin(), s.end() );
//create bitset from reversed bits
bits = std::bitset<8>(s);
//add char to result string
res_str += bits.to_ulong();
}
str = res_str;
}
//-----------------------------------------------------------------------------
// Repeatable function that checks if some data is available for printing.
//-----------------------------------------------------------------------------
void Printer::read_line( void )
{
int byte_width = width/8;
char buf[byte_width];
//read print data from driver
while( byte_width == read( m_fd, buf, byte_width ) )
{
std::string str;
str.assign(buf, byte_width);
reverse_bits( str );
buffer += str;
lines++;
need_refresh = true;
}
Fl::repeat_timeout( 1.0/read_rate, s_read_line, this );
}
//-----------------------------------------------------------------------------
// Repeatable function that prints data.
//-----------------------------------------------------------------------------
void Printer::refresh( void )
{
if ( need_refresh )
{
if ( lines > parent()->h() ) size( w(), lines );
bitmap.reset( new Fl_Bitmap( buffer.data(), width, lines ) );
image( bitmap.get() );
parent()->redraw();
need_refresh = false;
}
Fl::repeat_timeout( 1.0/refresh_rate, s_refresh, this );
}
//-----------------------------------------------------------------------------
// Printer initialization.
//-----------------------------------------------------------------------------
int Printer::init( void )
{
m_fd = open( dev_name.c_str(), O_RDONLY );
if( m_fd < 0 ) printf("Printer driver opening error\n" );
width = ioctl( m_fd, PRN_GET_WIDTH );
return 0 <= m_fd;
}
Эмуляция считывателя магнитных карт (MCR.cpp):
//=============================================================================
// Company:
// Terminal Technologies Ltd
//
// Product:
// Zemul (POS Emulator)
//
// File Name:
// MCR.cpp
//
// File Contents:
// Magnetic Card Reader (MCR).
//=============================================================================
#include "system.h"
#include "dev_emcr.h"
#include "MCR.hpp"
#include <iostream>
//-----------------------------------------------------------------------------
//! Constructor. Initializes MCR widget.
//!
//! \param
//! X X coordinate of top left corner.
//! \param
//! Y Y coordinate of top left corner.
//! \param
//! W Width.
//! \param
//! H Height.
//-----------------------------------------------------------------------------
MCR::MCR( int X, int Y, int W, int H ) : Fl_Box( X, Y, W, H, 0 ),
dev_name("/dev/"EMCR_DEV)
{
if ( !init() ) exit(1);
//clear track data
track.assign(0);
//draw interface
box(FL_DOWN_BOX);
color(FL_BLACK);
tooltip("Left click to swipe a card\nRight click to choose the card");
}
//-----------------------------------------------------------------------------
// Gets file size in bytes.
// IN:
// path File path.
// OUT:
// 0 on error and file size otherwise.
//-----------------------------------------------------------------------------
int MCR::file_size( std::string path )
{
struct stat stat_buf;
int err = stat( path.c_str(), &stat_buf );
if (err) return 0; else return stat_buf.st_size;
}
//-----------------------------------------------------------------------------
// Widget event handler.
// IN:
// event Event code
// OUT:
// 1 on FL_PUSH and 0 otherwise.
//-----------------------------------------------------------------------------
int MCR::handle( int event )
{
switch (event)
{
//mouse button released
case FL_RELEASE:
{
color(FL_BLACK); redraw();
//if right mouse released
if( FL_RIGHT_MOUSE == Fl::event_button() )
{
//show "Select file" dialog box
boost::scoped_ptr<Fl_File_Chooser> fc( new Fl_File_Chooser(".", "*.trk", Fl_File_Chooser::SINGLE, "Select Card Track") );
fc->show();
while ( fc->visible() ) Fl::wait();
//get selected file name
const char *name = fc->value();
//file was selected and it has correct size
if ( name && file_size( std::string(name) ) == TRACK_LEN )
{
int trk_fd = open( name, O_RDONLY );
if ( trk_fd )
{
if ( TRACK_LEN != read( trk_fd, track.c_array(), TRACK_LEN ) )
std::cout << "Can't read track from file [" << name << "]" << std::endl;
}
close(trk_fd);
}
}
//if left mouse button released
if( FL_LEFT_MOUSE == Fl::event_button() )
{
int mcr_fd = open( dev_name.c_str(), O_WRONLY );
if ( mcr_fd )
{
if ( TRACK_LEN != write( mcr_fd, track.c_array(), TRACK_LEN ) )
printf( "Swipe emulation failure\n" );
}
close(mcr_fd);
}
break;
}
//mouse button pushed
case FL_PUSH:
{
if ( Fl::event_button() == 1 )
{
color(FL_GREEN); redraw();
}
return 1;
}
}
return 0;
}
//-----------------------------------------------------------------------------
// Class initializtion
// OUT:
// 1 on success and 0 on error.
//-----------------------------------------------------------------------------
int MCR::init( void )
{
int fd = open( dev_name.c_str(), O_WRONLY );
if( fd < 0 ) printf("Card reader driver opening error\n" );
close( fd ) ;
return 0 <= fd;
}
ПРИЛОЖЕНИЕ 3
ФРАГМЕНТЫ ТЕКСТА ПРОГРАММ ЗАГРУЗОЧНЫХ МОДУЛЕЙ
Драйвер эмуляции звукового устройства (zemul_buzz.c):
//=============================================================================
// Company:
// Terminal Technologies Ltd
//
// Product:
// Zemul (POS Emulator)
//
// File Name:
// zemul_buzz.c
//
// File Contents:
// Buzzer emulation driver.
//=============================================================================
#ifndef MODULE
#define MODULE
#endif
#ifndef __KERNEL__
#define __KERNEL__
#endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/ioctl.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/miscdevice.h>
#include <linux/vt_kern.h>
#include "include/dev_buzz.h"
// Beep duty in % (0...100)
static unsigned long duty = 0;
// Beep frequency (between BUZZ_MIN_FREQ and BUZZ_MAX_FREQ)
static unsigned long freq = BUZZ_MIN_FREQ;
// Opened flag
static int opened = 0;
//-----------------------------------------------------------------------------
// open() file operation
//-----------------------------------------------------------------------------
static int buzz_fops_open( struct inode *inode, struct file *filp )
{
if ( opened ) return -EBUSY;
opened++;
nonseekable_open(inode, filp);
return 0;
}
//-----------------------------------------------------------------------------
// close() file operation
//-----------------------------------------------------------------------------
static int buzz_fops_release( struct inode *inode, struct file *filp )
{
opened--;
kd_mksound(0, 0);
return 0;
}
//-----------------------------------------------------------------------------
// ioctl() file operation
//-----------------------------------------------------------------------------
static int buzz_fops_ioctl( struct inode* inode, struct file* flip, unsigned int cmd, unsigned long param )
{
switch ( cmd )
{
case BUZZ_START:
kd_mksound(freq, 0);
break;
case BUZZ_STOP: // Stop sound
kd_mksound(0, 0);
break;
case BUZZ_SET_FREQ: // Set sound frequency
freq = param;
break;
case BUZZ_SET_DUTY: // Set sound duty
duty = param;
break;
default:
return -EINVAL;
}
return 0;
}
//-----------------------------------------------------------------------------
// Definition of file operations
//-----------------------------------------------------------------------------
static struct file_operations buzz_fops =
{
.owner = THIS_MODULE,
.open = buzz_fops_open,
.release = buzz_fops_release,
.ioctl = buzz_fops_ioctl,
.llseek = no_llseek
};
//-----------------------------------------------------------------------------
// Device definition
//-----------------------------------------------------------------------------
static struct miscdevice buzz_dev = {
BUZZ_DEV_MINOR,
BUZZ_DEV,
&buzz_fops
};
//-----------------------------------------------------------------------------
// Driver Init
//-----------------------------------------------------------------------------
static int __init buzzdrv_init(void)
{
printk( "Buzzer Emulation Driver\n" );
misc_register(&buzz_dev);
printk("Registered Misc device (major 10) with minor: %d\n", buzz_dev.minor);
return 0;
}
//-----------------------------------------------------------------------------
// Driver Unload
//-----------------------------------------------------------------------------
static void __exit buzzdrv_exit(void)
{
printk( "Buzzer Emulation Driver\n" );
misc_deregister(&buzz_dev);
}
module_init( buzzdrv_init )
module_exit( buzzdrv_exit )
MODULE_AUTHOR("Terminal Technologies");
MODULE_DESCRIPTION("Buzzer Emulation Driver");
MODULE_LICENSE("GPL");
Драйвер эмуляции принтера (zemul_printer.c):
//=============================================================================
// Company:
// Terminal Technologies Ltd
//
// Product:
// Zemul (POS Emulator)
//
// File Name:
// zemul_printer.c
//
// File Contents:
// Printer emulation driver.
//=============================================================================
#ifndef MODULE
#define MODULE
#endif
#ifndef __KERNEL__
#define __KERNEL__
#endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/ioctl.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/miscdevice.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>
#include "include/dev_printer.h"
#define PRINT_MAX 48 // Maximum line length in bytes
#define PRN_DEF_DARKNESS PRN_MAX_CONTRAST / 2
// Opened flag
static int prn_opened;
// Flag shows if some is ready to be printed
static int buf_ready;
// Current darkness value
static int darkness;
// Printer internal buffer
static char prn_buf[PRINT_MAX];
// Buffer mutex
static struct mutex prn_mutex;
// Waiting queue
wait_queue_head_t waitq;
//-----------------------------------------------------------------------------
// Printer init function
//-----------------------------------------------------------------------------
void prn_init(void)
{
prn_opened = 0;
buf_ready = 0;
darkness = PRN_DEF_DARKNESS;
memset( prn_buf, 0, sizeof(prn_buf) );
}
//-----------------------------------------------------------------------------
// ioctl() file operation
//-----------------------------------------------------------------------------
static int printer_fops_ioctl( struct inode* inode, struct file* flip, unsigned int cmd, unsigned long param )
{
int status = -EINVAL;
mutex_lock(&prn_mutex);
switch ( cmd )
{
// Feed paper command
case PRN_FEED_PAPER:
while(param--)
{
if ( wait_event_interruptible(waitq, !buf_ready) ) break;
memset( prn_buf, 0, sizeof(prn_buf) );
buf_ready = 1;
}
status = 0;
break;
// Set darkness command
case PRN_SET_CONTRAST:
darkness=param;
status = 0;
break;
// Check paper command
case PRN_HAS_PAPER:
status = 0;
break;
// Get printer width command
case PRN_GET_WIDTH:
status = PRINT_MAX * 8;
break;
}
mutex_unlock(&prn_mutex);
return status;
}
//-----------------------------------------------------------------------------
// write() file operation
//-----------------------------------------------------------------------------
static ssize_t printer_fops_write( struct file *filp, const char __user *buffer, size_t length, loff_t *offset )
{
int len = length;
int pos = 0;
mutex_lock(&prn_mutex);
while (len > 0)
{
if ( wait_event_interruptible(waitq, !buf_ready) ) return 0;
memset( prn_buf, 0, sizeof(prn_buf) );
copy_from_user( prn_buf, buffer + pos, (len>PRINT_MAX ? PRINT_MAX : len) );
pos += (len>PRINT_MAX ? PRINT_MAX : len);
len -= PRINT_MAX;
buf_ready = 1;
}
mutex_unlock(&prn_mutex);
return length;
}
//-----------------------------------------------------------------------------
// read() file operation
//-----------------------------------------------------------------------------
static ssize_t printer_fops_read( struct file *filp, char __user *buffer, size_t length, loff_t *offset )
{
if (!buf_ready) return 0;
copy_to_user( buffer, prn_buf, PRINT_MAX );
buf_ready = 0;
wake_up_interruptible( &waitq );
return PRINT_MAX;
}
//-----------------------------------------------------------------------------
// open() file operation
//-----------------------------------------------------------------------------
static int printer_fops_open( struct inode* inode, struct file* filp )
{
if ( ( filp->f_flags & O_ACCMODE ) == O_RDONLY ) return 0;
if ( prn_opened ) return -EBUSY;
prn_opened++;
nonseekable_open(inode,filp);
return 0;
}
//-----------------------------------------------------------------------------
// close() file operation
//-----------------------------------------------------------------------------
static int printer_fops_release( struct inode* inode, struct file* filp )
{
prn_opened--;
return 0;
}
//-----------------------------------------------------------------------------
// Define printer file operations
//-----------------------------------------------------------------------------
static struct file_operations printer_fops =
{
.owner = THIS_MODULE,
.open = printer_fops_open,
.release = printer_fops_release,
.write = printer_fops_write,
.read = printer_fops_read,
.ioctl = printer_fops_ioctl,
.llseek = no_llseek
};
//-----------------------------------------------------------------------------
// Device info
//-----------------------------------------------------------------------------
static struct miscdevice printer_dev = {
PRN_DEV_MINOR,
PRN_DEV,
&printer_fops
};
//-----------------------------------------------------------------------------
// Driver init function
//-----------------------------------------------------------------------------
static int __init printer_init(void)
{
prn_init();
printk("Printer Emulation Driver\n");
init_waitqueue_head(&waitq);
mutex_init(&prn_mutex);
if (misc_register(&printer_dev)) return -ENODEV;
printk("Registered Misc device (major 10) with minor: %d", printer_dev.minor);
return 0;
}
//-----------------------------------------------------------------------------
// Driver unload function
//-----------------------------------------------------------------------------
static void __exit printer_exit(void)
{
printk("Printer Emulation Driver\n");
misc_deregister(&printer_dev);
mutex_destroy(&prn_mutex);
}
module_init(printer_init)
module_exit(printer_exit)
MODULE_AUTHOR("Terminal Technologies");
MODULE_DESCRIPTION("Printer Emulation Driver");
MODULE_LICENSE("GPL");
Драйвер эмуляции считывателя магнитных карт (zemul_mcr.c):
//=============================================================================
// Company:
// Terminal Technologies Ltd
//
// Product:
// Zemul (POS Emulator)
//
// File Name:
// zemul_mcr.c
//
// File Contents:
// Magnetic Card Reader (MCR) emulation driver.
//=============================================================================
#ifndef MODULE
#define MODULE
#endif
#ifndef __KERNEL__
#define __KERNEL__
#endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/ioctl.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/miscdevice.h>
#include <linux/poll.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>
#include "include/dev_emcr.h"
// Data for each of 3 tracks
static char track_data[NUM_EMCR_TRACKS][MAGTEK_TRACK_LEN];
// Hash for each of 3 tracks
static int track_has_data[NUM_EMCR_TRACKS] = {0};
// Opened flag
static int mcr_opened = 0;
// number of track to read
static int track_num = 0;
// FLAG: indicates if magnetic card was swiped
static int swiped = 0;
// MCR mutex
static struct mutex mcr_mutex;
// Wait queue
static wait_queue_head_t wait_q;
// Serial number
static unsigned char serial[MAGTEK_SERIAL_LEN] = "12345678";
// Version
static unsigned char version[MAGTEK_VERSION_LEN] = "0123456789A";
//-----------------------------------------------------------------------------
// Initialize driver variables
//-----------------------------------------------------------------------------
void mag_init(void)
{
track_num = 0;
swiped = 0;
memset( track_data, 0, sizeof(track_data) );
memset( track_has_data, 0, sizeof(track_has_data) );
}
//-----------------------------------------------------------------------------
// write() file operation
//-----------------------------------------------------------------------------
static ssize_t mag_fops_write( struct file *filp, const char __user *buffer, size_t length, loff_t *offset )
{
int i;
char empty[MAGTEK_TRACK_LEN] = {0};
mutex_lock(&mcr_mutex);
// Set track data to NULL
memset( track_data, 0, sizeof(track_data));
// Check length of data to read
if ( length > NUM_EMCR_TRACKS * MAGTEK_TRACK_LEN ) length = NUM_EMCR_TRACKS * MAGTEK_TRACK_LEN;
// Copy track data
copy_from_user(track_data, buffer, length);
// All three tracks have data by default
for( i = 0; i<NUM_EMCR_TRACKS; i++ )
{
track_has_data[i] = (memcmp(empty, track_data[i], MAGTEK_TRACK_LEN) == 0) ? 0 : 1;
}
swiped = 1;
wake_up_interruptible(&wait_q);
mutex_unlock(&mcr_mutex);
return length;
}
//-----------------------------------------------------------------------------
// read() file operation
//-----------------------------------------------------------------------------
ssize_t mag_fops_read(struct file *filp, char __user *buffer, size_t length, loff_t *offset)
{
ssize_t ret = 0;
mutex_lock(&mcr_mutex);
// If specified track has some data to read
if (track_has_data[track_num])
{
// Copy track data to user pointer
copy_to_user( buffer, track_data[track_num], length );
ret = length;
track_has_data[track_num] = 0;
swiped = 0;
}
mutex_unlock(&mcr_mutex);
return ret;
}
//-----------------------------------------------------------------------------
// ioctl() file operation
//-----------------------------------------------------------------------------
static int mag_fops_ioctl( struct inode* inode, struct file* file, unsigned int cmd, unsigned long param )
{
int status = 0;
mutex_lock(&mcr_mutex);
switch (cmd)
{
// Fake control codes
case EMCR_RESET:
case EMCR_VERIFYDEVKEY:
case GET_KEYLOCKPPT:
break;
case GET_ENCRYPTIONPPT:
status = 1;
break;
case GET_SWID:
if (copy_to_user((unsigned char*)param, version, MAGTEK_VERSION_LEN)) status = -EFAULT;
break;
case SET_DEVSERIALNUM:
if (copy_from_user(serial, (unsigned char*)param, MAGTEK_SERIAL_LEN)) status = -EFAULT;
break;
case GET_DEVSERIALNUM:
if (copy_to_user((unsigned char*)param, serial, MAGTEK_SERIAL_LEN)) status = -EFAULT;
break;
// Set track number to read
case SET_EMCRTRACK:
if( 0 <= param && param < NUM_EMCR_TRACKS )
{
swiped = 0;
track_num = param;
}
else status = -EFAULT;
break;
// Indicates that magnetic card was swipped
case EMCR_SWIPED:
status = swiped;
break;
default: status = -ENOIOCTLCMD;
}
mutex_unlock(&mcr_mutex);
return status;
}
//-----------------------------------------------------------------------------
// poll() file operation
//-----------------------------------------------------------------------------
static unsigned int mag_fops_poll(struct file* filp, struct poll_table_struct* wait)
{
unsigned int mask = 0;
poll_wait(filp, &wait_q, wait);
if (swiped) mask |= POLLIN | POLLRDNORM;
return mask;
}
//-----------------------------------------------------------------------------
// open() file operation
//-----------------------------------------------------------------------------
static int mag_fops_open( struct inode* inode, struct file* filp )
{
if ( ( filp->f_flags & O_ACCMODE ) == O_RDONLY ) return 0;
if ( mcr_opened ) return -EBUSY;
mcr_opened=1;
mag_init();
nonseekable_open(inode,filp);
return 0;
}
//-----------------------------------------------------------------------------
// close() file operation
//-----------------------------------------------------------------------------
static int mag_fops_release( struct inode* inode, struct file* filp )
{
mcr_opened=0;
return 0;
}
//-----------------------------------------------------------------------------
// Define file operations for MCR device
//-----------------------------------------------------------------------------
static struct file_operations mag_fops =
{
.owner = THIS_MODULE,
.open = mag_fops_open,
.read = mag_fops_read,
.write = mag_fops_write,
.release = mag_fops_release,
.ioctl = mag_fops_ioctl,
.poll = mag_fops_poll,
.llseek = no_llseek
};
//-----------------------------------------------------------------------------
// MCR device info
//-----------------------------------------------------------------------------
static struct miscdevice mcr_dev = {
EMCR_MINOR,
EMCR_DEV,
&mag_fops
};
//-----------------------------------------------------------------------------
// Driver init function
//-----------------------------------------------------------------------------
static int __init mcr_init(void)
{
int res;
printk("MCR Emulation Driver\n");
init_waitqueue_head(&wait_q);
mutex_init(&mcr_mutex);
mag_init();
res = misc_register(&mcr_dev);
if (res < 0) return res;
printk("Registered Misc device (major 10) with minor: %d", mcr_dev.minor);
return 0;
}
//-----------------------------------------------------------------------------
// Driver unload function
//-----------------------------------------------------------------------------
static void __exit mcr_exit(void)
{
printk("MCR Emulation Driver\n");
misc_deregister(&mcr_dev);
mutex_destroy(&mcr_mutex);
}
module_init(mcr_init)
module_exit(mcr_exit)
MODULE_AUTHOR("Terminal technologies");
MODULE_DESCRIPTION("MCR Emulation Driver");
MODULE_LICENSE("GPL");
ПРИЛОЖЕНИЕ 4
РУКОВОДСТВО ПРОГРАММИСТА
«ПРОГРАММНОЕ СРЕДСТВО ЭМУЛЯЦИИ POS-ТЕРМИНАЛА»
