asterisk代码学习笔记_第1页
asterisk代码学习笔记_第2页
asterisk代码学习笔记_第3页
asterisk代码学习笔记_第4页
asterisk代码学习笔记_第5页
已阅读5页,还剩98页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Asterisk1.2配置文件参数读取相关的ast_config_engine_registerreload_queues->ast_config_load->ast_config_internal_load->load_func(queues.conf时就是config_text_file_load)-> process_text_line-> ast_category_browse-> ast_variable_browse-> queue_set_paramasterisk.c/main-> read_config_maps-> as

2、t_config_internal_load-> config_text_file_load -> ast_variable_browse -> append_mappingchan_sip.c/ do_monitordo_monitor -> ast_io_add-> sip_do_reload-> sip_poke_all_peers -> sip_send_all_registers -> ast_softhangup_nolock-> ast_queue_frame -> pthread_testcancel -> as

3、t_sched_wait -> ast_io_wait-> sipsock_read -> ast_sched_runq /在调用callback时调用的函数是用ast_sched_add 时设置的回调。收到一个invite时的处理函数:系统初始化时:load_module ->restart_monitor 起一个线程>do_monitor一个死循环,接收sip信令,This thread monitors all the SIP sessions and peers that needs notification of mwi (and thus do not

4、 have a separate thread) indefinitely->ast_io_add/设置回调函数sipsock_read, Add an I/O event to our SIP UDP socket, 有事件时则回调sipsock_read 读取socket数据->rtp.c/ast_rtp_sendcng->ast_sched_wait->ast_io_wait/将调用sipsock_read->ast_sched_runq-> sip_send_mwi_to_peer在reload-> sip_reload-> restar

5、t_monitor 也会调用restart_monitor*Chan_sip.c/ sip_tech收到一个invite时的处理函数:sipsock_read ->parse_request/解析了消息的头部和体部,解析方法名 -> find_sip_method/找到方法名对应的ID -> find_call->get_header->gettag->sip_alloc/找不到/不存在,就分配一个,这里的是主叫的sip_pvt->handle_request-> get_header/当收到响应消息时,会调用handle_response -&

6、gt;handle_response-> hangup_sip2cause-> _sip_semi_ack-> _sip_ack-> handle_response_peerpoke-> transmit_request-> reqprep -> send_request-> _sip_xmit-> sendto-> handle_response_invite -> handle_request_options -> handle_request_refer -> handle_request_cancel -&g

7、t; handle_request_bye -> handle_request_message -> handle_request_subscribe -> handle_request_register -> handle_request_info /当收到invite时,会调用handle_request_invite-> handle_request_invite-> transmit_response_with_unsupported->respprep-> init_resp-> copy_via_headers-> _ge

8、t_header-> add_header-> copy_all_header -> _get_header -> add_header-> copy_header->send_response-> parse_copy->append_history-> _sip_xmit-> sendto -> transmit_response-> _transmit_response-> respprep -> send_response ->check_via ->find_sdp->process

9、_sdp/收到第一个invite时鉴权->check_user->check_user_full->find_peer->realtime_peer->ast_load_realtime ->check_auth_first->sip_new/分配主叫的ast_channel-> build_route->ast_pbx_start创建一个线程运行pbx_threadpbx_thread-> _ast_pbx_run-> ast_exists_extension-> pbx_extension_helper -> a

10、st_spawn_extension-> pbx_extension_helper-> pbx_exec->执行到Dial时,调用回调函数dial_exec,这个是通过load_module->ast_register_application注册的 -> ast_pbx_startdial_exec->dial_exec_full->ast_request(sip_request_call)-> sip_alloc/这里是被叫的sip_pvt -> sip_new/分配被叫的ast_channel ->create_addr->

11、find_peer-> realtime_peer-> ast_load_realtime -> build_peer-> handle_common_options ->sched.c/ast_sched_del->acl.c/ast_get_ip_or_srv->acl.c/ast_append_ha->callerid.c/ast_parse_caller_presentation->cdr.c/ast_cdr_amaflags2int->channel.c/ast_get_group->frame.c/ast_parse

