슬라이드 1

Similar documents
K&R2 Reference Manual 번역본

슬라이드 1

Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100

PowerPoint 프레젠테이션

<322EBCF8C8AF28BFACBDC0B9AEC1A6292E687770>

Microsoft PowerPoint - 3ÀÏ°_º¯¼ö¿Í »ó¼ö.ppt

Poison null byte Excuse the ads! We need some help to keep our site up. List 1 Conditions 2 Exploit plan 2.1 chunksize(p)!= prev_size (next_chunk(p) 3

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C D616E2E637070>

Microsoft PowerPoint - chap03-변수와데이터형.pptx

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

The Pocket Guide to TCP/IP Sockets: C Version

C# Programming Guide - Types

Microsoft PowerPoint - chap13-입출력라이브러리.pptx

BMP 파일 처리

금오공대 컴퓨터공학전공 강의자료

PowerPoint 프레젠테이션

Microsoft PowerPoint - [2009] 02.pptx

< E20C6DFBFFEBEEE20C0DBBCBAC0BB20C0A7C7D12043BEF0BEEE20492E707074>

프로그램을 학교 등지에서 조금이라도 배운 사람들을 위한 프로그래밍 노트 입니다. 저 역시 그 사람들 중 하나 입니다. 중고등학교 시절 학교 도서관, 새로 생긴 시립 도서관 등을 다니며 책을 보 고 정리하며 어느정도 독학으르 공부하긴 했지만, 자주 안하다 보면 금방 잊어

11장 포인터

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202839C1D6C2F7207E203135C1D6C2F >

OCW_C언어 기초

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

비트와바이트 비트와바이트 비트 (Bit) : 2진수값하나 (0 또는 1) 를저장할수있는최소메모리공간 1비트 2비트 3비트... n비트 2^1 = 2개 2^2 = 4개 2^3 = 8개... 2^n 개 1 바이트는 8 비트 2 2

UI TASK & KEY EVENT

PowerPoint 프레젠테이션

목차 포인터의개요 배열과포인터 포인터의구조 실무응용예제 C 2

chap 5: Trees

untitled

03장.스택.key

Microsoft PowerPoint - Chapter_04.pptx

UI TASK & KEY EVENT

Microsoft PowerPoint - C프로그래밍-chap03.ppt [호환 모드]

구조체정의 자료형 (data types) 기본자료형 (primitive data types) : char, int, float 등과같이 C 언어에서제공하는자료형. 사용자정의자료형 (user-defined data types) : 다양한자료형을묶어서목적에따라새로운자료형을

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

OCW_C언어 기초

PowerPoint 프레젠테이션

The Pocket Guide to TCP/IP Sockets: C Version

PowerPoint Presentation

Lab 3. 실습문제 (Single linked list)_해답.hwp

SRC PLUS 제어기 MANUAL



A Hierarchical Approach to Interactive Motion Editing for Human-like Figures

PowerPoint 프레젠테이션

Microsoft PowerPoint 자바-기본문법(Ch2).pptx

thesis

Microsoft PowerPoint - chap01-C언어개요.pptx

PowerPoint 프레젠테이션

슬라이드 1

다른 JSP 페이지호출 forward() 메서드 - 하나의 JSP 페이지실행이끝나고다른 JSP 페이지를호출할때사용한다. 예 ) <% RequestDispatcher dispatcher = request.getrequestdispatcher(" 실행할페이지.jsp");

0. 들어가기 전

Microsoft PowerPoint - chap10-함수의활용.pptx

슬라이드 1

(Asynchronous Mode) ( 1, 5~8, 1~2) & (Parity) 1 ; * S erial Port (BIOS INT 14H) - 1 -

Frama-C/JESSIS 사용법 소개

Chapter #01 Subject

슬라이드 1

이번장에서학습할내용 동적메모리란? malloc() 와 calloc() 연결리스트 파일을이용하면보다많은데이터를유용하고지속적으로사용및관리할수있습니다. 2

T100MD+

5.스택(강의자료).key

컴파일러

02장.배열과 클래스

PowerPoint Presentation

기초컴퓨터프로그래밍

untitled

C++-¿Ïº®Çؼ³10Àå

1.2 자료형 (data type) 프로그램에서다루는값의형태로변수나함수를정의할때주로사용하며, 컴퓨터는선언된 자료형만큼의메모리를확보하여프로그래머에게제공한다 정수 (integer) 1) int(4 bytes) 연산범위 : (-2 31 ) ~ (2 31 /2)-

Microsoft PowerPoint - Lecture_Note_5.ppt [Compatibility Mode]

Microsoft PowerPoint - ch10 - 이진트리, AVL 트리, 트리 응용 pm0600

Microsoft PowerPoint - es-arduino-lecture-03

Mobile Service > IAP > Android SDK [ ] IAP SDK TOAST SDK. IAP SDK. Android Studio IDE Android SDK Version (API Level 10). Name Reference V

PowerPoint Presentation

13주-14주proc.PDF

Microsoft PowerPoint - chap04-연산자.pptx

PowerPoint 프레젠테이션

Microsoft PowerPoint - chap06-2pointer.ppt

슬라이드 1

ISP and CodeVisionAVR C Compiler.hwp

중간고사

untitled

Microsoft PowerPoint - ch07 - 포인터 pm0415

Microsoft PowerPoint - lec2.ppt

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202834C1D6C2F7207E2038C1D6C2F729>

KNK_C_05_Pointers_Arrays_structures_summary_v02

학습목차 2.1 다차원배열이란 차원배열의주소와값의참조

The Pocket Guide to TCP/IP Sockets: C Version

강의 개요

윈도우시스템프로그래밍

Microsoft PowerPoint - chap12-고급기능.pptx

Microsoft Word - FunctionCall

MPLAB C18 C

[ 네트워크 1] 3 주차 1 차시. IPv4 주소클래스 3 주차 1 차시 IPv4 주소클래스 학습목표 1. IP 헤더필드의구성을파악하고요약하여설명할수있다. 2. Subnet ID 및 Subnet Mask 를설명할수있고, 각클래스의사용가능한호스트수와사설 IP 주소및네트

Lab 4. 실습문제 (Circular singly linked list)_해답.hwp

PowerPoint Presentation

Microsoft PowerPoint - 04-UDP Programming.ppt

강의10

<B1E2BCFAB9AEBCAD5FB9DABAB4B1D45F F F64746F72732E687770>

Transcription:

제 1 장개요 1. ASN.1 개요 2. BER 개요 3. CRC 개요 제 2 장프로토콜설명및예제 1. 프로토콜설명 2. 운영정보표시장치태그종류및설명 3. 메시지데이터구조및설명 4. 데이터의 ASN.1 BER Encoding 제 3 장이벤트별 1. 예제 Source 2. 예제 Source 실행결과 3. 예제 Source에대한이벤트별설명 4 5 7 15 16 17 24 26 28 30 31 51 73 2

- 주의사항 - 본설명서는게임제공업소용운영정보표시장치와의통신프로토콜인 ASN.1/BER 에대하여게임개발사에서게임개발시참조를목적으로제공하여드리는것입니다. 본설명서의제공소스및설명은게임기와운영정보표시장치간통신을위한표준통신규격매뉴얼에기초하여작성되어진것입니다. 본설명서및제공된소스에대한오류는책임지지않습니다. 본설명서에서제공된소스를게임제공업소용운영정보표시장치와통신하기위한게임기에사용하는것은게임개발사및관련자의판단이며, 이에대한문의및이의제기는하실수없습니다. 게임제공업소용운영정보표시장치의표준통신규격매뉴얼에서추가이벤트발생또는이벤트삭제등표준통신규격매뉴얼의변경공고시본설명서의내용과일치하지않더라도본설명서내용을근거로이의제기하실수없습니다. 본설명서에서는게임제공업소용운영정보표시장치와통신을위한 ASN.1/BER을설명하고있습니다. 이외에추가적인 ASN.1/BER 지식을습득하시려면마지막장에안내한 RL을참조하시기바랍니다. 본설명서에서제공하는예제소스는 EV-C++ 컴파일러를통해확인하였고, 확인하실수있습니다. (EV-C++ 은 GN General ublic License is a free SoftWare 입니다.) 본설명서에서제공하는예제소스는 Windows 운영체제가있는컴퓨터에서확인되었습니다. 3

Ⅰ 제 1 장 개요 1. ASN.1 개요 2. BER 개요 3. CRC 개요 4

1 1.1. 사용이유 ASN.1 개요 각환경의시스템마다동일한 ata 를표현하는방법이다를수있다. 예제와같이데이터의표현하는방법이다를경우 Byte Swapping 또는 Conversion 이필요하다. Example> 십진수 (EC) 100 = 16 진수 (HEX) 0x64 32 Bit Little Endian rocessor ( 0x00 0x00 0x00 0x64 ) 32 Bit Big Endian rocessor ( 0x64 0x00 0x00 0x00 ) 이러한이유로인하여 System의유형과형태가다변화되면서 Conversion operation의중요성이부각되어 ASN.1을이용하여서로다른환경을갖고있는장비에서동일한데이터를인식하도록하여데이터의오류가생기지않도록한다. Ⅰ 개요 그림 1.1. ASN.1 탄생배경 이기종간통신시기종별유형 / 형태파악후데이터전송 1.2. ASN.1 이란? ASN.1 이기종간통신시 ASN.1 규격으로변환후전송 -> 수신후변환후사용 ASN.1은 Abstract Syntax Notation #1을말하며, 국제전기통신연합 (IT) 에서정의한네트워크상의데이터교환을정의한프로토콜로 X.208에정의되어있다. OSI 참조모델에서 ASN.1 은네트워크관리시스템에있는관리되는개체와같이데이터 Structure를기술하는데사용되는표시법이다. ASN.1 은머신독립적이고많은네트워크콘텍스트에서사용된다. 예를들면 OSI 네트워크관리프레임워크와인터넷 TC/I 프로토콜모음에서온 SNM 양쪽모두에서와같이어플리케이션층의패킷을기술하는데사용된다. ASN.1은각끝점에서다른변조시스템을사용할수있는 ES(End System) 사이의정보를전송하기위한공동 Syntax로서기능한다. 네트워크상에존재하는다양한종류의시스템들은각각데이터를표현하는독특한방식을가지고있다. 따라서네트워크상에서메시지를교환하기위해서는모든시스템에서받아들일수있는형태의호환성있는데이터표현방식을정의할필요가있다. 이러한제반환경에의해서 ASN.1은정의되게되었다. ASN.1에서는 INTEGER나각종 STRING형태의데이터를비롯하여그러한 ASN.1 content들의모임인 SEQENCE나 SET등의데이터표현방식을정의함으로써대부분의네트워크상에서교환되어지는메시지들을 ASN.1 방식에따라서표현할수있도록하였다. 5

