MISTERY

IPC라는게 필요한 배경??

p1, p2, p3라는 프로세스가 있습니다. p1이 작업중에 문제가 생겼는데, 만일 p2나 p3같은 다른 주소공간을 침범(write)해 버린다면?

즉, p2나 p3의 스택영역을 건드린다면 정말 큰 문제가 발생하겠지요!!

이것은 "비정상공유" 가 이뤄진 것인데, 아주 큰 문제입니다.

그래서 커널은 이것을 막기위해 Protection 을 합니다.

 

Protection ??

커널은 임의의 프로세스가 다른 프로세스의 주소공간에 접근(access)하는 것을 금지하는 것입니다.

그러고는 오직 커널만이 모든 프로세스의 주소공간에 접근할 수 있도록 합니다. 커널은 신뢰되는 것이기 때문이지요. 그래서 디바이스 드라이버를 작성하든 뭘하든 커널을 잘못 건드리면 전체 시스템이 잘못될수 있는거구요.

 그렇다면, 프로세스 사이에서 데이터 통신을 수행해야 하는 경우에는 어떻게 해야 할까요??

  

IPC (Inter-Process Communication) 란??

프로세스 사이의 데이터통신은 IPC를 통해서 합니다. IPC는 영문 약자 그대로 "프로세스 간 통신"이라는 뜻이구요, 커널은 프로세스 통신을 위해 다양한 IPC매커니즘을 제공합니다.

 프로세스는 IPC를 통하여 다른 프로세스에게 데이터를 송신하거나, 다른 프로세스로부터 데이터를 수신할 수 있습니다.

 IPC가 필요한 예로는 :

LCD에 출력할 문자 메세지를 전달하거나,

센서로부터 읽은 값을 다른 프로세스한테 전달하거나,

디스플레이에 그릴 비트맵 데이터를 전달하는 등등...

 

수도없이 많은 예가 있겠네요!

 

IPC의 종류??

IPC의 종류는 여러가지가 있겠지만, 대표적으로

 

1. 시그널 (Signal)

2. 파이프 (Pipe)

3. 메세지 큐 (Message Queue)

4. 공유 메모리 (Shared Memory)

5. 메일박스 (Mailbox)

 

등등 을 들수 있겠습니다~

 

 

1. 시그널 (Signal)

예전에 상훈이가 스터디때 강조했던 시그널은 임의의 프로세스에세 특정 이벤트가 발생했다는 사실을 알려주는 매커니즘이지요.

(예를들어, 리눅스에서 Ctrl + C 가 눌리면 SIGINT시그널이 프로세스에 전달되어 중단되는 것처럼)
이것은 이벤트 발생 -> 시그널 전달 -> 시그널 처리 의 순으로 진행됩니다.

시그널의 종류는 운영체제에서 미리 정의하며, 그러므로 운영체제에 따라서 다르겠지요.

근데 엄밀히 말해서 시그널은 신호를 발생시키는 매커니즘이고, 데이터를 전달하는 매커니즘은 아닙니다.

시그널 전달이 이뤄지는 과정은 다음과 같습니다.

일단 PCB(Process Control Block ; 리눅스에서 task_struct 같은~ )에 시그널 개수만큼 미리 확보된 시그널 벡터가 있습니다.

시그널 개수만큼 확보되어있기 때문에, 평소에는 0으로 clear되어 있다가 해당 시그널이 발생하면 그 bit만 1로 set 해주면 되는것이지요.

즉, 3번 시그널이 전달되면 3번 시그널벡터가 1로 set되는 것입니다.

시그널이 발생하면, 프로세스는 기존의 수행 흐름에서 벗어나, 해당 시그널 핸들러를 수행합니다.

시그널 핸들러는 커널이 지정해놓을 수도 있고(예를들어 프로세스 종료, 시그널 무시, 프로세스 중지, 실행 재개 등등) 사용자가 특정 기능을 수행하는 코드도 등록해 놓을 수 있습니다.

시그널 핸들러는 시그널 공간 할당 후에 함수포인터를 만들어서 시그널을 처리할 함수의 주소를 가리키도록 해놓는 방식으로 구현하게 됩니다.

시그널에 대해 더 자세히 알고싶으시면 카페에서 시그널로 검색하시면 됩니다ㅋㅋ

그렇다면 이제 데이터를 통신하는 IPC 매커니즘에 대해 알아봅시다.

 

2. 파이프(Pipe)

파이프는 프로세스 사이에 형식없는(unstructured) 데이터의 교환을 가능케 합니다. 파이프를 통해 전달되는 데이터는 단순한 바이트 스트림 형태로 전달됩니다.

파이프는 말그대로 파이프처럼 생겼다고 생각하시면 됩니다.

프로세스1 =>  파이프  =>  프로세스2     요렇게 되는것입니다.

리눅스에서 쉘명령어중에   |   <- 요것도 파이프입니다.

많이들 쓰시다시피 ls | grep ~~ 이런식으로 많이 쓰지요. 이것의 뜻은 "ls의 출력을 grep의 입력으로!" 라는 뜻이지요.

파이프의 특징은 다음과 같습니다.

- 파이프 안의 데이터는 바이트스트림(형식 없는 데이터)로 취급되기 때문에, 여러 메세지 객체가 쓰여졌을 때, 메세지의 경계를  분간할 수 없습니다.

- 또한 파이프는 FIFO(First In First Out)방식으로 데이터를 처리하므로, 메세지가 파이프에 들어온 순서대로 처리됩니다.

- 파이프는 고정된 크기(용량)을 갖습니다.

- 파이프의 데이터가 용량을 초과하면, 파이프에 데이터를 쓰는 프로세스는 "블록" 상태가 됩니다. 파이프에 쓰려고 하는데 파이프 용량이 꽉 찼으니 파이프가 데이터 쓰기 가능 상태가 되기 전까지 블록되는 것 입니다~!

 - 반대로, 파이프가 텅 비어있으면, 파이프에서 데이터를 읽는 프로세스는 "블록" 상태가 됩니다. 파이프에서 데이터 읽으려고 하는데 파이프가 비어있으니, 파이프에 데이타가 쓰여져서 그걸 읽기전까지 블록되는 것 이지요!!

 

3. 메세지큐(Message Queue)

메세지큐는 파이프와 유사하게 프로세스들 간의 데이터통신(메세지 통신)을 위한 IPC입니다.

하지만, 메세지는 structured data이기 떄문에, 경계가 구분 가능합니다. 그러므로 하나의 메세지큐 안에 여러개의 메세지를 버퍼링 할 수 있습니다!

또한 FIFO, LIFO(Last In First Out) 을 모두 지원하며, 고정된 크기를 갖습니다.

메세지큐는 다음과 같은 구조를 가지고 있습니다.

------------------------------------------------------

송신큐 => 메세지큐 => 수신큐

------------------------------------------------------

요기서 송신 프로세스가 자기 주소공간에서  메세지큐 주소공간으로 보낼 것을 복사하게 되고, 메세지큐는 자기 복사된 것을 수신 프로세스의 주소공간으로 복사하는 방식으로 동작합니다.

이렇게 되면 복사가 2번 일어나므로 overhead 이죠!

그래서 많은 양의 데이터를 전송하는 프로그램이 있다면 2번의 메모리 복사는 큰 부담입니다.

결과적으로, 많은 양의 데이터를 전달할 때에는 데이터 대신 그 데이터를 가리키고 있는 포인터만 전달하는 방법을 사용합니다.

메세지큐 사용시에 메세지 송수신을 양방향으로 이루어지게 하면 클라이언트/서버 시스템 설계에 사용할 수 있습니다.

 

4. 공유 메모리 (Shared Memory)

공유 메모리는 두 개 이상으 프로세스가 특정한 메모리 영역을 공유하는 것을 말합니다. 이 공유메모리 영역에 대한 쓰기와 읽기작업을 통해 데이터통신이 가능한 것입니다.

이 공유메모리를 사용할 때 가장 중요한것은 Race Condition이 일어나지 않도록 동기화 매커니즘을 적절히 사용하는 것입니다.

예전에 말했던 쓰레드개념도 이와 비슷하지요. 지역 변수는 각각 가지지만, 전역 변수는 여러 쓰레드(태스크)가 공유할 수 있기 때문에 공유 메모리를 사용하는 것입니다.

 

5. 메일박스 (Mailbox)

메일박스는 메세지큐와 비슷한데, 구현이 훨씬 간단하고 단순한 기능을 가집니다. 한 개의 메세지를 전달할 수 있는 IPC입니다.

 

 

 

 

 

 

출처 : http://cafe.naver.com/cmenia/3068

 

 

 

 

 

 

 

신고

'Skill > Interface' 카테고리의 다른 글

프로세스간 통신(IPC ; Inter-Process Communication)  (1) 2014.04.02
Socket 에 대한 기본지식  (1) 2014.03.03
MAXIM 스마트 카드 I/F 원리  (0) 2014.02.26

Comment +1

  • IPC 는 inter process comunication 이다

    즉 한 컴퓨터 내부에 있는 프로세스 간의 통신 기법

    shared memory나 세마포어, pipe 등이 있고,
    socket도 IPC 로 사용할 수 있으나 보통은 외부 컴퓨터와 연결에 사용 됨.

    내부 프로세서 기리 통신하는 거라면 ipc
    외부 프로세서랑 통신할려면 tcp/udp 를 사용

    etc. RPC, RMI, DCOM

소켓옵션

완성이 되면 docbook(:12)에 추가될 것이다.

네트워크 환경은 매우 다양하며, 예측하기 힘든경우도 많이 발생한다. 때문에 네트워크프로그램의 종류에 따라서 소켓의 세부사항을 조절해야 하는 경우가 발생한다. 이러한 소켓옵션 설정을 위해서 소켓은 getsockopt()와 setsockopt()두개의 함수를 제공한다. 이름에서 알 수 있듯이 getsockopt는 현재의 소켓옵션값을 가져오기 위해서, setsockopt는 소켓옵션값을 변경하기 위해서 사용한다.

