2016년 8월 1일 월요일

PJSUA Function Flow-SIP

PJSUA Function Flow-SIP


pjproject-2.5의 pjsua의 오퍼레이션을 소스레벨에서 추적해 본다. PJSIP Developer’s Guide를 중심으로 전화를 수신했을때 수행되는 함수의 흐름을 따라간다.


1. app_init 의 오퍼레이션 절차

  1. pjsip-apps/src/pjsua/pjsua_app.c
  2. pjsua 생성(endpoint 생성)
  3. 응용프로그램용 pool 생성
  4. CLI 및 FE 설정
  5. 설정 파라미터 파싱
  6. 각종 전화상태에 따른 콜백함수 등록(on_call_state, on_incoming_call 등)
  7. 오디오 장치의 캡춰 및 재생의 레이턴시 설정
  8. pjsua 초기화 : pjsua_init()
    1. pjsua_media_subsys_init(): work thread 생성(media): pjmedia_endpt->ioqueue RTP 폴링
    2. work thread 생성(pjsua_0) :  pjsip_endpoint->ioqueue SIP message 폴링
  9. endpoint에 module 등록
    1. 디폴트 모듈을 등록하고 나머지 모듈은 아래에서 등록한다.
    2. pjsip-simple/mwi.c - mod_mwi
    3. pjsip-simple/presence.c - mod_presence
    4. pjsip-ua/sip_100rel.c - mod_100rel.mod
    5. pjsip-ua/sip_inv.c - mod_inv.mod
    6. pjsip-ua/sip_xfer.c - mod_xfer
    7. pjsip/sip_transaction.c -  mod_tsx_layer.mod, mod_stateful_uitl, mod_msg_prit 등록
    8. pjsip/sip_ua_layer.c - mod_ua.mod 등록
    9. pjsua-lib/pjsua_core - pjsua_msg_logger, pjsua_var.mod, pjsua_options_handler 등록
    10. pjsua-lib/pjsua_im.c - mod_pjsua_im
    11. pjsua-lib/pjsua_pres.c - pjsua_unsolicited_mwi_mod
  10. 옵션사항으로 WAV파일 등록
  11. 옵션사항으로 tone 재생기등록
  12. 옵션사항으로 레코딩 파일 등록
  13. Ringback(발신벨소리) 및 Ring(수신벨소리)  생성
  14. AVI 재생기 생성
  15. UDP 전송포트, 생성
    1. pjsua_transport_create() -> pjsip_udp_transport_attach2() ->
    2. transport_attach() -> register_to_ioqueue()
    3. ioqueue_cb.on_read_complete = &udp_on_read_complete
      ioqueue_cb.on_write_complete = &udp_on_write_complete
  16. TCP 전송포트 생성
  17. TLS 전송포트 생성
  18. buddy 등록
  19. 일부 코덱 비활성화 및 우선순위 설정
  20. 콜 초기화


2. pjsua_app_run 의 오퍼레이션 절차

  1. pjsip-apps/src/pjsua/pjsua_app.c
  2. 콘솔 리프레쉬 스레스 생성
  3. pjsua 시작
  4. 전화걸기 파리미터 있다면, 콜생성
  5. 콘솔 대기 및 명령처리 루프
  6. 어플리케이션 종료.


이 후 이벤트에 따라 함수 호출이  수행된다.


3. 주요 자료구조

