freeswitch系列5 channel

  1. 初始化

channel在switch_channel.c实现,在switch_channel.h定义相关数据结构。在第2章节初始化的时候,在核心初始化里会调用channel_global初始化。

 

  1. static struct {  
  2.     switch_memory_pool_t *pool;  
  3.     switch_hash_t *device_hash;  
  4.     switch_mutex_t *device_mutex;  
  5.     switch_device_state_binding_t *device_bindings;  
  6. } globals;  
  7.   
  8. SWITCH_DECLARE(void) switch_channel_global_init(switch_memory_pool_t *pool)  
  9. {  
  10.     memset(&globals, 0, sizeof(globals));  
  11.     globals.pool = pool;  
  12.   
  13.     switch_mutex_init(&globals.device_mutex, SWITCH_MUTEX_NESTED, pool);  
  14.     switch_core_hash_init(&globals.device_hash);  
  15. }

 

 

channel也有一个全局结构globals,其中比较重要的设备容器device_hash和设备状态处理device_bindings,还不明白,初步猜测channel跟设备有关。

 

  1. 创建channel

channel和session是一一对应的,上一章讲过,创建session的时候,会同时创建channel并初始化。

 

  1. SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_endpoint_interface_t  
  2.                                                                          *endpoint_interface,  
  3.                                                                          switch_call_direction_t direction,  
  4.                                                                          switch_originate_flag_t originate_flags,  
  5.                                                                          switch_memory_pool_t **pool, const char *use_uuid)  
  6. {  
  7.     switch_memory_pool_t *usepool;  
  8.     switch_core_session_t *session;  
  9.     switch_uuid_t uuid;  
  10.   
  11. ...  
  12.     //申请session的channel内存  
  13.     if (switch_channel_alloc(&session->channel, direction, session->pool) != SWITCH_STATUS_SUCCESS) {  
  14.         abort();  
  15.     }  
  16.   
  17.     //初始化channel  
  18.     switch_channel_init(session->channel, session, CS_NEW, 0);  
  19.   
  20.     if (direction == SWITCH_CALL_DIRECTION_OUTBOUND) {  
  21.         switch_channel_set_flag(session->channel, CF_OUTBOUND);  
  22.     }  
  23.   
  24.     //设置一些channel的变量  
  25.     switch_channel_set_variable(session->channel, "uuid", session->uuid_str);  
  26.     switch_channel_set_variable(session->channel, "call_uuid", session->uuid_str);  
  27.   
  28.     switch_channel_set_variable_printf(session->channel, "session_id""%u", session->id);  
  29.   
  30.     return session;  
  31. }

 

创建session的时候,同时对channel干了三件事:申请channel内存、初始化channel、设置一些channel变量。下面分析下channel数据结构和这三个步骤。

    1. switch_channel

 

  1. struct switch_channel {  
  2.     char *name;  
  3.     switch_call_direction_t direction;  
  4.     switch_call_direction_t logical_direction;  
  5.     switch_queue_t *dtmf_queue;  
  6.     switch_queue_t *dtmf_log_queue;  
  7.     switch_mutex_t*dtmf_mutex;  
  8.     switch_mutex_t *flag_mutex;  
  9.     switch_mutex_t *state_mutex;  
  10.     switch_mutex_t *thread_mutex;  
  11.     switch_mutex_t *profile_mutex;  
  12.     switch_core_session_t *session;  
  13.     switch_channel_state_t state;//状态  
  14.     switch_channel_state_t running_state;//运行状态  
  15.     switch_channel_callstate_t callstate;//通话状态  
  16.     uint32_t flags[CF_FLAG_MAX];  
  17.     uint32_t caps[CC_FLAG_MAX];  
  18.     uint8_t state_flags[CF_FLAG_MAX];  
  19.     uint32_t private_flags;  
  20.     switch_caller_profile_t *caller_profile;//  
  21.     const switch_state_handler_table_t *state_handlers[SWITCH_MAX_STATE_HANDLERS];//状态回调  
  22.     int state_handler_index;  
  23.     switch_event_t *variables;  
  24.     switch_event_t *scope_variables;  
  25.     switch_hash_t *private_hash;  
  26.     switch_hash_t *app_flag_hash;  
  27.     switch_call_cause_t hangup_cause;  
  28.     int vi;  
  29.     int event_count;  
  30.     int profile_index;  
  31.     opaque_channel_flag_t opaque_flags;  
  32.     switch_originator_type_t last_profile_type;  
  33.     switch_caller_extension_t *queued_extension;  
  34.     switch_event_t *app_list;  
  35.     switch_event_t *api_list;  
  36.     switch_event_t *var_list;  
  37.     switch_hold_record_t *hold_record;  
  38.     switch_device_node_t *device_node;  
  39.     char *device_id;  
  40. }; 

 

