프 리 스위치 상태 기 정적 인터페이스 분석
10485 단어 FreeSWITCH
본 고 는 정적 데이터 구조의 시각 에서 FreeSwitch 의 상태 기 를 묘사 하고 자 한다.
FreeSwitch core 는 유한 상태 기 를 실현 했다.모든 호출 된 다 리 는 하나의 상태 기 인 스 턴 스 로 유지 된다.상태 기 정의 인 터 페 이 스 는 freeswitch - 1.8.7 \ src \ include \ \ switchtypes. h 파일 중
/*!
\enum switch_channel_state_t
\brief Channel States (these are the defaults, CS_SOFT_EXECUTE, CS_EXCHANGE_MEDIA, and CS_CONSUME_MEDIA are often overridden by specific apps)
CS_NEW - Channel is newly created.
CS_INIT - Channel has been initialized.
CS_ROUTING - Channel is looking for an extension to execute.
CS_SOFT_EXECUTE - Channel is ready to execute from 3rd party control.
CS_EXECUTE - Channel is executing it's dialplan.
CS_EXCHANGE_MEDIA - Channel is exchanging media with another channel.
CS_PARK - Channel is accepting media awaiting commands.
CS_CONSUME_MEDIA - Channel is consuming all media and dropping it.
CS_HIBERNATE - Channel is in a sleep state.
CS_RESET - Channel is in a reset state.
CS_HANGUP - Channel is flagged for hangup and ready to end.
CS_REPORTING - Channel is ready to collect call detail.
CS_DESTROY - Channel is ready to be destroyed and out of the state machine.
*/
typedef enum {
CS_NEW,
CS_INIT,
CS_ROUTING,
CS_SOFT_EXECUTE,
CS_EXECUTE,
CS_EXCHANGE_MEDIA,
CS_PARK,
CS_CONSUME_MEDIA,
CS_HIBERNATE,
CS_RESET,
CS_HANGUP,
CS_REPORTING,
CS_DESTROY,
CS_NONE
} switch_channel_state_t;
상태 기 인터페이스
외곽 인터페이스
상태 기 인 터 페 이 스 는 리 셋 함수 표 로 상 태 를 처리 해 야 하 는 모듈 은 자신의 인터페이스 리 셋 함 수 를 실현 하고 등록 할 수 있다.상태 기 상태 이전 시 등 록 된 state 를 하나씩 호출 합 니 다.handler。 /*! \brief A table of functions to execute at various states
*/
typedef enum {
SWITCH_SHN_ON_INIT,
SWITCH_SHN_ON_ROUTING,
SWITCH_SHN_ON_EXECUTE,
SWITCH_SHN_ON_HANGUP,
SWITCH_SHN_ON_EXCHANGE_MEDIA,
SWITCH_SHN_ON_SOFT_EXECUTE,
SWITCH_SHN_ON_CONSUME_MEDIA,
SWITCH_SHN_ON_HIBERNATE,
SWITCH_SHN_ON_RESET,
SWITCH_SHN_ON_PARK,
SWITCH_SHN_ON_REPORTING,
SWITCH_SHN_ON_DESTROY
} switch_state_handler_name_t;
struct switch_state_handler_table {
/*! executed when the state changes to init */
switch_state_handler_t on_init;
/*! executed when the state changes to routing */
switch_state_handler_t on_routing;
/*! executed when the state changes to execute */
switch_state_handler_t on_execute;
/*! executed when the state changes to hangup */
switch_state_handler_t on_hangup;
/*! executed when the state changes to exchange_media */
switch_state_handler_t on_exchange_media;
/*! executed when the state changes to soft_execute */
switch_state_handler_t on_soft_execute;
/*! executed when the state changes to consume_media */
switch_state_handler_t on_consume_media;
/*! executed when the state changes to hibernate */
switch_state_handler_t on_hibernate;
/*! executed when the state changes to reset */
switch_state_handler_t on_reset;
/*! executed when the state changes to park */
switch_state_handler_t on_park;
/*! executed when the state changes to reporting */
switch_state_handler_t on_reporting;
/*! executed when the state changes to destroy */
switch_state_handler_t on_destroy;
int flags;
void *padding[10];
};
상태 기 내부 표준 인터페이스
외곽 에서 이 루어 진 인 터 페 이 스 를 제외 하고 freeswitch - 1.8.7 \ src \ switchcore_state_machine. c 에서 핵심 적 인 표준 상태 처리 인 터 페 이 스 를 실현 했다. 이것 이 바로 상태 기 실현 코드 중의 switchcore_standard_on_XXX 인터페이스.
상태 기 관련 데이터 구조
Channel
채널 구조 에 하나 가 들 어 있어 요. switch_state_handler_table_t 의 목록, 채널 등급 의 상태 처리 반전 함수 표를 유지 합 니 다.struct switch_channel {
char *name;
switch_call_direction_t direction;
switch_call_direction_t logical_direction;
switch_queue_t *dtmf_queue;
switch_queue_t *dtmf_log_queue;
switch_mutex_t*dtmf_mutex;
switch_mutex_t *flag_mutex;
switch_mutex_t *state_mutex;
switch_mutex_t *thread_mutex;
switch_mutex_t *profile_mutex;
switch_core_session_t *session;
switch_channel_state_t state;
switch_channel_state_t running_state;
switch_channel_callstate_t callstate;
uint32_t flags[CF_FLAG_MAX];
uint32_t caps[CC_FLAG_MAX];
uint8_t state_flags[CF_FLAG_MAX];
uint32_t private_flags;
switch_caller_profile_t *caller_profile;
const switch_state_handler_table_t *state_handlers[SWITCH_MAX_STATE_HANDLERS];
.........
}
Channel 구현 중 채널 의 상태 기 함수 표를 조작 하 는 데 사용 할 다음 인 터 페 이 스 를 제공 합 니 다./*!
\brief add a state handler table to a given channel
\param channel channel on which to add the state handler table
\param state_handler table of state handler functions
\return the index number/priority of the table negative value indicates failure
*/
SWITCH_DECLARE(int) switch_channel_add_state_handler(switch_channel_t *channel, const switch_state_handler_table_t *state_handler);
/*!
\brief clear a state handler table from a given channel
\param channel channel from which to clear the state handler table
\param state_handler table of state handler functions
*/
SWITCH_DECLARE(void) switch_channel_clear_state_handler(switch_channel_t *channel, const switch_state_handler_table_t *state_handler);
/*!
\brief Retrieve an state handler tablefrom a given channel at given index level
\param channel channel from which to retrieve the state handler table
\param index the index of the state handler table (start from 0)
\return given channel's state handler table at given index or NULL if requested index does not exist.
*/
SWITCH_DECLARE(const switch_state_handler_table_t *) switch_channel_get_state_handler(switch_channel_t *channel, int index);
그 밖 에 채널 은 상 태 를 설정 하 는 조작 인터페이스 도 제공 했다./*!
\brief Set the current state of a channel
\param channel channel to set state of
\param state new state
\return current state of channel after application of new state
*/
#define switch_channel_set_state(channel, state) switch_channel_perform_set_state(channel, __FILE__, __SWITCH_FUNC__, __LINE__, state)
switch_runtime
switch_runtime 은 FreeSwitch core 가 유지 하 는 커 널 이 실 행 될 때 데 이 터 를 유지 합 니 다. 여기 서도 switch 를 유지 합 니 다.state_handler_table_t 의 목록, 이 층 에 대응 하 는 핵심 층 의 동적 추 가 된 상태 처리 리 셋.struct switch_runtime {
switch_time_t initiated;
switch_time_t reference;
int64_t offset;
switch_event_t *global_vars;
switch_hash_t *mime_types;
switch_hash_t *mime_type_exts;
switch_hash_t *ptimes;
switch_memory_pool_t *memory_pool;
const switch_state_handler_table_t *state_handlers[SWITCH_MAX_STATE_HANDLERS];
.........
}
같은 커 널 층 은 이 함수 표 에 대한 조작 인 터 페 이 스 를 제공 합 니 다:SWITCH_DECLARE(void) switch_core_remove_state_handler(const switch_state_handler_table_t *state_handler)
{
int index, tmp_index = 0;
const switch_state_handler_table_t *tmp[SWITCH_MAX_STATE_HANDLERS + 1] = { 0 };
switch_mutex_lock(runtime.global_mutex);
for (index = 0; index < runtime.state_handler_index; index++) {
const switch_state_handler_table_t *cur = runtime.state_handlers[index];
runtime.state_handlers[index] = NULL;
if (cur == state_handler) {
continue;
}
tmp[tmp_index++] = cur;
}
runtime.state_handler_index = 0;
for (index = 0; index < tmp_index; index++) {
runtime.state_handlers[runtime.state_handler_index++] = tmp[index];
}
switch_mutex_unlock(runtime.global_mutex);
}
SWITCH_DECLARE(int) switch_core_add_state_handler(const switch_state_handler_table_t *state_handler)
{
int index;
switch_mutex_lock(runtime.global_mutex);
index = runtime.state_handler_index;
if (index > (SWITCH_MAX_STATE_HANDLERS - 1)) {
index = -1;
} else {
runtime.state_handlers[index] = state_handler;
runtime.state_handler_index++;
}
switch_mutex_unlock(runtime.global_mutex);
return index;
}
SWITCH_DECLARE(const switch_state_handler_table_t *) switch_core_get_state_handler(int index)
{
if (index >= SWITCH_MAX_STATE_HANDLERS || index > runtime.state_handler_index) {
return NULL;
}
return runtime.state_handlers[index];
}
switch_endpoint_interface
endpoint 에서 인터페이스 에 switch 가 포함 되 어 있 습 니 다.state_handler_table_t 지침.endpoint 층 의 상태 처리 handler 는 구동 상태 기의 관건 적 인 인터페이스 로 FS 에서 driver 라 고 부른다.state_handler。 struct switch_endpoint_interface {
/*! the interface's name */
const char *interface_name;
/*! channel abstraction methods */
switch_io_routines_t *io_routines;
/*! state machine methods */
switch_state_handler_table_t *state_handler;
/*! private information */
void *private_info;
switch_thread_rwlock_t *rwlock;
int refs;
switch_mutex_t *reflock;
/* parent */
switch_loadable_module_interface_t *parent;
/* to facilitate linking */
struct switch_endpoint_interface *next;
switch_core_recover_callback_t recover_callback;
};
예 를 들 어 sofia 모듈 에서 전체 대상 sofia 를 예화 하 였 습 니 다.event_handlers: switch_state_handler_table_t sofia_event_handlers = {
/*.on_init */ sofia_on_init,
/*.on_routing */ sofia_on_routing,
/*.on_execute */ sofia_on_execute,
/*.on_hangup */ sofia_on_hangup,
/*.on_exchange_media */ sofia_on_exchange_media,
/*.on_soft_execute */ sofia_on_soft_execute,
/*.on_consume_media */ NULL,
/*.on_hibernate */ sofia_on_hibernate,
/*.on_reset */ sofia_on_reset,
/*.on_park */ NULL,
/*.on_reporting */ NULL,
/*.on_destroy */ sofia_on_destroy
};
모듈 초기 화 시 인터페이스 할당: sofia_endpoint_interface->io_routines = &sofia_io_routines;
sofia_endpoint_interface->state_handler = &sofia_event_handlers;
sofia_endpoint_interface->recover_callback = sofia_recover_callback;
상태 기 핵심
전체 상태 기의 핵심 코드 는 switch 에 봉 인 됩 니 다.core_session_run () 함수 에서.그것 은 바로 순환 체 이다.while ((state = switch_channel_get_state(session->channel)) != CS_DESTROY) {
......
}
상태 만 CS 가 아니라면DESTROY, 계속 실행 합 니 다.안에 긴 switch... case... 문구 가 있 습 니 다. 현재 상태 에 따라 코드 세 션 을 실행 합 니 다.
STATE_MACRO 매크로
이 매크로 는 서로 다른 상태 에서 상태 기기 의 실행 동작 에 대해 통 일 된 패 키 징 을 하여 코드 논 리 를 간소화 했다.이 매크로 는 매우 길 고 복잡 하지만 요약 하면 한 가지 일 을 했다. 각 등록 상태 handler 를 호출 하 는 것 이다. 우선 driverstate_handler, 즉 endpoint 그 층 의 handler 그리고 switchchannel_get_state_handler, 즉 channel 층 의 handler 그리고 switchcore_get_state_handler, 즉 core 1 층 마지막 으로 상태 기 자체 의 가장 핵심 적 인 상태 처리, 즉 switchcore_standard_on_XXX