아래는 여러함수에서 자주 보게되는 자료구조이다.
  • struct pjsua_msg_data
    • SIP message와 함께 추가로 보낼 정보를 위한 구조체.
    • 멤버: target_uri, content_type(MIME type of message body), msg_body …
  • struct pjsua_call
    • 어플리케이션 레벨에서 필요한 콜관련 정보(콜시작시간등)
    • dlg->mod_data[pjsua.mod.id] 에 저장된다.
    • 주요멤버:
      pj_time_val:start_time, res_time
      pjsip_inv_session:inv,
      pjsip_rx_data:*incoming_data,
      void:*hold_msg - Outgoing hold tx_data
      pjsua_med_tp_state_cb :med_ch_cb - media channel callback.


  • struct pjsip_dialog
    • 다이얼로그 구조체, 반드시 API를 이용해서 멤버를 변경해야한다.
    • 어플리케이션은 잠근 후 바로 읽는 것은 가능하다.
    • 잠그는 것은 pjsip_dlg_inc_lock/ xx_dec_lock을 이용해야 한다.
    • 멤버 - pjsip_user_agent, pjsip_endpoint, dlg_set, pjsip_module:usage[max_module]
      mod_data[max_module], … 등
  • struct pjsip_inv
    • pjsip/include/pjsip-ua/sip_inv.h
    • pool_prov와 pool_active는  re-INVITE 와 UPDATE 에서 임시로 사용된다. pool_prov는 SDP offer나 answer에 사용되고 협상이 끝나면 pool_active처럼 만들어지고, pool_active도 리셋된다.
    • 주요멤버:
      pj_pool_t    *pool          - Long term pool
      pj_pool_t    *pool_pov    - Provisional pool,
      pjsip_inv_state     state      - Invite session state
      pjsip_dialog    *dlg             - Underlying dialog
      pjsip_role_e    role             - Invite role: uac/uas
      pjmedia_sdp_neg *neg;      - Negotiator
      pjsip_transaction   *invite_tsx;                      - 1st invite tsx
      void    *mod_data[PJSIP_MAX_MODULE];   - Modules data.
      struct pjsip_timer  *timer;     - Session Timers
      ….


4. 전화 수신 절차

주요수행에 따른 흐름은 아래와 같다.


Transport INVITE 수신
mod_pjsua모듈의 on_rx_request(): mod_pjsua_on_rx_request(rdata) 수행시작


*전화 수신을 위한 리소스 설정 후 100 trying전송
  • UAS Transaction 생성
    Transaction state: NULL -> Trying
  • Dialog 생성
  • Dialog usage:INVITE 세션 생성
  • SDP에 따라 미디어 채널 초기화
  • 100 Trying 메시지 전송
  • 트랜잭션 상태변경 -> 트랜잭션유저:mod_ua 상태변경 -> 다이얼로그 usage 상태변경 -> 어플리케이션 callback함수:on_call_state 수행.
    Transaction state: Trying -> Proceeding
    Invite Session state:PJSIP_INV_STATE_INCOMING
    어플리케이션 callback함수인 on_incoming_call 수행: 링백시작
*INVITE module에서 SDP 협상 및 200 OK를 전송
  • pjsua_call_answer2() 수행시작
  • SDP 협상 후 결과에 따라 미디어채널 업데이트
  • 어플리케이션 callback함수인 on_call_media_state 수행: 링백정지, 컨퍼런스 포트 연결(스트리밍 시작)
  • 200 OK 메시지 전송
  • 트랜잭션 상태변경 -> 트랜잭션유저:mod_ua 상태변경 -> Dialog usage state  -> 어플리케이션 callback함수:on_call_state 수행.
    Transaction state: Proceeding -> Complete
    Invite Session state: PJSIP_INV_STATE_CONNECTING
    call.info: CONNECTING
  • 트랜젹션 상태변경 후 콜백 수행
  • pjsua_call_answer2() 수행완료


mod_pjsua모듈의 on_rx_request(): mod_pjsua_on_rx_reques(rdata) 수행완료


ACK 수신
  • ACK 메시지 수신
  • User agent module on_rx_request 에서 상태변경 및 Transaction Timer 설정.
    Transaction state:Terminated -> Destroyed
    Invite Session state: PJSIP_INV_STATE_CONFIRMED
    call.info: CONFIRMED
  • Transaction destroy는 tsx_set_state()에서 등록한 타이머콜백에서 수행된다.
    tsx_schedule_timer(.., tsx->timeout_timer, timeout,..)