12、_allow_disallow->config.c/ast_variable_new ->sched.c/ast_sched_del ->sched.c/ast_sched_add ->create_addr_from_peer ->srv.c/ast_get_srv->autoservice.c/ast_autoservice_start-> ast_pthread_create/autoservice_run ->dns.c/ast_search_dns-> dns_parse_answer ->autoservice.c/ast

13、_autoservice_stop-> pthread_kill -> ast_sip_ouraddrfor -> build_via -> build_callid -> sip_new->channel.c/ast_channel_alloc->sched.c/sched_context_create ->sched.c/sched_context_destroy ->ast_codec_choose ->ast_best_codec ->dsp.c/ast_dsp_new->dsp.c/ast_dtmf_detect

14、_init ->dsp.c/ast_dsp_prog_reset->dsp.c/goertzel_init ->dsp.c/ast_dsp_set_features ->dsp.c/ast_dsp_digitmode ->pbx.c/pbx_builtin_setvar_helper ->channel.c/ast_setstate ->channel.c/ast_hangup -> sip_destroy/ restart_monitor当收到一个invite时,这个函数会给monitor_thread 线程发送一个信号 -> resta

15、rt_monitor->do_monitor/当收到一个invite时,这里会给不会起线程,线程在系统初始化时就已经创建了/ast_call 函数在发出invite后返回,这里是把收到的来自主叫的invite转发给被叫,被叫是指上面使用ast_request分配资源的那个刚刚创建的被叫 -> ast_call(sip_call)-> transmit_invite-> build_via -> add_header -> copy_request -> parse_request -> add_sdp -> send_request -&g

16、t; ast_sched_add / wait_for_answer 函数被叫摘机应答后这个函数才返回-> wait_for_answer-> ast_waitfor_n->ast_bridge_call-> ast_answer-> sip_answer ->transmit_response_with_sdp(p, "200 OK", &p->initreq, 1)-> add_sdp /这里把从被叫收到的200ok消息发给主叫 /这里会更改从被叫收到的200OK中的sdp信息 -> ast_channel_

17、bridge(ast_rtp_bridge)循环调用 sip_rtp_read. ->ast_write->sip_write->ast_rtp_writeast_waitfor_nast_waitfor_n->ast_waitfor_nandfds-> ast_do_masquerade -> poll举个例子,当sipsock_read中读到了200 ok信令,会写到相应的通道的文件描述符,然后在ast_waitfor_n 中调用的poll函数会返回,判断收到的类型为信令,并且是200 ok,会调用bridge 相关的函数,然后在bridge中让然调用a

18、st_waitfor_n,读写rtp信息。在channel.c/ast_channel_alloc中的/* Always watch the alertpipe */tmp->fdsAST_MAX_FDS-1 = tmp->alertpipe0;/* And timing pipe */tmp->fdsAST_MAX_FDS-2 = tmp->timingfd;使通道的8个描述符中的最后2个监视信令。一般主线程(sipsock_read)通过ast_queue_frame 函数告诉描述符收到的信令(描述符是指在poll中监视的描述符),然后poll返回,去处理收到的信令

19、。app_queue.c/wait_for_answer宏BUILD_WATCHERS是把主叫的channel(in)放在watchers的第一位,被叫的(坐席的)(o)放在后面。wait_for_answer->while(*to && !peer) ->ast_waitfor_n/这个函数返回可读写的channel(winner),不是in就是o, ->while(o) ->ast_read /收到被叫的信令时,会走到这里,180、200等,o指的是被叫。主叫此时在振铃或收听背景音,不会有信令,只有rtp ->if (winner = in)

20、->ast_read/读取主叫的rtp,一般是背景音乐,即MOH发送183和播放彩铃代码流程紫红色的是另外一种路径,这里要把ast_channel_alloc中的tmp->timingfd = open("/dev/zap/timer", O_RDWR);打开相关函数monmp3thread执行到Dial时,调用回调函数dial_exec->dial_exec->dial_exec_full->ast_request(sip_request_call)-> ast_call(sip_call)->ast_moh_start由于传给

