快速发表文发表的含义,文发表的含义

更新时间:2024-01-27 作者:用户投稿原创标记本站原创 点赞:26264 浏览:119361

IP的设计与实现

前言

本文从VoIP相关知识入手,介绍了IP的软硬件结构设计及实现方案,并描述了IP基于SIP的呼叫流程,并通过设计杂项的方式详细描述了系统中的几个关键点.内容仅供大家参考,更详细内容可参见源代码,源代码是最好的老师.

VoIP相关知识介绍

什么是VoIP

VoIP是VoiceoverInterProtocol的缩写,指的是将模拟的声音讯号经过压缩与封包之后,以数据封包的形式在IP网络的环境进行语音讯号的传输.VoIP技术是目前互联网应用领域的一个热门话题,已经成为下一代网络发展的必然趋势.IP为广大电信用户和运营提供了一个成熟的,可实现广泛多媒体业务的终端载体,是下一代网络技术先进性的重要体现,它为基础语音的业务拓展提供了美好灿烂的应用前景.VoIP的基本原理通过语音的压缩算法对语音数据编码进行压缩处理,然后把这些语音数据按TCP/IP标准进行打包,经过IP网络把数据包送至接收地,再把这些语音数据包串起来,经过解压处理后,恢复成原来的语音信号,从而达到由互联网传送语音的目的.IP的核心与关键设备是IP网关,它把各地区区号映射为相应的地区网关IP地址.这些信息存放在一个数据库中,数据接续处理软件将完成呼叫处理,数字语音打包,路由管理等功能.在用户拨打长途时,网关根据区号数据库资料,确定相应网关的IP地址,并将此IP地址加入IP数据包中,同时选择最佳路由,以减少传输时延,IP数据包经Inter到达目的地的网关.在一些Inter尚未延伸到或暂时未设立网关的地区,可设置路由,由最近的网关通过长途网转接,实现通信业务.IP的技术基础是语音压缩技术.目前用于IP的标准是G.723.1静噪抑制技术又称语音激活技术,是指检测到通话过程中的安静时段即停止发送语音包的技术.通过静噪抑制技术,可大大节省带宽.回声抵消技术在PBX或局用交换机侧,有少量电能未被充分转换而沿原路返回,形成回声.语音抖动处理技术IP网络的一个特征就是网络延时与网络抖动,它们可以导致IP通话质量明显下降.网络延时是指IP包在网络上平均的传输时间,网络抖动是指IP包传输时间的长短变化.为了防止这种抖动,人们采用抖动缓冲技术,即在接收端设置一个缓冲池,语音包到达时首先进行缓存,然后系统以稳定平滑的速率将语音包从缓冲池中取出并处理,再播放给受话者.语音优先技术语音通信对实时性要求较高,在带宽不足的IP网络中,一般需要语音优先技术,即在IP网络路由器中必须设置语音包的优先级最高.这样,网络延时和网络抖动对语音的影响均将得到明显改善.IP包分割技术有时网络上有长数据包,一个包上千字节,这样的长包如不加以限制,在某些情况下也会影响语音质量.为了保证IP的通话质量,应将IP包的大小限制为不超过2556字节.VoIP前向纠错技术为了保证语音质量,有些先进的VoIP网关采用信道编码以及交织等技术.目前构建IP系统结构的信令协议主要有H.323SIP和MGCP(H.248).H.323协议是为多媒体会议系统而提出的国际电联ITU制定该协议采用传统电信网络繁琐的信令概念,非常庞大,无论从实现技术手段,还是使用和管理方法上都十分复杂.MGCP是互联网工程任务组(IETF)定义发布的基本思想就是网关分离.将H.323协议的IP网关分为媒体网关(MG),信令网关(SG)和媒体网关控制器(MGC,又称CA).其中MG仅负责媒体格式的变换,SG负责信令的转换,MGC才是真正的智能部分,根据收到的信令控制MG的连接建立和释放.这样的分离结构不仅可以大幅度提高中继MG的容量,而且可以提供7号信令的支持,并提高了系统的可用性和鲁棒性.SIP(SessionInitiationProtocol)会话初始协议是IETF制订的,用于多方多媒体通信.定义,SIP是一个基于文本的应用层控制协议,独立于底层传输协议TCP/UDP/SCTP,用于建立,修改和终止IP网上的双方或多方多媒体会话.SIP协议借鉴了HTTP,TP等协议,SIP应用崭新的业务模式不断呈现,相关研发和项目投资增长迅速,终端产品不断下降,SIP协议正得到越来越广泛的支持,SIP协议以其更加开放,更易扩展,与Inter紧密结合等特性,战胜H.323,MGCP等协议成为VoIP的主流协议.SIP产品将主导未来VoIP通信市场已成为业界人士的共识,基于SIP的IP通信正在成为一个巨大的产业.INCA-IP芯片,此芯片是为IPPhone应用设计的一款SOC解决方案,内部集成32-BITMIPSCPU,高性能dsp,SLIC,LCD控制器,MAC,PHY单元,CPU主频达到150MHz的主频,DSP达100MHz,在网络处理和语音方面可以达到很高的性能,是现有市场上比较先进的IPPhoneSoc解决方案.