BYE발신
  • BYE메시지 전송
    transaction state: NULL -> Trying)
  • OK 메시지 수신
    Tansaction state: Trying -> Complete
    Invite Session state: PJSIP_INV_STATE_DISCONNECTED
    call.info: DISCONNECTED
  • Transaction destroy는 왜 없을까?? (Dialog session count가 0인데 Dialog를 소멸시키지 않는 이유는??)

각 모듈에 따른 자세한 흐름은 아래와 같다.

4.1. Application

pjsua_init -> worker_thread -> pjsua_handle_events
  • pjsip/src/pjsua-lib/pjsua_core.c
  • poll 이벤트 대기 반복
  • app_init()에서 pjsua_transport_create() 에서 UDP 패킷 수신시 udp_on_read_complete가 콜백함수로 등록되어 UDP를 수신하면 udp_on_read_complete가 자동으로 호출된다.

4.2. Transport Layer :INVITE 수신

4.2.1. udp_on_read_complete()

  • ioqueue로 부터 UDP수신 (recvfrom() 오퍼레이션)이 완료되면 호출된다.
  • pjsip_tpmgr_receive_packet(rdata->tp_info.transport->tpmgr, data) 호출
  • TCP의 경우 pjsip/src/pjsip/sip_transport_tcp.c : on_data_read() 에서 호출된다.


pjsip_tpmgr_receive_packet()
  • pjsip/src/pjsip/sip_transport.c
  • mgr->on_rx_msg(mgr->endpt, ..) 호출


4.2.2. pjsip_tpmgr mgr - on_rx_msg()

  • pjsip/src/pjsip/sip_endpoint.c
  • mgr->on_rx_msg = endpt_on_rx_msg 함수 진입
128 15:04:38.901 sip_endpoint.c  Processing incoming message: Request msg INVITE/cseq=20 (rdata0xb5a0047c)
  • Endpoint Distribution 시작 : pjsip_endpt_process_rx_data() - 우선순위에 따라 각 모듈의 on_rx_request() 콜백을 호출한다. 모듈 호출순서:
    mod-pjsua-log -> mod-msg-print -> mod-tsx-layer -> mod-ua -> mod-100rel -> mod-invite -> mod-evsub
    -> mod-presence -> mod-mwi -> mod-refer -> mod-stateful-util -> mod-pjsuaz
    mod_tsx_layer에 transaction도 없고, mod_ua에 Dialog도 없어 최상위 모듈까지 전달된다.
  • endpt_on_rx_msg 함수 완료


4.3. mod-pjsua-log

4.3.1. pjsip_moudle pjsua_msg_logger - on_rx_request()

  • /pjsip/src/pjsua-lib/pjsua_core.c
  • logging_on_rx_msg 함수진입 메시지 내용 출력
129 15:04:38.901   pjsua_core.c  .RX 1188 bytes Request msg INVITE/cseq=20 (rdata0xb5a0047c) from UDP 192.168    .1.17:5060:
130 INVITE sip:1234@192.168.1.11:5060;ob SIP/2.0
131 Record-Route: <sip:192.168.1.17;lr>
….
  • logging_on_rx_msg 함수완료


4.4. mod-pjsua

4.4.1. pjsip_modlue mod_initializer[mod-pjsua] - on_rx_request()

  • INVITE 요청을 받아 SDP를 협상하고, 협상된 SDP에 따라 미디어를 설정한 후 OK 메시지를 전송한다.
  • pjsip/src/pjsua-lib/pjsua_core.c
  • mod_pjsua_on_rx_request호출 INVITE_METHOD일 경우만 pjsua_call_on_incoming 함수진입
  • 다이얼로그생성 :
    • pjsip_dlg_create_uas_and_inc_lock() 함수진입
    • UAS transaction 생성:pjsip_tsx_create_uas()
    • user agent를 다이얼로그에 등록
