2012년 5월 1일 화요일

[VoIP SIP 알자/11-2. SIP 서비스 Call Flow]

출처 : http://blog.naver.com/mongu2/140123155328



[고급 전화 서비스]
SIP 기반 전화서비스에 대한 기본적인 기대는, 이 서비스가 인터넷에서 구현될 수 있고, 서비스사간의 경계를 없애며,
나아가 개별 회사의 제품이나 소프트웨어에 구애 받지 않을 것이라는 점이다.
   
* 전화통신의 고급 서비스 기능
PBX 및 센트릭스 기능들
사설 구내 교환 서비스(CLASS:Custom Local Area Signaling Services) 기능들
지능망(Advanced Intelligent Network) 서비스
   
기존 PBX 제품들은 상호 연동을 기대할 수 없다. 하지만 인터넷 기반 PBX 서비스들에 대한 표준화는 그 자체로
기존 PBX 시장에 지각변동을 일으키기에 충분하다.
   
[PBX 및 CLASS(사설 구내 교환 서비스) 기능]
   
ㄱ. 호 전환(Call Transfer)
ㄴ. 통화중 대기(Call waiting)
ㄷ. 호 보류(Call Hold)
ㄹ. 호 교체(Call Park and Pickup)
ㅁ. 착신 전환(Call Forwarding)
ㅂ. 발신자 표시(Calling Line Identification)
ㅅ. 수발신 호 걸러내기(incoming and outgoing call screening)
ㅇ. 자동 콜백(automatic callback and recall)
ㅈ. 단축 다이얼
ㅊ. 컨퍼런스 콜
ㅋ. 음성메일
ㅌ. 음성 자동 안내 시스템(IVR)
ㅍ. 최적 라우팅 서비스
ㅎ. 데이터베이스 관련 서비스
   
   
ㄱ. 호 전환(Call Transfer)
크게 4가지의 형태(Unattended, Attended, Consultation Hold, Instant Messaging)가 있으며 REFER 메소드로 구현된다.
   
a. Unattended (무조건 확인 없이 전환)
: 전화를 돌려주는 측이 REFER 메시지를 보낸 후 바로 BYE 메시지를 보내 호 전환 결과에 무관하게 현재 호를 종료한다.
! 아래는 Alice<->Bob 간 통화 중 Alice 가 Carol 로 호를 전환 해주는 과정의 Flow 이다.
   
   
b. Attended (확인 후 전환)
: 일시적인 3자간 컨퍼런싱과 같다. 돌려주는 측은 호 전환 진행상황을 주시하다가 호 전환이 이루어진 것을 확인 한 후
호에서 빠진다. 즉, 통화 연결음 후 통화 완료 후 전환 후 빠지는 방법
! 아래는 Alice<->Bob 간 통화 중 Bob 가 Carol 에게 호를 전환 해주고 빠지는 과정의 Flow 이다.
   
   
c. Consultation Hold (확인 없는 호 전환)
: 돌려주는 측이 REFER 요청에 대한 응답을 기다리는 동안 발신자도 기다리게 한다. REFER 요청에 대한 결과로 호 전환이
성공하면 BYE 메시지를 보내 기존 호를 종료한다. 즉, 통화 연결음만 듣고 전환 후 빠지는 방법
   