1 ASN.1 개요 1.3. ASN.1 Syntax 의기본형식 기본적인 ASN1의기본타입들은 tag number와클래스의 (class) 종류, constructed 인가 primitive인지를나타내는플래그등으로구성된헤더와 base contents의길이그리고 base contents등으로구성된다. CHOICE와 ANY타입을제외한모든 ASN.1의타입은 class와음이아닌 tag number로구성된 tag를가지고있다. tag의클래스에는 niversal, Application, rivate, Context-specific등의클래스가있다. 운영정보표시장치는일반 (niversal) tag class와운영정보표시장치에서정의하여사용하는 Context-specific class 를사용한다. Base content의길이는직접지정하는 definite 형식과길이를 0으로설정하고 base contents가오고마지막에 eoc(end of octet) 를나타내는 0000으로 base contents의끝을나타내는 indefinite형식이있다. Ⅰ 개요 6

2 BER(Basic Encoding Rule) 개요 2.1. 사용이유 네트워크상에서교환되는메시지는 ASN.1형태로구성되어교환된다고하였지만, ASN.1은그자체로는추상적인데이터형식이기때문에그것을그대로전송할수없다. 따라서 ASN.1 형태의추상데이터형식을네트워크상에서전송할수있는형식으로변환시켜야할필요성이있다. Ⅰ 개요 이때사용되는것이 BER(Basic Encoding Rule) 과 ER(istinguished Encoding Rule) 이다. 2.2. BER 개요 BER과 ER은각 ASN.1 형태의데이터형식을네트워크상에서전송할수있는형태로 encoding해주고그것을다시 ASN.1 형태로 decoding해주는방법에대하여정의하고있다. 대부분의 ASN.1 형식에대해서 BER과 ER방식의 encoding 방법은큰차이를보이지않는다. 다만경우에따라서약간의다른점들이존재하며, BER이 ER보다더큰범위의 encoding 방법을정의하고있다. Bit와 Octet의순서는시스템간의동일한데이터의전달을위하며각데이터간및 Bit의순서가동일해야한다. 이러한이유로 BER에서는각 Bit 와 Octet의순서를아래와같이정의하고있다. 그림 1.2. Bit 와 Octet 순서 7

2 BER(Basic Encoding Rule) 개요 2.3. TLV란? 기본부호화규칙 (Basic Encoding Rule) 으로데이터의형태와길이에따라부호화방법이달라지나모두식별자 (Tag), 길이 (Length), 내용 (Value), 내용끝을나타내는 Octet으로표현한다. 2.3.1 식별자 T(Tag) 해당데이터의식별 I 를표시한다. Ⅰ 개요 TAG 구조는기본적으로 0~30까지가정의되어있으며 1바이트로표현한다. 31번이후의 I는 2바이트로표기할수있으나운영정보표시장치에서는 30번까지의 I만을사용하므로별도성명하지않는다. 각비트별내용을살펴보면다음과같이나눌수있다. 표1.1 Tag구조 구분 Bit8 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 내용 Class /C I Number 2.3.1.1 Class( bit7~8 ) 필드 Tag의클래스를나타내는필드로 niversal, Application, rivate, Context-specific등의클래스가있다. 표1.2 Class Field 분류 Class Bit8 Bit7 niversal 0 0 Application, 0 1 Context-specific 1 0 rivate 1 1 위 4가지중운영정보표시장치에서는 niversal, Context-specific 두가지만사용된다. niversal - 기본데이터클래스 Context-specific - 사용자정의클래스 8

2 BER(Basic Encoding Rule) 개요 2.3.1.2 /C( bit6 ) 필드 데이터의 Type 을나타내는필드로다음과같이두가지로구분되어짐. 표 1.3 /C Field 분류 Ⅰ 개요 구분 Bit6 rimitive 0 Constructive 1 rimitive - INTEGER, OCTET STRING 등에해당 Constructive - SEQENCE, SET 에해당 2.3.1.3 I Number( bit5~1 ) 필드 I 의종류를나타내는필드로서클래스에따라다르게정의되어있습니다. 그중기본데이터클래스 (niversal) 를살펴보면다음과같습니다. 표 1.4 I Number Field 분류 - (1/2) 구분 /C Bit5 ~ Bit1 Number (decimal) Number (hexadecimal) EOC (End-of-Content) 0 0 BOOLEAN 1 1 INTEGER 2 2 BIT STRING /C 3 3 OCTET STRING /C 4 4 NLL 5 5 OBJECT IENTIFIER 6 6 Object escriptor 7 7 EXTERNAL C 8 8 REAL (float) 9 9 9

2 BER(Basic Encoding Rule) 개요 표 1.4 I Number Field 분류 - (2/2) 구분 /C Bit5 ~ Bit1 Number (decimal) Number (hexadecimal) ENMERATE 10 A Ⅰ 개요 EMBEE V C 11 B TF8String /C 12 C RELATIVE-OI 13 SEQENCE and SEQENCE OF C 16 10 SET and SET OF C 17 11 NumericString /C 18 12 rintablestring /C 19 13 T61String /C 20 14 VideotexString /C 21 15 IA5String /C 22 16 TCTime /C 23 17 GeneralizedTime /C 24 18 GraphicString /C 25 19 VisibleString /C 26 1A GeneralString /C 27 1B niversalstring /C 28 1C CHARACTER STRING /C 29 1 BMString /C 30 1E BOOLEAN - 논리연산데이터 ( True/Fail ) INTEGER - INTEGER ATA( n BYTE ) OCTET STRING - 문자열 NLL - 데이터없음 NumericString - 숫자배열 10

2 BER(Basic Encoding Rule) 개요 2.3.1.4 I Number Filed중운영정보표시장치에서사용하는 I 설명 SEQENCE 와 SET 의차이점. SEQENCE는 C의 struct와동일한개념이다. SET의개념은 C에는없고, 굳이찾는다면 C의 struct에서순서가무의미한 type으로보면된다. Ⅰ 개요 Example) Seq ::= SEQENCE { first INTEGER, second INTEGER } Set ::= SET { first INTEGER, second INTEGER } seqva1 Seq ::= { 10, 20 } seqval2 Seq ::= { 20, 10 } setval1 Set ::= { 10, 20 } setval2 Set ::= { 20, 10 } seqval1과 seqval2의경우에는서로다른값이지만 setval1과 setval2는동일한값이다. SEQENCE와 SEQENCE OF 차이점이둘은이름만비슷하지전혀다른개념이다. SEQENCE는 C의 struct이고 SEQENCE OF는 C 의 Array선언 [ ] 에해당된다. Name ::= SEQENCE OF INTEGER는 int Name[ ] 과동일한의미이다. SET과 SET OF도유사하다. 11

2 BER(Basic Encoding Rule) 개요 SET OF와 SEQENCE OF 차이점 Ⅰ SEQENCE 와 SET 과차이처럼 Array 내값의순서가의미를가지느냐여부의차이이다. Example) SeqOf ::= SEQENCE OF INTEGER 개요 SetOf ::= SET OF INTEGER seqofval1 SeqOf ::= { 10, 20, 30 } seqofval2 SeqOf ::= { 20, 30, 10 } setofval1 SeqOf ::= { 10, 20, 30 } setofval2 SeqOf ::= { 20, 30, 10 } seqofval1와 seqofval2는다른값이지만 setofval1와 setofval2는동일한값이다. CHOICE 개념 CHOICE는 C의 union과동일한개념이다. CHOICE에값을선언할때선언되어있는 Element중하나를사용하면된다. Example) Choice ::= CHOICE { int INTEGER, string rintablestring } chocieval1 Choice ::= int : 10 choiceval2 Choice ::= string : asn.1 is fun 위의예제는 1997년 ASN.1 표준을따른것이며 : 앞의 int와 string은 Choice의 Alternative의 identifier를가리킨다. 12

2 BER(Basic Encoding Rule) 개요 2.3.2 길이 L(Length) V(Value) 필드의길이를나타내며두가지방법으로나타낸다. a. short form 일경우 ( 1~127 ) 1byte 만으로 V 필드의길이를나타낸다. Ⅰ 개요 bit8은 0으로셋팅, bit7~1는실제길이수록 b. long form일경우 ( 128~ ) 1byte 이상으로 V필드의길이를나타낸다. 첫 byte는 bit8을 1로셋팅하여 long form임나타내고 bit7~1은두번째 byte부터실제길이를나타내기위한 byte 갯수를나타낸다. 두번째 byte부터는길이를나타내는값을수록 Example) 100BYTE( 0x64 ) = 0x64 200BYTE( 0xC8 ) = 0x81 0xC8 300BYTE( 0x012C ) = 0x82 0x01 0x2C 13