예를 들자면 동일한 네트워 프로그램이라고 하더라도 ATM망에서 작동하는 것과 인터넷망 PPP에서 작동하는 것은 환경에 있어서 차이가 생길 수 밖에 없을 것이다. 소켓버퍼의 크기를 예로 들자면, 일반적으로 (대역폭 * 지연율) * 2의 공식에 따를 경우 최적의 효과를 보여준다고 한다. 다음은 이들 함수의 사용방법이다.
#include <sys/types.h>
#include <sys/socket.h>

int  getsockopt(int  s, int level, int optname, void *optval, socklen_t *optlen);
int setsockopt(int s, int  level,  int  optname,  const  void  *optval, socklen_t optlen);
  • s : 소켓지정번호
  • level : 소켓의 레벨로 어떤 레벨의 소켓정보를 가져오거나 변경할 것인지를 명시하며, SOL_SOCKETIPPROTO_TCP 중 하나를 사용할 수 있다.
  • optname : 설정을 위한 소켓옵션의 번호
  • optval : 설정값을 저장하기 위한 버퍼의 포인터
  • optlen : optval 버퍼의 크기

설정값을 void * 로 넘기는 이유는 설정하고자 하는 소켓옵션에 따라서, boolean, interger, 구조체등 다양한 크기를 가지는 데이터형이 사용되기 때문이다. 만약 변경하고자 하는 소켓옵션이 boolean(:12)을 따른다면, 0혹은 1이 사용될 것이다.

SOL_SOCKET레벨에서 사용할 수 있는 옵션과 데이타형은 다음과 같다.

옵션값 데이터형 설명
SO_BROADCAST BOOL 브로드캐스트 메시지 전달이 가능하도록 한다.
SO_DEBUG BOOL 디버깅 정보를 레코딩 한다.
SO_DONTLINGER BOOL 소켓을 닫을때 보내지 않은 데이터를 보내기 위해서 블럭되지 않도록 한다.
SO_DONTROUTE BOOL 라우팅 하지 않고 직접 인터페이스로 보낸다.
SO_GROUP_PRIORITY int 사용하지 않음
SO_KEEPALIVE BOOL Keepalives를 전달한다.
SO_LINGER struct LINGER 소켓을 닫을 때 전송되지 않은 데이터의 처리 규칙
SO_RCVBUF int 데이터를 수신하기 위한 버퍼공간의 명시
SO_REUSEADDR BOOL 이미 사용된 주소를 재사용 (bind) 하도록 한다.
SO_SNDBUF int 데이터 전송을 위한 버퍼공간 명시

IPPROTO_TCP레벨에서 사용할 수 있는 옵션과 데이터형이다.
TCP_NODELAY BOOL Nagle 알고리즘 제어

SO_REUSEADDR

간단한 예로, 소켓을 이용한 서버프로그램(:12)을 운용하다 보면 강제종료되거나 비정상 종료되는 경우가 발생한다. 테스트를 목적으로 할 경우에는 특히 강제종료 시켜야 하는 경우가 자주 발생하는데, 강제종료 시키고 프로그램을 다시 실행시킬경우 다음과 같은 메시지를 종종 보게 된다.
bind error : Address already in use
이는 기존 프로그램이 종료되었지만, 비정상종료된 상태로 아직 커널이 bind(2)정보를 유지하고 있음으로 발생하는 문제다. 보통 1-2분 정도 지나만 커널이 알아서 정리를 하긴 하지만, 그 시간동안 기달려야 한다는 것은 상당히 번거로운 일이 될 것이다. 이 경우 다음과 같은 코드를 삽입함으로써 문제를 해결할 수 있다.
int sock = socket(...);
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&bf, (int)sizeof(bf));
이렇게 하면 커널은 기존에 bind로 할당된 소켓자원을 프로세스(:12)가 재 사용할 수 있도록 허락하게 된다.

다음은 소켓버퍼의 크기를 가져오고 설정하는 완전한 코드다.
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
  int sockfd;
  int bufsize;
  int rn;

  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  {
    perror("Error");
    return 1;
  }

  rn = sizeof(int);
  // 현재 RCVBUF 값을 얻어온다.
  if (getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &bufsize, (socklen_t *)&rn) < 0)
  {
    perror("Set Error");
    return 1;
  }
  printf("Socket RCV Buf Size is %d\n", bufsize);

  // 버퍼의 크기를 100000 으로 만든다.
  bufsize = 100000;
  if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (void *)&bufsize, (socklen_t)rn) < 0)
  {
    perror("Set Error");
    return 1;
  }
  return 0;
}

TCP_NODELAY

이 옵션을 이해하려면 Nagle알고리즘에 대해서 이해를 해야 한다. Nagle 알고리즘(:12)이 적용되면, 운영체제(:12)는 패킷(:12)을 ACK가 오기를 기다렸다가 도착하면, 그 동안 쌓여있던 데이터를 한꺼번에 보내게 된다. 이러한 방식을 사용하게 되면, 대역폭이 낮은 WAN에서 빈번한 전송을 줄이게 됨으로 효과적인 대역폭활용이 가능해진다.

대부분의 경우에 있어서 Nagle 알고리즘은 효율적으로 작동하긴 하지만, 빈번한 응답이 중요한 서비스의 경우에는 적당하지 않은 경우가 발생한다. 예를 들어 X-Terminal을 이용할 경우 마우스 이벤트는 즉시 전달될 필요가 있는데, Nagle알고리즘을 사용하면 아무래도 반응시간이 떨어지게 될 것이다. 실시간적인 반응이 중요한 온라인 게임역시 Nagle 알고리즘을 제거하는게 좋을 것이다.

아래의 이미지는 nagle이 적용되었을 때와 그렇지 않을 때, 어떻게 데이터 전송이 일어나는지를 보여주고 있다.

https://lh5.googleusercontent.com/-c_4XWF0jagg/UAZQFlw8AMI/AAAAAAAACOY/tnXyASYod7I/s400/Nagle.jpg

SO_LINGER

SO_LINGER은 소켓이 close()되었을 때, 소켓버퍼에 남아있는 데이터를 어떻게 할 것이지를 결정하기 위해서 사용한다. 다음은 SO_LINGER 옵션에 사용되는 데이터구조체이다.
struct linger
{
	int l_onoff;
	int l_linger;
}
  • l_onoff : linger 옵션을 끌것인지 킬 것인지 결정
  • l_linger : 기다리는 시간의 결정

위의 두개의 멤버변수의 값을 어떻게 하느냐에 따라 3가지 close방식을 결정되어 진다.
  1. l_onoff == 0 : 이 경우 l_linger의 영향을 받지 않는다. 소켓의 기본설정으로 소켓버퍼에 남아 있는 모든 데이터를 보낸다. 이때 close()는 바로 리턴을 하게 되므로 백그라운드에서 이러한 일이 일어나게 된다. 우아한 연결 종료를 보장한다.
  2. l_onoff > 0 이고 l_linger == 0 : close()는 바로 리턴을 하며, 소켓버퍼에 아직 남아있는 데이터는 버려 버린다. TCP 연결상태일 경우에는 상대편 호스트에 리셋을 위한 RST 패킷을 보낸다. hard 혹은 abortive 종료라고 부른다.
  3. l_onoff > 0 이고 l_linger > 0 : 버퍼에 남아있는 데이터를 모두 보내는 우아한 연결 종료를 행한다. 이때 close()에서는 l_linger에 지정된 시간만큼 블럭상태에서 대기한다. 만약 지정된 시간내에 데이터를 모두 보냈다면 리턴이 되고, 시간이 초과되었다면 에러와 함께 리턴이 된다.

소켓 timeout

  1. 소켓 Timeout

Socket

윤 상배

고친 과정
고침 0.9 2004년 8월 19일
입출력함수/도메인 이름변환/바이트오더 관련 함수 추가

1. Socket 에 대한 기본지식

1.1. Socket Layer

Socket 은 유닉스의 파일 기술자를 통해서 다른 프로그램간의 정보교환을 가능하도록 해주는 방법으로, 같은 시스템에 있는 프로그램들간의 정보교환을 위한목적, 혹은 다른 시스템(네트웍 상으로 멀리떨어져있는) 들간의 정보교환을 위한 목적으로 사용된다.

그런데 왜 Layer 라고 부르는가 그 이유는 TCP/IP 4계층의 응용계층(applicaton layer)과 전송계층(transmission layer) 중간에 존재하기 때문이다. 아래의 그림을 보라

그림 1. 소켓 계층

위의 그림은 TCP/IP 개요에서 이미 본적이 있는 그림일 것이다. 그때의 그림과 달라진 점이 있다면, 응용계층과 전송계층에 Socket Layer 가 존재한다는 것이다. 이 Socket Layer 가 응용계층과 전송계층 사이에 존재하게 됨으로 우리 프로그래머들은 복잡하게 TCP 를 직접 제어할 필요없이, Socket Layer 에서 제공하는 다양한 함수(Socket API)를 이용해서 간단하게 인터넷 네트웍 프로그래밍 작업을 하게 되는것이다.

 

Socket Layer 은 응용계층에서 받은 메시지를 하부 Socket API 를 이용해서 전송계층으로 보낸다. 전송계층에는 2가지 대표적인 프로토콜 이 있는데 바로 TCP(:12) 와 UDP(:12) 이다. 그럼으로 우리 프로그래머들은 TCP프로토콜(:12)을 사용할것인지 UDP 프로토콜을 사용할것인지만 결정해주면된다.


1.2. 왜 Layer 구조를 가지는가

일상 생활에서 소켓레이어와 비슷한게, 전화기라고 볼수 있을것이다. 우리는 상대편에서 전화를 걸기 위해서 상대편전화의 지리적 위치가 어디인지, 어떤 전화국에서 관리하는지, 언어를 신호로 변환 시키기 위해서 어떠한 작업을 해야하는지, 어떻게 보내야 하는지 전혀 알필요가 없다. 그냥 수화기 들고 전화 번호만 누르면 그걸로 끝이다. 즉 전화기 라는게 있음으로 그 내부에서 일어나는 여러가지 복잡한 통신 프로세스를 모르고도 상대편과 전화통화를 할수 있게 된다.