21、Dial("SIP/8801-081b8c4c", "SIP/802802|25|tTrm()")的参数中有m,表示播放彩铃->local_ast_moh_start->ast_activate_generator->ast_prod/ Send empty audio to prime a channel driver-> ast_write->sip_write(chan->tech->write)->transmit_response_with_sdp发送183->ast_rtp_write发送

22、empty audio->moh_alloc->ast_settimeout这里设置timer来循环调用generator_forcegenerator_force调用generate(moh_generate)发送彩铃的rtp->设置channnel的chan->generator回调函数-> wait_for_answer->循环调用ast_waitfor_n-> ast_waitfor_nandfds-> poll-> ast_read (winner = in)-> generate(moh_generate)->moh

23、_generate->read ->ast_write>sip_write(chan->tech->write) ->transmit_response_with_sdp发送183 ->ast_rtp_write发送彩铃的rtpast_read->sip_read->sip_rtp_read->ast_rtp_read->ast_rtcp_readframe.c/ast_smootherast_prod-> ast_write(chan,frame)->sip_write(chan->tech->writ

24、e)->ast_rtp_write->ast_rtp_lookup_code ->ast_smoother_new ->ast_smoother_feed->_ast_smoother_feed ->ast_smoother_read ->ast_rtp_raw_writeapp_queue.cqueue_exec-> pbx_findapp -> pbx_exec ->pbx_builtin_getvar_helper -> join_queue -> ast_indicate -> ast_moh_start -

25、> wait_our_turn -> try_calling-> ring_one-> ring_entry->ast_request->sip_request_call->sip_alloc ->sip_new->ast_channel_alloc ->restart_monitor->pthread_kill(monitor_thread, SIGURG)-> ast_call(sip_call)-> transmit_invite->wait_for_answer/坐席摘机应答后wait_for_answ

26、er返回-> ast_bridge_callmanager.c/init_managerinit_manager-> ->创建线程运行accept_thread/等待客户端登录,为每个登录的客户端创建一个线程,分配一个mansession结构体。accept_thread->创建线程运行session_do/处理每隔线程的事务。session_do->process_message->authenticateformats/codecs目录A和B注册到asterisk,A发出的RTP(比如是alaw)到达asterisk,asterisk会调用formats

27、目录下的相应的文件进行解包(解析rtp的数据部分的内容)、重新打包,然后发到B端。如果A、B的编码方式不一样,还会调用codecs目录下的相应的文件。Formats目录下的模块都会调用file.c/ast_format_register函数。file.c app_queue.c/play_file 函数 调用方法 play_file(qe->chan,"gonghao");play_file->ast_stopstream->ast_closestream ->ast_streamfile->ast_openstream->ast_ope

28、nstream_full->ast_set_write_format->ast_openvstream ->ast_applystream-> ast_playstream-> ast_readaudio_callback-> (s->fmt->)read-> ast_write->ast_settimeout->ast_sched_add/在ast_readaudio_callback中会从文件中读取一帧写到通道中,然后起一个timer,在callback后会调用ast_readaudio_callback再发送一帧。 -&g

29、t; ast_readvideo_callback ->ast_waitstream->ast_sched_wait->ast_waitfor->ast_waitfor_n->ast_read->ast_sched_runq->(current->callback) ast_readaudio_callback ->ast_stopstream把对方hold住对方听背景音乐时,敲命令moh reloadippbx刚刚起来时会走到这里 load_moh_classes-> moh_register->创建线程monmp3threa

30、dmonmp3thread-> spawn_mp3->fork->write(moh->pipe1, sbuf, res2)/这里是循环调用把对方hold住对方听背景音乐收到INVITE消息,process_sdp->ast_moh_start->ast_moh_start_ptr(local_ast_moh_start)-> ast_activate_generator->moh_release->ast_prod ->moh_alloc->mohalloc->pipe->fcntl ->chan->g