软件平台采用vxWorks嵌入式操作系统,vxWorks是世界上领先的嵌入式操作系统,因其良好的可靠性和卓越的实时性被广泛地应用在通信,军事,航空和航天等高精尖技术及实时性要求极高的领域.信令协议采用SIP协议,主要是由于SIP协议正得到越来越广泛的支持,SIP协议以其更加开放,更易扩展,与Inter紧密结合等特性,战胜H.323,MGCP等协议成为VoIP的主流协议libosip2-2.2.2版本,另外根据国外的需求,后续将要支持IAX2协议.

硬件架构

方案主芯片采用Infelion的INCA-IP芯片,内部集成了32-BITMIPSCPU,高性能dsp,SLIC,LCD控制器,MAC,PHY单元,因此硬件则通过外接flash,SDRAM,手柄,耳机,LCD,键盘和以太变压器来实现.

硬件系统构架见下面框图:

软件架构

我们的软件是在vxWorks操作系统的基础上自主开发完成,主要包括:驱动模块(DSP驱动,LCD驱动,以太驱动,键盘驱动等),OSIP协议栈,ORTP协议栈,呼叫控制模块,用户接口模块(menu,CLI,WEB),扩展业务模块等.

软件系统构架见下面框图:

其中:

DSP驱动:

Dsp驱动模块是语音,信号处理的核心,完成对语音,数据,信号的采集和发送,同时它还完成对dsp控制,管理的功能.在系统启动时,完成dsp初始化工作.

SLIC驱动:

SLIC驱动主要实现对端口摘挂机状态的检测,同时通知上层对摘挂机事件进行相应的处理.

键盘驱动

主要负责对键盘事件的检测,并将所检测的事件送到上层.键盘驱动层不负责解析键盘事件的具体含义,而是由上层根据当前话机类型找到相应的键盘布局表,将其转化为对应的按键,并进行处理.

LCD驱动:

LCD驱动主要负责对LCD显示屏的操作,并为上层提供统一的LCD操作函数,由上层完成LCD显示.

Ether驱动:

以太驱动模块负责CPU上以太网控制器的初始化,PHY的初始化,状态检测,数据处理,访问控制.接受物理层的数据,并交给链路层进行处理,同时发送链路层数据到物理介质.

硬件接口层:

主要负责本地端点的资源管理控制,将物理接口的事件转化为系统能够识别的事件,为核心控制层屏蔽具体的物理设备细节,保证除驱动层之外其它层的可移植性,硬件无关性.

呼叫控制层

呼叫控制层维护端点状态转换关系,根据收到的SIP信令或硬件产生的事件来完成端点状态的转换及呼叫的处理.