Socket Layer 이 존재함으로써, 우리는 TCP/UDP 헤더를 어떻게 만들어야 하는지, 구조가 어떻게 되는지, 어떻게 커널에 전달해야 하는지 신경쓸필요 없이 네트웍 프로그램을 만들수 있게 된다.


1.3. Socket

"Socket 이라뇨 우리는 위에서 Socket Layer를 이미 다루었는데요 ?" 라고 의문을 가질수도 있을것이다. Socket Layer 과 Socket 는 엄연히 다르다. Socket Layer 는 계층을 나타내는 것이다. 즉 Socket 를 다루기 위한 계층이다. 이는 TCP가 전송계층(:12)이 아닌것과 마찬가지이다. 우리는 Socket Layer 에서 제공하는 다양한 API를 통해서 Socket 를 제어하게 된다.

그럼 Socket 이란 무엇인가. 소켓이란 유닉스 파일 지시자 를 이용하여 다른 프로그램과 정보교환을 하는 방법(혹은 도구) 이다. 일반적으로 유닉스 상에서 정보교환은 파일지시자를 통한다는걸 알고 있을것이다. 마찬가지로 Socket 를 이용한 지역 혹은 네트웍으로 연결된 프로그램 간의 정보교환 역시 파일지시자를 통해서 이루어진다.

다중연결서버 만들기(1) 의 zipcode_multi.c 를 이용해서 소켓이 어떻게 작동하는지 알아보도록 하겠다. 먼저의 위의 프로그램을 컴파일(:12) 시키고 작동을 시켜보자. 작동을 시켰다면 ps 로 zipcode_multi 프로그램의 pid 를 확인해보고 /proc/pid/fd 디렉토리로 이동해서 어떠한 파일 지시자를 가지고 있는지 확인해보도록 하자.

[yundream@localhost test]# ./zipcode_multi 4444
...
[yundream@localhost test]# ps -ax | grep zipcode 
 2473 ttyp1    S      0:00 ./zipcode_multi 4444
			
pid가 2473 이므로 이 프로그램의 /proc/2473/fd 로 이동해서 ls해보면 프로그램에서 사용하고있는 파일지시자들에 대해서 알수 있다.
[yundream@localhost test]# ls -al /proc/2473/fd
합계 0
dr-x------    2 root     root            0  5월 28 16:07 .
dr-xr-xr-x    3 root     root            0  5월 28 16:07 ..
lrwx------    1 root     root           64  5월 28 16:14 0 -> /dev/ttyp1
lrwx------    1 root     root           64  5월 28 16:14 1 -> /dev/ttyp1
lrwx------    1 root     root           64  5월 28 16:14 2 -> /dev/ttyp1
lr-x------    1 root     root           64  5월 28 16:14 3 -> /home/mycvs/test/zipcode.txt
lrwx------    1 root     root           64  5월 28 16:14 4 -> socket:[171434]
			
0, 1, 2 는 각각 표준입력(:12), 표준출력(:12), 표준에러(:12)를 가리키는 파일지시자 라는것은 이미 알고 있을것이다. 3 은 프로그램이 연 파일을 가리킨다. 마지막 4가 바로 socket 통신을 위해 만들어진 파일 지시자이다. 다른 것들이 터미널이나 파일을 가리키는것과는 달리 socket 를 가리 키고 있음을 알수 있다.

 

여기에 새로운 클라이언트가 접근을하면 (telnet 이나 전용클라이언트 를 이용해서) 다음과 같은 파일 지시자가 하나 추가 될것이다.

lrwx------    1 root     root           64  5월 28 16:14 5 -> socket:[171435]
			

 


1.4. socket API

이번에는 socket 레이어에서 제공하는 소켓 관련 함수들을 설명하도록 하겠다.


1.4.1. 소켓 생성 및 연결

1.4.1.1. socket(2) 함수

이러한 소켓 은 socket(2) 함수를 이용해서 만들어진다. 최초 socket 함수를 이용해서 소켓을 생성하면 커널은 통신을 위한 종점(end point,즉 통신연결상황을 체크하는)을 생성하고, 여기에 대한 파일 지시자를 되돌려준다. 프로그램은 socket 함수를 이용해서 생성한 파일 지시자에 새로운 연결이 들어오는 지를 확인하게 된다.

위에 있는 TCP/IP(:12) 4계층을 보면 Socket Layer 아래에는 최소한 2개 이상의 사용가능한 데이타 그램의 타입이 있음을 알수 있다. 이러한 데이타 그램의 타입에는 TCP, UDP, RAW(:12) 등이 있다. TCP 소켓, UDP 소켓, RAW 소켓이라고 부르기도 한다. 또한 다양한 소켓 주소패밀리(군)를 제공한다.

표 1. 소켓주소 패밀리

UNIX 유닉스 도메인 소켓, IPC 용으로 많이 사용한다.
INET TCP/IP 프로토콜을 이용한 인터넷주소 패밀리, 보통의 네트웍프로그래밍시 주로 사용
IPX 노벨의 IPX 프로토콜, 게임을 좋아한다면 많이 들어봤음직한
AX25 아마추어 라디오 X.25
X25 X.25 프로토콜

 

그러므로 socket 함수는 위의 소켓 주소 패밀리와 소켓 타입 지정이 가능해야 한다.

int socket(int domain, int type, int protocol);
					
첫번째 아규먼트가 소켓주소 패밀리 지정을 위해서 사용되며, 두번째 아규먼트가 소켓 타입지정을 위해서 사용된다. 소켓주소 패밀리는 주로 INET(AF_INET), UNIX(AF_UNIX) 가 사용되며, 소켓타입은 TCP(SOCK_STREAM), UDP(SOCK_DGRAM), RAW(SOCK_RAW) 가 사용된다.

 

즉 인터넷 프로토콜을 이용하는 TCP 소켓을 만들기 원한다면 socket(AF_INET, SOCK_STREAM, 0) 과 같이 사용하면 된다.

socket 함수가 성공적으로 수행되면, 사용가능한 소켓을 가르키는 파일 지시자를 되돌려주며, 이 파일지시자는 endpoint(연결 확인 통로) 로써 사용된다.


1.4.1.2. bind(2) 함수

socket 함수를 이용해서 만들어진 소켓에 이름을 부여한다.

라고 번역된 man(:12) 페이지혹은 관련된 번역서에서 설명을 하고 있지만, 소켓에 특성을 부여(소켓과 특성을 묶는다(bind))한다 라는게 좀더 적당한 설명이 아닐까 싶다.

int bind(int  sockfd, struct sockaddr *my_addr, socklen_t addrlen);
					
인자로 주어진 sockfd 에대해서 sockaddr(:12) 을 이용해서 특성을 묶어준다. bind 함수를 통해서 우리는 sockfd 가 사용할 포트번호(port), 그리고 연결을 받아들일 IP 주소 특성등을 묶어줄수 있다. IP 주소는 IPv4, IPv6 등이 사용될수 있을것이다.

 

bind 함수는 보통 서버에서 사용된다. 그 이유는 대부분의 서비스(HTTP, FTP..)들이 지정된 포트(:12)번호를 통해서 서비스 되기 때문이다. 반면 클라이언트의 경우 커널에서 할당한 임의의 포트번호를 이용해서 서버와 연결하기 때문에 bind 를 사용할 필요가 없다.


1.4.1.3. connect(2) 함수

int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
					
이것은 클라이언트(:12)측 에서 사용되며, struct sockaddr 구조체에 세팅된 내용대로 서버측에 연결한다. sockaddr 구조체에는 연결될 서버에 대한 정보들, 즉 주소 패밀리 IP 번호와 PORT 번호 등이 들어가 있으며, connect 함수는 sockaddr 정보를 이용해서 서버측에 연결을 하며 서버와의 통신을 위한 endpoint 와 sockfd 를 연결시킨다. sockfd 는 socket 함수를 이용해서 만들어진 소켓 지정 번호이다.

 


1.4.1.4. listen(2) 함수

int listen(int sockfd, int backlog);
					
서버측에서 사용되며 socket 함수를 이용해서 만들어진 sockfd 에 대해서, 들어 오는 연결을 기다린다. backlog 는 아직 완전히 연결되지 않은 연결들이 대기할 queue 의 길이를 명시하기 위해서 사용된다.

 


1.4.1.5. accept(2) 함수

int accept(int s,  struct  sockaddr  *addr,  socklen_t *addrlen); 
					
listen(2) 을 통해서 만들어진 미연결의 대기열에서 가장 앞에 있는 연결의 내용을 가져와서 새로운 연결 소켓을 만들어준다. 새로만들어진 연결소켓은 파일 지시자를 할당하여서 리턴해주게 되며, 우리는 리턴된 파일 지시자를 이용해서 새로만들어진 소켓과 통신을 할수 있게 된다.

 


1.4.2. 입출력 함수

유닉스에서 소켓은 파일과 동일하게 취급 되기 때문에 read(), write()와같은 시스템 함수를 이용해도 대부분의 입출력을 다룰 수 있다. 그러나 이들 시스템 함수들은 네트워크의 특성을 고려하지 않고 만들었기 때문에 네트워크 정보를 필요로 하는 작업을 하기에는 적당하지 않은 점이 있다.

예를들어 UDP를 이용해서 통신을 할경우 읽기는 문제없지만 쓰기에는 문제가 생길 수 있다. UDP는 연결 소켓을 만들지 않기 때문에 쓸때 연결된 호스트의 정보를 알 수가 없기 때문에 write()함수로는 데이터를 전송할 수 없게 된다. 이럴경우에는 소켓 API를 사용해서 통신을 해주어야 한다.


1.4.2.1. 입력함수 - recvfrom/recvmsg