20:09:33.842  dlg0xb5a05364  ..UAS dialog created
    • pjsip_dlg_create_uas_and_inc_lock() 함수완료
  • 인증서 설정
  • INVITE 세션생성
    • pjsip_inv_create_uas() 함수진입
    • mod_invite를 dialog usage로 등록
    • UAS invite session 생성
    • pjsip_inv_create_uas() 함수완료
  • 미디어 채널 초기화
    • pjsua_media_channel_init() 함수진입
    • SDP가 없을 경우 pjsua_call_answer()에서 처리된다.
    • RTCP, RTP 소켓 생성 및 네트워크전송 준비 :create_udp_media_transport()
    • 통화를 위한 미디어 인덱스 선택
    • pjsua_media_channel_init() 함수완료
  • 세션 타이머 초기화
  • INVITE에 대한 초기응답 메시지 전송(100 trying)
    • 메시지생성:pjsip_inv_initial_answer(100) 호출
    • 메시지전송:pjsip_inv_send_msg(100) 호출
  • app_int()에서 등록된 app_config.cfg.cb.on_incoming_call() 호출.
  • pjsua_call_on_incoming 함수완료

4.5. Application

4.5.1. app_config.cfg.cb.on_incoming_call()

  • pjsip-apps/src/pjsua/pjsua_app.c
  • on_incoming_call() 함수진입
  • 링백시작
  • 자동응답의 경우 INVITE 요청에 대한 응답을 처리한다.
  • 자동응답인 경우 pjsua_call_answer2() 호출. 아니면 함수완료 후 ui_answer_call()에서 호출됨.
  • pjsua_call_answer2() 함수진입
  • pjsip/src/pjsua-lib/pjsua_call.c
  • 다이얼로그 뮤텍스 잠그고 세션카운트를 증가시킨다.
  • 수신된 콜에 SDP offer가 없다면, 미디어 채널이 초기화 되지않은 경우이므로 미디어 채널을 초기화 한다.
    • pjsua_media_channel_init() 함수 수행,
  • INVITE에 대한 응답 메시지 전송(200 Trying)
    • 메시지생성:pjsip_inv_answer(200) 호출
    • 메시지전송:pjsip_inv_send_msg(200)호출
  • pjsua_call_answer2() 함수완료
  • on_incoming_call() 함수완료

180 Rining 를 UAC에 전달 후 pjsua가  a를 누른 상태,  UAS가 200 OK로 응답하고 미디어가 연결되는 과정이다.


ui_answer_call() 함수진입
  • current_call 은 전역변수로 전화요청받은 콜 아이디가 세팅되어 있다.
  • call_opt 는 전역변수로 현재 통화의 옵션이 세팅되어 있다.
  • 사용자로 부터 상태코드 입력 (예: 200)
  • 메시지를 담을 구조체 pjsua_msg_data 조기화
  • pjsua_call_answer2() 호출: 자동응답의 경우 app_config.cfg.cb. on_incoming_call()에서 호출됨.
    :pjsip_inv_answer(200) 호출,
    pjsip_inv_send_msg(200)호출.
ui_answer_call() 함수완료

4.6. mod-invite

4.6.1. pjsip_inv_answer(): OK 생성

  • INVITE 요청을 처리한다.
  • pjsip/src/pjsip-ua/sip_inv.c
  • process_answer() 함수진입
  • pjsip/src/pjsip-ua/sip_inv.c
  • INVITE 응답과 re-INVITE의 초기화 및 subsequent를 처리한다.
  • SDP negotiator가 준비됐으면, 협상을 시작한다.
  • inv_negotiate_sdp() 호출.
  • process_answer() 함수완료
  • 응답메시지에 세션 타임아웃을 설정한다. : pjsip_timer_update_resp()
  • 지원하지 않는 기능을 헤더에서 제거한다.: cleanup_allow_sup_hdr()