2 BER(Basic Encoding Rule) 개요 2.3.3 내용 V(Value) 데이터의내용을나타내며두가지형태로구분된다. a. 실제데이터 실제값을나타낼경우가주로해당이되며 Length 만큼데이터를수록한다. b. 데이터식별자 (Tag) 를시작으로하는데이터 Ⅰ 개요 여러데이터의모임인 Structure와같은종류의데이터표현의경우다시 TLV형태의데이터를수록한다. 즉 T L TLV TLV TLV 와같이데이터를표현할수있다. 2.3.4 TLV 구조예제 struct test{ // SEQENCE Tag( 0x30 ) char a; // 1byte INTEGER Tag( 0x02 ) short b; // 2byte INTEGER Tag( 0x02 ) }; 위 structure와같이선언을하고 test.a = 0x00, test.b = 0x1122의값을저장하기위해변환을한다면다음과같다. Byte1 Byte2 Byte3 Byte4 Byte5 Byte6 Byte7 Byte8 Byte9 T L T L V T L V 0x30 0x07 0x02 0x02 0x11 0x22 byte1 - SEQENCE이며 Constructive Type 이므로 0x30임 byte2 - test struct를나타내기위한전체길이 byte3 - 첫번째데이터가변수임을나타내기위한 Tag ( INTEGER : 0x02 ) byte4 - 첫번째데이터의길이로 char형은 1바이트이므로 1 byte5 - 첫번째데이터의값 0 byte6 - 두번째데이터가변수임을나타내기위한 Tag ( INTEGER : 0x02 ) byte7 - 두번째데이터의길이로 short형에 2바이트데이터이므로 2 byte8~9 - 두번째데이터의값으로 0x11 0x22와같이 BER기본순서대로수록 14

3 CRC 개요 3.1 CRC소개 자료출처 :http://myhome.shinbiro.com/~beechang/pgm_crc.html CRC(Cyclic Redundancy Check) 는시리얼전송에서데이타의신뢰성을검증하기위한에러검출방법의일종이다. 간단한에러검출방법으로는 parity 비트에의한방법과 check-sum에의한에러검출방법이있지만 parity 비트에의한방법은데이타중에한꺼번에 2비트나 4비트가변하게되면검출을할수없고, check-sum에의한방법은한바이트에서 +1, 다른바이트에서는 -1 로에러가생기는경우만해도에러는검출되지않는다. 즉, 이들방법으로는에러를검출해낼수있는확률이대단히낮다. Ⅰ 개요 CRC에의한방법은높은신뢰도를확보하며에러검출을위한오버헤드가적고, 랜덤에러나버스트에러를포함한에러검출에매우좋은성능을갖는것을특징으로한다. 이러한 CRC 방법으로보통 2가지종류가사용되는데, 원칩마이크로프로세서와같이간단한용도에서는 CRC-16 이사용되고, 이보다더욱정확한에러검출이필요한경우에는 CRC-32를사용한다. ZI,ARJ,RAR 과같은압축프로그램이나플로피디스크등의데이터검증용도에널리사용되고있다. 운영정보표시장치에서는 CRC-16(CCITT) 가사용됩니다. 15

Ⅰ 제 2 장 프로토콜설명및예제 1. 프로토콜설명 2. 운영정보표시장치태그종류및설명 3. 메시지데이터구조및설명 4. 데이터의 ASN.1 BER Encoding 16

1 1.1. 게임이벤트 프로토콜설명 게임이시작되거나종료되는등의이벤트가발생할때마다변동사항을 OI로전송해야합니다. 게임기에서 OI로전송하는이벤트는 msgtype이 ELIVER이며, OI에서게임기로전송하는이벤트는 msgtype이 RECEIVE로되어있습니다. 표 2.1. 이벤트 Ⅱ 프로토콜설명및예제 이벤트 CONNECT ( 게임기접속 ) RECEIVE._INT_AMT ( 투입금액 ) ELIVER._OT_AMT ( 이용금액 ) ELIVER._GAME_START ( 게임시작 ) ELIVER._BET_AMT ( 배팅금액 ) ELIVER._WIN_SCORE ( 당첨점수 ) 설명 게임기가부팅되면게임기에서 OI 로연결메시지를전송할때발생되는이벤트입니다. 게임기는부팅되면반드시 OI 와연결되어야하며게임기가종료되기전까지연결상태를유지해야합니다. 게임기와 OI 간최초접속일경우 OI 는게임기에게임초기화키를생성해서 OI 에저장하고게임기에전송해야합니다. 지폐인식기에지폐나통전투입기에코인이투입되었을때 OI 에서게임기로투입금액을전송할때발생되는이벤트입니다. OI 는지폐인식기에지폐나동전투입기에코인이투입되면게임기로투입금액메시지를전송하고게임기는받은금액메시지를 OI 로전송해야합니다. OI 는투입금액과게임기에서받은금액이일치하면지폐인식기나코인기에입수신호를전송합니다. 투입된금액을사용금액 ( 사용점수 ) 로변환하여게임기에서 OI 로전송할때발생되는이벤트입니다. 게임기는지폐나코인입수가완료되면투입금액을사용금액 ( 사용점수 ) 로변환하여 OI 로전송해야하며 OI 는게임기에서수신한사용금액 ( 사용점수 ) 을저장하고 LC 화면에사용금액 ( 사용점수 ) 을표시해야합니다. 게임이시작될때게임시작메시지를게임기에서 OI 로전송할때발생되는이벤트입니다. 게임기에서시작버튼이눌리거나배팅되면게임기는게임시작메시지를 OI 로전송해야합니다. 게임진행시배팅에사용한사용금액 ( 사용점수 ) 을전송하기위해다음과같이패킷을구성하여통신해야합니다. ( 배팅은게임진행중 1 회이상발생할수있습니다 ) 게임기는배팅점수가발생할때마다 OI 로배팅점수를전송해야하고, OI 는저장하고 LC 에배팅점수를표시해야합니다. 게임진행중당첨점수이벤트가발생했을때게임기에서 OI로당첨점수를전송할때발생되는이벤트입니다. 게임진행중당첨점수이벤트가발생하면게임기는 OI로당첨점수를전송해야하며 OI는당첨점수를저장하고 LC화면에당첨점수를표시하고게임기로 RESONSE/Ack해야합니다. 17

1 프로토콜설명 표2.1. 이벤트 ( 계속 ) 이벤트설명 ELIVER._BANK_SCORE ( 누적점수 ) 이전게임까지누적된점수를게임기에서 OI로전송할때발생되는이벤트입니다. 게임기에누적점수이벤트가발생하면게임기는 OI로누적점수를전송하고 OI는누적점수를저장하고 LC화면에누적점수를표시하고게임기로 RESONSE/Ack해야합니다. Ⅱ 프로토콜설명및예제 ELIVER._GAME_EN ( 게임종료 ) ISCONNECT ( 접속해제 ) LINK ( 링크확인 ) RECEIVE._ERROR ( 에러발생 ) RECEIVE._LINK_REQEST ( 링크요구 ) 게임이종료될때게임종료메시지를게임기에서 OI로전송할때발생되는이벤트입니다. 한게임이종료되면게임기는게임종료메시지를 OI로전송해야하며 OI는게임기로 RESONSE/Ack해야합니다. 게임기가 OI와연결을해제하기위하여발생되는이벤트입니다. 게임기가종료되지전게임기는 OI로연결해제메시지를전송해야하며, 연결해제메시지를수신한 OI 는게임기로 RESONSE/Ack하고연결을해제합니다. 게임기가 OI랑정상적으로연결되었다는메시지를게임기에서 OI로전송할때발생되는이벤트입니다. 게임기는 OI와정상연결상태를확인하기위해 180초간격으로 LINK 메시지를 OI 로전송해야하며 OI 는게임기로 RESONSE/Ack해야합니다. 게임기가종료되지전까지게임기는 OI와연결상태를유지해야합니다. 지폐인식기, 판독장치등에서에러가발생했을때 OI에서게임기로에러정보를전송할때발생되는이벤트입니다. 지폐인식기, 판독장치등에에러가발생하면 OI는게임기로에러메시지를전송해야한다. Error Request를수신한게임기는에러코드에해당하는에러메시지를게임기화면에출력해야합니다. 게임기에서연결메시지가오지않을경우 OI에서게임기로연결메시지를요청할때발생되는이벤트입니다. 게임기에서 180초동안 LINK메시지가없을경우 OI는게임기로 LINK REQEST메시지를전송해야합니다. LINK REQEST메시지에게임기의 RESONSE/Ack가없을경우 OI는 LINK REQEST메시지를게임기로다시전송합니다. 3회반복후에도게임기로부터 RESONSE/Ack가없을경우 OI 는모든동작을멈추고부저음과함께에러메시지를표시합니다. 18

1 1.2. 통신 프로토콜설명 통신 는 ASN.1 형식으로작성되었으며자세한설명은추후설명. 통신 OI-GAME EFINITIONS ::= BEGIN Ⅱ 프로토콜설명및예제 GameMsg ::= SEQENCE { } header body GameMsgHeader, GameMsgBody GameMsgHeader ::= SEQENCE { msgtype1 INTEGER (0..255), msgtype2 INTEGER (0..255), returncode INTEGER (0..65535), windowhandle INTEGER (0..4294967295), blockingcode INTEGER (0..255), actionid INTEGER (0..4294967295), version INTEGER (0..255) } GameMsgBody ::= CHOICE { nullata gameinfo gameata } [1]NLL, [2]GameInfo, [3]Gameata GameInfo ::= SEQENCE { gameid gameinitkey } OCTET STRING(SIZE(10)), OCTET STRING(SIZE(16)) Gameata ::= SEQENCE { } EN value1 INTEGER (0..4294967295), value2 INTEGER (0..4294967295) 19

1 1.3 통신 포맷 프로토콜설명 통신 는 OSI 모델에서두시스템간의통신은두시스템의각동위계층들간의통신에의해이루어집니다. 이때각동위계층간의데이타전송의단위를 (rotocol ata nit) 라고합니다. 게임기와운영정보표시장치의통신인터페이스는 RS-232C 기반이며, 통신규약은 ASN.1(Abstract Syntax Notation One) 을사용하고, encoding/decoding은 BER(Basic Encoding Rules) 로합니다. Ⅱ 프로토콜설명및예제 통신 는 GAMEMSG와 2Byte의 CRC 코드로구성되어있습니다. GAMEMSG는 7개의필드로된 HEAER와 BOY로나뉘는데 HEAER에는메시지종류를구분하는 msgtype1, msgtype2가있고통신시에러발생여부를확인하는 returncode가있습니다. windowhandle과 blockingcode는예약필드이며 actionid는메시지순번을나타내는필드이고 version은현재사용중인버전값을확인하기위한필드입니다. BOY의 gameinfo에는 OI주문시공급자로부터발급받은 gamei와게임기가 OI에최초접속시부여받은 gameinitkey로구성되어있고 gameata에는동전투입, 당첨점수, 누적점수등의이벤트가발생했을때해당데이터값을넣는 value1,value2 필드가있습니다. 메시지종류에따라 BOY는 2개의필드중 1개만사용되거나사용되지않습니다. 표 2.2. 통신 포맷 HEAER GAMEMSG BOY CRC msg Type1 msg Type2 return Code windo whand le blocking Code Action Id version nullat a game Info game ata crc 20

1 프로토콜설명 1.4 통신 필드설명 데이터유형 : N1 - Numeric 1Byte, O1 - Octet 1Byte을나타냅니다. 통신규약은 ASN.1기준으로처리하며 encoding/decoding은 BER로합니다. GAMEMSG의 BOY는 msgtype1, msgtype2에따라 gameinfo, gameata 중 1개가사용됩니다. CRC체크값은 GAMEMSG의뒤 2Byte를사용합니다. 시리얼통신시송수신에대한오류를판단하기위해 CRC체크로많이사용되는 CRC-16을사용하고 CCITT에서표준으로사용하는 CRC16-CCITT를사용합니다. 게임초기화키는게임기가 OI에최초접속했을경우 1회만발급합니다. Ⅱ 프로토콜설명및예제 표 2.3. 통신 필드설명 FIELS 유형설명 msgtype1 N1 메시지종류 1 G A M E M S G C R C H E A E R B O Y msgtype2 N1 메시지종류 2 returncode N2 결과코드 (0 : 성공, 이외에러코드 ) windowhandle N4 예약 ( 전달값그대로 ) blockingcode N1 예약 ( 전달값그대로 ) actionid N4 메시지 sequence (Ack시전달값그대로 ) 신규메시지전송시는 n+1 version N1 프로토콜버전 ( 공고한버전값 ) nullata NLL N0 BOY ata가필요없는경우 gameinfo gameata crc OR gameid O10 게임I (GYYMMNNN) gameinit Key O16 게임초기화키 OR value1 N4 게임데이터 value2 N4 게임데이터 ( 예약 ) N2 GAMEMSG fields 의 CRC check 시리얼통신시송수신에대한오류를판단하기위해 CRC 체크로많이사용되는 CRC-16 을사용 CCITT 에서표준으로사용하는 CRC16-CCITT olynomial function = x^16+x^12+x^5+1, (0x1021), 초기값 = 0(zero) 추가되는 CRC 2Byte 값은반드시 BigEndian /Network orderby 로표현한다. 예 ) crc = htons(crc) 21