SIP协议栈:

SIP协议栈是SIP协议的具体实现,包括两部分,分别由开源项目libosip2-2.2.2及libeXosip2-2.2.3移植而来.

话机工作流程

话机的工作流程要结合SIP协议,SIP协议规定了用来建立,改变和终止基于IP网络的用户间的呼叫.

其中主叫端点表示主叫用户,UA1状态机表明了主叫侧呼叫状态的处理,被叫端点表示被叫用户,UA2状态机表明了被叫侧呼叫状态的处理,

检测设主被叫用户均是我们的话机,则结合代码实现呼叫流程如下:

主叫键盘检测驱动检测到用户按键,通过回调函数kbdEventCallback()上交,在kbdEventCallback()根据当前话机类型找到相应的键盘布局表,将按键事件转化为对应的按键,并最终调用kbdkey_job_add()函数将事件加入到键盘事件处理任务队列中.任务tKbdTask的主处理函数kbdkey_task()被触发,将摘机事件通过函数endpoint_event_notify()通知到呼叫控制层,呼叫控制层判断出是摘机事件EV_OFFHOOK,则先打开DSP通道,然后在offhook_handler()处理函数中放拨号音,将端点状态由IDLE转换为等待拨号状态.

用户拨号,在拨号处理函数dialup_handler()中收集用户(注:检测到第一个拨号时要关闭拨号音),并根据拨号规则判断用户是否拨号完毕,一旦检测到拨号完毕,则调用call_originate()发起SIP呼叫.

call_originate()中会判断是IP地址拨号还是拨号,并根据dial-peer配置变换被叫,根据SIP配置获得SIP怎么写作器信息,最后调用sip_invite()通过SIP协议栈提供的函数发出invite消息,并将端点状态由等待拨号状态转换为连接中状态.

tExosip任务负责处理从SIP获取到的消息事件,被叫先发送100trying消息(1xx消息是临时消息,表明收到了SIP消息,正进行处理或已放到处理队列中,以告诉对端不必再重传此消息),然后通过call_new()函数通知被叫呼叫状态机进行处理,被叫振铃,发送180或183消息,并将端点状态由IDLE转换到等待摘机状态.


主叫呼叫控制层收到180或183消息,则调用call_ringing()进行处理,通知主叫回铃.

被叫摘机,则调用offhook_handler()进行处理,由于被叫处于等待摘机状态,因此进入到相应的处理流程中,调用sip_200ok()发送200OK消息,

主叫呼叫控制层收到200OK消息,则调用call_answered()处理,根据SIP消息进行ACK,并将端点状态由连接中转换为已连接状态.

被叫收到ACK消息,通过函数call_ack()处理,并将端点状态由等待摘机状态转换为已连接状态.

至此,双向的媒体连接已建立,主被叫双方可进行正常的语音通话.

被叫挂机,则呼叫控制层调用onhook_handler(),根据当前端点状态调用sip_bye()发送BYE消息,关闭DSP通道,并将端点状态恢复成IDLE状态.

主叫收到BYE消息,SIP协议栈会自动发送200OK消息,并通过呼叫控制层的call_closed()函数进行处理,关闭DSP,端点状态转换为等待挂机,并释放催挂音.

主叫挂机,则onhook_handler()根据当前端点状态进行处理,并将端点状态恢复成IDLE状态.

端点及状态转换图

端点是对物理端口的一种抽象,由于话机只有一个语音端口,因此系统中ENDPOINT_NUM为1,但可以很容易地扩展从而支持更多端口的设备(如网关).

typedefstructendpoint_t