31、enerator = gen/把mohgen付给chan->generator-> ast_rtp_stopast_read->generate(chan->generator->generate,实际是moh_generate)->read (moh->pipe0, buf + AST_FRIENDLY_OFFSET/2, len) ->ast_write (chan, &f)敲命令moh reloadmoh_cli-> moh_on_off(0)-> ast_deactivate_generator-> chan-&

32、gt;generator->release(moh_release) -> ast_moh_destroy->moh->pid = 0;->ast_moh_free_class -> load_moh_classes(1)-> moh_register->创建线程monmp3thread ->sleep(1)/创建线程需要时间的,要等线程创建好了再让rtp去读(就是调用ast_read->moh_generate),否则pid为0 -> moh_on_off(1)-> local_ast_moh_start-> as

33、t_activate_generator->moh_release->ast_prod->moh_alloc->mohalloc->pipe ->fcntl->chan->generator = gen/把mohgen付给chan->generator这时应该是重新开始放背景音乐music on hold在函数local_ast_moh_start 中会设置AST_FLAG_MOH标志,在ast_activate_generator中会调用moh_alloc分配mohdata结构体local_ast_moh_start->ast_ac

34、tivate_generator->ast_prod/发送一个空的帧->moh_alloc->mohalloc /创建管道,分配mohdata结构体,每个被hold住的channnel都会有这个结构体,在下面的write中会使用->chan->generator = gen /设置回调local_ast_moh_stop做和local_ast_moh_start相反的事情。load_moh_classes-> moh_register->创建线程运行monmp3thread,死循环-> class->srcfd =spawn_mp3/启动m

35、pg123进程 ->read(class->srcfd, sbuf, len)/class->srcfd是pipe 0,对应的pipe 1是有mpg123写入的。 ->write(moh->pipe1, sbuf, res2)/把从class->srcfd读出的内容写到moh->pepe1中,会循环写到每个客户的mohdata中。在moh_generate函数中会->read(moh->pipe0, buf + AST_FRIENDLY_OFFSET/2, len)/读取写入moh->pepe1中的内容 ->ast_write(

36、chan, &f)/发送到远端在 ast_read()中会调用moh_generategenerate = chan->generator->generate;res = generate(chan, tmp, f->datalen, f->samples);/will invoke moh_generate在queue_exec中,运行queue应用的线程应该是主叫的线程,这个线程在调用ast_moh_start后,就会返回,但是,运行ast_read函数的也是这个线程,是主叫线程运行到wait_for_answer函数,在这个函数中调用ast_read函数的

37、(wait_for_answer->ast_read)。chan_sip.c/sip_newsip_new->ast_channel_alloc-> sched_context_create -> tmp->tech = &sip_tech -> ast_codec_choose -> ast_best_codec -> ast_dsp_new -> ast_rtp_fdAsterisk1.4A打B简单通话的代码流程:系统初始化时:load_module ->restart_monitor 起一个线程>do_monito

38、r一个死循环,接收sip信令,This thread monitors all the SIP sessions and peers that needs notification of mwi (and thus do not have a separate thread) indefinitely->ast_io_add/设置回调函数sipsock_read, Add an I/O event to our SIP UDP socket, 有事件时则回调sipsock_read 读取socket数据->rtp.c/ast_rtp_sendcng->ast_sched_wa

39、it->ast_io_wait/将调用sipsock_read->ast_sched_runq-> sip_send_mwi_to_peer在reload-> sip_reload-> restart_monitor 也会调用restart_monitor*Chan_sip.c/ sip_tech收到一个invite时的处理函数:sipsock_read ->parse_request/解析了消息的头部和体部,解析方法名 -> find_sip_method/找到方法名对应的ID -> find_call->get_header->g

40、ettag->sip_alloc/找不到/不存在,就分配一个,这里的是主叫的sip_pvt->handle_request-> get_header/当收到响应消息时,会调用handle_response ->handle_response-> hangup_sip2cause-> _sip_semi_ack-> AST_SCHED_DEL(sched, cur->retransid) / Stopping retransmission-> _sip_ack-> handle_response_peerpoke-> transm