4.6.1.1. inv_negotiate_sdp()

  • SDP 협상을 수행하고 협상정보에 따라 INVITE session의 미디어를 업데이트한다.
  • pjmedia_sdp_neg_negotiate()
  • mod_inv.cb.on_media_update() 호출

4.6.1.2. inv_cb.on_media_update()

pjsua_call_on_media_update() 함수진입
  • SDP 협상이 완료되면 이 INVITE 콜백함수가 호출됨. 이 함수에서 미디어를 시작하거나 업데이트한다.
  • pjsip/src/pjsua-lib/pjsua_call.c
  • 협상된 SPD에 따라 미디어 설정: pjsua_media_channel_update()
  • pjsua_media_channel_update() 함수진입
  • SDP에 따라 stream 설정: pjmedia_stream_info_from_sdp()
  • pjmedia_transport_media_start() : Do nothing.
  • pjsua_aud_channel_update() : Encoder / Decoder 스트림 생성 후 컨퍼런스에 추가.
  • pjsua_media_channel_update() 함수완료
  • app_config.cfg.cb.on_call_media_state() 호출
pjsua_call_on_media_update() 함수완료


app_config.cfg.cb.on_call_media_state()
  • 미디어 상태 변경에 따라 이 콜백함수가 호출됨.
  • call_info의 미디어 타입에 따라 on_call_audio_state(), on_call_video_state() 호출


4.6.1.3. on_call_audio_state()

  • pjsip-apps/src/pjsua/pjsua_app.c
  • 링백 전달 정지.
  • 옵션에 따라 Loopback포트 연결
  • 옵션에 따라 레코딩포트 연결
  • 옵션에 따라 파일플레이백포트 연결
  • pjsua_conf_connect() 함수진입
  • pjsip/src/pjsua-lib/pjsua_aud.c
  • 사운드 디바이스의 idle timer가 활성화된 경우, 비활성화설정.
  • playback & capure를 위한 장치 설정: pjsua_set_snd_dev() - 오디오장치 오픈 및 스레드시작.
  • pjmedia_conf_connect_port() : 연결포트 세팅.
  • pjsua_conf_connect() 함수완료


4.6.2. pjsip_inv_send_msg():OK 전송

  • pjsua_call_answer2()에서 pjsip_inv_answer()수행 후 호출된다.
  • 요청/응잡 메시지를 전달하고 트랜잭션레이어에서  어플리케이션레이어까지 상태변경을 통지한다.(각 모듈의 콜백함수를 호출함으로써 수행된다.)
  • pjsip/src/pjsip-ua/sip_inv.c
  • 디버깅메시지:
inv0xb5a05364  ...Sending Response msg 100/INVITE/cseq=20 (tdta0xb5a0f040)
  • 응답의 경우:pjsip_dlg_send_response()호출, 요청의 경우: pjsip_dlg_send_request()을 호출한다.
    100 trying 또는 200 OK는 응답이므로 pjsip_dlg_send_response()가 호출된다.
  • pjsip_dlg_send_response() 호출


4.6.2.1. pjsip_dlg_send_response()

  • statefully 응답을 전달한다.
  • pjsip/src/pjsip/sip_dialog.c
  • 디버깅메시지
dlg0xb5a05364  ....Sending Response msg 100/INVITE/cseq=20 (tdta0xb5a0f040)
  • pjsip_tsx_send_msg() 함수진입  : 트랜잭션에 응답메시지 전송을 요청한다.
  • 이 함수는 메시지를 전송하기위해 트랜잭션 유저에 의해 호출된다.
  • src/pjsip/sip_transaction.c
  • 디버깅메시지:
tsx0xb5a05d74  ....Sending Response msg 100/INVITE/cseq=20 (tdta0xb5a0f040) in state Trying
  • 트랜잭션에 transport 셀렉터 설정: pjsip_tx_data_set_transport
  • 트랜잭션의 state handler 호출: INVITE 메시지 수신시 tsx_set_state()에서 tsx_state_handler_uas[trying]로 설정되어있다.
  • tsx_on_state_trying() 함수진입
  • 요청메시지를 받았으나 응답을 보내지 않은 상태의 UAS일 경우 Trying state이다.
  • 이 함수는 trying 메시지를 전송하고 트랜잭션상태를 PJSIP_TSX_STATE_PROCEEDING로 변경한다.
    이 상태변경은 어플리케이션 레벨까지 상위 모듈에 전달된다.
  • 메시지 전송: tsx_on_state_proceeding_uas() -> tsx_send_msg() -> pjsip_transport_send()
  • 상태변경 및 변경통지:
    tsx_set_state(PJSIP_TSX_STATE_PROCEEDING) : Transaction State 변경.
    -> (*tsx->tsx_user->on_tsx_state)(tsx, &e) : tsx_user는 mod_ua이다.
    -> struct user_agent mod_ua->on_tsx_state() -> mod_ua_on_tsx_state()
    -> pjsip_dlg_on_tsx_state() : dialog usage modlue에 전달한다.
    -> struct mod_inv->on_tsx_state() -> mod_inv_on_tsx_state()
    ->  (*inv_state_handler[inv->state])(inv, e) -> inv_on_state_null()
    -> inv_set_state(PJSIP_INV_STATE_INCOMING): Invite Session  state 변경
  • mod_inv_on_tsx_state()에서 inv_state_handler() 수행 후 mod_inv.cb.on_tsx_state_changed()수행:
    pjsua_var.ua_cfg.cb.on_call_tsx_state():on_call_tsx_state() 수행
    메시지가 REFER, MESSAGE 일 경우 추가수행
  • tsx_on_state_trying() 함수완료
  • pjsip_tsx_send_msg() 함수완료


4.6.2.2. inv_set_state()

  • pjsip/src/pjsip-ua/sip_inv.c
  • session state를 변경한다. : inv->state = state
  • mod_inv.cb.on_state_changed()  -> pjsua_call_on_state_changed()
  • pjsua_call_on_state_changed() 함수진입
  • pjsip/src/pjsua-lib/pjsua_call.c
  • 이 콜백은 invite session으로 부터 session state가 변경되면 호출된다.
  • pjsua_var.ua_cfg.cb.on_call_state() 호출
  • pjsua_call_on_state_changed() 함수완료


app_config.cfg.cb.on_call_state()
  • invite state 변경시 이 콜백함수가 호출된다.
on_call_state() 함수진입
  • call_info 생성: call_info->state = call->inv->state
  • call_info 의 전화가 끊어진 경우 링백정지: ring_stop()
  • 파일재생의 경우, 재생위치 Rewind.
  • Duration이 있다면, 전화종료.
  • current_call = call_id
on_call_state() 함수완료


4.7. Transport Layer: ACK 수신

udp_on_read_complete() -> pjsip_tpmgr_receive_packet() -> pjsip_tpmgr mgr - on_rx_msg() 호출
  • pjsip/src/pjsip/sip_endpoint.c
  • mgr->on_rx_msg = endpt_on_rx_msg 함수 진입
  • 디버깅 메시지:
16:21:16.176 sip_endpoint.c @Processing incoming message: Request msg ACK/cseq=20 (rdata0xb5a0047c)
  • Endpoint Distribution 시작 : pjsip_endpt_process_rx_data() - 우선순위에 따라 각 모듈의 on_rx_request() 콜백을 호출한다. 모듈 호출순서:
    mod-pjsua-log -> mod-msg-print -> mod-tsx-layer -> mod-ua
    mod-ua에 invite session을 가지 Dialog가 존재하므로 mod-ua->on_rx_reuqest()는 PJ_TRUE를 리턴한다.
  • endpt_on_rx_msg 함수 완료


4.7.1. mod-pjsua-log