{

//端点标识部分

charindex,/*index,from0toENDPOINT_NUM*/

chartype,/*endpointtype*/

charname[ZCOS_EPNAME_LEN],/*endpointname*/

//端点信息记录部分

charstate,/*endpointstate,justsimple*/

charcallee,/*calleeorcalledparty*/

charoffhook,/*FLASE:onhookorTRUE:offhook*/

charmute,

charholded,/*holdbypeer*/

characked,/*receivedACKforthisdialog*/

charfirstkey,/*iffirstkey,thenstopthedialtone*/

WDOG_IDinterKeyTmr,/*timerbetweentwokeys*///不用了

intinterkeyTmrVal,/*timervalue,seconds*/

chardialstr[ZCOS_PHONENUM_LEN],/*currentdialstring*/

/*

callinfo

*/

//呼叫信息记录,主要是保存与一次会话呼叫有关的信息,这样当进行hold,traner等时可以找到原来的信息

CALLINFOcallinfo,

/*

//定时器信息,端点使用了一个统一的定时器,用来支持等待摘机,等待按键,等待对端应答的定时,

#defineWDOGEVT_WAIT_NONE0/*无*/

#defineWDOGEVT_WAIT_OFFHOOK1/*等待摘机定时器*/

#defineWDOGEVT_WAIT_KEY2/*等待按键定时器*/

#defineWDOGEVT_WAIT_ANSWER3/*等待对端应答定时器*/

*/

WDOG_IDwdog,

intwdogVal,

intwdogEnv,

/*

reserveinformation

保存的一些端点信息

*/

chardisplayname[ZCOS_USERNAME_LEN],/*对端可显示的用户名,nousenow*/

charcalledstr[ZCOS_PHONENUM_LEN],/*主叫时表示被叫信息,被叫时是主叫*/

charcallerstr[ZCOS_PHONENUM_LEN],/*主叫时表示本端,被叫时是被叫*/

chardtmfstr[ZCOS_PHONENUM_LEN],/*连接后拨的分机*/

HOLDCBholdq[HOLDQ_SIZE],

intmic,/*mictype*/

RECENT_CALLS*pRecentCalls,

unsignedlongcallStartTick,

/*

forconfiguration

配置信息部分

*/

//SIP_USER*user,

SIP_PHONENUM*phonenum[SIP_REGISTRAR_MAX],

charhotline[ZCOS_PHONENUM_LEN],

charprefix[ZCOS_PHONENUM_LEN],

chartoype,

u_charcodec,

u_charg729payload,/*payloadlenforG729*/

u_charg72ayload,/*6.3kor5.3k*/

u_charsilencepress,/*silencepress*/

u_charvolume,/*DSPvolume,defaultis0,maxis7*/

charbaningoing,/*TRUE:nodisturb*/

charbanoutgoing,/*TRUE:banoutgoing*/

BOOLcallwaiting,

BOOLcalltraner,

BOOLconference,

CALLFORWARDcallforward,

intnoanswertime,/*noanswertime*/

}ENDPOINT,

话机工作流程一节中也描述了端点状态转换,下图则更详细地描述了端点状态下收到的事件及状态转换关系.

设计杂项

MENU工作机制

系统中的menu部分是我们自己设计的,数据结构为:

typedefstructmenuNode{

char*pPrompt,//此节点的提示信息

intnumChildren,//子节点的个数

structmenuNode*pChildren,//子节点的入口

FUNCPTRpHandlers,//此节点对应的处理函数

}menuNode,

通过静态方式组织系统menu节点成员,并通过一个递归方式实现了菜单功能:

voidmenu_main(void)

{

menuExitFlag等于FALSE,

if(mRootMenuNode.pHandlers){

if((*(mRootMenuNode.pHandlers))(mRootMenuNode.pPrompt)等于等于OK){

menu_sub(mRootMenuNode.pChildren,mRootMenuNode.numChildren),

}

}else{

menu_sub(mRootMenuNode.pChildren,mRootMenuNode.numChildren),

}

menuExitFlag等于FALSE,

kbdkey_mode_enter(KBDKEYMODE_NONE),

}

多语言支持