소켓으로 부터 데이터를 받기 위해서 사용한다.

	
#include <sys/types.h>
#include <sys/socket.h>

ssize_t  recvfrom(int s, void *buf, size_t len, int flags, struct sock-
addr *from, socklen_t *fromlen);

ssize_t recvmsg(int s, struct msghdr *msg, int flags);
					
소켓 지정자 s로 부터 데이터를 읽는 일을 한다. 둘다 연결지향 소켓과 비연결지향 소켓 모두에 사용할 수 있다. 보통 recvfrom()함수가 사용하기에 직관적인 관계로 쉽게 사용할 수 잇다. 소켓으로 부터 len 만큼 데이터를 읽어와서 buf에 저장한다. 또한 5번째 인자인 from를 통해서 데이터를 보낸 호스트의 인터넷 정보를 얻어 올 수 있다. 그러므로 비연결 지향 소켓을 사용하더라도 이 인터넷 정보를 통해서 데이터를 수신할 목적지 호스트를 결정할 수 있게 된다. fromlen는 sockaddr 구조체의 길이다. 나머지 자세한 내용은 recvform(2)의 맨페이지를 참고하기 바란다.

 


1.4.2.2. 출력함수 - sendto/sendmsg

소켓으로 데이터를 보내기 위해서 사용한다.

#include <sys/types.h>
#include <sys/socket.h>

ssize_t  sendto(int  s,  const  void *buf, size_t len, int flags, const
struct sockaddr *to, socklen_t tolen);
ssize_t sendmsg(int s, const struct msghdr *msg, int flags);
					
역시 직관적인 sendto(:12)를 널리 사용한다. 소켓 지정자 slen크기만큼 buf의 내용을 보낸다. to를 이용해서 데이터를 받을 호스트를 명시할 수 있다. sendto()와 recvfrom()함수의 사용예는 UDP 소켓 프로그래밍 을 참고하기 바란다.

 


1.4.3. 인터넷 주소변환

인터넷 주소 자체가 인간이 인지하기 어려운 수로 되어 있다 보니 이것을 관리하기 쉽도록 점박이 3형제 스타일의 인터넷 주소체계를 만들어서 관리하고 여기에 또 도메인(:12) 이름을 줘서 쉽게 기억할 수 있도록 하고 있다. 프로그래머나 사용자는 보통 도메인 이름이나 점박이 3형제 스타일의 인터넷 주소를 사용하게 되는데, 실제 네트워크 프로그램에서는 32bit 주소 형태로 변환 시켜줘야할 필요가 있다.

여기에서는 이들 주소간 변환과 관련된 함수를 소개한다.


1.4.4. 인터넷 주소 <-> 32bit 주소

inet_addr(3), inet_aton(3), inet_network(3), inet_ntoa(3) 의 함수를 이용해서 인터넷 주소와 32bit 주소간 변환을 할 수 있다. inet_addr(3)과 inet_network(3)함수는 점박이 3형재 스타일 인터넷 주소로 부터 32bit 주소를 얻기 위해서, inet_aton(3)과 inet_ntoa(3)그 반대의 변환 값을 얻기 위해서 사용한다. 자세한 내용은 man 페이지를 참고하기 바란다(그냥 함수 링크를 클릭하면 된다).


1.4.5. 도메인 이름 -> 32bit 주소

점박이 3형제 스타일의 인터넷 주소는 확실히 관리하기 좋고 외우기에 좀더 편하긴 하지만 숫자로 되어 있다는 것 때문에 인터넷 서비스를 위한 호스트 주소로 사용하기엔 적당하지 않다. 그래서 인터넷 주소에 이름을 주는 서비스가 만들어지게 되었는데 도메인 서비스이다. 도메인 서비스는 도메인 이름에 대한 인터넷 주소를 되돌려 주는 일을 한다. 자세한 내용은 인터넷 주소 변환문서를 참고하기 바란다.


1.4.5.1. gethostbyname/gethostbyaddr

도메인 이름에서 인터넷 주소를 얻어오는 일을 한다. 자세한 내용은 gethostbyname(3)과 getbyaddr(3)의 맨페이지(:12)를 참고 하기바란다.


1.4.6. 네트워크 바이트 오더

네트워크 통신을 하다보면 CPU의 바이트 오더가 다른 이유로 이를 표준 바이트 오더인 네트워크 바이트 오더로 변환해서 보내고, 받아들인 데이터는 호스트의 바이트 오더에 맞게 다시 변경시켜주는 작업이 필요하다. 이러한 작업을 위해서 소켓은 몇 개의 함수들을 제공한다. 바이트 오더에 대한 자세한 내용은 endian에 대해서 를 참고하기 바란다.


1.4.6.1. 호스트 바이트 오더 -> 네트워크 바이트 오더

htonl(3), htons(3) 함수를 사용한다. 전자는 4byte 데이터, 후자는 2byte 데이터를 네트워크 바이트 오더를 따르도록 변환한다.


1.4.6.2. 네트워크 바이트 오더 -> 호스트 바이트 오더

ntohl(3), ntohs(3) 함수를 사용한다. 전자는 4byte데이터, 후자는 2byte데이터를 호스트 바이트 오더를 따르도록 변환한다.


1.4.6.3. 엔디안 검사 함수

이건 보너스다. 현재 CPU(:12)의 바이트 오더 방식을 알려 주는 간단한 함수다.

int endian(void)
{
	int i = 0x00000001;
	if ( ((char *)&i)[0] )
		return LITTLE_ENDIAN;
	else
		return BIG_ENDIAN;
}
					

 


2. 소켓 프로그래밍 일반

2.1. 서버측 socket 생성 순서

다음은 서버측의 소켓 생성 순서를 나열한 것이다.

 

  1. 서버측의 소켓 생성순서는 최초 socket 함수를 이용해서 endpoint 소켓, 즉 클라이언트의 연결을 듣기 위한 소켓을 생성하게 된다. 이 소켓은 서버가 종료될때까지 남아있게 된다.

  2. bind 함수를 호출하여 소켓특성을 묶어준다. 이 함수를 이용하여 port 번호를 지정해주며, 받아들일 IP주소에 대한 설정을 한다.

  3. listen 함수를 이용하여 듣기 소켓(socket 함수를 통해서 만들어진) 에 연결이 있는지 기다린다. 만약 연결이 있다면, 연결 대기열(queue)에 쌓아놓는다.

  4. accept 함수를 이용하여 연결 대기열에 대기중인 연결이 있다면 해당 연결에 대하여 새로운 소켓을 만들고 만들어진 소켓에 대한 파일 지시자를 되돌려준다. 이 소켓은 읽기/쓰기로 만들어진다. 만약 연결 대기열에 대기중인 연결이 없다면 (기본적으로) 해당 영역에서 봉쇄(block)된다.

  5. read, write 등의 함수를 이용해서 통신을 한다.

 


2.2. 클라이언트 측 socket 생성순서

다음은 클라이언트측의 소켓 생성 순서를 나열한 것이다. 서버측에 비하여서 훨신 간단하게 이루어짐을 알수 있다.

 

  1. 최초 socket 를 이용하여 endpoint 소켓을 생성한다. 클라이언트 이므로 이것은 듣기 소켓이 아니고, 연결 소켓이 될것이다. (이름만 다를뿐 사실 듣기 소켓과 연결 소켓의 구분은 없다)

  2. connect 를 이용하여 서버에 연결한다.

  3. read, write 등의 함수를 이용해서 서버와 통신한다.

 


3. 결론

이상 Socket Layer 의 개념과 Socket Layer 에서 제공하는 Socket API 에 대한 간단히 알아 보았다. 여기에 있는 API 들은 가장 기본적인(통신을 위해서 필요한) 함수들이다. 나머지 좀더 세밀한 함수들에 대해서는 Unix NetWork Programming 등의 서적을 참고하기 바란다.

여기에 있는 소켓 API 들의 사용예는 이 사이트에서 충분히 찾아볼수 있을것이다.


신고

'Skill > Interface' 카테고리의 다른 글

프로세스간 통신(IPC ; Inter-Process Communication)  (1) 2014.04.02
Socket 에 대한 기본지식  (1) 2014.03.03
MAXIM 스마트 카드 I/F 원리  (0) 2014.02.26

Comment +1

  • sugerent@gmail.com 2014.03.07 20:16 신고

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <arpa/inet.h>
    #include <sys/socket.h>

    #define BUFSIZE 512
    #define SERVER_IP "192.168.2.71"
    #define PORT 5001

    int main(void) {

    //먼저 socket을 만들고!
    int c_socket = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in c_addr;

    //주소를 정한다.
    memset(&c_addr, 0, sizeof(c_addr));
    c_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
    c_addr.sin_family = AF_INET;
    c_addr.sin_port = htons(PORT);

    //그리고 연결!! 연결실패시 -1이 return된다.
    if(connect(c_socket, (struct sockaddr*)&c_addr, sizeof(c_addr))==-1)
    printf("connect() error!\n");
    else
    printf("connect() success!\n");
    //error_handling("connect() error!");

    write(c_socket, "king of beer",sizeof("king of beer"));

    //연결되면 버퍼를 생성하고
    //char RXbuffer[1024];
    //memset(RXbuffer,0,1024);

    // read하면 server에서 보낸걸 읽어온다.
    //int len = read(c_socket, RXbuffer, sizeof(RXbuffer));

    //if(len > 0){
    // printf("data : %s index : %d", RXbuffer, cnt);
    //}

    // write하면 server에 쓴다!!!

    return 0;
    }

DS8007과 스마트 카드 인터페이스의 기본 원리

개요: DS8007은 모든 ISO 7816, EMV™ 및 GSM11-11 요구사항을 지원하는 저가의 멀티프로토콜, 듀얼, 스마트 카드 인터페이스이다. 이 단일 혼합 신호 (mixed-signal) 주변장치는 1개의 마이크로컨트롤러와 2개의 독립적인 스마트 카드 사이에 모든 인터페이스 세부사항을 관리한다. 이 애플리케이션 노트에서는 스마트 카드의 몇 가지 기본 원리를 살펴보고 이들 소자 간에 통신을 수행하는 방법에 대해 설명한다. 또한 DS8007을 사용하여 스마트 카드와 DS5002 보안 마이크로프로세서에 인터페이싱하기 위한 소프트웨어가 제공된다.