channel结构体全部列举出来了,这里只看一些比较重要的成员:

1、通道状态state、running_state、状态回调state_handlers。这个在上一章节session的时候就有讲到状态机。

 

  1. typedef enum {  
  2.     CS_NEW,  
  3.     CS_INIT,  
  4.     CS_ROUTING,  
  5.     CS_SOFT_EXECUTE,  
  6.     CS_EXECUTE,  
  7.     CS_EXCHANGE_MEDIA,  
  8.     CS_PARK,  
  9.     CS_CONSUME_MEDIA,  
  10.     CS_HIBERNATE,  
  11.     CS_RESET,  
  12.     CS_HANGUP,  
  13.     CS_REPORTING,  
  14.     CS_DESTROY,  
  15.     CS_NONE  
  16. } switch_channel_state_t;  

 

刚创建channel的时候是CS_NEW,然后进行初始化进入CS_INIT,有来电进入路由后,就是CS_ROUTING,路由解析完,进入执行action时变成CS_EXECUTE。什么状态执行什么操作,看状态机的实现函数,这里就不展开。

2、跟通话call相关的有callstate、caller_profile。call的相关代码还未跟踪,这里先列出call状态。

  1. typedef enum {  
  2.     CCS_DOWN,  
  3.     CCS_DIALING,  
  4.     CCS_RINGING,  
  5.     CCS_EARLY,  
  6.     CCS_ACTIVE,  
  7.     CCS_HELD,  
  8.     CCS_RING_WAIT,  
  9.     CCS_HANGUP,  
  10.     CCS_UNHELD  
  11. } switch_channel_callstate_t;  

 

从这些状态来看,也是比较清晰的,比如CSS_RINGING应该是本路通话在响铃时候设置。

3、跟设备device相关的,预留后面补充。

    1. 申请channel内存

申请channel结构体内存使用switch_channel_alloc,该函数除了申请内存外,还初始化若干个默认值,除了创建通道变量channel->variables外,其它没什么重要的。

 

  1. SWITCH_DECLARE(switch_status_t) switch_channel_alloc(switch_channel_t **channel, switch_call_direction_t direction, switch_memory_pool_t *pool)  
  2. {  
  3.     switch_assert(pool != NULL);  
  4.   
  5.     if (((*channel) = switch_core_alloc(pool, sizeof(switch_channel_t))) == 0) {  
  6.         return SWITCH_STATUS_MEMERR;  
  7.     }  
  8.   
  9.     switch_event_create_plain(&(*channel)->variables, SWITCH_EVENT_CHANNEL_DATA);  
  10.   
  11.     switch_core_hash_init(&(*channel)->private_hash);  
  12.     switch_queue_create(&(*channel)->dtmf_queue, SWITCH_DTMF_LOG_LEN, pool);  
  13.     switch_queue_create(&(*channel)->dtmf_log_queue, SWITCH_DTMF_LOG_LEN, pool);  
  14.   
  15.     switch_mutex_init(&(*channel)->dtmf_mutex, SWITCH_MUTEX_NESTED, pool);  
  16.     switch_mutex_init(&(*channel)->flag_mutex, SWITCH_MUTEX_NESTED, pool);  
  17.     switch_mutex_init(&(*channel)->state_mutex, SWITCH_MUTEX_NESTED, pool);  
  18.     switch_mutex_init(&(*channel)->thread_mutex, SWITCH_MUTEX_NESTED, pool);  
  19.     switch_mutex_init(&(*channel)->profile_mutex, SWITCH_MUTEX_NESTED, pool);  
  20.     (*channel)->hangup_cause = SWITCH_CAUSE_NONE;  
  21.     (*channel)->name = "";  
  22.     (*channel)->direction = (*channel)->logical_direction = direction;  
  23.     switch_channel_set_variable(*channel, "direction", switch_channel_direction(*channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound");  
  24.   
  25.     return SWITCH_STATUS_SUCCESS;  
  26. }  

 

 

    1. channel初始化

channel初始化调用switch_channel_init,这里很简单,初始化状态,保存channel对应的session,running_state设为CS_NONE,state和running_state什么区别,还不是很清晰。

 

  1. SWITCH_DECLARE(switch_status_t) switch_channel_init(switch_channel_t *channel, switch_core_session_t *session, switch_channel_state_t state,  
  2.                                                     switch_channel_flag_t flag)  
  3. {  
  4.     switch_assert(channel != NULL);  
  5.     channel->state = state;  
  6.     switch_channel_set_flag(channel, flag);  
  7.     channel->session = session;  
  8.     channel->running_state = CS_NONE;  
  9.     return SWITCH_STATUS_SUCCESS;  

 

channel相关的还不是看得很细,本文档先编写最基本的,后面了解更深入了再补充。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值