1 1.5. 메시지타입설명 프로토콜설명 게임기와 OI가최초 CONNECT시 OI는게임기에 gameinitkey를생성해야합니다. 이후접속시게임기는내부에저장되어있는 gameid와 gameinitkey를이용해서 OI에접속해야합니다. RECEIVE 명령은 OI에서게임기로먼저데이터를전송하고게임기에서응답을받는형태이고, 그외명령은게임기에서 OI로먼저데이터를전송하고 OI에서응답을받는형태입니다. 모든메시지의 Ack는동일한 Header에 returncode 0 이면성공, 실패이면 0 이외의값을설정하여리턴하도록해야합니다. Ⅱ 프로토콜설명및예제 표 2.4. 메시지타입설명 msgtype1 msgtype2 COE CONTENTS CONNECT - 0x01 0x00 초기접속요구 ISCONNECT - 0x02 0x00 접속종료요구 _OT_AMT 0x01 이용금액 _BET_AMT 0x02 배팅점수 ELIVER _WIN_SCORE 0x03 0x03 당첨점수 _BANK_SCORE 0x04 누적점수 _GAME_START 0x05 게임시작 _GAME_EN 0x06 게임종료 LINK - 0x04 0x00 연결확인 _INT_AMT 0x01 투입금액 RECEIVE _LINK_REQEST 0x05 0x02 링크메시지요구 _ERROR 0x03 에러신호 게임초기화키는게임기가 OI에접속시최초 1회만생성되며, 각장치 ( 게임기,OI) 별로저장하여관리해야합니다. 링크메시지요구 (RECEIVE, _LINK_REQEST) 게임기는 Link 메시지를 180초주기로운영정보표시장치로전송해야합니다. 표시장치는게임기로부터 180초동안아무런메시지가없을경우 Link 메시지를요구합니다. **Link요구메시지를보내 3회응답이없으면표시장치는알람표시하고모든기능중지 22

1 프로토콜설명 vari 는 OI 주문시공급자로부터발급받은 gamei 입니다. varkey 는게임기가 OI 에최초접속시 OI 가발급해준 gameinitkey 값입니다. ErrorCode 는에러발생코드입니다. varerr 는에러에종류에따라필요한데이터가입력되는값입니다 연결이벤트 표 2.4.1 메시지타입설명 필드구분 msg Type 1 msg Type 2 retu rn Cod e GAMEMSG HEAER windo w Handl e blocki ng Code acti on I versi on CONNECT 0x01 0x00 0x00 - - n+1 0x01 BOY CRC 아래참조 crc gameinfo gameid gameinitk ey vari varkey Ⅱ 프로토콜설명및예제 ISCONNECT 0x02 0x00 0x00 - - n+1 0x01 nullata ELIVER._OT_AMT 0x03 0x01 0x00 - - n+1 0x01 ELIVER._BET_AMT 0x03 0x02 0x00 - - n+1 0x01 ELIVER._WIN_SCORE 0x03 0x03 0x00 - - n+1 0x01 ELIVER._BANK_SCORE 0x03 0x04 0x00 - - n+1 0x01 gameata value1 value2 이용금액 - gameata value1 value2 배팅금액 - gameata value1 value2 당첨점수 - gameata value1 value2 누적점수 - ELIVER._GAME_START 0x03 0x05 0x00 - - n+1 0x01 nullata ELIVER._GAME_EN 0x03 0x06 0x00 - - n+1 0x01 nullata LINK 0x04 0x00 0x00 - - n+1 0x01 RECEIVE._INT_AMT 0x05 0x01 0x00 - - n+1 0x01 gameinfo gameid gameinitk ey vari varkey gameata value1 value2 투입금액 - RECEIVE._LINK_REQEST 0x05 0x02 0x00 - - n+1 0x01 nullata RECEIVE._ERROR 0x05 0x03 0x00 - - n+1 0x01 gameata value1 value2 ErrCode - 23

2 운영정보표시장치태그종류및설명 2.1 niversal TAG 표 2.5. niversal TAG 종류 구분 /C Bit5 ~ Bit1 Number (decimal) Number (hexadecimal) EOC (End-of-Content) 0 0 BOOLEAN 1 1 Ⅱ 프로토콜설명및예제 INTEGER 2 2 BIT STRING /C 3 3 OCTET STRING /C 4 4 NLL 5 5 OBJECT IENTIFIER 6 6 Object escriptor 7 7 EXTERNAL C 8 8 REAL (float) 9 9 ENMERATE 10 A EMBEE V C 11 B TF8String /C 12 C RELATIVE-OI 13 SEQENCE and SEQENCE OF C 16 10 SET and SET OF C 17 11 NumericString /C 18 12 rintablestring /C 19 13 T61String /C 20 14 VideotexString /C 21 15 IA5String /C 22 16 TCTime /C 23 17 GeneralizedTime /C 24 18 GraphicString /C 25 19 VisibleString /C 26 1A 24

2 운영정보표시장치태그종류및설명 표 2.5. niversal TAG 종류 ( 계속 ) 구분 /C Number (decimal) Bit5 ~ Bit1 Number (hexadecimal) GeneralString /C 27 1B niversalstring /C 28 1C Ⅱ 프로토콜설명및예제 CHARACTER STRING /C 29 1 BMString /C 30 1E 위 31가지의 TAG가있으며운영정보표시장치에서는다음과같은 4개의 TAG를사용한다. SEQENCE( 0x10 ) : 데이터구조체시작 Integer( 0x02 ) : int 형데이터 ( 4byte ) Octet string( 0x04 ) : char 배열 Null( 0x05 ) : 데이터없음 2.2 Context-specific Class TAG 운영정보표시장치의메시지중 Body의종류를구분하기위한 TAG. 이 TAG는운영정보표시장치와의통신을위해구성한 TAG I이므로 /C bit6는 Constructive(1), class bit8~7은 Context-specific class( 10 ) 으로셋팅되어아래와같이구분되어진다. 표 2.6. Context-specific Class TAG 종류및설명 Name Hex code 설명 NOTHING 0xA0 사용안함 Null ata 0xA1 Null 데이터 GameInfo ata 0xA2 게임 I 및 INIT Key Game ata 0xA3 게임이벤트데이터 25

3 메시지데이터구조및설명운영정보표시장치통신규격매뉴얼에나와있는 필드를구조체와공용체를사용하여변수로 다음과같이선언이가능하다. 메시지데이터구조및설명 typedef int NLL_t; // NLL ATA 필드구조유지를위한변수선언시사용 typedef struct GameMsgHeader { // } GameMsgHeader_t; unsigned char msgtype1; unsigned char msgtype2; unsigned short returncode; unsigned long windowhandle; unsigned char blockingcode; unsigned long actionid; unsigned char version; Ⅱ 프로토콜설명및예제 typedef enum GameMsgBody_R { // GameMsgBody_R_NOTHING,/* No components present */ GameMsgBody_R_nullata, GameMsgBody_R_gameInfo, GameMsgBody_R_gameata, } GameMsgBody_R; typedef struct GameInfo { // unsigned unsigned char gameid[10]; char gameinitkey[16]; } GameInfo_t; typedef struct Gameata { // unsigned unsigned long value1; long value2; } Gameata_t; 26