d. Instant Messaging
: 돌려주는 측이 메시지에 URI를 보내어 URI를 선택하면 발신자와 호 연결이 된다.
   
   
tip. 시스코 IOS 장비에서 transfer-system
   
   
ㄴ. 통화중 대기(Call waiting)
: SIP 네트워크는 '회선'이라는 개념이 없기 때문에 이와 정확히 일치하는 서비스는 없다. 하지만 수신측에서 현재
통화중인 상태임에도 불구하고 180Ringing 응답을 보낸 후, 현재 호를 중단하고 새로운 호를 받을 지, 아니면 두 번째
호 발신자를 그냥 무시할 지를 결정할 수 있다.
! 아래는 시스코 의 Call waiting 의 Call Flow 이다.
! SIP A<-> SIP B 통화 중 SIP C가 SIP B로 통화를 하게 되면 SIP B에 display 에 두번째 통화가 표현이 되고
! SIP B는 SIP C를 받게 되면 SIP A는 잠시 Hold 상태가 된다. 이후 SIP B는 SIP C와 통화를 한다.
! 중간에 SIP B가 SIP A에게 미디어를 단방향으로 전달하게 하는 INVITE(a=sendonly)로 보내는 것 알 수 있다.
! 이후 SIP B가 SIP A와 통화를 재게 하기 위해서 INVITE(a=sendrecv)를 다시 보내는 것 을 알 수 있다.
   
   
ㄷ. 호 보류(Call Hold)
PSTN에서 이 기능은 매우 다양한다. 간단하게는 전화기의 '보류' 버튼을 눌러서 수화기의 스피커와 마이크를 차단하는
것에서부터 PBX나 ISDN 시스템의 고급 서비스에까지 걸쳐 있다. SIP 에서는 통화중에 re-INVITE 메시지를 보내
미디어 스트림을 양방향 통신에서 단방향(보내기만 하는) 통신으로 변경함으로써 호 보류 기능을 제공할 수 있다.
초기 버전에서는 SDP의 IP 주소를 0.0.0.0 으로 설정한 re-INVITE 메시지가 이 기능을 담당했다. 호 보류의 해제는
0 이 아닌 IP 주소의 re-INVITE 메시지를 보내 양방향 통신으로 변경함으로써 이루어 진다.
! Alice 와 Bob 이 통화 중 Bob 이 hold 후 hole 해제 후 통화 과정의 Flow 이다.
   
   
ㄹ. 호 교체(Call Park and Pickup)
현재 호를 잠시 보류하고 다른 장소에서 호를 재개하는 기능.
SIP에서는 REFER 를 이용한 방식제3자 호 제어re-INVITE를 통한 방식 등이 있다.
!- Call Park 아래는 Alice<->Bob 통화 중 Bob이 REFER 로 Call Park 후 Carol 이 Alice 와 통화를 재개하는 방식이다.
   
!- Call Pickup, Alice 가 Bob에게 전화를 하지만 Bob이 부재중이라서 Bill 이 대신 Bob에게 걸려온 전화를 pickup 한다.
   
   
ㅁ. 착신 전환(Call Forwarding)
착신 전환은 3가지로 형태로 나누어진다. 즉 '통화중/부재중/무조건 착신전환' 이다.
SIP 착신 전환은 [7. SIP 서비스] 에서 알아보았습니다. Proxy 나 UA에서 기능 제공될 수 있습니다.
   
a. 무조건 착신 전환(Unconditional)
! SIP A가 SIP B에게 전화를 하였지만 무조건 착신 전환에 의해 SIP C에게 전화가 걸리게 됩니다.
   
!- 아래는 Alice 가 Bob에게 전화를 하였지만 Proxy에서 Bob의 착신전화측은 PSTN(Gateway측)으로 INVITE 보냄
   
b. 퉁화중 착신 전환(Busy)
! Alice 가 Bob에게 통화를 시도하였으나 현재 Bob(B1) 은 통화 중이라서 486 메시지 후 Bob(B2)로 INVITE 한다.
   