개요

스마트 카드란 무엇인가? 스마트 카드란 보통 IC가 내장된 포켓 크기의 카드로 정의된다. 스마트 카드에는 IC가 내장되어 있어 IC 카드(ICC)라고 부르기도 한다. 그림 1은 일반적인 스마트 카드의 예이다. 다양한 애플리케이션에서 사용되는 이러한 카드들이 마그네틱 선을 사용하여 카드 계정 정보를 저장하는 기존의 지불 (직불 또는 신용) 카드를 대체하고 있다. 이는 스마트 카드가 다양한 기능을 제공할 뿐 아니라 특히 IC 기술을 이용한 강력한 보안 기능을 제공하기 때문이다. 그러나 후자의 보안 기능은 스마트 카드의 높은 비용과 대비하여 신중한 평가가 요구된다.


그림 1. 스마트 카드의 예

스마트 카드에는 간단한 비휘발성 메모리 소자나 복잡한 연산을 수행할 수 있는 마이크로컨트롤러와 같은 정교한 IC가 내장된다. 카드에 내장된 간단한 비휘발성 메모리 소자가 데이터 저장을 위한 마그네틱 선을 대체할 수 있다. 이러한 소자는 대부분 메모리와 추가 로직을 결합하여 메모리의 일부 또는 전체에 대한 액세스를 제한한다. 그러나 스마트 카드의 진정한 힘은 데이터 프로세싱 및/또는 암호화 기능을 수행하는 내장된 마이크로컨트롤러의 능력에 있다. 이 프로세싱 능력은 강력한 보안 기능을 제공한다. 그러나 설계가 복잡해질수록 카드 비용도 증가한다. 프로세서가 내장된 스마트 카드의 비용은 $7.00 ~ $15.00 (USD) 범위인 반면 마그네틱 선이 있는 지불 카드는 $0.75¹ (USD) 정도에 불과하다. 이렇게 비싼 가격이 스마트 카드로의 전면적인 교체를 지연시키고 있지만, 보안 요구가 높아짐에 따라 스마트 카드에 대한 필요성도 커지고 있다.

DS8007은 마이크로컨트롤러와 2개의 개별적인 스마트 카드에 물리적으로 인터페이싱하는 데 필요한 모든 전기적 신호를 제공한다. 이 소자에는 데이터 통신을 위한 ISO UART뿐 아니라 자동 카드 액티베이션 및 디액티베이션을 제어하는 전용 시퀀서가 내장되어 있다. 또 차지 펌프와 전압 레귤레이터가 있어 소자는 2.7V ~ 6.0V의 전원 전압으로 동작하며, 2개의 독립적인 스마트 카드 전원 전압을 생성할 수 있는데, 이 중 하나는 1.8V, 3.0V 또는 5V로 설정할 수 있다. 마이크로컨트롤러와의 통신은 비다중화 구성으로 데이터를 전달하거나 다중화 구성으로 데이터와 어드레스를 전달하는 표준, 병렬 8비트 버스에 의해 제공된다.

스마트 카드 세부사항

가장 많이 볼 수 있는 스마트 카드 폼 팩터는 신용 카드 크기의 소자이지만, "스마트 카드"라는 용어는 휴대 전화에 많이 사용되는 우표 크기만 한 가입자 인증 모듈(SIM)에도 적용된다. 이 SIM 폼 팩터는 단말기에 특정 지불 시스템 데이터와 상세한 애플리케이션 정보를 제공하기 위해 지불 단말기에도 이용되고 있다. 소자의 카드 부분은 보통 PVC로 만들어지며, 일반적으로 계정 번호와 만기일 등의 정보가 새겨진다. 폼 팩터와 상관없이 모든 전자기 규격은 ISO 7816 표준 시리즈를 기반으로 한다. 이 밖에도 EuroCard®, MasterCard®, Visa® (EMV) 업체로 구성된 컨소시엄에서는 특별히 스마트 카드와 해당 기업의 지불 시스템 애플리케이션에 관한 일련의 표준을 개발했다. EMV 규격은 보통 ISO 7816 문서를 기반으로 한다.

스마트 카드 접촉

스마트 카드상 접촉부의 숫자, 위치 및 기능은 위에서 언급된 표준에 의해 명확히 규정되어 있다. 표준 스마트 카드의 IC 위치와 접촉 치수는 그림 2에 나와 있다. ISO 7816은 8개의 가능한 접촉 위치를 규정하고 있다. EMV 애플리케이션에는 8가지 위치 중 현재 5가지가 사용된다. 이들 접촉의 이름과 기능은 표 1을 참조한다. 접촉 C6은 ISO 7816에서 VPP로 정의되어 있으며, 이 프로그래밍 가능 전압은 EMV 규격에 따라 현재 카드에는 사용되지 않는다. 접촉 C4 및 C8 역시 사용되지 않으므로 물리적으로는 카드에 존재할 필요가 없다. EMV 규격에 지정되어 있는 개별 접촉에 대한 자세한 내용은 다음과 같다.

표 1. 스마트 카드 접촉
Contact Name Contact Function
C1 Supply voltage to card (VCC)
C2 Reset (RST)
C3 Clock (CLK)
C4 Provided on the DS8007; not used in EMV
C5 Ground (GND)
C6 VPP; not used in EMV
C7 Input/output (I/O)
C8 Provided on the DS007; not used in EMV


그림 2. 접촉 치수 및 위치

VCC 접촉 (C1)
이 접촉은 카드에 전원 전압을 제공한다. 원래 VCC에 대한 규격에는 5V DC ±10%만 포함되어 있었지만, 지금은 더 낮은 전압의 카드로 위상 이동(phased migration)도 규정하고 있다. 초기 규격만 지원하는 카드는 클래스 A 카드라고 부르며, 2009년 6월 말까지 클래스 AB 또는 클래스 ABC 카드로 교체되어야 한다. 카드 클래스에 대한 VCC 규격은 다음과 같다.

클래스 A 카드: ≤ 50mA에서 4.5V ≤ VCC ≤ 5.5V
클래스 AB 카드: ≤ 50mA에서 2.70V ≤ VCC ≤ 3.3V
클래스 ABC 카드: ≤ 30mA에서 1.62V ≤ VCC ≤ 1.98V

DS8007 카드 인터페이스에는 차지 펌프와 전압 레귤레이터가 내장되어 있어 소자가 2.6V ~ 6.0V 전원으로 동작할 때, 3가지 카드 클래스에 모두 적절한 전압을 공급할 수 있다.

I/O 접촉 (C7)
스마트 카드의 I/O 접촉은 입력(수신 모드)으로 사용되어 단말기로부터 데이터를 수신하거나 출력(전송 모드)으로 사용되어 단말기로 데이터를 전송한다.

수신 모드에서 입력이 다음 규격을 준수할 경우 카드는 유효 데이터를 인식한다.

클래스 A 카드

    입력 고전압: 0.7 × VCC ≤ VIH ≤ VCC
    입력 저전압: 0.0 ≤ VIL ≤ 0.8V
    상승 시간/하강 시간: ≤ 1µs
클래스 AB 또는 ABC 카드
    입력 고전압: 0.7 × VCC ≤ VIH ≤ VCC
    입력 저전압: 0.0 ≤ VIL ≤ 0.2 × VCC
    상승 시간/하강 시간: ≤ 1µs
전송 모드에서 I/O 접촉은 다음과 같은 신호 레벨을 제공한다.

클래스 A 카드
    출력 고전압: 0.7 × VCC ≤ VOH ≤ VCC, -20µA < IOH < 0, VCC = min
    출력 저전압: 0.0 ≤ VOL ≤ 0.4V, 0 < IOL < 1mA, VCC = min
    상승 시간/하강 시간: ≤ 1.0µs
클래스 AB 또는 ABC 카드
    출력 고전압: 0.7 × VCC ≤ VOH ≤ VCC, -20µA < IOH < 0, VCC = min
    출력 저전압: 0.0 ≤ VOL ≤ 0.15 × VCC, 0 < IOL < 1mA, VCC = min
    상승 시간/하강 시간: ≤ 1.0µs
EMV 규격에서는 I/O 접촉이 송신 중이 아닌 한, 스마트 카드의 I/O 접촉 드라이버는 수신 모드로 설정한다고 규정하고 있다.

CLK 접촉 (C3)
CLK 접촉은 인터페이싱 단말기, 즉 DS8007에 의해 소싱되는 입력이다. 이 신호는 트랜잭션 프로세스 중 데이터 전송 타이밍을 제어하는 데 사용된다. 주파수 범위는 1.0MHz ~ 5.0MHz 사이이다. 이 접촉의 전기적 규격은 다음과 같다.

클래스 A 카드
    입력 고전압: VCC - 0.7 ≤ VIH ≤ VCC
    입력 저전압: 0.0 ≤ VIL ≤ 0.5V
    상승 시간/하강 시간: ≤ 9% of clock period
클래스 AB 또는 ABC 카드
    입력 고전압: 0.7 × VCC ≤ VIH ≤ VCC
    입력 저전압: 0.0 ≤ VIL ≤ 0.2 × VCC
    상승 시간/하강 시간: ≤ 9% of clock period
RST 접촉 (C2)
RST 접촉은 인터페이싱 단말기에 의해 소싱되는 카드에 대한 입력이다. 이 신호는 액티브 로우(active-low)이며, 카드의 비동기 리셋을 발생시킨다. 이 접촉은 CLK 접촉과 전기적 규격이 동일하지만, 최대 상승 및 하강 시간은 1.0µs이다.