3 메시지데이터구조및설명 메시지데이터구조및설명 ( 계속 ) typedef struct GameMsgBody { // GameMsgBody_R present; union GameMsgBody_u { NLL_t GameInfo_t Gameata_t } choice; } GameMsgBody_t; nullata; gameinfo; gameata; Ⅱ 프로토콜설명및예제 typedef struct GameMsg { GameMsgHeader_t GameMsgBody_t header; body; } GameMsgStruct; GameMsgStruct GAME_MSG; header 의 7 가지항목은변하지않으므로 structure 로구성이되며값의변동이없다. BOY 의종류별순서를정의 (Context-specific TAG) 한다. 게임기의 Info 정보전송시사용하는 body structure로 I는 10바이트 InitKey는 16바이트문자열값을가진다. 게임이벤트처리시데이터로 2 개의 4byte 값을 body structure 로구성한다. body는크게 3가지로구분되어있으므로어떤 body인지선택변수를생성하고공용체를사용하여선택에따른 body을사용할수있도록 structure로구성한다. 27

4 데이터의 ASN.1 BER Encoding 구조체변수를 ASN.1 BER 변환을하기위해먼저 TLV형식으로표현하면다음과같이두종류로 표현이되어집니다. a. Body NLL ATA b. Body Info or ATA TL TL TLV TLV TLV TLV TLV TLV TLV TL TL TL TL TLV TLV TLV TLV TLV TLV TLV TL TL TLV TLV 위두종류에서의차이점은 Body의데이터가 NLL일경우데이터가없으므로 Length가 0이되어서 Tag와 Length만으로표현이되어집니다. Ⅱ 프로토콜설명및예제 자세히살펴보면다음과같다. T L : Tag = SEQENCE( 0x30 ), L = Total Length 메시지전체 Structure의시작이므로 TAG는 SEQENCE, Length는전체데이터의 Size가된다. T L : Tag = SEQENCE( 0x30 ), L = Header Length 메시지헤더 Structure의시작이므로 TAG는 SEQENCE, Length는헤더데이터의 Size가된다. T L V : Tag = Integer( 0x02 ), L = ata Length, V = MsgType1 메시지헤더중 MsgType1의값이므로 TAG는 Integer, Length는데이터의 Size가된다. T L V : Tag = Integer( 0x02 ), L = ata Length, V = MsgType2 메시지헤더중 MsgType2의값이므로 TAG는 Integer, Length는데이터의 Size가된다. T L V : Tag = Integer( 0x02 ), L = ata Length, V = returncode 메시지헤더중 returncode의값이므로 TAG는 Integer, Length는데이터의 Size가된다. T L V : Tag = Integer( 0x02 ), L = ata Length, V = windowhandle 메시지헤더중 windowhandle의값이므로 TAG는 Integer, Length는데이터의 Size가된다. T L V : Tag = Integer( 0x02 ), L = ata Length, V = blockingcode 메시지헤더중 blockingcode의값이므로 TAG는 Integer, Length는데이터의 Size가된다. T L V : Tag = Integer( 0x02 ), L = ata Length, V = actionid 메시지헤더중 actionid의값이므로 TAG는 Integer, Length는데이터의 Size가된다. T L V : Tag = Integer( 0x02 ), L = ata Length, V = version 메시지헤더중 version의값이므로 TAG는 Integer, Length는데이터의 Size가된다. 28

4 데이터의 ASN.1 BER Encoding T L : Tag = Context-specific( 0xA1~0xA3 ), L = Body Total Length 메시지 BOY Structure의종류를선택하는 TAG이므로 Context-specific클래스 TAG, Length는 BOY Structure의 Size가된다. T L : Tag = SEQENCE( 0x30 ) or NLL( 0x05 ), L = Body data Length Body의종류에 Structure와 NLL이틀려지므로 SEQENCE와 NLL의 TAG을가지고 Length는 Structure일경우 size를 NLL일경우 0이된다. T L V : Tag = Integer( 0x02 ) or Octet string( 0x04 ), L = ata Length, V = Body ata 1 Ⅱ 프로토콜설명및예제 Body data 중첫번째의값이므로 TAG 는 Integer, Length 는데이터의 Size 가된다. T L V : Tag = Integer( 0x02 ) or Octet string( 0x04 ), L = ata Length, V = Body ata 2 Body data 중두번째의값이므로 TAG 는 Integer, Length 는데이터의 Size 가된다. 29

Ⅰ 제 3 장 이벤트별 1. 예제 Source 2. 예제 Source 실행결과 3. 예제 Source 에대한이벤트별설명 30

1 예제Source 운영정보표시장치이벤트별설명을위한예제는다음과같으며, 아래의 Source를바탕으로설명합니다. 예제 Source /****************************************************************** * Title : ASN.1 BER encoding and decoding sample source * Language : C Language * Compiler : ev-c++ V4.9.9.2 * Version : 1.0 * Edit Tabs : 4 ******************************************************************/ /*================================================================= REVISION HISTORY =================================================================*/ /*2009-08-19 AM - Created the program - Version 1.0*/ /*----------------------------------------------------------------- EFINES... -----------------------------------------------------------------*/ /*------------------------------------------------------------- INCLE FILES -------------------------------------------------------------*/ #include <stdio.h> #include <stdlib.h> /*------------------------------------------------------------- VARIABLES EFINES -------------------------------------------------------------*/ #define TRE 1 #define FALSE 0 // BOOLEAN Value define #define LITTLE_ENIAN_SYSTEM 1 #define BIG_ENIAN_SYSTEM 0 // Endian Type Value define #define EF_GAME_I_SIZE 10 #define EF_GAME_INITKEY_SIZE 16 // 게임 I,init key 크기값으로고정되어있으므로수정불가 typedef int NLL_t; // NLL ATA 필드구조유지를위한변수선언시사용 31

1 예제 Source 예제 Source( 계속 ) typedef struct GameMsgHeader { unsigned char msgtype1; unsigned char msgtype2; unsigned short returncode; unsigned long windowhandle; unsigned char blockingcode; unsigned long actionid; unsigned char version; } GameMsgHeader_t; typedef enum GameMsgBody_R { GameMsgBody_R_NOTHING,/* No components present */ GameMsgBody_R_nullata, GameMsgBody_R_gameInfo, GameMsgBody_R_gameata, } GameMsgBody_R; typedef struct GameInfo { unsigned char gameid[10]; unsigned char gameinitkey[16]; } GameInfo_t; typedef struct Gameata { unsigned long value1; unsigned long value2; } Gameata_t; typedef struct GameMsgBody { GameMsgBody_R present; union GameMsgBody_u { NLL_t nullata; GameInfo_t gameinfo; Gameata_t gameata; } choice; } GameMsgBody_t; typedef struct GameMsg { GameMsgHeader_t header; GameMsgBody_t body; } GameMsgStruct; 32

1 예제 Source 예제 Source( 계속 ) GameMsgStruct GAME_MSG; unsigned char endian_type; //--------------------------------------------------------------------------- /* CRC16 implementation acording to CCITT standards */ static const unsigned short crc16tab[256]= { 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485, 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b, 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d, 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab, 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 }; //CRC16 계산을위한테이블로수정하면안된다. 33

1 예제 Source 예제 Source( 계속 ) /*----------------------------------------------------------------- FNCTIONS... -----------------------------------------------------------------*/ /*------------------------------------------------------------- * crc16_ccitt * * escription : CRC16( CCITT 표준 ) 계산함수 * Arguments : *buf = 계산할데이터포인터, len = 길이 * Return : crc result * Notes : -------------------------------------------------------------*/ unsigned short crc16_ccitt(unsigned char *buf, unsigned long len) { register unsigned long counter; register unsigned short crca = 0; // CRC16 연산버퍼 for( counter = 0; counter < len; counter++){ crca = ( crca << 8 ) ^ crc16tab[ ( ( crca >> 8 ) ^ *( char * )buf++ ) & 0x00FF ]; } // CRC16 연산 return crca; // 결과리턴 } /*------------------------------------------------------------- * check_crc16 * * escription : CRC16을사용한데이터검증함수 * Arguments: crc = 기준 CRC값, *buf = 검증데이터포인터, sz = size * Return : 검증결과 * Notes: -------------------------------------------------------------*/ int check_crc16(int crc, unsigned char *buf, unsigned long sz) { unsigned short tcrc = crc16_ccitt(buf, sz); // if( crc == tcrc ) return TRE; // return FALSE; // } 34

1 예제 Source 예제 Source( 계속 ) /*------------------------------------------------------------- * calintegerlength * escription : integer data의표현에필요한 SIZE 계산 * Arguments: src_dat = 데이터 * Return : SIZE ( 값이 0 일경우 FALSE ) * Notes : -------------------------------------------------------------*/ int calintegerlength( unsigned long src_dat ) { if( src_dat <= 0x000000ff ) { return 1; } else if( src_dat <= 0x0000ffff ) { return 2; } else if( src_dat <= 0x00ffffff ) { return 3; } else if( src_dat <= 0xffffffff ) { return 4; } else return FALSE; } /*------------------------------------------------------------- * calintegertochar * escription : integer data를 BIG endian 출력 * Arguments: src_dat = 데이터, sz = integer data real size, * *out_dat = 데이터를출력할변수포인터 * Return : * Notes : -------------------------------------------------------------*/ void calintegertochar( unsigned long src_dat, unsigned int sz, unsigned char *out_dat ) { unsigned long tmp; int i,z; tmp = src_dat; if(!endian_type ) // *1 z = 0; else z = sz - 1; for( i = 0 ; i < sz ; i++ ) { out_dat[i] = *(((char *)&tmp)+z); // *2 if(!endian_type ) // *1 z++; else z--; } } //*1 system endian 에따라서출력이 Big endian 이될수있도록포인터증가또는감소. //*2 Integer data 를 Big endian char 배열로출력 35

1 예제 Source 예제 Source( 계속 ) /*------------------------------------------------------------- * calchartointeger * escription : BIG endian Char data를 integer 데이터로출력 * Arguments : src_dat = 데이터, sz = integer data real size, * *out_dat = 데이터를출력할변수포인터 * Return : * Notes : -------------------------------------------------------------*/ unsigned long calchartointeger( unsigned char *src_dat, unsigned int sz ) { unsigned long tmp; int i,z; tmp = 0; if(!endian_type ) // *1 z = 0; else z = sz - 1; for( i = 0 ; i < sz ; i++ ) { *( (char *)&tmp + i ) = src_dat[z]; // *2 if(!endian_type ) // *1 z++; else z--; } return tmp; } //*1 Big endian char data 를 integer 로변환시 system endian 에맞도록포인터증가또는감소. //*2 Big endian char 배열을이용하여 system endian 에맞는 integer data 로저장. /*------------------------------------------------------------- * callength * escription : Length feild 의값을계산 * Arguments: src_dat = 데이터, *out_sz = 길이값 * Return : Length 표현을위한 byte 수 * Notes : -------------------------------------------------------------*/ int callength( unsigned char *src_dat, unsigned int *out_sz ) { unsigned long tmp; unsigned long tmp_sz; int i; if( ( src_dat[0] & 0x80 ) == 0 ) // short or long form check { // short form 1~127 *out_sz = src_dat[0]; return 1; } 36

1 } 예제 Source 예제 Source( 계속 ) else { // long form 128~ tmp_sz = src_dat[0] & 0x7F; if( tmp_sz > 4 ) return FALSE; // 길이표현을위한최대자리수제한. tmp = 0; for( i = 0 ; i < tmp_sz ; i++ ) { tmp = tmp << 8; tmp = src_dat[ 1 + i ]; } *out_sz = tmp; return ( tmp_sz + 1 ); } /*------------------------------------------------------------- * asnencode * * escription : ASN.1 BER ENCOING * Arguments: *src_dat = 변환할메시지데이터 struct 포인터, * *out_dat = 변환후데이터출력포인터 * Return : 출력데이터 SIZE ( 값이 0 일경우 FALSE ) * Notes : -------------------------------------------------------------*/ int asnencode( GameMsgStruct *src_dat, unsigned char *out_dat ) { int index,total_size,header_size,body_size; unsigned int tmp_size[10]; unsigned long tmp_dat[10]; unsigned int i,z; tmp_dat[0] = src_dat->header.msgtype1; tmp_dat[1] = src_dat->header.msgtype2; tmp_dat[2] = src_dat->header.returncode; tmp_dat[3] = src_dat->header.windowhandle; tmp_dat[4] = src_dat->header.blockingcode; tmp_dat[5] = src_dat->header.actionid; tmp_dat[6] = src_dat->header.version; for( i = 0 ; i < 7 ; i++ ) { tmp_size[i] = calintegerlength(tmp_dat[i]); } header_size = 0; 37

1 예제 Source 예제 Source( 계속 ) for( i = 0 ; i < 7 ; i++ ) { header_size += tmp_size[i] + 2; } printf("header size : %d(0x%02x)\r\n",header_size,header_size); switch( src_dat->body.present ) { case GameMsgBody_R_nullata: printf("nll ATA "); body_size = 2; break; case GameMsgBody_R_gameInfo: printf("game Info ATA "); body_size = 32; break; case GameMsgBody_R_gameata: printf("game event ATA "); body_size = 2 + 2 + calintegerlength( src_dat- >body.choice.gameata.value1 ) + 2 + calintegerlength( src_dat- >body.choice.gameata.value2 ); break; default: printf("body NOT FIN\r\n"); return FALSE; break; } printf("body size : %d(0x%02x)\r\n",body_size,body_size); total_size = 2 + header_size + 2 + body_size; printf("total size : %d(0x%02x)\r\n",total_size,total_size); index = 0; out_dat[ index++ ] = 0x30; // 전체 struct start tag out_dat[ index++ ] = total_size; // 전체 struct size printf("0x%02x 0x%02X \r\n",out_dat[ index - 2 ],out_dat[ index - 1 ]); out_dat[ index++ ] = 0x30; // header struct start tag out_dat[ index++ ] = header_size; // header struct size printf("0x%02x 0x%02X \r\n",out_dat[ index - 2 ],out_dat[ index - 1 ]); for( i = 0 ; i < 7 ; i++ ) { out_dat[ index++ ] = 0x02; // INTEGER tag out_dat[ index++ ] = tmp_size[i]; // size printf("0x%02x 0x%02X ",out_dat[ index - 2 ],out_dat[ index - 1 ]); calintegertochar( tmp_dat[i], tmp_size[i], &out_dat[ index ] ); //value index += tmp_size[i]; for( z = tmp_size[i] ; z > 0 ; z-- ) { printf("0x%02x ",out_dat[ index - z ]); } printf("\r\n"); } 38

1 예제 Source 예제 Source( 계속 ) switch( src_dat->body.present ) { case GameMsgBody_R_nullata: out_dat[ index++ ] = 0xA1; // body Context-specific tag out_dat[ index++ ] = body_size; // body struct size printf("0x%02x 0x%02X \r\n",out_dat[ index - 2 ],out_dat[ index - 1 ]); out_dat[ index++ ] = 0x05; // NLL tag out_dat[ index++ ] = body_size - 2; // NLL size printf("0x%02x 0x%02X \r\n",out_dat[ index - 2 ],out_dat[ index - 1 ]); break; case GameMsgBody_R_gameInfo: out_dat[ index++ ] = 0xA2; // body Context-specific tag out_dat[ index++ ] = body_size; // body struct size printf("0x%02x 0x%02X \r\n",out_dat[ index - 2 ],out_dat[ index - 1 ]); out_dat[ index++ ] = 0x30; // body data struct start tag out_dat[ index++ ] = body_size - 2; // body data struct size printf("0x%02x 0x%02X \r\n",out_dat[ index - 2 ],out_dat[ index - 1 ]); out_dat[ index++ ] = 0x04; // Octet String tag out_dat[ index++ ] = EF_GAME_I_SIZE; // game id size printf("0x%02x 0x%02X ",out_dat[ index - 2 ],out_dat[ index - 1 ]); for( i = 0 ; i < EF_GAME_I_SIZE ; i++ ) { out_dat[ index++ ] = src_dat- >body.choice.gameinfo.gameid[i]; // game id data save printf("0x%02x ",out_dat[ index - 1 ]); } printf("\r\n"); out_dat[ index++ ] = 0x04; // Octet String tag out_dat[ index++ ] = EF_GAME_INITKEY_SIZE; // game id size printf("0x%02x 0x%02X ",out_dat[ index - 2 ],out_dat[ index - 1 ]); for( i = 0 ; i < EF_GAME_INITKEY_SIZE ; i++ ) { out_dat[ index++ ] = src_dat- >body.choice.gameinfo.gameinitkey[i]; // game id data save printf("0x%02x ",out_dat[ index - 1 ]); } printf("\r\n"); break; 39

1-1 ]); - 1 ]); 예제 Source 예제 Source( 계속 ) 2 ],out_dat[ index - 1 ]); case GameMsgBody_R_gameata: out_dat[ index++ ] = 0xA3; // body Context-specific tag out_dat[ index++ ] = body_size; // body struct size printf("0x%02x 0x%02X \r\n",out_dat[ index - 2 ],out_dat[ index default: return index; } out_dat[ index++ ] = 0x30; // body data struct start tag out_dat[ index++ ] = body_size - 2; // body data struct size printf("0x%02x 0x%02X \r\n",out_dat[ index - 2 ],out_dat[ index tmp_dat[7] = src_dat->body.choice.gameata.value1; tmp_size[7] = calintegerlength(tmp_dat[7]); tmp_dat[8] = src_dat->body.choice.gameata.value2; tmp_size[8] = calintegerlength(tmp_dat[8]); for( i = 7 ; i < 9 ; i++ ) { out_dat[ index++ ] = 0x02; // INTEGER tag out_dat[ index++ ] = tmp_size[i]; // size printf("0x%02x 0x%02X ",out_dat[ index - printf("\r\n"); } break; return FALSE; break; } calintegertochar( tmp_dat[i], tmp_size[i], &out_d at[ index ] ); //value index += tmp_size[i]; for( z = tmp_size[i] ; z > 0 ; z-- ) { printf("0x%02x ",out_dat[ index - z ]); } 40