c. 부재중 착신 전환(No Answer)
일정 기간 동안 전화를 받지 않을 시 다른 쪽으로 호를 전환하는 방법이다.
! Alice 가 Bob(B1)에게 전화를 하였으나 일정 기간 동안(TIMEOUT!) Bob(B1)이 응답하지 않으면 Bob(B2)에게 호 전환.
   
   
ㅂ. 발신자 표시(Calling Line Identification)
위 기능은 모르는 사람으로 부터 오는 전화는 미리 차단할 수 있다. SIP 에서는 From 헤더 정보를 통해 간단히 구현 됨.
문제는 From 헤더가 발신 UA에 의해 작성되는 것이기 때문에 정확하지 않을 수 있다. 대안으로 [9. SIP보안]에서 살펴본
Identity 헤더를 통해 From 헤더의 정확성을 검증 할 수 있다.
   
   
ㅅ. 수발신 호 걸러내기(incoming and outgoing call screening)
이 기능은 Proxy 나 UA에서 구현 가능. 메시지의 Request-URI 나 From 헤더를 미리 저장된 허용 또는 차단 URI 목록과
비교하여 적절한 동작을 수행한다. 예를 들면 차단 URI에 해당되면 403 Forbidden 응답을 보내고 호를 차단한다.
발신 호의 경우 UA가 항샹 Outbound Proxy 를 기본으로 사용하도록 설정되어 있다면 그 Proxy 에서 걸러내기 기능을
수행할 수 있다. 수신 호의 경우에도 UA가 Inbound Proxy 하고만 통신하도록 설정되어 있다면 수신 호 걸러내기 기능은
Inbound Proxy 에서 제공될 수 있다.
   
! incoming call screening (수신호 걸러내기)
Alice 가 Bob 에게 전화를 하였지만 Bob의 차단 List 에 Alice 가 있어서 차단 되고 차단에 대한 간단한 응답 멘트를 들음.
   
! outcoming call screening (발신호 걸러내기)
   
   
ㅇ. 자동 콜백(automatic callback and recall)
PSTN 자동 콜백은 발신자 표시 서비스를 이용하여 받지 못한 전화를 다시 걸어준다. SIP에서는 성공하지 못한 이전
INVITE 메시지들의 From 헤더를 이용한다. PSTN 자동 재시도는 상대방이 통화중으로 인해 실패했던 호에 대해
상대방이 통화를 마치는대로 다시 연결해주는 서비스이다. SIP에서는 상태정보 서비스로 간단히 해결된다.
상대방에게 통화를 끝내는대로 알려줄 것을 요청하는 SUBSCRIBE 메시지를 보내고 NOTIFY 메시지를 통해 자동으로
INVITE 메시지를 다시 보내도록 한다. [6장] 참고
   
! Alice 가 Bob 에게 전화를 하였으나 Bob 이 통화 중이다. Bob은 AutoCallBack 기능에 의해서 Subscirbe/NOTIFY 을
통해 Bob가 이후 전화 가능 상태가 되면 NOTIFT를 보내엇 Alice 가 다시 INVITE 가 보내어지게 한다.
   
!- 아래는 시스코의 CallBack 서비스 실행 후
   
   
ㅈ. 단축 다이얼
작은 갯수의 번호만으로 전화를 걸 수 있는 기능. 단축 다이얼 정보는 전화기 또는 망에 저장된다.
! 시스코의 스피드 다이얼 설정 화면(단축 다이얼)
   
   
ㅊ. 컨퍼런스 콜
[14장]에서 다루기로 한다.
   
   
ㅋ. 음성메일
[12장]에서 다루기로 한다
   
ㅌ. 음성 자동 안내 시스템(IVR)
시스템이 자동으로 전화를 받아 음성 안내나 음성 멘트를 내보낸다. 발신자의 음성이나 DTMF 신호(키 패드 입력)
로부터 정보를 수집하여, 필요 시 담당자에게 호를 연결, 즉 전환한다. 이 뒤 제3자 제어 방식으로 구현 가능.
   
ㅍ. 최적 라우팅 서비스
호 설정 경로를 시간, 발신 위치, 트래픽 상황 등에 따라 최적화하여 제공하는 서비스, Proxy 서버에 의해 제공 된다.
   
ㅎ. 데이터베이스 관련 서비스
PSTN망에서는 망과 DB가 분리되어 있어 DB에 접근하는 일이 매우 민감한 문제이다. 반면 SIP은 SIP 장비나 DB 서버나
모두 같은 인터넷에 있기 때문에 DB에 접근하는 것도 간단하다. 보통 HTTP나 FTP가 사용되고 간단한 질의 서비스는
SIP Redirect Server 를 통해 제공된다.
   
   
* 참고
http://www.flypiggy.org/mtwin/tech-invite/ <- SIP Call Flow(강추!)


