版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1 AT命令模块框架设计 11.1 ATCOP功能划分 11.2 AT命令处理流程详解 31.3 AT命令表结构 71.4 命令表项解释 111.5 增加一条AT命令 151.5.1 基本流程 151.5.2 增加一条同步AT命令范例 181.5.3 增加一条异步AT命令范例 201.5.4 主动上报的AT事件如何实现实现方法 272 高通AT命令模块主要文件功能 333 AT命令的流程 343.1 同步AT命令的流程 343.2 异步AT命令的流程 343.3 主动上报AT命令的流程 34QCT6085AT命令模块设计与实现AT命令模块框架设计本节对AT命令模块的总体设计与实现进行了详细描述,并对AT命令表结构内容做了说明,最后解释了如何添加一条AT命令。ATCOP功能划分高通的AT模块,也就是AT命令处理器(ATCOP)完成了多种AT命令的解析、处理以及产生和发送命令响应消息,同时也处理在AT命令执行过程中的各种AT相关的事件。在高通的软件平台中,ATCOP作为数据服务模块(DSdataservices)的一个子任务来实现。在ds_task中完成对dsat_task的初始化和调用功能,所有的AT命令通过TE和TA之间的串行接口发送。收到的AT命令缓存在DS的消息队列dsi_cmd_q中,并由ds的消息分发机制统一分发给各个子任务。ATCOP的处理流程包括SIO数据预处理模块、AT命令解析器、AT命令处理器、AT命令响应产生器、AT命令表及命令处理功能模块。1.通过串口设备(SIO)接收的AT命令数据,首先由SIO数据预处理,产生一个null-terminated命令行并由DS分发给AT命令解析器。2.产生的null-terminated命令行由AT命令解析器解析,解析器为每个要解析的命令产生一个token结构,并送到处理队列由AT命令处理器处理。在AT命令处理器被调用前,解析器将每个命令的token结构放入队列中。3.AT命令处理器完成对每个token结构进行表查找,同时将该token结构从队列中移除。如果查找到,对应的处理函数被调用处理该命令;AT命令在命令表中定义,每个命令表入口包含对应命令执行函数的指针。4.AT命令响应产生器将命令响应数据格式化,产生结果编码,并将响应数据发送给DTE。5.ATCOP每次处理一条AT命令行命令,如果任何命令行的命令产生一个错误,在错误前就会产生命令处理的响应,同时产生一个错误代码,不再对该命令进行后续处理。AT命令处理流程详解图1AT命令处理流程图详细描述了AT命令模块在处理各类AT命令的具体具体流程。DS_Task的建立,SIO唤醒rx收到数据,将sio唤醒2.初始化解析函数dsat_process_sio_command去掉命令行中的"AT"前缀,然后把以NULL结尾的命令行传给函数dsat_process_cmd_line来进行后续的分析和处理。dsatpar_parse_cmd_line函数完成对命令行的解析,检查每个AT命令的首字符然后根据AT命令的类型调用相应的解析函数。每个AT命令名(包括首符号,如,$QCDMG)以及相关的命令参数都被从命令行中解析出来,然后放到一个tokendatastructure中。命令行中的每个命令都产生一个tokenstructure,放到token排队上等待后续处理,此时一个命令行解析完成。一般添加或修改AT命令时不改动这部分代码。3.命令解析根据命令的不同首字符,不同的解析函数解析AT命令后,把解析的信息填充到上一步产生的tokendatastructure中,然后返回结果。如果结果是OK(意味着参数、参数个数以及特殊处理码specialprocessingcode等等都已经存好),此时tokendatastructure已放在队列中等待AT命令处理器(ATcommandprocessor)后续处理。命令行中的每个命令都在队列中放一个tokenstructure。例如,extendedorproprietaryAT命令调用的分析函数是parse_extended_cmd。4.命令执行每个命令产生的tokenstructure被函数dsatcmdp_queue_token放入队列中。命令解析完成后,调用函数process_at_cmd_line处理队列中的每个tokenstructure。从队列中取出并删除一个命令tokenstructure后,在命令表中搜索该命令。顶层命令表(toplevelcommandtable)在文件dsatetsitgt.c中。顶层命令表又指向文件dsatctab.c和dsatetsictab.c中的多个命令表,这些表定义了所支持的AT命令集。在表中查找到该命令后,调用表中对应的处理函数执行该命令。命令执行后如果有返回数据时,返回的响应数据在函数dsat_fmt_response中格式化。每个token结构都进行这样的处理。最后调用函数dsatrsp_send_response把命令响应送到DTE。对于异步AT命令处理流程与正常AT命令略有不同,在命令预处理、命令解析过程都是一样的,在命令处理过程中(process_at_cmd_line),如果命令处理函数返回DSAT_OK,说明命令处理完成调用dsat_fmt_response函数格式化响应数据并发送,正常的命令处理流程;如果命令处理函数返回DSAT_ASYNC_CMD说明当前命令是异步命令,此时函数process_at_cmd_line设置变量dsatcmdp_processing_async_cmd=TRUE,表示当前正在处理异步命令,然后返回,不再进行后续处理,直到该命令处理完成,函数返回DSAT_OK(未必一定是DSAT_OK,当返回不是DSAT_ASYNC_CMD和DSAT_ASYNC_EVENT时,说明异步命令/事件处理完成)。当DS收到异步事件经任务分发器,再次调用dsat_process_async_cmd函数,在该函数中通过查找异步事件表async_event_table,调用相应的事件处理函数继续处理,如果事件处理函数返回值不是DSAT_ASYNC_CMD或DSAT_ASYNC_EVENT,说明异步事件处理完成,调用process_at_cmd_line继续处理命令行的命令。AT命令表结构AT命令的处理是由命令表驱动的,ATCOP实现的命令表是一个分级的表结构,主要分为:主表(mastertable)、子表(subtable)、命令表(commandtable),如图4.2所示。其中主表是一个二维的数组,数组的行表示AT命令的分类,分为:基本AT命令(basic_table)、寄存器AT命令(sreg_table)、扩展AT命令(extended_table)、厂商AT命令(vendor_table)四大类;数组的列表示是ETSI模式还是其它模式的AT命令。图2AT命令表结构图主表定义在dsati.h文件中:typedefstructdsati_cmd_struct{bytename[20];uint32attrib;bytespecial;bytecompound;constvoid*val_ptr;constvoid*def_lim_ptr;dsat_result_enum_type(*proc_func)(dsat_mode_enum_type,conststructdsati_cmd_struct*,consttokens_struct_type*,dsm_item_type*);boolean(*abort_func)(conststructdsati_cmd_struct*);}dsati_cmd_type;typedefstruct{constdsati_cmd_type*table_ptr;constunsignedint*table_size;}dsati_at_cmd_table_entry_type;typedefdsati_at_cmd_table_entry_type*dsati_at_cmd_table_type[NUM_AT_CMD_CATEGORIES][NUM_OPER_CMD_MODES];分类表定义在文件dsatetsitgt.c中:constdsati_at_cmd_table_typeat_cmd_table={{basic_table_entries,NULL},{sreg_table_entries,NULL},{extended_table_entries,NULL},{vendor_table_entries,NULL}};1.基本命令表基本命令的格式为:<command>[<number>]其中<command>或者是单个字母(A-Z),或者是“&”字符接单个字母。<number>是一个十进制数,可以是一位,也可以是多位。<number>最前面的0会被忽略。默认<number>为0。如果一个不带<number>的基本命令带了<number>,则返回TOOMANYPARAMETERS。2.寄存器命令表所有以字母“S”开头的命令统称为S寄存器命令,格式如下:S<parameternumber>?S<parameternumber>=<value>S寄存器命令名由字母“S”接上一个十进制数构成,这个十进制数称为寄存器序号(parameternumber)。如果寄存器序号不被识别,说明不存在该命令,返回COMMANDNOTSUPPORT。每个S寄存器保存一个字符。命令名后面如果接“?”表示是READ命令,返回此S寄存器当前保存的字符的ASCII码值,以3位十进制数表示,位数不足的前面补0;如果接“=”表示是SET命令,将<value>值对应的字符替换此S寄存器保存的字符。3.扩展命令表和厂商提供的命令表扩展命令均由“+”开头,厂商定义的命令也是由一个特殊符号开头,例如“$”,“%”等。本文中所实现的命令均为扩展命令。所有的扩展命令和厂商定义命令又可以分为两类:Actioncommand和Parametercommand。1)actioncommandactioncommand指完成某个具体的动作,而不仅仅是与MS本地的参数打交道的命令,例如AT+CMGS等。actioncommand可以带参数也可以不带。Actioncommand包含EXECUTION命令和TEST命令。(1)EXECUTION命令EXECUTION命令格式如下:不带参数:<name>带1个参数:<name>[=<value>]带多个参数:<name>[=<compound_value>]<compound_value>表示多个参数,中间以“,”分隔。对于有默认值的参数,可以在命令中省略,此时以默认值代替。如果所有的参数都省略,则<name>后面的“=”也一并略去。如果<name>不被识别,则表示此命令不存在,返回COMMANDNOTSUPPORT。<name>可识别的前提下,如果不能带参数的命令带了参数,或者参数个数超出定义,则返回TOOMANYPARAMETERS。(2)TEST命令TEST命令格式:<name>=?如果MS不能识别<name>,返回COMMANDNOTSUPPORT。如果MS可以识别<name>,且命令是不带参数的,则返回OK。如果命令带参数,则先返回各个参数的可取值范围,最后再加上OK。2)parametercommandparametercommand包括与MS本地的参数打交道的命令,这些参数有些会影响到atcioncommand的执行。parametercommand又分为SET命令、READ命令和TEST命令。(1)SET命令命令格式为:带1个参数:<name>[=<value>]带多个参数:<name>[=<compound_value>]SET命令用于设置参数。<compound_value>表示多个参数,中间以“,”分隔。对于有默认值的参数,可以在命令中省略,此时以默认值代替。如果所有的参数都省略,则<name>后面的“=”也一并略去。如果<name>不被识别,则表示此命令不存在,返回COMMANDNOTSUPPORT。<name>可识别的前提下,如果不能带参数的命令带了参数,或者参数个数超出定义,则返回TOOMANYPARAMETERS。(2)READ命令命令格式:<name>?READ命令用于读取参数当前值。(3)TEST命令命令格式:<name>=?如果MS不能识别<name>,返回COMMANDNOTSUPPORT。如果MS可以识别<name>,且命令是不带参数的,则返回OK。如果命令带参数,则先返回各个参数的可取值范围,最后再加上OK。命令表项解释下面依次介绍各个表项的含义:1.nameAT命令名,包括需要处理的+,$,&和终止的NULL。如+IPR,$QCDMG,S6,&C,Z。2.attitude32位的掩码,用来指定单个或多个命令属性。表4.1列出了AT命令的所有属性,后面给出了具有该属性的命令。3.special如果有需要,就指定处理编码,否则就是SPECIAL_NONE,指定处理编码定义在dsati.h。只是用在与外部软件的兼容性时。表1AT命令属性列表4.compound数字命令的参数个数或是字符串命令的最大长度(不包括NULL)。例如:S0,带有一个数字参数,compound=1;对于一个命令的字符串参数定义大小为30,compound=29。5.value_ptr指针变量,存储参数值。如果变量是一个数组(具有多个参数的命令),该指针指向数组的第一个元素。具有LIST属性的命令,存储在*val_ptr中的值不是真正的参数值,而是数组list_v指向的地址。对于带有MIXED_PARAM属性的命令,指针指向dsat_mixed_param_val_type,这是一个字符串或是数字值的联合体union类型。数组的成员是字符串还是数值依赖于对应数组成员的属性def_lim_ptr。该指针指向的变量可以是下面的类型之一:1)dsat_num_item_type带有数字参数或是LIST属性的命令;2)dsat_string_item_type带有字符串参数的命令;3)dsat_mixed_param_val_type带有混合类型参数的命令,参数可以是规定值的字符串,某一范围的数字,或是限定长度的字符串;4)NULL表示命令没有参数。6.defaultlimitptr定义默认值和允许范围的参数该指针的变量可以是下面类型中的一个:1)dflm_type带有CONFIG属性的命令;2)def_list_type带有LIST属性的命令;3)mixed_def_s_type带有MIXED_PARAM属性的参数;4)NULL带有STRING属性的命令或是没有参数的命令。7.processfunctionptr函数指针被调用用于执行在命令表入口定义的命令。函数指针参数是:1)dsat_mode_enum_type定义当前AT命令模式,表4.2列出模式和对应的含义。表2AT命令模式表2)dsati_cmd_struct*是dsati_cmd_struct结构入口指针,对于包含这个命令表入口指定命令。3)token_struct_type*是一个定义好的tokenstructure解析器指针,这个token结构包含处理该命令所要求的信息。4)dsm_item_type*是DSMbuffer的指针,存储命令响应。如果命令响应超出了一个DSMbuffer的容量,可以将多个DSMbuffer可以链接到一起。函数返回类型应该是表.3列出值中的一个。表4.3函数返回类型表8.abortfunctionptr函数指针通过命令表入口调用定义的abort命令,函数指针值不是NULL表示命令表入口定义的命令是可以abort的。函数指针参数是:dsati_cmd_struct*是dsati_cmd_struct结构入口指针,用于指示包含该命令表入口的指定命令。函数返回类型是一个Boolen表示:如果值是TRUE,表示数据调用可以通过DsmgrAbort,否则不需要任何动作。9.dflm_type定义AT命令中数字参数的最大值和最小值参数,这里的数字参数一定是连续的取值类型。如果参数取值为{0,1,255}这种参数应该设置为list类型。Default_v为默认值,lower和upper为最小和最大取值。10.def_list_type用于定义LIST类型的参数取值范围,其中:Default_v代表参数的默认值,它是指向list_v数组的指针。List_v是一个8-byte字符串的数组指针,代表该参数允许的所有值,数组的最后一项必须是NULL来终止参数列表。AT命令处理器完成该数组的字符串匹配,以决定参数值是否在有效的范围内。List_t是一个字符串指针,逐字返回测试命令的响应。AT命令如果含有多个参数,每个参数都关联于def_list_type结构。11.mixed_def_s_type和dsat_mixed_param_val_typeMixed_def_s_type用于存储AT命令中混合参数的默认值和可能值,混合参数类型表示AT命令的参数可以是不同类型的,其允许值范围也是个集合,如果是数值类型需要指定在某一范围内,如果是字符串类型则限定长度。如果命令有N个不同类型参数,默认的可能值范围包含一个长度为N的mixed_def_s_type数组,类型参数i是数组下标,如mixed_argus[]定义为mixed_argus[i].attrib。如果AT命令有N种不同类型参数,参数的当前值包含在长度为N的dsat_mixed_param_val_type数组中。该数组用于联系mixed_def_s_type数组Dsat_mixed_param_val_type数组下标为i的元素,在mixed_def_s_type数组对应i分量为该AT命令的默认和可能的范围值。增加一条AT命令基本流程AT命令处理器方便扩展以支持新的AT命令,图4.3所示的是添加一条新的AT命令的具体流程。1.Selectauniquenameforthecommand.Thecommandnamecanbeupto10charactersinlength,includingtheleading+,$,or&.首先选择一个唯一的命令名称,命令名长度最大10个字符,包括开始的+,$,&。本文中所用AT命令均为扩展命令,所以用的都是+。2.Determinethecommandattributes.ThevariouscommandattributesandtheirmeaningsareAre14listedinTable4-3决定命令属性不同命令属性和含义在表1AT命令属性列表中列出。3.Createavariabletostoretheargumentvalue(s).Ifthecommandhasoneormorearguments,declareavariableoftheappropriatetypeindsatctab.cordsatetsictab.ctostoretheargumentvalues.CommandtablesmustbeexportedinternaltotheATCoPunitindsatctab.hordsatetsictab.h.IftheargumentvaluesarereferencedbymodulesexternaltoATCoP,declare,thisvariableasanexternindsat.h.产生一个变量存储参数值,如果命令包含一个或多个参数,在dsatctab.c中定义一个对应类型的变量来存储参数值,命令表应该定义在dsatctab.c或dsatctab.h中。如果参数值用于ATCOP模块外部,将该变量声明在dsat.h中。4.Definethedefaultvalueandtheallowedrangeforthecommandarguments.Forcommandswithsimplenumericarguments,usethedflm_type.Initializethedefaultvalueandthelowerandupperbounds.ForcommandsoftypeLIST,usethedef_list_type.Createthelist_vandlist_tdatastructures,andinitializethedefaultvalue.Forcommandsoftypemixedparameter,createandinitializetheappropriatedflm_typeanddef_list_typeforeachparameterofthistype.Forstringarguments,thisisnotapplicable.Allofthesevariablesshouldbedeclaredindsatctab.cordsatetsictab.c.ForATcommandswhosedefaultsand/orlimitsneedtobeinitializedatrun-time,thisinitializationmaybeperformedinthefunctiondsatctab_data_init.定义命令参数的默认值和允许范围对于简单数字型参数的命令,使用dflm_type,初始化默认值和最小最大界限。对于LIST类型命令,使用def_list_type,产生list_v和list_t数据结构,并初始化默认值。对于混合参数类型命令,为每个类型参数产生并初始化相应dflm_type和def_list_type,对于string参数类型,不需要这些。所有这些变量应该声明在dsatctab.c或是dsatctab.h中,对应AT命令默认的限制需要在run-time初始化,初始化功能由dsatctab_data_init实现。5.AddtheCommandExecutionfunction,ifany.Ifthecommandrequiresspecialprocessingcodeoutsidethegenericparameterprocessingfunctionsdefinedindsatparm.c,addanewCommandExecutionfunctiontotheappropriatecommand-processingfile(dsatparm.c,dsatact.c,dsatvend.c,dsatetsicall.c,dsatetsipkt.c,dsatetsime.c,dsatetsismsc.c,dsatgsmfax.c).TakeadvantageofanyATcommandprocessingutilitiesexportedbydsati.horparameterprocessingexportedbydsatparm.h.添加命令执行函数(如果需要)如果命令需要指定额外处理函数,而不是在dsatparm.c中定义的通用函数,添加一个新的命令执行函数到对应的命令处理文件(dsatparm.cdsatact.cdsatvend.cdsatetsicall.c,dsatetsipkt.c,dsatetsime.c,dsatetsismsc.c)。可以使用任何AT命令处理单元在dsati.h中或是dsatparm.h中exported的。还有可能修改命令解析部分的代码,在文件dsatpar.c中,比如增加的以’^’开始的命令,需要增加相应的解析代码。6.AddtheAbortCommandfunction,ifany.Ifthecommandisabortable,anAbortCommandfunctionmustbedefinedintheappropriatecommandprocessingfile.Thecommandprocessingfilesarethesameasthoseidentifiedinstep5.添加abort命令函数(如果需要)如果命令是可终止的,一个终止命令函数定义在对应命令处理文件中。7.Addthecommandtotheappropriatecommandtable.First,determinewhichcommandtabletheATcommandbelongsto,basedonthecommandsyntaxandcommandtype.Then,addthedsati_cmd_typeentrytotheselectedcommandtable.Initializethedsati_cmd_typecommandtableentry.Initializethedsati_cmd_typecommandtableentrytopointtothisnewCommandExecutionfunction.Ifnonewspecialprocessingcodeisrequired,initializethecommandtableentrytopointtotheappropriateParameterProcessingfunctionorNULL,dependingonthecommandresponsedesired.InitializetheAbortCommandfunctionpointertoNULLifthecommandisnotabortable,otherwiseinitializeittopointtotheAbortCommandfunction添加命令表单首先,决定命令属于AT命令表中那个表,基于命令的语法和命令类型。然后添加dsati_cmd_type入口到选定的命令表。初始化dsati_cmd_type命令表入口,初始化dsati_cmd_type命令表入口指向这个新的命令执行函数。如果不需要指定新的处理代码,初始化命令表入口指向相应处理函数或是NULL,依赖于命令响应要求。如果命令不能abort,初始化abort函数指针到NULL,否则将其初始化到abort命令函数。图3添加一条AT命令的流程图增加一条同步AT命令范例SupposethatyouwanttoaddanewATcommand,AT$MYCMD,whichhastwonumericThefirstargumenttakesvaluesfrom0to7,withadefaultvalueof0,andthesecondargumenttakesvaluesfrom0to3,withadefaultvalueof2.Thecommandisnotabortable1.Name(首先选择一个唯一的命令名称)Thecommandnameis$MYCMD.2.Attributes(决定命令属性)Thiscommandhasthefollowingattributes:CONFIG–ThecommandhastwoargumentsEXTENDED–Thecommandusesextendedsyntax(beginswith$)3.Argumentstorage(产生一个变量存储参数值)Indsatctab.c:dsat_num_item_typedsat_mycmd_val[2];ForreferenceexternaltoATCoP,indsat.h,otherwiseindsatctab.h:externdsat_num_item_typedsat_mycmd_val[];4.DefaultsandlimitsIndsatctab.c:LOCALconstdflm_typedsat_mycmd_dflm[]={{0,0,7},/*argument1:default=0,range=0–7*/{2,0,3}/*argument2:default=2,range=0–3*/};5.Specialprocessing(添加命令执行函数)Supposethataspecialfunction,mycmd_action(),mustbeinvokedeachtimeAT$MYCMDisissued,aftertheparametervalueshavebeenstored.Accordingly,aCommandExecutionfunctionmustbedefinedindsatvend.c.ThisfunctionmustcalltheappropriateParameterProcessingfunctionexportedbydsatparm.handcallmycmd_action(),thenreturntheappropriateresultcode.Anexampleofthiscommandexecutionfunctionis:dsat_result_enum_typedsatvend_exec_mycmd_cmd(dsat_mode_enum_typemode,/*ATcommandmode*/constdsati_cmd_type*cmd_table,/*Ptrtocmdincommandtable*/consttokens_struct_type*tok_ptr,/*Commandtokensfromparser*/dsm_item_type*res_buff_ptr/*Placetoputresponse*/){dsat_result_enum_typeresult;/*Performcommandparameterprocessing:*/result=dsatparm_exec_param_cmd(mode,cmd_table,tok_ptr,res_buff_ptr);/*Performspecialprocessing:*/result=mycmd_action();returnresult;}/*dsatvend_exec_mycmd_cmd*/6.Abortcommandprocessing(添加abort命令函数)Sincethecommandisnotabortable,noAbortCommandfunctionneedstobedefined.7.Commandtableentry(添加命令表单)Sincethecommandusesvendor-specific(extended)syntax,itshouldbeaddedtothedsat_vendor_table[]indsatctab.c.Thecommandtableentrylookslikethis:{"$MYCMD",EXTENDED|CONFIG,SPECIAL_NONE,2,&dsat_mycmd_val[0],&dsat_mycmd_dflm[0],dsatvend_exec_mycmd_cmd,NULL},8.CompileandtestTheATcommandisnowinstalledinthecommandtable.Recompilethefilesthatweremodifiedandexecute.在超级终端输入:AT$MYCMD;观察输出9.参考//CCSPECelement*CHECKEDOUTelement\qct_6085\....../QSC6085_E2_v1.0.5_PRAtSyComand/LATESTelement\qct_6085\...QSC6085_e2_v1.0.5-mkbranchQSC6085_E2_v1.0.5_PRAtSyComandelement\qct_6085\.../main/0-mkbranchQSC6085_E2_v1.0.5_PRAtSyComandload\qct_6085//CCSPECEND增加一条异步AT命令范例Toaddanasynchronouscommand,thestepsdefinedintheprevioussectionmustbefollowedwiththefollowingdifferences:1.CommandExecutionfunctionmustreturnDSAT_ASYNC_CMD.ThisvaluemustbereturnedbytheCommandExecutionfunctiontonotifytheATcommandprocessorthatthisisanasynchronouscommand.TheCommandExecutionfunctiontypicallyinitiatesthecommandprocessingbycallingontheservicesofanothertask.Theothertaskthenrespondsbygeneratinganasynchronousevent.命令处理涵数必须返回DSAT_ASYNC_CMD值。返回值告知AT命令处理器这是异步命令。命令处理涵数指派其他任务服务发起命令处理,其他任务产生一异步事件来响应。2.AddanasynchronousEventHandlerfunction.AnEventHandlerfunctionmustbedefinedtohandletheevent.AddthenewEventHandlerfunctiontotheappropriatecommandprocessingfile(dsatparm.c,dsatact.c,dsatvend.c,dsatetsicall.c,dsatetsipkt.c,dsatetsime.c,dsatetsismsa.c).TheeventhandlermustreturnavalueotherthanDSAT_ASYNC_CMDorDSAT_ASYNC_EVENTtoindicatetheasynchronouscommandprocessinghascompleted.增加一个异步件处理函数。必须定义一个异步事件处理函数来处理该异步事件异步事件处理函数可以定义在响应的命令处理文件中。异步事件处理不返回DSAT_ASYNC_CMD或DSAT_ASYNC_EVENT值时,表明该异步事件处理完毕。3.Addtheasynchronouseventidentifierandeventstructuretothedataservicestask.Theeventidentifiermustbeaddedtods_cmd_enum_typeinfiledstask.h.AddtheeventidentifierbetweentheDS_AT_ASYNC_EVENT_STARTandDS_AT_ASYNC_EVENT_ENDitemsintheenumerationtypetoinsuretheeventishandledasanATCoPasynchronousevent.AddthisneweventidentifiertoATCoPcommandsintheswitchstatementoffunctiondsi_process_cmds.Thisfunctionislocatedinthefiledstask.c.Defineandaddanyneweventparametersrequiredtobeprocessedbytheeventhandlertotheds_cmd_typestructuredefinedindstask.h.往数据服务任务增加一个异步件处理标识号和异步事件结构。异步件处理标识添加到dstask.h.里的ds_cmd_enum_type枚举结构中。必须保证标识号在DS_AT_ASYNC_EVENT_STARTandDS_AT_ASYNC_EVENT_END之间。在dstask.c.下dsi_process_cmds涵数中,增加该异步件处理标识号case语句开关,确保调用dsat_process_async_cmd函数。在dstask.h.下,ds_cmd_type结构中,增加一异步事件的参数(unit变量),以便异步事件回调涵数进一步处理。4.Addtheeventandhandlertotheasynchronouseventhandlertable.Addanewdsati_async_event_table_entry_typetotheasynchronouseventhandlertable.Thetableislocatedinthefiledsatetsitgt.c.InitializethetableentrytopointtothenewEventHandlerfunctionandwiththeeventidentifier.添加该异步件处理函数到异步事件处理表单中。异步事件处理表单中位于dsatetsitgt.c的async_event_table中,根据异步件处理标识号,当前模式,该异步件处理函数指针新增一条记录。Example:SupposethatyouwanttomakethenewATcommand,AT$MYCMD,addedinthepreviousexample,anasynchronouscommand.Thisasynchronouscommandrequiresasingleasynchronouseventtocompleteprocessingofthecommand.Difference1–CommandExecutionfunctionreturnsDSAT_ASYNC_CMDSupposethataspecialfunction,mycmd_action(),whichisinvokedeachtimetheAT$MYCMDisissued,requestsinformationfromanothertask.TheinformationisthensenttoATCoPfromanothertaskbycallingtheprovidedCallbackfunctiontogenerateanasynchronousevent.Sincethisisavendor-specificcommand,thesefunctionsmustbedefinedindsatvend.c.Theyaregivenhere:命令处理涵数必须返回DSAT_ASYNC_CMD值,每次执行AT$MYCMD命令,都会调用专门涵数mycmd_action();请求来自其他任务的信息。其他任务通过准备好的回调涵数发送来自其他任务的信息到AT命令处理器。回调涵数产生一异步事件。dsat_result_enum_typedsatvend_exec_mycmd_cmd(dsat_mode_enum_typemode,/*ATcommandmode*/constdsati_cmd_type*cmd_table,/*Ptrtocmdincommandtable*/consttokens_struct_type*tok_ptr,/*Commandtokensfromparser*/dsm_item_type*res_buff_ptr/*Placetoputresponse*/){/*Performcommandparameterhandling.....*//*Requestinformationfromanothertask:*///这个地方真看不懂?//为什么要这样//纯脆为本例子而做?mycmd_action(my_callback_func);returnDSAT_ASYNC_CMD;}/*dsatvend_exec_mycmd_cmd*/LOCALvoidmy_callback_func(other_task_data_type*cmd){ds_cmd_type*cmd_buf;/*Sendasynchronouseventtodataservicestask*/if((cmd_buf=ds_get_cmd_buf())==NULL){ERR_FATAL("Nodscommandbuffer",0,0,0);}else{cmd_buf->hdr.cmd_id=DS_AT_MY_ASYNC_CMD;cmd_buf->cmd.my_cmd.data=*cmd;ds_put_cmd(cmd_buf);}}/*my_callback_func*/Difference2–ASYNCEventHandlerfunctionAnasynchronouseventisreceivedfromtheothertaskwhentherequestedinformationisavailable.ThisoccurswhentheothertaskcallstheCallbackfunctionpreviouslydefinedtopassthedatatoATCoP.TheAsynchronousEventHandlerfunctiondefinedherehandlestheeventandindicatescommandprocessinghascompletedwiththeresultreturned.异步事件回调涵数调用:数据服务任务上一次执行mycmd_action(my_callback_func)时,做了{cmd_buf->hdr.cmd_id=DS_AT_MY_ASYNC_CMD;cmd_buf->cmd.my_cmd.data=*cmd;ds_put_cmd(cmd_buf);}调用,其结果当数据服务任务再次执行(不一定就是下一次)执行{if((set_sigs&DS_CMD_Q_SIG)!=0){dsi_process_cmds();}}时,调用dsat_process_async_cmd(cmd_ptr);通过对异步事件处理表单中异步件处理标识号的查找比对,响应的异步确事件回调涵数被调用,生成response报文,发送到DTE的SIO,异步AT命令结束。dsat_result_enum_typedsatvend_my_async_event_handler(dsat_mode_enum_typemode,ds_cmd_type*cmd_ptr){dsm_item_type*response_buffer;/*CreatecommandresponseandreturnpointertoDSMitemcontainingresponse.*/response_buffer=build_mycmd_response(cmd_ptr);/*FormatresponseandqueueupfortransmissiontoDTE.*/dsatcmdp_handle_async_cmd_rsp(response_buffer);/*Indicatecommandprocessingwascompletedsuccessfully.*/returnDSAT_OK;}/*dsatvend_my_async_event_handler*/Difference3–AddneweventAddtheneweventidentifierandcommandstructuretothefiledstask.h:往数据服务任务增加一个异步件处理标识号DS_AT_MY_ASYNC_CMD,确保在DS_AT_ASYNC_EVENT_END前面/*---------------------------CommandsthatmaybesenttotheDataServicesTask.---------------------------*/typedefenum{/*3GDsmgrsub-taskcommands*/DS_RDM_OPEN_CMD,/*ATCoPsub-taskcommands*/DS_AT_ASYNC_EVENT_START,/*StartofATCoPasynchronousevents*/DS_AT_SMS_MSG_CMD,//DS_AT_MY_ASYNC_CMD,DS_AT_ASYNC_EVENT_END/*EndofATCoPasynchronousevents*/}ds_cmd_enum_type;/*---------------------------CommandDatatypes---------------------------*/typedefstruct{other_task_data_typedata;}ds_at_mycmd_type;/*-----------------------------Commandtype:Thecommandheaderidentifiesthecommand.Ifthecommandhasanyparameters,theyarespecifiedintheunion.-----------------------------*/typedefstruct{ds_cmd_hdr_typehdr;/*Commandheader*/union{ds_rdm_open_typerdm_open;ds_at_sms_msg_typesms_msg;ds_at_mycmd_typemy_cmd;}cmd;}Addtheneweventidentifiertoswitchstatementindstask.c:voiddsi_process_cmds(void){ds_cmd_type*cmd_ptr;/*Getcommandsfromthecommandqueueuntilthequeueisempty.Foreachcommandreceived,dispatchthecommandtotheappropriatesubtask.*/while((cmd_ptr=(ds_cmd_type*)q_get(&dsi_cmd_q))!=NULL){switch(cmd_ptr->hdr.cmd_id){/*--------------------------3GDsmgrCommands--------------------------*/caseDS_RDM_OPEN_CMD:ds3g_process_cmds(cmd_ptr);break;/*--------------------------ATCoPCommands--------------------------*/caseDS_AT_SMS_MSG_CMD:caseDS_AT_MY_ASYNC_CMD:dsat_process_async_cmd(cmd_ptr);break;default:ERR_FATAL("InvalidDStaskcommand:%d",cmd_ptr->hdr.cmd_id,0,0);}/*switch*//*Returnthecommandbuffertothefreecommandqueue.*/q_put(&dsi_cmd_free_q,&cmd_ptr->hdr.link);}/*while*/}/*dsi_process_cmds()*/Difference4–EventhandlertableentryAddthenewasynchronouseventhandlertothetabledefinedindsatetsitgt.c:constdsati_async_event_table_entry_typeasync_event_table[]={DS_AT_SMS_MSG_CMD,{dsatetsismsa_msg_handler},DS_AT_MY_ASYNC_CMD,{dsatvend_my_async_event_handler},DS_AT_ASYNC_EVENT_END,{NULL}};10.参考CCSPEC:element*CHECKEDOUTelement\qct_6085\....../QSC6085_E2_v1.0.5_PRAtaSyComand/LATESTelement\qct_6085\...QSC6085_e2_v1.0.5-mkbranchQSC6085_E2_v1.0.5_PRAtaSyComandelement\qct_6085\.../main/0-mkbranchQSC6085_E2_v1.0.5_PRAtaSyComandload\qct_6085主动上报的AT事件如何实现实现方法什么是主动上报的事件?DT主动上报结果码给TE,如振铃上报、短信上报、状态改变上报等。英文缩写URC,英文全称“Unsolicitedresultcode”。确认数据的来源。短信上报的数据来源于SMS系统,振铃上报等来源于CM系统,其他的也可来自应用的注册事件,如USB插拔,SD卡插拔,耳机插事件等。确定主动上报事件的名称如:+CMTI(短信到达提示)主动上报的AT事件ID同1.5.2和1.5.3同样处理5.主动上报的事件的触发事件主动上报的事件发生时,应准好事件的触发相应函数。产生一个主动上报的事件,等待AT命令处理器ds_task调度处理。来电,短信通常注册一个回调函数来监测主动上报的事件的发生。其他则通过应用层注册Notify事件,通知ds_task调度处理6.主动上报的事件的处理函数同1.5.2和1.5.3同样处理其他可参考1.5.2和1.5.3同样处理范例:确定名称^MODE数据的来源CM服务模块主动上报的AT事件ID同1.5.2和1.5.3定义DS_CM_SS_SRV_CHG_CMDdstask.h:typedefenum{DS_MIN_CMD=-1,/*======================3GDSMGR(values0-199)========================*//*3GDsmgrsub-taskcommands(values0-199)*/DS_RDM_OPEN_CMD=0,/*CmdfromRDMtoopenaserialport*/proceeding*/DS_CM_CALL_MODIFY_CMD=10,/*ConfirmthatMOcallisproceeding*/DS_CM_SS_SRV_CHG_CMD=11,}ds_cmd_hdr_type;4.主动上报的事件的触发事件ds3gcmif.c:voidds3gi_cm_init(void){//addfor主动上报的事件的范例begin/*Registertobenotifiedwhenevertheservingsystemchanges.*/ret_val=cm_mm_client_ss_reg(ds3gi_cm_client_id,ds3gi_cm_ss_event_cb,CM_CLIENT_EVENT_REG,CM_SS_EVENT_SRV_CHANGED,CM_SS_EVENT_SRV_CHANGED,NULL);if(ret_val!=CM_CLIENT_OK){MSG_ERROR("cm_mm_client_call_regerror%d",(int)(ret_val),0,0);}}//addfor主动上报的事件的范例end}//addfor主动上报的事件的范例beginvoidds3gi_cm_ss_event_cb(cm_ss_event_e_typess_event,/*Theeventtoccurred*/ constcm_mm_ss_info_s_type*ss_info_ptr/*Servingsysteminformation*/){cmd_ptr->hdr.cmd_id=DS_CM_SS_SRV_CHG_CMD;cmd_ptr->cmd.ss_info.sys_mode=ss_info_ptr->sys_mode;cmd_ptr->cmd.ss_info.hdr_hybrid=ss_info_ptr->hdr_hybrid;cmd_ptr->cmd.ss_info.hdr_srv_status=ss_info_ptr->hdr_srv_status;cmd_ptr->cmd.ss_info.ps_data_suspend=ss_info_ptr->ps_data_suspend;cmd_ptr->cmd.ss_info.hdr_active_prot=ss_info_ptr->hdr_active_prot;ds_put_cmd(cmd_ptr);}//addfor主动上报的事件的范例end5.主动上报的事件的处理函数dstask.c:voiddsi_process_cmds(void){caseDS_RELEASE_CALL_CMD://addfor主动上报的事件的范例begincaseDS_CM_SS_SRV_CHG_CMD://addfor主动上报的事件的范例endcaseDS_CM_PDP_MODIFY_IND_CMD:caseDS_CM_PDP_PROMOTE_IND_CMD:caseDS_CM_SS_PS_DATA_FAIL_CMD:caseDS_CM_PDP_MODIFY_CONF_CMD:caseDS_CM_PDP_MODIFY_REJ_CMD:ds3g_process_cmds(cmd_ptr);break;}ds3gmgr.c:voidds3g_process_cmds(ds_cmd_type*cmd_ptr){switch(cmd_ptr->hdr.cmd_id){//addfor主动上报的事件的范例begincaseDS_CM_SS_SRV_CHG_CMD:ds3gi_process_cm_ss_srv_chg_cmd(cmd_ptr);break;//addfor主动上报的事件的范例end}}//addfor主动上报的事件的范例beginvoidds3gi_process_cm_ss_srv_chg_cmd(ds_cmd_type*cmd_ptr/*Pointertothecommand*/){//moresomrtning}/*ds3gi_process_cm_ss_srv_chg_cmd()*///addfor主动上报的事件的范例end//addfor主动上报的事件的范例beginLOCALvoidds3gi_process_sys_mode_change(sys_sys_mode_e_typenew_mode){//添加主动回报内容#ifdefFEATURE_CHINA_TELECOM_PC_MODEMif(new_mode!=last_mode){last_mode=new_mode; std_strlprintf(mode_str,sizeof(mode_str),"^MODE:%d",new_mode); dsattelutil_send_resp_string(mode_str);}#endif}
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024新型物业管理安全服务协议范本
- 2024项目部全职员工聘用协议简化
- 2024年度公司借贷协作协议样本
- 2024-2025学年广西南宁市青秀区天桃实验学校九年级(上)月考数学试卷(10月份)
- 2024年常用公司担保协议样式
- 2024金融借款协议法律答辩文件
- 2024专用工程预拌干粉砂浆购销协议
- 2024年协议延期条款详细协议样例
- 幼儿饺子课件教学课件
- 航模科普课件教学课件
- GMP质量管理体系文件 中药材洗、润、切制SOP
- 贵州茅台酒全国经销商信息汇总
- 儿科学教学课件:儿童股骨干骨折
- 喹啉安全技术说明书MSDS
- GB/T 25217.1-2010冲击地压测定、监测与防治方法第1部分:顶板岩层冲击倾向性分类及指数的测定方法
- GB/T 24511-2017承压设备用不锈钢和耐热钢钢板和钢带
- GB 30255-2019室内照明用LED产品能效限定值及能效等级
- GB 18613-2020电动机能效限定值及能效等级
- 深度解读强基计划-被强基计划课件
- Banach空间及其相关定理
- 小学数学西南师大三年级上册四两位数除以一位数的除法 两位数除以一位数的除法问题解决
评论
0/150
提交评论