1 예제 Source 예제 Source( 계속 ) /*------------------------------------------------------------- * asnecode * escription : ASN.1 BER ECOING * Arguments: *src_dat = 변환할메시지데이터포인터, * *out_dat = 변환후데이터출력포인터 * Return : 결과 TRE/FALSE * Notes : -------------------------------------------------------------*/ int asnecode( unsigned char *src_dat, GameMsgStruct *out_dat ) { int index,total_size,header_size,body_size; int len_sz; unsigned int tmp_size[10]; unsigned long tmp_dat[10]; int i,rtn; index = 0; if( src_dat[ index++ ]!= 0x30 ) return FALSE; // 전체 struct start tag 확인 len_sz = callength( &src_dat[ index ],&total_size); index += len_sz; printf("total struct size : %d(0x%x)\r\n",total_size,total_size); if( src_dat[ index++ ]!= 0x30 ) return FALSE; // header struct start tag 확인 len_sz = callength( &src_dat[ index ],&header_size); index += len_sz; printf("header struct size : %d(0x%x)\r\n",header_size,header_ size); for( i = 0 ; i < 7 ; i++ ) { if( src_dat[ index++ ]!= 0x02 ) return FALSE; // integer tag 확인 len_sz = callength( &src_dat[ index ], &tmp_size[ i ] ); index += len_sz; tmp_dat[i] = calchartointeger( &src_dat[ index ], tmp_size[ i ] ) ; index += tmp_size[ i ]; } out_dat->header.msgtype1 = tmp_dat[0]; out_dat->header.msgtype2 = tmp_dat[1]; out_dat->header.returncode = tmp_dat[2]; out_dat->header.windowhandle = tmp_dat[3]; out_dat->header.blockingcode = tmp_dat[4]; out_dat->header.actionid = tmp_dat[5]; out_dat->header.version = tmp_dat[6]; printf("msgtype1 : %d(0x%08x)\r\n",out_dat->header.msgtype1,out_dat->header.msgtype1); printf("msgtype2 : %d(0x%08x)\r\n",out_dat->header.msgtype2,out_dat->header.msgtype2); printf("returncode : %d(0x%08x)\r\n",out_dat->header.returncode,out_dat->header.returncod e); printf("windowhandle : %d(0x%08x)\r\n",out_dat->header.windowhandle,out_dat->header.win dowhandle); printf("blockingcode : %d(0x%08x)\r\n",out_dat->header.blockingcode,out_dat->header.blocki ngcode); printf("actionid : %d(0x%08x)\r\n",out_dat->header.actionid,out_dat->header.actionid); printf("version : %d(0x%08x)\r\n",out_dat->header.version,out_dat->header.version); 41

1 예제 Source 예제 Source( 계속 ) switch( src_dat[ index++ ] ) // body Context-specific tag check { case 0xA1:// GameMsgBody_R_nullata: printf("nll ATA\r\n"); out_dat->body.present = 1; rtn = FALSE; if( ( out_dat->header.msgtype1 == 0x02 ) && ( out_dat->header.msgtype2 == 0x00 ) ) rtn = TRE; if( ( out_dat->header.msgtype1 == 0x03 ) && ( ( out_dat->header.msgtype2 == 0x05 ) ( out_dat->header.msgtype2 == 0x06 ) ) ) rtn = TRE; if( ( out_dat->header.msgtype1 == 0x05 ) && ( out_dat->header.msgtype2 == 0x02 ) ) rtn = TRE; if( rtn == FALSE ) return FALSE; len_sz = callength( &src_dat[ index ],&body_size); index += len_sz; printf("body struct size : %d(0x%x)\r\n",body_size,body_size); if( src_dat[ index++ ]!= 0x05 ) return FALSE; // body struct start tag 확인 out_dat->body.choice.nullata = 0; body_size = 2; break; case 0xA2:// GameMsgBody_R_gameInfo: printf("game Info ATA\r\n"); rtn = FALSE; if( ( out_dat->header.msgtype1 == 0x01 ) && ( out_dat->header.msgtype2 = = 0x00 ) ) rtn = TRE; if( ( out_dat->header.msgtype1 == 0x04 ) && ( out_dat->header.msgtype2 == 0x00 ) ) rtn = TRE; if( rtn == FALSE ) return FALSE; out_dat->body.present = 2; len_sz = callength( &src_dat[ index ],&body_size); index += len_sz; printf("body struct size : %d(0x%x)\r\n",body_size,body_size); if( src_dat[ index++ ]!= 0x30 ) return FALSE; // body struct start tag 확인 len_sz = callength( &src_dat[ index ],&body_size); index += len_sz; printf("game info struct size : %d(0x%x)\r\n",body_size,body_size); if( src_dat[ index++ ]!= 0x04 ) return FALSE; // Octet string tag 확인 len_sz = callength( &src_dat[ index ], &tmp_size[ 7 ] ); index += len_sz; printf("game info I : "); for( i = 0 ; i < tmp_size[ 7 ]; i++ ) { out_dat->body.choice.gameinfo.gameid[i] = src_dat[ index++ ]; printf("0x%02x ",out_dat->body.choice.gameinfo.gameid[i]); } printf("\r\n"); if( src_dat[ index++ ]!= 0x04 ) return FALSE; // Octet string tag 확인 len_sz = callength( &src_dat[ index ], &tmp_size[ 8 ] ); index += len_sz; printf("game info Init Key : "); 42

1 예제 Source 예제 Source( 계속 ) for( i = 0 ; i < tmp_size[ 8 ]; i++ ) { out_dat->body.choice.gameinfo.gameinitkey[i] = src_dat[ index++ ]; printf("0x%02x ",out_dat->body.choice.gameinfo.gameinitkey[i]); } printf("\r\n"); body_size = 32; break; case 0xA3:// GameMsgBody_R_gameata: printf("game event ATA\r\n"); rtn = FALSE; if( ( out_dat->header.msgtype1 == 0x03 ) && ( ( out_dat- >header.msgtype2 > 0x00 ) && ( out_dat->header.msgtype2 <= 0x04 ) ) ) rtn = TRE; if( ( out_dat->header.msgtype1 == 0x05 ) && ( ( out_dat->header.msgtype2 == 0x01 ) ( out_dat->header.msgtype2 == 0x03 ) ) ) rtn = TRE; if( rtn == FALSE ) return FALSE; out_dat->body.present = 3; len_sz = callength( &src_dat[ index ],&body_size); index += len_sz; printf("body struct size : %d(0x%x)\r\n",body_size,body_size); if( src_dat[ index++ ]!= 0x30 ) return FALSE; // body struct start tag 확인 len_sz = callength( &src_dat[ index ],&body_size); index += len_sz; printf("game event data struct size : %d(0x%x)\r\n",body_size,body_size); for( i = 7 ; i < 9 ; i++ ) { if( src_dat[ index++ ]!= 0x02 ) return FALSE; // integer tag 확인 len_sz = callength( &src_dat[ index ], &tmp_size[ i ] ); index += len_sz; tmp_dat[i] = calchartointeger( &src_dat[ index ], tmp_size[ i ] ); index += tmp_size[ i ]; } out_dat->body.choice.gameata.value1 = tmp_dat[7]; out_dat->body.choice.gameata.value2 = tmp_dat[8]; printf("value1 : %d(0x%08x)\r\n",out_dat- >body.choice.gameata.value1,out_dat->body.choice.gameata.value1); printf("value2 : %d(0x%08x)\r\n",out_dat- >body.choice.gameata.value2,out_dat->body.choice.gameata.value2); break; default: printf("body NOT FIN\r\n"); out_dat->body.present = 0; return FALSE; break; } return TRE; } 43

1 예제 Source 예제 Source( 계속 ) int main(int argc, char *argv[]) { unsigned char asn_ber_buf[1024]; GameMsgStruct asn_game_msg; int i; int asn_ber_buf_size; printf("/******************************************************************\r\n"); printf("* Title : ASN.1 BER encoding and decoding sample source\r\n"); printf("* Language : C Language\r\n"); printf("* Compiler : ev-c++ V4.9.9.2\r\n"); printf("* Version : 1.0\r\n"); printf("* System Endian : "); i = 0x00000001; endian_type = *((char *)&i); if( endian_type ) printf( "Little Endian\r\n" ); else printf( "Big Endian\r\n" ); printf("******************************************************************/\r\n"); system("ase"); printf("================ OI CONNECT EVENT =====================\r\n"); memset(asn_ber_buf,0,sizeof(asn_ber_buf)); GAME_MSG.header.msgType1 = 0x01; GAME_MSG.header.msgType2 = 0; GAME_MSG.header.returnCode = 0; GAME_MSG.header.windowHandle = 0; GAME_MSG.header.blockingCode = 0; GAME_MSG.header.actionId = 0; GAME_MSG.header.version = 1; GAME_MSG.body.present = 2; // game info for( i = 0 ; i < EF_GAME_I_SIZE ; i++ ) GAME_MSG.body.choice.gameInfo.gameId[i] = '0' + i; for( i = 0 ; i < EF_GAME_INITKEY_SIZE ; i++ ) GAME_MSG.body.choice.gameInfo.gameInitKey[i] = 'A' + i; asn_ber_buf_size = asnencode( &GAME_MSG, asn_ber_buf ); if( asn_ber_buf_size ) { printf("asn.1 BER Encoding ATA : \r\n"); for( i = 0 ; i < asn_ber_buf_size ; i++ ) { printf("0x%02x ",asn_ber_buf[i]); } printf("\r\n"); printf("crc16 CCITT ATA : 0x%04X\r\n",crc16_ccitt( asn_ber_buf,asn_ber_buf_size ) ); } printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); if(!asnecode( asn_ber_buf, &asn_game_msg ) ) printf("ecoding FAIL\r\n"); printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); system("ase"); printf("================ OI ISCONNECT EVENT ==================\r\n"); memset(asn_ber_buf,0,sizeof(asn_ber_buf)); 44

1 예제 Source 예제 Source( 계속 ) GAME_MSG.header.msgType1 = 0x02; GAME_MSG.header.msgType2 = 0; GAME_MSG.header.returnCode = 0; GAME_MSG.header.windowHandle = 0; GAME_MSG.header.blockingCode = 0; GAME_MSG.header.actionId = 0; GAME_MSG.header.version = 1; GAME_MSG.body.present = 1; //NLL asn_ber_buf_size = asnencode( &GAME_MSG, asn_ber_buf ); if( asn_ber_buf_size ) { printf("asn.1 BER Encoding ATA : \r\n"); for( i = 0 ; i < asn_ber_buf_size ; i++ ) { printf("0x%02x ",asn_ber_buf[i]); } printf("\r\n"); printf("crc16 CCITT ATA : 0x%04X\r\n",crc16_ccitt( asn_ber_buf,asn_ber_buf_size ) ); } printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); if(!asnecode( asn_ber_buf, &asn_game_msg ) ) printf("ecoding FAIL\r\n"); printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); system("ase"); printf("================ OI _OT_AMT EVENT =====================\r\n"); memset(asn_ber_buf,0,sizeof(asn_ber_buf)); GAME_MSG.header.msgType1 = 0x03; GAME_MSG.header.msgType2 = 0x01; GAME_MSG.header.returnCode = 0; GAME_MSG.header.windowHandle = 0; GAME_MSG.header.blockingCode = 0; GAME_MSG.header.actionId = 0; GAME_MSG.header.version = 1; GAME_MSG.body.present = 3; // game data GAME_MSG.body.choice.gameata.value1 = 500; GAME_MSG.body.choice.gameata.value2 = 0; asn_ber_buf_size = asnencode( &GAME_MSG, asn_ber_buf ); if( asn_ber_buf_size ) { printf("asn.1 BER Encoding ATA : \r\n"); for( i = 0 ; i < asn_ber_buf_size ; i++ ) { printf("0x%02x ",asn_ber_buf[i]); } printf("\r\n"); printf("crc16 CCITT ATA : 0x%04X\r\n",crc16_ccitt( asn_ber_buf,asn_ber_buf_size ) ); } printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); 45

1 예제 Source 예제 Source( 계속 ) if(!asnecode( asn_ber_buf, &asn_game_msg ) ) printf("ecoding FAIL\r\n"); printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); system("ase"); printf("================ OI _BET_AMT EVENT =====================\r\n"); memset(asn_ber_buf,0,sizeof(asn_ber_buf)); GAME_MSG.header.msgType1 = 0x03; GAME_MSG.header.msgType2 = 0x02; GAME_MSG.header.returnCode = 0; GAME_MSG.header.windowHandle = 0; GAME_MSG.header.blockingCode = 0; GAME_MSG.header.actionId = 0; GAME_MSG.header.version = 1; GAME_MSG.body.present = 3; // game data GAME_MSG.body.choice.gameata.value1 = 500; GAME_MSG.body.choice.gameata.value2 = 0; asn_ber_buf_size = asnencode( &GAME_MSG, asn_ber_buf ); if( asn_ber_buf_size ) { printf("asn.1 BER Encoding ATA : \r\n"); for( i = 0 ; i < asn_ber_buf_size ; i++ ){ printf("0x%02x ",asn_ber_buf[i]); } printf("\r\n"); printf("crc16 CCITT ATA : 0x%04X\r\n",crc16_ccitt(asn_ber_buf,asn_ber_buf_size ) ); } printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); if(!asnecode( asn_ber_buf, &asn_game_msg ) ) printf("ecoding FAIL\r\n"); printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); system("ase"); printf("================ OI _WIN_SCORE EVENT =====================\r\n"); memset(asn_ber_buf,0,sizeof(asn_ber_buf)); GAME_MSG.header.msgType1 = 0x03; GAME_MSG.header.msgType2 = 0x03; GAME_MSG.header.returnCode = 0; GAME_MSG.header.windowHandle = 0; GAME_MSG.header.blockingCode = 0; GAME_MSG.header.actionId = 0; GAME_MSG.header.version = 1; GAME_MSG.body.present = 3; // game data GAME_MSG.body.choice.gameata.value1 = 500; GAME_MSG.body.choice.gameata.value2 = 0; asn_ber_buf_size = asnencode( &GAME_MSG, asn_ber_buf ); if( asn_ber_buf_size ) { printf("asn.1 BER Encoding ATA : \r\n"); for( i = 0 ; i < asn_ber_buf_size ; i++ ){ printf("0x%02x ",asn_ber_buf[i]); } printf("\r\n"); printf("crc16 CCITT ATA : 0x%04X\r\n",crc16_ccitt( asn_ber_buf,asn_ber_buf_size ) ); } printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); r\n"); 46

1 예제 Source 예제 Source( 계속 ) if(!asnecode( asn_ber_buf, &asn_game_msg ) ) printf("ecoding FAIL\r\n"); printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); system("ase"); printf("================ OI _BANK_SCORE EVENT =====================\r\n"); memset(asn_ber_buf,0,sizeof(asn_ber_buf)); GAME_MSG.header.msgType1 = 0x03; GAME_MSG.header.msgType2 = 0x04; GAME_MSG.header.returnCode = 0; GAME_MSG.header.windowHandle = 0; GAME_MSG.header.blockingCode = 0; GAME_MSG.header.actionId = 0; GAME_MSG.header.version = 1; GAME_MSG.body.present = 3; // game data GAME_MSG.body.choice.gameata.value1 = 500; GAME_MSG.body.choice.gameata.value2 = 0; asn_ber_buf_size = asnencode( &GAME_MSG, asn_ber_buf ); if( asn_ber_buf_size ) { printf("asn.1 BER Encoding ATA : \r\n"); for( i = 0 ; i < asn_ber_buf_size ; i++ ) { printf("0x%02x ",asn_ber_buf[i]); } printf("\r\n"); printf("crc16 CCITT ATA : 0x%04X\r\n",crc16_ccitt( asn_ber_buf,asn_ber_buf_size ) ); } printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); if(!asnecode( asn_ber_buf, &asn_game_msg ) ) printf("ecoding FAIL\r\n"); printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); system("ase"); printf("================ OI GAME START EVENT =====================\r\n"); memset(asn_ber_buf,0,sizeof(asn_ber_buf)); GAME_MSG.header.msgType1 = 0x03; GAME_MSG.header.msgType2 = 0x05; GAME_MSG.header.returnCode = 0; GAME_MSG.header.windowHandle = 0; GAME_MSG.header.blockingCode = 0; GAME_MSG.header.actionId = 0; GAME_MSG.header.version = 1; GAME_MSG.body.present = 1; // NLL data asn_ber_buf_size = asnencode( &GAME_MSG, asn_ber_buf ); if( asn_ber_buf_size ) { printf("asn.1 BER Encoding ATA : \r\n"); for( i = 0 ; i < asn_ber_buf_size ; i++ ) { printf("0x%02x ",asn_ber_buf[i]); } printf("\r\n"); printf("crc16 CCITT ATA : 0x%04X\r\n",crc16_ccitt( asn_ber_buf,asn_ber_buf_size ) ); } printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); 47