* 쏠라구구 생각
위 기능들은 대부분의 PSTN에서 제공하는 기술로 VoIP 에서도 거의 필수적으로 구현되야만 하는 기술이라 생각합니다.
해당 서비스 기술들이 어떠한 Call Flow 를 통해서 제공되는지 명확히 알고 있어야 '기능 구현/장애 처리/고객과대화' 를
유연하게 처리할 수 있을거라 생각합니다. 물론 장비/단말에서도 지원이 되어야 겠지요.


Asterisk에서 Dial Plan 설정하는 extensions.conf 파일

출처 : http://jhyuns.tistory.com/entry/PracticerAsterisk%EC%9D%98-%EB%8B%A4%EC%9D%B4%EC%96%BC%ED%94%8C%EB%9E%9C%EC%9D%98-%EC%84%A4%EC%A0%95%EC%9D%84-%EC%9C%84%ED%95%9C-extensionsconf-%EC%84%A4%EB%AA%85


Asterisk에서 Dial Plan 설정하는 extensions.conf 파일

◈ 다이얼 플랜(Dial Plan)의 개요

1. 다이얼 플랜이란?
간단히 말하자면 어느 번호의 Inbound(착신)와 Oubound(발신) Call(호)를 어떻게 처리할까 하는 통화 룰을 
결정하는 것이라 할 수 있겠 습니다.(이런 부분을 Asterisk는 자유롭게 커스텀마이즈 할 수 있다는 것이, 
Asterisk의 강점입니다.)
따라서, extensions.conf 은 위와 같은 콜의 흐름을 기술해 나가는 설정 파일이라 하겠습니다.

2. extensions.conf 파일 
Extension은 , 어느 채널의 착신(처)이나 다이얼 숫자를 기동되는 명령이 됩니다.
Call이 다이얼 플랜에 따라서 어떻게 다루어질까를 결정합니다.
이 파일에 기술 되는 다이얼 플랜은,
Context(문맥), Extension(내선번호), Priority(우선순위), Application(응용부)
의 4 부분으로 구성되어집니다. (※ 위의 한글용어는 설명을 위해 임의로 붙였습니다.)

exten => extension명(내선번호), priority(우선순위), Application(응용명령)

3. Context(문맥)
다이얼 플랜을 그룹에 이름을 붙인 것이 Context가 됩니다. 어떤 Context 안에 정의된 extension는 
다른 Context에 영향을 주지 못합니다. (단 "include =>"로 관계가 연결되지 않았을 경우임.)
Context는 괄호 [ ] 안에 표기하여 사용하며, 알파벳(대,소문자), 숫자, 하이픈(-),언더스코아(_)로만
이루어진 문자로 표기합니다. 예) [out-going], [070_inbound]

Context 중에서 [general] 은 다이얼 플랜에 관한 일반 설정이 있는 Context 이고, [global]은 설정 
파일에서 사용될 전역변수(Global Variable)를 정의하는 특별한 콘텍스트명이 있습니다.

◈ 다이얼 플랜(Dial Plan) 설정하기

전번에 설명드린 sip.conf와 연장하여 /etc/asterisk/extensions.conf 파일을 설명드리고자 합니다.

전에 sip.conf에 등록하였던 내선번호 2000~2002 사이에 통화에 대한 다이얼 플랜을 예로 들어 설명하고자 합니다.

1. 우선 /etc/asterisk/extensions.conf 파일을 백업을 하여 두십시오.

# cp /etc/asterisk/extensions.conf /etc/asterisk/extensions.conf.bak

위와 같이 백업을 해두셨다면, 신규파일을 작성하면서 설명을 보는 것이 좋다고 생각됩니다.

2. 이제 아래와 같은 내용으로 /etc/asterisk/extensions.conf 를 편집합시다.