위의 규격에서 보듯이 스마트 카드와 인터페이싱하는 단말기는 다양한 전원 전압과 신호 레벨을 제공해야 한다. 또한 인터페이스 규격은 단말기가 카드 접촉 중 임의 두 접촉 간의 단락을 견디도록 요구하고 있다. 이러한 이유로 필요한 전원 전압과 신호 레벨을 제공하는 데 전용 소자를 사용하는 것이 여러 개의 개별 아날로그 IC를 조합하는 것보다 훨씬 유리하다. DS8007이 바로 이러한 전용 소자이다. 이 소자는 위의 기능을 제공하는 데 필요한 아날로그 회로뿐만 아니라 FIFO 및 기타 디지털 제어 로직을 포함하고 있어 완벽한 카드 세션 지원에 필요한 상태 시퀀싱 및 타이밍을 제공한다.

단말기 인터페이스 요구사항

모든 카드 세션은 다음 단계로 구성된다.
  1. 단말기에 카드 삽입; 접촉의 연결 및 액티베이션
  2. 카드 리셋; 단말기와 카드 간의 통신 구축 (아래 ATR 시퀀스 참조)
  3. 트랜잭션 실행
  4. 접촉의 디액티베이션 및 카드 제거
삽입 후 초기 리셋을 수행하면 카드는 ATR(Answer to Reset)이라고 하는 일련의 문자로 응답한다. 이 일련의 문자는 특정 프로토콜, 비트 타이밍 및 이후의 모든 통신을 위한 데이터 전송 세부사항을 포함하여 초기의 통신 세부사항을 수립한다. 이후의 데이터 전송에서 특정 통신 파라미터가 변경될 수 있지만, ATR은 초기 통신 상태를 유지한다. ATR은 아래 섹션에서 자세히 설명한다.

각각의 문자
스마트 카드와 단말기 간에 인터페이싱이 이루어지는 동안 정보는 양방향 I/O 접촉을 통해 직렬로 전달된다. 비트 유지 시간(bit duration)은 ETU(Elemental Time Unit)로 정의된다. ETU에 대한 시간 주기(time period)는 CLK 접촉상의 단말기에 의해 제공되는 클록 신호와 직접적 선형 관계에 있다. ATR 동안 문자의 비트 타이밍을 초기 ETU라고 한다. 이 값은 다음 수식으로 구할 수 있다.

Initial ETU = 372/ƒ seconds (Eq.1)

여기서 ƒ는 클록 신호의 주파수이다(Hz).

ATR 후 비트 길이는 현재 ETU라고 하며, 이것은 파라미터 F 및 D와 클록 주파수의 함수이다. (파라미터 F 및 D는 아래 TA1 문자 섹션에서 자세히 나와있다.)

Current ETU = F/(Dƒ) seconds (Eq.2)

여기서 ƒ는 클록 신호의 주파수이다(Hz).

모든 통신에서 각 문자는 10비트로 구성되며, 결과적으로 10ETU의 길이가 소요된다. 문자의 첫 번째 비트는 시작 비트라고 하며 언제나 로우(low)이다. 시작 비트가 진행되기 전, I/O 라인은 디폴트 하이 상태를 유지한다. 문자의 마지막 비트는 패리티 비트로 소스에 의해 하이 또는 로우로 결정되므로 문자에서 전체 1의 개수는 짝수가 된다. 그림 3에 이러한 비트 패턴이 나와있다.


그림 3. 10비트 문자 프레임

스마트 카드 통신 프로토콜

ISO 7816 규격에서 카드 세션을 위한 통신 프로토콜을 선택할 때에는 4비트가 사용된다. 현재 16개의 가능한 프로토콜 중 T=0 및 T=1이라는 2개의 프로토콜이 사용된다. 두 프로토콜은 모두 하프 듀플렉스(한 번에 한 방향), 비동기 통신이다. T=0 프로토콜은 문자 기반 형식이며, T=1은 블록 기반 형식이다. 모든 EMV 규격준수 스마트 카드는 T=0이나 T=1 프로토콜을 지원해야 하고, 단말기는 두 가지를 모두 지원해야 한다.

카드가 단말기에 삽입되자 마자, 그리고 모든 접촉이 "로우" 상태에 있는 동안 전원 전압이 카드의 VCC 접촉에 인가된다. 단말기가 전압이 안정적이고 지정된 제한 내에 있다는 것을 확인하면, 단말기는 수신 모드에 들어가고 클록 신호가 카드의 CLK 접촉에 인가된다. 200사이클의 클록 신호 초기화 이내에 단말기는 I/O 라인을 수신 모드로 설정하고, 카드는 I/O 라인을 전송 모드로 놓는다. 40,000 ~ 45,000 사이의 클록 주기 이후에 단말기는 카드의 RST 접촉에 액티브 하이 신호를 인가한다. 400 ~ 40,000 클록 주기 후에 카드는 ATR이라고 하는 일련의 문자로 응답한다. ATR에는 T=0 또는 T=1 프로토콜 선택을 포함하여 이후에 통신을 어떻게 수행할지에 대한 정보가 포함된다. 프로토콜이 지정되지 않으면 T=0으로 가정한다. (ATR 및 포함된 정보에 대한 자세한 내용은 아래에서 설명한다.)

ATR (Answer to Reset)

단말기에 의한 초기 리셋이 완료되면 EMV 스마트 카드는 ATR이라고 하는 문자열로 응답한다. 이들 문자는 초기 문자 TS와 최대 32개의 추가 문자로 구성된다. 이들 문자는 함께 단말기에 나머지 세션에서 카드와 통신하는 방법에 관한 정보를 제공한다. 각 문자는 다음 섹션에서 설명한다.

EMV 규격에서 정의하고 있는 프로토콜 T=0에 대한 ATR 내용은 표 2에, 프로토콜 T=1에 대한 내용은 표 3에 나와 있다.

표 2. T=0인 경우 기본 EMV ATR
Character Value Remarks
TS '3B' or '3F' Indicates direct (3B) or inverse (3F) convention.
T0 '6x TB1 and TC1 present, TA1 and TD1 absent; x indicates the number of historical bytes present.
TB1 '00' VPP is not required.
TC1 '00' to 'FF' Indicates the amount of extra guard time required. Value 'FF' has a special meaning. (See TC1 description below.)

표 3. T=1인 경우 기본 EMV ATR
Character Value Remarks
TS '3B' or '3F' Indicates direct (3B) or inverse (3F) convention.
T0 'Ex' TB1, TC1, and TD1 present, TA1 is absent; x indicates the number of historical bytes present.
TB1 '00' VPP is not required.
TC1 '00' to 'FF' Indicates the amount of extra guard time required.
TD1 '81' TA2, TB2, and TC2 absent; TD2 present; T=1 to be used.
TD2 '31' TA3 and TB3 present; TC3 and TD3 absent; T=1 to be used.
TA3 '10' to 'FE' Returns IFSI, which indicates the initial value for the card's information field size and IFSC of 16 bytes to 254 bytes.
TB3 m.s. nibble* '0' to '4'; l.s. nibble '0' to '5' BWI = 0 to 4
CWI = 0 to 5
TCK   Check character. Exclusive ORing of all ATR bytes from T0 to TCK inclusive is null.
*참고: m.s. nibble = 최상위 니블. l.s. nibble = 최하위 니블.

TS 초기 문자
ATR 시퀀스의 첫 번째 문자는 초기 문자, TS로 정의된다. 이 문자는 비트 패턴을 이용하여 정보를 동기화하고 이후의 모든 문자의 극성을 정의한다. TS의 처음 4비트는 1개의 로우 시작 비트, 2개의 하이 비트, 그리고 1개의 추가 로우 비트 순서로 구성된다. 이러한 고정 비트 패턴은 타이밍 동기화를 가능하게 해준다. 다음 3비트가 모두 하이(high)이면 직접 규칙을, 모두 로우(low)이면 반전 규칙을 나타낸다. 직접 규칙에서 I/O 라인의 하이 상태는 로직 1과 같으며 데이터는 최하위 비트부터 전송된다. 반전 규칙에서 I/O 라인의 로우 상태는 로직 1과 같으며 데이터는 최상위 비트부터 전송된다. 규격에서는 반전 규칙이 허용되어 있지만 EMV에서는 현재의 모든 카드 설계에 직접 규칙을 사용할 것을 권장한다. 마지막 3비트는 2개의 로우 비트와 1개의 하이 비트로 이루어진다. 여기에서 또는 기타 다른 10비트 문자 프레임에서 마지막 비트는 패리티 비트로서, 프레임에서 1의 개수를 짝수로 만들기 위해 설정되거나 클리어된다.

T0 형식 문자
ATR 시퀀스의 두 번째 문자는 형식 문자로 정의되며 T0이라고 한다. 이 문자는 두 부분으로 구성되며, 두 부문 모두 나머지 ATR 시퀀스에 포함되는 문자를 결정한다. 최상위 4비트는 Y1이라고 하며, 이들은 TA1, TB1, TC1 또는 TD1을 전송할지 여부를 나타낸다. Y1의 각 로직 1에서 문자의 존재는 각각 다음과 같이 결정된다.

Bit 8 (msb) = 1은 문자 TD1이 전송됨을 나타낸다.
Bit 7 = 1은 문자 TC1이 전송됨을 나타낸다.
Bit 6 = 1은 문자 TB1이 전송됨을 나타낸다.
Bit 5 = 1은 문자 TA1이 전송됨을 나타낸다.

T0의 최하위 4비트는 K라고 한다. 이들 비트는 나머지 ATR 시퀀스에 포함되는 "히스토리컬 바이트"의 숫자(0 ~ 15)를 결정한다. 히스토리컬 바이트는 카드 제조업체, 카드 내부 칩, 칩에 마스킹된 ROM 또는 카드의 수명 상태와 같은 카드에 관한 일반적인 정보를 전달한다. 어떤 정보가 전달되어야 하는지는 ISO 7816이나 EMV 규격에서도 명확히 정의되어 있지 않다.