系统可很容易地支持更多语言,这要归功于rcc_language.c提供的多语言支持功能.RCC_Language_Id_add():增加要支持的语言及其前缀标识,如要增加对中文的支持,则可调用RCC_Language_Id_add(RCC_LANGUAGE_CN,RCC_LANGUAGE_ID_CN),这样rcc_language.c在根据相应的提示信息中查找中文就以前缀"|CN"查找,至到遇到分隔符"|".

RCC_Language_Id_show():查看系统支持的语言及前缀标识.

RCC_Language_Default_Set():设置默认的语言,即在查找相应的语言帮助信息未成功的情况下使用默认语言显示.

RCC_Language_Set():设置当前语言.

RCC_Language_Get():获取当前语言.

举一个例子:

在web的登录页面中有一个login(登录)按钮,如果当前语言是英文则显示login,是中文则显示登录,那么代码可这样实现:

#defineloginPrompt_EN"Login"

#defineloginPrompt_CN"登录"

#defineloginPromptEN(loginPrompt_EN)CN(loginPrompt_CN),其实loginPrompt的全部信息是:|EN:Login|CN:登录

在read_login()中通过RCC_Language_Help_String_Get(loginPrompt,pDest),函数调用,根据当前语言如果是英文,则会从|EN:Login|CN:根据英文的前缀标识EN找到Login,然后传给pDest,这样就获取到了相应的语言,从而可以很容易地支持多种语言.

对于menu,CLI支持多种语言,同上.

但需要说明的是如果真正要支持某一语言,则要有相应的字库支持,对于如何支持字库,则可以由牛ben同学进行补充.

快速转发实现

我们的系统语音质量好也与我们实现了快速转发有一定的关系(呵呵).根据软件系统架构图,我们可以看出,当从以太收到语音数据时,会先送到以太的链路层处理,这层有一个主要的工作是去除链路层头部,并将剩下的IP数据交给IP层处理,然后IP层做必要的处理,并剥去IP头部,再将语音数据送到UDP层处理,UDP处理完后再交给RTP层处理,RTP剥离出真正的语音数据,才将其送到DSP,并最终给用户播放出声音来.先不说层层检查会浪费CPU时间,单就各层的任务间切换就会消耗大量的CPU时间,从而导倒语音处理的滞后,因此我们设计了快速转发功能.

快速转发的主要思想是每建立一个会话,就同时建立一个会话地址表(又称快速转发表),其实就是本地(IP+port)与远端(IP+port)的一个对应关系,这样,当以太收到语音数据时,先定位出IP及UDP信息,查找是否在快速转发表项中,如果在,则说明数据是到本地的语音数据,则直接定位到RTP处,取出语音数据,交由DSP处理,而对于DSP打包完成后的语音数据,则根据此表项,直接打包成以太数据,通过调用相应的以太接口处理函数将数据发送出去.相对正常流程,快速转发直接在一个任务中处理了语音数据,并采用了简化方式,从而提高了处理效率.

主要数据结构:

typedefstruct{

unsignedlongsrcip,

unsignedlongdstip,

unsignedshortsport,

unsignedshortdport,

}sessionQTKey,

如何增加配置命令

我们的设备有四种配置方式:CLI命令行,WEB,MENU及auto-provisioning方式,auto-provisioning方式是为客户写作的自动方式.

CLI命令行:这种方式就是通过终端或tel进行的交互式配置方式,通过showrunning-config可以看到当前的配置内容,而showstartup-config则可以看到保存到flash中的配置,系统启动时读取flash中的startup文件,并设置话机.对话机的每条配置都必须增加相应的CLI命令,这是由于信息保存就是以命令行的方式保存到flash中.可以没有其它配置方式,但要支持配置可保存,目前就必须支持CLI命令方式.

WEB配置:则为用户提供了一种方便,直观的配置方式,

MENU配置:为用户提供了一种最直接的配置方式.

下面以支持中文语言配置来说明:

首先在usr_cli.c中增加相应的命令节点:{"chinese",kChineseHelp,NULL,kRCC_COMMAND_GLOBAL,NULL,0,0,NULL,0,NULL,1,mChineseHandlers},其中kChineseHelp对应此命令help信息,mChineseHandlers则是当用户输入了chinese命令后要执行的函数相关信息定义:

statichandlerDefnmChineseHandlers[]等于

{

{0,CLI_Chinese,0,0}

},

而CLI_Chinese是用户输入chinese命令后要执行的函数:

externRLSTATUS

CLI_Chinese(cli_env*pCliEnv,paramList*pParams,sbyte*pAuxBuf)

{

RLSTATUSstatus等于OK,

RCC_Language_Set(RCC_LANGUAGE_CN),

returnstatus,

}

那么RCC_Language_Set则是系统定义的语言设置函数,此处是设置中文语言,

前面一步仅是在系统中支持了chinese命令,从而可通过命令行方式修改当前语言为中文,但系统重启动后会恢复成默认值,所以还要修改支持script.

在usr_script.c中增加对languageScript()的调用,而languageScript()则是语言对应的脚本显示信息:

staticvoidlanguageScript(intfd)

{

#include"rc.h"

#include"rcc.h"

intlang,

lang等于RCC_Language_Get(),

if(lang等于等于RCC_LANGUAGE_EN)

fdprintf(fd,"english\n"),

elseif(lang等于等于RCC_LANGUAGE_CN)

fdprintf(fd,"chinese\n"),

}

这样,当用户配置为中文后,showrunning-config时会看到chinese配置,如果再执行write,保存配置到flash,则showstartup-config也会看到此条命令,从而重启动时系统从startup-config中读取信息,并设置当前语言为中文.

WEB中会为此增加一个关键字language,即<,selectname等于"language">,$%language#$<,/select>,,这句话表明关键字为language,当用户通过web设置了时会将值赋给language,而当用户更新网页时系统会将language($%xxx#$中的)修改为相应的值.

Usr_web.c中会增加一条表项:DB_CreateEntry("language",NULL,kDTstring,kReadWriteAccess,0,0,(p_funcValid)NULL,(p_funcRdPrim)read_language,(p_funcWrPrim)write_language,NULL,0),其中language对应上面的关键字,read_language则是当刷新网页时调用的函数,write_language则是当用户配置时调用的函数.

同命令行一样,write_language实现如下:

RLSTATUSwrite_language(environment*pEnv,void*pDest,void*pInputBuf,sbyte*pArgs)

{

RCC_Language_Set(atoi(pInputBuf)),

returnOK,

}

因为语言是一个选择项,所以当读取执行的函数为read_language,从而将原始网页中的$%language#$进行了替换.

RLSTATUSread_language(environment*pEnv,void*pDest,void*pInputBuf,sbyte*pArgs)

{

char*format等于"<,optionvalue等于\"%d\"%s>,%s<,/option>,",

RCC_LANGUAGElang等于0,

charbuf[128],

charret[32],

lang等于RCC_Language_Get(),

sprintf(pDest,format,0,(lang等于等于RCC_LANGUAGE_EN)"SELECTED":"",RCC_Language_Help_String_Get(ENPrompt,ret)),

sprintf(buf,format,1,(lang等于等于RCC_LANGUAGE_CN)"SELECTED":"",RCC_Language_Help_String_Get(CNPrompt,ret)),

strcat(pDest,buf),

returnOK,

}

Usr_menu.c中增加对应的菜单选项:{mSystemsettingslangugePrompt,0,NULL,menuSystemsettinglangugeHandler},其中mSystemsettingslangugePrompt是提示信息,而menuSystemsettinglangugeHandler则是对应菜单项要执行的函数.

intmenuSystemsettinglangugeHandler(char*pPrompt)

{

language_select(pPrompt),

returnOK,

}

voidlanguage_select(char*pPrompt)