;-------------------------이하 설정-----------------------
[default];현재 설정 없음.
[lan]exten => 2000,1,Dial(SIP/2000,30)
exten => 2000,2,Congestion
exten => 2000,102,Busy

exten => 2001,1,Dial(SIP/2001,30)
exten => 2001,2,Congestion
exten => 2001,102,Busy

exten => 2002,1,Dial(SIP/2002,30)
exten => 2002,2,Congestion
exten => 2002,102,Busy


;콜 테스트용
; 9000번 번호에 다이얼 하면, 아래 행의 순서로 실행됩니다
.
exten => 9000,1,Answer()
exten => 9000,2,Wait(1)
exten => 9000,3,Playback(demo-congrats)
exten => 9000,4,Echo()
exten => 9000,5,Hangup()
;---------------------------설정 끝 ----------------------------
위 와 같이, extensions.conf을 설정하고 asterisk를 재시작하믄 간단하게나마 내선 통화와 콜백 테스트는 
할 수 있게 될 겁니다.

3. 위파일을 적용 시키려면 콘솔 화면에서 Asterisk를 재가동합니다.

# asteriskr -vvvvvr
ipbpxsrv*CLI> reload


◈ 다이얼 플랜(Dial Plan)의 각 항목 해석

9000 번으로 콜 테스트를 성공 하면, 각각의 내선번호로 걸어 보십시오. 각각의 내선번호끼리 통화가 가능하면
위 설정이 잘 적용 된것입니다. ( 앗 ! 저의 환경에서는 약간의 에코가 걸렸습니다만, 통화는 가능 햇습니다.)

그럼 위의 설정한 다이얼 플랜의 각 항목을 설명해 보겟습니다.
/etc/asterisk/extensions.conf
 1: [default]
 2: ;현재 설정 없음.
 3:
 4: [lan]
 5: exten => 2000,1,Dial(SIP/2000,30)
 6: exten => 2000,2,Congestion
 7: exten => 2000,102,Busy

 8: exten => 2001,1,Dial(SIP/2001,30)
 9: exten => 2001,2,Congestion
10: exten => 2001,102,Busy

11: exten => 2002,1,Dial(SIP/2002,30)
12: exten => 2002,2,Congestion
13: exten => 2002,102,Busy

14: ; 콜 테스트용
15: ; 9000 번호에 다이얼 하면, 아래의 행의 순서로 실행됩니다.
16: exten => 9000,1,Answer()
17: exten => 9000,2,Wait(1)
18: exten => 9000,3,Playback(demo-congrats)
19: exten => 9000,4,Echo()
20: exten => 9000,5,Hangup()

[해설]
1행    Context [default]는 sip.conf 등으로 현재 사용하고 있었습니다만,
     [general]에 기술되어 있기 때문에, 준비되어 있어라고 하는 것으로 기입했습니다.

4행    sip.conf그리고 기술한, Context [lan]을 준비합니다.

5행    exten => 2000,1,Dial(SIP/2000,30) 
      Dial()함수로 SIP의 2000(내선2000)을 불러 내며(calling), 응답 제산시간을 30초로 하고 있습니다.
      2000(내선2000)이 응답하면 통화가 가능 합니다.
      제한 시간 내에 응답하지 않을 경우, 현재의 우선 순위(priority)에+1(합계2)해, 거기에 대응한
레코드를 호출합니다.
      그리고 2000(내선2000)이 통화중인 경우 원래 호출 자체를 할 수 없는 경우는 현재의 우선 순위에
+101되어 대응 레코드가 불려 갑니다.

6행    exten => 2000,2,Congestion
      우선 순위가2, 즉 Dial() 함수로 2000을 콜링하여,
      제한 시간내에 응답하지 않았던 경우에 호출되는 부분입니다..
      Congestion 명령어는 발신측이 자르는 것을 기다립니다. 자를 때까지는 절단음이 흐릅니다.