41、it_request-> reqprep -> send_request-> _sip_xmit-> sendto /这里是发送AST_CONTROL_RINGING ,_ast_queue_frame发送一个frame到chan->readq-> if 180 -> handle_response_invite->if 180 -> ast_queue_control-> ast_queue_frame-> _ast_queue_frame->AST_LIST_APPEND_LIST ->if 200 ->

42、handle_response_invite-> if 200 -> find_sdp -> process_sdp -> update_call_counter -> build_route -> set_address_from_contact -> ast_queue_control /发送AST_CONTROL_ANSWER -> transmit_request /向被叫回ack -> handle_request_options -> handle_request_refer -> handle_request_ca

43、ncel -> handle_request_bye -> handle_request_message -> handle_request_subscribe -> handle_request_register -> handle_request_info -> SIP_ACK-> _sip_ack / stops retransmission /当收到invite时,会调用handle_request_invite-> handle_request_invite-> transmit_response_with_unsupported

44、->respprep-> init_resp-> copy_via_headers-> _get_header-> add_header-> copy_all_header -> _get_header -> add_header-> copy_header->send_response-> parse_copy->append_history-> _sip_xmit-> sendto -> transmit_response-> _transmit_response-> respprep -

45、> send_response -> ast_queue_control -> _sip_ack -> transmit_response_reliable ->check_via/收到第一个invite时鉴权->check_user->check_user_full-> find_user-> ast_rtp_codec_setpref-> ast_smoother_reconfigure-> smoother_frame_feed -> check_auth-> transmit_response_with_au

46、th /发出407 -> sip_scheddestroy->find_peer->realtime_peer->ast_load_realtime -> ast_rtp_codec_setpref -> check_auth ->find_sdp->process_sdp->ast_queue_frame->update_call_counter->get_destination->get_rdnis->extract_uri->build_contact->sip_new/分配主叫的ast_chann

47、el-> build_routeif AST_STATE_DOWN-> transmit_provisional_response(p, "100 Trying", req, 0); /向主叫回100try->ast_pbx_start为主叫创建一个线程运行pbx_threadpbx_thread-> _ast_pbx_run-> ast_exists_extension-> pbx_extension_helper -> ast_spawn_extension-> pbx_extension_helper-> pbx_

48、exec->执行到Dial时,调用回调函数dial_execdial_exec->dial_exec_full->ast_request(sip_request_call)-> sip_alloc/这里是被叫的sip_pvt -> sip_new/分配被叫的ast_channel ->create_addr->find_peer-> realtime_peer-> ast_load_realtime -> build_peer-> handle_common_options ->sched.c/ast_sched_del-

49、>acl.c/ast_get_ip_or_srv->acl.c/ast_append_ha->callerid.c/ast_parse_caller_presentation->cdr.c/ast_cdr_amaflags2int->channel.c/ast_get_group->frame.c/ast_parse_allow_disallow->config.c/ast_variable_new ->sched.c/ast_sched_del ->sched.c/ast_sched_add ->create_addr_from_p

50、eer ->srv.c/ast_get_srv->autoservice.c/ast_autoservice_start-> ast_pthread_create/autoservice_run ->dns.c/ast_search_dns-> dns_parse_answer ->autoservice.c/ast_autoservice_stop-> pthread_kill -> ast_sip_ouraddrfor -> build_via -> build_callid -> sip_new->channel.c

51、/ast_channel_alloc->sched.c/sched_context_create ->sched.c/sched_context_destroy ->ast_codec_choose ->ast_best_codec ->dsp.c/ast_dsp_new->dsp.c/ast_dtmf_detect_init ->dsp.c/ast_dsp_prog_reset->dsp.c/goertzel_init ->dsp.c/ast_dsp_set_features ->dsp.c/ast_dsp_digitmode ->pbx.c/pbx_builtin_setvar_helper ->channel.c/ast_setstate ->channel.c/ast_hangup -> sip_destroy/ restart_monitor当收到一个invite时,这个函数会给monitor_thread 线程发送一个信号 -> restart_monitor->do_monitor/当收到一个invite时,这里会给不会起线程,线程在系统初始化时就已经创建了/ast_call 函数在发出invite后返回,这里是把

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论