IECLINK.c 88 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301
  1. /********************************************************************
  2. 版权所有:
  3. 文件版本: V1.00
  4. 文件名称: IEC_LINK.c
  5. 生成日期: 2010年04月26日
  6. 作 者:hhw
  7. 使用范围:
  8. 功 能: 装置级联处理
  9. 更新信息:
  10. 更新日志1
  11. 修改者:
  12. 修改日期:
  13. 修改内容:
  14. 修改原因:
  15. *********************************************************************/
  16. #include "head.h"
  17. volatile int g_net_104link_data[CFG_LINK_104_NUM];
  18. // 级联104初始化标志
  19. int g_link104_init_ok[CFG_LINK_104_NUM];
  20. u8 g_link104_buf[CFG_LINK_104_NUM][IEC_BUF_LEN];
  21. IECLINK_DEF g_link_104[CFG_LINK_104_NUM];
  22. LINKYK_DEF g_lnk_yk[SWITCH_NUM_EXT_PUB];
  23. LINKPAR_DEF g_link_par[SWITCH_NUM_EXT_PUB];
  24. u8 g_link_par_cnt=0; /*当前遥参游标*/
  25. #ifdef IEC_NOLINK_NO_CALLYX
  26. IEC_LINK_REG g_link_comm;
  27. #endif
  28. int get_index_setno(u8 group_type,u16 setno)
  29. {
  30. int i=0;
  31. for(i=0;i<ParaIDNum;i++)
  32. {
  33. if(tParaID[i].link_ch != 0) continue; //不是本地定值
  34. if((tParaID[i].group_type == group_type) && (tParaID[i].setno == setno))
  35. {
  36. return i;
  37. }
  38. }
  39. return -1;
  40. }
  41. #ifdef YPARA_LINK
  42. msg_data_struct temp_par;
  43. void print_msg_base(msg_ypara_data_struct *msg)
  44. {
  45. int i=0;
  46. for(i=0;i<msg->num;i++)
  47. {
  48. rt_printf("%02d:cp_m[%x],cp_s[%x],len=%d\r\n",i,msg->base_data[i].cp_m,msg->base_data[i].cp_s,msg->base_data[i].val_iec.size);
  49. }
  50. }
  51. par_queque_m * lnk_msg_ypara_head_s(u8 chnl)
  52. {
  53. u8 ch=0;
  54. u8 index=0;
  55. ch=(chnl>>5)&0x07;
  56. index = chnl&0x1f;
  57. if(ch >= 2) /*串口*/
  58. {
  59. ch -= 2; /*串口号*/
  60. if((ch < CFG_UART_NUM_MAX) && (tRunPara.tUartPara[ch].wProtocol == PROTOCOL_101_M))
  61. {
  62. IECLINK_DEF *pt;
  63. pt=(IECLINK_DEF *)g_tRsComm[ch].ptBuf;
  64. return &pt->par_queue;
  65. }
  66. #ifdef FUN_IEC103_STA
  67. else if((ch < CFG_UART_NUM_MAX) &&
  68. (tRunPara.tUartPara[ch].wProtocol == PROTOCOL_103_M || tRunPara.tUartPara[ch].wProtocol == PROTOCOL_YZ103_M))
  69. {
  70. IECLINK_DEF *pt;
  71. pt=(IECLINK_DEF *)g_tRsComm[ch].ptBuf;
  72. return &pt->par_queue;
  73. }
  74. #endif
  75. }
  76. else /*网口*/
  77. {
  78. index = index - 1; /*级联网络号*/
  79. // 以太网通道
  80. if(index < CFG_LINK_104_NUM)
  81. {
  82. IECLINK_DEF *pt;
  83. pt=&g_link_104[index];
  84. if(g_link104_init_ok[index] == 0)
  85. {
  86. return 0;
  87. }
  88. else
  89. {
  90. return &pt->par_queue;
  91. }
  92. }
  93. }
  94. return 0;
  95. }
  96. msg_data_struct * lnk_msg_ypara_head_m(u8 chnl)
  97. {
  98. u8 ch=0;
  99. ch = chnl;
  100. if(ch < CFG_UART_NUM_MAX) /*串口子站*/
  101. {
  102. IEC101_DEF *pt101;
  103. pt101 = (IEC101_DEF *)g_tRsComm[ch].ptBuf;
  104. if((tRunPara.tUartPara[ch].wProtocol==PROTOCOL_101)
  105. || (tRunPara.tUartPara[ch].wProtocol==PROTOCOL_101_PH)) // 串口级联规约
  106. {
  107. return &pt101->msg_ypara_recv;
  108. }
  109. }
  110. else if(ch < CFG_UART_NUM_MAX + CFG_ETH_MAX_LOGIC) /*网口104*/
  111. {
  112. IEC104_DEF *pt104;
  113. ch = chnl-CFG_UART_NUM_MAX;
  114. pt104=&g_t104[ch];
  115. return &pt104->msg_ypara_recv;
  116. }
  117. return 0;
  118. }
  119. int get_stbl_index_s(u16 parId)
  120. {
  121. int i=0;
  122. for(i=0;i<ParaIDNum;i++)
  123. {
  124. if(tParaID[i].parId == parId)
  125. {
  126. return i;
  127. }
  128. }
  129. return -1;
  130. }
  131. int get_index_link(u16 link_ch,u16 link_cp)
  132. {
  133. int i=0;
  134. for(i=0;i<ParaIDNum;i++)
  135. {
  136. if(tParaID[i].link_ch == 0) continue; //不是级联定值
  137. if(((tParaID[i].link_ch == link_ch) || ((tParaID[i].link_ch &0x1f) == 0x1F))
  138. && (tParaID[i].link_cp == link_cp))
  139. {
  140. return i;
  141. }
  142. }
  143. return -1;
  144. }
  145. int mananger_msg_ypara_s(msg_data_struct *msg,u8 sport,u8 dport)
  146. {
  147. int i=0;
  148. IECLINK_DEF *pt;
  149. par_queque_m *par_queque;
  150. temp_par= *msg;
  151. if((dport & 0x1F) == 0x1F) /*广播*/
  152. {
  153. rt_printf("广播:::::::子站--->级联主站(msg),sport=%x,dport=%x,type=%d\r\n",sport,dport,msg->type);
  154. {
  155. for(i=0;i<CFG_LINK_104_NUM;i++)
  156. {
  157. if(g_link104_init_ok[i] == 0) continue; //没初始化的不增加
  158. pt = &g_link_104[i];
  159. par_queque = &pt->par_queue;
  160. temp_par.dport = msg->dport;
  161. temp_par.sport = 0x1F; /*级联源口号0x1F表示不用返回*/
  162. temp_par.flag = 0x81;
  163. add_data_queque(&par_queque->queue,(u8 *)&temp_par,OVER_QUEUE);
  164. }
  165. return 0;
  166. }
  167. }
  168. else
  169. {
  170. rt_printf("常规:::::::子站--->级联主站(msg),sport=%x,dport=%x,type=%d\r\n",sport,dport,msg->type);
  171. par_queque = lnk_msg_ypara_head_s(dport);
  172. if(par_queque == 0)
  173. {
  174. //sprintf(buf,"级联遥参:未找到从设备通道(link_ch=%02x)",dport);
  175. //log_str_time(LOG_OPERATE,buf,0,0);
  176. rt_printf("级联遥参:未找到从设备通道(link_ch=%02x)\r\n",dport);
  177. return -1;
  178. }
  179. //print_msg_base(msg);
  180. temp_par.dport = msg->dport;
  181. temp_par.sport = msg->sport;
  182. temp_par.flag = 0x81;
  183. add_data_queque(&par_queque->queue,(u8 *)&temp_par,OVER_QUEUE);
  184. rt_printf("----par_queue num=%d\r\n",get_queue_count(&par_queque->queue));
  185. return 0;
  186. }
  187. return -1;
  188. }
  189. int rec_msg_ypara_return(msg_data_struct *msg,u8 sport,u8 dport)
  190. {
  191. msg_data_struct *msg_ypara;
  192. rt_printf("级联主站---子站(msg),sport=%d,dport=%d,type=%d\r\n",sport,dport,msg->ypara_msg.type);
  193. if((dport & 0x1F) == 0x1F) /*广播的不返回*/
  194. {
  195. return 0;
  196. }
  197. msg_ypara = lnk_msg_ypara_head_m(dport);
  198. if(msg_ypara == 0)
  199. {
  200. rt_printf("级联主站---子站(msg)通道失败\r\n");
  201. return -1;
  202. }
  203. //print_msg_base(msg);
  204. *msg_ypara = *msg;
  205. msg_ypara->flag = 1;
  206. return 0;
  207. }
  208. void lnk_slave_ypara_write(IECLINK_DEF *pt,u8 chnl,u8 vsq,u8 cot,u8 *ps,bool b104)
  209. {
  210. int i =0;
  211. u8 num=0;
  212. u8 off=0;
  213. u8 len =0;
  214. u16 link_cp=0;
  215. u8 pdi=0;
  216. msg_data_struct *msg_data;
  217. msg_ypara_data_struct *msg;
  218. iec_val_struct v;
  219. num=(vsq&0x7f);
  220. msg_data = &pt->temp_par;
  221. msg = &pt->temp_par.ypara_msg;
  222. memset(msg,0,sizeof(msg_ypara_data_struct));
  223. off += 2; /*定值区*/
  224. pdi = ps[off++]; /*参数特征标识*/
  225. for(i=0;i<num;i++)
  226. {
  227. link_cp=(ps[off]+(ps[off+1]<<8));
  228. off += 2;
  229. if(b104) off +=1;
  230. v.tag = ps[off++];
  231. v.size = ps[off++];
  232. memcpy(v.value,&ps[off],v.size);
  233. len = v.size+2;
  234. off += v.size;
  235. msg->base_data[msg->num].val_iec = v;
  236. msg->base_data[msg->num].cp_s = link_cp;
  237. msg->base_data[msg->num].cp_m = 0;
  238. msg->num++;
  239. }
  240. if((pdi&0xc0)==0) // 定值固化
  241. {
  242. if(cot & IEC_COT_PN)
  243. {
  244. msg->cmd = YP_EXE_FAULT;
  245. }
  246. else
  247. {
  248. msg->cmd = YP_EXE_RETURN;
  249. }
  250. }
  251. else if((pdi&0xc0)==0x40) /*撤销*/
  252. {
  253. if(cot & IEC_COT_PN)
  254. {
  255. msg->cmd = YP_CANCEL_FAULT;
  256. }
  257. else
  258. {
  259. msg->cmd = YP_CANCEL_RETURN;
  260. }
  261. }
  262. else // 参数预置
  263. {
  264. if(cot & IEC_COT_PN)
  265. {
  266. msg->cmd = YP_SEL_FAULT;
  267. }
  268. else
  269. {
  270. msg->cmd = YP_SEL_RETURN;
  271. }
  272. }
  273. msg->type = modify_set;
  274. msg_data->dport = pt->sport;
  275. msg_data->sport = chnl;
  276. rec_msg_ypara_return(msg_data,msg_data->sport,msg_data->dport);
  277. }
  278. void lnk_slave_ypara_read(IECLINK_DEF *pt,u8 chnl,u8 vsq,u8 cot,u8 *ps,bool b104)
  279. {
  280. int i =0;
  281. u8 num=0;
  282. u8 off=0;
  283. u16 link_cp=0;
  284. int index=0;
  285. SET_PARA_VAL *tmp_pval;
  286. u8 type=0,len=0;
  287. char str[64];
  288. num=(vsq&0x7f);
  289. off += 2; /*定值区*/
  290. off++; /*参数特征标识*/
  291. if(cot & IEC_COT_PN)
  292. {
  293. return ;
  294. }
  295. for(i=0;i<num;i++)
  296. {
  297. link_cp=(ps[off]+(ps[off+1]<<8));
  298. off += 2;
  299. if(b104) off +=1;
  300. type = ps[off++];
  301. len = ps[off++];
  302. if(len <sizeof(str))
  303. {
  304. memcpy(str,&ps[off],len);
  305. off += len;
  306. index = get_index_link(chnl,link_cp);
  307. if(index < 0)
  308. {
  309. //rt_printf("M104_read_unpack::index<0,chnl=0x%x,di=0x%x\r\n",chnl,link_cp);
  310. continue;
  311. }
  312. tmp_pval = &tPara_val[index];
  313. tmp_pval->datatype = type;
  314. tmp_pval->len = len;
  315. memcpy(tmp_pval->str,str,len);
  316. //rt_printf("M104_read_unpack::chnl=0x%x,di=0x%x,tmp_pval[%d]:datatype=0x%x,len=0x%x\r\n",chnl,link_cp,index,tmp_pval->datatype,tmp_pval->len);
  317. }
  318. else
  319. {
  320. off += len;
  321. }
  322. }
  323. }
  324. void lnk_slave_ypara_updata(IECLINK_DEF *pt,u8 *ps)
  325. {
  326. u8 flag=0;
  327. ps += 3; /*信息体地址*/
  328. flag = ps[0];
  329. if(flag)
  330. {
  331. set_read_all(pt);
  332. }
  333. }
  334. void set_read_all(IECLINK_DEF *pt)
  335. {
  336. LNK_STATUS *ptlnk = &pt->tlnk;
  337. //rt_printf("!!!!!!!![%d]----set\r\n,",pt->chnl);
  338. ptlnk->bSet_all=true;
  339. }
  340. void clear_read_all(IECLINK_DEF *pt)
  341. {
  342. LNK_STATUS *ptlnk = &pt->tlnk;
  343. //rt_printf("!!!!!!!![%d]----clear\r\n,",pt->chnl);
  344. ptlnk->bSet_all=false;
  345. }
  346. void print_tPara_val(int index)
  347. {
  348. SET_PARA_VAL *tmp_pval;
  349. float val=0;
  350. if(index >=MAX_SET_NUMBER) return;
  351. tmp_pval = &tPara_val[index];
  352. switch(tmp_pval->datatype)
  353. {
  354. case BOOL_R:
  355. case TINY_R:
  356. case UTINY_R:
  357. val=tmp_pval->str[0];
  358. rt_printf("-----val[%f-[%02x]]\r\n",val,tmp_pval->str[0]);
  359. break;
  360. case UINT_R:
  361. case INT_R:
  362. case LONG_R:
  363. case ULONG_R:
  364. val=(tmp_pval->str[0]+(tmp_pval->str[1]<<8)+(tmp_pval->str[2]<<16)+(tmp_pval->str[3]<<24));
  365. rt_printf("-----val[%f-[%02x-%02x-%02x-%02x]]\r\n",val,tmp_pval->str[0],tmp_pval->str[1],tmp_pval->str[2],tmp_pval->str[3]);
  366. break;
  367. case SHORT_R:
  368. case USHORT_R:
  369. val=(tmp_pval->str[0]+(tmp_pval->str[1]<<8));
  370. rt_printf("-----val[%f-[%02x-%02x]]\r\n",val,tmp_pval->str[0],tmp_pval->str[1]);
  371. break;
  372. case FLOAT_R:
  373. {
  374. union{
  375. float ff;
  376. u8 tt[4];
  377. }ff;
  378. ff.tt[3]=tmp_pval->str[0];
  379. ff.tt[2]=tmp_pval->str[1];
  380. ff.tt[1]=tmp_pval->str[2];
  381. ff.tt[0]=tmp_pval->str[3];
  382. val=ff.ff;
  383. rt_printf("-----val[%f-[%02x-%02x-%02x-%02x]]\r\n",val,tmp_pval->str[0],tmp_pval->str[1],tmp_pval->str[2],tmp_pval->str[3]);
  384. break;
  385. }
  386. }
  387. }
  388. #endif
  389. u32 * lnk_get_ch_par_head(u8 chnl)
  390. {
  391. u8 ch=chnl;
  392. u8 index=0;
  393. ch=(chnl>>5)&0x07;
  394. index = chnl&0x1f;
  395. if(ch>=2) // 串口
  396. {
  397. ch -=2;
  398. if(ch < CFG_LINK_101_NUM &&( tRunPara.tUartPara[ch].wProtocol == PROTOCOL_101_M||tRunPara.tUartPara[ch].wProtocol == PROTOCOL_101_PH_M))
  399. {
  400. IECLINK_DEF *pt;
  401. pt=(IECLINK_DEF *)g_tRsComm[ch].ptBuf;
  402. return &pt->par_send_flag;
  403. }
  404. }
  405. else /*网口*/
  406. {
  407. index = index - 1; /*级联网络号*/
  408. // 以太网通道
  409. if(index < CFG_LINK_104_NUM)
  410. {
  411. IECLINK_DEF *pt;
  412. pt=&g_link_104[index];
  413. return &pt->par_send_flag;
  414. }
  415. }
  416. return 0;
  417. }
  418. u32 * lnk_get_ch_head(u8 chnl)
  419. {
  420. u8 ch=chnl;
  421. ch=(chnl>>5)&0x07;
  422. if(ch>=2) // 串口
  423. {
  424. ch -=2;
  425. if(ch < CFG_LINK_101_NUM &&( tRunPara.tUartPara[ch].wProtocol == PROTOCOL_101_M||tRunPara.tUartPara[ch].wProtocol == PROTOCOL_101_PH_M))
  426. {
  427. IECLINK_DEF *pt;
  428. pt=(IECLINK_DEF *)g_tRsComm[ch].ptBuf;
  429. return &pt->yk_send_flag;
  430. }
  431. else if(ch < CFG_LINK_101_NUM && tRunPara.tUartPara[ch].wProtocol == PROTOCOL_MODBUS)
  432. {
  433. MODBUS_DEF *pt;
  434. pt= (MODBUS_DEF *)g_tRsComm[ch].ptBuf;
  435. return &pt->yk_send_flag;
  436. }
  437. #if defined BATTERY_WITH_COMM && defined FUNC_SEL_BAT_MODULE
  438. else if(ch < CFG_LINK_101_NUM && tRunPara.tUartPara[ch].wProtocol == PROTOCOL_PWRM)
  439. {
  440. pwdmodlue_def *pt;
  441. pt= (pwdmodlue_def *)g_tRsComm[ch].ptBuf;
  442. return &pt->yk_sendflag;
  443. }
  444. #endif
  445. }
  446. else // 网口
  447. {
  448. ch=chnl-1;
  449. // 以太网通道
  450. if(ch < CFG_LINK_104_NUM)
  451. {
  452. IECLINK_DEF *pt;
  453. pt=&g_link_104[ch];
  454. return &pt->yk_send_flag;
  455. }
  456. }
  457. return 0;
  458. }
  459. void lnk_call_all(void)
  460. {
  461. int i;
  462. for(i=0; i<CFG_LINK_104_NUM; i++)
  463. {
  464. g_link_104[i].tlnk.bCallAll = true;
  465. }
  466. for(i=0; i<CFG_LINK_101_NUM; i++)
  467. {
  468. if(tRunPara.tUartPara[i].wProtocol == PROTOCOL_101_M||tRunPara.tUartPara[i].wProtocol == PROTOCOL_101_PH_M)
  469. {
  470. int j;
  471. IECLINK_DEF *pt=(IECLINK_DEF *)g_tRsComm[i].ptBuf;
  472. if(pt == NULL)
  473. continue;
  474. for(j=0;j<pt->slave_num;j++)
  475. {
  476. pt->tsla[j].tlnksave.bCallAll=true;
  477. }
  478. pt->tlnk.bCallAll=true;
  479. }
  480. }
  481. }
  482. void lnk_rst_set(void)
  483. {
  484. int i;
  485. for(i=0; i<CFG_LINK_104_NUM; i++)
  486. {
  487. g_link_104[i].tlnk.brst = true;
  488. }
  489. for(i=0; i<CFG_LINK_101_NUM; i++)
  490. {
  491. if(tRunPara.tUartPara[i].wProtocol == PROTOCOL_101_M||tRunPara.tUartPara[i].wProtocol == PROTOCOL_101_PH_M)
  492. {
  493. int j;
  494. IECLINK_DEF *pt=(IECLINK_DEF *)g_tRsComm[i].ptBuf;
  495. if(pt == NULL)
  496. continue;
  497. pt->tlnk.brst=true;
  498. for(j=0;j<pt->slave_num;j++)
  499. {
  500. pt->tsla[j].tlnksave.brst=true;
  501. }
  502. }
  503. }
  504. }
  505. void lnk_update_time_all(void)
  506. {
  507. int i;
  508. for(i=0; i<CFG_LINK_104_NUM; i++)
  509. {
  510. g_link_104[i].tlnk.bSetTime = true;
  511. }
  512. for(i=0; i<CFG_LINK_101_NUM; i++)
  513. {
  514. if(tRunPara.tUartPara[i].wProtocol == PROTOCOL_101_M||tRunPara.tUartPara[i].wProtocol == PROTOCOL_101_PH_M)
  515. {
  516. int j;
  517. IECLINK_DEF *pt=(IECLINK_DEF *)g_tRsComm[i].ptBuf;
  518. if(pt == NULL)
  519. continue;
  520. for(j=0;j<pt->slave_num;j++)
  521. {
  522. pt->tsla[j].tlnksave.bSetTime=true;
  523. }
  524. pt->tlnk.bSetTime = true;
  525. }
  526. }
  527. }
  528. void lnk_slave_yx(u8 ch,u8 ti,u8 vsq,u8 cot,u8 al,u8 *ps)
  529. {
  530. u8 num=(vsq&0x7f);
  531. u8 ngd=(vsq&0x80);
  532. u8 v;
  533. u16 cp;
  534. int i;
  535. LINK_TABLE * lt;
  536. //struct di_table *dt;
  537. // 获取首地址
  538. cp =(ps[0]+(ps[1]<<8));
  539. ps+=al;
  540. // 循环处理每个数据
  541. for(i=0;i<num;i++)
  542. {
  543. // 获取值,如果是单点,转化为双点保存
  544. v=*ps++;
  545. if(ti==1)
  546. {
  547. v+=1;
  548. }
  549. // 查找点表,如果找到,保存。
  550. lt = tbl_link_di(ch,cp);
  551. if(lt)
  552. {
  553. sw_di_set(lt->owner,lt->indexno,v);
  554. }
  555. // 根据ngd修正后续地址
  556. if(ngd)
  557. {
  558. cp++;
  559. }
  560. else
  561. {
  562. cp=(ps[0]+(ps[1]<<8));
  563. ps+=al;
  564. }
  565. }
  566. }
  567. void lnk_find_yx_iec_no(u8 ch, u8 *ps)// 寻找级联点号对应的点表中点号,并替换
  568. {
  569. int i;
  570. u16 di;
  571. di=ps[0]+(ps[1]<<8);
  572. for(i=0;i<g_table_head->di_num;i++)
  573. {
  574. if(g_di_table[i].link_ch!=0)
  575. {
  576. if((g_di_table[i].link_cp==di) && (g_di_table[i].link_ch == ch)) // 级联点号有对应的点表值
  577. {
  578. ps[0]=(u8)g_di_table[i].cp;
  579. ps[1]=(u8)(g_di_table[i].cp>>8);
  580. //rt_printf("\r\n yx %04x-->%04x",g_di_table[i].cp,di);
  581. break;
  582. }
  583. }
  584. }
  585. }
  586. void lnk_find_yc_iec_no(u8 ch, u8 *ps,u8 baddr3,u8 yc_type)// 寻找级联点号对应的点表中点号,并替换
  587. {
  588. int i;
  589. u16 di;
  590. di=ps[0]+(ps[1]<<8);
  591. for(i=0;i<g_table_head->ac_num;i++)
  592. {
  593. if(g_ac_table[i].link_ch!=0)
  594. {
  595. if((g_ac_table[i].link_cp==di) && (g_ac_table[i].link_ch == ch)) // 级联点号有对应的点表值
  596. {
  597. ps[0]=(u8)g_ac_table[i].cp;
  598. ps[1]=(u8)(g_ac_table[i].cp>>8);
  599. if(pRunSet->bTT_EV_YCRate)
  600. {
  601. union{
  602. float ff;
  603. u8 tt[4];
  604. }ff;
  605. u8 *pdat;
  606. u16 v=0;
  607. pdat = &ps[2];
  608. if(baddr3) pdat = &ps[3];
  609. if(yc_type == 13)
  610. {
  611. #ifdef MODE_LITTLE_ENDIAN
  612. ff.tt[0]=pdat[0];
  613. ff.tt[1]=pdat[1];
  614. ff.tt[2]=pdat[2];
  615. ff.tt[3]=pdat[3];
  616. #else
  617. ff.tt[3]=pdat[0];
  618. ff.tt[2]=pdat[1];
  619. ff.tt[1]=pdat[2];
  620. ff.tt[0]=pdat[3];
  621. #endif
  622. }
  623. else
  624. {
  625. ff.ff = pdat[0] + (pdat[1]<<8);
  626. }
  627. rt_printf("fault_yc_two::%f\r\n",ff.ff);
  628. ff.ff *= ((float)g_ac_table[i].rate/65536.0); //系数转换
  629. v = ff.ff;
  630. rt_printf("fault_yc_one::%f\r\n",ff.ff);
  631. if(yc_type == 13)
  632. {
  633. #ifdef MODE_LITTLE_ENDIAN
  634. pdat[0] = ff.tt[0];
  635. pdat[1] = ff.tt[1];
  636. pdat[2] = ff.tt[2];
  637. pdat[3] = ff.tt[3];
  638. #else
  639. pdat[0] = ff.tt[3];
  640. pdat[1] = ff.tt[2];
  641. pdat[2] = ff.tt[1];
  642. pdat[3] = ff.tt[0];
  643. #endif
  644. }
  645. else
  646. {
  647. pdat[0] = (u8)v;
  648. pdat[1] = (u8)(v>>8);
  649. }
  650. }
  651. //rt_printf("\r\n yc %04x-->%04x",g_ac_table[i].cp,di);
  652. break;
  653. }
  654. }
  655. }
  656. }
  657. int EventInfoAddr101_to_104(BYTE *frame,BYTE *pbuf)
  658. {
  659. int len;
  660. int yc_num,yc_type;
  661. int i,buf_pos=0,frame_pos=0;
  662. memcpy(pbuf,frame,4);
  663. buf_pos += 4;
  664. frame_pos += 4;
  665. memcpy(&pbuf[buf_pos],&frame[frame_pos],8);
  666. buf_pos += 8;
  667. frame_pos += 8;
  668. yc_num = frame[frame_pos];
  669. yc_type = frame[frame_pos+1];
  670. memcpy(&pbuf[buf_pos],&frame[frame_pos],2);
  671. buf_pos += 2;
  672. frame_pos += 2;
  673. for(i=0;i<yc_num;i++){
  674. memcpy(&pbuf[buf_pos],&frame[frame_pos],2);
  675. buf_pos += 2;
  676. frame_pos += 2;
  677. pbuf[buf_pos++] = 0; //信息体地址
  678. if(yc_type == 0x0D){
  679. len = 4;
  680. }else{
  681. len = 2;
  682. }
  683. memcpy(&pbuf[buf_pos],&frame[frame_pos],len);
  684. buf_pos += len;
  685. frame_pos += len;
  686. }
  687. return buf_pos;
  688. }
  689. int EventInfoAddr104_to_101(BYTE *frame,BYTE *pbuf)
  690. {
  691. int len;
  692. int yc_num,yc_type;
  693. int i,buf_pos=0,frame_pos=0;
  694. memcpy(pbuf,frame,4);
  695. buf_pos += 4;
  696. frame_pos += 4;
  697. memcpy(&pbuf[buf_pos],&frame[frame_pos],8);
  698. buf_pos += 8;
  699. frame_pos += 8;
  700. yc_num = frame[frame_pos];
  701. yc_type = frame[frame_pos+1];
  702. memcpy(&pbuf[buf_pos],&frame[frame_pos],2);
  703. buf_pos += 2;
  704. frame_pos += 2;
  705. for(i=0;i<yc_num;i++){
  706. memcpy(&pbuf[buf_pos],&frame[frame_pos],2);
  707. buf_pos += 2;
  708. frame_pos += 2;
  709. frame_pos++; //信息体地址
  710. if(yc_type == 0x0D){
  711. len = 4;
  712. }else{
  713. len = 2;
  714. }
  715. memcpy(&pbuf[buf_pos],&frame[frame_pos],len);
  716. buf_pos += len;
  717. frame_pos += len;
  718. }
  719. return buf_pos;
  720. }
  721. void lnk_slave_fault(u8 ch,u8 len,u8 *ps, bool b104)
  722. {
  723. int i;
  724. int num;
  725. u8 yctype;
  726. u8 *pdat;
  727. int frame_len;
  728. BYTE tmp_buf[256];
  729. pdat=ps;
  730. if(len>=IEC_FAULT_FRAMELEN-1)return;
  731. num=pdat[0];
  732. pdat+=2;
  733. for(i=0;i<num;i++) // ps[0] 遥信个数
  734. {
  735. lnk_find_yx_iec_no(ch, &pdat[0]);
  736. pdat+=10;
  737. }
  738. num=pdat[0];
  739. yctype=pdat[1];
  740. pdat+=2;
  741. for(i=0;i<num;i++) // ps[0] 遥测个数
  742. {
  743. lnk_find_yc_iec_no(ch, &pdat[0],b104,yctype);
  744. if(b104)
  745. {
  746. if(yctype==13) //浮点值四个字节
  747. {
  748. pdat+=7;
  749. }
  750. else
  751. {
  752. pdat+=5;
  753. }
  754. }
  755. else
  756. {
  757. if(yctype==13) //浮点值四个字节
  758. {
  759. pdat+=6;
  760. }
  761. else
  762. {
  763. pdat+=4;
  764. }
  765. }
  766. }
  767. for(i=0;i<CFG_UART_NUM_MAX;i++)
  768. {
  769. if(tRunPara.tUartPara[i].wProtocol==PROTOCOL_101||tRunPara.tUartPara[i].wProtocol==PROTOCOL_101_PH) //子站规约
  770. {
  771. IEC101_DEF *pt=(IEC101_DEF *)g_tRsComm[i].ptBuf;
  772. if(b104)
  773. {
  774. frame_len = EventInfoAddr104_to_101(ps,tmp_buf);
  775. if(frame_len > IEC_FAULT_FRAMELEN-1) continue;
  776. memcpy(&pt->tfault.data[pt->tfault.head][1],tmp_buf,frame_len);
  777. pt->tfault.data[pt->tfault.head][0]=frame_len;
  778. }
  779. else
  780. {
  781. memcpy(&pt->tfault.data[pt->tfault.head][1],ps,len);
  782. pt->tfault.data[pt->tfault.head][0]=len;
  783. }
  784. pt->tfault.head++;
  785. if(pt->tfault.head==pt->tfault.tail)
  786. {
  787. pt->tfault.tail++;
  788. }
  789. }
  790. }
  791. for(i=0;i<CFG_ETH_MAX_LOGIC;i++)
  792. {
  793. IEC104_DEF *pt;
  794. pt=&g_t104[i];
  795. if(b104 == false)
  796. {
  797. frame_len = EventInfoAddr101_to_104(ps,tmp_buf);
  798. if(frame_len > IEC_FAULT_FRAMELEN-1) continue;
  799. memcpy(&pt->tfault.data[pt->tfault.head][1],tmp_buf,frame_len);
  800. pt->tfault.data[pt->tfault.head][0]=frame_len;
  801. }
  802. else
  803. {
  804. memcpy(&pt->tfault.data[pt->tfault.head][1],ps,len);
  805. pt->tfault.data[pt->tfault.head][0]=len;
  806. }
  807. rt_printf("\r\n fault lenth=%d head=%d",len,pt->tfault.head);
  808. pt->tfault.head++;
  809. if(pt->tfault.head==pt->tfault.tail)
  810. {
  811. pt->tfault.tail++;
  812. }
  813. }
  814. }
  815. //
  816. void lnk_slave_yc(u8 ch,u8 ti,u8 vsq,u8 al,u8 *ps)
  817. {
  818. u8 num=(vsq&0x7f);
  819. u8 ngd=(vsq&0x80);
  820. u16 cp;
  821. int i;
  822. LINK_TABLE * lt;
  823. struct ac_table *at;
  824. u8 ycQDS=0;
  825. qs16 v;
  826. #ifndef MODE_LITTLE_ENDIAN
  827. u8 ycval[4];
  828. #endif
  829. // 获取首地址
  830. cp=(ps[0]+(ps[1]<<8));
  831. ps+=al;
  832. // 循环处理每个数据
  833. for(i=0;i<num;i++)
  834. {
  835. // 根据类型,将遥测转换为qs16格式的值。
  836. if(ti==13)
  837. {
  838. // 浮点
  839. #ifdef MODE_LITTLE_ENDIAN
  840. union
  841. {
  842. u8 arr[4];
  843. float fval;
  844. }tmpyc;
  845. tmpyc.arr[0] = *ps++;
  846. tmpyc.arr[1] = *ps++;
  847. tmpyc.arr[2] = *ps++;
  848. tmpyc.arr[3] = *ps++;
  849. v = (qs16)(tmpyc.fval*Q16_BASE);
  850. #else
  851. ycval[3]=*ps++;
  852. ycval[2]=*ps++;
  853. ycval[1]=*ps++;
  854. ycval[0]=*ps++;
  855. v = *(float *)ycval*Q16_BASE;
  856. #endif
  857. }
  858. else
  859. {
  860. //归一、标度
  861. v = (ps[0]<<16) | (ps[1]<<24);
  862. ps += 2;
  863. }
  864. // TODO:记录QDS,需后续处理
  865. if(ti != 21)
  866. {
  867. ycQDS=*ps++;
  868. }
  869. // 记录遥测值
  870. // rt_printf_time("ch=%d,cp=%04x,v=%s.\r\n",ch,cp,q16_to_str(v));
  871. lt = tbl_link_ac(ch,cp);
  872. if(lt)
  873. {
  874. at = &g_ac_table[lt->tbl_index];
  875. if(at->owner == 0)
  876. {
  877. g_sw_pub.ac_in[at->indexno-1] = v;
  878. }
  879. else
  880. {
  881. g_sw[at->owner-1].ac_in[at->indexno-1] = v;
  882. g_sw[at->owner-1].link_qds[at->indexno-1] = ycQDS;
  883. }
  884. }
  885. // 根据ngd修正后续地址
  886. if(ngd)
  887. {
  888. cp++;
  889. }
  890. else
  891. {
  892. cp=(ps[0]+(ps[1]<<8));
  893. ps+=al;
  894. }
  895. }
  896. }
  897. //
  898. void lnk_slave_dd(u8 ch,u8 ti,u8 vsq,u8 cot,u8 al,u8 *ps)
  899. {
  900. u8 num=(vsq&0x7f);
  901. u8 ngd=(vsq&0x80);
  902. u16 cp;
  903. int i;
  904. LINK_TABLE * lt;
  905. struct dd_table *dt;
  906. struct rtc_time_t ct;
  907. u8 QDS;
  908. bool bchange=false;
  909. float v;
  910. #ifndef MODE_LITTLE_ENDIAN
  911. u8 ycval[4];
  912. #endif
  913. // 获取首地址
  914. cp=(ps[0]+(ps[1]<<8));
  915. ps+=al;
  916. // 循环处理每个数据
  917. for(i=0;i<num;i++)
  918. {
  919. #ifdef MODE_LITTLE_ENDIAN
  920. union
  921. {
  922. u8 arr[4];
  923. float fval;
  924. }tmpyc;
  925. tmpyc.arr[0] = *ps++;
  926. tmpyc.arr[1] = *ps++;
  927. tmpyc.arr[2] = *ps++;
  928. tmpyc.arr[3] = *ps++;
  929. v = tmpyc.fval;
  930. #else
  931. ycval[3]=*ps++;
  932. ycval[2]=*ps++;
  933. ycval[1]=*ps++;
  934. ycval[0]=*ps++;
  935. v = *(float *)ycval;
  936. #endif
  937. QDS=*ps++;
  938. if(ti==207) // 带时标电度
  939. {
  940. ct.ms=ps[0]+(ps[1]<<8);
  941. ct.min=ps[2];
  942. ct.hour=ps[3];
  943. ct.day=ps[4];
  944. ct.month=ps[5];
  945. ct.year=ps[6];
  946. ps+=7;
  947. if(cot==3) //突发上送
  948. {
  949. bchange=true;
  950. }
  951. }
  952. else
  953. {
  954. ct.ms=0;
  955. ct.ms=0;
  956. ct.min=0;
  957. ct.hour=0;
  958. ct.day=0;
  959. ct.month=0;
  960. ct.year=0;
  961. bchange=false;
  962. }
  963. // 记录遥测值
  964. // rt_printf_time("ch=%d,cp=%04x,v=%.4f.\r\n",ch,cp,v);
  965. lt = tbl_link_dd(ch,cp);
  966. if(lt)
  967. {
  968. dt = &g_dd_table[lt->tbl_index];
  969. if ((dt->owner > 0)
  970. #ifdef METERING_ENERGY
  971. && (pRunSet->dd_calc_mode == 2)
  972. #endif
  973. )
  974. {
  975. #ifdef M_IT_TC
  976. int j=0;
  977. if(bchange)//级联突发上送
  978. {
  979. for(j=0;j<CFG_UART_NUM_MAX;j++)
  980. {
  981. g_sw[dt->owner-1].dd[dt->indexno-1].bsend101[j] = true;
  982. }
  983. for(j=0;j<CFG_ETH_MAX_LOGIC;j++)
  984. {
  985. g_sw[dt->owner-1].dd[dt->indexno-1].bsend104[j] = true;
  986. }
  987. }
  988. #endif
  989. g_sw[dt->owner-1].dd[dt->indexno-1].fv= v;
  990. g_sw[dt->owner-1].dd[dt->indexno-1].ct= ct;
  991. g_sw[dt->owner-1].dd[dt->indexno-1].bchanged= bchange;
  992. // 记录遥测值
  993. //rt_printf_time("owner=%d,index=%04x,v=%.4f.\r\n",dt->owner-1,dt->indexno,v);
  994. }
  995. }
  996. // 根据ngd修正后续地址
  997. if(ngd)
  998. {
  999. cp++;
  1000. }
  1001. else
  1002. {
  1003. cp=(ps[0]+(ps[1]<<8));
  1004. ps+=al;
  1005. }
  1006. }
  1007. }
  1008. void lnk_slave_soe(IECLINK_DEF *pt,u8 ch,u8 ti,u8 vsq,u8 al,u8 *ps)
  1009. {
  1010. u8 num=(vsq&0x7f);
  1011. u8 ngd=(vsq&0x80);
  1012. u8 v;
  1013. u16 cp;
  1014. int i;
  1015. LINK_TABLE * lt;
  1016. // struct di_table *dt;
  1017. struct rtc_time_t rt;
  1018. struct timespec ts;
  1019. // 获取首地址
  1020. cp=(ps[0]+(ps[1]<<8));
  1021. ps+=al;
  1022. // 循环处理每个数据
  1023. for(i=0;i<num;i++)
  1024. {
  1025. // 获取值,如果是单点,转化为双点保存
  1026. v=*ps++;
  1027. if(ti==30)
  1028. {
  1029. v+=1;
  1030. }
  1031. // 获取时间
  1032. rt.ms = *ps++;
  1033. rt.ms |= (*ps++)<<8;
  1034. rt.min = *ps++;
  1035. rt.hour = *ps++;
  1036. rt.day = ((*ps++)&0x1f);
  1037. rt.month= *ps++;
  1038. rt.year = *ps++;
  1039. #ifdef FUN_YPARA_CFG_NOTY
  1040. if(cp == 0x8001) /*参数变化,特殊soe*/
  1041. {
  1042. if(v == 2)
  1043. {
  1044. set_read_all(pt);
  1045. if(soe_check(EV_PARA_CHG)==false) //
  1046. {
  1047. soe_record_ev(EV_PARA_CHG, 1, 0,0,0 );
  1048. }
  1049. dTpartime = ustimer_get_origin();
  1050. }
  1051. }
  1052. #endif
  1053. // 查找点表,如果找到,保存。
  1054. lt = tbl_link_di(ch,cp);
  1055. if(lt)
  1056. {
  1057. //dt = &g_di_table[lt->tbl_index];
  1058. sw_di_set(lt->owner,lt->indexno,v);
  1059. rtc_to_timespec(&rt,&ts);
  1060. v = lt->is_inverse ? ((~v)&0x03) : v;
  1061. soe_record_lnk(lt->cp ,v,&ts,(s32)lt,lt->is_mix,lt->cp_s);
  1062. }
  1063. // 根据ngd修正后续地址
  1064. if(ngd)
  1065. {
  1066. cp++;
  1067. }
  1068. else
  1069. {
  1070. cp=(ps[0]+(ps[1]<<8));
  1071. ps+=al;
  1072. }
  1073. }
  1074. }
  1075. extern u8 get_par_link_data(BYTE *out,BYTE *in,BYTE parNum,u8 ti);//test
  1076. void lnk_slave_par(u8 ch,u8 ti,u8 cot,u8 al,u8 *ps,u8 vsq)
  1077. {
  1078. u8 ti_m=ti;
  1079. u8 v,yktype;
  1080. u16 cp;
  1081. LINK_TABLE * lt;
  1082. //struct do_table *dt;
  1083. LINKPAR_DEF *par;
  1084. u8 *pbuf=ps;
  1085. int i;
  1086. // 获取地址和值
  1087. cp=(ps[0]+(ps[1]<<8));
  1088. ps+=al;
  1089. v=*ps++;
  1090. // 查找点表,如果找到,保存。
  1091. lt = tbl_link_do(ch,cp);
  1092. lt = &g_lt_do[1];
  1093. #ifdef YC_QUANTITY
  1094. rt_printf("\r\nch=%02x parAddr=%02x vsq=%d\r\n",(ch>>4),cp-(pRunSet->dYC_num*((ch&0x0f)-1)),vsq);
  1095. cp=cp-(pRunSet->dYC_num*((ch&0x0f)-1)) ;//点表转换
  1096. #else
  1097. rt_printf("\r\nch=%02x parAddr=%02x vsq=%d\r\n",(ch>>4),cp-(FOS_PAR_SW_NUM*((ch&0x0f)-1)),vsq);
  1098. cp=cp-(FOS_PAR_SW_NUM*((ch&0x0f)-1)) ;//点表转换
  1099. #endif
  1100. for(i=0;i<SWITCH_NUM_EXT_PUB;i++)
  1101. {
  1102. #ifdef FUNC_MORE_PREREAD
  1103. if(g_link_par[i].flag[IECLINK_YK_SND] == false) continue;
  1104. #endif
  1105. //if((g_link_par[i].cp_s == cp||g_link_par[i].cp_s ==(pbuf[0]+(pbuf[1]<<8)) )&& g_link_par[i].data[IECLINK_YK_SND].ti==0xff)//当前sw归属对应点号有效
  1106. if((g_link_par[i].cp_s ==(pbuf[0]+(pbuf[1]<<8)) )&& g_link_par[i].data[IECLINK_YK_SND].ti==0xff)//当前sw归属对应点号有效
  1107. {
  1108. par = &g_link_par[i];
  1109. rt_printf("\r\n i=%x Ti=%02x ti_m=%02x cp_s%02x cp_m %02x chnl=%02x \r\n",i,g_link_par[i].data[IECLINK_YK_SND].ti,g_link_par[i].data[IECLINK_YK_SND].ti_m,g_link_par[i].cp_m,g_link_par[i].cp_s,g_link_par[i].cp_m,g_link_par[i].chnl);
  1110. #if 0// 由于有些从设备只发10,不发07,所以在10时将 07 10 报文同时发出。
  1111. if(cot == 10 && (par->data[IECLINK_YK_ACK].ti == 0))
  1112. {
  1113. yktype = IECLINK_YK_ACK;
  1114. par->data[yktype].ti=ti;
  1115. par->data[yktype].cot=7;
  1116. par->data[yktype].len=v;
  1117. par->flag[yktype] = true;
  1118. }
  1119. #endif
  1120. yktype = cot==10 ? IECLINK_YK_END : IECLINK_YK_ACK;
  1121. if(ti == FOS_PAR_SET_MUL_EXT)
  1122. {
  1123. ti_m = FOS_PAR_SET_MUL;
  1124. }
  1125. else if(ti == FOS_PAR_SET_ONE_EXT)
  1126. {
  1127. ti_m = FOS_PAR_SET_ONE;
  1128. }
  1129. else if(ti == FOS_PAR_READ_ONE_EXT)
  1130. {
  1131. ti_m = FOS_PAR_READ_ONE;
  1132. }
  1133. else if(ti == FOS_PAR_READ_MUL_EXT)
  1134. {
  1135. ti_m = FOS_PAR_READ_MUL;
  1136. }
  1137. par->data[yktype].ti=ti_m;
  1138. par->data[yktype].cot=cot;
  1139. par->data[yktype].len=1;
  1140. par->data[yktype].vsq=vsq;
  1141. //
  1142. if(al == 2)
  1143. {
  1144. par->data[yktype].len = get_par_link_data(&par->data[yktype].buf[0] ,pbuf,vsq, ti_m);
  1145. }
  1146. else
  1147. {
  1148. par->data[yktype].len = get_par_link_data_dz(&par->data[yktype].buf[0] ,pbuf,vsq, ti_m);
  1149. }
  1150. par->flag[yktype] = true;
  1151. rt_printf("级联遥参上行:(ch=%02x,cp_s=%04x,ti=%02x,cot=%02x,len=%02x yktype=%02x \r\n",ch,g_link_par[i].cp_s,ti_m,cot,par->data[yktype].len,yktype);
  1152. #ifdef FUNC_MORE_PREREAD
  1153. g_link_par[i].flag[IECLINK_YK_SND] = false;
  1154. #endif
  1155. return ;
  1156. }
  1157. }
  1158. rt_printf_time("lnk_slave_par:查找级联表失败 ch=%02x,cp=%04x.\r\n",ch,cp);
  1159. return ;
  1160. }
  1161. void lnk_slave_yk(u8 ch,u8 ti,u8 cot,u8 al,u8 *ps)
  1162. {
  1163. u8 v,yktype;
  1164. u16 cp;
  1165. LINK_TABLE * lt;
  1166. struct do_table *dt;
  1167. LINKYK_DEF *yk;
  1168. char buf[128];
  1169. // 获取地址和值
  1170. cp=(ps[0]+(ps[1]<<8));
  1171. ps+=al;
  1172. v=*ps++;
  1173. // 查找点表,如果找到,保存。
  1174. lt = tbl_link_do(ch,cp);
  1175. if(lt)
  1176. {
  1177. dt = &g_do_table[lt->tbl_index];
  1178. yk = &g_lnk_yk[dt->owner];
  1179. if(cp != yk->cp_s)
  1180. {
  1181. rt_printf_time("lnk_slave_yk err:cp=%04x,cp_s=%04x",cp,yk->cp_s);
  1182. return;
  1183. }
  1184. // 由于有些从设备只发10,不发07,所以在10时将 07 10 报文同时发出。
  1185. if(cot == 10 && (yk->data[IECLINK_YK_ACK].ti == 0))
  1186. {
  1187. yktype = IECLINK_YK_ACK;
  1188. yk->data[yktype].ti=ti;
  1189. yk->data[yktype].cot=7;
  1190. yk->data[yktype].v=v;
  1191. yk->flag[yktype] = true;
  1192. }
  1193. yktype = cot==10 ? IECLINK_YK_END : IECLINK_YK_ACK;
  1194. yk->data[yktype].ti=ti;
  1195. yk->data[yktype].cot=cot;
  1196. yk->data[yktype].v=v;
  1197. yk->flag[yktype] = true;
  1198. sprintf(buf,"级联遥控上行:(ch=%02x,cp_s=%04x,cp_m=%04x,ti=%02x,cot=%02x,v=%02x)",ch,lt->cp_s,dt->cp,ti,cot,v);
  1199. log_str_time(LOG_OPERATE,buf,0,0);
  1200. rt_printf_time("%s\r\n",buf);
  1201. }
  1202. else
  1203. {
  1204. rt_printf_time("lnk_slave_yk:查找级联表失败 ch=%d,cp=%04x.\r\n",ch,cp);
  1205. }
  1206. }
  1207. //定值参数&&... 数据级联转发
  1208. int lnk_master_par(struct do_table *pdt,u8 ti,u8 cot,u8 len,BYTE *datBuf,u8 vsq)
  1209. {
  1210. u8 yktype;
  1211. LINKPAR_DEF * par;
  1212. char buf[128];
  1213. u32 *par_send_flag;
  1214. // 获取对应通道的结构,获取失败,直接返回
  1215. par_send_flag = lnk_get_ch_par_head(pdt->link_ch);
  1216. if(par_send_flag == 0)
  1217. {
  1218. sprintf(buf,"级联:未找到从设备通道(cp=%04x,link_ch=%02x,link_cp=%04x)",pdt->cp,pdt->link_ch,pdt->link_cp);
  1219. log_str_time(LOG_OPERATE,buf,0,0);
  1220. rt_printf_time("%s\r\n",buf);
  1221. return -1;
  1222. }
  1223. #ifdef FUNC_MORE_PREREAD
  1224. par = &g_link_par[g_link_par_cnt];
  1225. *par_send_flag |= 1<<g_link_par_cnt;
  1226. #else
  1227. *par_send_flag |= (1<<pdt->owner);
  1228. par = &g_link_par[pdt->owner];
  1229. #endif
  1230. // 清对应数据结构
  1231. memset(par,0,sizeof(g_link_par[0]));
  1232. // 赋值
  1233. yktype = IECLINK_YK_SND;
  1234. par->data[yktype].ti=0xff;//???
  1235. par->data[yktype].vsq=vsq;
  1236. par->data[yktype].cot=cot;
  1237. par->data[yktype].len=len;
  1238. memcpy(par->data[yktype].buf,datBuf,len);
  1239. par->cp_m=pdt->cp;
  1240. par->cp_s=pdt->link_cp;
  1241. par->chnl=pdt->link_ch;
  1242. par->flag[yktype] = true;
  1243. //*par_send_flag |= (1<<pdt->owner);
  1244. par->data[yktype].ti_m = ti;
  1245. // 记录日志
  1246. sprintf(buf,"级联遥参下行:(cp=%04x,link_ch=%02x,link_cp=%04x,ti=%02x,cot=%02x,len=%02x ,ti_m=%02x)",pdt->cp,pdt->link_ch,pdt->link_cp,ti,cot,len,par->data[yktype].ti_m);
  1247. log_str_time(LOG_OPERATE,buf,0,0);
  1248. rt_printf_time("%s\r\n",buf);
  1249. return 0;
  1250. }
  1251. int lnk_master_yk(struct do_table *pdt,u8 ti,u8 cot,u8 v)
  1252. {
  1253. u8 yktype;
  1254. LINKYK_DEF * yk;
  1255. char buf[128];
  1256. u32 *yk_send_flag;
  1257. // 获取对应通道的结构,获取失败,直接返回
  1258. yk_send_flag = lnk_get_ch_head(pdt->link_ch);
  1259. if(yk_send_flag == 0)
  1260. {
  1261. sprintf(buf,"级联遥控:未找到从设备通道(cp=%04x,link_ch=%02x,link_cp=%04x)",pdt->cp,pdt->link_ch,pdt->link_cp);
  1262. log_str_time(LOG_OPERATE,buf,0,0);
  1263. rt_printf_time("%s\r\n",buf);
  1264. return -1;
  1265. }
  1266. yk = &g_lnk_yk[pdt->owner];
  1267. // 清对应遥控数据结构
  1268. memset(yk,0,sizeof(g_lnk_yk[0]));
  1269. // 赋值
  1270. yktype = IECLINK_YK_SND;
  1271. yk->data[yktype].ti=ti;
  1272. yk->data[yktype].cot=cot;
  1273. yk->data[yktype].v=v;
  1274. yk->cp_m=pdt->cp;
  1275. yk->cp_s=pdt->link_cp;
  1276. yk->chnl=pdt->link_ch;
  1277. yk->flag[yktype] = true;
  1278. *yk_send_flag |= (1<<pdt->owner);
  1279. // 记录日志
  1280. sprintf(buf,"级联遥控下行:(cp=%04x,link_ch=%02x,link_cp=%04x,ti=%02x,cot=%02x,v=%02x)",pdt->cp,pdt->link_ch,pdt->link_cp,ti,cot,v);
  1281. log_str_time(LOG_OPERATE,buf,0,0);
  1282. rt_printf_time("%s\r\n",buf);
  1283. return 0;
  1284. }
  1285. void lnk_count_slaveaddr(IECLINK_DEF *pt,u8 chnl,LINK_TABLE* lt,u32 num)
  1286. {
  1287. u8 ch;
  1288. u8 addr=0;
  1289. int j;
  1290. for(j=0;j<num;j++)
  1291. {
  1292. ch=(u8)((lt->cp_s>>21)&0x0f);
  1293. addr=(u8)((lt->cp_s>>16)&0x1f);
  1294. if(addr>0&&(ch==chnl)) // 通道相符
  1295. {
  1296. if(pt->slave_num==0)
  1297. {
  1298. pt->tsla[pt->slave_num++].addr=addr;
  1299. }
  1300. else
  1301. {
  1302. int i;
  1303. for(i=0;i<pt->slave_num;i++) // 查找子站地址是否保存
  1304. {
  1305. if(addr==pt->tsla[i].addr)
  1306. {
  1307. break;
  1308. }
  1309. }
  1310. if(i==pt->slave_num)
  1311. {
  1312. pt->tsla[pt->slave_num++].addr=addr;
  1313. }
  1314. if(pt->slave_num>=32)pt->slave_num=31;
  1315. }
  1316. }
  1317. lt++;
  1318. }
  1319. }
  1320. int getstrval(char *buf)
  1321. {
  1322. char *str;
  1323. int val=0;
  1324. str=strchr(buf,'=');
  1325. if(str)
  1326. {
  1327. str++;
  1328. if(str[0]=='0'&&(str[1]=='x'||str[1]=='X'))
  1329. {
  1330. val=strtoul(str,NULL,16);
  1331. }
  1332. else
  1333. {
  1334. val=strtoul(str,NULL,10);
  1335. }
  1336. }
  1337. return val;
  1338. }
  1339. static void lnk_getcfg(IECLINK_DEF *pt,u8 *filestr,u8 *keystr)
  1340. {
  1341. u8 str[32],str1[32];
  1342. if(filestr[0]=='[') // 是规约类型
  1343. {
  1344. pt->bcfg=false;
  1345. sprintf(str,"[COM%d_%s]",pt->chnl,keystr);
  1346. sprintf(str1,"[%s_ALL]",keystr);
  1347. if(strcmp(filestr,str)==0||strcmp(filestr,str1)==0)
  1348. {
  1349. pt->bcfg=true;
  1350. }
  1351. return;
  1352. }
  1353. if(!pt->bcfg)return;
  1354. if(strstr(filestr,"appaddr")) // 遥信命令码
  1355. {
  1356. pt->b101App2Byte=(getstrval(filestr)==2)?true:false;
  1357. }
  1358. else if(strstr(filestr,"linkaddr")) //
  1359. {
  1360. pt->b101Addr2Byte=(getstrval(filestr)==2)?true:false;
  1361. }
  1362. else if(strstr(filestr,"cotaddr")) //
  1363. {
  1364. pt->b101Cot2Byte=(getstrval(filestr)==2)?true:false;
  1365. }
  1366. else if(strstr(filestr,"callalltime")) //
  1367. {
  1368. pt->callalltime=getstrval(filestr)*SAM_FREQUENCY; // 单位秒,转为dTcounter 值
  1369. }
  1370. else if(strstr(filestr,"retrytime")) //
  1371. {
  1372. pt->retrytime=getstrval(filestr)*SAM_FREQUENCY; // 单位秒,转为dTcounter 值
  1373. }
  1374. else if(strstr(filestr,"sendinteraltime")) //
  1375. {
  1376. pt->sendinteraltime=getstrval(filestr)*SAMFREQ/20; // 单位毫秒,转为dTcounter值
  1377. }
  1378. else if(strstr(filestr,"lb_master_en"))
  1379. {
  1380. pt->b_lb_master = getstrval(filestr);
  1381. }
  1382. else
  1383. {
  1384. return;
  1385. }
  1386. }
  1387. static int lnk_init_cfg(IECLINK_DEF *pt,u8 *keystr)
  1388. {
  1389. u32 i,file_length;
  1390. struct file * pfile;
  1391. u8 *filebuf;
  1392. u8 filestr[128],*pstr,strlenth;
  1393. loff_t pos;
  1394. // 打开文件
  1395. pt->callalltime=SAM_FREQUENCY*15;
  1396. pt->retrytime=SAM_FREQUENCY*5;
  1397. pt->sendinteraltime=T_100ms;
  1398. rt_printf("\r\n%s:%d 级联参数初始化\r\n",keystr,pt->chnl);
  1399. pfile = rt_file_open("/app/data/pcolcfg.ini",O_RDONLY ,0);
  1400. if(IS_ERR(pfile))
  1401. {
  1402. dp_err_n_c_rt("\r\nerror! 无法打开 pcolcfg.ini");
  1403. return -1;
  1404. }
  1405. // 得到文件长度
  1406. file_length = rt_file_getfile_size(pfile);
  1407. if(file_length <= 0)
  1408. {
  1409. rt_file_close(pfile,0);
  1410. return -2;
  1411. }
  1412. // 分配内存
  1413. filebuf = rt_malloc(file_length);
  1414. if((filebuf) == NULL)
  1415. {
  1416. rt_file_close(pfile,0);
  1417. return -3;
  1418. }
  1419. pos = 0;
  1420. if(rt_file_read(pfile,filebuf,file_length,&pos) != file_length)
  1421. {
  1422. rt_file_close(pfile,0);
  1423. rt_free(filebuf);
  1424. return -4;
  1425. }
  1426. pstr = filestr;
  1427. strlenth=0; // 纠错处理
  1428. //找到\r\n位置,得到一行长度
  1429. for(i = 0; i < file_length; i++)
  1430. {
  1431. *pstr++=filebuf[i];
  1432. strlenth++;
  1433. if(filebuf[i] == 0x0a||strlenth>=128)
  1434. {
  1435. int j;
  1436. pstr = filestr;
  1437. for(j=0;j<strlenth;j++)
  1438. {
  1439. if(*pstr==' '||*pstr=='\t') // 取空格或tab 前的字符
  1440. {
  1441. *pstr='\0';
  1442. break;
  1443. }
  1444. pstr++;
  1445. }
  1446. *pstr='\0';
  1447. lnk_getcfg(pt,filestr,keystr);
  1448. pstr=filestr;
  1449. strlenth=0;
  1450. }
  1451. }
  1452. rt_file_close(pfile,0); // 关闭文件
  1453. rt_free(filebuf); // 释放内存
  1454. return 0;
  1455. }
  1456. void lnk_101_init(IECLINK_DEF *pt,u8 chnl,bool bPH)
  1457. {
  1458. int i;
  1459. LNK_STATUS *ptlnk=&pt->tlnk;
  1460. memset(pt,0,sizeof(IECLINK_DEF));
  1461. pt->type=IEC101_CHN;
  1462. pt->chnl=chnl;
  1463. pt->sendbuf=g_tRsComm[chnl].sendbuf;
  1464. pt->bPH101=bPH;
  1465. // 初始化状态
  1466. ptlnk->bLinkOK=false;
  1467. ptlnk->bCallLnk=true;
  1468. ptlnk->dTMWait=dTCounter;
  1469. ptlnk->dTInteral=dTCounter;
  1470. ptlnk->dTCallAllTime=dTCounter;
  1471. ptlnk->dTSendTime=dTCounter;
  1472. pt->slave_num=0;
  1473. pt->slave_current=0;
  1474. lnk_init_cfg(pt,"IEC101_LNK");
  1475. lnk_count_slaveaddr(pt,chnl+2,&g_lt_di[0],g_lt_di_num);
  1476. lnk_count_slaveaddr(pt,chnl+2,&g_lt_ac[0],g_lt_ac_num);
  1477. lnk_count_slaveaddr(pt,chnl+2,&g_lt_dd[0],g_lt_dd_num);
  1478. lnk_count_slaveaddr(pt,chnl+2,&g_lt_do[0],g_lt_do_num);
  1479. //rintf("port[%d]------101装置数量:%d\r\n",chnl,pt->slave_num);
  1480. #ifdef RCD_STRAN_M
  1481. queue_init(&pt->rcd_m.queue,NEWRCD_COUNT_M,&pt->rcd_m.data,NEWRCD_SIZE_M);
  1482. #endif
  1483. #ifdef YPARA_LINK
  1484. queue_init(&pt->par_queue.queue,PAR_COUNT_M,&pt->par_queue.data,PAR_SIZE_M);
  1485. rt_printf("-----PAR_SIZE_M=%d\r\n",PAR_SIZE_M);
  1486. #endif
  1487. // 判断 装置是否有电度
  1488. for(i=0;i<pt->slave_num;i++)
  1489. {
  1490. int j;
  1491. pt->tsla[i].bDdValid=false;
  1492. for(j=0;j<g_lt_dd_num;j++)
  1493. {
  1494. if(((WORD)((g_lt_dd[j].cp_s>>16)&0x1f))==pt->tsla[i].addr)
  1495. {
  1496. pt->tsla[i].bDdValid=true;
  1497. }
  1498. }
  1499. }
  1500. for(i=0; i<pt->slave_num;i++)
  1501. {
  1502. // 初始化状态
  1503. pt->tsla[i].tlnksave.bLinkOK=false;
  1504. pt->tsla[i].tlnksave.bCallLnk=true;
  1505. pt->tsla[i].tlnksave.dTMWait=dTCounter;
  1506. pt->tsla[i].tlnksave.dTInteral=dTCounter;
  1507. pt->tsla[i].tlnksave.dTCallAllTime=dTCounter;
  1508. pt->tsla[i].tlnksave.dTSendTime=dTCounter;
  1509. }
  1510. pt->slave_addr=pt->tsla[0].addr;
  1511. }
  1512. void lnk_101_send(IECLINK_DEF *pt)
  1513. {
  1514. RS_Send_Enable(pt->chnl);
  1515. g_tRsComm[pt->chnl].nSendCnt=1; // 发送缓冲区的第一个字节为发送长度
  1516. g_tRsComm[pt->chnl].bSend=true;
  1517. if(g_print_lnk && (g_print_port & (1<<pt->chnl)))
  1518. {
  1519. char tmpstr[24];
  1520. sprintf(tmpstr,"TL_101(%d):",pt->chnl);
  1521. print_msg(tmpstr,&g_tRsComm[pt->chnl].sendbuf[1],g_tRsComm[pt->chnl].sendbuf[0]);
  1522. }
  1523. }
  1524. static void lnk_101_call_fixed(IECLINK_DEF *pt,unsigned char zone,bool bFCV)
  1525. {
  1526. u8 *pd=pt->sendbuf;
  1527. LNK_STATUS *ptlnk=&pt->tlnk;
  1528. if(bFCV)
  1529. {
  1530. IEC101_SETFCV(zone);
  1531. if(ptlnk->bMFCB)
  1532. {
  1533. IEC101_SETFCB(zone);
  1534. }
  1535. else
  1536. {
  1537. IEC101_CLRFCB(zone);
  1538. }
  1539. }
  1540. if(!pt->b101Addr2Byte)
  1541. {
  1542. pd[0]=5;
  1543. pd[1]=0x10;
  1544. pd[2]=zone;
  1545. pd[3]=(u8)pt->slave_addr;
  1546. pd[4]=pd[2]+pd[3];
  1547. pd[5]=0x16;
  1548. }
  1549. else
  1550. {
  1551. pd[0]=6;
  1552. pd[1]=0x10;
  1553. pd[2]=zone;
  1554. pd[3]=(u8)pt->slave_addr;
  1555. pd[4]=(u8)(pt->slave_addr>>8);
  1556. pd[5]=pd[2]+pd[3]+pd[4];
  1557. pd[6]=0x16;
  1558. }
  1559. }
  1560. static void lnk_101_call(IECLINK_DEF *pt, u8 type,u8 ngd,u8 cot,u8 *pdat,u8 len)
  1561. {
  1562. u8 *pd;
  1563. u8 cnt,checksum;
  1564. u8 zone=0x53;
  1565. u8 tmplen;
  1566. LNK_STATUS *ptlnk=&pt->tlnk;
  1567. tmplen=len+6;
  1568. // 报文长度调整变量赋值
  1569. if(pt->b101Addr2Byte) tmplen++;
  1570. if(pt->b101Cot2Byte) tmplen++;
  1571. if(pt->b101App2Byte) tmplen++;
  1572. if(ptlnk->bMFCB)
  1573. {
  1574. IEC101_SETFCB(zone);
  1575. }
  1576. else
  1577. {
  1578. IEC101_CLRFCB(zone);
  1579. }
  1580. pd=pt->sendbuf;
  1581. *pd++=tmplen+6;
  1582. *pd++=0x68;
  1583. *pd++=tmplen;
  1584. *pd++=tmplen;
  1585. *pd++=0x68;
  1586. *pd++=zone;
  1587. *pd++=(u8)pt->slave_addr; //链路地址1
  1588. if(pt->b101Addr2Byte)
  1589. {
  1590. *pd++=(u8)(pt->slave_addr>>8); //链路地址2
  1591. }
  1592. *pd++=type; //帧类型
  1593. *pd++=ngd; //VSQ
  1594. *pd++=cot; //传送原因
  1595. if(pt->b101Cot2Byte)
  1596. {
  1597. *pd++=0; //传送原因2
  1598. }
  1599. *pd++=(u8)pt->slave_addr; //应用服务单元地址1
  1600. if(pt->b101App2Byte)
  1601. {
  1602. *pd++=(u8)(pt->slave_addr>>8); //应用服务单元地址2
  1603. }
  1604. for(cnt=0;cnt<len;cnt++) //标示拷贝
  1605. {
  1606. *pd++=*pdat++;
  1607. }
  1608. checksum=0;
  1609. pd=&pt->sendbuf[5];
  1610. for(cnt=0;cnt<tmplen;cnt++) //标示拷贝
  1611. {
  1612. checksum+=*pd++;
  1613. }
  1614. *pd++=checksum;
  1615. *pd++=0x16;
  1616. }
  1617. #ifdef FUN_YPARA_CFG_NOTY
  1618. void lnk_para_chg(IECLINK_DEF *pt,u8 chnl,u8 vsq,u8 cot,u8 *ps,bool b104)
  1619. {
  1620. int i =0,j=0;
  1621. u8 num=0;
  1622. u8 off=0;
  1623. u16 link_cp=0;
  1624. int index=0;
  1625. para_chg_single single;
  1626. struct rtc_time_t ct;
  1627. union{
  1628. float ff;
  1629. BYTE tt[4];
  1630. }ff;
  1631. num=(vsq&0x7f);
  1632. memset(&single,0,sizeof(para_chg_single));
  1633. for(i=0;i<num;i++)
  1634. {
  1635. /*点号*/
  1636. link_cp=(ps[off]+(ps[off+1]<<8));
  1637. off += 2;
  1638. if(b104) off +=1;
  1639. /*值*/
  1640. ff.tt[3] = ps[off++];
  1641. ff.tt[2] = ps[off++];
  1642. ff.tt[1] = ps[off++];
  1643. ff.tt[0] = ps[off++];
  1644. /*时标*/
  1645. ct.ms=ps[off]+(ps[off+1]<<8);
  1646. ct.min=ps[off+2];
  1647. ct.hour=ps[off+3];
  1648. ct.day=ps[off+4];
  1649. ct.month=ps[off+5];
  1650. ct.year=ps[off+6];
  1651. off += 7;
  1652. index = get_index_link(chnl,link_cp);
  1653. if(index < 0)
  1654. {
  1655. rt_printf("lnk_para_chg fail:chnl=0x%x,di=0x%x\r\n",chnl,link_cp);
  1656. continue;
  1657. }
  1658. single.ct = ct;
  1659. single.parId = tParaID[index].parId;
  1660. single.val = ff.ff;
  1661. for(j=0;j<COMM_CHANNEL_NUM;j++)
  1662. {
  1663. add_data_queque(&g_para_chg_queque[j].queue,(u8 *)&single,OVER_QUEUE);
  1664. }
  1665. }
  1666. }
  1667. #endif
  1668. #ifdef RCD_STRAN_M
  1669. bool lnk_qaddr_check(IECLINK_DEF *pt)
  1670. {
  1671. u32 pos=0;
  1672. QTYPE *queue;
  1673. newrcd_m_struct data;
  1674. queue = &pt->rcd_m.queue;
  1675. if(queue->count == 0) return 0; /*无数据*/
  1676. pos = queue->front * queue->s_size;
  1677. memcpy(&data, &queue->data[pos], queue->s_size);
  1678. if(data.addr != pt->slave_addr)
  1679. {
  1680. return 0;
  1681. }
  1682. else
  1683. {
  1684. return 1;
  1685. }
  1686. }
  1687. void lnk_rcdfile_check_104(IECLINK_DEF *pt)
  1688. {
  1689. char tmp[100];
  1690. newrcd_m_struct data;
  1691. if(pt->tft.bTransing == false) /*为该地址并且,没有文件在传输*/
  1692. {
  1693. if(get_queue_count(&pt->rcd_m.queue) > 0)
  1694. {
  1695. get_data_queque(&pt->rcd_m.queue,(u8 *)&data);
  1696. strncpy(pt->tft.filename,data.filename,sizeof(pt->tft.filename));
  1697. pt->tft.fnamelen=strlen(pt->tft.filename);
  1698. pt->tft.bFile=true;
  1699. pt->tft.bTransing = true; /*启动传输*/
  1700. pt->tft.addr = pt->slave_addr; /*启动传输*/
  1701. pt->tft.us0_file_trans = ustimer_get_origin();
  1702. sprintf(tmp, "BAY%02d%s文件传输启动!!!!!!!", pt->chnl+1,pt->tft.filename+5); /*104替换成级联通道号*/
  1703. log_str_time(LOG_OPERATE,tmp,0,1);
  1704. }
  1705. }
  1706. }
  1707. void lnk_rcdfile_check(IECLINK_DEF *pt)
  1708. {
  1709. char tmp[100];
  1710. newrcd_m_struct data;
  1711. if(lnk_qaddr_check(pt) && (pt->tft.bTransing == false)) /*为该地址并且,没有文件在传输*/
  1712. {
  1713. if(get_queue_count(&pt->rcd_m.queue) > 0)
  1714. {
  1715. get_data_queque(&pt->rcd_m.queue,(u8 *)&data);
  1716. strncpy(pt->tft.filename,data.filename,sizeof(pt->tft.filename));
  1717. pt->tft.fnamelen=strlen(pt->tft.filename);
  1718. pt->tft.bFile=true;
  1719. pt->tft.bTransing = true; /*启动传输*/
  1720. pt->tft.addr = pt->slave_addr; /*启动传输*/
  1721. sprintf(tmp, "%s传输启动!!!",pt->tft.filename);
  1722. log_str_time(LOG_OPERATE,tmp,0,1);
  1723. }
  1724. }
  1725. }
  1726. void lnk_rcdfile(IECLINK_DEF *pt,u8 *buf,u16 addr)
  1727. {
  1728. char namestr[64]={0};
  1729. u8 namelen=0,num=0;
  1730. s32 i=0,off=0;
  1731. newrcd_m_struct data;
  1732. //strncpy(pt->tfile_m.dirpath,RCD_DIR,sizeof(pt->tfile_m.dirpath)); /*默认目录名*/
  1733. num =buf[off++];
  1734. for(i=0;i<num;i++)
  1735. {
  1736. namelen = buf[off++]; /*目录长*/
  1737. for(i=0;i<namelen;i++) /*文件名*/
  1738. {
  1739. namestr[i]=buf[off++];
  1740. }
  1741. namestr[namelen]='\0';
  1742. strncpy(data.filename,namestr,sizeof(data));
  1743. data.addr = addr;
  1744. add_data_queque(&pt->rcd_m.queue,(u8 *)&data,OVER_QUEUE);
  1745. //print_queque(&pt->rcd_m.queue,0);
  1746. }
  1747. }
  1748. #endif
  1749. void lnk_101_app_recv(IECLINK_DEF *pt)
  1750. {
  1751. u8 *pd;
  1752. u8 AddByte=0;
  1753. u8 CotByte=0; //传送原因双字节
  1754. u8 AppByte=0; //应用单元地址双字节
  1755. BYTE addr;
  1756. LNK_STATUS *ptlnk=&pt->tlnk;
  1757. if(pt->bData) //有接收到的数据
  1758. {
  1759. if(pt->b101Addr2Byte) AddByte=1;
  1760. if(pt->b101Cot2Byte) CotByte=1;
  1761. if(pt->b101App2Byte) AppByte=1;
  1762. if(g_print_lnk && (g_print_port & (1<<pt->chnl)))
  1763. {
  1764. char tmpstr[24];
  1765. sprintf(tmpstr,"RL_101(%d):",pt->chnl);
  1766. if(pt->recvbuf[0]==0x10)
  1767. {
  1768. print_msg(tmpstr,pt->recvbuf,5+AddByte);
  1769. }
  1770. else if(pt->recvbuf[0]==0xe5)
  1771. {
  1772. print_msg(tmpstr,pt->recvbuf,1);
  1773. }
  1774. else
  1775. {
  1776. print_msg(tmpstr,pt->recvbuf,pt->recvbuf[1]+6);
  1777. }
  1778. }
  1779. pt->bData=false;
  1780. // 检查帧类型
  1781. if(pt->recvbuf[0]==0x10) pd=&pt->recvbuf[1];//短帧
  1782. else if(pt->recvbuf[0]==0x68) pd=&pt->recvbuf[4];//长帧
  1783. else if(pt->recvbuf[0]==0xe5) pd=&pt->recvbuf[0];//长帧
  1784. else return;
  1785. // 根据类型标识处理长帧
  1786. if(pt->recvbuf[0]==0x68)
  1787. {
  1788. u8 chnl,asdu_addr=0;
  1789. addr=pd[1]; //装置地址
  1790. chnl=((pt->chnl+2)<<5)+addr;
  1791. asdu_addr=pd[5+AddByte+CotByte];
  1792. if(asdu_addr == addr)
  1793. {
  1794. switch(pd[2+AddByte]) //帧类型 pd[7]=ngd
  1795. {
  1796. case 1: // 遥信帧:单点值
  1797. case 3: // 遥信帧:双点值
  1798. lnk_slave_yx(chnl,pd[2+AddByte],pd[3+AddByte],pd[4+AddByte],2,pd+6+AddByte+CotByte+AppByte);
  1799. break;
  1800. case 9: // 遥测帧:归一化值
  1801. case 11: // 遥测帧:标度化值
  1802. case 13: // 遥测帧:浮点值
  1803. case 21: // 遥测帧:不带品质描述字的归一化值
  1804. lnk_slave_yc(chnl,pd[2+AddByte],pd[3+AddByte],2,pd+6+AddByte+CotByte+AppByte);
  1805. break;
  1806. case 206: // 不带时标电度
  1807. case 207: //带时标 电度
  1808. lnk_slave_dd(chnl,pd[2+AddByte],pd[3+AddByte],pd[4+AddByte],2,pd+6+AddByte+CotByte+AppByte);
  1809. break;
  1810. case 30: // 事件记录:单点
  1811. case 31: // 事件记录:双点
  1812. lnk_slave_soe(pt,chnl,pd[2+AddByte],pd[3+AddByte],2,pd+6+AddByte+CotByte+AppByte);
  1813. break;
  1814. case 45: // 遥控确认帧
  1815. case 46: // 遥控确认帧
  1816. lnk_slave_yk(chnl,pd[2+AddByte],pd[4+AddByte],2,pd+6+AddByte+CotByte+AppByte);
  1817. break;
  1818. case FOS_PAR_READ_ONE:
  1819. case FOS_PAR_SET_ONE:
  1820. case FOS_PAR_SET_MUL:
  1821. case FOS_PAR_READ_MUL:
  1822. lnk_slave_par(chnl,pd[2+AddByte],pd[4+AddByte],2,pd+6+AddByte+CotByte+AppByte,pd[3+AddByte]);
  1823. break;
  1824. case 42: // 故障参数上送
  1825. lnk_slave_fault(chnl,pt->recvbuf[1]-6-AddByte-CotByte-AppByte,pd+6+AddByte+CotByte+AppByte,false);
  1826. break;
  1827. #ifdef YPARA_LINK
  1828. case 202:
  1829. lnk_slave_ypara_read(pt,chnl,pd[3+AddByte],pd[4+AddByte],pd+6+AddByte+CotByte+AppByte,false);
  1830. break;
  1831. case 203:
  1832. //rt_printf("104级联读参数解包-------\r\n");
  1833. lnk_slave_ypara_write(pt,chnl,pd[3+AddByte],pd[4+AddByte],pd+6+AddByte+CotByte+AppByte,false);
  1834. break;
  1835. #endif
  1836. case 210: // 文件传输
  1837. lnk_test_file_frame(pt,&pt->recvbuf[12+AddByte+CotByte+AppByte],pt->recvbuf[1]-(AddByte+CotByte+AppByte)-9);
  1838. break;
  1839. case 211: // 文件下载
  1840. lnk_update_file_frame(pt,pt->recvbuf[12+AddByte+CotByte+AppByte]);
  1841. break;
  1842. case 70: // 初始化结束帧
  1843. ptlnk->bCallAll=true;
  1844. break;
  1845. #ifdef RCD_STRAN_M
  1846. case IECLINK_RCD: // 新录波帧
  1847. lnk_rcdfile(pt,&pt->recvbuf[12+AddByte+CotByte+AppByte],addr);
  1848. break;
  1849. #endif
  1850. }
  1851. }
  1852. ptlnk->bEchoApp=(true&&pt->bPH101);
  1853. }
  1854. else if(pt->recvbuf[0]==0xe5)
  1855. {
  1856. pt->recvbuf[0]=0; // 防止影响: 设置1级数据标志
  1857. }
  1858. else
  1859. {
  1860. // 连接建立
  1861. if((pd[0]&0x0f) == IEC101_ECHO_LINK_OK)
  1862. {
  1863. ptlnk->bLinkOK = true;
  1864. pt->LinkCount++;
  1865. rt_printf_time("101级联成功(通道=%d,连接计数=%d)!\r\n",pt->chnl,pt->LinkCount);
  1866. ptlnk->dTCallAllTime=dTCounter;
  1867. }
  1868. else if(pt->bPH101) // 平衡101
  1869. {
  1870. if((pd[0]&0xCf) == (IEC101_ECHO_NO_DATA|0xC0)) //召链路
  1871. {
  1872. ptlnk->bEchoLnk=true;
  1873. }
  1874. else if((pd[0]&0xCf) == (IEC101_REMOTE_RESET|0xC0)) //召链路
  1875. {
  1876. ptlnk->bEchoApp=true;
  1877. }
  1878. }
  1879. }
  1880. // 请求链路状态必须得到正确的报文才允许继续往下走
  1881. if(ptlnk->bLinkOK)
  1882. {
  1883. ptlnk->bMRecvOK=true;
  1884. }
  1885. ptlnk->dTInteral=dTCounter;
  1886. // 设置1级数据标志
  1887. if(pd[0]&0x20)
  1888. {
  1889. ptlnk->bCallOne=(true&&!pt->bPH101);
  1890. }
  1891. ptlnk->dTSendTime=dTCounter;
  1892. }
  1893. }
  1894. void lnk_101_salve_restore(IECLINK_DEF *pt,int pre,int m_current) //切换子站地址,并保存及恢复数据
  1895. {
  1896. pt->tsla[pre].tlnksave=pt->tlnk;
  1897. pt->tlnk=pt->tsla[m_current].tlnksave;
  1898. pt->tlnk.bDdValid=pt->tsla[m_current].bDdValid;
  1899. pt->slave_addr=pt->tsla[m_current].addr;
  1900. }
  1901. void lnk_101_change_slave(IECLINK_DEF *pt) //切换子站地址,并保存及恢复数据
  1902. {
  1903. int m_current;
  1904. LNK_STATUS *ptlnk=&pt->tlnk;
  1905. if(pt->slave_num<=1)
  1906. {
  1907. ptlnk->bDdValid=pt->tsla[0].bDdValid;
  1908. return; //只有一个子站地址,不切换
  1909. }
  1910. if(ptlnk->bCallOne) return; //有一级数据需继续召唤,不切换子站地址
  1911. m_current=pt->slave_current;
  1912. m_current++;
  1913. if(m_current>=pt->slave_num)m_current=0;
  1914. pt->slave_addr=pt->tsla[m_current].addr;
  1915. lnk_101_salve_restore(pt,pt->slave_current,m_current);
  1916. pt->slave_current=m_current;
  1917. }
  1918. void lnk_101_app_send(IECLINK_DEF *pt)
  1919. {
  1920. LNK_STATUS *ptlnk=&pt->tlnk;
  1921. bool bWantEcho=true;
  1922. if(pt->slave_num==0)return;
  1923. #ifdef RCD_STRAN_M
  1924. if((pt->tft.bTransing == false) /*有文件正在传输,加速召唤*/
  1925. &&(dTCounter-ptlnk->dTSendTime<pt->sendinteraltime))
  1926. {
  1927. return;
  1928. }
  1929. #else
  1930. if((dTCounter-ptlnk->dTSendTime) <pt->sendinteraltime) // 接收到报文后,发送间隔
  1931. {
  1932. return;
  1933. }
  1934. #endif
  1935. // 检查从机应答
  1936. if(ptlnk->bMSend)
  1937. {
  1938. if(!ptlnk->bMRecvOK)
  1939. {
  1940. // 如果超时未收到应答,重发
  1941. if(dTCounter-ptlnk->dTMWait>pt->retrytime)
  1942. {
  1943. ptlnk->dTMWait=dTCounter;
  1944. //重发三次后,重新初始化
  1945. if(++ptlnk->byRetryTimes>2||ptlnk->bRetryErr)
  1946. {
  1947. ptlnk->bMSend=false;
  1948. ptlnk->bCallLnk=true;
  1949. ptlnk->bRetryErr=true;
  1950. if(ptlnk->bLinkOK)
  1951. {
  1952. #ifdef RCD_STRAN_M
  1953. if((pt->tft.bTransing) && (pt->tft.addr == pt->slave_addr)) /*通道中断,重新召唤*/
  1954. {
  1955. log_str_time(LOG_OPERATE,"通讯断开,中断传输",0,1);
  1956. pt->tft.bTransing = false;
  1957. }
  1958. #endif
  1959. ptlnk->bLinkOK = false;
  1960. rt_printf_time("重发失败,复位链路(通道=%d,连接计数=%d)!\r\n",pt->chnl,pt->LinkCount);
  1961. }
  1962. }
  1963. else
  1964. {
  1965. //需重新组织发送
  1966. lnk_101_send(pt);
  1967. }
  1968. }
  1969. // 发送,未收到数据,返回
  1970. return;
  1971. }
  1972. else
  1973. {
  1974. ptlnk->bRetryErr=false;
  1975. }
  1976. }
  1977. lnk_101_change_slave(pt);
  1978. #ifdef RCD_STRAN_M
  1979. if(ptlnk->bLinkOK)
  1980. {
  1981. lnk_rcdfile_check(pt);
  1982. }
  1983. #endif
  1984. // 上一帧从机应答OK,开始下一帧发送
  1985. ptlnk->bMSend=false;
  1986. if(ptlnk->bEchoApp)
  1987. {
  1988. lnk_101_call_fixed(pt,IECLINK_ECHOAPP,false);
  1989. ptlnk->bEchoApp=false;
  1990. bWantEcho=false;
  1991. }
  1992. else if(ptlnk->bEchoLnk)
  1993. {
  1994. lnk_101_call_fixed(pt,IECLINK_ECHOLNK,false);
  1995. ptlnk->bEchoLnk=false;
  1996. bWantEcho=false;
  1997. }
  1998. else if(ptlnk->bCallLnk)
  1999. {
  2000. lnk_101_call_fixed(pt,IECLINK_CALLLNK,false);
  2001. ptlnk->bMFCB=false;
  2002. ptlnk->bCallLnk=false;
  2003. ptlnk->bCallRst=true;
  2004. }
  2005. else if(ptlnk->bCallRst)
  2006. {
  2007. lnk_101_call_fixed(pt,IECLINK_CALLRST,false);
  2008. ptlnk->bMFCB=false;
  2009. ptlnk->bCallRst=false;
  2010. if(!pt->bPH101)
  2011. {
  2012. ptlnk->bCallAll=true;
  2013. ptlnk->bSetTime=true;
  2014. #ifdef YPARA_LINK
  2015. set_read_all(pt);
  2016. #endif
  2017. }
  2018. }
  2019. else if(ptlnk->bCallOne)
  2020. {
  2021. lnk_101_call_fixed(pt,IECLINK_CALLONE,true);
  2022. ptlnk->bCallOne=false;
  2023. }
  2024. else if(ptlnk->bCallAll)
  2025. {
  2026. u8 dat[4];
  2027. int num=0;
  2028. dat[num++]=0;
  2029. dat[num++]=0;
  2030. dat[num++]=0x14;
  2031. lnk_101_call(pt,100,1,6,dat,num);
  2032. ptlnk->bCallAll=false;
  2033. ptlnk->bCallDD=true;
  2034. ptlnk->dTCallAllTime=dTCounter;
  2035. }
  2036. else if(ptlnk->brst)
  2037. {
  2038. u8 dat[4];
  2039. int num=0;
  2040. dat[num++]=0;
  2041. dat[num++]=0;
  2042. dat[num++]=0x14;
  2043. lnk_101_call(pt,176,1,6,dat,num);
  2044. ptlnk->brst=false;
  2045. }
  2046. else if(ptlnk->bCallDD&&ptlnk->bDdValid)
  2047. {
  2048. u8 dat[4];
  2049. int num=0;
  2050. dat[num++]=0;
  2051. dat[num++]=0;
  2052. dat[num++]=0x05;
  2053. lnk_101_call(pt,101,1,6,dat,num);
  2054. ptlnk->bCallDD=false;
  2055. }
  2056. else if(ptlnk->bSetTime)
  2057. {
  2058. u8 dat[12];
  2059. int num=0;
  2060. struct timespec ts;
  2061. struct rtc_time_t rtc;
  2062. clk_time_get(&ts);
  2063. timespec_to_rtc(ts,&rtc,1);
  2064. dat[num++]=0; //信息序号=0时钟同步
  2065. dat[num++]=0; //信息序号=0时钟同步
  2066. dat[num++]=(u8)rtc.ms; //MsL
  2067. dat[num++]=(u8)(rtc.ms>>8); //MsH
  2068. dat[num++]=rtc.min; //Min
  2069. dat[num++]=rtc.hour; //hour
  2070. dat[num++]=rtc.day; //Day
  2071. dat[num++]=rtc.month; //month
  2072. dat[num++]=rtc.year; //year
  2073. lnk_101_call(pt,103,1,6,dat,num);
  2074. ptlnk->bSetTime=false;
  2075. ptlnk->us0_set_time = ustimer_get_origin();
  2076. }
  2077. // 遥控
  2078. else if(pt->yk_send_flag)
  2079. {
  2080. u8 dat[12];
  2081. int i,num=0;
  2082. for(i=0;i<SWITCH_NUM_EXT_PUB;i++)
  2083. {
  2084. if(pt->yk_send_flag & (1<<i))
  2085. {
  2086. u8 addr;
  2087. num=0;
  2088. addr=g_lnk_yk[i].chnl&0x1f;
  2089. if(addr!=pt->slave_addr)continue;
  2090. dat[num++]=(u8)g_lnk_yk[i].cp_s;
  2091. dat[num++]=(u8)(g_lnk_yk[i].cp_s>>8);
  2092. // 远动选择
  2093. if(g_lnk_yk[i].data[IECLINK_YK_SND].ti == 0xff)
  2094. {
  2095. dat[num]=g_lnk_yk[i].data[IECLINK_YK_SND].v|0x80;
  2096. lnk_101_call(pt,46,1,g_lnk_yk[i].data[IECLINK_YK_SND].cot,dat,num+1);
  2097. g_lnk_yk[i].data[IECLINK_YK_SND].ti = 0xfe;
  2098. }
  2099. // 远动遥控
  2100. else if(g_lnk_yk[i].data[IECLINK_YK_SND].ti == 0xfe)
  2101. {
  2102. dat[num]=g_lnk_yk[i].data[IECLINK_YK_SND].v;
  2103. lnk_101_call(pt,46,1,g_lnk_yk[i].data[IECLINK_YK_SND].cot,dat,num+1);
  2104. // 清除标志
  2105. g_lnk_yk[i].flag[IECLINK_YK_SND]=false;
  2106. pt->yk_send_flag &= ~(1<<i);
  2107. }
  2108. //主站遥控
  2109. else
  2110. {
  2111. dat[num++]=g_lnk_yk[i].data[IECLINK_YK_SND].v;
  2112. lnk_101_call(pt,g_lnk_yk[i].data[IECLINK_YK_SND].ti,1,g_lnk_yk[i].data[IECLINK_YK_SND].cot,dat,num);
  2113. // 清除标志
  2114. g_lnk_yk[i].flag[IECLINK_YK_SND]=false;
  2115. pt->yk_send_flag &= ~(1<<i);
  2116. }
  2117. ptlnk->bMSend=true;
  2118. break;
  2119. }
  2120. }
  2121. }
  2122. // 遥参
  2123. else if(pt->par_send_flag)
  2124. {
  2125. u8 dat[256];
  2126. int i,num=0;
  2127. for(i=0;i<SWITCH_NUM_EXT_PUB;i++)
  2128. {
  2129. if(pt->par_send_flag & (1<<i))
  2130. {
  2131. u8 addr;
  2132. num=0;
  2133. addr=g_link_par[i].chnl&0x1f;
  2134. if(addr!=pt->slave_addr)continue;
  2135. //dat[num++]=(u8)g_link_par[i].cp_s;
  2136. //dat[num++]=(u8)(g_link_par[i].cp_s>>8);
  2137. // 远动选择
  2138. if(g_link_par[i].data[IECLINK_YK_SND].ti == 0xff)
  2139. {
  2140. int count;
  2141. //dat[num]=g_link_par[i].data[IECLINK_YK_SND].v|0x80;
  2142. memcpy(&dat[num],&g_link_par[i].data[IECLINK_YK_SND].buf,g_link_par[i].data[IECLINK_YK_SND].len);
  2143. rt_printf("参数选择 \r\n");
  2144. for (count=0;count<g_link_par[i].data[IECLINK_YK_SND].len;count++)
  2145. rt_printf("%02X ",dat[num+count]);
  2146. num += g_link_par[i].data[IECLINK_YK_SND].len;
  2147. //vsq=1;//ngd
  2148. lnk_101_call(pt,g_link_par[i].data[IECLINK_YK_SND].ti_m,g_link_par[i].data[IECLINK_YK_SND].vsq,g_link_par[i].data[IECLINK_YK_SND].cot,dat,num);
  2149. //g_link_par[i].data[IECLINK_YK_SND].ti = 0xfe;
  2150. // 清除标志
  2151. #ifdef FUNC_MORE_PREREAD
  2152. pt->dtpartime[i]=ustimer_get_origin();
  2153. #endif
  2154. pt->par_send_flag &= ~(1<<i);
  2155. }
  2156. // 远动
  2157. else if(g_link_par[i].data[IECLINK_YK_SND].ti == 0xfe)
  2158. {
  2159. //dat[num]=g_link_par[i].data[IECLINK_YK_SND].v;
  2160. memcpy(&dat[num],g_link_par[i].data[IECLINK_YK_SND].buf,g_link_par[i].data[IECLINK_YK_SND].len);
  2161. num += g_link_par[i].data[IECLINK_YK_SND].len;
  2162. lnk_101_call(pt,g_link_par[i].data[IECLINK_YK_SND].ti_m,g_link_par[i].data[IECLINK_YK_SND].vsq,g_link_par[i].data[IECLINK_YK_SND].cot,dat,num);
  2163. rt_printf("参数激活\r\n");
  2164. g_link_par[i].data[IECLINK_YK_SND].ti = 0;
  2165. // 清除标志
  2166. // 清除标志
  2167. #ifdef FUNC_MORE_PREREAD
  2168. pt->dtpartime[i]=ustimer_get_origin();
  2169. #else
  2170. g_link_par[i].flag[IECLINK_YK_SND]=false;
  2171. #endif
  2172. pt->par_send_flag &= ~(1<<i);
  2173. }
  2174. //主站遥控
  2175. else
  2176. {
  2177. //dat[num++]=g_link_par[i].data[IECLINK_YK_SND].v;
  2178. memcpy(&dat[num],g_link_par[i].data[IECLINK_YK_SND].buf,g_link_par[i].data[IECLINK_YK_SND].len);
  2179. num += g_link_par[i].data[IECLINK_YK_SND].len;
  2180. rt_printf("主站下发遥参定值\r\n");
  2181. lnk_101_call(pt,g_link_par[i].data[IECLINK_YK_SND].ti_m,g_link_par[i].data[IECLINK_YK_SND].vsq,g_link_par[i].data[IECLINK_YK_SND].cot,dat,num);
  2182. // 清除标志
  2183. #ifdef FUNC_MORE_PREREAD
  2184. pt->dtpartime[i]=ustimer_get_origin();
  2185. #else
  2186. g_link_par[i].flag[IECLINK_YK_SND]=false;
  2187. #endif
  2188. pt->par_send_flag &= ~(1<<i);
  2189. }
  2190. ptlnk->bMSend=true;
  2191. break;
  2192. }
  2193. }
  2194. }
  2195. #ifdef YPARA_LINK
  2196. //遥参
  2197. else if(get_queue_count(&pt->par_queue.queue) > 0)
  2198. {
  2199. u8 dat[256];
  2200. int i=0,num=0;
  2201. msg_data_struct *msg =&pt->temp_par;
  2202. msg_ypara_data_struct *ypara_msg = &msg->ypara_msg;
  2203. //rt_printf("[%d]:::101遥参下发-----par_queue num=%d,[%x,%x]\r\n",pt->chnl,get_queue_count(&pt->par_queue.queue),msg->dport &0x1f,pt->slave_addr);
  2204. check_data_queque(&pt->par_queue.queue,(u8 *)msg);
  2205. if((msg->dport &0x1f) != pt->slave_addr) /*非当前地址*/
  2206. {
  2207. return;
  2208. }
  2209. del_data_queue(&pt->par_queue.queue);
  2210. if(ypara_msg->type == modify_set)
  2211. {
  2212. /*定值区*/
  2213. dat[num++] = (u8)ypara_msg->section_p;
  2214. dat[num++] = (u8)(ypara_msg->section_p>>8);
  2215. if(ypara_msg->cmd == YP_SEL)
  2216. {
  2217. dat[num++] = 0x80; /*特征码*/
  2218. for(i=0;i<ypara_msg->num;i++)
  2219. {
  2220. dat[num++]=(u8)ypara_msg->base_data[i].cp_s;
  2221. dat[num++]=(u8)(ypara_msg->base_data[i].cp_s>>8);
  2222. dat[num++] = ypara_msg->base_data[i].val_iec.tag;
  2223. dat[num++] = ypara_msg->base_data[i].val_iec.size;
  2224. if(ypara_msg->base_data[i].val_iec.size >0)
  2225. {
  2226. memcpy(&dat[num],ypara_msg->base_data[i].val_iec.value,ypara_msg->base_data[i].val_iec.size);
  2227. num += ypara_msg->base_data[i].val_iec.size;
  2228. }
  2229. }
  2230. }
  2231. else if(ypara_msg->cmd == YP_EXE)
  2232. {
  2233. dat[num++] = 0; /*特征码*/
  2234. set_read_all(pt);
  2235. }
  2236. else
  2237. {
  2238. dat[num++] = 0x40; /*特征码*/
  2239. }
  2240. if((ypara_msg->cmd == 2) || (ypara_msg->cmd == 1))
  2241. {
  2242. lnk_101_call(pt,203,ypara_msg->num,6,dat,num);
  2243. }
  2244. else
  2245. {
  2246. lnk_101_call(pt,203,ypara_msg->num,8,dat,num);
  2247. }
  2248. pt->sport = msg->sport;
  2249. ptlnk->bMSend=true;
  2250. }
  2251. else if(ypara_msg->type == settion_swht) //切换定值区
  2252. {
  2253. }
  2254. }
  2255. else if(ptlnk->bSet_all)
  2256. {
  2257. u8 dat[4];
  2258. int num=0;
  2259. dat[num++]=0; //当前定值区
  2260. dat[num++]=0; //当前定值区
  2261. lnk_101_call(pt,202,0,6,dat,num);
  2262. clear_read_all(pt);
  2263. ptlnk->bMSend=true;
  2264. }
  2265. #endif
  2266. #ifdef RCD_STRAN_M
  2267. else if((ptlnk->bRcd)
  2268. && (get_queue_count(&pt->rcd_m.queue) <= 0) && (pt->tft.bTransing == false)
  2269. && (tRunPara.b_lb_master || (pt->b_lb_master))) /*没有文件传输*/
  2270. {
  2271. u8 dat[4];
  2272. int num=0;
  2273. dat[num++]=0;
  2274. dat[num++]=0;
  2275. lnk_101_call(pt,IECLINK_RCD,1,6,dat,num);
  2276. ptlnk->bRcd=false;
  2277. }
  2278. // 空闲时,以500ms间隔召二级数据
  2279. else if((lnk_file_check_trans(pt)) && (pt->tft.addr == pt->slave_addr))
  2280. {
  2281. rt_printf("---------文件传输%d\r\n",pt->slave_addr);
  2282. lnk_test_file_trans(pt);
  2283. }
  2284. else if((pt->tft.bTransing == true)&&(pt->tft.addr == pt->slave_addr)) /*有文件正在传输,加速召唤*/
  2285. {
  2286. if(!pt->bPH101)
  2287. {
  2288. lnk_101_call_fixed(pt,IECLINK_CALLTWO,true);
  2289. }
  2290. else
  2291. {
  2292. return;
  2293. }
  2294. }
  2295. #else
  2296. // 空闲时,以500ms间隔召二级数据
  2297. else if(lnk_file_check_trans(pt))
  2298. {
  2299. lnk_test_file_trans(pt);
  2300. }
  2301. #endif
  2302. else if(dTCounter-ptlnk->dTInteral>pt->sendinteraltime)
  2303. {
  2304. if(!pt->bPH101)
  2305. {
  2306. lnk_101_call_fixed(pt,IECLINK_CALLTWO,true);
  2307. }
  2308. else
  2309. {
  2310. return;
  2311. }
  2312. }
  2313. else
  2314. {
  2315. return;
  2316. }
  2317. // 开始发送,清重发标志,翻转FCB位
  2318. ptlnk->bMSend=true&& bWantEcho;
  2319. ptlnk->bMRecvOK=false;
  2320. ptlnk->dTMWait=dTCounter;
  2321. ptlnk->byRetryTimes=0;
  2322. if(bWantEcho) ptlnk->bMFCB=!ptlnk->bMFCB;
  2323. lnk_101_send(pt);
  2324. }
  2325. void lnk_101_par_timer(IECLINK_DEF *pt)
  2326. {
  2327. int i=0;
  2328. int flag=0;
  2329. for(i=0;i<SWITCH_NUM_EXT_PUB;i++)
  2330. {
  2331. flag = pt->par_send_flag & (1<<i);
  2332. if(g_link_par[i].flag[IECLINK_YK_SND] && !flag)
  2333. {
  2334. if(ustimer_get_duration(pt->dtpartime[i]) > 10*USTIMER_SEC) /*10秒遥参*/
  2335. {
  2336. rt_printf("--------遥参超时!!!\r\n");
  2337. g_link_par[i].flag[IECLINK_YK_SND] = false;
  2338. }
  2339. }
  2340. }
  2341. }
  2342. void lnk_101_app_timer(IECLINK_DEF *pt)
  2343. {
  2344. LNK_STATUS *ptlnk=&pt->tlnk;
  2345. // 定时总召
  2346. if(!ptlnk->bCallAll)
  2347. {
  2348. if(dTCounter-ptlnk->dTCallAllTime>pt->callalltime) // 10分钟总召一次
  2349. {
  2350. ptlnk->bCallAll=true;
  2351. ptlnk->dTCallAllTime=dTCounter;
  2352. }
  2353. }
  2354. #ifdef RCD_STRAN_M
  2355. if(ustimer_get_duration(ptlnk->dTRcdTime) > 3*USTIMER_SEC) /*3秒间隔*/
  2356. {
  2357. ptlnk->bRcd = true;
  2358. ptlnk->dTRcdTime=ustimer_get_origin();
  2359. }
  2360. #endif
  2361. #ifdef FUNC_MORE_PREREAD
  2362. //lnk_101_par_timer(pt);
  2363. #endif
  2364. // 检查对时间隔
  2365. if(ustimer_get_duration(ptlnk->us0_set_time) > 5*60*USTIMER_SEC)
  2366. {
  2367. ptlnk->bSetTime = true;
  2368. }
  2369. }
  2370. void lnk_101_app(IECLINK_DEF *pt)
  2371. {
  2372. LNK_STATUS *ptlnk=&pt->tlnk;
  2373. lnk_101_app_recv(pt);
  2374. lnk_101_app_send(pt);
  2375. if(ptlnk->bLinkOK)
  2376. {
  2377. lnk_101_app_timer(pt);
  2378. }
  2379. }
  2380. static void lnk_101_recv_rst(IECLINK_DEF *pt)
  2381. {
  2382. pt->nTypeCounter=0;
  2383. pt->nRecvLenth=0;
  2384. pt->nRecvCounter=0;
  2385. }
  2386. void lnk_101_recv(IECLINK_DEF *pt,u8 byRevData)
  2387. {
  2388. pt->recvbuf[pt->nRecvCounter++]=byRevData;
  2389. switch(pt->nTypeCounter)
  2390. {
  2391. case 0:
  2392. if(byRevData==0x68)
  2393. {
  2394. pt->nTypeCounter=1;
  2395. pt->sum=0;
  2396. }
  2397. else if(byRevData==0x10)
  2398. {
  2399. if(!pt->b101Addr2Byte)
  2400. {
  2401. pt->nRecvLenth=2;
  2402. }
  2403. else
  2404. {
  2405. pt->nRecvLenth=3;
  2406. }
  2407. pt->nTypeCounter=6;
  2408. pt->nRecvCnt=0;
  2409. pt->sum=0;
  2410. }
  2411. else if(byRevData==0xe5) // e5处理
  2412. {
  2413. lnk_101_recv_rst(pt);
  2414. pt->bData=true;
  2415. // 唤醒主循环
  2416. mainloop_wakeup();
  2417. }
  2418. else
  2419. {
  2420. lnk_101_recv_rst(pt);
  2421. }
  2422. break;
  2423. case 1:
  2424. pt->nTypeCounter=2;
  2425. pt->nRecvLenth=byRevData; //长帧长度
  2426. if(pt->nRecvLenth>IECLINK_RECVBUF_MAX)
  2427. {
  2428. lnk_101_recv_rst(pt);
  2429. }
  2430. break;
  2431. case 2:
  2432. if(pt->nRecvLenth==byRevData)
  2433. {
  2434. pt->nTypeCounter=3;
  2435. }
  2436. else
  2437. {
  2438. lnk_101_recv_rst(pt);
  2439. }
  2440. break;
  2441. case 3:
  2442. if(byRevData==0x68)
  2443. {
  2444. pt->nTypeCounter=6;
  2445. pt->nRecvCnt=0;
  2446. }
  2447. else
  2448. {
  2449. lnk_101_recv_rst(pt);
  2450. }
  2451. break;
  2452. //case 4: //控制域
  2453. // pt->sum=byRevData;
  2454. // pt->nTypeCounter=5;
  2455. // break;
  2456. //case 5: //目标地址
  2457. // pt->sum+=byRevData;
  2458. // pt->nRecvCnt=0;
  2459. // pt->nTypeCounter=6;
  2460. // if(pt->nRecvLenth==2)//短帧
  2461. // pt->nTypeCounter=7;
  2462. // break;
  2463. case 6: //有效数据 //有效数据
  2464. if(++pt->nRecvCnt>=pt->nRecvLenth)
  2465. {
  2466. pt->nTypeCounter=7;
  2467. }
  2468. pt->sum+=byRevData;
  2469. break;
  2470. case 7: //校验和
  2471. if(pt->sum==byRevData)
  2472. {
  2473. pt->nTypeCounter=8;
  2474. }
  2475. else
  2476. {
  2477. lnk_101_recv_rst(pt);
  2478. }
  2479. break;
  2480. case 8: //结束符
  2481. lnk_101_recv_rst(pt);
  2482. if(byRevData==0x16) //校验结束字符,报文接收完毕,
  2483. {
  2484. pt->bData=true;
  2485. // 唤醒主循环
  2486. mainloop_wakeup();
  2487. return ;
  2488. }
  2489. break;
  2490. }
  2491. }
  2492. // 下面是以太网级联代码
  2493. void lnk_104_init(int net)
  2494. {
  2495. IECLINK_DEF *pt = &g_link_104[net];
  2496. LNK_STATUS *ptlnk=&pt->tlnk;
  2497. memset(pt,0,sizeof(IECLINK_DEF));
  2498. pt->type=IEC104_CHN;
  2499. pt->chnl = net;
  2500. pt->sendbuf=g_link104_buf[net];
  2501. ptlnk->bCallRst=true;
  2502. ptlnk->dTMWait=dTCounter;
  2503. ptlnk->dTInteral=dTCounter;
  2504. ptlnk->dTCallAllTime=dTCounter;
  2505. ptlnk->us0_set_time=ustimer_get_origin();
  2506. // 测试状态复位
  2507. pt->bStartTest=false;
  2508. pt->us0_test=ustimer_get_origin();
  2509. lnk_init_cfg(pt,"IEC104_LNK");
  2510. pt->AckRecvNum=0;
  2511. #ifdef RCD_STRAN_M
  2512. queue_init(&pt->rcd_m.queue,NEWRCD_COUNT_M,&pt->rcd_m.data,NEWRCD_SIZE_M);
  2513. #endif
  2514. #ifdef YPARA_LINK
  2515. queue_init(&pt->par_queue.queue,PAR_COUNT_M,&pt->par_queue.data,PAR_SIZE_M);
  2516. #endif
  2517. }
  2518. void lnk_104_send(IECLINK_DEF *pt,u8 num)
  2519. {
  2520. char tmpstr[16];
  2521. sprintf(tmpstr,"TL_104(%d):",pt->chnl+1);
  2522. if(g_print_lnk && (g_print_port & (1<<pt->chnl)))
  2523. {
  2524. print_msg(tmpstr,pt->sendbuf,num);
  2525. }
  2526. net_104link_send(pt->chnl,pt->sendbuf,num);
  2527. // 发送了任意帧,复位T3定时器(测试帧超时)
  2528. pt->us0_test=ustimer_get_origin();
  2529. }
  2530. static void lnk_104_ack(IECLINK_DEF *pt,u8 zone)
  2531. {
  2532. u8 *pd=pt->sendbuf;
  2533. int sum=0;
  2534. pd[sum++]=0x68;
  2535. pd[sum++]=0x04;
  2536. pd[sum++]=zone;
  2537. pd[sum++]=0x00;
  2538. pd[sum++]=0x00;
  2539. pd[sum++]=0x00;
  2540. lnk_104_send(pt,sum);
  2541. }
  2542. static void lnk_104_sAck(IECLINK_DEF *pt)
  2543. {
  2544. u8 *pd=pt->sendbuf;
  2545. int sum=0;
  2546. pd[sum++]=0x68;
  2547. pd[sum++]=0x04;
  2548. pd[sum++]=0x01;
  2549. pd[sum++]=0x00;
  2550. sum += CopySwap(&pd[sum],pt->RecvNum.tt,2,true);
  2551. pt->AckRecvNum=pt->RecvNum.ss;
  2552. lnk_104_send(pt,sum);
  2553. }
  2554. static void lnk_104_call(IECLINK_DEF *pt, u8 type,u8 ngd,u8 cot,u8 *pdat,u8 len)
  2555. {
  2556. u8 *pd;
  2557. int sum=0;
  2558. int i;
  2559. pd=pt->sendbuf;
  2560. //68 14 00 00 00 00 67 01 06 01 01 00 00 00 00 34 df 1d 0e 51 09 0d //对时
  2561. //68 0e 02 00 04 00 64 01 06 01 01 00 00 00 00 14 //总招
  2562. //68 0e 04 00 4c 00 2e 01 06 01 01 00 01 60 00 82 //遥控
  2563. pd[sum++]=0x68;
  2564. pd[sum++]=len+10;
  2565. sum += CopySwap(&pd[sum],pt->SendNum.tt,2,true);
  2566. sum += CopySwap(&pd[sum],pt->RecvNum.tt,2,true);
  2567. pd[sum++]=type;//帧类型
  2568. pd[sum++]=ngd;
  2569. pd[sum++]=cot;
  2570. pd[sum++]=0;
  2571. pd[sum++]=(u8)1; // 使用1作为级联从机的地址
  2572. pd[sum++]=(u8)0;
  2573. for(i=0;i<len;i++) //标示拷贝
  2574. {
  2575. pd[sum++]=*pdat++;
  2576. }
  2577. pt->AckRecvNum=pt->RecvNum.ss;
  2578. lnk_104_send(pt,sum);
  2579. pt->SendNum.ss+=2;
  2580. pt->bSendS = 0;
  2581. }
  2582. void lnk_104_app_recv(int net)
  2583. {
  2584. IECLINK_DEF *pt = &g_link_104[net];
  2585. u8 *pd,addr;
  2586. Byte2WORD Num;
  2587. LNK_STATUS *ptlnk=&pt->tlnk;
  2588. char tmpstr[16];
  2589. if(pt->bData == 0) //有接收到的数据
  2590. {
  2591. return;
  2592. }
  2593. sprintf(tmpstr,"RL_104(%d):",pt->chnl+1);
  2594. if(g_print_lnk && (g_print_port & (1<<pt->chnl)))
  2595. {
  2596. print_msg(tmpstr,pt->recvbuf,pt->recvbuf[1]+2);
  2597. }
  2598. if(pt->recvbuf[0] != 0x68)
  2599. {
  2600. pt->bData=false;
  2601. g_net_104link_data[net]=0;
  2602. return;
  2603. }
  2604. switch(pt->recvbuf[2]&0x03) //控制域判断
  2605. {
  2606. case 0x00: //I格式
  2607. case 0x02:
  2608. // 确认发送帧的接收序号
  2609. pt->recvbuf[2] &= 0xfe;
  2610. CopySwap(Num.tt,&pt->recvbuf[2],2,false);
  2611. Num.ss += 2;
  2612. if(Num.ss != pt->RecvNum.ss)
  2613. {
  2614. if(pt->bSendS == 0)
  2615. {
  2616. ptlnk->dTInteral=dTCounter;
  2617. }
  2618. pt->bSendS = ((Num.ss - pt->RecvNum.ss) > 8*2)? 2 : 1;
  2619. pt->RecvNum.ss = Num.ss;
  2620. }
  2621. //确认序号
  2622. pt->recvbuf[4] &= 0xfe;
  2623. CopySwap(pt->AckNum.tt,&pt->recvbuf[4],2,false);
  2624. // 处理ASDU
  2625. pd=&pt->recvbuf[6];
  2626. addr=pt->chnl+1; // 网络通道,统一使用网络1,级联地址代表参数表中子站地址,下发从1开始,pt->chnl从0开始
  2627. switch(pd[0])
  2628. {
  2629. case 1: // 遥信帧:单点值
  2630. case 3: // 遥信帧:双点值
  2631. lnk_slave_yx(addr,pd[0],pd[1],pd[2],3,pd+6);
  2632. break;
  2633. case 9: // 遥测帧:归一化值
  2634. case 11: // 遥测帧:标度化值
  2635. case 13: // 遥测帧:浮点值
  2636. lnk_slave_yc(addr,pd[0],pd[1],3,pd+6);
  2637. break;
  2638. case 30: // 事件记录:单点
  2639. case 31: // 事件记录:双点
  2640. lnk_slave_soe(pt,addr,pd[0],pd[1],3,pd+6);
  2641. break;
  2642. case 45: // 遥控确认帧
  2643. case 46: // 遥控确认帧
  2644. lnk_slave_yk(addr,pd[0],pd[2],3,pd+6);
  2645. break;
  2646. case FOS_PAR_READ_ONE:
  2647. case FOS_PAR_SET_ONE:
  2648. case FOS_PAR_SET_MUL:
  2649. case FOS_PAR_READ_MUL:
  2650. lnk_slave_par(addr,pd[0],pd[2],3,pd+6,pd[1]);
  2651. break;
  2652. case FOS_PAR_READ_ONE_EXT:
  2653. case FOS_PAR_SET_ONE_EXT:
  2654. case FOS_PAR_SET_MUL_EXT:
  2655. case FOS_PAR_READ_MUL_EXT:
  2656. lnk_slave_par(addr,pd[0],pd[2],2,pd+6,pd[1]);
  2657. break;
  2658. #ifdef FUN_YPARA_CFG_NOTY
  2659. case 116:
  2660. lnk_para_chg(pt,addr,pd[1],pd[2],pd+6,true);
  2661. break;
  2662. #endif
  2663. #ifdef YPARA_LINK
  2664. case 202:
  2665. lnk_slave_ypara_read(pt,addr,pd[1],pd[2],pd+6,true);
  2666. break;
  2667. case 203:
  2668. //rt_printf("104级联读参数解包-------\r\n");
  2669. lnk_slave_ypara_write(pt,addr,pd[1],pd[2],pd+6,true);
  2670. break;
  2671. case SET_UP_TYPE:
  2672. if(pd[2] & IEC_COT_PN) break;
  2673. lnk_slave_ypara_updata(pt,pd+6);
  2674. break;
  2675. #endif
  2676. #ifdef RCD_STRAN_M
  2677. case IECLINK_RCD: // 新录波帧
  2678. ptlnk->bRcding = false;
  2679. if(pd[2] & IEC_COT_PN) break;
  2680. lnk_rcdfile(pt,&pt->recvbuf[15],tRunPara.byAddr);
  2681. break;
  2682. #endif
  2683. case 206: // 不带时标电度
  2684. case 207: //带时标 电度
  2685. lnk_slave_dd(addr,pd[0],pd[1],pd[2],3,pd+6);
  2686. break;
  2687. case 42: // 故障参数上送
  2688. lnk_slave_fault(addr,pt->recvbuf[1]-10,pd+6,true);
  2689. break;
  2690. case 210: // 文件传输
  2691. lnk_test_file_frame(pt,&pt->recvbuf[15],pt->recvbuf[1]-14);
  2692. break;
  2693. case 211: // 文件传输
  2694. lnk_update_file_frame(pt,pt->recvbuf[15]);
  2695. break;
  2696. }
  2697. break;
  2698. case 0x01: //S格式
  2699. pt->recvbuf[4] &= 0xfe;
  2700. CopySwap(pt->AckNum.tt,&pt->recvbuf[4],2,false);
  2701. break;
  2702. case 0x03: //U格式
  2703. // 如果是子站主动发送的测试帧,必须应答
  2704. if(pt->recvbuf[2] == FRAME_U_TEST)
  2705. {
  2706. pt->bTestAck = true;
  2707. }
  2708. break;
  2709. }
  2710. ptlnk->bMRecvOK=true;
  2711. ptlnk->byRetryTimes=0;
  2712. // 清Test计数器
  2713. pt->us0_test=ustimer_get_origin();
  2714. pt->bStartTest=false;
  2715. pt->bData=false;
  2716. g_net_104link_data[net]=0;
  2717. }
  2718. void lnk_104_app_send(int net)
  2719. {
  2720. IECLINK_DEF *pt = &g_link_104[net];
  2721. LNK_STATUS *ptlnk=&pt->tlnk;
  2722. // 以下开始处理发送
  2723. // 检查从站应答
  2724. if(ptlnk->bMSend && (!ptlnk->bMRecvOK))
  2725. {
  2726. if(dTCounter-ptlnk->dTMWait>pt->retrytime) // 2秒后,未收到应答报文
  2727. {
  2728. ptlnk->dTMWait=dTCounter;
  2729. ptlnk->bMSend=false;
  2730. ptlnk->bCallRst=true;
  2731. #ifdef RCD_STRAN_M
  2732. if(pt->tft.bTransing) /*通道中断,重新召唤*/
  2733. {
  2734. log_str_time(LOG_OPERATE,"通讯断开,中断传输",0,1);
  2735. pt->tft.bTransing = false;
  2736. }
  2737. #endif
  2738. }
  2739. // 从站未应答,直接返回
  2740. return;
  2741. }
  2742. // 到这儿,以前的发送帧已应答完成,开始新的发送
  2743. // 先初始化数据
  2744. ptlnk->byRetryTimes=0;
  2745. ptlnk->dTMWait=dTCounter;
  2746. ptlnk->bMRecvOK=false;
  2747. ptlnk->bMSend=false;
  2748. #ifdef RCD_STRAN_M
  2749. lnk_rcdfile_check_104(pt); /*扫描是否有录波文件召唤*/
  2750. #endif
  2751. // 进入STARTDT状态
  2752. if(ptlnk->bCallRst)
  2753. {
  2754. lnk_104_ack(pt,0x07);
  2755. ptlnk->bCallRst=false;
  2756. ptlnk->bMSend=true;
  2757. ptlnk->bCallAll=true;
  2758. ptlnk->bSetTime=true;
  2759. #ifdef YPARA_LINK
  2760. set_read_all(pt);
  2761. #endif
  2762. pt->SendNum.ss=0;
  2763. }
  2764. // 总召
  2765. else if(ptlnk->bCallAll)
  2766. {
  2767. u8 dat[4];
  2768. int num=0;
  2769. dat[num++]=0;
  2770. dat[num++]=0;
  2771. dat[num++]=0;
  2772. dat[num++]=0x14;
  2773. lnk_104_call(pt,100,1,6,dat,4);
  2774. ptlnk->bCallAll=false;
  2775. ptlnk->bCallDD=true;
  2776. ptlnk->dTCallAllTime=dTCounter;
  2777. ptlnk->bMSend=true;
  2778. }
  2779. else if(ptlnk->bCallDD)
  2780. {
  2781. u8 dat[4];
  2782. int num=0;
  2783. dat[num++]=0;
  2784. dat[num++]=0;
  2785. dat[num++]=0;
  2786. dat[num++]=0x05;
  2787. lnk_104_call(pt,101,1,6,dat,4); //电度召唤
  2788. ptlnk->bCallDD=false;
  2789. ptlnk->bMSend=true;
  2790. }
  2791. // 对时
  2792. else if(ptlnk->bSetTime)
  2793. {
  2794. u8 dat[12];
  2795. int num=0;
  2796. struct timespec ts;
  2797. struct rtc_time_t rtc;
  2798. clk_time_get(&ts);
  2799. timespec_to_rtc(ts,&rtc,1);
  2800. dat[num++]=0; //信息序号=0时钟同步
  2801. dat[num++]=0; //信息序号=0时钟同步
  2802. dat[num++]=0; //信息序号=0时钟同步
  2803. dat[num++]=(u8)rtc.ms; //MsL
  2804. dat[num++]=(u8)(rtc.ms>>8); //MsH
  2805. dat[num++]=rtc.min; //Min
  2806. dat[num++]=rtc.hour; //hour
  2807. dat[num++]=rtc.day; //Day
  2808. dat[num++]=rtc.month; //month
  2809. dat[num++]=rtc.year; //year
  2810. lnk_104_call(pt,103,1,6,dat,num);
  2811. ptlnk->bSetTime=false;
  2812. ptlnk->bMSend=true;
  2813. ptlnk->us0_set_time = ustimer_get_origin();
  2814. }
  2815. // 遥控
  2816. else if(pt->yk_send_flag)
  2817. {
  2818. u8 dat[12];
  2819. int i,num=0;
  2820. for(i=0;i<SWITCH_NUM_EXT_PUB;i++)
  2821. {
  2822. if(pt->yk_send_flag & (1<<i))
  2823. {
  2824. dat[num++]=(u8)g_lnk_yk[i].cp_s;
  2825. dat[num++]=(u8)(g_lnk_yk[i].cp_s>>8);
  2826. dat[num++]=0;
  2827. if(g_lnk_yk[i].data[IECLINK_YK_SND].ti == 0xff)
  2828. {
  2829. dat[num]=g_lnk_yk[i].data[IECLINK_YK_SND].v|0x80;
  2830. lnk_104_call(pt,46,1,g_lnk_yk[i].data[IECLINK_YK_SND].cot,dat,num+1);
  2831. dat[num]=g_lnk_yk[i].data[IECLINK_YK_SND].v;
  2832. lnk_104_call(pt,46,1,g_lnk_yk[i].data[IECLINK_YK_SND].cot,dat,num+1);
  2833. }
  2834. else
  2835. {
  2836. dat[num++]=g_lnk_yk[i].data[IECLINK_YK_SND].v;
  2837. lnk_104_call(pt,g_lnk_yk[i].data[IECLINK_YK_SND].ti,1,g_lnk_yk[i].data[IECLINK_YK_SND].cot,dat,num);
  2838. }
  2839. g_lnk_yk[i].flag[IECLINK_YK_SND]=false;
  2840. ptlnk->bMSend=true;
  2841. // 清除标志
  2842. pt->yk_send_flag &= ~(1<<i);
  2843. break;
  2844. }
  2845. }
  2846. }
  2847. else if(pt->par_send_flag)
  2848. {
  2849. u8 dat[256];
  2850. int i,num=0;
  2851. int len=0;
  2852. for(i=0;i<SWITCH_NUM_EXT_PUB;i++)
  2853. {
  2854. if(pt->par_send_flag & (1<<i))
  2855. {
  2856. u8 ti_m=0;
  2857. num=0;
  2858. // 远动选择
  2859. if(g_link_par[i].data[IECLINK_YK_SND].ti == 0xff)
  2860. {
  2861. int count;
  2862. #ifdef FOS_PAR_EXT
  2863. memcpy(&dat[num],&g_link_par[i].data[IECLINK_YK_SND].buf,g_link_par[i].data[IECLINK_YK_SND].len);
  2864. len = g_link_par[i].data[IECLINK_YK_SND].len;
  2865. if(g_link_par[i].data[IECLINK_YK_SND].ti_m==FOS_PAR_SET_MUL)
  2866. {
  2867. ti_m = FOS_PAR_SET_MUL_EXT;
  2868. }
  2869. else if(g_link_par[i].data[IECLINK_YK_SND].ti_m==FOS_PAR_SET_ONE)
  2870. {
  2871. ti_m = FOS_PAR_SET_ONE_EXT;
  2872. }
  2873. else if(g_link_par[i].data[IECLINK_YK_SND].ti_m==FOS_PAR_READ_ONE)
  2874. {
  2875. ti_m = FOS_PAR_READ_ONE_EXT;
  2876. }
  2877. else if(g_link_par[i].data[IECLINK_YK_SND].ti_m==FOS_PAR_READ_MUL)
  2878. {
  2879. ti_m = FOS_PAR_READ_MUL_EXT;
  2880. }
  2881. #else
  2882. len = get_par_link_101_to_104(&dat[num],&g_link_par[i].data[IECLINK_YK_SND].buf[0],g_link_par[i].data[IECLINK_YK_SND].vsq,g_link_par[i].data[IECLINK_YK_SND].ti_m);
  2883. ti_m = g_link_par[i].data[IECLINK_YK_SND].ti_m;
  2884. #endif
  2885. num += len;
  2886. rt_printf("参数选择 \r\n");
  2887. for (count=0;count<len;count++)
  2888. rt_printf("%02X ",dat[num+count]);
  2889. lnk_104_call(pt,ti_m,g_link_par[i].data[IECLINK_YK_SND].vsq,g_link_par[i].data[IECLINK_YK_SND].cot,dat,num);
  2890. // 清除标志
  2891. #ifdef FUNC_MORE_PREREAD
  2892. pt->dtpartime[i]=ustimer_get_origin();
  2893. #endif
  2894. pt->par_send_flag &= ~(1<<i);
  2895. }
  2896. // 远动
  2897. else if(g_link_par[i].data[IECLINK_YK_SND].ti == 0xfe)
  2898. {
  2899. //dat[num]=g_link_par[i].data[IECLINK_YK_SND].v;
  2900. len = get_par_link_101_to_104(&dat[num],&g_link_par[i].data[IECLINK_YK_SND].buf[0],g_link_par[i].data[IECLINK_YK_SND].vsq,g_link_par[i].data[IECLINK_YK_SND].ti_m);
  2901. num += len;
  2902. lnk_104_call(pt,g_link_par[i].data[IECLINK_YK_SND].ti_m,g_link_par[i].data[IECLINK_YK_SND].vsq,g_link_par[i].data[IECLINK_YK_SND].cot,dat,num);
  2903. rt_printf("参数激活\r\n");
  2904. g_link_par[i].data[IECLINK_YK_SND].ti = 0;
  2905. // 清除标志
  2906. // 清除标志
  2907. #ifdef FUNC_MORE_PREREAD
  2908. pt->dtpartime[i]=ustimer_get_origin();
  2909. #else
  2910. g_link_par[i].flag[IECLINK_YK_SND]=false;
  2911. #endif
  2912. pt->par_send_flag &= ~(1<<i);
  2913. }
  2914. //主站遥控
  2915. else
  2916. {
  2917. //dat[num++]=g_link_par[i].data[IECLINK_YK_SND].v;
  2918. len = get_par_link_101_to_104(&dat[num],&g_link_par[i].data[IECLINK_YK_SND].buf[0],g_link_par[i].data[IECLINK_YK_SND].vsq,g_link_par[i].data[IECLINK_YK_SND].ti_m);
  2919. num += len;
  2920. rt_printf("主站下发遥参定值\r\n");
  2921. lnk_104_call(pt,g_link_par[i].data[IECLINK_YK_SND].ti_m,g_link_par[i].data[IECLINK_YK_SND].vsq,g_link_par[i].data[IECLINK_YK_SND].cot,dat,num);
  2922. // 清除标志
  2923. #ifdef FUNC_MORE_PREREAD
  2924. pt->dtpartime[i]=ustimer_get_origin();
  2925. #else
  2926. g_link_par[i].flag[IECLINK_YK_SND]=false;
  2927. #endif
  2928. pt->par_send_flag &= ~(1<<i);
  2929. }
  2930. ptlnk->bMSend=true;
  2931. break;
  2932. }
  2933. }
  2934. }
  2935. #ifdef YPARA_LINK
  2936. //遥参
  2937. else if(get_queue_count(&pt->par_queue.queue) > 0)
  2938. {
  2939. u8 dat[256];
  2940. int i=0,num=0;
  2941. msg_data_struct *msg_data =&pt->temp_par;
  2942. get_data_queque(&pt->par_queue.queue,(u8 *)msg_data);
  2943. //rt_printf("-----104级联:::遥参下发\r\n");
  2944. //print_msg_base(ypara_msg);
  2945. if(msg_data->type == modify_set)
  2946. {
  2947. msg_ypara_data_struct *ypara_msg = &msg_data->ypara_msg;
  2948. /*定值区*/
  2949. dat[num++] = (u8)ypara_msg->section_p;
  2950. dat[num++] = (u8)(ypara_msg->section_p>>8);
  2951. if(ypara_msg->cmd == YP_SEL)
  2952. {
  2953. dat[num++] = 0x80; /*特征码*/
  2954. for(i=0;i<ypara_msg->num;i++)
  2955. {
  2956. dat[num++]=(u8)ypara_msg->base_data[i].cp_s;
  2957. dat[num++]=(u8)(ypara_msg->base_data[i].cp_s>>8);
  2958. dat[num++]=0;
  2959. dat[num++] = ypara_msg->base_data[i].val_iec.tag;
  2960. dat[num++] = ypara_msg->base_data[i].val_iec.size;
  2961. if(ypara_msg->base_data[i].val_iec.size >0)
  2962. {
  2963. memcpy(&dat[num],ypara_msg->base_data[i].val_iec.value,ypara_msg->base_data[i].val_iec.size);
  2964. num += ypara_msg->base_data[i].val_iec.size;
  2965. }
  2966. }
  2967. }
  2968. else if(ypara_msg->cmd == YP_EXE)
  2969. {
  2970. dat[num++] = 0; /*特征码*/
  2971. set_read_all(pt);
  2972. }
  2973. else
  2974. {
  2975. dat[num++] = 0x40; /*特征码*/
  2976. }
  2977. if((ypara_msg->cmd == 2) || (ypara_msg->cmd == 1))
  2978. {
  2979. lnk_104_call(pt,203,ypara_msg->num,6,dat,num);
  2980. }
  2981. else
  2982. {
  2983. lnk_104_call(pt,203,ypara_msg->num,8,dat,num);
  2984. }
  2985. pt->sport = msg_data->sport;
  2986. ptlnk->bMSend=true;
  2987. }
  2988. else if(msg_data->type == settion_swht)
  2989. {
  2990. msg_oper_setion_struct *setion_msg = &msg_data->setion_msg;
  2991. /*信息体地址0*/
  2992. dat[num++] = 0;
  2993. dat[num++] = 0;
  2994. dat[num++] = 0;
  2995. /*定值区*/
  2996. dat[num++] = (u8)setion_msg->section_p;
  2997. dat[num++] = (u8)(setion_msg->section_p>>8);
  2998. lnk_104_call(pt,200,1,6,dat,num);
  2999. pt->sport = msg_data->sport;
  3000. ptlnk->bMSend=true;
  3001. }
  3002. }
  3003. else if(ptlnk->bSet_all)
  3004. {
  3005. u8 dat[4];
  3006. int num=0;
  3007. dat[num++]=0; //当前定值区
  3008. dat[num++]=0; //当前定值区
  3009. lnk_104_call(pt,202,0,6,dat,num);
  3010. clear_read_all(pt);
  3011. ptlnk->bMSend=true;
  3012. }
  3013. // 空闲时,以500ms间隔召二级数据
  3014. #endif
  3015. #ifdef RCD_STRAN_M
  3016. else if((ptlnk->bRcd) && (ptlnk->bRcding == false)
  3017. && (get_queue_count(&pt->rcd_m.queue) <= 0) && (pt->tft.bTransing == false)
  3018. && (tRunPara.b_lb_master || (pt->b_lb_master))) /*没有文件传输*/
  3019. {
  3020. u8 dat[4];
  3021. int num=0;
  3022. dat[num++]=0;
  3023. dat[num++]=0;
  3024. lnk_104_call(pt,IECLINK_RCD,1,6,dat,num);
  3025. ptlnk->bMSend=true;
  3026. ptlnk->bRcding = true;
  3027. ptlnk->dRcdingTime = ustimer_get_origin();
  3028. ptlnk->bRcd=false;
  3029. }
  3030. #endif
  3031. // 空闲时,以500ms间隔召二级数据
  3032. else if(lnk_file_check_trans(pt))
  3033. {
  3034. lnk_test_file_trans(pt);
  3035. }
  3036. // 子站测试帧应答
  3037. if(pt->bTestAck)
  3038. {
  3039. lnk_104_ack(pt,FRAME_U_TEST_ACK);
  3040. pt->bTestAck = false;
  3041. }
  3042. // 发送S帧
  3043. if(((pt->RecvNum.ss - pt->AckRecvNum) >=tRunPara.w104W)
  3044. ||((pt->bSendS ==2) || ((pt->bSendS == 1) && (dTCounter-ptlnk->dTInteral > 5*T_1s)))
  3045. )
  3046. {
  3047. lnk_104_sAck(pt);
  3048. pt->bSendS = 0;
  3049. }
  3050. }
  3051. void lnk_104_par_timer(IECLINK_DEF *pt)
  3052. {
  3053. int i=0;
  3054. int flag=0;
  3055. for(i=0;i<SWITCH_NUM_EXT_PUB;i++)
  3056. {
  3057. flag = pt->par_send_flag & (1<<i);
  3058. if(g_link_par[i].flag[IECLINK_YK_SND] && !flag)
  3059. {
  3060. if(ustimer_get_duration(pt->dtpartime[i]) > 10*USTIMER_SEC) /*10秒遥参*/
  3061. {
  3062. rt_printf("--------遥参超时!!!\r\n");
  3063. g_link_par[i].flag[IECLINK_YK_SND] = false;
  3064. }
  3065. }
  3066. }
  3067. }
  3068. void lnk_104_app_timer(int net)
  3069. {
  3070. IECLINK_DEF *pt = &g_link_104[net];
  3071. LNK_STATUS *ptlnk=&pt->tlnk;
  3072. if(!ptlnk->bCallAll)
  3073. {
  3074. if(dTCounter-ptlnk->dTCallAllTime>pt->callalltime) // 10分钟总召一次
  3075. {
  3076. ptlnk->bCallAll=true;
  3077. ptlnk->dTCallAllTime=dTCounter;
  3078. }
  3079. }
  3080. #ifdef FUNC_MORE_PREREAD
  3081. //lnk_104_par_timer(pt);
  3082. #endif
  3083. #ifdef RCD_STRAN_M
  3084. if(ustimer_get_duration(ptlnk->dTRcdTime) > 1*USTIMER_SEC) /*10秒间隔*/
  3085. {
  3086. ptlnk->bRcd = true;
  3087. ptlnk->dTRcdTime=ustimer_get_origin();
  3088. }
  3089. if(ptlnk->bRcding)
  3090. {
  3091. u8 tmp[64];
  3092. if(ustimer_get_duration(ptlnk->dRcdingTime)>(10*USTIMER_SEC)) /*10秒无文件内容,超时*/
  3093. {
  3094. sprintf(tmp,"link[%d]::查询录波应答超时!!!!!!!",pt->chnl+1);
  3095. log_str_time(LOG_OPERATE,tmp,0,1);
  3096. ptlnk->bRcding = false;
  3097. }
  3098. }
  3099. if(pt->tft.bTransing)
  3100. {
  3101. u8 tmp1[128];
  3102. if(ustimer_get_duration(pt->tft.us0_file_trans)>(10*USTIMER_SEC)) /*10秒无文件内容,超时*/
  3103. {
  3104. sprintf(tmp1, "BAY%02d%s读文件传输超时(%d)!!!!!!!", pt->chnl+1,pt->tft.filename+5,pt->tft.offset); /*104替换成级联通道号*/
  3105. log_str_time(LOG_OPERATE,tmp1,0,1);
  3106. pt->tft.bTransing=false;
  3107. }
  3108. }
  3109. #endif
  3110. // 检查对时间隔
  3111. if(ustimer_get_duration(ptlnk->us0_set_time) > 5*60*USTIMER_SEC)
  3112. {
  3113. ptlnk->bSetTime = true;
  3114. }
  3115. // 检查测试帧超时
  3116. if(pt->bStartTest)//启动了
  3117. {
  3118. if(ustimer_get_duration(pt->us0_test_wait)>(tRunPara.w104AckTime*USTIMER_SEC))
  3119. {
  3120. // 测试帧没有及时返回,主动关闭连接
  3121. rt_printf_time("级联104(%d) 测试帧超时!\r\n",net);
  3122. net_104link_close(net);
  3123. return;
  3124. }
  3125. }
  3126. else if(ustimer_get_duration(pt->us0_test) > (tRunPara.w104TestTime*USTIMER_SEC))//超时测试
  3127. {
  3128. // 发送测试帧
  3129. lnk_104_ack(pt,FRAME_U_TEST);
  3130. pt->us0_test=ustimer_get_origin();
  3131. pt->us0_test_wait=ustimer_get_origin();
  3132. pt->bStartTest=true;
  3133. }
  3134. }
  3135. void lnk_104_app(int net)
  3136. {
  3137. //通道未建立连接,直接返回
  3138. if(!net_104link_is_connect(net))
  3139. {
  3140. return;
  3141. }
  3142. // 如果没有初始化,初始化
  3143. if(g_link104_init_ok[net] == 0)
  3144. {
  3145. lnk_104_init(net);
  3146. g_link104_init_ok[net] = 1;
  3147. }
  3148. lnk_104_app_recv(net);
  3149. lnk_104_app_send(net);
  3150. lnk_104_app_timer(net);
  3151. }
  3152. static void _lnk_104_recv_reset(IECLINK_DEF *pt)
  3153. {
  3154. pt->nTypeCounter=0;
  3155. pt->nRecvCnt=0;
  3156. }
  3157. void lnk_104_recv(int net,u8 cRcvData)
  3158. {
  3159. IECLINK_DEF *pt = &g_link_104[net];
  3160. pt->recvbuf[pt->nRecvCnt++]=cRcvData;
  3161. switch(pt->nTypeCounter)
  3162. {
  3163. case 0:
  3164. if( cRcvData==0x68)
  3165. {
  3166. pt->nTypeCounter=1;
  3167. }
  3168. else
  3169. {
  3170. _lnk_104_recv_reset(pt);
  3171. }
  3172. break;
  3173. case 1:
  3174. pt->nRecvLenth=cRcvData+2;
  3175. pt->nTypeCounter=2;
  3176. break;
  3177. case 2:
  3178. if(pt->nRecvCnt>=pt->nRecvLenth) /*报文接受完毕*/
  3179. {
  3180. _lnk_104_recv_reset(pt);
  3181. pt->bData=true;
  3182. g_net_104link_data[net]=1;
  3183. // 唤醒主循环
  3184. mainloop_wakeup();
  3185. }
  3186. break;
  3187. default:
  3188. _lnk_104_recv_reset(pt);
  3189. break;
  3190. }
  3191. }
  3192. int lnk_info_printf(void)
  3193. {
  3194. int i;
  3195. rt_printf("级联遥控信息:\n");
  3196. rt_printf("cp_m\tcp_s\tflg[0]\tflg[1]\tflg[2]\r\n");
  3197. for(i=0; i<SWITCH_NUM_EXT_PUB; i++)
  3198. {
  3199. LINKYK_DEF * yk;
  3200. yk = &g_lnk_yk[i];
  3201. rt_printf("%04x\t%04x\t%d\t%d\t%d\r\n",yk->cp_m,yk->cp_s,yk->flag[0],yk->flag[1],yk->flag[2]);
  3202. }
  3203. return 0;
  3204. }
  3205. /*********下面是文件传输,模拟主站程序,招目录后,招第一个文件******************/
  3206. void lnk_read_test_file(void)
  3207. {
  3208. int i;
  3209. for(i=0; i<CFG_LINK_101_NUM; i++)
  3210. {
  3211. if(tRunPara.tUartPara[i].wProtocol == PROTOCOL_101_M||tRunPara.tUartPara[i].wProtocol == PROTOCOL_101_PH_M)
  3212. {
  3213. ((IECLINK_DEF *)g_tRsComm[i].ptBuf)->tft.bDir = true;
  3214. }
  3215. }
  3216. for(i=0; i<CFG_LINK_104_NUM; i++)
  3217. {
  3218. g_link_104[i].tft.bDir= true;
  3219. }
  3220. }
  3221. void lnk_write_test_file(void)
  3222. {
  3223. int i;
  3224. for(i=0; i<CFG_LINK_101_NUM; i++)
  3225. {
  3226. if(tRunPara.tUartPara[i].wProtocol == PROTOCOL_101_M||tRunPara.tUartPara[i].wProtocol == PROTOCOL_101_PH_M)
  3227. {
  3228. ((IECLINK_DEF *)g_tRsComm[i].ptBuf)->tft.bUpdateStart = true;
  3229. }
  3230. }
  3231. for(i=0; i<CFG_LINK_104_NUM; i++)
  3232. {
  3233. g_link_104[i].tft.bUpdateStart= true;
  3234. }
  3235. }
  3236. bool lnk_file_check_trans(IECLINK_DEF *pt)
  3237. {
  3238. bool ret;
  3239. ret=pt->tft.bDir||pt->tft.bFile||pt->tft.bFileok||pt->tft.bwFile||pt->tft.bwTrans||pt->tft.b104ack||pt->tft.bUpdateStart||pt->tft.bUpdateEnd;
  3240. return ret;
  3241. }
  3242. void lnk_test_file_trans(IECLINK_DEF *pt)
  3243. {
  3244. char * strdir="/app/data/filetest/";
  3245. u8 dirlen;
  3246. dirlen=strlen(strdir);
  3247. if(pt->tft.bDir) //招目录
  3248. {
  3249. u8 dat[128];
  3250. int num=0;
  3251. dat[num++]=0; // 信息体地址
  3252. dat[num++]=0;
  3253. if(pt->type==IEC104_CHN)dat[num++]=0;
  3254. dat[num++]=2; // 附加数据包类型
  3255. dat[num++]=1; // 读目录
  3256. dat[num++]=0; // ID
  3257. dat[num++]=0;
  3258. dat[num++]=0;
  3259. dat[num++]=0;
  3260. dat[num++]=dirlen;
  3261. memcpy(&dat[num],strdir,dirlen);
  3262. num+=dirlen;
  3263. dat[num++]=0; // 召唤标识 :0 全部 :1 时间范围内
  3264. // 起始时间
  3265. dat[num++]=0; //MsL
  3266. dat[num++]=0; //MsH
  3267. dat[num++]=0; //Min
  3268. dat[num++]=0; //hour
  3269. dat[num++]=1; //Day
  3270. dat[num++]=1; //month
  3271. dat[num++]=17; //year
  3272. // 结束时间
  3273. dat[num++]=0; //MsL
  3274. dat[num++]=0; //MsH
  3275. dat[num++]=10; //Min
  3276. dat[num++]=15; //hour
  3277. dat[num++]=21; //Day
  3278. dat[num++]=2; //month
  3279. dat[num++]=17; //year
  3280. if(pt->type==IEC101_CHN)
  3281. {
  3282. lnk_101_call(pt,210,1,5,dat,num);
  3283. }
  3284. else
  3285. {
  3286. lnk_104_call(pt,210,1,5,dat,num);
  3287. }
  3288. pt->tft.bDir=false;
  3289. }
  3290. if(pt->tft.bFile) //召文件
  3291. {
  3292. u8 dat[128];
  3293. int num=0;
  3294. dat[num++]=0; // 信息体地址
  3295. dat[num++]=0;
  3296. if(pt->type==IEC104_CHN)dat[num++]=0;
  3297. dat[num++]=2; // 附加数据包类型
  3298. dat[num++]=3; // 读文件
  3299. dat[num++]=pt->tft.fnamelen;
  3300. memcpy(&dat[num],pt->tft.filename,pt->tft.fnamelen);
  3301. num+=pt->tft.fnamelen;
  3302. if(pt->type==IEC101_CHN)
  3303. {
  3304. lnk_101_call(pt,210,1,5,dat,num);
  3305. }
  3306. else
  3307. {
  3308. lnk_104_call(pt,210,1,5,dat,num);
  3309. }
  3310. pt->tft.bFile=false;
  3311. }
  3312. if(pt->tft.bFileok) //文件传输确认
  3313. {
  3314. u8 dat[128];
  3315. int num=0;
  3316. dat[num++]=0; // 信息体地址
  3317. dat[num++]=0;
  3318. if(pt->type==IEC104_CHN)dat[num++]=0;
  3319. dat[num++]=2; // 附加数据包类型
  3320. dat[num++]=6; // 读文件
  3321. dat[num++]=(u8)pt->tft.fileid; // ID
  3322. dat[num++]=(u8)(pt->tft.fileid>>8);
  3323. dat[num++]=(u8)(pt->tft.fileid>>16);
  3324. dat[num++]=(u8)(pt->tft.fileid>>24);
  3325. dat[num++]=(u8)pt->tft.offset; // 偏移
  3326. dat[num++]=(u8)(pt->tft.offset>>8);
  3327. dat[num++]=(u8)(pt->tft.offset>>16);
  3328. dat[num++]=(u8)(pt->tft.offset>>24);
  3329. dat[num++]=(pt->tft.offset+FILE_SEND_FRAME_LENTH)>=pt->tft.filelenth?0:1; // 有无后续
  3330. if(pt->type==IEC101_CHN)
  3331. {
  3332. lnk_101_call(pt,210,1,6,dat,num);
  3333. }
  3334. else
  3335. {
  3336. lnk_104_call(pt,210,1,6,dat,num);
  3337. }
  3338. pt->tft.bFileok=false;
  3339. }
  3340. if(pt->tft.bwFile) // 写文件
  3341. {
  3342. u8 dat[128];
  3343. int num=0;
  3344. char* ko_path ="/app/data/dftu.ko";
  3345. char *filename="dftu.ko";
  3346. int namelen=strlen(filename);
  3347. struct file *handle;
  3348. loff_t pos;
  3349. int ret;
  3350. handle= rt_file_open(ko_path,O_RDONLY ,0);
  3351. if(IS_ERR(handle))
  3352. {
  3353. rt_printf("打开%s,失败",ko_path);
  3354. pt->tft.bwFile=false;
  3355. return;
  3356. }
  3357. //得到文件长度
  3358. pt->tft.wfilelenth = rt_file_getfile_size(handle);
  3359. if(pt->tft.wfilelenth == 0)
  3360. {
  3361. rt_file_close(handle,0);
  3362. return;
  3363. }
  3364. //分配内存
  3365. pt->tft.wbuf = rt_malloc(pt->tft.wfilelenth);
  3366. if(pt->tft.wbuf == NULL)
  3367. {
  3368. pt->tft.bwFile=false;
  3369. rt_printf("%s: 分配内存失败\r\n",__func__);
  3370. return;
  3371. }
  3372. //读出文件内容
  3373. pos=0;
  3374. ret = rt_file_read(handle,pt->tft.wbuf, pt->tft.wfilelenth,&pos);
  3375. if(ret != pt->tft.wfilelenth)
  3376. {
  3377. rt_file_close(handle,0);
  3378. rt_printf("%s: read error:file_length=%d,ret=%d!\r\n",__func__,pt->tft.wfilelenth,ret);
  3379. pt->tft.bwFile=false;
  3380. rt_free(pt->tft.wbuf);
  3381. return ;
  3382. }
  3383. pt->tft.wId=0x1234;
  3384. dat[num++]=0; // 信息体地址
  3385. dat[num++]=0;
  3386. if(pt->type==IEC104_CHN)dat[num++]=0;
  3387. dat[num++]=2; // 附加数据包类型
  3388. dat[num++]=7; // 读文件
  3389. dat[num++]=namelen;
  3390. memcpy(&dat[num],filename,namelen);
  3391. num+=namelen;
  3392. dat[num++]=(u8)pt->tft.wId; // ID
  3393. dat[num++]=(u8)(pt->tft.wId>>8);
  3394. dat[num++]=(u8)(pt->tft.wId>>16);
  3395. dat[num++]=(u8)(pt->tft.wId>>24);
  3396. dat[num++]=(u8)pt->tft.wfilelenth; // ID
  3397. dat[num++]=(u8)(pt->tft.wfilelenth>>8);
  3398. dat[num++]=(u8)(pt->tft.wfilelenth>>16);
  3399. dat[num++]=(u8)(pt->tft.wfilelenth>>24);
  3400. if(pt->type==IEC101_CHN)
  3401. {
  3402. lnk_101_call(pt,210,1,6,dat,num);
  3403. }
  3404. else
  3405. {
  3406. lnk_104_call(pt,210,1,6,dat,num);
  3407. }
  3408. pt->tft.bwFile=false;
  3409. pt->tft.woffset=0;
  3410. rt_printf("%s:malloc:file_length=%d,ret=%d!\r\n",__func__,pt->tft.wfilelenth,ret);
  3411. }
  3412. if(pt->tft.bwTrans) // 写文件
  3413. {
  3414. u8 dat[256];
  3415. int num=0;
  3416. int i;
  3417. BYTE datalen=FILE_SEND_FRAME_LENTH;
  3418. bool beof=false;
  3419. BYTE checksum=0;
  3420. static u32 us0_1=0;
  3421. if((ustimer_get_duration(us0_1) <USTIMER_MS*6))//超时测试
  3422. {
  3423. return;
  3424. }
  3425. us0_1=ustimer_get_origin();
  3426. if((pt->tft.woffset+FILE_SEND_FRAME_LENTH)>=pt->tft.wfilelenth)
  3427. {
  3428. datalen=pt->tft.wfilelenth-pt->tft.woffset; //最后一帧传输的字节数
  3429. beof=true;
  3430. pt->tft.bwTrans=false;
  3431. }
  3432. dat[num++]=0; // 信息体地址
  3433. dat[num++]=0;
  3434. if(pt->type==IEC104_CHN)dat[num++]=0;
  3435. dat[num++]=2; // 附加数据包类型
  3436. dat[num++]=9; // 写文件
  3437. dat[num++]=(u8)pt->tft.wId; // ID
  3438. dat[num++]=(u8)(pt->tft.wId>>8);
  3439. dat[num++]=(u8)(pt->tft.wId>>16);
  3440. dat[num++]=(u8)(pt->tft.wId>>24);
  3441. dat[num++]=(u8)pt->tft.woffset; // 偏移
  3442. dat[num++]=(u8)(pt->tft.woffset>>8);
  3443. dat[num++]=(u8)(pt->tft.woffset>>16);
  3444. dat[num++]=(u8)(pt->tft.woffset>>24);
  3445. dat[num++]=beof?0:1; // 有无后续
  3446. for(i=0;i<datalen;i++)
  3447. {
  3448. BYTE dd;
  3449. dd=pt->tft.wbuf[pt->tft.woffset+i];
  3450. dat[num++] = dd;
  3451. checksum+=dd;
  3452. }
  3453. dat[num++]=checksum;
  3454. if(pt->type==IEC101_CHN)
  3455. {
  3456. lnk_101_call(pt,210,1,5,dat,num);
  3457. }
  3458. else
  3459. {
  3460. lnk_104_call(pt,210,1,5,dat,num);
  3461. }
  3462. if(beof)
  3463. {
  3464. if(!pt->tft.wbuf)
  3465. {
  3466. rt_free(pt->tft.wbuf);
  3467. pt->tft.wbuf=NULL;
  3468. }
  3469. rt_printf("%s:写文件传输完毕,释放内存",__func__);
  3470. }
  3471. if(pt->type==IEC101_CHN)
  3472. {
  3473. pt->tft.bwTrans=false;
  3474. }
  3475. if(pt->type==IEC104_CHN)
  3476. {
  3477. pt->tft.woffset+=FILE_SEND_FRAME_LENTH;
  3478. if(pt->tft.woffset>=pt->tft.wfilelenth)
  3479. {
  3480. pt->tft.bwTrans=false;
  3481. }
  3482. }
  3483. }
  3484. if(pt->tft.bUpdateStart) //文件升级启动
  3485. {
  3486. u8 dat[128];
  3487. int num=0;
  3488. dat[num++]=0; // 信息体地址
  3489. dat[num++]=0;
  3490. if(pt->type==IEC104_CHN)dat[num++]=0;
  3491. dat[num++]=0x80; // ctype
  3492. if(pt->type==IEC101_CHN)
  3493. {
  3494. lnk_101_call(pt,211,1,6,dat,num);
  3495. }
  3496. else
  3497. {
  3498. lnk_104_call(pt,211,1,6,dat,num);
  3499. }
  3500. pt->tft.bUpdateStart=false;
  3501. }
  3502. if(pt->tft.bUpdateEnd) //文件升级结束
  3503. {
  3504. u8 dat[128];
  3505. int num=0;
  3506. dat[num++]=0; // 信息体地址
  3507. dat[num++]=0;
  3508. if(pt->type==IEC104_CHN)dat[num++]=0;
  3509. dat[num++]=0x00; // ctype
  3510. if(pt->type==IEC101_CHN)
  3511. {
  3512. lnk_101_call(pt,211,1,6,dat,num);
  3513. }
  3514. else
  3515. {
  3516. lnk_104_call(pt,211,1,6,dat,num);
  3517. }
  3518. pt->tft.bUpdateEnd=false;
  3519. }
  3520. if(pt->tft.b104ack)
  3521. {
  3522. lnk_104_sAck(pt);
  3523. pt->tft.b104ack=false;
  3524. }
  3525. }
  3526. void lnk_test_file_frame(IECLINK_DEF *pt,u8 *pdat,u8 framelen) //
  3527. {
  3528. u8 cmd ,*pd;
  3529. int i;
  3530. #ifdef RCD_STRAN_M
  3531. s32 ret=0;
  3532. char tmp[128],tmp1[128];
  3533. static s32 testnum=0;
  3534. struct dir_file_ext_struct *pdfs;
  3535. struct dir_file_ext_struct *pdfs_min=0;
  3536. int file_cnt = 0;
  3537. u8 flag=0;
  3538. #endif
  3539. pdat+=1;
  3540. cmd=pdat[0];
  3541. if(cmd==1) // 目录
  3542. {
  3543. rt_printf("\r\n 收到目录 成功标识:%d ID:%d 后续标识:%d 文件数量:%d\r\n",pdat[1],(pdat[2]|(pdat[3]<<8)|(pdat[4]<<16)|(pdat[5]<<24)),pdat[6],pdat[7]);
  3544. pd=&pdat[8];
  3545. for(i=0;i<pdat[7];i++) //文件
  3546. {
  3547. u8 namestr[64],namelen;
  3548. u32 filelen;
  3549. namelen=pd[0];
  3550. if(namelen>63)
  3551. {
  3552. rt_printf("\r\n文件长度错误!");
  3553. break;
  3554. }
  3555. memcpy(namestr,&pd[1],namelen);
  3556. namestr[namelen]='\0';
  3557. pd+=namelen+2;
  3558. filelen=(pd[0]|(pd[1]<<8)|(pd[2]<<16)|(pd[3]<<24));
  3559. pd+=4;
  3560. rt_printf("\r\n 文件名长度:%d 名称:%s 长度:%d 时间:%d-%d-%d %d:%d:%d.%d\r\n",namelen,namestr,filelen,pd[6],pd[5],pd[4],pd[3],pd[2],(pd[1]*256+pd[0])/1000,(pd[1]*256+pd[0])%1000);
  3561. pd+=7;
  3562. if(i==0)
  3563. {
  3564. pt->tft.filelenth=filelen;
  3565. pt->tft.fnamelen=namelen;
  3566. memcpy(pt->tft.filename,namestr,namelen);
  3567. pt->tft.bFile=true;
  3568. }
  3569. }
  3570. }
  3571. if(cmd==4) // 读文件激活
  3572. {
  3573. u8 namestr[64],namelen;
  3574. u32 id,filelen;
  3575. pd=&pdat[2];
  3576. namelen=pd[0];
  3577. if(namelen>63)
  3578. {
  3579. rt_printf("\r\n文件长度错误!");
  3580. return;
  3581. }
  3582. memcpy(namestr,&pd[1],namelen);
  3583. namestr[namelen]='\0';
  3584. pd+=namelen+1;
  3585. id=pd[0]|(pd[1]<<8)|(pd[2]<<16)|(pd[3]<<24);
  3586. pd+=4;
  3587. filelen=pd[0]|(pd[1]<<8)|(pd[2]<<16)|(pd[3]<<24);
  3588. rt_printf("\r\n 文件名长度:%d 名称:%s 长度:%d id:%d\r\n",namelen,namestr,filelen,id);
  3589. //pt->tft.bFile=true;
  3590. {
  3591. if(pt->type==IEC104_CHN)
  3592. {
  3593. char fnstr[64];
  3594. sprintf(fnstr,"/tmp/rmtfile_%d",pt->chnl);
  3595. pt->tft.handle = rt_file_open(fnstr,O_CREAT|O_RDWR|O_TRUNC,0);
  3596. if(IS_ERR(pt->tft.handle))
  3597. {
  3598. pt->tft.handle = 0;
  3599. rt_printf("%s创建失败!\r\n",fnstr);
  3600. pt->tft.bFile=false;
  3601. return ;
  3602. }
  3603. }
  3604. else
  3605. {
  3606. //创建文件
  3607. char *fnstr="/app/data/rmtfile";
  3608. pt->tft.handle = rt_file_open(fnstr,O_CREAT|O_RDWR|O_TRUNC,0);
  3609. if(IS_ERR(pt->tft.handle))
  3610. {
  3611. pt->tft.handle = 0;
  3612. rt_printf("%s创建失败!\r\n",fnstr);
  3613. pt->tft.bFile=false;
  3614. return ;
  3615. }
  3616. }
  3617. }
  3618. pt->tft.fileid=id;
  3619. pt->tft.filelenth=filelen;
  3620. pt->tft.us0_file_trans = ustimer_get_origin();
  3621. }
  3622. if(cmd==5) // 读文件响应
  3623. {
  3624. loff_t pos;
  3625. u32 id,offset;
  3626. pd=&pdat[1];
  3627. id=pd[0]|(pd[1]<<8)|(pd[2]<<16)|(pd[3]<<24);
  3628. pd+=4;
  3629. offset=pd[0]|(pd[1]<<8)|(pd[2]<<16)|(pd[3]<<24);
  3630. #ifdef RCD_STRAN_M
  3631. pd+=4;
  3632. flag = *pd++; /*结束标识*/
  3633. pos=offset;
  3634. if(pt->tft.bTransing == false) return;
  3635. rt_file_write(pt->tft.handle,pd,framelen-11,&pos);
  3636. if(flag == 0)
  3637. {
  3638. rt_file_close(pt->tft.handle,0);
  3639. if(strncmp(pt->tft.filename,"BAY",3) == 0) /*录波文件*/
  3640. {
  3641. if(pt->type==IEC104_CHN)
  3642. {
  3643. sprintf(pt->tft.filename, "BAY%02d%s", pt->chnl+1,pt->tft.filename+5); /*104替换成级联通道号*/
  3644. }
  3645. sprintf(tmp, "%s传输完成!!!",pt->tft.filename);
  3646. log_str_time(LOG_OPERATE,tmp,0,1);
  3647. sprintf(tmp, "%s%s", HF_WAVE_DIR,pt->tft.filename);
  3648. if(pt->type==IEC104_CHN)
  3649. {
  3650. sprintf(tmp1,"/tmp/rmtfile_%d",pt->chnl);
  3651. ret = rt_file_mv(tmp1, tmp);
  3652. }
  3653. else
  3654. {
  3655. ret = rt_file_mv("/app/data/rmtfile", tmp);
  3656. }
  3657. if(ret != 0)
  3658. {
  3659. rt_printf("%s 文件移动失败(ret=%d)!\r\n","/app/data/rmtfile",ret);
  3660. rt_file_del("/app/data/rmtfile");
  3661. }
  3662. sprintf(tmp, "/tmp/dev_rcd_%d",(int)testnum++);
  3663. pdfs = hf_get_dir_file_ext(HF_WAVE_DIR, &file_cnt, tmp);
  3664. if((file_cnt) > (NEWRCD_COUNT_M*2)*2)
  3665. {
  3666. rt_printf("file_cnt=%d***********************************\r\n",file_cnt);
  3667. //找到最早的文件,并删除
  3668. pdfs_min = pdfs;
  3669. for(i=1;i<file_cnt;i++)
  3670. {
  3671. if(strncmp(pdfs[i].file_name+11, pdfs_min->file_name+11, 19) < 0)
  3672. {
  3673. pdfs_min = &pdfs[i];
  3674. }
  3675. }
  3676. //因为文件以及已经排好序,找到第一个是cfg文件,第二个是dat文件
  3677. //先删除.cfg文件
  3678. sprintf(tmp, "%s%s", HF_WAVE_DIR,pdfs_min->file_name);
  3679. rt_file_del(tmp);
  3680. sprintf(tmp, "%s%s", HF_WAVE_DIR,pdfs_min[1].file_name);
  3681. rt_file_del(tmp);
  3682. }
  3683. if(pdfs)
  3684. {
  3685. rt_free(pdfs);
  3686. }
  3687. }
  3688. pt->tft.bTransing =false;
  3689. pt->tft.bFileok=false;
  3690. pt->tft.offset=offset;
  3691. }
  3692. else
  3693. {
  3694. if(pt->type==IEC104_CHN) pt->tft.b104ack=true;
  3695. pt->tft.us0_file_trans = ustimer_get_origin();
  3696. }
  3697. #else
  3698. pd+=5;
  3699. pos=offset;
  3700. rt_file_write(pt->tft.handle,pd,framelen-11,&pos);
  3701. if(offset+FILE_SEND_FRAME_LENTH>=pt->tft.filelenth)
  3702. {
  3703. rt_file_close(pt->tft.handle,0);
  3704. rt_printf("文件传输完毕!\r\n");
  3705. pt->tft.bFileok=true;
  3706. pt->tft.offset=offset;
  3707. }
  3708. else if(pt->type==IEC101_CHN)
  3709. {
  3710. pt->tft.bFileok=true;
  3711. pt->tft.offset=offset;
  3712. }
  3713. else if(pt->type==IEC104_CHN)
  3714. {
  3715. pt->tft.b104ack=true;
  3716. }
  3717. #endif
  3718. }
  3719. if(cmd==8) //写文件激活
  3720. {
  3721. pt->tft.bwTrans=true;
  3722. pt->tft.woffset=0;
  3723. }
  3724. if(cmd==10) //写文件确认
  3725. {
  3726. u32 id,offset;
  3727. pd=&pdat[1];
  3728. id=pd[0]|(pd[1]<<8)|(pd[2]<<16)|(pd[3]<<24);
  3729. pd+=4;
  3730. offset=pd[0]|(pd[1]<<8)|(pd[2]<<16)|(pd[3]<<24);
  3731. pd+=5;
  3732. pt->tft.bwTrans=true;
  3733. pt->tft.woffset=offset+FILE_SEND_FRAME_LENTH;
  3734. if(pt->tft.woffset>=pt->tft.wfilelenth)
  3735. {
  3736. pt->tft.bwTrans=false;
  3737. if(pdat[9]==0)
  3738. {
  3739. pt->tft.bUpdateEnd=true;
  3740. }
  3741. }
  3742. }
  3743. }
  3744. void lnk_update_file_frame(IECLINK_DEF *pt,u8 ctype) //
  3745. {
  3746. if(ctype&0x80) // 目录
  3747. {
  3748. pt->tft.bwFile=true;
  3749. }
  3750. }
  3751. /************************endfile**********************/