7행    exten => 2000,102,Busy
      우선 순위가102, 즉 2000(내선2000)이 다른 곳과 통화중에 있어,
      Dial() 함수로 2000을 호출할 수 없었던 경우의 처리입니다.
      Busy명령어로 Busy음을 흘립니다.


8~10행  2001의 설정

11~13행 2002의 설정

16행   exten => 9000,1,Answer()
     9000번의 콜에 응답합니다.

17행   exten => 9000,2,Wait(1)
     착신과 동시에 음성을 발생시키면, 이야기 처음이 빠지는 일이 있으므로1초 wait 시킵니다.

18행   exten => 9000,3,Playback(demo-congrats)
     demo-congrats.gsm파일을 재생합니다. 확장자(extension)는 기입할 필요는 없습니다.

19행   exten => 9000,4,Echo()
     메세지 재생 후(선택한 녀석이라면 길다!)자신의 소리를 에코 해 줍니다.
발신자가 '#' 를 누르면 종료합니다.

20행째  exten => 9000,5,Hangup()
     끊기, 콜의 단절을 실시합니다.



방금전의 내선의 정보를 정리해 보겠습니다.(매크로 지정)

위에서는 3개의 내선번로만 다이얼 플랜을 했을 뿐입니다만, 많은 내선번홀 가지고 위와 같은 내용을 복수 써 가며 설 
정 하는 것은 큰 일입니다.
200X 로 시작되는 번호를 같은 동작을 주도록 다음과 같이 합니다.

붉은 글씨는 변경하기위하여 삭제될 문이다.
현재의 파일
 
1: [default]
 2: ;현재 설정 없음.
 3:
 4: [lan]
 5: exten => 2000,1,Dial(SIP/2000,30)
 6: exten => 2000,2,Congestion
 7: exten => 2000,102,Busy

 8: exten => 2001,1,Dial(SIP/2001,30)
 9: exten => 2001,2,Congestion
10: exten => 2001,102,Busy

11: exten => 2002,1,Dial(SIP/2002,30)
12: exten => 2002,2,Congestion
13: exten => 2002,102,Busy

14:; 콜 테스트용
15:; 9000 번호에 다이얼 하면 아래의 행 순서로 실행됩니다.
16: exten => 9000,1,Answer()
17: exten => 9000,2,Wait(1)
18: exten => 9000,3,Playback(demo-congrats)
19: exten => 9000,4,Echo()
20: exten => 9000,5,Hangup()

변경 후의 파일
녹색 글자가 바뀐 글자이다.
 1: [default]
 2: ;현재 설정 없음.
 3:
 4: [lan]
 5: exten => _200X,1,Dial(SIP/{EXTEN},30)
 6: exten => _200X,2,Congestion
 7: exten => _200X,102,Busy

 8: ; 콜 테스트용
 9: ; 9000번호로 다이얼 하면 아래의 행 순서로 실행됩니다.
10: exten => 9000,1,Answer()
11: exten => 9000,2,Wait(1)
12: exten => 9000,3,Playback(demo-congrats)
13: exten => 9000,4,Echo()
14: exten => 9000,5,Hangup()

내선마다 준비해 있었던 extension을 하나로 정리했습니다.

1.”_200X”와 같이”_”로 시작되는 경우는, 패턴 지정이라고 나타내 보입니다.2.다음의 문자를 사용할 수 있습니다.

   X : 0 - 9 의 숫자  

   Z : 1 - 9 의 숫자
   N : 2 - 9 의 숫자
   [12679] : 1,2,6,7,9
    . : 와일드 카드
   여기에서는 200X 그러니까, 2000~2009번까지를 지정해 있습니다.

3.${EXTEN} 은 입력된 내선 번호가 들어가는 환경 변수입니다.,
  "2000" 과 다이얼 되면 ${EXTEN} 는, "2000" 되어, "내선 번호 "2000" 가 호출되어집니다.



4. extensions.conf를 리로드 하려면 ,
asterisk의 화면에서
# asterisk -vvvvr
>extensions reload
을 실행 합니다.