pjsip_moudle pjsua_msg_logger - on_rx_request() 호출
  • /pjsip/src/pjsua-lib/pjsua_core.c
  • logging_on_rx_msg 함수진입 메시지 내용 출력
382 16:21:16.176   pjsua_core.c  .RX 434 bytes Request msg ACK/cseq=20 (rdata0xb5a0047c) from UDP 192.168.1.1    7:5060:
383 ACK sip:1234@192.168.1.11:5060;ob SIP/2.0
384 Via: SIP/2.0/UDP 192.168.1.17:5060;branch=z9hG4bK1677.d27d82c2.2
385 Via: SIP/2.0/UDP 192.168.1.26:5060;received=192.168.1.26;rport=5060;branch=z9hG4bK.LPfi39mfK
386 From: "alice" <sip:6983@192.168.1.17>;tag=wXVZb-3v-
387 To: <sip:1234@192.168.1.17>;tag=ded5c253-61ef-4fd9-8d40-726a57fb8721
….
  • logging_on_rx_msg 함수완료

4.7.2. mod-ua

pjsip_moudle -m on_rx_request() 호출
mod_ua_on_rx_request() 함수진입
  • Dialog set에서 Dialog 검색. Dialog가 발견되지 않으면 UAS가 NOTIFY를 SUBSCRIBE전에 보낸 경우임.
  • 다이얼로그에 메시지 전달: pjsip_dlg_on_rx_request()
  • pjsip_dlg_on_rx_request() 함수진입
  • 트랜젹션이 없을 경우, 트랜잭션 생성: pjsip_tsx_create_uas()
  • 다이얼로그 생성(??)
  • *dlg->usage[i]->on_rx_request : mod_inv_on_rx_request() 호출
  • mod_inv_on_rx_request() 함수진입
  • invite sesstion state가 DISCONNECTED가 아닐 때 필요한 ACK request의 SDP 처리 : inv_check_sdp_in_incoming_msg()
  • Invite transaction 종료:pjsip_tsx_terminate()
  • transaction state 변경:
    tsx_set_state(Terminated)  함수진입
    tsx->tsx_user->on_rx_response)(rdata)
    tsx->tsx_user->on_tsx_state()
    tsx_cancel_timer(tsx->timeout_timer)
    tsx_schedule_timer(tsx->timeout_timer)
    tsx_set_state(Terminated)  함수완료
    tsx->tsx_user->on_tsx_state:mod_ua_on_tsx_state() -> pjsip_dlg_on_tsx_state() -> dlg->usage[i]->on_tsx_state:mod_inv_on_tsx_state() -> pjsua_call_on_tsx_state_changed() -> on_call_tsx_state()
    mod_inv_on_rx_request() 함수완료
  • pjsip_dlg_on_rx_request() 함수완료
mod_ua_on_rx_request() 함수완료


4.7.3. Transaction Timer

tsx_set_state에서 등록된 스케쥴 타이머가 시간만료로 콜백함수가 호출된다.

  • transaction 생성시 callback함수 등록:
    tsx_create() :: tsx->timeout_timer.cb = &tsx_timer_callback;
                         tsx->retransmit_timer.cb = &tsx_timer_callback;
    pj_grp_lock_add_handler(tsx->grp_lock,...., &tsx_on_destroy);
  • 타임아웃 등록
    mod_ua_on_rx_request() -> tsx_set_state() :tsx_cancel_timer(), tsx_schedule_timer()
  • 이벤트에 따른 콜백함수 호출:
    pjsip_endpt_handle_events2() -> pj_timer_heap_poll 함수진입
    타임아웃이 발생되면 (*node->cb)(ht, node) : tsx_timer_callback() 이 호출됨.
    pj_grp_lock_dec_ref(grp_lock) : Lock 레퍼런스 카운터가 0이면 tsx_on_destroy()호출 -> Transaction 소멸.
    pj_timer_heap_poll 함수완료


댓글 없음:

댓글 쓰기