위의 표 2에서 보듯이 Y1 비트 b7과 b6은 하이이며, 비트 b8과 b5은 로우('6x')이다. 이것은 TC1과 TB1이 전송되며 문자 TA1과 TD1은 전송되지 않는다는 것을 나타낸다(표 참조). 프로토콜 T=0에서는 문자 TB1과 TC1이 기본 ATR 시퀀스를 완성한다. 표 3에서 Y1의 비트 8도 하이이므로, 프로토콜 T=1에서는 문자 TD1도 전송된다..

TA1 문자
문자 TA1은 T=0 또는 T=1 프로토콜을 위한 기본 EMV ATR에서 전송되지 않지만, 기타 통신을 위한 ISO 7816 규격에 정의되어 있다. 사용될 경우 TA1은 상위 니블과 하위 니블로 나누어진다. 상위 니블은 클록 레이트 변환 인수 F를 결정하는데, 이것은 클록 신호의 주파수를 수정하는 데 사용된다. 하위 니블은 ATR 이후의 비트 길이를 조정하는 데 사용할 수 있는 비트 레이트 조정 인수 D를 결정한다. 이러한 파라미터의 사용은 위의 수식 2에 나와 있다. F = 372 및 D = 1의 디폴트 값은 ATR 동안 초기 ETU 값을 위해 사용되며, 기본 ATR을 벗어나도록 변경되지 않는 한 이후의 교환에서도 계속 사용된다.

TB1 문자
TB1 문자는 스마트 카드의 프로그래밍 전압 요구사항에 대한 정보를 전달한다. 비트 b1 ~ b5(PI1)는 프로그래밍 전압을 전달하며, 비트 b6과 b7(II)은 스마트 카드에 필요한 최대 프로그래밍 전류를 전달한다. 기본 ATR에서 TB1 = '00'은 스마트 카드에서 VPP 핀이 연결되지 않았음을 나타낸다.

TC1 문자
TC1 문자는 N의 값을 전달하며, 이 값은 단말기로부터 스마트 카드에 전송되는 연속적인 문자 사이에 추가되는 별도의 가드 시간을 결정한다. 이 값은 카드로부터 단말기로 전송되는 문자나 반대 방향으로 전송되는 2개의 문자에는 적용되지 않는다. N은 별도의 가드 시간으로 추가될 추가 ETU를 나타내는 2진수이다. TC1= 'FF'일 때, 문자 사이에 최소 지연을 사용해야 한다. 프로토콜 T=0에서 이것은 12ETU이며, T=1에서는 11이다. N의 값은 0과 255 사이의 어느 값이나 될 수 있다. TC1이 ATR에서 리턴되지 않으면 단말기는 00의 값이 수신된 것처럼 계속 진행한다. 이 값은 문자 전송 시 시간이 추가될 수 있기 때문에 빠른 트랜잭션을 위해서는 최소화해야 한다.

TD1 문자
TD1 문자는 전송할 인터페이스 바이트가 더 있는지, 있다면 어떠한 프로토콜을 사용할 것인지를 나타낸다. 문자 TD1은 일반 문자 TDx의 지정 인스턴스이다. TDx의 최상위 니블은 TA(x + 1), TB(x + 1), TC(x + 1), TD(x + 1)이 전송될지 여부를 나타낸다. 각 로직 1의 경우, 이후 전송에서 각 문자의 존재는 다음과 같이 결정된다.

Bit 8 (msb) = 1은 문자 TD(x + 1)이 전송됨을 나타낸다.
Bit 7 = 1은 문자 TC(x + 1)이 전송됨을 나타낸다.
Bit 6 = 1은 문자 TB(x + 1)이 전송됨을 나타낸다.
Bit 5 = 1은 문자 TA(x + 1)이 전송됨을 나타낸다.

TD1 문자(TDx 일반)의 최하위 니블은 각각 프로토콜 T=0 또는 T=1을 나타내는 값 0x0 또는 0x1을 포함한다.

프로토콜 T=0이 사용되면, ATR 시퀀스에는 문자 TD1이 포함되지 않으며 이후의 모든 전송에서 프로토콜 T=0이 사용된다. 프로토콜 T=1이 사용되면 TD1이 포함되며 0x81의 값을 포함한다. 이 후자의 값은 TD2가 존재하며 이후의 모든 전송에서 프로토콜 T=1이 사용된다는 것을 나타낸다.

TA2 문자
문자 TA2는 T=0 또는 T=1 프로토콜을 위한 기본 EMV ATR 응답에서 전송되지 않지만, ISO 7816 규격에 정의되어 있다. TA2의 존재 여부는 스마트 카드가 ATR 이후에 각각 지정 모드 또는 협상 모드에서 동작할지 여부를 결정한다. TA2가 존재하지 않는다는 것은 협상 동작 모드가 사용됨을 의미한다.

TB2 문자
문자 TB2는 T=0 또는 T=1 프로토콜을 위한 기본 EMV ATR 응답에서 전송되지 않지만, ISO 7816 규격에 정의되어 있다. 문자 TB2는 스마트 카드에 필요한 프로그래밍 전압의 값을 결정하는 PI2를 전달한다. 문자 TB2가 존재하면 문자 TB1에서 PI1 값이 대체된다.

TC2 문자
문자 TC2는 T=0 또는 T=1 프로토콜을 위한 기본 EMV ATR 응답에서 전송되지 않지만, ISO 7816 규격에 정의되어 있다. TC2가 존재하는 경우 이는 프로토콜 유형 T=0에만 해당된다. TC2는 스마트 카드에 의해 전송되는 임의 문자에서 시작 비트의 리딩 에지와 카드 또는 단말기에 의해 전송되는 이전 문자 시작 비트의 리딩 에지 간의 최대 간격을 결정하는 작업 대기 시간 정수(WI)를 전달한다. 작업 대기 시간의 값은 다음과 같이 나타낼 수 있다.

Work Waiting Time = 960 × D ×WI (Eq.3)

여기서 D는 비트 레이트 조정 인수이다(위 TA1 설명 참조).

TC2가 ATR 시퀀스에 포함되어 있지 않으면, 디폴트로 WI = 0x0A가 사용된다고 가정한다.

TD2 문자
TD2 문자는 TD1 문자와 동일한 기능을 한다. 자세한 내용은 위의 TD1 설명을 참조한다. 표 3의 프로토콜 T=1에서는 TD2가 존재하며 0x31 값을 포함하고 있다. 이 값은 TA3과 TB3이 존재하고 TC3과 TD3은 존재하지 않으며, 프로토콜 유형이 T=1임을 나타낸다.

TA3 문자
TA3 문자는 스마트 카드에 대한 정보 필드 크기 정수(IFSI)를 전달한다. IFSI는 스마트 카드에 대한 정보 필드 크기를 결정하며, 이것은 카드에서 수신할 수 있는 정보 필드 (INF) 블록의 최대 길이이다. 필드 크기는 0x01과 0xFE 사이의 어느 값이나 될 수 있다. 0x0과 0xFF 값은 이후 사용을 위해 남겨진다. 기본 ATR에서 T=1 프로토콜을 사용할 때 TA3은 0x10 ~ 0xFE 범위의 값을 갖는데, 이것은 IFSC가 16 ~ 254바이트 범위에 있음을 나타낸다. TA3을 포함하고 있지 않은 ATR의 경우 단말기는 디폴트 값 0x20을 가정한다.

TB3 문자
TB3 문자는 문자 대기 시간(CWT)과 블록 대기 시간(BWT)을 계산하기 위해 사용되는 문자 대기 시간 정수(CWI)와 블록 대기 시간 정수(BWI)의 값을 나타낸다. TB3(b1 ~ b4)의 최하위 니블은 CWI 값을 나타내며, 최상위 니블(b5 ~ b8)은 BWI 값을 나타낸다. T=1 프로토콜의 기본 ATR에서 TB3 문자는 0 ~ 5 (CWI = 0 ~ 5) 범위의 최하위 니블과 0 ~ 4 (BWI = 0 ~ 4) 범위의 최상위 니블을 갖는다.

TC3 문자
문자 TC3는 T=0 또는 T=1 프로토콜을 위한 기본 EMV ATR 응답에서 전송되지 않지만, ISO 7816 규격에 정의되어 있다. TC3이 존재하는 경우, 이것은 사용할 블록 에러 검출 유형을 나타낸다. TC3이 존재하지 않으면, 디폴트 LRC(longitudinal redundancy check)로 블록 에러 검사가 사용된다.

TCK 문자
TCK 문자는 검사 문자로, ATR에서 전송되는 데이터의 무결성을 검사할 수 있는 값을 갖는다. T0 ~ TCK(포함)에서 모든 바이트의 논리합이 제로인 한, TCK의 값은 어느 값이나 될 수 있다. TCK는 T=0에서는 사용되지 않지만 다른 모든 경우 ATR에서 리턴된다.

ATR 요약
단말기가 ATR 시퀀스에서 마지막 문자를 수신한 후 필요한 파라미터가 카드로부터 단말기로 전송되면, DS8007에서 인터페이스 파라미터에 필요한 모든 조정을 수행할 수 있다. 그런 다음 통신을 시작한다.

APDU (Application Protocol Data Unit)

앞에서 설명했듯이 카드 세션의 다음 단계는 트랜잭션의 실행이다. 트랜잭션 중에 수행되는 특정 동작은 카드와 계정 유형 (신용, 직불 등) 및 사용자의 요구에 의해 결정된다. 특정 동작과 상관없이 트랜잭션은 단말기에서 스마트 카드로 보내는 명령을 통해 이루어진다. 스마트 카드는 요청된 동작을 수행하며 잠재적으로 결과를 통신할 수 있다. 카드의 동작은 메모리 위치를 읽는 간단한 동작에서부터 암호화 동작을 수행하는 복잡한 형태까지 다양하다. 동작과 관계없이 단말기와 카드 간의 통신은 APDU를 통해 수행된다.