1 예제 Source 예제 Source( 계속 ) if(!asnecode( asn_ber_buf, &asn_game_msg ) ) printf("ecoding FAIL\r\n"); printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); system("ase"); printf("================ OI GAME EN EVENT =====================\r\n"); memset(asn_ber_buf,0,sizeof(asn_ber_buf)); GAME_MSG.header.msgType1 = 0x03; GAME_MSG.header.msgType2 = 0x06; GAME_MSG.header.returnCode = 0; GAME_MSG.header.windowHandle = 0; GAME_MSG.header.blockingCode = 0; GAME_MSG.header.actionId = 0; GAME_MSG.header.version = 1; GAME_MSG.body.present = 1; // NLL data asn_ber_buf_size = asnencode( &GAME_MSG, asn_ber_buf ); if( asn_ber_buf_size ) { printf("asn.1 BER Encoding ATA : \r\n"); for( i = 0 ; i < asn_ber_buf_size ; i++ ) { printf("0x%02x ",asn_ber_buf[i]); } printf("\r\n"); printf("crc16 CCITT ATA : 0x%04X\r\n",crc16_ccitt( asn_ber_buf,asn_ber_buf_size ) ); } printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); if(!asnecode( asn_ber_buf, &asn_game_msg ) ) printf("ecoding FAIL\r\n"); printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); system("ase"); printf("================ OI LINK EVENT =====================\r\n"); memset(asn_ber_buf,0,sizeof(asn_ber_buf)); GAME_MSG.header.msgType1 = 0x04; GAME_MSG.header.msgType2 = 0; GAME_MSG.header.returnCode = 0; GAME_MSG.header.windowHandle = 0; GAME_MSG.header.blockingCode = 0; GAME_MSG.header.actionId = 0; GAME_MSG.header.version = 1; GAME_MSG.body.present = 2; // game info for( i = 0 ; i < EF_GAME_I_SIZE ; i++ ) GAME_MSG.body.choice.gameInfo.gameId[i] = '0' + i; for( i = 0 ; i < EF_GAME_INITKEY_SIZE ; i++ ) GAME_MSG.body.choice.gameInfo.gameInitKey[i] = 'A' + i; asn_ber_buf_size = asnencode( &GAME_MSG, asn_ber_buf ); if( asn_ber_buf_size ) { printf("asn.1 BER Encoding ATA : \r\n"); for( i = 0 ; i < asn_ber_buf_size ; i++ ) { printf("0x%02x ",asn_ber_buf[i]); } printf("\r\n"); printf("crc16 CCITT ATA : 0x%04X\r\n",crc16_ccitt( asn_ber_buf,asn_ber_buf_size ) ); } printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); 48