{

intindex等于0,

intmode等于0,

intlanguage_amount等于3,

char*list[3]等于{STR_ENGLISH,STR_CHINESE,STR_POLISH},

mode等于RCC_Language_Get(),

if(mode等于等于RCC_LANGUAGE_CN)

index等于1,

elseif(mode等于等于RCC_LANGUAGE_PL)

index等于2,

else

index等于0,

index等于menu_kbd_select_get_handler(pPrompt,list,language_amount,index),

if(index等于等于1)

_menuWindows->,language等于RCC_LANGUAGE_CN,

elseif(index等于等于2)

_menuWindows->,language等于RCC_LANGUAGE_PL,

else

_menuWindows->,language等于RCC_LANGUAGE_EN,

RCC_Language_Set(_menuWindows->,language),

}

支持OEM

要支持OEM,就需要根据用户厂商信息修改,但我们的系统可很容易地支持OEM,具体对应于oemVender.c实现,对应的结构体为:

//OEMvenderinformationstructure

typedefstruct{

intindex,

intid,

charwebsite[20],

char[20],

charmodelno[20],

VENDER_INFOvender[OEM_VENDER_LANGUAGE_MAX],//language

}OEM_VENDER,

从而需要用户提供网站,,产品显示型号及中英文的公司全名,简称及地址,这样在oemVender.c中就可以参照实现增加对OEM厂商的支持.

添加了如上信息后可通过几种方式来操作:

通过命令venderx来即时体现OEM厂商信息并通过保存来永久支持,

根据不同的OEM厂商编译一个版本,但仅修改一处,即在usr_root.c的初始化函数中默认设置相应厂商的标识,

硬件支持,这样通过读取硬件信息判断OEM厂商信息,并在代码中自动设置,

产品型号

我们现在话机支持的型号在oemProduct.h中有定义,为:

/*

productID

*/

#defineZCOS_PRODUCT_ZP2020x00

#defineZCOS_PRODUCT_ZP2040x01//forcent

#defineZCOS_PRODUCT_ZP2060x02//forfenghua

#defineZCOS_PRODUCT_MAX0x04

因为各产品型号还是有些差别,如键盘布局,显示屏,功能等,因此系统提供了产品型号,并也会根据产品型号来进行一些判断.

对产品型号也可以象支持OEM一样的几种方式来操作.

软件版本号

软件版本号是根据世纪网通的需求定义的,基本格式为:v12.02.t1.05.31,其中05.31为编译日期,在编译后代码自动获取生成,不需要人工干预.

各功能模块对应的目录

根据软件系统构架图,结合需要根据用户需求写作的原则,说明几个主要的功能模块:

呼叫控制模块:zycoo\src\sipctrl

主要有两个文件:

sip_calls.c是接收SIP消息事件,并将其转换为到端点的操作,

zcos_callctrl.c则相反,接收端点的事件,并将其转换为SIP信令.

硬件适配层模块:zycoo\kbd

Kbd.c:接收键盘事件,并根据当前话机的键盘布局转化为相应的键盘事件,并交由上层处理,

Appdisplay.c:是对LCD驱动提供接口函数的抽象,为上层提供统一接口,

Zycoo\system\Callctrl.c:这是历史原因留下这个名字,其实其内容是对物理端点的一种抽象,也是为上层提供统一接口,屏蔽了具体硬件.

WEB页面模块:zycoo\

包含了web页面内容,当修改了页面后需要支持其中的web.bat批处理,生成web.c及web.h,并将其拷贝到cfg目录下编译即可.

系统功能模块:zycoo\system

这是我们自己实现的系统功能模块,包括端点抽象部分zcos_ep.c,MMI,本,等实现.

OSIP协议栈:zycoo\osip

OSIP协议栈的实现代码

WEB,CLI,MENU配置管理模块:zycoo\cfg

实现的为用户提供配置管理的接口实现部分,包括WEB,CLI,MENU,

IP的设计与实现第15页共15页