애플리케이션을 실행하려면 스마트 카드와 단말기는 정보를 교환해야 한다. 이러한 정보의 공유는 명령-응답 데이터 교환을 통해 이뤄진다. 단말기가 명령을 생성하여 스마트 카드에 전송하면, 스마트 카드는 이 명령을 해석하고 응답을 보낸다. 이 명령-응답 메시지 쌍을 APDU(Application Protocol Data Unit)라고 한다. 단말기에서 전송되는 특정 명령 메시지(C-APDU)는 카드의 특정 응답 메시지와 대응된다(R-APDU). 이들 메시지를 APDU 명령-응답 쌍이라고 한다. EMV 규격에서는 이 두 가지 메시지 유형을 자세히 정의하고 있으며, 그 형식에 대해서는 아래에서 설명한다.

C-APDU 형식
단말기는 모든 명령 APDU를 시작한다. 이 명령은 필수적인 4바이트 헤더와 데이터를 포함할 수 있는 가변 길이 바디 (body) 옵션으로 구성된다. C-APDU에 포함되는 데이터 바이트 수는 명령 바이트 Lc에서 지정된다. 단말기에서 카드의 응답으로부터 수신이 예상되는 바이트 수는 명령 바이트 Le에서 지정된다. 표 4는 C-APDU 형식을 보여주며, 문자는 표 5에 설명되어 있다.

표 4. 명령 APDU 구조
CLA INS P1 P2 Lc Data Le
←Mandatory Header→ ←Conditional Body→

표 5. 명령 APDU 내용 설명
Code Description Length
CLA Class of instruction 1
INS Instruction code 1
P1 Instruction parameter 1 1
P2 Instruction parameter 2 1
Lc Number of bytes present in command date field 0 or 1
Data String of data bytes sent in command (= Lc) Variable
Le Maximum number of data bytes expected in data field of response 0 or 1

명령 APDU의 첫 번째 바이트는 명령 클래스로 정의되며 CLA라고 한다. 이 바이트는 0xFF를 제외한 모든 8비트 값을 취할 수 있다. 그러나 지금은 0과 8의 최상위 니블 값만 사용된다. 0의 값을 갖는 최상위 니블은 산업간 (interindustry) 명령으로 정의되며, 8의 값은 EMV 규격이다.

명령 APDU의 두 번째 바이트는 명령 코드이며 INS라고 한다. 이 바이트는 최하위 비트가 0이고 최상위 니블이 6도 9도 아닐 때에만 유효하다.

필수 헤더의 P1 및 P2 바이트는 특정 명령에 대한 파라미터를 포함하며 임의 값이 될 수 있다. 사용하지 않을 경우 파라미터 바이트 값은 0x00이어야 한다.

R-APDU
스마트 카드는 단말기로부터 APDU 명령을 수신하고 해석한 후 응답을 리턴한다. 규격에 정의되어 있듯이 이 응답은 가변 길이 바디 옵션과 2바이트로 이루어진 필수 트레일러로 구성된다. 이 형식은 표 6에 나와 있으며, APDU 응답의 내용은 표 7에 설명되어 있다.

표 6. APDU 카드 응답 형식
Data SW1 SW2
←Body→ ←Trailer→

표 7. APDU 명령 응답 내용
Code Description Length
Data String of data bytes received in APDU response Var (= Lr)
SW1 Command processing status 1
SW2 Command processing qualifier 1

카드 응답의 예상 길이는 APDU 명령의 Le 코드 부분으로 전송된다. 응답의 실제 길이는 Lr이라고 한다. 카드가 Lr 값을 전송하지 않더라도 애플리케이션에서 필요한 경우 단말기는 값을 계산할 수 있다.

명령의 정상적인 완료를 위해 스마트 카드는 SW1을 0x90로, SW2를 0x00로 리턴한다. 그 밖의 다른 모든 응답은 에러 또는 경고가 발생했음을 뜻한다.²

예제 코드

이 애플리케이션 노트에서 제공되는 소프트웨어는 다운로드 파일 an4029_sw.zip에 포함되어 있다. 이 파일에는 실행 헥사 파일(ds8007.hex)을 생성하는 데 필요한 모든 C (main.c, ds8007.c, LCD_Funct.c) 및 어셈블리 언어 (Startup.a51) 소스 코드가 포함된다. 코드는 Keil PK51 개발자용 킷과 µVision® Integrated Development Environment (IDE)를 사용하여 컴파일하고 링크되었다. µVision 프로젝트 파일 (ds8007.Uv2)도 .zip 파일에 포함되어 있다. .HEX 파일은 Maxim의 DS8007 EV 킷에서 DS8007 스마트 카드 인터페이스 보드상에 로드한 다음 실행하였다. 예제 소프트웨어는 파워 업, ATR, APDU 및 파워 다운 동작을 포함하여 완전한 스마트 카드 세션을 구현한다. 덤 터미널에 연결하면 보드와 소프트웨어는 38,400 속도로 RS-232 직렬 출력을 생성한다. 이 출력은 아래 그림 4에 나와 있다. 소프트웨어에 대한 자세한 설명은 이 애플리케이션 노트의 범위를 벗어나지만, 제공되는 소스 코드는 DS5002 보안 마이크로프로세서와 DS8007 멀티프로토콜 듀얼 스마트 카드 인터페이스 칩을 사용하는 완벽한 스마트 카드 인터페이스의 기본으로 사용할 수 있다.


그림 4. 소프트웨어 출력

예제 소프트웨어를 테스트하기 위해 Advanced Card Systems(ACS)의 마이크로컨트롤러 기반 스마트 카드를 사용하였다. 이 카드는 마이크로컨트롤러 기반 장치로 ACS 스마트 카드 운영 시스템 버전 1(ACOS1) 임베디드 운영 시스템 기능을 실행하며, 다음과 같은 특징이 있다.
  • 애플리케이션 데이터를 위한 8kB EEPROM 메모리
  • ISO 7816-3, T=0 프로토콜 준수
  • DES 및 MAC 기능
  • 난수를 기반으로 하는 세션 키
  • 카드 홀더를 통해 변경할 수 있는 PIN
  • 상호 인증을 위한 키 쌍 (Key pair)
ACOS1 문서는 이 카드가 19바이트의 데이터로 리셋에 응답한다는 것을 보여준다. 그림 4에서 볼 수 있듯이 T0에 대해 리턴된 값은 0xBE이다. 하이 니블(0xB)은 TS와 함께 ATR에 TA1, TB1, TD1이 포함됨을 나타낸다. 로우 니블은 0xE를 포함하고 있으며, 이것은 14개의 히스토리컬 바이트가 ATR 응답에 포함됨을 나타낸다(위의 문자 T0 설명 참조). 따라서 총 19바이트가 카드로부터의 ATR에 포함된다.

이 예제 소프트웨어에서는 1 ADPU, 시작 세션 명령이 실행된다. 이 명령의 형식은 다음과 같다.

CLA INS P1 P2 P3
0x80 0x84 0x00 0x00 0x08

시작 세션 명령에 대한 응답 형식은 다음과 같다.

Data SW1 SW2
RNDc (8 bytes from card) Status Status

그림 4에 보이는 소프트웨어의 출력은 카드로부터 리턴된 난수가 0xCB, 0xC4, 0xBD, 0xD5, 0xA4, 0x7E, 0x36, 0x3F라는 것을 나타낸다. 또 리턴된 상태가 0x90, 0x00이라는 것은 명령이 성공적으로 완료되었음을 뜻한다.

결론

DS8007은 마이크로컨트롤러와 스마트 카드의 인터페이싱을 용이하게 해주는 혼합 신호 주변 장치이다. 이 소자는 2개의 개별적인 스마트 카드에 물리적으로 인터페이싱하는 데 필요한 모든 전기적 신호를 제공한다. 이 소자에는 데이터 통신을 위한 ISO UART뿐 아니라 자동 카드 액티베이션 및 디액티베이션을 제어하는 내부 시퀀서가 포함되어 있다. 또 차지 펌프와 전압 레귤레이터가 내장되어 있어 2.7V ~ 6.0V의 전원 전압으로 동작하면서 동시에 2개의 독립적인 스마트 카드 전원 전압을 생성할 수 있는데, 이 중 하나는 1.8V, 3.0V 또는 5V로 설정할 수 있다. 마이크로컨트롤러와의 통신은 비다중화 구성으로 데이터를 전달하거나 다중화 구성으로 데이터와 어드레스를 전달하는 표준, 병렬 8비트 버스를 통해 수행된다. 제공되는 소프트웨어는 스마트 카드 인터페이스로 DS5002 보안 마이크로프로세서와 DS8007을 사용하여 완벽한 카드 세션을 구현한다. ATR에서 스마트 카드에 의해 리턴되는 문자는 38400 속도 보드의 직렬 포트로 출력되며, 카드에는 "시작 세션" 명령 APDU가 전송된다. 이렇게 발생된 난수도 직렬 포트로 출력된다.

¹ java.sun.com/products/javacard/smartcards.html. 출처: Gartner Group.
² 명령 APDU 응답 에러 또는 경고 상태 코드에 대한 설명은 EMV 규격 Book-1 Part II Section 6에 나와 있다.

이 내용의 중국어 버전이 EDN China 2007년 9월호에 게재되었다.

µVision은 Keil Corporation의 등록상표이다.
EMV는 EMVCo LLC 소유 상표이다. (EMVCo 관련 법적 고지 참조.)
EuroCard는 EuroCard Inc.의 등록상표이다.
MasterCard는 MasterCard International Inc.의 등록상표이다.
VISA는 Visa International Service Association의 등록상표이다.

 

 

 

 

 

 

출처 : http://blog.naver.com/neokcu?Redirect=Log&logNo=90052761039

 

 

 

 

 

 

신고

'Skill > Interface' 카테고리의 다른 글

프로세스간 통신(IPC ; Inter-Process Communication)  (1) 2014.04.02
Socket 에 대한 기본지식  (1) 2014.03.03
MAXIM 스마트 카드 I/F 원리  (0) 2014.02.26

Comment +0