1 예제 Source 예제 Source( 계속 ) if(!asnecode( asn_ber_buf, &asn_game_msg ) ) printf("ecoding FAIL\r\n"); printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); system("ase"); printf("================ OI S_INT_AMT EVENT =====================\r\n"); memset(asn_ber_buf,0,sizeof(asn_ber_buf)); GAME_MSG.header.msgType1 = 0x05; GAME_MSG.header.msgType2 = 0x01; GAME_MSG.header.returnCode = 0; GAME_MSG.header.windowHandle = 0; GAME_MSG.header.blockingCode = 0; GAME_MSG.header.actionId = 0; GAME_MSG.header.version = 1; GAME_MSG.body.present = 3; // game data GAME_MSG.body.choice.gameata.value1 = 500; GAME_MSG.body.choice.gameata.value2 = 0; asn_ber_buf_size = asnencode( &GAME_MSG, asn_ber_buf ); if( asn_ber_buf_size ) { printf("asn.1 BER Encoding ATA : \r\n"); for( i = 0 ; i < asn_ber_buf_size ; i++ ) { printf("0x%02x ",asn_ber_buf[i]); } printf("\r\n"); printf("crc16 CCITT ATA : 0x%04X\r\n",crc16_ccitt( asn_ber_buf,asn_ber_buf_size ) ); } printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); if(!asnecode( asn_ber_buf, &asn_game_msg ) ) printf("ecoding FAIL\r\n"); printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); system("ase"); printf("================ OI _LINK_REQEST EVENT =====================\r\n"); memset(asn_ber_buf,0,sizeof(asn_ber_buf)); GAME_MSG.header.msgType1 = 0x05; GAME_MSG.header.msgType2 = 0x02; GAME_MSG.header.returnCode = 0; GAME_MSG.header.windowHandle = 0; GAME_MSG.header.blockingCode = 0; GAME_MSG.header.actionId = 0; GAME_MSG.header.version = 1; GAME_MSG.body.present = 1; // NLL data asn_ber_buf_size = asnencode( &GAME_MSG, asn_ber_buf ); if( asn_ber_buf_size ) { printf("asn.1 BER Encoding ATA : \r\n"); for( i = 0 ; i < asn_ber_buf_size ; i++ ) { printf("0x%02x ",asn_ber_buf[i]); } printf("\r\n"); printf("crc16 CCITT ATA : 0x%04X\r\n",crc16_ccitt( asn_ber_buf,asn_ber_buf_size ) ); } printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n"); if(!asnecode( asn_ber_buf, &asn_game_msg ) ) printf("ecoding FAIL\r\n"); 49