12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831 |
- /*
- This software is subject to the license described in the License.txt file
- included with this software distribution. You may not use this file except in compliance
- with this license.
- Copyright (c) Dynastream Innovations Inc. 2013
- All rights reserved.
- */
- #include "types.h"
- #include "dsi_framer_ant.hpp"
- #include "dsi_serial_generic.hpp"
- #include "dsi_thread.h"
- #include "dsi_timer.hpp"
- #include "dsi_convert.h"
- #include "crc.h"
- #include "antfs_host_channel.hpp"
- #include "antfsmessage.h"
- #include "config.h"
- #include "dsi_debug.hpp"
- #if defined(DEBUG_FILE)
- #include "macros.h"
- #endif
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <time.h>
- //////////////////////////////////////////////////////////////////////////////////
- // Private Definitions
- //////////////////////////////////////////////////////////////////////////////////
- #define TRANSPORT_NETWORK ((UCHAR) 0)
- #define TRANSPORT_MESSAGE_PERIOD ((USHORT) 4096) // 8Hz default
- #define TRANSPORT_MESSAGE_PERIOD_CODE ((UCHAR) 4) // 8Hz default
- #define TRANSPORT_SEARCH_TIMEOUT ((UCHAR) 3) // ~7.5 Seconds.
- #define HOST_SERIAL_NUMBER ((ULONG) 1) // Use if not configured otherwise
- #define UPLOAD_PROGRESS_CHECK_BYTES ((ULONG) 64) // 64 bytes (8 packets) have to be transfered in order to reset the UL loop timeout.
- #define ADDRESS_TYPE_PAGE_OFFSET 3
- #define ADDRESS_TYPE_PAGE_SMALL_0 ((UCHAR) 0x00) // Default; page contains both data offset and data block size.
- #define ADDRESS_TYPE_PAGE_SMALL_1 ((UCHAR) 0x01) // Contains total remaining data length (in response)
- #define ADDRESS_TYPE_PAGE_BIG_0 ((UCHAR) 0x02) // Page contains data offset.
- #define ADDRESS_TYPE_PAGE_BIG_1 ((UCHAR) 0x03) // Page contains data block size.
- #define ADDRESS_TYPE_PAGE_BIG_2 ((UCHAR) 0x04) // Page contains total remaining data length (in response)
- #define DATA_OFFSET_OFFSET_LOW 4
- #define DATA_OFFSET_OFFSET_HIGH 5
- #define DATA_BLOCK_SIZE_OFFSET_LOW 6
- #define DATA_BLOCK_SIZE_OFFSET_HIGH 7
- // ID Command
- #define ID_OFFSET_0 4
- #define ID_OFFSET_1 5
- #define ID_OFFSET_2 6
- #define ID_OFFSET_3 7
- #define ANTFS_RESPONSE_RETRIES 5
- #define SEND_DIRECT_BURST_TIMEOUT 15000 // 15 seconds.
- #define STRIKE_COUNT 2
- #define MAX_STALE_COUNT ((UCHAR) 100)
- #define MAJOR_STALE_COUNT ((UCHAR) 50)
- #define MINOR_STALE_COUNT ((UCHAR) 25)
- #define MIN_STALE_COUNT ((UCHAR) 1)
- typedef void (*CALLBACK_T)(void);
- static const UCHAR caucNetworkKey[] = NETWORK_KEY;
- static const char acSwVersion[] = SW_VER;
- //////////////////////////////////////////////////////////////////////////////////
- // Private Function Prototypes
- //////////////////////////////////////////////////////////////////////////////////
- static int ListCompare(const void *puvKeyVal, const void *puvDatum);
- static int DeviceParametersItemCompare(const void *pvItem1, const void *pvItem2);
- //////////////////////////////////////////////////////////////////////////////////
- // Public Functions
- //////////////////////////////////////////////////////////////////////////////////
- ANTFSHostChannel::ANTFSHostChannel()
- {
- bInitFailed = FALSE;
- bIgnoreListRunning = FALSE;
- bPingEnabled = FALSE;
- bRequestPageEnabled = FALSE;
- // Default channel configuration
- ucChannelNumber = ANTFS_CHANNEL;
- ucNetworkNumber = ANTFS_NETWORK;
- ucTheDeviceType = ANTFS_DEVICE_TYPE;
- ucTheTransmissionType = ANTFS_TRANSMISSION_TYPE;
- usTheMessagePeriod = ANTFS_MESSAGE_PERIOD;
- ucTheProxThreshold = 0; //0=Disabled
- memcpy(aucTheNetworkkey,caucNetworkKey,8);
-
- // Host configuration
- ulHostSerialNumber = HOST_SERIAL_NUMBER;
- hANTFSThread = (DSI_THREAD_ID)NULL; // Handle for the ANTFS thread
- bKillThread = FALSE;
- bANTFSThreadRunning = FALSE;
- pclANT = (DSIFramerANT*) NULL;
- pbCancel = &bCancel;
- *pbCancel = FALSE;
- // Ignore List variables
- usListIndex = 0;
- memset(astIgnoreList, 0, sizeof(astIgnoreList));
- pclQueueTimer = (DSITimer*)NULL;
- ucTransportFrequencyStaleCount = 0;
- ucCurrentTransportFreqElement = 0;
- memset(aucFrequencyTable, 0, sizeof(aucFrequencyTable));
- memset(asDeviceParametersList, 0, sizeof(asDeviceParametersList));
- usDeviceListSize = 0;
- eANTFSState = ANTFS_HOST_STATE_OFF;
- ResetHostState();
- // Debugging is initialized by DSIANTDevice (or ANTDevice in Managed Lib)
- if (DSIThread_MutexInit(&stMutexCriticalSection) != DSI_THREAD_ENONE)
- {
- bInitFailed = TRUE;
- }
- if (DSIThread_MutexInit(&stMutexResponseQueue) != DSI_THREAD_ENONE)
- {
- bInitFailed = TRUE;
- }
- if (DSIThread_CondInit(&stCondANTFSThreadExit) != DSI_THREAD_ENONE)
- {
- bInitFailed = TRUE;
- }
- if (DSIThread_CondInit(&stCondRequest) != DSI_THREAD_ENONE)
- {
- bInitFailed = TRUE;
- }
- if (DSIThread_CondInit(&stCondRxEvent) != DSI_THREAD_ENONE)
- {
- bInitFailed = TRUE;
- }
- if (DSIThread_CondInit(&stCondWaitForResponse) != DSI_THREAD_ENONE)
- {
- bInitFailed = TRUE;
- }
- //If the init fails, something is broken and nothing is going to work anyway
- //additionally the logging isn't even setup at this point
- //so we throw an exception so we know something is broken right away
- if(bInitFailed == TRUE)
- throw "ANTFS constructor: init failed";
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFSHostChannel::~ANTFSHostChannel()
- {
- this->Close();
- if (bInitFailed == FALSE)
- {
- DSIThread_MutexDestroy(&stMutexCriticalSection);
- DSIThread_MutexDestroy(&stMutexResponseQueue);
- DSIThread_CondDestroy(&stCondANTFSThreadExit);
- DSIThread_CondDestroy(&stCondRequest);
- DSIThread_CondDestroy(&stCondRxEvent);
- DSIThread_CondDestroy(&stCondWaitForResponse);
- }
- }
- ///////////////////////////////////////////////////////////////////////
- UCHAR ANTFSHostChannel::GetVersion(UCHAR *pucVersionString_, UCHAR ucBufferSize_)
- {
- ucBufferSize_--; // Allow for NULL cstring termination.
- if (ucBufferSize_ > sizeof(acSwVersion))
- ucBufferSize_ = sizeof(acSwVersion);
- memcpy(pucVersionString_, acSwVersion, ucBufferSize_);
- pucVersionString_[ucBufferSize_++] = '\0'; // Terminate the string and increment the size.
- return ucBufferSize_; // Return the string size, including the terminator.
- }
- ///////////////////////////////////////////////////////////////////////
- BOOL ANTFSHostChannel::Init(DSIFramerANT* pclANT_, UCHAR ucChannel_)
- {
- if (bInitFailed == TRUE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Init(): bInitFailed == TRUE");
- #endif
- return FALSE;
- }
- ucChannelNumber = ucChannel_;
- pclANT = pclANT_;
- if(pclANT)
- {
- if(pclANT->GetCancelParameter() == (BOOL*) NULL) // If cancel parameter has not been configured in framer, use internal
- pclANT->SetCancelParameter(pbCancel);
- else // Use cancel parameter configured in framer
- pbCancel = pclANT->GetCancelParameter();
- }
- return ReInitDevice();
- }
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::SetChannelID(UCHAR ucDeviceType_, UCHAR ucTransmissionType_)
- {
- ucTheDeviceType = ucDeviceType_;
- ucTheTransmissionType = ucTransmissionType_;
- }
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::SetChannelPeriod(USHORT usChannelPeriod_)
- {
- usTheMessagePeriod = usChannelPeriod_;
- }
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::SetNetworkKey(UCHAR ucNetwork_, UCHAR ucNetworkkey[])
- {
- ucNetworkNumber = ucNetwork_;
- memcpy(aucTheNetworkkey,ucNetworkkey,8);
- }
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::SetProximitySearch(UCHAR ucSearchThreshold_)
- {
- if(ucSearchThreshold_ > 10) //Depending on device higher thresholds can be ignored, cause undefined consequences, or even have different functionality assigned to them, so we cap at the valid 0-10 range
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::SetProximitySearch(): User threshold value > 10, setting to max 10.");
- #endif
- ucSearchThreshold_ = 10;
- }
- ucTheProxThreshold = ucSearchThreshold_;
- }
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::SetSerialNumber(ULONG ulSerialNumber_)
- {
- ulHostSerialNumber = ulSerialNumber_;
- }
- ///////////////////////////////////////////////////////////////////////
- BOOL ANTFSHostChannel::GetEnabled()
- {
- if(eANTFSState < ANTFS_HOST_STATE_DISCONNECTING)
- {
- return FALSE;
- }
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFS_HOST_STATE ANTFSHostChannel::GetStatus(void)
- {
- return eANTFSState;
- }
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::Close(void)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Close(): Closing ANTFS...");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- // Stop the threads.
- bKillThread = TRUE;
- *pbCancel = TRUE;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Close(): SetEvent(stCondWaitForResponse).");
- #endif
- DSIThread_MutexLock(&stMutexResponseQueue);
- DSIThread_CondSignal(&stCondWaitForResponse);
- clResponseQueue.Clear();
- DSIThread_MutexUnlock(&stMutexResponseQueue);
- if (hANTFSThread)
- {
- if (bANTFSThreadRunning == TRUE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Close(): SetEvent(stCondRequest).");
- #endif
- DSIThread_CondSignal(&stCondRequest);
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Close(): SetEvent(stCondRxEvent).");
- #endif
- DSIThread_CondSignal(&stCondRxEvent);
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Close(): Killing thread.");
- #endif
- if (DSIThread_CondTimedWait(&stCondANTFSThreadExit, &stMutexCriticalSection, 9000) != DSI_THREAD_ENONE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Close(): Thread not dead.");
- DSIDebug::ThreadWrite("ANTFSHostChannel::Close(): Forcing thread termination...");
- #endif
- DSIThread_DestroyThread(hANTFSThread);
- }
- else
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Close(): Thread terminated successfully.");
- #endif
- }
- }
- DSIThread_ReleaseThreadID(hANTFSThread);
- hANTFSThread = (DSI_THREAD_ID)NULL;
- }
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- if (bIgnoreListRunning)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Close(): Deleting Timer Queue Timer...");
- #endif
- delete pclQueueTimer;
- pclQueueTimer = (DSITimer*)NULL;
- DSIThread_MutexDestroy(&stMutexIgnoreListAccess);
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Close(): Deleted Timer Queue Timer.");
- #endif
- bIgnoreListRunning = FALSE;
- }
- eANTFSState = ANTFS_HOST_STATE_OFF;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Close(): Closed.");
- #endif
- if (pucTransferBufferDynamic)
- {
- if (pucTransferBuffer == pucTransferBufferDynamic)
- pucTransferBuffer = (UCHAR*)NULL;
- delete[] pucTransferBufferDynamic;
- pucTransferBufferDynamic = (UCHAR*)NULL;
- }
- }
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::Cancel(void)
- {
- DSIThread_MutexLock(&stMutexCriticalSection);
- *pbCancel = TRUE;
- DSIThread_CondSignal(&stCondRxEvent);
- DSIThread_CondSignal(&stCondRequest);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return;
- }
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::ProcessDeviceNotification(ANT_DEVICE_NOTIFICATION eCode_, void* pvParameter_)
- {
- DSIThread_MutexLock(&stMutexCriticalSection);
- if(eCode_ != ANT_DEVICE_NOTIFICATION_RESET &&
- eCode_ != ANT_DEVICE_NOTIFICATION_SHUTDOWN)
- {
- #if defined(DEBUG_FILE)
- UCHAR aucString[256];
- SNPRINTF((char *) aucString, 256, "ANTFSHostChannel::ProcessDeviceNotification(): Unknown code %0", eCode_);
- DSIDebug::ThreadWrite((char *) aucString);
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return;
- }
- if(eANTFSState <= ANTFS_HOST_STATE_IDLE)
- {
- // We do not need to do anything, since ANT-FS is already in idle state
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return;
- }
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ProcessDeviceNotification(): Resetting state...");
- #endif
- *pbCancel = TRUE;
- eANTFSRequest = ANTFS_REQUEST_INIT;
- DSIThread_CondSignal(&stCondRxEvent);
- DSIThread_CondSignal(&stCondRequest);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return;
- }
- ///////////////////////////////////////////////////////////////////////
- #define MESG_CHANNEL_OFFSET 0
- #define MESG_EVENT_ID_OFFSET 1
- #define MESG_EVENT_CODE_OFFSET 2
- void ANTFSHostChannel::ProcessMessage(ANT_MESSAGE* pstMessage_, USHORT usMesgSize_)
- {
- UCHAR ucANTChannel;
- BOOL bProcessed = FALSE;
- // Check that we are in the correct state to receive messages
- if(!GetEnabled())
- return; // Only process ANT messages if ANT-FS is on
- if (usMesgSize_ < DSI_FRAMER_TIMEDOUT) //if the return isn't DSI_FRAMER_TIMEDOUT or DSI_FRAMER_ERROR
- {
- ucANTChannel = pstMessage_->aucData[MESG_CHANNEL_OFFSET] & CHANNEL_NUMBER_MASK;
- if(!FilterANTMessages(pstMessage_, ucANTChannel))
- return; // Wrong channel, do not process
- switch (pstMessage_->ucMessageID)
- {
- case MESG_RESPONSE_EVENT_ID:
- if (pstMessage_->aucData[MESG_EVENT_ID_OFFSET] != MESG_EVENT_ID) // this is a response
- {
- memcpy(aucResponseBuf, pstMessage_->aucData, MESG_RESPONSE_EVENT_SIZE);
- bProcessed = ANTProtocolEventProcess(ucANTChannel, MESG_RESPONSE_EVENT_ID);
- }
- else // this is an event
- {
- memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
- bProcessed = ANTChannelEventProcess(ucANTChannel, pstMessage_->aucData[MESG_EVENT_CODE_OFFSET]); // pass through any events not handled here
- }
- break;
- case MESG_BROADCAST_DATA_ID:
- //Call channel event function with Broadcast message code
- memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
- bProcessed = ANTChannelEventProcess(ucANTChannel, EVENT_RX_BROADCAST);
- break;
- case MESG_ACKNOWLEDGED_DATA_ID:
- //Call channel event function with Acknowledged message code
- memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
- bProcessed = ANTChannelEventProcess(ucANTChannel, EVENT_RX_ACKNOWLEDGED);
- break;
- case MESG_BURST_DATA_ID:
- //Call channel event function with Burst message code
- memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
- bProcessed = ANTChannelEventProcess(ucANTChannel, EVENT_RX_BURST_PACKET);
- break;
- case MESG_EXT_BROADCAST_DATA_ID:
- //Call channel event function with Broadcast message code
- memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
- bProcessed = ANTChannelEventProcess(ucANTChannel, EVENT_RX_EXT_BROADCAST);
- break;
- case MESG_EXT_ACKNOWLEDGED_DATA_ID:
- //Call channel event function with Acknowledged message code
- memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
- bProcessed = ANTChannelEventProcess(ucANTChannel, EVENT_RX_EXT_ACKNOWLEDGED);
- break;
- case MESG_EXT_BURST_DATA_ID:
- //Call channel event function with Burst message code
- memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
- bProcessed = ANTChannelEventProcess(ucANTChannel, EVENT_RX_EXT_BURST_PACKET);
- break;
- case MESG_RSSI_BROADCAST_DATA_ID:
- //Call channel event function with Broadcast message code
- memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
- bProcessed = ANTChannelEventProcess(ucANTChannel, EVENT_RX_RSSI_BROADCAST);
- break;
- case MESG_RSSI_ACKNOWLEDGED_DATA_ID:
- //Call channel event function with Acknowledged message code
- memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
- bProcessed = ANTChannelEventProcess(ucANTChannel, EVENT_RX_RSSI_ACKNOWLEDGED);
- break;
- case MESG_RSSI_BURST_DATA_ID:
- //Call channel event function with Burst message code
- memcpy(aucRxBuf, pstMessage_->aucData, usMesgSize_);
- bProcessed = ANTChannelEventProcess(ucANTChannel, EVENT_RX_RSSI_BURST_PACKET);
- break;
- default:
- memcpy(aucResponseBuf, pstMessage_->aucData, usMesgSize_);
- bProcessed = ANTProtocolEventProcess(ucANTChannel, pstMessage_->ucMessageID );
- break;
- }
- }
- return;
- }
- //////////////////////////////////////////////////////////////////////////////////
- // ANTFS Link Layer
- //////////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////
- USHORT ANTFSHostChannel::AddSearchDevice(ANTFS_DEVICE_PARAMETERS *pstDeviceSearchMask_, ANTFS_DEVICE_PARAMETERS *pstDeviceParameters_)
- {
- USHORT usHandle;
- if (usDeviceListSize >= SEARCH_DEVICE_LIST_MAX_SIZE)
- return 0;
- // Find the next available handle.
- usHandle = 0;
- while (usHandle < usDeviceListSize)
- {
- if ((usHandle + 1) < asDeviceParametersList[usHandle].usHandle)
- break;
- usHandle++;
- }
- asDeviceParametersList[usDeviceListSize].usHandle = ++usHandle;
- asDeviceParametersList[usDeviceListSize].sDeviceParameters = *pstDeviceParameters_;
- asDeviceParametersList[usDeviceListSize].sDeviceSearchMask = *pstDeviceSearchMask_;
- usDeviceListSize++;
- qsort(asDeviceParametersList, usDeviceListSize, sizeof(DEVICE_PARAMETERS_ITEM), &DeviceParametersItemCompare);
- return usHandle;
- }
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::RemoveSearchDevice(USHORT usHandle_)
- {
- DEVICE_PARAMETERS_ITEM sDeviceParametersItem;
- DEVICE_PARAMETERS_ITEM *psDeviceParametersItem;
- if (usDeviceListSize == 0)
- return; // Nothing to do.
- // Find the handle in the list.
- sDeviceParametersItem.usHandle = usHandle_;
- psDeviceParametersItem =(DEVICE_PARAMETERS_ITEM *) bsearch(&sDeviceParametersItem, asDeviceParametersList, usDeviceListSize, sizeof(DEVICE_PARAMETERS_ITEM), &DeviceParametersItemCompare);
- if (psDeviceParametersItem != NULL)
- {
- psDeviceParametersItem->usHandle = MAX_USHORT; // Make it invalid.
- qsort(asDeviceParametersList, usDeviceListSize, sizeof(DEVICE_PARAMETERS_ITEM), &DeviceParametersItemCompare); // Sorting will cause the large invalid item to drop to the end of the list.
- usDeviceListSize--; // Reduce the size to reflect that the item has been removed.
- }
- }
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::ClearSearchDeviceList(void)
- {
- usDeviceListSize = 0;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFS_RETURN ANTFSHostChannel::SearchForDevice(UCHAR ucSearchRadioFrequency_, UCHAR ucConnectedRadioFrequency_, USHORT usRadioChannelID_, BOOL bUseRequestPage_)
- {
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest != ANTFS_REQUEST_NONE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::SearchForDevice(): Request Busy.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_BUSY;
- }
- if (eANTFSState != ANTFS_HOST_STATE_IDLE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::SearchForDevice(): Not in correct state.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_FAIL;
- }
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::SearchForDevice(): Search starting...");
- #endif
- ucSearchRadioFrequency = ucSearchRadioFrequency_;
- ucTransportFrequencySelection = ucConnectedRadioFrequency_;
- usRadioChannelID = usRadioChannelID_;
- bRequestPageEnabled = bUseRequestPage_;
- eANTFSRequest = ANTFS_REQUEST_SEARCH;
- DSIThread_CondSignal(&stCondRequest);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::SearchForDevice(): Search request pending...");
- #endif
- return ANTFS_RETURN_PASS;
- }
- ///////////////////////////////////////////////////////////////////////
- BOOL ANTFSHostChannel::GetFoundDeviceParameters(ANTFS_DEVICE_PARAMETERS *pstDeviceParameters_, UCHAR *aucFriendlyName_, UCHAR *pucBufferSize_)
- {
- if (eANTFSState < ANTFS_HOST_STATE_CONNECTED)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::GetFoundDeviceParameters(): Not in correct state.");
- #endif
- return FALSE;
- }
- memcpy(pstDeviceParameters_, &stFoundDeviceParameters, sizeof(ANTFS_DEVICE_PARAMETERS));
- if (ucRemoteFriendlyNameLength < *pucBufferSize_)
- *pucBufferSize_ = ucRemoteFriendlyNameLength;
- memcpy(aucFriendlyName_, aucRemoteFriendlyName, *pucBufferSize_);
- *pucBufferSize_ = ucRemoteFriendlyNameLength;
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////
- BOOL ANTFSHostChannel::GetFoundDeviceChannelID(USHORT *pusDeviceNumber_, UCHAR *pucDeviceType_, UCHAR *pucTransmitType_)
- {
- if (eANTFSState < ANTFS_HOST_STATE_CONNECTED)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::GetFoundDeviceChannelID(): Not in correct state.");
- #endif
- return FALSE;
- }
- if(pusDeviceNumber_ != NULL)
- *pusDeviceNumber_ = usFoundANTFSDeviceID;
- if(pucDeviceType_ != NULL)
- *pucDeviceType_ = ucFoundANTDeviceType;
- if(pucTransmitType_ != NULL)
- *pucTransmitType_ = ucFoundANTTransmitType;
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFS_RETURN ANTFSHostChannel::RequestSession(UCHAR ucBroadcastRadioFrequency_, UCHAR ucConnectRadioFrequency_)
- {
- DSIThread_MutexLock(&stMutexCriticalSection);
- if(eANTFSRequest != ANTFS_REQUEST_NONE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::RequestSession(): Request Busy.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_BUSY;
- }
- if(eANTFSState != ANTFS_HOST_STATE_IDLE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::RequestSession(): Not in correct state.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_BUSY;
- }
- ucTransportLayerRadioFrequency = ucConnectRadioFrequency_;
- ucSearchRadioFrequency = ucBroadcastRadioFrequency_;
- eANTFSRequest = ANTFS_REQUEST_SESSION_REQ;
- DSIThread_CondSignal(&stCondRequest);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::RequestSession(): Request for ANT-FS session pending...");
- #endif
- return ANTFS_RETURN_PASS;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFS_RETURN ANTFSHostChannel::Authenticate(UCHAR ucAuthenticationType_, UCHAR *pucAuthenticationString_, UCHAR ucLength_, UCHAR *pucResponseBuffer_, UCHAR *pucResponseBufferSize_, ULONG ulResponseTimeout_)
- {
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest != ANTFS_REQUEST_NONE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Authenticate(): Request Busy.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_BUSY;
- }
- if (eANTFSState != ANTFS_HOST_STATE_CONNECTED)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Authenticate(): Not in correct state.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_FAIL;
- }
- ucTxPasswordLength = ucLength_;
- ucAuthType = ucAuthenticationType_;
- pucResponseBuffer = pucResponseBuffer_;
- pucResponseBufferSize = pucResponseBufferSize_;
- ulAuthResponseTimeout = ulResponseTimeout_;
- memcpy(aucTxPassword, pucAuthenticationString_, ucTxPasswordLength);
- //may switch on Auth type here...
- eANTFSRequest = ANTFS_REQUEST_AUTHENTICATE;
- DSIThread_CondSignal(&stCondRequest);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_PASS;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFS_RETURN ANTFSHostChannel::Disconnect(USHORT usBlackoutTime_, UCHAR ucDisconnectType_, UCHAR ucTimeDuration_, UCHAR ucAppSpecificDuration_)
- {
- ANTFS_RETURN eReturn = ANTFS_RETURN_PASS;
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest != ANTFS_REQUEST_NONE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Disconnect(): Request Busy.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_BUSY;
- }
- if (eANTFSState < ANTFS_HOST_STATE_REQUESTING_SESSION)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Disconnect(): Already disconnected.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_FAIL;
- }
- if (eANTFSState >= ANTFS_HOST_STATE_CONNECTED)
- {
- if (usBlackoutTime_ )
- {
- if(Blackout(usFoundANTFSDeviceID, usFoundANTFSManufacturerID, usFoundANTFSDeviceType, usBlackoutTime_) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Disconnect(): Failed adding device to ignore list.");
- #endif
- eReturn = ANTFS_RETURN_FAIL;
- }
- }
- }
-
- ucDisconnectType = ucDisconnectType_;
- ucUndiscoverableTimeDuration = ucTimeDuration_;
- ucUndiscoverableAppSpecificDuration = ucAppSpecificDuration_;
- eANTFSRequest = ANTFS_REQUEST_DISCONNECT;
- DSIThread_CondSignal(&stCondRequest);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return eReturn;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFS_RETURN ANTFSHostChannel::SwitchFrequency(UCHAR ucRadioFrequency_, UCHAR ucChannelPeriod_)
- {
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest != ANTFS_REQUEST_NONE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::SwitchFrequency(): Request Busy.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_BUSY;
- }
- if (eANTFSState != ANTFS_HOST_STATE_TRANSPORT)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::SwitchFrequency(): Not in transport state.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_FAIL;
- }
- ucTransportFrequencySelection = ucRadioFrequency_;
- ucTransportChannelPeriodSelection = ucChannelPeriod_;
- eANTFSRequest = ANTFS_REQUEST_CHANGE_LINK;
- DSIThread_CondSignal(&stCondRequest);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_PASS;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFS_RETURN ANTFSHostChannel::Download(USHORT usFileIndex_, ULONG ulDataOffset_, ULONG ulMaxDataLength_, ULONG ulMaxBlockSize_)
- {
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest != ANTFS_REQUEST_NONE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Download(): Request Busy.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_BUSY;
- }
- if (eANTFSState != ANTFS_HOST_STATE_TRANSPORT)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Download(): Not in transport state.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_FAIL;
- }
- bTransfer = FALSE;
- ulTransferTotalBytesRemaining = 0;
- ulTransferBytesInBlock = 0;
- usTransferDataFileIndex = usFileIndex_;
- ulTransferDataOffset = ulDataOffset_;
- ulTransferByteSize = ulMaxDataLength_;
- ulHostBlockSize = ulMaxBlockSize_;
- #if defined(DEBUG_FILE)
- {
- char szString[256];
- SNPRINTF(szString, 256, "ANTFSHostChannel::Download():\n usTransferDataFileIndex = %u.\n ulTransferDataOffset = %lu.\n ulTransferByteSize = %lu.",
- usTransferDataFileIndex, ulTransferDataOffset, ulTransferByteSize);
- DSIDebug::ThreadWrite(szString);
- }
- #endif
- if ((usFoundANTFSManufacturerID == 1) && (usFoundANTFSDeviceType == 782))
- bLargeData = FALSE; // !! Forerunner 50 only -- obsolete for all other devices.
- else
- bLargeData = TRUE;
- eANTFSRequest = ANTFS_REQUEST_DOWNLOAD;
- DSIThread_CondSignal(&stCondRequest);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_PASS;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFS_RETURN ANTFSHostChannel::Upload(USHORT usFileIndex_, ULONG ulDataOffset_, ULONG ulDataLength_, void *pvData_, BOOL bForceOffset_, ULONG ulMaxBlockSize_)
- {
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest != ANTFS_REQUEST_NONE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Upload(): Request Busy.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_BUSY;
- }
- if (eANTFSState != ANTFS_HOST_STATE_TRANSPORT)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Upload(): Not in transport state.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_FAIL;
- }
- bTransfer = FALSE;
- ulUploadIndexProgress = 0;
- usTransferDataFileIndex = usFileIndex_;
- ulTransferDataOffset = ulDataOffset_;
- ulTransferByteSize = ulDataLength_;
- pucUploadData = (UCHAR*)pvData_;
- bForceUploadOffset = bForceOffset_;
- if (ulDataOffset_)
- bForceUploadOffset = TRUE; //Force the offset if the app is giving us an initial offset other than 0.
- if(ulMaxBlockSize_ == 0)
- ulHostBlockSize = MAX_ULONG;
- else
- ulHostBlockSize = ulMaxBlockSize_;
- #if 0
- if ((ulTransferDataOffset > MAX_USHORT) || (ulTransferByteSize > MAX_USHORT))
- bLargeData = TRUE;
- else
- bLargeData = FALSE;
- #endif
- bLargeData = TRUE;
- eANTFSRequest = ANTFS_REQUEST_UPLOAD;
- DSIThread_CondSignal(&stCondRequest);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_PASS;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFS_RETURN ANTFSHostChannel::ManualTransfer(USHORT usFileIndex_, ULONG ulDataOffset_, ULONG ulDataLength_, void *pvData_)
- {
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest != ANTFS_REQUEST_NONE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ManualTransfer(): Request Busy.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_BUSY;
- }
- if (eANTFSState != ANTFS_HOST_STATE_TRANSPORT)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ManualTransfer(): Not in transport state.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_FAIL;
- }
- if (ulDataOffset_ >= DIRECT_TRANSFER_SIZE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ManualTransfer(): ulDataOffset) too large.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_FAIL;
- }
- if ((ulDataLength_ > DIRECT_TRANSFER_SIZE) || (ulDataLength_ == 0))
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ManualTransfer(): ulDataLength_ is 0 or too large.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_FAIL;
- }
- memcpy(&aucSendDirectBuffer[8], pvData_, ulDataLength_); //pvData_ must be little endian when sent to device!
- memset(&aucSendDirectBuffer[ulDataLength_ + 8], 0, 8 - (ulDataLength_ % 8) ); // Clear the rest of the last payload packet.
- #if defined(DEBUG_FILE)
- {
- char acString[256];
- SNPRINTF(acString, 256, "ANTFSHostChannel::ManualTransfer(): ulDataLength_ = %lu; ulDataOffset_ = %lu.", ulDataLength_, ulDataOffset_);
- DSIDebug::ThreadWrite(acString);
- }
- #endif
- bTransfer = FALSE;
- ulUploadIndexProgress = 0;
- ulTransferTotalBytesRemaining = 0;
- usTransferDataFileIndex = usFileIndex_;
- ulTransferDataOffset = ulDataOffset_;
- ulTransferByteSize = ulDataLength_;
- bLargeData = FALSE;
- eANTFSRequest = ANTFS_REQUEST_MANUAL_TRANSFER;
- DSIThread_CondSignal(&stCondRequest);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_PASS;
- }
- ///////////////////////////////////////////////////////////////////////
- BOOL ANTFSHostChannel::GetDownloadStatus(ULONG *pulByteProgress_, ULONG *pulTotalLength_)
- {
- ULONG ulOffset;
- if (ulTransferTotalBytesRemaining == 0)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::GetDownloadStatus(): Download not in progress.");
- #endif
- *pulTotalLength_ = 10;
- *pulByteProgress_ = 0;
- return FALSE;
- }
- *pulTotalLength_ = ulTransferTotalBytesRemaining;
- // The first 8 / 16 bytes of the array form the response packet.
- // Subtract them from the length count.
- if (bLargeData)
- ulOffset = 16;
- else
- ulOffset = 8;
- if (ulTransferArrayIndex >= ulOffset)
- *pulByteProgress_ = ulTransferArrayIndex - ulOffset;
- else
- *pulByteProgress_ = 0;
- *pulByteProgress_ += ulTransferDataOffset;
- if (*pulByteProgress_ > *pulTotalLength_) //the index can go beyond the total length because we transfer with 8 byte packets
- *pulByteProgress_ = *pulTotalLength_;
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////
- BOOL ANTFSHostChannel::GetTransferData(ULONG *pulDataSize_ , void *pvData_)
- {
- ULONG ulLength;
- int iOffset;
- if ((!bTransfer) || (pucTransferBufferDynamic == NULL))
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::GetTransferData(): No valid data.");
- #endif
- return FALSE;
- }
- if (bLargeData)
- iOffset = 16;
- else
- iOffset = 8;
- ulLength = ulTransferArrayIndex - iOffset;
- if (ulLength > ulTransferTotalBytesRemaining)
- ulLength = ulTransferTotalBytesRemaining;
- if (pvData_ != NULL)
- memcpy(pvData_, pucTransferBufferDynamic + iOffset, ulLength);
- if (pulDataSize_ != NULL)
- *pulDataSize_ = ulLength;
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////
- BOOL ANTFSHostChannel::GetUploadStatus(ULONG *pulByteProgress_, ULONG *pulTotalLength_)
- {
- if (ulTransferByteSize == 0)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::GetDownloadStatus(): Upload not in progress.");
- #endif
- *pulTotalLength_ = 10;
- *pulByteProgress_ = 0;
- return FALSE;
- }
- *pulTotalLength_ = ulTransferByteSize;
- *pulByteProgress_ = ulUploadIndexProgress;
- if (*pulByteProgress_ >= 16) //take off the extra 8 byte overhead
- *pulByteProgress_ = *pulByteProgress_ - 16;
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFS_RETURN ANTFSHostChannel::EraseData(USHORT usDataFileIndex_)
- {
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest != ANTFS_REQUEST_NONE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::EraseData(): Request Busy.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_BUSY;
- }
- if (eANTFSState != ANTFS_HOST_STATE_TRANSPORT)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::EraseData(): Not in transport state.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_FAIL;
- }
- bTransfer = FALSE;
- usTransferDataFileIndex = usDataFileIndex_;
- eANTFSRequest = ANTFS_REQUEST_ERASE;
- DSIThread_CondSignal(&stCondRequest);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return ANTFS_RETURN_PASS;
- }
- //////////////////////////////////////////////////////////////////////
- BOOL ANTFSHostChannel::EnablePing(BOOL bEnable_)
- {
- bPingEnabled = bEnable_;
- return TRUE;
- }
- //////////////////////////////////////////////////////////////////////////////////
- // Private Functions
- //////////////////////////////////////////////////////////////////////////////////
- DSI_THREAD_RETURN ANTFSHostChannel::ANTFSThreadStart(void *pvParameter_)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadInit("ANTFSHost");
- #endif
- ((ANTFSHostChannel *)pvParameter_)->ANTFSThread();
- return 0;
- }
- ///////////////////////////////////////////////////////////////////////
- // ANTFS Task Thread
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::ANTFSThread(void)
- {
- ANTFS_HOST_RESPONSE eResponse;
- BOOL bPingNow = FALSE;
- bANTFSThreadRunning = TRUE;
- while (bKillThread == FALSE)
- {
- eResponse = ANTFS_HOST_RESPONSE_NONE;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Awaiting Requests...");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (*pbCancel == TRUE) //If there was a cancel, then return ANTFS_HOST_RESPONSE_CANCEL_DONE when we've reached this point
- {
- *pbCancel = FALSE;
- if (eANTFSRequest != ANTFS_REQUEST_INIT && eANTFSRequest != ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- {
- eANTFSRequest = ANTFS_REQUEST_NONE; //Clear any other request
- }
- AddResponse(ANTFS_HOST_RESPONSE_CANCEL_DONE);
- }
- if ((eANTFSRequest == ANTFS_REQUEST_NONE) && (bKillThread == FALSE))
- {
- UCHAR ucResult = DSIThread_CondTimedWait(&stCondRequest, &stMutexCriticalSection, 2000);
-
- if (ucResult != DSI_THREAD_ENONE)
- {
- #if defined(DEBUG_FILE)
- if(ucResult == DSI_THREAD_EOTHER)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): CondTimedWait() Failed!");
- #endif
- if ((eANTFSRequest == ANTFS_REQUEST_NONE) && (bPingEnabled == TRUE) && (eANTFSState >= ANTFS_HOST_STATE_CONNECTED))
- {
- bPingNow = TRUE;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Requesting Ping.");
- #endif
- }
- }
- }
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- if (bPingNow == TRUE)
- {
- bPingNow = FALSE;
- Ping();
- }
- if (bKillThread)
- break;
- if (eANTFSRequest != ANTFS_REQUEST_NONE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Request received");
- #endif
- switch (eANTFSRequest)
- {
- case ANTFS_REQUEST_INIT:
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Idle.");
- #endif
-
- ResetHostState();
- eANTFSState = ANTFS_HOST_STATE_IDLE;
- eResponse = ANTFS_HOST_RESPONSE_INIT_PASS;
- } // ANTFS_REQUEST_INIT
- break;
- case ANTFS_REQUEST_SESSION:
- {
- RETURN_STATUS eReturn;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Requesting ANT-FS session...");
- #endif
- eANTFSState = ANTFS_HOST_STATE_REQUESTING_SESSION;
- eReturn = AttemptRequestSession();
- if (eReturn == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Session request serial error.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- else if (eReturn == RETURN_FAIL)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Session request failed.");
- #endif
- eANTFSState = ANTFS_HOST_STATE_IDLE;
- eResponse = ANTFS_HOST_RESPONSE_REQUEST_SESSION_FAIL;
- }
- else if (eReturn == RETURN_STOP)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Session request stopped.");
- #endif
- eANTFSState = ANTFS_HOST_STATE_IDLE;
- }
- else if (eReturn == RETURN_PASS)
- {
- RETURN_STATUS eConnectStatus;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Connecting...");
- #endif
- eConnectStatus = AttemptConnect();
- if (eConnectStatus == RETURN_FAIL)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Connect failed.");
- #endif
- eANTFSState = ANTFS_HOST_STATE_IDLE;
- eResponse = ANTFS_HOST_RESPONSE_REQUEST_SESSION_FAIL;
- }
- else if (eConnectStatus == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Connect rejected.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- else if (eConnectStatus == RETURN_PASS)
- {
- // No need to request the serial number in this case, as
- // we already know we are connected to the right device
- eANTFSState = ANTFS_HOST_STATE_CONNECTED;
- eResponse = ANTFS_HOST_RESPONSE_CONNECT_PASS;
- }
- else if (eConnectStatus == RETURN_STOP)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Session request stopped.");
- #endif
- eANTFSState = ANTFS_HOST_STATE_IDLE;
- }
- else
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Session request failed.");
- #endif
- eANTFSState = ANTFS_HOST_STATE_IDLE;
- eResponse = ANTFS_HOST_RESPONSE_REQUEST_SESSION_FAIL;
- }
- }
- } // ANTFS_REQUEST_SESSION
- break;
- case ANTFS_REQUEST_SEARCH:
- {
- RETURN_STATUS eReturn;
- eANTFSState = ANTFS_HOST_STATE_SEARCHING;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Searching...");
- #endif
- eReturn = AttemptSearch();
- if (eReturn == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Search serial error.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- else if (eReturn == RETURN_FAIL)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Search failed.");
- #endif
- //eANTFSRequest should still be ANTFS_REQUEST_SEARCH; // Keep searching.
- //stay in searching state so we keep retrying
- }
- else if (eReturn == RETURN_STOP)
- {
- RETURN_STATUS eDisconnectStatus;
-
- eDisconnectStatus = AttemptDisconnect();
- if(eDisconnectStatus == RETURN_PASS)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Search stopped.");
- #endif
- eANTFSState = ANTFS_HOST_STATE_IDLE;
- //eResponse = ANTFS_HOST_RESPONSE_DISCONNECT_PASS;
- }
- else if(eDisconnectStatus == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Serial error stopping search.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- }
- else if (eReturn == RETURN_PASS)
- {
- RETURN_STATUS eConnectStatus;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Connecting...");
- #endif
- eConnectStatus = AttemptConnect();
- if (eConnectStatus == RETURN_FAIL)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Connect failed.");
- #endif
- //eANTFSRequest should still be ANTFS_REQUEST_SEARCH; // Keep searching.
- eANTFSState = ANTFS_HOST_STATE_SEARCHING;
- }
- else if (eConnectStatus == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Connect rejected.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- else
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Requesting ID...");
- #endif
- //eANTFSState = ANTFS_HOST_STATE_REQUESTING_ID;
- //We do not want to set the state to connected until after we have sucessfully retrived the serial number
- ucTxPasswordLength = 0;
- ucAuthType = AUTH_COMMAND_REQ_SERIAL_NUM;
- pucResponseBuffer = aucRemoteFriendlyName;
- ucRemoteFriendlyNameLength = sizeof(aucRemoteFriendlyName);
- pucResponseBufferSize = &ucRemoteFriendlyNameLength;
- ulAuthResponseTimeout = AUTH_TIMEOUT;
- eReturn = AttemptAuthenticate();
- if ((eReturn == RETURN_PASS) || (eReturn == RETURN_NA))
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Connected.");
- #endif
- //grab and save the remote serial number
- stFoundDeviceParameters.ulDeviceID = Convert_Bytes_To_ULONG(aucTransferBufferFixed[AUTH_REMOTE_SERIAL_NUMBER_OFFSET + 3],
- aucTransferBufferFixed[AUTH_REMOTE_SERIAL_NUMBER_OFFSET + 2],
- aucTransferBufferFixed[AUTH_REMOTE_SERIAL_NUMBER_OFFSET + 1],
- aucTransferBufferFixed[AUTH_REMOTE_SERIAL_NUMBER_OFFSET]);
- if (IsDeviceMatched(&stFoundDeviceParameters, FALSE) == TRUE)
- {
- eANTFSState = ANTFS_HOST_STATE_CONNECTED;
- eResponse = ANTFS_HOST_RESPONSE_CONNECT_PASS;
- }
- else
- {
- //possibly blackout the device for a period of time here.
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Full ID is not a match.");
- #endif
- RETURN_STATUS eDisconnectStatus;
-
- eDisconnectStatus = AttemptDisconnect();
- if(eDisconnectStatus == RETURN_PASS)
- {
- eANTFSState = ANTFS_HOST_STATE_IDLE;
- }
- else if(eDisconnectStatus == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Serial error stopping search.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- }
- }
- else if (eReturn == RETURN_STOP)
- {
- RETURN_STATUS eDisconnectStatus;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Search stopped.");
- #endif
- eDisconnectStatus = AttemptDisconnect();
- if(eDisconnectStatus == RETURN_PASS)
- {
- eANTFSState = ANTFS_HOST_STATE_IDLE;
- //eResponse = ANTFS_HOST_RESPONSE_DISCONNECT_PASS;
- }
- else if(eDisconnectStatus == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Serial error getting ID.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- }
- else
- {
- RETURN_STATUS eDisconnectStatus;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Get ID failed.");
- #endif
- eDisconnectStatus = AttemptDisconnect();
- if(eDisconnectStatus == RETURN_PASS)
- {
- // Keep searching.
- eANTFSState = ANTFS_HOST_STATE_SEARCHING;
- }
- else if(eDisconnectStatus == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Serial error getting ID.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- }
- }
- }
- }
- break;
- case ANTFS_REQUEST_AUTHENTICATE:
- {
- RETURN_STATUS eReturn;
- eANTFSState = ANTFS_HOST_STATE_AUTHENTICATING;
- eResponse = ANTFS_HOST_RESPONSE_AUTHENTICATE_FAIL; //set a default response
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Authenticating...");
- #endif
- eReturn = AttemptAuthenticate();
- pucResponseBuffer = (UCHAR*)NULL; //clear response buffer pointers
- pucResponseBufferSize = (UCHAR*)NULL;
- if (eReturn == RETURN_PASS)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Authentication passed.");
- #endif
- eANTFSState = ANTFS_HOST_STATE_TRANSPORT;
- eResponse = ANTFS_HOST_RESPONSE_AUTHENTICATE_PASS;
- }
- else if (eReturn == RETURN_FAIL)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Authentication failed.");
- #endif
- IncFreqStaleCount(MAJOR_STALE_COUNT);
- eANTFSState = ANTFS_HOST_STATE_CONNECTED;
- eResponse = ANTFS_HOST_RESPONSE_AUTHENTICATE_FAIL;
- }
- else if (eReturn == RETURN_REJECT)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Authentication rejected.");
- #endif
- eANTFSState = ANTFS_HOST_STATE_CONNECTED;
- eResponse = ANTFS_HOST_RESPONSE_AUTHENTICATE_REJECT;
- }
- else if (eReturn == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Authentication serial error.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- else if (eReturn == RETURN_STOP)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Authentication stopped.");
- #endif
- eANTFSState = ANTFS_HOST_STATE_CONNECTED;
- //eResponse = ANTFS_HOST_RESPONSE_DISCONNECT_PASS);
- }
- else //RETURN_NA
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Authentication NA.");
- #endif
- eANTFSState = ANTFS_HOST_STATE_CONNECTED;
- eResponse = ANTFS_HOST_RESPONSE_AUTHENTICATE_NA;
- }
- }
- break;
- case ANTFS_REQUEST_DISCONNECT:
- {
- RETURN_STATUS eReturn;
- eANTFSState = ANTFS_HOST_STATE_DISCONNECTING;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Disconnecting...");
- #endif
- eReturn = AttemptDisconnect();
- if(eReturn == RETURN_PASS)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Disconnect passed.");
- #endif
- ResetHostState();
- eANTFSState = ANTFS_HOST_STATE_IDLE;
- eResponse = ANTFS_HOST_RESPONSE_DISCONNECT_PASS;
- }
- else if(eReturn == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Disconnect serial error.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- }
- break;
- case ANTFS_REQUEST_CHANGE_LINK:
- {
- RETURN_STATUS eReturn;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Changing radio frequency and channel period...");
- #endif
- eReturn = AttemptSwitchFrequency();
- if (eReturn == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Serial error while changing radio frequency/period.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- else if (eReturn == RETURN_FAIL)
- {
- RETURN_STATUS eDisconnectStatus;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Changing radio frequency and channel period failed.");
- #endif
-
- // We end up here if we lost the beacon when trying to change the channel parameters, so
- // disconnect, so we can try to connect to it again
- eDisconnectStatus = AttemptDisconnect();
- if(eDisconnectStatus == RETURN_PASS)
- {
- eANTFSState = ANTFS_HOST_STATE_IDLE;
- eResponse = ANTFS_HOST_RESPONSE_CONNECTION_LOST;
- }
- else if(eDisconnectStatus == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Serial error changing channel parameters.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- }
- else if (eReturn == RETURN_PASS)
- {
- eANTFSRequest = ANTFS_REQUEST_NONE;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Changed radio frequency and channel period.");
- #endif
- // TODO: Do we need a response as well?
- }
- } // ANTFS_REQUEST_CHANGE_LINK
- break;
- case ANTFS_REQUEST_DOWNLOAD:
- {
- RETURN_STATUS eReturn;
- eANTFSState = ANTFS_HOST_STATE_DOWNLOADING;
- eResponse = ANTFS_HOST_RESPONSE_DOWNLOAD_FAIL; //Set a default response
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Downloading...");
- #endif
- eReturn = AttemptDownload();
- if (eReturn == RETURN_PASS)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Download complete.");
- #endif
- eANTFSState = ANTFS_HOST_STATE_TRANSPORT;
- eResponse = ANTFS_HOST_RESPONSE_DOWNLOAD_PASS;
- }
- else if (eReturn == RETURN_FAIL)
- {
- RETURN_STATUS eDisconnectStatus;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Download failed.");
- #endif
- IncFreqStaleCount(MINOR_STALE_COUNT);
-
- eDisconnectStatus = AttemptDisconnect();
- if(eDisconnectStatus == RETURN_PASS)
- {
- eANTFSState = ANTFS_HOST_STATE_IDLE;
- eResponse = ANTFS_HOST_RESPONSE_DOWNLOAD_FAIL;
- }
- else if(eDisconnectStatus == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Serial error on failed download.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- }
- else if (eReturn == RETURN_REJECT)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Download rejected.");
- #endif
- eANTFSState = ANTFS_HOST_STATE_TRANSPORT;
-
- switch (ucRejectCode)
- {
- case DOWNLOAD_RESPONSE_DOES_NOT_EXIST:
- eResponse = ANTFS_HOST_RESPONSE_DOWNLOAD_INVALID_INDEX;
- break;
- case DOWNLOAD_RESPONSE_NOT_DOWNLOADABLE:
- eResponse = ANTFS_HOST_RESPONSE_DOWNLOAD_FILE_NOT_READABLE;
- break;
- case DOWNLOAD_RESPONSE_NOT_READY:
- eResponse = ANTFS_HOST_RESPONSE_DOWNLOAD_NOT_READY;
- break;
- case DOWNLOAD_RESPONSE_REQUEST_INVALID:
- default:
- eResponse = ANTFS_HOST_RESPONSE_DOWNLOAD_REJECT;
- break;
- }
- }
- else if (eReturn == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Download serial error.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- else
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Download stopped.");
- #endif
- //Disconnect();
- //eANTFSState = ANTFS_HOST_STATE_IDLE;
- //eResponse = ANTFS_HOST_RESPONSE_DISCONNECT_PASS;
- eANTFSState = ANTFS_HOST_STATE_TRANSPORT;
- }
- }
- break;
- case ANTFS_REQUEST_UPLOAD:
- {
- RETURN_STATUS eReturn;
- eANTFSState = ANTFS_HOST_STATE_UPLOADING;
- eResponse = ANTFS_HOST_RESPONSE_UPLOAD_FAIL; //Set a default response
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Requesting upload.");
- #endif
- eReturn = UploadLoop();
- if (eReturn == RETURN_PASS)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Upload complete.");
- #endif
- eANTFSState = ANTFS_HOST_STATE_TRANSPORT;
- eResponse = ANTFS_HOST_RESPONSE_UPLOAD_PASS;
- }
- else if (eReturn == RETURN_FAIL)
- {
- RETURN_STATUS eDisconnectStatus;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Upload failed.");
- #endif
- IncFreqStaleCount(MINOR_STALE_COUNT);
-
- eDisconnectStatus = AttemptDisconnect();
- if(eDisconnectStatus == RETURN_PASS)
- {
- eANTFSState = ANTFS_HOST_STATE_IDLE;
- eResponse = ANTFS_HOST_RESPONSE_UPLOAD_FAIL;
- }
- else if(eDisconnectStatus == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Serial error on failed upload.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- }
- else if (eReturn == RETURN_REJECT)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Upload rejected.");
- #endif
- eANTFSState = ANTFS_HOST_STATE_TRANSPORT;
- switch (ucRejectCode)
- {
- case UPLOAD_RESPONSE_DOES_NOT_EXIST:
- eResponse = ANTFS_HOST_RESPONSE_UPLOAD_INVALID_INDEX;
- break;
- case UPLOAD_RESPONSE_NOT_WRITEABLE:
- eResponse = ANTFS_HOST_RESPONSE_UPLOAD_FILE_NOT_WRITEABLE;
- break;
- case UPLOAD_RESPONSE_INSUFFICIENT_SPACE:
- eResponse = ANTFS_HOST_RESPONSE_UPLOAD_INSUFFICIENT_SPACE;
- break;
- default:
- eResponse = ANTFS_HOST_RESPONSE_UPLOAD_REJECT;
- break;
- }
- }
- else if (eReturn == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Upload serial error.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- else
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Upload stopped.");
- #endif
- //Disconnect();
- //eANTFSState = ANTFS_HOST_STATE_IDLE;
- //eResponse = ANTFS_HOST_RESPONSE_DISCONNECT_PASS;
- eANTFSState = ANTFS_HOST_STATE_TRANSPORT;
- }
- }
- break;
- case ANTFS_REQUEST_MANUAL_TRANSFER:
- {
- RETURN_STATUS eReturn;
- eANTFSState = ANTFS_HOST_STATE_SENDING;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Sending Direct.");
- #endif
- eReturn = AttemptManualTransfer();
- if (eReturn == RETURN_PASS)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): ManualTransfer complete.");
- #endif
- eANTFSState = ANTFS_HOST_STATE_TRANSPORT;
- eResponse = ANTFS_HOST_RESPONSE_MANUAL_TRANSFER_PASS;
- }
- else if (eReturn == RETURN_FAIL)
- {
- RETURN_STATUS eDisconnectStatus;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): ManualTransfer failed to retrieve data.");
- #endif
- IncFreqStaleCount(MINOR_STALE_COUNT);
-
- eDisconnectStatus = AttemptDisconnect();
- if(eDisconnectStatus == RETURN_PASS)
- {
- eANTFSState = ANTFS_HOST_STATE_IDLE;
- eResponse = ANTFS_HOST_RESPONSE_MANUAL_TRANSFER_RESPONSE_FAIL;
- }
- else if(eDisconnectStatus == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Serial error on failed manual transfer.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- }
- else if (eReturn == RETURN_REJECT)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): ManualTransfer rejected due to Tx error.");
- #endif
- IncFreqStaleCount(MIN_STALE_COUNT); //Have to check if a NAK on the Garmin protocol will cause this condition
- eANTFSState = ANTFS_HOST_STATE_TRANSPORT;
- eResponse = ANTFS_HOST_RESPONSE_MANUAL_TRANSFER_TRANSMIT_FAIL;
- }
- else if (eReturn == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): ManualTransfer serial error.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- else
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): ManualTransfer stopped.");
- #endif
- //Disconnect();
- //eANTFSState = ANTFS_HOST_STATE_IDLE;
- //eResponse = ANTFS_HOST_RESPONSE_DISCONNECT_PASS;
- eANTFSState = ANTFS_HOST_STATE_TRANSPORT;
- }
- }
- break;
- case ANTFS_REQUEST_ERASE:
- {
- RETURN_STATUS eReturn;
- eANTFSState = ANTFS_HOST_STATE_ERASING;
- eResponse = ANTFS_HOST_RESPONSE_ERASE_FAIL; //Set default response
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Erasing...");
- #endif
- eReturn = AttemptErase();
- if (eReturn == RETURN_PASS)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Erase complete.");
- #endif
- eANTFSState = ANTFS_HOST_STATE_TRANSPORT;
- eResponse = ANTFS_HOST_RESPONSE_ERASE_PASS;
- }
- else if (eReturn == RETURN_FAIL)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Erase fail.");
- #endif
- IncFreqStaleCount(MINOR_STALE_COUNT);
- eANTFSState = ANTFS_HOST_STATE_TRANSPORT;
- eResponse = ANTFS_HOST_RESPONSE_ERASE_FAIL;
- }
- else if (eReturn == RETURN_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Erase serial error.");
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- eANTFSRequest = ANTFS_REQUEST_HANDLE_SERIAL_ERROR;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- else
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Erase stopped.");
- #endif
- //Disconnect();
- //eANTFSState = ANTFS_HOST_STATE_IDLE;
- //eResponse = ANTFS_HOST_RESPONSE_DISCONNECT_PASS;
- }
- }
- break;
- default:
- break;
- }
- //This is where to handle the internal requests, because they can happen asyncronously.
- //We will also clear the request here.
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eResponse != ANTFS_HOST_RESPONSE_NONE)
- AddResponse(eResponse);
- if (eANTFSRequest == ANTFS_REQUEST_CONNECTION_LOST)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Connection lost.");
- #endif
- eANTFSRequest = ANTFS_REQUEST_NONE;
- bFoundDevice = FALSE;
- if (eANTFSState >= ANTFS_HOST_STATE_CONNECTED)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Connection lost - ignored.");
- #endif
- ResetHostState();
- eANTFSState = ANTFS_HOST_STATE_IDLE;
- AddResponse(ANTFS_HOST_RESPONSE_CONNECTION_LOST);
- }
- }
- else if (eANTFSRequest == ANTFS_REQUEST_HANDLE_SERIAL_ERROR)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Serial error!");
- #endif
- HandleSerialError();
- AddResponse(ANTFS_HOST_RESPONSE_SERIAL_FAIL);
- }
- else if (eANTFSRequest == ANTFS_REQUEST_SERIAL_ERROR_HANDLED)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Serial error handled");
- #endif
- ResetHostState();
- eANTFSState = ANTFS_HOST_STATE_IDLE;
- eANTFSRequest = ANTFS_REQUEST_INIT;
- }
- else
- {
- if (eANTFSState == ANTFS_HOST_STATE_SEARCHING)
- eANTFSRequest = ANTFS_REQUEST_SEARCH; //Set the search request if we're still in search mode
- else
- eANTFSRequest = ANTFS_REQUEST_NONE; //Clear any other request
- }
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- }//while()
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): Exiting thread.");
- #endif
- eANTFSRequest = ANTFS_REQUEST_NONE;
- DSIThread_MutexLock(&stMutexCriticalSection);
- bANTFSThreadRunning = FALSE;
- DSIThread_CondSignal(&stCondANTFSThreadExit);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- #if defined(__cplusplus)
- return;
- #else
- ExitThread(0);
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTFSThread(): C code reaching return statement unexpectedly.");
- #endif
- return; // Code should not be reached.
- #endif
- }
- /////////////////////////////////////////////////////////////////////
- // Returns: TRUE if the message is for the ANT-FS channel
- BOOL ANTFSHostChannel::FilterANTMessages(ANT_MESSAGE* pstMessage_, UCHAR ucANTChannel_)
- {
- // Some messages do not include the channel number in the response, so
- // they might get processed incorrectly
- if(pstMessage_->ucMessageID == MESG_RESPONSE_EVENT_ID)
- {
- if(pstMessage_->aucData[MESG_EVENT_ID_OFFSET] == MESG_NETWORK_KEY_ID)
- {
- if(pstMessage_->aucData[MESG_CHANNEL_OFFSET] == ucNetworkNumber)
- return TRUE; // this is the network we are using
- }
- }
- else if(pstMessage_->ucMessageID == MESG_STARTUP_MESG_ID)
- {
- return TRUE;
- }
- if(ucANTChannel_ == ucChannelNumber)
- return TRUE;
- return FALSE;
- }
- ///////////////////////////////////////////////////////////////////////
- BOOL ANTFSHostChannel::ReportDownloadProgress(void)
- {
- // We used to perodically signal our transfer progress, we dont do that anymore.
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::ResetHostState(void)
- {
- // Clear all state variables, while keeping the configuration:
- // channel parameters, search list, ignore list, frequency table selection
- *pbCancel = FALSE;
- bForceFullInit = FALSE;
- memset(aucResponseBuf, 0, sizeof(aucResponseBuf));
- memset(aucRxBuf, 0, sizeof(aucRxBuf));
- memset(aucTxBuf, 0, sizeof(aucTxBuf));
- memset(aucRemoteFriendlyName, 0, sizeof(aucRemoteFriendlyName));
- ucRemoteFriendlyNameLength = 0;
- ucAuthType = 0;
- memset(aucTxPassword, 0, sizeof(aucTxPassword));
- ucTxPasswordLength = 0;
- ucPasswordLength = 0;
- ucDisconnectType = DISCONNECT_COMMAND_LINK;
- ucUndiscoverableTimeDuration = 0;
- ucUndiscoverableAppSpecificDuration = 0;
- pucUploadData = (UCHAR*)NULL;
- pucResponseBuffer = (UCHAR*)NULL;
- pucResponseBufferSize = (UCHAR*)NULL;
- ulAuthResponseTimeout = AUTH_TIMEOUT;
- ucChannelStatus = 0;
- ulFoundBeaconHostID = 0;
- usFoundBeaconPeriod = 0;
- usFoundANTFSDeviceID = 0;
- usFoundANTFSManufacturerID = 0;
- usFoundANTFSDeviceType = 0;
- ucFoundANTDeviceType = 0;
- ucFoundANTTransmitType = 0;
- bFoundDeviceHasData = FALSE;
- bFoundDeviceUploadEnabled = FALSE;
- bFoundDeviceInPairingMode = FALSE;
- ucFoundDeviceAuthenticationType = 0;
- ucFoundDeviceState = 0;
- bFoundDevice = FALSE;
- bFoundDeviceIsValid = FALSE;
- bNewRxEvent = FALSE;
- stFoundDeviceParameters.usDeviceType = 0;
- stFoundDeviceParameters.usManufacturerID = 0;
- stFoundDeviceParameters.ucAuthenticationType = 0;
- stFoundDeviceParameters.ucStatusByte1 = 0;
- stFoundDeviceParameters.ucStatusByte2 = 0;
- // Download Data
- pucTransferBuffer = (UCHAR*)NULL;
- memset(aucTransferBufferFixed, 0, sizeof(aucTransferBufferFixed));
- memset(aucSendDirectBuffer, 0, sizeof(aucSendDirectBuffer));
- ulTransferArrayIndex = 0;
- ulPacketCount = 0;
- ulUploadIndexProgress = 0;
- bTxError = FALSE;
- bRxError = FALSE;
- bReceivedBurst = FALSE;
- bReceivedResponse = FALSE;
- ulTransferTotalBytesRemaining = 0;
- ulTransferBytesInBlock = 0;
- bTransfer = FALSE;
- usRadioChannelID = 0;
- ucTransportFrequencySelection = ANTFS_AUTO_FREQUENCY_SELECTION;
- ucTransportLayerRadioFrequency = 0;
- ucSearchRadioFrequency = ANTFS_RF_FREQ;
- usTransferDataFileIndex = 0;
- ulTransferDataOffset = 0;
- ulTransferByteSize = 0;
- ulTransferBufferSize = 0;
- bLargeData = FALSE;
- ulHostBlockSize = MAX_ULONG;
- ucLinkResponseRetries = 0;
- ucStrikes = STRIKE_COUNT;
- if(eANTFSState == ANTFS_HOST_STATE_OFF)
- {
- pucTransferBufferDynamic = (UCHAR*) NULL;
- }
- else
- {
- eANTFSState = ANTFS_HOST_STATE_IDLE;
- if (pucTransferBufferDynamic)
- {
- if (pucTransferBuffer == pucTransferBufferDynamic)
- pucTransferBuffer = (UCHAR*)NULL;
- delete[] pucTransferBufferDynamic;
- pucTransferBufferDynamic = (UCHAR*)NULL;
- }
- }
- eANTFSRequest = ANTFS_REQUEST_NONE;
- }
- ///////////////////////////////////////////////////////////////////////
- BOOL ANTFSHostChannel::ReInitDevice(void)
- {
- if (eANTFSState != ANTFS_HOST_STATE_OFF)
- this->Close();
- bKillThread = FALSE;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ReInitDevice(): Initializing");
- #endif
- if (hANTFSThread == NULL)
- {
- hANTFSThread = DSIThread_CreateThread(&ANTFSHostChannel::ANTFSThreadStart, this);
- if (hANTFSThread == NULL)
- return FALSE;
- }
- if (!bIgnoreListRunning)
- {
- if (DSIThread_MutexInit(&stMutexIgnoreListAccess) != DSI_THREAD_ENONE)
- {
- return FALSE;
- }
- usListIndex = 0;
- bTimerThreadInitDone = FALSE;
- pclQueueTimer = new DSITimer(&ANTFSHostChannel::QueueTimerStart, this, 1000, TRUE);
- if (pclQueueTimer->NoError() == FALSE)
- {
- DSIThread_MutexDestroy(&stMutexIgnoreListAccess);
- return FALSE;
- }
- bIgnoreListRunning = TRUE;
- }
- PopulateTransportFreqTable();
- DSIThread_MutexLock(&stMutexResponseQueue);
- clResponseQueue.Clear();
- DSIThread_MutexUnlock(&stMutexResponseQueue);
- DSIThread_MutexLock(&stMutexCriticalSection);
- eANTFSRequest = ANTFS_REQUEST_INIT;
- DSIThread_CondSignal(&stCondRequest);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFSHostChannel::RETURN_STATUS ANTFSHostChannel::AttemptSearch(void)
- {
- IGNORE_LIST_ITEM stListItem;
- IGNORE_LIST_ITEM *pstListItem;
- BOOL bFullInit = TRUE;
- BOOL bFoundBroadcastDevice = FALSE;
- UCHAR ucFirstMesgRetries;
- BOOL bFirstMesgResult;
- while (eANTFSState == ANTFS_HOST_STATE_SEARCHING)
- {
- //if (!bFullInit)
- {
- if(pclANT->GetChannelStatus(ucChannelNumber, &ucChannelStatus, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptOpenBeacon(): Failed ANT_GetChannelStatus().");
- #endif
- return RETURN_SERIAL_ERROR;
- }
- if ((ucChannelStatus & STATUS_CHANNEL_STATE_MASK) == STATUS_TRACKING_CHANNEL ||
- (ucChannelStatus & STATUS_CHANNEL_STATE_MASK) == STATUS_SEARCHING_CHANNEL)
- {
- if (pclANT->CloseChannel(ucChannelNumber, ANT_CLOSE_TIMEOUT) == FALSE)
- return RETURN_SERIAL_ERROR;
- if(bFullInit || bForceFullInit)
- {
- if(pclANT->UnAssignChannel(ucChannelNumber) == FALSE)
- return RETURN_SERIAL_ERROR;
- bFullInit = TRUE;
- }
- }
- else if ((ucChannelStatus & STATUS_CHANNEL_STATE_MASK) == STATUS_UNASSIGNED_CHANNEL)
- {
- bFullInit = TRUE;
- }
- else if(bFullInit) // Status = ASSIGNED, we only need to unassign it for full configuration
- {
- if(pclANT->UnAssignChannel(ucChannelNumber) == FALSE)
- return RETURN_SERIAL_ERROR;
-
- bFullInit = TRUE;
- }
- }
- if (bFullInit)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Full Init Begin");
- #endif
- //if (pclANT->ResetSystem() == FALSE)
- // return RETURN_SERIAL_ERROR;
- //DSIThread_Sleep(1000);
- ucFirstMesgRetries = 0;
- while (((bFirstMesgResult = pclANT->SetNetworkKey(ucNetworkNumber, (UCHAR *) aucTheNetworkkey,MESSAGE_TIMEOUT)) == FALSE) && (ucFirstMesgRetries++ < ANTFS_RESPONSE_RETRIES));
- #if defined(DEBUG_FILE)
- if (ucFirstMesgRetries)
- {
- UCHAR aucString[256];
- SNPRINTF((char*)&aucString[0], 256, "ANTFSHostChannel::AttemptSearch(): %d message retries on first message.", ucFirstMesgRetries);
- DSIDebug::ThreadWrite((char*)aucString);
- }
- #endif
- if (!bFirstMesgResult)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Failed ANT_SetNetworkKey().");
- #endif
- return RETURN_SERIAL_ERROR;
- }
- if (pclANT->AssignChannel(ucChannelNumber, 0x00, ucNetworkNumber, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Failed ANT_AssignChannel().");
- #endif
- return RETURN_SERIAL_ERROR;
- }
- if (pclANT->SetChannelPeriod(ucChannelNumber, usTheMessagePeriod, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Failed ANT_SetChannelPeriod().");
- #endif
- return RETURN_SERIAL_ERROR;
- }
- if (pclANT->SetChannelSearchTimeout(ucChannelNumber, ANTFS_SEARCH_TIMEOUT, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Failed ANT_SetChannelSearchTimeout().");
- #endif
- return RETURN_SERIAL_ERROR;
- }
- if (pclANT->SetChannelRFFrequency(ucChannelNumber, ucSearchRadioFrequency, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Failed ANT_SetChannelRFFreq().");
- #endif
- return RETURN_SERIAL_ERROR;
- }
- if (pclANT->SetFastSearch(ucChannelNumber, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Failed SetFastSearch().");
- #endif
- return RETURN_SERIAL_ERROR;
- }
- bForceFullInit = FALSE;
- bFullInit = FALSE;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Full Init Complete");
- #endif
- }
- //This gets reset everytime a device is found, so we need to set it every time
- if(ucTheProxThreshold > 0) //Don't need to send if it is default=0, saves sending command on unsupported devices, plus a little time
- {
- if(pclANT->SetProximitySearch(ucChannelNumber, ucTheProxThreshold, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Failed ANT_SetProximitySearch(). Ignored, possibly unsupported device.");
- #endif
- //don't return RETURN_SERIAL_ERROR, Ignore failure so we don't fail on unsupported devices and maintain compatibility.
- }
- }
- //This gets reset everytime a device is found, so we need to set it every time
- if (pclANT->SetChannelID(ucChannelNumber, usRadioChannelID, ucTheDeviceType, ucTheTransmissionType, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Failed ANT_SetChannelId().");
- #endif
- return RETURN_SERIAL_ERROR;
- }
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Opening channel...");
- #endif
- bFoundDevice = FALSE;
- bFoundBroadcastDevice = FALSE;
- if (pclANT->OpenChannel(ucChannelNumber,MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Failed ANT_OpenChannel().");
- #endif
- return RETURN_SERIAL_ERROR;
- }
- bNewRxEvent = FALSE;
- do
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Waiting for search results...");
- #endif
- if (pclANT->GetChannelStatus(ucChannelNumber, &ucChannelStatus, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Cannot get ANT Channel Status.");
- #endif
- return RETURN_FAIL;
- //return RETURN_SERIAL_ERROR;
- }
- if (ucChannelStatus < STATUS_SEARCHING_CHANNEL)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): ANT Channel not searching or tracking.");
- #endif
- return RETURN_FAIL;
- }
- DSIThread_MutexLock(&stMutexCriticalSection);
- if ((bNewRxEvent == FALSE) && (*pbCancel == FALSE))
- {
- DSIThread_CondTimedWait(&stCondRxEvent, &stMutexCriticalSection, SEARCH_STATUS_CHECK_TIMEOUT);
- }
- bNewRxEvent = FALSE;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- if (*pbCancel == TRUE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Searching stopped.");
- #endif
- return RETURN_STOP;
- }
- } while (!bFoundDevice);
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Search results loop exitted.");
- #endif
- if (!bFoundDeviceIsValid)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Device not sending a valid beacon.");
- #endif
- if(!bRequestPageEnabled)
- continue;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Attempting to request an ANT-FS session...");
- #endif
- if(AttemptRequestSession() != RETURN_PASS)
- continue;
- bFoundBroadcastDevice = TRUE;
- }
- if (ucFoundDeviceState != REMOTE_DEVICE_STATE_LINK)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Device not in link mode.");
- #endif
- continue;
- }
- if (pclANT->GetChannelID(ucChannelNumber, (USHORT*)&usFoundANTFSDeviceID, (UCHAR*)&ucFoundANTDeviceType, (UCHAR*)&ucFoundANTTransmitType, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Cannot get ANT ID.");
- #endif
- continue;
- }
- // Save 2 bytes of the DeviceID
- stFoundDeviceParameters.ulDeviceID &= 0xFFFF0000;
- stFoundDeviceParameters.ulDeviceID |= (0x0000FFFF&usFoundANTFSDeviceID);
- // Check the Ignore list
- stListItem.usID = usFoundANTFSDeviceID;
- stListItem.usManufacturerID = usFoundANTFSManufacturerID;
- stListItem.usDeviceType = usFoundANTFSDeviceType;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Entering critical section.");
- #endif
- DSIThread_MutexLock(&stMutexIgnoreListAccess);
- pstListItem = (IGNORE_LIST_ITEM *) bsearch(&stListItem, astIgnoreList, usListIndex, sizeof(IGNORE_LIST_ITEM), &ListCompare);
- DSIThread_MutexUnlock(&stMutexIgnoreListAccess);
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Leaving critical section.");
- #endif
- if (pstListItem != NULL)
- {
- #if defined(DEBUG_FILE)
- UCHAR aucString[256];
- SNPRINTF((char *)&aucString[0], 256, "ANTFSHostChannel::AttemptSearch(): Device %u is on the ignore list.", usFoundANTFSDeviceID);
- DSIDebug::ThreadWrite((char *)aucString);
- #endif
- if(bFoundBroadcastDevice)
- {
- ucDisconnectType = DISCONNECT_COMMAND_BROADCAST; // Device is in ignore list, let it go back to broadcast
- if(AttemptDisconnect() == RETURN_SERIAL_ERROR)
- return RETURN_SERIAL_ERROR;
- eANTFSState = ANTFS_HOST_STATE_SEARCHING;
- }
- continue; // Continue searching if the device is on the ignore list.
- }
- #if defined(DEBUG_FILE)
- {
- UCHAR aucString[256];
- SNPRINTF((char *)aucString,256, "ANTFSHostChannel::AttemptSearch(): Found device %u (Manufacturer ID: %u Device Type: %u Beacon Period: %u/32768 Authentication Type: %u).", usFoundANTFSDeviceID, usFoundANTFSManufacturerID, usFoundANTFSDeviceType, usFoundBeaconPeriod, ucFoundDeviceAuthenticationType);
- DSIDebug::ThreadWrite((char *)aucString);
- if (bFoundDeviceHasData)
- DSIDebug::ThreadWrite(" Device has data.");
- else
- DSIDebug::ThreadWrite(" Device has no data.");
- if (bFoundDeviceUploadEnabled)
- DSIDebug::ThreadWrite(" Device has upload enabled.");
- else
- DSIDebug::ThreadWrite(" Device has upload disabled.");
- if (bFoundDeviceInPairingMode)
- DSIDebug::ThreadWrite(" Device is in pairing mode.");
- else
- DSIDebug::ThreadWrite(" Device is not in pairing mode.");
- }
- #endif
- // Check for a match.
- if (IsDeviceMatched(&stFoundDeviceParameters, TRUE) == TRUE)
- {
- // We have found a match.
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite(" Device is a match.");
- #endif
- return RETURN_PASS;
- }
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite(" Device is not a match.");
- #endif
- // No match; continue searching.
- if(bFoundBroadcastDevice)
- {
- ucDisconnectType = DISCONNECT_COMMAND_BROADCAST; // Device is in ignore list, let it go back to broadcast
- if(AttemptDisconnect() == RETURN_SERIAL_ERROR)
- return RETURN_SERIAL_ERROR;
- eANTFSState = ANTFS_HOST_STATE_SEARCHING;
- }
- }
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSearch(): Not searching anymore.");
- #endif
- return RETURN_FAIL;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFSHostChannel::RETURN_STATUS ANTFSHostChannel::AttemptConnect(void)
- {
- UCHAR ucTxRetries;
- ANTFRAMER_RETURN eTxComplete;
- UCHAR ucRxRetries = 3;
- BOOL bStatus = FALSE;
- if (!bFoundDevice)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptConnect(): Device not found.");
- #endif
- return RETURN_FAIL;
- }
- if (ucTransportFrequencySelection == ANTFS_AUTO_FREQUENCY_SELECTION)
- ucTransportLayerRadioFrequency = CheckForNewTransportFreq();
- else
- ucTransportLayerRadioFrequency = ucTransportFrequencySelection;
- // Set up the command
- memset(aucTxBuf,0x00,sizeof(aucTxBuf));
- aucTxBuf[ANTFS_CONNECTION_OFFSET] = ANTFS_COMMAND_RESPONSE_ID;
- aucTxBuf[ANTFS_COMMAND_OFFSET] = ANTFS_CONNECT_ID;
- aucTxBuf[TRANSPORT_CHANNEL_FREQ_OFFSET] = ucTransportLayerRadioFrequency;
- aucTxBuf[TRANSPORT_CHANNEL_PERIOD] = TRANSPORT_MESSAGE_PERIOD_CODE;
- Convert_ULONG_To_Bytes(ulHostSerialNumber,
- &aucTxBuf[HOST_ID_OFFSET+3],
- &aucTxBuf[HOST_ID_OFFSET+2],
- &aucTxBuf[HOST_ID_OFFSET+1],
- &aucTxBuf[HOST_ID_OFFSET]);
- #if defined(ACCESS_POINT)
- ucTxRetries = 2;
- #else
- ucTxRetries = 8;
- #endif
- do
- {
- eTxComplete = pclANT->SendAcknowledgedData(ucChannelNumber, aucTxBuf,CONNECT_TIMEOUT);
- #if defined(DEBUG_FILE)
- if (eTxComplete == ANTFRAMER_FAIL)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptConnect(): Tx error.");
- else if (eTxComplete == ANTFRAMER_TIMEOUT)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptConnect(): Tx timeout.");
- #endif
- } while (eTxComplete == ANTFRAMER_FAIL && --ucTxRetries);
- if (eTxComplete != ANTFRAMER_PASS)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptConnect(): Failed sending connect command.");
- #endif
- return RETURN_FAIL;
- }
- if (pclANT->SetChannelPeriod(ucChannelNumber, TRANSPORT_MESSAGE_PERIOD, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptConnect(): Failed ANT_SetChannelPeriod().");
- #endif
- return RETURN_SERIAL_ERROR;
- }
- if (pclANT->SetChannelSearchTimeout(ucChannelNumber, TRANSPORT_SEARCH_TIMEOUT, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptConnect(): Failed ANT_SetChannelSearchTimeout().");
- #endif
- return RETURN_SERIAL_ERROR;
- }
- if (pclANT->SetChannelRFFrequency(ucChannelNumber, ucTransportLayerRadioFrequency, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptConnect(): Failed ANT_SetChannelRFFreq().");
- #endif
- return RETURN_SERIAL_ERROR;
- }
- do
- {
- bNewRxEvent = FALSE;
- DSIThread_MutexLock(&stMutexCriticalSection);
- if ((bNewRxEvent == FALSE) && (*pbCancel == FALSE))
- {
- UCHAR ucResult = DSIThread_CondTimedWait(&stCondRxEvent, &stMutexCriticalSection, BROADCAST_TIMEOUT);
- if (ucResult != DSI_THREAD_ENONE)
- {
- #if defined(DEBUG_FILE)
- if(ucResult == DSI_THREAD_EOTHER)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptConnect(): CondTimedWait() Failed!");
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptConnect(): Rx timeout.");
- #endif
- IncFreqStaleCount(MAX_STALE_COUNT);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return RETURN_FAIL;
- }
- }
- bNewRxEvent = FALSE;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- if (*pbCancel == TRUE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptConnect(): Stopped.");
- #endif
- return RETURN_STOP;
- }
- if (ucFoundDeviceState == REMOTE_DEVICE_STATE_AUTH)
- bStatus = TRUE;
- } while ((bStatus == FALSE) && ucRxRetries--);
- if (!bStatus)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptConnect(): Remote not in auth mode.");
- #endif
- IncFreqStaleCount(MINOR_STALE_COUNT); // Investigate why this happens, may be that the remote is not updating it's beacon fast enough.
- return RETURN_FAIL;
- }
- if (ulFoundBeaconHostID != ulHostSerialNumber)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptConnect(): Remote connected to another host.");
- #endif
- IncFreqStaleCount(MAX_STALE_COUNT);
- return RETURN_FAIL;
- }
- return RETURN_PASS;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFSHostChannel::RETURN_STATUS ANTFSHostChannel::AttemptRequestSession(void)
- {
- ANTFRAMER_RETURN eTxComplete;
- UCHAR ucTxRetries = 4;
- UCHAR ucRxRetries = 3;
- BOOL bStatus = FALSE;
- USHORT usBroadcastANTDeviceID = 0;
- UCHAR ucBroadcastANTDeviceType = 0;
- UCHAR ucBroadcastANTTransmitType = 0;
- if (pclANT->GetChannelStatus(ucChannelNumber, &ucChannelStatus, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptRequestSession(): Cannot get ANT Channel Status.");
- #endif
- return RETURN_FAIL;
- }
- if ((ucChannelStatus & STATUS_CHANNEL_STATE_MASK) != STATUS_TRACKING_CHANNEL)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptRequestSession(): Not connected to a broadcast device");
- #endif
- return RETURN_FAIL;
- }
- if (pclANT->GetChannelID(ucChannelNumber, (USHORT*)&usBroadcastANTDeviceID, (UCHAR*)&ucBroadcastANTDeviceType, (UCHAR*)&ucBroadcastANTTransmitType, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptRequestSession(): Cannot get ANT ID.");
- #endif
- }
- else
- {
- #if defined(DEBUG_FILE)
- UCHAR aucString[256];
- SNPRINTF((char *)aucString,256, "ANTFSHostChannel::AttemptRequestSession(): Broadcast Device (Device Number: %u Device Type: %u Tx Type: %u).", usBroadcastANTDeviceID, ucBroadcastANTDeviceType, ucBroadcastANTTransmitType);
- DSIDebug::ThreadWrite((char *)aucString);
- #endif
- }
- memset(aucTxBuf, REQUEST_PAGE_INVALID, sizeof(aucTxBuf));
- aucTxBuf[ANTFS_CONNECTION_OFFSET] = ANTFS_REQUEST_PAGE_ID ;
- aucTxBuf[REQUEST_TX_RESPONSE_OFFSET] = (UCHAR) 0x00;
- aucTxBuf[REQUEST_PAGE_NUMBER_OFFSET] = ANTFS_BEACON_ID;
- aucTxBuf[REQUEST_COMMAND_TYPE_OFFSET] = ANTFS_REQUEST_SESSION;
- // Send request session message
- do
- {
- eTxComplete = pclANT->SendAcknowledgedData(ucChannelNumber, aucTxBuf, REQUEST_TIMEOUT);
- #if defined(DEBUG_FILE)
- if (eTxComplete == ANTFRAMER_FAIL)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptRequestSession(): Tx error.");
- else if (eTxComplete == ANTFRAMER_TIMEOUT)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptRequestSession(): Tx timeout.");
- #endif
- } while (eTxComplete == ANTFRAMER_FAIL && --ucTxRetries);
- if (eTxComplete != ANTFRAMER_PASS)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptRequestSession(): Failed sending request page.");
- #endif
- return RETURN_FAIL;
- }
- // Wait for beacon
- do
- {
- bFoundDevice = FALSE;
- bNewRxEvent = FALSE;
- DSIThread_MutexLock(&stMutexCriticalSection);
- if ((bNewRxEvent == FALSE) && (*pbCancel == FALSE))
- {
- UCHAR ucResult = DSIThread_CondTimedWait(&stCondRxEvent, &stMutexCriticalSection, BROADCAST_TIMEOUT);
- if(ucResult != DSI_THREAD_ENONE)
- {
- #if defined(DEBUG_FILE)
- if(ucResult == DSI_THREAD_EOTHER)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptRequestSession(): CondTimedWait() Failed!");
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptRequestSession(): Rx timeout.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return RETURN_FAIL;
- }
- }
- bNewRxEvent = FALSE;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- if (*pbCancel == TRUE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptRequestSession(): ANT-FS session request stopped.");
- #endif
- return RETURN_STOP;
- }
- if(bFoundDevice && bFoundDeviceIsValid)
- bStatus = TRUE;
- } while ((bStatus == FALSE) && ucRxRetries--);
- if(!bStatus)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptRequestSession(): No response to ANT-FS Session request.");
- #endif
- // TODO: Possibly blackout the device for a period of time here? Might need a different blacklist for this, as we should
- // blacklist based on the Channel ID instead of beacon parameters
- // Blackout(usFoundANTFSDeviceID, 0, 0, 300); // 5 min?
- return RETURN_FAIL;
- }
- if(eANTFSState != ANTFS_HOST_STATE_SEARCHING)
- {
- usFoundANTFSDeviceID = usBroadcastANTDeviceID; // TODO: Is this needed? Assumes device ID is derived from serial number
- ucFoundANTDeviceType = ucBroadcastANTDeviceType;
- ucFoundANTTransmitType = ucBroadcastANTTransmitType;
- }
- return RETURN_PASS;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFSHostChannel::RETURN_STATUS ANTFSHostChannel::AttemptDisconnect(void)
- {
- UCHAR ucTxRetries;
- ANTFRAMER_RETURN eTxComplete;
- if(eANTFSState != ANTFS_HOST_STATE_SEARCHING)
- eANTFSState = ANTFS_HOST_STATE_DISCONNECTING;
- //We change the state here so that we don't get connection lost responses after we've decided to disconnect
- if (bFoundDevice)
- {
- bFoundDevice = FALSE;
- memset(aucTxBuf, 0x00, sizeof(aucTxBuf));
- aucTxBuf[ANTFS_CONNECTION_OFFSET] = ANTFS_COMMAND_RESPONSE_ID;
- aucTxBuf[ANTFS_COMMAND_OFFSET] = ANTFS_DISCONNECT_ID;
- aucTxBuf[DISCONNECT_COMMAND_TYPE_OFFSET] = ucDisconnectType;
- aucTxBuf[DISCONNECT_TIME_DURATION_OFFSET] = ucUndiscoverableTimeDuration;
- aucTxBuf[DISCONNECT_APP_DURATION_OFFSET] = ucUndiscoverableAppSpecificDuration;
-
- ucTxRetries = 8;
- do
- {
- eTxComplete = pclANT->SendAcknowledgedData(ucChannelNumber, aucTxBuf, DISCONNECT_TIMEOUT);
- #if defined(DEBUG_FILE)
- if (eTxComplete == ANTFRAMER_FAIL)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Disconnect(): Tx error.");
- else if(eTxComplete == ANTFRAMER_TIMEOUT)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Disconnect(): Tx timeout.");
- #endif
- } while (eTxComplete == ANTFRAMER_FAIL && --ucTxRetries);
- }
- if(ucDisconnectType == DISCONNECT_COMMAND_BROADCAST)
- {
- // Go back to link frequency and channel period
- if (pclANT->SetChannelPeriod(ucChannelNumber, usTheMessagePeriod, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptDisconnect(): Failed ANT_SetChannelPeriod().");
- #endif
- return RETURN_SERIAL_ERROR;
- }
- if (pclANT->SetChannelRFFrequency(ucChannelNumber, ucSearchRadioFrequency, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptDisconnect(): Failed ANT_SetChannelRFFreq().");
- #endif
- return RETURN_SERIAL_ERROR;
- }
- }
- else // DISCONNECT_TYPE_LINK or custom disconnect types
- {
- if(ucDisconnectType != DISCONNECT_COMMAND_LINK)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptDisconnect(): Application specific disconnect type.");
- #endif
- // Disconnect anyway, and close the channel
- }
- // Close the channel
- if(pclANT->GetChannelStatus(ucChannelNumber, &ucChannelStatus, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptDisconnect(): Failed ANT_GetChannelStatus().");
- #endif
- return RETURN_SERIAL_ERROR;
- }
- if ((ucChannelStatus & STATUS_CHANNEL_STATE_MASK) == STATUS_TRACKING_CHANNEL ||
- (ucChannelStatus & STATUS_CHANNEL_STATE_MASK) == STATUS_SEARCHING_CHANNEL)
- {
- if (pclANT->CloseChannel(ucChannelNumber, ANT_CLOSE_TIMEOUT) == FALSE)
- return RETURN_SERIAL_ERROR;
- if (pclANT->UnAssignChannel(ucChannelNumber, MESSAGE_TIMEOUT) == FALSE)
- return RETURN_SERIAL_ERROR;
- }
- else if ((ucChannelStatus & STATUS_CHANNEL_STATE_MASK) == STATUS_ASSIGNED_CHANNEL)
- {
- if (pclANT->UnAssignChannel(ucChannelNumber, MESSAGE_TIMEOUT) == FALSE)
- return RETURN_SERIAL_ERROR;
- }
- }
- usFoundANTFSManufacturerID = 0;
- usFoundANTFSDeviceType = 0;
- bFoundDeviceHasData = FALSE;
- ucDisconnectType = DISCONNECT_COMMAND_LINK;
- ucUndiscoverableTimeDuration = 0;
- ucUndiscoverableAppSpecificDuration = 0;
-
- return RETURN_PASS;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFSHostChannel::RETURN_STATUS ANTFSHostChannel::AttemptSwitchFrequency()
- {
- USHORT usTransportChannelPeriod;
- UCHAR ucTxRetries;
- ANTFRAMER_RETURN eTxComplete;
- UCHAR ucRxRetries = 3;
- BOOL bStatus = FALSE;
- if (ucTransportFrequencySelection == ANTFS_AUTO_FREQUENCY_SELECTION)
- ucTransportLayerRadioFrequency = CheckForNewTransportFreq();
- else
- ucTransportLayerRadioFrequency = ucTransportFrequencySelection;
- switch(ucTransportChannelPeriodSelection)
- {
- case BEACON_PERIOD_0_5_HZ:
- usTransportChannelPeriod = 65535;
- break;
- case BEACON_PERIOD_1_HZ:
- usTransportChannelPeriod = 32768;
- break;
- case BEACON_PERIOD_2_HZ:
- usTransportChannelPeriod = 16384;
- break;
- case BEACON_PERIOD_4_HZ:
- usTransportChannelPeriod = 8192;
- break;
- case BEACON_PERIOD_8_HZ:
- default:
- usTransportChannelPeriod = 4096;
- break;
- }
- // Set up the command
- memset(aucTxBuf,0x00,sizeof(aucTxBuf));
- aucTxBuf[ANTFS_CONNECTION_OFFSET] = ANTFS_COMMAND_RESPONSE_ID;
- aucTxBuf[ANTFS_COMMAND_OFFSET] = ANTFS_LINK_ID;
- aucTxBuf[TRANSPORT_CHANNEL_FREQ_OFFSET] = ucTransportLayerRadioFrequency;
- aucTxBuf[TRANSPORT_CHANNEL_PERIOD] = ucTransportChannelPeriodSelection;
- Convert_ULONG_To_Bytes(ulHostSerialNumber,
- &aucTxBuf[HOST_ID_OFFSET+3],
- &aucTxBuf[HOST_ID_OFFSET+2],
- &aucTxBuf[HOST_ID_OFFSET+1],
- &aucTxBuf[HOST_ID_OFFSET]);
- ucTxRetries = 8;
- do
- {
- eTxComplete = pclANT->SendAcknowledgedData(ucChannelNumber, aucTxBuf,CONNECT_TIMEOUT);
- #if defined(DEBUG_FILE)
- if (eTxComplete == ANTFRAMER_FAIL)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSwitchFrequency(): Tx error.");
- else if (eTxComplete == ANTFRAMER_TIMEOUT)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSwitchFrequency(): Tx timeout.");
- #endif
- } while (eTxComplete == ANTFRAMER_FAIL && --ucTxRetries);
- if (eTxComplete != ANTFRAMER_PASS)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSwitchFrequency(): Failed sending connect command.");
- #endif
- return RETURN_FAIL;
- }
-
- // Change channel parameters
- if(ucTransportChannelPeriodSelection != BEACON_PERIOD_KEEP)
- {
- if (pclANT->SetChannelPeriod(ucChannelNumber, usTransportChannelPeriod, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSwitchFrequency(): Failed ANT_SetChannelPeriod().");
- #endif
- return RETURN_SERIAL_ERROR;
- }
- }
- if (pclANT->SetChannelRFFrequency(ucChannelNumber, ucTransportLayerRadioFrequency, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSwitchFrequency(): Failed ANT_SetChannelRFFreq().");
- #endif
- return RETURN_SERIAL_ERROR;
- }
- // Check that the remote device changed its channel parameters as well, and that it is still a valid beacon
- do
- {
- bNewRxEvent = FALSE;
- DSIThread_MutexLock(&stMutexCriticalSection);
- if ((bNewRxEvent == FALSE) && (*pbCancel == FALSE))
- {
- UCHAR ucResult = DSIThread_CondTimedWait(&stCondRxEvent, &stMutexCriticalSection, BROADCAST_TIMEOUT);
- if (ucResult != DSI_THREAD_ENONE)
- {
- #if defined(DEBUG_FILE)
- if(ucResult == DSI_THREAD_EOTHER)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSwitchFrequency(): CondTimedWait() Failed!");
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSwitchFrequency(): Rx timeout.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return RETURN_FAIL;
- }
- }
- bNewRxEvent = FALSE;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- if (*pbCancel == TRUE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSwitchFrequency(): Stopped.");
- #endif
- return RETURN_STOP;
- }
- if (ucFoundDeviceState == REMOTE_DEVICE_STATE_TRANS)
- bStatus = TRUE;
- } while ((bStatus == FALSE) && ucRxRetries--);
- if (!bStatus)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptSwitchFrequency(): Remote device not in transport state.");
- #endif
- IncFreqStaleCount(MINOR_STALE_COUNT); // Investigate why this happens, may be that the remote is not updating it's beacon fast enough.
- return RETURN_FAIL;
- }
- return RETURN_PASS;
- }
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::Ping(void)
- {
- UCHAR ucTxRetries;
- ANTFRAMER_RETURN eTxComplete;
- if (eANTFSState == ANTFS_HOST_STATE_TRANSPORT || eANTFSState == ANTFS_HOST_STATE_CONNECTED)
- {
- memset(aucTxBuf, 0x00, sizeof(aucTxBuf));
- aucTxBuf[ANTFS_CONNECTION_OFFSET] = ANTFS_COMMAND_RESPONSE_ID;
- aucTxBuf[ANTFS_COMMAND_OFFSET] = ANTFS_PING_ID;
- ucTxRetries = 8;
- do
- {
- eTxComplete = pclANT->SendAcknowledgedData(ucChannelNumber, aucTxBuf, PING_TIMEOUT);
- #if defined(DEBUG_FILE)
- if (eTxComplete == ANTFRAMER_FAIL)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Ping(): Tx error.");
- else if (eTxComplete == ANTFRAMER_TIMEOUT)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Ping(): Tx timeout.");
- #endif
- } while (eTxComplete == ANTFRAMER_FAIL && --ucTxRetries);
- }
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFSHostChannel::RETURN_STATUS ANTFSHostChannel::AttemptDownload(void)
- {
- UCHAR ucNoRxTicks = 4;
- UCHAR ucAttemptTick = 15;
- UCHAR aucDownloadRequest[16];
- ANTFRAMER_RETURN eTxComplete;
- UCHAR ucCRCReset = 1;
- USHORT usCRCCalc = 0;
- ULONG ulDataOffset;
- BOOL bDone = FALSE;
- ULONG ulLastTransferArrayIndex = 0;
- ULONG ulLastUpdateTime;
- /* //The found device state may not have updated yet if we attempt to ul/dl right after authentication
- if ((ucFoundDeviceState != REMOTE_DEVICE_STATE_TRANS) && (ucFoundDeviceState != REMOTE_DEVICE_STATE_BUSY))
- return RETURN_FAIL; // Not in the correct mode.
- */
- ulTransferArrayIndex = 0;
- bReceivedResponse = FALSE;
- bReceivedBurst = FALSE;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Download(): Starting download...");
- #endif
- ulLastUpdateTime = DSIThread_GetSystemTime();
- do
- {
- ulDataOffset = ulTransferDataOffset;
- if (bLargeData)
- {
- if (ulTransferArrayIndex >= 16) // The first 16 bytes of the array form the response packet so don't include it in the data offset.
- ulDataOffset += (ulTransferArrayIndex - 16);
- }
- else
- {
- if (ulTransferArrayIndex >= 8) // The first 8 bytes of the array form the response packet so don't include it in the data offset.
- ulDataOffset += (ulTransferArrayIndex - 8);
- }
- if ((!bReceivedBurst) &&(!bReceivedResponse)) //prevents us from sending requests until the Rx bursts have stopped and been cleared.
- {
- if (ucAttemptTick-- == 0)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("Download(): Maximum retry attempts reached.");
- #endif
- return RETURN_FAIL;
- }
- bRxError = FALSE;
- DSIThread_MutexLock(&stMutexCriticalSection);
- bNewRxEvent = FALSE;
- if ((bNewRxEvent == FALSE) && (*pbCancel == FALSE))
- {
- UCHAR waitResult = DSIThread_CondTimedWait(&stCondRxEvent, &stMutexCriticalSection, DOWNLOAD_RESYNC_TIMEOUT);
- if(waitResult != DSI_THREAD_ENONE)
- {
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- if (waitResult == DSI_THREAD_ETIMEDOUT)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptDownload(): Fail syncing with remote device.");
- #endif
- return RETURN_FAIL; //if we've waited 10 seconds and there is no incoming messages, something is wrong with the connection
- }
- else
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptDownload(): CondTimedWait() Failed!");
- #endif
- return RETURN_FAIL; //If the condition variable is broken, we are in trouble
- }
- }
- if (bNewRxEvent == FALSE) //The way our threads are setup, we should never see this anymore now that the locks are fixed
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptDownload():: CondTimedWait false alarm signal.");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
-
- continue;
- }
- }
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- if (*pbCancel == TRUE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("AttemptDownload(): Stopped.");
- #endif
- return RETURN_STOP;
- }
- // Send out the download command.
- memset(aucDownloadRequest, 0x00, sizeof(aucDownloadRequest));
- if (bLargeData)
- {
- aucDownloadRequest[ANTFS_CONNECTION_OFFSET] = ANTFS_COMMAND_RESPONSE_ID;
- aucDownloadRequest[ANTFS_COMMAND_OFFSET] = ANTFS_DOWNLOAD_BIG_ID;
- Convert_USHORT_To_Bytes(usTransferDataFileIndex,
- &aucDownloadRequest[DATA_INDEX_OFFSET + 1],
- &aucDownloadRequest[DATA_INDEX_OFFSET]);
- Convert_ULONG_To_Bytes(ulDataOffset,
- &aucDownloadRequest[DOWNLOAD_DATA_OFFSET_OFFSET + 3],
- &aucDownloadRequest[DOWNLOAD_DATA_OFFSET_OFFSET + 2],
- &aucDownloadRequest[DOWNLOAD_DATA_OFFSET_OFFSET + 1],
- &aucDownloadRequest[DOWNLOAD_DATA_OFFSET_OFFSET]);
- if (ulTransferByteSize) //if the max file size is set
- {
- ULONG ulLocalBlockSize = MAX_ULONG;
- if(ulHostBlockSize)
- ulLocalBlockSize = ulHostBlockSize;
-
- //We need to set the block size to the max transfer size - the offset.
- if(ulLocalBlockSize > (ulTransferByteSize - (ulDataOffset - ulTransferDataOffset)))
- ulLocalBlockSize = ulTransferByteSize - (ulDataOffset - ulTransferDataOffset);
- Convert_ULONG_To_Bytes(ulLocalBlockSize,
- &aucDownloadRequest[DOWNLOAD_MAX_BLOCK_SIZE_OFFSET + 3],
- &aucDownloadRequest[DOWNLOAD_MAX_BLOCK_SIZE_OFFSET + 2],
- &aucDownloadRequest[DOWNLOAD_MAX_BLOCK_SIZE_OFFSET + 1],
- &aucDownloadRequest[DOWNLOAD_MAX_BLOCK_SIZE_OFFSET]);
- }
- if (ulTransferArrayIndex > 16) // If the download has progressed at least to the first data packet
- ucCRCReset = 0; // Clear the Initial download request bit, so the client knows to start checking our CRC
- aucDownloadRequest[DOWNLOAD_INITIAL_REQUEST_OFFSET] = ucCRCReset; // Set initial request byte
- if (ucCRCReset == 0) // If this is not the initial request
- { // Calculate and send a non-zero CRC value
- if (pucTransferBuffer != NULL) // Just to make sure the transfer buffer has been created
- usCRCCalc = CRC_Calc16(&pucTransferBuffer[16], ulDataOffset); //CRC_UpdateCRC16
- else
- usCRCCalc = 0;
- Convert_USHORT_To_Bytes(usCRCCalc,
- &aucDownloadRequest[DOWNLOAD_CRC_SEED_OFFSET + 1],
- &aucDownloadRequest[DOWNLOAD_CRC_SEED_OFFSET]);
- }
- }
- else
- {
- aucDownloadRequest[ANTFS_CONNECTION_OFFSET] = ANTFS_COMMAND_RESPONSE_ID;
- aucDownloadRequest[ANTFS_COMMAND_OFFSET] = ANTFS_DOWNLOAD_SMALL_ID;
- Convert_USHORT_To_Bytes(usTransferDataFileIndex,
- &aucDownloadRequest[DATA_INDEX_OFFSET + 1],
- &aucDownloadRequest[DATA_INDEX_OFFSET]);
- Convert_ULONG_To_Bytes(ulDataOffset,
- (UCHAR*)NULL,
- (UCHAR*)NULL,
- &aucDownloadRequest[DATA_OFFSET_SMALL_OFFSET + 1],
- &aucDownloadRequest[DATA_OFFSET_SMALL_OFFSET]);
- Convert_ULONG_To_Bytes(ulTransferByteSize,
- (UCHAR*)NULL,
- (UCHAR*)NULL,
- &aucDownloadRequest[MAX_BLOCK_SIZE_SMALL_OFFSET + 1],
- &aucDownloadRequest[MAX_BLOCK_SIZE_SMALL_OFFSET]);
- }
- if (bLargeData)
- eTxComplete = pclANT->SendANTFSTransfer(ucChannelNumber, (UCHAR*)NULL, (UCHAR*)NULL, aucDownloadRequest, 16, ACKNOWLEDGED_TIMEOUT, (ULONG*)NULL);
- else
- eTxComplete = pclANT->SendAcknowledgedData(ucChannelNumber, aucDownloadRequest, ACKNOWLEDGED_TIMEOUT);
- #if defined(DEBUG_FILE)
- if (eTxComplete == ANTFRAMER_FAIL)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Download(): Tx error sending download command.");
- else if (eTxComplete == ANTFRAMER_TIMEOUT)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Download(): Tx timeout sending download command.");
- #endif
- //Removed the immediate retries to avoid the issue of queing up requests while we get a response for a request we thought we failed.
- if (eTxComplete == ANTFRAMER_TIMEOUT)
- return RETURN_FAIL;
- }
- //Do not need to clear bReceivedBurst here because it will be done if the transfer fails, if we timeout, or receive a broadcast.
- //Now we wait for a response...
- while (bDone == FALSE)
- {
- //Wait for an rxEvent before starting to check the data
- //Since this event is fired for many circumstances we manage all the error checking below and
- //just use this for the wait functionality.
- DSIThread_MutexLock(&stMutexCriticalSection);
- bNewRxEvent = FALSE;
- if ((bNewRxEvent == FALSE) && (*pbCancel == FALSE))
- {
- DSIThread_CondTimedWait(&stCondRxEvent, &stMutexCriticalSection, BURST_CHECK_TIMEOUT);
- }
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- if (*pbCancel == TRUE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptDownload(): Stopped.");
- #endif
- return RETURN_STOP;
- }
- if (bReceivedResponse) //If a response has been received, process it.
- {
- bReceivedResponse = FALSE; //Clear these for any potential retries
- bReceivedBurst = FALSE; //Clearing this here allows for quicker retries, otherwise we would have to wait for an incoming broadcast to clear it
- bDone = TRUE; //Mark that we are done... for now.
- if ((pucTransferBufferDynamic) && ((pucTransferBufferDynamic[ANTFS_COMMAND_OFFSET] == ANTFS_RESPONSE_DOWNLOAD_SMALL_ID) || (pucTransferBufferDynamic[ANTFS_COMMAND_OFFSET] == ANTFS_RESPONSE_DOWNLOAD_BIG_ID)))
- {
- if (pucTransferBufferDynamic[DOWNLOAD_RESPONSE_OFFSET] == DOWNLOAD_RESPONSE_CRC_FAILED)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Download(): CRC failed, download failed.");
- #endif
- //clear variables to retry from start.
- ucCRCReset = 1;
- usCRCCalc = 0;
- ulTransferArrayIndex = 16;
- ulLastTransferArrayIndex = 16;
- bDone = FALSE;
- break;
- }
- else if (pucTransferBufferDynamic[DOWNLOAD_RESPONSE_OFFSET] != DOWNLOAD_RESPONSE_OK)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Download(): Download request rejected.");
- #endif
- ucRejectCode = pucTransferBufferDynamic[DOWNLOAD_RESPONSE_OFFSET];
- return RETURN_REJECT;
- }
- }
- else
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Download(): Unknown response during download.");
- #endif
- return RETURN_FAIL;
- }
- // Check if we need to check the CRC
- if ((bLargeData) &&
- (((ulDataOffset - ulTransferDataOffset) + ulTransferBytesInBlock + 8) < ulTransferArrayIndex)) //if there is one more packet beyond the data, we will process the CRC
- {
- ULONG ulCRCLocation, ulLength;
- USHORT usReceivedCRC;
- USHORT usCalcCRC;
- ulLength = (ulDataOffset - ulTransferDataOffset) + ulTransferBytesInBlock; //find length of actual data that needs to be CRC checked
- ulCRCLocation = ulTransferArrayIndex - 2; //Assume that the CRC will be the last 2 bytes of the last packet received
- ulTransferArrayIndex = ulLength + 16; //correct ulTransferArrayIndex in case we are downloading in odd blocks.
- usReceivedCRC = pucTransferBufferDynamic[ulCRCLocation];
- usReceivedCRC |= ((USHORT)pucTransferBufferDynamic[ulCRCLocation + 1] << 8);
- usCalcCRC = CRC_Calc16(&pucTransferBufferDynamic[16], ulLength); //Calculate the CRC of the received data from the start, this should always be what the CRC value is based in becaue we pass in the initial seed
- if (usCalcCRC != usReceivedCRC)
- {
- #if defined(DEBUG_FILE)
- char cBuffer[256];
- SNPRINTF(cBuffer, 256, "ANTFSHostChannel::Download(): Failed CRC Check. Expected %d, Got %d",usCalcCRC, usReceivedCRC);
- DSIDebug::ThreadWrite(cBuffer);
- #endif
- //return RETURN_FAIL;
- //clear variables to retry from start.
- ucCRCReset = 1;
- usCRCCalc = 0;
- ulTransferArrayIndex = 16;
- ulLastTransferArrayIndex = 16;
- bDone = FALSE;
- }
- }
- //Catch the cases where we get a completed transfer but there are more packets coming
- if ((bLargeData) && ((ulTransferArrayIndex -16) < ulTransferTotalBytesRemaining))
- bDone = FALSE;
- ucNoRxTicks = 4; // Reset counter
- ucAttemptTick = 15; // Reset counter for attempts of request
- break;
- }
- if (bRxError)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Download(): Rx error.");
- #endif
- break;
- }
- if (ulTransferArrayIndex > ulLastTransferArrayIndex)
- {
- ulLastUpdateTime = DSIThread_GetSystemTime();
- ulLastTransferArrayIndex = ulTransferArrayIndex;
- }
- else
- {
- if ((DSIThread_GetSystemTime() - ulLastUpdateTime) > DOWNLOAD_LOOP_TIMEOUT)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Download(): Timeout receiving packets.");
- #endif
- return RETURN_FAIL;
- }
- }
- if (!bReceivedBurst)
- {
- if ((ucFoundDeviceState != REMOTE_DEVICE_STATE_BUSY) && (ucNoRxTicks > 0))
- ucNoRxTicks--;
- if (ucNoRxTicks == 0)
- {
- ucNoRxTicks = 4;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Download(): Not receiving packets.");
- #endif
- break;
- }
- }
- else
- {
- ucNoRxTicks = 4; // Reset counter
- ucAttemptTick = 15; // Reset counter for attempts of request
- }
- ReportDownloadProgress();
- } //while();
- } while (!bDone);
- bTransfer = TRUE;
- // Wait for resync.
- DSIThread_MutexLock(&stMutexCriticalSection);
- bNewRxEvent = FALSE;
- if ((bNewRxEvent == FALSE) && (*pbCancel == FALSE))
- {
- UCHAR ucResult = DSIThread_CondTimedWait(&stCondRxEvent, &stMutexCriticalSection, BROADCAST_TIMEOUT);
- if (ucResult != DSI_THREAD_ENONE)
- {
- #if defined(DEBUG_FILE)
- if(ucResult == DSI_THREAD_EOTHER)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptDownload(): CondTimedWait() Failed!");
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptDownload(): Rx timeout.");
- #endif
- }
- }
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return RETURN_PASS;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFSHostChannel::RETURN_STATUS ANTFSHostChannel::UploadLoop(void)
- {
- RETURN_STATUS eReturn;
- ULONG ulLastProgressValue = 0;
- ULONG ulLastTimeWeGotDataThru = DSIThread_GetSystemTime();
- UCHAR ucFreshRetries = 3;
- #if defined(DEBUG_FILE)
- UCHAR aucString[256];
- #endif
- do
- {
- //ulLastProgressValue = ulUploadIndexProgress; // figure out where we thought we left off last time, this may be a little further than we actually got, but it will be okay unless the USB device has a massive amount of buffering or is broken.
- eReturn = AttemptUpload();
- switch (eReturn)
- {
- case RETURN_PASS:
- if ((ulUploadIndexProgress - UPLOAD_DATA_MESG_OVERHEAD) >= ulTransferByteSize)
- return RETURN_PASS;
- if (ulUploadIndexProgress > ulLastProgressValue + UPLOAD_DATA_MESG_OVERHEAD) //we use the overhead size for the check here because the return was a pass
- {
- bForceUploadOffset = FALSE; //clear the force offset if we get any data across
- ulLastTimeWeGotDataThru = DSIThread_GetSystemTime();
- ulLastProgressValue = ulUploadIndexProgress;
- }
- #if defined(DEBUG_FILE)
- SNPRINTF((char *) aucString, 256, "ANTFSHostChannel::UploadLoop(): RETURN_PASS - %lu", ulLastTimeWeGotDataThru);
- DSIDebug::ThreadWrite((char *) aucString);
- #endif
- break;
- case RETURN_FAIL:
- if (ulUploadIndexProgress > ulLastProgressValue + UPLOAD_PROGRESS_CHECK_BYTES) //we use the larger check size here because the return was a failure
- {
- bForceUploadOffset = FALSE; //clear the force offset if we get any data across
- ulLastTimeWeGotDataThru = DSIThread_GetSystemTime();
- ulLastProgressValue = ulUploadIndexProgress;
- }
- #if defined(DEBUG_FILE)
- SNPRINTF((char *) aucString, 256, "ANTFSHostChannel::UploadLoop(): RETURN_FAIL - %lu", ulLastTimeWeGotDataThru);
- DSIDebug::ThreadWrite((char *) aucString);
- #endif
- break;
- case RETURN_NA: //This means we have failed CRC or the device returned a weird last offset.
- if (ucFreshRetries--)
- {
- ulUploadIndexProgress = 0; //reset the progress
- ulLastProgressValue = 0;
- ulLastTimeWeGotDataThru = DSIThread_GetSystemTime(); //reset the time
- }
- else
- {
- return RETURN_FAIL;
- }
- break;
- case RETURN_REJECT:
- case RETURN_STOP:
- default:
- return eReturn;
- break;
- }
- }
- while ((DSIThread_GetSystemTime() - ulLastTimeWeGotDataThru) < UPLOAD_LOOP_TIMEOUT);
- return RETURN_FAIL;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFSHostChannel::RETURN_STATUS ANTFSHostChannel::AttemptUpload(void)
- {
- BOOL bStatus = FALSE;
- UCHAR aucTxUpload[16];
- UCHAR aucUploadHeader[8];
- UCHAR aucUploadFooter[8];
- ULONG ulStartTime;
- UCHAR ucTxRetries;
- ANTFRAMER_RETURN eTxComplete;
- ULONG ulLastOffset;
- ULONG ulMaxBlockSize, ulMaxFileSize, ulUploadTimeout, ulLocalTransferSize;
- ANTFRAMER_RETURN eReturn;
- USHORT usReceivedCRC;
- USHORT usCalculatedCRC;
- USHORT usCRCSeed;
- UCHAR ucUploadResponse;
- //The found device state may not have updated yet if we attempt to ul/dl right after authentication, but addition of ULLoop allows us to do this check
- if ((ucFoundDeviceState != REMOTE_DEVICE_STATE_TRANS) && (ucFoundDeviceState != REMOTE_DEVICE_STATE_BUSY))
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Upload(): Remote device is not in correct state.");
- #endif
- return RETURN_FAIL; // Not in the correct mode.
- }
- //ulTransferArrayIndex = 0;
- bReceivedResponse = FALSE;
- bRxError = FALSE;
- bReceivedBurst = FALSE;
- memset(aucTxUpload, 0x00, sizeof(aucTxUpload));
- ULONG ulMaxTransferIndex = ulTransferDataOffset + ulTransferByteSize;
- // Build upload request
- aucTxUpload[ANTFS_CONNECTION_OFFSET] = ANTFS_COMMAND_RESPONSE_ID;
- aucTxUpload[ANTFS_COMMAND_OFFSET] = ANTFS_UPLOAD_BIG_ID;
- Convert_USHORT_To_Bytes(usTransferDataFileIndex,
- &aucTxUpload[DATA_INDEX_OFFSET + 1],
- &aucTxUpload[DATA_INDEX_OFFSET]);
- Convert_ULONG_To_Bytes(ulMaxTransferIndex,
- &aucTxUpload[UPLOAD_MAX_SIZE_OFFSET + 3],
- &aucTxUpload[UPLOAD_MAX_SIZE_OFFSET + 2],
- &aucTxUpload[UPLOAD_MAX_SIZE_OFFSET + 1],
- &aucTxUpload[UPLOAD_MAX_SIZE_OFFSET]);
- if (bForceUploadOffset)
- {
- Convert_ULONG_To_Bytes(ulTransferDataOffset,
- &aucTxUpload[UPLOAD_DATA_OFFSET_OFFSET + 3],
- &aucTxUpload[UPLOAD_DATA_OFFSET_OFFSET + 2],
- &aucTxUpload[UPLOAD_DATA_OFFSET_OFFSET + 1],
- &aucTxUpload[UPLOAD_DATA_OFFSET_OFFSET]);
- }
- else
- {
- Convert_ULONG_To_Bytes(MAX_ULONG,
- &aucTxUpload[UPLOAD_DATA_OFFSET_OFFSET + 3],
- &aucTxUpload[UPLOAD_DATA_OFFSET_OFFSET + 2],
- &aucTxUpload[UPLOAD_DATA_OFFSET_OFFSET + 1],
- &aucTxUpload[UPLOAD_DATA_OFFSET_OFFSET]);
- }
- bNewRxEvent = FALSE;
- ucTxRetries = 8;
- // Try sending upload request until success or retries exhausted.
- eTxComplete = pclANT->SendANTFSTransfer(ucChannelNumber, (UCHAR*)NULL, (UCHAR*)NULL, aucTxUpload, 16, ACKNOWLEDGED_TIMEOUT, (ULONG*)NULL);
- #if defined(DEBUG_FILE)
- if (eTxComplete == ANTFRAMER_FAIL)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Upload(): Tx error sending upload command.");
- else if (eTxComplete == ANTFRAMER_TIMEOUT)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Upload(): Tx timeout sending upload command.");
- #endif
- //Removed the immediate retries to avoid the issue of queing up requests while we get a response for a request we thought we failed.
- if (eTxComplete == ANTFRAMER_TIMEOUT)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Upload(): Tx failed.");
- #endif
- return RETURN_FAIL;
- }
- ulStartTime = DSIThread_GetSystemTime();
- ucLinkResponseRetries = ANTFS_RESPONSE_RETRIES;
- do
- {
- DSIThread_MutexLock(&stMutexCriticalSection);
- if ((bNewRxEvent == FALSE) && (*pbCancel == FALSE))
- {
- DSIThread_CondTimedWait(&stCondRxEvent, &stMutexCriticalSection, 1000);
- }
- bNewRxEvent = FALSE;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- if (*pbCancel == TRUE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptUpload(): Stopped.");
- #endif
- return RETURN_STOP;
- }
- if (bReceivedResponse)
- {
- if (aucTransferBufferFixed[ANTFS_COMMAND_OFFSET] == ANTFS_RESPONSE_UPLOAD_ID)
- {
- if (aucTransferBufferFixed[UPLOAD_RESPONSE_OFFSET] == UPLOAD_RESPONSE_OK)
- {
- bStatus = TRUE;
- bLargeData = TRUE;
- }
- else
- {
- ucRejectCode = aucTransferBufferFixed[UPLOAD_RESPONSE_OFFSET];
- return RETURN_REJECT;
- }
- }
- }
- #if defined(DEBUG_FILE)
- else
- {
- DSIDebug::ThreadWrite("-->Requesting Upload...");
- }
- #endif
- if ((bRxError) || (ucFoundDeviceState != REMOTE_DEVICE_STATE_BUSY))
- {
- #if defined(DEBUG_FILE)
- if (bRxError)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Upload(): Rx error");
- else
- DSIDebug::ThreadWrite("ANTFSHostChannel::Upload(): Non-busy beacon");
- #endif
- if (ucLinkResponseRetries == 0)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Upload(): Retries exhausted");
- #endif
- return RETURN_FAIL;
- }
- else
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Upload(): Retrying");
- #endif
- ucLinkResponseRetries--;
- bRxError = FALSE;
- }
- }
- } while ((bStatus == FALSE) && ((DSIThread_GetSystemTime() - ulStartTime) < UPLOAD_REQUEST_TIMEOUT));
- if (!bStatus)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Upload(): Timeout.");
- #endif
- return RETURN_FAIL;
- }
- bReceivedResponse = FALSE;
- bNewRxEvent = FALSE;
- ucUploadResponse = aucTransferBufferFixed[UPLOAD_RESPONSE_OFFSET];
- if (!ucUploadResponse) // it's accepting the upload
- {
- // Decode response
- ulLastOffset = Convert_Bytes_To_ULONG(aucTransferBufferFixed[UPLOAD_RESPONSE_LAST_OFFSET_OFFSET + 3],
- aucTransferBufferFixed[UPLOAD_RESPONSE_LAST_OFFSET_OFFSET + 2],
- aucTransferBufferFixed[UPLOAD_RESPONSE_LAST_OFFSET_OFFSET + 1],
- aucTransferBufferFixed[UPLOAD_RESPONSE_LAST_OFFSET_OFFSET]);
- ulMaxBlockSize = Convert_Bytes_To_ULONG(aucTransferBufferFixed[UPLOAD_RESPONSE_BLOCK_SIZE_OFFSET + 3],
- aucTransferBufferFixed[UPLOAD_RESPONSE_BLOCK_SIZE_OFFSET + 2],
- aucTransferBufferFixed[UPLOAD_RESPONSE_BLOCK_SIZE_OFFSET + 1],
- aucTransferBufferFixed[UPLOAD_RESPONSE_BLOCK_SIZE_OFFSET]);
- usReceivedCRC = Convert_Bytes_To_USHORT(aucTransferBufferFixed[UPLOAD_RESPONSE_CRC_OFFSET + 1],
- aucTransferBufferFixed[UPLOAD_RESPONSE_CRC_OFFSET]);
- ulMaxFileSize = Convert_Bytes_To_ULONG(aucTransferBufferFixed[UPLOAD_RESPONSE_MAX_SIZE_OFFSET + 3],
- aucTransferBufferFixed[UPLOAD_RESPONSE_MAX_SIZE_OFFSET + 2],
- aucTransferBufferFixed[UPLOAD_RESPONSE_MAX_SIZE_OFFSET + 1],
- aucTransferBufferFixed[UPLOAD_RESPONSE_MAX_SIZE_OFFSET]);
- if (ulMaxTransferIndex > ulMaxFileSize)
- {
- #if defined(DEBUG_FILE)
- UCHAR aucString[256];
- SNPRINTF((char *) aucString, 256, "ANTFSHostChannel::Upload(): Upload size larger than Max Files size (%lu > %lu)", ulMaxTransferIndex, ulMaxFileSize);
- DSIDebug::ThreadWrite((char *) aucString);
- #endif
- ucRejectCode = UPLOAD_RESPONSE_INSUFFICIENT_SPACE;
- return RETURN_REJECT;
- }
- if (bForceUploadOffset) // Override the suggested offset if we are instructed to.
- {
- usCRCSeed = 0;
- ulLastOffset = ulTransferDataOffset; // We will start from where the app told us to
- ulLocalTransferSize = ulTransferByteSize; // and set the next transfer size to the correct value
- }
- else //we need to check the CRC
- {
- if (ulLastOffset > ulMaxTransferIndex) //The last offset we got is larger than our max, we are just going to force a restart from where we want to start
- {
- #if defined(DEBUG_FILE)
- UCHAR aucString[256];
- SNPRINTF((char *) aucString, 256, "ANTFSHostChannel::Upload(): ulLastOffset from device is larger than our max offset - Restarting UL (%lu > %lu)", ulLastOffset, ulMaxTransferIndex);
- DSIDebug::ThreadWrite((char *) aucString);
- #endif
- bForceUploadOffset = TRUE;
- return RETURN_NA;
- }
- usCRCSeed = CRC_Calc16(&pucUploadData[0], ulLastOffset-ulTransferDataOffset);
- if (usCRCSeed != usReceivedCRC)
- {
- #if defined(DEBUG_FILE)
- UCHAR aucString[256];
- SNPRINTF((char *) aucString, 256, "ANTFSHostChannel::Upload(): CRC Check Failed - Wanted 0x%04X, Got 0x%04X", usCRCSeed, usReceivedCRC);
- DSIDebug::ThreadWrite((char *) aucString);
- #endif
- //We are going to send no data.
- ulLocalTransferSize = 0;
- //ulLastOffset = 0; // we're going to start over if the client doesn't have the right CRC
- bForceUploadOffset = TRUE;
- return RETURN_NA;
- }
- }
- if ((ulLastOffset == ulMaxTransferIndex))
- {
- #if defined(DEBUG_FILE)
- UCHAR aucString[256];
- SNPRINTF((char *) aucString, 256, "ANTFSHostChannel::Upload(): We think we were sucessful Last time - UploadIndexProgress %lu, TransferByteSize %lu", ulUploadIndexProgress, ulTransferByteSize);
- DSIDebug::ThreadWrite((char *) aucString);
- #endif
- //ulLastOffset = 0;
- ulLocalTransferSize = 0; //Send only the header and try if we think we actually completed last time and only failed getting the response
- }
- else
- {
- if (ulLastOffset > ulTransferDataOffset) //Check if there is a suggested last offset and if it's further along than our original offset
- {
- ulLocalTransferSize = ulTransferByteSize - (ulLastOffset - ulTransferDataOffset); //If it is then we'll use it, and adjust the size of the next burst
- }
- else
- {
- ulLastOffset = ulTransferDataOffset; // We will start from where the app told us to
- ulLocalTransferSize = ulTransferByteSize; // and set the next transfer size to the correct value
- }
- }
- if (ulLocalTransferSize) // If we are actually sending data
- ulUploadIndexProgress = ulLastOffset - ulTransferDataOffset; // Set the progress to start at the offset
- else
- ulUploadIndexProgress = ulTransferByteSize; // Otherwise, we are already complete and just need confirmation, so set the progress back to the transfer size (the transfer function will keep trying to add to this because of the header)
- if(ulMaxBlockSize < ulLocalTransferSize) // Check if we exceed the max client block size
- ulLocalTransferSize = ulMaxBlockSize;
- if(ulHostBlockSize < ulLocalTransferSize) // Check if we exceed the max host block size
- ulLocalTransferSize = ulHostBlockSize;
- if (ulLocalTransferSize)
- {
- usCalculatedCRC = CRC_Calc16(&pucUploadData[0], (ulLastOffset - ulTransferDataOffset) + ulLocalTransferSize); // compute the CRC fromt he start up till the end of the current block
- }
- else
- {
- usCalculatedCRC = usCRCSeed;
- }
- //Add CRC to the footer.
- memset(aucUploadFooter,0x00,sizeof(aucUploadFooter));
- Convert_USHORT_To_Bytes(usCalculatedCRC,
- &aucUploadFooter[UPLOAD_DATA_CRC_OFFSET + 1],
- &aucUploadFooter[UPLOAD_DATA_CRC_OFFSET]); //put CRC at the end of the footer packet
- // figure out our timeout value from the size of the transfer
- if (ulLocalTransferSize > ((MAX_ULONG - BROADCAST_TIMEOUT) / 2))
- ulUploadTimeout = (MAX_ULONG - 1);
- else
- ulUploadTimeout = BROADCAST_TIMEOUT + (ulTransferByteSize * 2);
- // fill in the header information
- aucUploadHeader[0] = ANTFS_COMMAND_RESPONSE_ID;
- aucUploadHeader[1] = ANTFS_UPLOAD_DATA_ID;
- Convert_USHORT_To_Bytes(usCRCSeed,
- &aucUploadHeader[UPLOAD_DATA_CRC_SEED_OFFSET + 1],
- &aucUploadHeader[UPLOAD_DATA_CRC_SEED_OFFSET]);
- if ((ulLastOffset == ulMaxTransferIndex)) // If we think we are done, we will fill zero into the offset but we send no data.
- { // This should result in only a complete to the embedded application.
- Convert_ULONG_To_Bytes(0,
- &aucUploadHeader[UPLOAD_DATA_DATA_OFFSET_OFFSET + 3],
- &aucUploadHeader[UPLOAD_DATA_DATA_OFFSET_OFFSET + 2],
- &aucUploadHeader[UPLOAD_DATA_DATA_OFFSET_OFFSET + 1],
- &aucUploadHeader[UPLOAD_DATA_DATA_OFFSET_OFFSET]);
- }
- else
- {
- Convert_ULONG_To_Bytes(ulLastOffset,
- &aucUploadHeader[UPLOAD_DATA_DATA_OFFSET_OFFSET + 3],
- &aucUploadHeader[UPLOAD_DATA_DATA_OFFSET_OFFSET + 2],
- &aucUploadHeader[UPLOAD_DATA_DATA_OFFSET_OFFSET + 1],
- &aucUploadHeader[UPLOAD_DATA_DATA_OFFSET_OFFSET]);
- }
- //Send the Burst
- eReturn = pclANT->SendANTFSTransfer(ucChannelNumber, aucUploadHeader, aucUploadFooter, &pucUploadData[ulLastOffset], ulLocalTransferSize, ulUploadTimeout, &ulUploadIndexProgress);
- if (eReturn == ANTFRAMER_FAIL)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Upload(): Failed Actual Upload Transfer.");
- #endif
- //fall thru to catch response
- }
- else if (eReturn == ANTFRAMER_CANCELLED)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptUpload(): Stopped2.");
- #endif
- return RETURN_STOP;
- }
- else if (eReturn == ANTFRAMER_TIMEOUT)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptUpload(): Tx transfer timeout.");
- #endif
- return RETURN_FAIL;
- }
- }
- else
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Upload(): Rejected by Client.");
- #endif
- ucRejectCode = ucUploadResponse;
- return RETURN_FAIL;
- }
- ulStartTime = DSIThread_GetSystemTime();
- //ResetEvent(hEventRx);
- ucLinkResponseRetries = ANTFS_RESPONSE_RETRIES;
- bStatus = FALSE;
- do
- {
- DSIThread_MutexLock(&stMutexCriticalSection);
- if ((bNewRxEvent == FALSE) && (*pbCancel == FALSE))
- {
- DSIThread_CondTimedWait(&stCondRxEvent, &stMutexCriticalSection, 1000);
- }
- bNewRxEvent = FALSE;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- if (*pbCancel == TRUE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptUpload(): Stopped.");
- #endif
- return RETURN_STOP;
- }
- if ((bRxError) || (ucFoundDeviceState != REMOTE_DEVICE_STATE_BUSY))
- {
- #if defined(DEBUG_FILE)
- if (bRxError)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Upload(): Rx error2");
- else
- DSIDebug::ThreadWrite("ANTFSHostChannel::Upload(): Non-busy beacon2");
- #endif
- if (ucLinkResponseRetries == 0)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Upload(): Retries exhausted2");
- #endif
- return RETURN_FAIL;
- }
- else
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Upload(): Retrying2");
- #endif
- ucLinkResponseRetries--;
- bRxError = FALSE;
- }
- }
- if (bReceivedResponse)
- {
- if (aucTransferBufferFixed[ANTFS_COMMAND_OFFSET] == ANTFS_RESPONSE_UPLOAD_COMPLETE_ID)
- {
- if (aucTransferBufferFixed[UPLOAD_RESPONSE_OFFSET] == UPLOAD_RESPONSE_OK)
- {
- return RETURN_PASS;
- }
- else
- {
- return RETURN_FAIL;
- }
- }
- }
- #if defined(DEBUG_FILE)
- else
- {
- DSIDebug::ThreadWrite("-->Waiting for upload complete...");
- }
- #endif
- } while ((bStatus == FALSE) && ((DSIThread_GetSystemTime() - ulStartTime) < UPLOAD_RESPONSE_TIMEOUT));
- return RETURN_FAIL;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFSHostChannel::RETURN_STATUS ANTFSHostChannel::AttemptManualTransfer(void)
- {
- ULONG ulBlockSize;
- USHORT usBlockOffset;
- // Convert bytes remaining to blocks remaining.
- if (ulTransferByteSize % 8)
- ulBlockSize = 1; // There is a remainder, so we need to send one extra payload to hold all the data.
- else
- ulBlockSize = 0;
- ulBlockSize += ulTransferByteSize / 8;
- // Convert byte offset to block offset.
- usBlockOffset = (USHORT) ulTransferDataOffset / 8; // The remainder must be dropped when computing offset.
- ulTransferArrayIndex = 0;
- bReceivedBurst = FALSE;
- bReceivedResponse = FALSE;
- if (*pbCancel == TRUE)
- return RETURN_STOP;
- aucSendDirectBuffer[ANTFS_CONNECTION_OFFSET] = ANTFS_COMMAND_RESPONSE_ID;
- aucSendDirectBuffer[ANTFS_COMMAND_OFFSET] = ANTFS_SEND_DIRECT_ID;
- Convert_USHORT_To_Bytes(usTransferDataFileIndex,
- &aucSendDirectBuffer[DATA_INDEX_OFFSET + 1],
- &aucSendDirectBuffer[DATA_INDEX_OFFSET]);
- Convert_USHORT_To_Bytes(usBlockOffset,
- &aucSendDirectBuffer[DATA_OFFSET_OFFSET_HIGH],
- &aucSendDirectBuffer[DATA_OFFSET_OFFSET_LOW]);
- Convert_ULONG_To_Bytes(ulBlockSize - 1, // Size - 1, as per the spec.
- (UCHAR*)NULL,
- (UCHAR*)NULL,
- &aucSendDirectBuffer[DATA_BLOCK_SIZE_OFFSET_HIGH],
- &aucSendDirectBuffer[DATA_BLOCK_SIZE_OFFSET_LOW]);
- #if 0
- #if defined(DEBUG_FILE)
- {
- char acString[256];
- int iCounter;
- ULONG ulCounter2;
- SNPRINTF(acString, 256, "ANTFSHostChannel::ManualTransfer(): ulTransferByteSize = %lu; ulTransferDataOffset = %lu.", ulTransferByteSize, ulTransferDataOffset);
- DSIDebug::ThreadWrite(acString);
- for (ulCounter2 = 0; ulCounter2 < ulBlockSize; ulCounter2++)
- {
- SNPRINTF(acString, 256, "ANTFSHostChannel::ManualTransfer(): <%lu>", ulCounter2);
- for (iCounter = 0; iCounter < 8; iCounter++)
- {
- char acSubString[10];
- SNPRINTF(acSubString, 10, "[%02X]", aucSendDirectBuffer[ulCounter2 + (ULONG) iCounter]);
- SNPRINTF(acString, 256, "%s%s", acString, acSubString);
- }
- DSIDebug::ThreadWrite(acString);
- }
- }
- #endif
- #endif
- ulUploadIndexProgress = 0;
- //pclANT->SendANTFSTransfer(ucChannelNumber, aucSendDirectBuffer, &aucSendDirectBuffer[8], (ulBlockSize + 1)*8, 120000, &ulUploadIndexProgress); // Size + 1 to account for the command payload.
- pclANT->SendANTFSTransfer(ucChannelNumber, (UCHAR*)NULL, (UCHAR*)NULL, aucSendDirectBuffer, (ulBlockSize + 1)*8, 120000, &ulUploadIndexProgress); // Size + 1 to account for the command payload.
- //pclANT->SendTransfer(ANTFS_CHANNEL, aucSendDirectBuffer, (ulBlockSize + 1)*8,120000); // Size + 1 to account for the command payload.
- //allow the receive function to return with error, even if the Tx transfer failed
- return Receive();
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFSHostChannel::RETURN_STATUS ANTFSHostChannel::Receive(void)
- {
- ULONG ulNoRxTime = DSIThread_GetSystemTime();
- UCHAR ucTicks = ucTransportBeaconTicks;
- bNewRxEvent = FALSE;
- eANTFSState = ANTFS_HOST_STATE_RECEIVING;
- while (bKillThread == FALSE)
- {
- DSIThread_MutexLock(&stMutexCriticalSection);
- if ((bNewRxEvent == FALSE) && (*pbCancel == FALSE))
- {
- UCHAR ucResult = DSIThread_CondTimedWait(&stCondRxEvent, &stMutexCriticalSection, BURST_CHECK_TIMEOUT);
- if (ucResult != DSI_THREAD_ENONE)
- {
- #if defined(DEBUG_FILE)
- if(ucResult == DSI_THREAD_EOTHER)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Receive(): CondTimedWait() Failed!");
- #endif
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- return RETURN_FAIL;
- }
- }
- bNewRxEvent = FALSE;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- if (*pbCancel == TRUE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Receive(): Stopped.");
- #endif
- return RETURN_STOP;
- }
- if ((ucFoundDeviceState == REMOTE_DEVICE_STATE_TRANS) && ((ucTransportBeaconTicks - ucTicks) >= 5))
- return RETURN_REJECT;
- if (bReceivedResponse && (ucFoundDeviceState == REMOTE_DEVICE_STATE_TRANS))
- {
- if (pucTransferBufferDynamic == NULL)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Receive(): pucTransferBufferDynamic is an undefined pointer.");
- #endif
- break;
- }
- if (pucTransferBufferDynamic[ANTFS_COMMAND_OFFSET] == ANTFS_RESPONSE_SEND_DIRECT_ID)
- {
- // If the index, offset and block size bytes are all 0xFF, then the
- // sent data was rejected by the remote device.
- int i;
- BOOL bAll0xFF = TRUE;
- for (i = 2; i < 8; i++)
- {
- if (pucTransferBufferDynamic[i] != 0xFF)
- {
- bAll0xFF = FALSE;
- break;
- }
- }
- if (bAll0xFF)
- return RETURN_REJECT;
- bTransfer = TRUE;
- return RETURN_PASS;
- }
- else
- {
- #if defined(DEBUG_FILE)
- char acString[256];
- SNPRINTF(acString, 256, "ANTFSHostChannel::Receive(): Bad response: [%02X][%02X][%02X][%02X][%02X][%02X][%02X][%02X]",
- pucTransferBufferDynamic[0],
- pucTransferBufferDynamic[1],
- pucTransferBufferDynamic[2],
- pucTransferBufferDynamic[3],
- pucTransferBufferDynamic[4],
- pucTransferBufferDynamic[5],
- pucTransferBufferDynamic[6],
- pucTransferBufferDynamic[7]);
- DSIDebug::ThreadWrite(acString);
- #endif
- break;
- }
- }
- if (bRxError)
- bRxError = FALSE;
- if (!bReceivedBurst)
- {
- if ((DSIThread_GetSystemTime() - ulNoRxTime) > SEND_DIRECT_BURST_TIMEOUT)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Receive(): Timeout waiting for burst packets.");
- #endif
- break;
- }
- else
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Receive(): Burst packet not received. Retrying...");
- #endif
- }
- }
- else
- {
- ulNoRxTime = DSIThread_GetSystemTime(); // Reset timeout.
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Receive(): Burst packets received. Reset timeout.");
- #endif
- }
- ReportDownloadProgress();
- }
- return RETURN_FAIL; // Shouldn't reach here.
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFSHostChannel::RETURN_STATUS ANTFSHostChannel::AttemptErase(void)
- {
- BOOL bStatus = FALSE;
- ULONG ulStartTime;
- UCHAR ucTxRetries;
- ANTFRAMER_RETURN eTxComplete;
- if ((ucFoundDeviceState != REMOTE_DEVICE_STATE_TRANS) && (ucFoundDeviceState != REMOTE_DEVICE_STATE_BUSY))
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Erase(): Remote device is not in transport state.");
- #endif
- return RETURN_FAIL; // Not in the correct mode.
- }
- ulTransferArrayIndex = 0;
- bReceivedResponse = FALSE;
- bRxError = FALSE;
- memset(aucTxBuf,0x00,sizeof(aucTxBuf));
- aucTxBuf[ANTFS_CONNECTION_OFFSET] = ANTFS_COMMAND_RESPONSE_ID;
- aucTxBuf[ANTFS_COMMAND_OFFSET] = ANTFS_ERASE_ID;
- Convert_USHORT_To_Bytes(usTransferDataFileIndex,
- &aucTxBuf[DATA_INDEX_OFFSET+1],
- &aucTxBuf[DATA_INDEX_OFFSET]);
- ucTxRetries = 8;
- do
- {
- eTxComplete = pclANT->SendAcknowledgedData(ucChannelNumber, aucTxBuf, ACKNOWLEDGED_TIMEOUT);
- #if defined(DEBUG_FILE)
- if (eTxComplete == ANTFRAMER_FAIL)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptConnect(): Tx error.");
- else if (eTxComplete == ANTFRAMER_TIMEOUT)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptConnect(): Tx timeout.");
- #endif
- } while (eTxComplete == ANTFRAMER_FAIL && --ucTxRetries);
- if (eTxComplete != ANTFRAMER_PASS)
- return RETURN_FAIL;
- ulStartTime = DSIThread_GetSystemTime();
- bNewRxEvent = FALSE;
- ucLinkResponseRetries = ANTFS_RESPONSE_RETRIES;
- do
- {
- DSIThread_MutexLock(&stMutexCriticalSection);
- if ((bNewRxEvent == FALSE) && (*pbCancel == FALSE))
- {
- DSIThread_CondTimedWait(&stCondRxEvent, &stMutexCriticalSection, ERASE_WAIT_TIMEOUT);
- }
- bNewRxEvent = FALSE;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- if (*pbCancel == TRUE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Erase(): Stopped.");
- #endif
- return RETURN_STOP;
- }
- if (bReceivedResponse)
- {
- if (aucTransferBufferFixed[ANTFS_COMMAND_OFFSET] == ANTFS_RESPONSE_ERASE_ID)
- {
- if (aucTransferBufferFixed[ERASE_RESPONSE_OFFSET] == ERASE_RESPONSE_OK)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Erase(): Erase successful.");
- #endif
- bStatus = TRUE;
- }
- else
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Erase(): Request rejected.");
- #endif
- bRxError = TRUE;
- }
- }
- }
- #if defined(DEBUG_FILE)
- else
- {
- DSIDebug::ThreadWrite("ANTFSHostChannel::Erase(): Erasing...");
- }
- #endif
- if (bRxError)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Erase(): Erase failed.");
- #endif
- if (ucLinkResponseRetries == 0)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Erase(): Retries exhausted");
- #endif
- break;
- }
- else
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Erase(): Retrying");
- #endif
- ucLinkResponseRetries--;
- bRxError = FALSE;
- }
- }
- } while ((bStatus == FALSE) && ((DSIThread_GetSystemTime() - ulStartTime) < ERASE_TIMEOUT));
- if (!bStatus)
- return RETURN_FAIL;
- return RETURN_PASS;
- }
- ///////////////////////////////////////////////////////////////////////
- ANTFSHostChannel::RETURN_STATUS ANTFSHostChannel::AttemptAuthenticate(void)
- {
- BOOL bStatus = FALSE;
- UCHAR aucTxAuth[8 + TX_PASSWORD_MAX_LENGTH + 8];
- ULONG ulStartTime;
- UCHAR ucTxRetries;
- ANTFRAMER_RETURN eTxComplete;
- BOOL bBeaconStateIncorrect = FALSE;
- if ((ucFoundDeviceState != REMOTE_DEVICE_STATE_AUTH) && (ucFoundDeviceState != REMOTE_DEVICE_STATE_BUSY))
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptAuthenticate(): Remote device is not in auth state.");
- #endif
- return RETURN_FAIL; // Not in the correct mode.
- }
- ulTransferArrayIndex = 0;
- bReceivedResponse = FALSE;
- bRxError = FALSE;
- memset(aucTxAuth,0x00,sizeof(aucTxAuth));
- aucTxAuth[ANTFS_CONNECTION_OFFSET] = ANTFS_COMMAND_RESPONSE_ID;
- aucTxAuth[ANTFS_COMMAND_OFFSET] = ANTFS_AUTHENTICATE_ID;
- aucTxAuth[AUTH_COMMAND_TYPE_OFFSET] = ucAuthType;
- aucTxAuth[AUTH_FRIENDLY_NAME_LENGTH_OFFSET] = ucTxPasswordLength;
- Convert_ULONG_To_Bytes(ulHostSerialNumber,
- &aucTxAuth[AUTH_HOST_SERIAL_NUMBER_OFFSET+3],
- &aucTxAuth[AUTH_HOST_SERIAL_NUMBER_OFFSET+2],
- &aucTxAuth[AUTH_HOST_SERIAL_NUMBER_OFFSET+1],
- &aucTxAuth[AUTH_HOST_SERIAL_NUMBER_OFFSET]);
- memcpy(&aucTxAuth[8], aucTxPassword, ucTxPasswordLength);
- if (ucTxPasswordLength) //Do this to not leave the last 8 bytes of the password in the host Tx buffer, but we are not required to do it.
- ucTxPasswordLength = ucTxPasswordLength + 8;
- #if defined(ACCESS_POINT)
- ucTxRetries = 2;
- #else
- ucTxRetries = 8;
- #endif
- do
- {
- if (ucTxPasswordLength)
- eTxComplete = pclANT->SendANTFSTransfer(ucChannelNumber, (UCHAR*)NULL, (UCHAR*)NULL, aucTxAuth, 8+ ucTxPasswordLength, ACKNOWLEDGED_TIMEOUT, (ULONG*)NULL);
- else
- eTxComplete = pclANT->SendAcknowledgedData(ucChannelNumber, aucTxAuth, ACKNOWLEDGED_TIMEOUT);
- #if defined(DEBUG_FILE)
- if (eTxComplete == ANTFRAMER_FAIL)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptAuthenticate(): Tx error.");
- else if (eTxComplete == ANTFRAMER_TIMEOUT)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptAuthenticate(): Tx timeout.");
- #endif
- } while (eTxComplete == ANTFRAMER_FAIL && --ucTxRetries);
- if (eTxComplete != ANTFRAMER_PASS)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptAuthenticate(): Tx failed.");
- #endif
- return RETURN_FAIL;
- }
- ulStartTime = DSIThread_GetSystemTime();
- bNewRxEvent = FALSE;
- #if defined(ACCESS_POINT)
- ucLinkResponseRetries = 3; // Current client implementation does not retry, so there is no point in keeping waiting longer
- #else
- ucLinkResponseRetries = ANTFS_RESPONSE_RETRIES;
- #endif
- do
- {
- DSIThread_MutexLock(&stMutexCriticalSection);
- if ((bNewRxEvent == FALSE) && (*pbCancel == FALSE))
- {
- DSIThread_CondTimedWait(&stCondRxEvent, &stMutexCriticalSection, BROADCAST_TIMEOUT);
- }
- bNewRxEvent = FALSE;
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- if (*pbCancel == TRUE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptAuthenticate(): Stopped.");
- #endif
- return RETURN_STOP;
- }
- if (ucFoundDeviceState != REMOTE_DEVICE_STATE_BUSY)
- {
- if (!((usFoundANTFSManufacturerID == 2) && (usFoundANTFSDeviceType == 1))) //Make an exception for the FR405
- bBeaconStateIncorrect = TRUE;
- }
- if (bRxError || bBeaconStateIncorrect)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptAuthenticate(): Rx error.");
- #endif
- if (ucLinkResponseRetries == 0)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptAuthenticate(): Retries exhausted");
- #endif
- return RETURN_FAIL;
- }
- else
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptAuthenticate(): Retrying"); // Not actual retries, just wait longer!
- #endif
- ucLinkResponseRetries--;
- bRxError = FALSE;
- bBeaconStateIncorrect = FALSE;
- }
- }
- if (bReceivedResponse)
- {
- if (aucTransferBufferFixed[ANTFS_COMMAND_OFFSET] == ANTFS_RESPONSE_AUTH_ID)
- {
- if ((pucResponseBuffer != NULL) && (pucResponseBufferSize != NULL))
- {
- if (*pucResponseBufferSize > aucTransferBufferFixed[AUTH_PASSWORD_LENGTH_OFFSET]) //set the reponse length up to the max
- *pucResponseBufferSize = aucTransferBufferFixed[AUTH_PASSWORD_LENGTH_OFFSET];
- memcpy(pucResponseBuffer, &aucTransferBufferFixed[8], *pucResponseBufferSize);
- }
- if (aucTransferBufferFixed[AUTH_RESPONSE_OFFSET] == AUTH_RESPONSE_ACCEPT)
- {
- bStatus = TRUE;
- }
- else if (aucTransferBufferFixed[AUTH_RESPONSE_OFFSET] == AUTH_RESPONSE_REJECT)
- {
- return RETURN_REJECT;
- }
- else
- {
- return RETURN_NA;
- }
- }
- }
- #if defined(DEBUG_FILE)
- else
- {
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptAuthenticate(): Authenticating...");
- }
- #endif
- } while ((bStatus == FALSE) && ((DSIThread_GetSystemTime() - ulStartTime) < ulAuthResponseTimeout));
- if (!bStatus)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::AttemptAuthenticate(): Timeout.");
- #endif
- return RETURN_FAIL;
- }
- return RETURN_PASS;
- }
- ///////////////////////////////////////////////////////////////////////
- // Returns: TRUE if the message has been handled by ANT-FS host, FALSE otherwise
- BOOL ANTFSHostChannel::ANTProtocolEventProcess(UCHAR ucChannel_, UCHAR ucMessageCode_)
- {
- #if 0
- #if defined(DEBUG_FILE)
- UCHAR aucString[256];
- SNPRINTF((char *)aucString,256, "ANTProtocolEventProcess(): Message 0x%02X", ucMessageCode_);
- DSIDebug::ThreadWrite((char *)aucString);
- #endif
- #endif
- if ((ucMessageCode_ == MESG_RESPONSE_EVENT_ID) && (ucChannel_ == ucChannelNumber))
- {
- #if defined(DEBUG_FILE)
- UCHAR aucString[256];
- SNPRINTF((char *) aucString, 256, "ANTFSHostChannel::ANTProtocolEventProcess(): MESG_RESPONSE_EVENT_ID - 0x%02X", aucResponseBuf[1]);
- DSIDebug::ThreadWrite((char *) aucString);
- #endif
- if (aucResponseBuf[1] == MESG_BURST_DATA_ID)
- {
- if (aucResponseBuf[2] != RESPONSE_NO_ERROR)
- {
- #if defined(DEBUG_FILE)
- UCHAR aucString1[256];
- SNPRINTF((char *) aucString1, 256, "ANTFSHostChannel::ANTProtocolEventProcess(): Burst transfer error: 0x%02X.", aucResponseBuf[2]);
- DSIDebug::ThreadWrite((char *) aucString1);
- #endif
- bTxError = TRUE;
- }
- }
- else if (aucResponseBuf[1] == MESG_ACKNOWLEDGED_DATA_ID)
- {
- if(aucResponseBuf[2] == TRANSFER_IN_PROGRESS)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTProtocolEventProcess(): TRANSFER_IN_PROGRESS");
- #endif
- bForceFullInit = TRUE; // Force assign/unassign channel as per "Uplink communication failure on slave channel" issue documented on AP2 Module Rev History
- }
- }
- }
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////
- // Returns: TRUE if the message has been handled by ANT-FS host, FALSE otherwise
- BOOL ANTFSHostChannel::ANTChannelEventProcess(UCHAR ucChannel_, UCHAR ucMessageCode_)
- {
- BOOL bIsValid = TRUE;
- #if 0
- #if defined(DEBUG_FILE)
- UCHAR aucString[256];
- SNPRINTF((char *)aucString,256, "ANTFSHostChannel::ANTChannelEventProcess(): Channel %u, Event 0x%02X", ucChannel_, ucMessageCode_);
- DSIDebug::ThreadWrite((char *)aucString);
- #endif
- #endif
- // Check that we're getting a message from the correct channel.
- if((ucChannel_ != ucChannelNumber) || ((aucRxBuf[0] & CHANNEL_NUMBER_MASK) != ucChannelNumber))
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Message received on wrong channel.");
- #endif
- return FALSE;
- }
- switch (ucMessageCode_)
- {
- case EVENT_RX_BROADCAST:
- case EVENT_RX_ACKNOWLEDGED:
- #if 0
- #if defined(DEBUG_FILE)
- {
- UCHAR aucString[256];
- if (ucMessageCode_ == EVENT_RX_BROADCAST)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): EVENT_RX_BROADCAST");
- else
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): EVENT_RX_ACKNOWLEDGED");
- SNPRINTF((char *)aucString,256, "ANTFSHostChannel::ANTChannelEventProcess(): Broadcast message received: {0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X}.", aucRxBuf[0], aucRxBuf[1], aucRxBuf[2], aucRxBuf[3], aucRxBuf[4], aucRxBuf[5], aucRxBuf[6], aucRxBuf[7], aucRxBuf[8]);
- DSIDebug::ThreadWrite((char *)aucString);
- }
- #endif
- #endif
- if (aucRxBuf[ANTFS_CONNECTION_OFFSET + 1] != ANTFS_BEACON_ID)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Invalid connection ID.");
- #endif
- bIsValid = FALSE;
- }
- else if (!bFoundDevice)
- {
- //Decode the payload
- usFoundBeaconPeriod = 0;
- switch (aucRxBuf[STATUS1_OFFSET + 1] & BEACON_PERIOD_MASK)
- {
- case BEACON_PERIOD_0_5_HZ:
- usFoundBeaconPeriod = 65535;
- break;
- case BEACON_PERIOD_1_HZ:
- usFoundBeaconPeriod = 32768;
- break;
- case BEACON_PERIOD_2_HZ:
- usFoundBeaconPeriod = 16384;
- break;
- case BEACON_PERIOD_4_HZ:
- usFoundBeaconPeriod = 8192;
- break;
- case BEACON_PERIOD_8_HZ:
- usFoundBeaconPeriod = 4096;
- break;
- case BEACON_PERIOD_KEEP: // Custom period
- usFoundBeaconPeriod = usTheMessagePeriod;
- break;
- default:
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Invalid beacon period.");
- #endif
- bIsValid = FALSE;
- break;
- }
- if (bIsValid)
- {
- if (aucRxBuf[STATUS1_OFFSET + 1] & DATA_AVAILABLE_FLAG_MASK)
- bFoundDeviceHasData = TRUE;
- else
- bFoundDeviceHasData = FALSE;
- if (aucRxBuf[STATUS1_OFFSET + 1] & UPLOAD_ENABLED_FLAG_MASK)
- bFoundDeviceUploadEnabled = TRUE;
- else
- bFoundDeviceUploadEnabled = FALSE;
- if (aucRxBuf[STATUS1_OFFSET + 1] & PAIRING_AVAILABLE_FLAG_MASK)
- bFoundDeviceInPairingMode = TRUE;
- else
- bFoundDeviceInPairingMode = FALSE;
- ucFoundDeviceAuthenticationType = aucRxBuf[AUTHENTICATION_TYPE_OFFSET + 1];
- usFoundANTFSDeviceType = Convert_Bytes_To_USHORT(aucRxBuf[DEVICE_TYPE_OFFSET_HIGH + 1], aucRxBuf[DEVICE_TYPE_OFFSET_LOW + 1]);
- usFoundANTFSManufacturerID = Convert_Bytes_To_USHORT(aucRxBuf[MANUFACTURER_ID_OFFSET_HIGH + 1], aucRxBuf[MANUFACTURER_ID_OFFSET_LOW + 1]);
- //Set Found device paramenters here
- stFoundDeviceParameters.usDeviceType = Convert_Bytes_To_USHORT(aucRxBuf[DEVICE_TYPE_OFFSET_HIGH + 1], aucRxBuf[DEVICE_TYPE_OFFSET_LOW + 1]);
- stFoundDeviceParameters.usManufacturerID = Convert_Bytes_To_USHORT(aucRxBuf[MANUFACTURER_ID_OFFSET_HIGH + 1], aucRxBuf[MANUFACTURER_ID_OFFSET_LOW + 1]);
- stFoundDeviceParameters.ucAuthenticationType = aucRxBuf[AUTHENTICATION_TYPE_OFFSET + 1];
- stFoundDeviceParameters.ucStatusByte1 = aucRxBuf[STATUS1_OFFSET + 1];
- stFoundDeviceParameters.ucStatusByte2 = aucRxBuf[STATUS2_OFFSET + 1];
- }
- }
- if (bIsValid)
- {
- USHORT usDeviceType;
- USHORT usManufID;
- ULONG ulHostID;
- UCHAR ucCurrentDeviceState = (aucRxBuf[STATUS2_OFFSET + 1] & REMOTE_DEVICE_STATE_MASK);
- usDeviceType = Convert_Bytes_To_USHORT(aucRxBuf[DEVICE_TYPE_OFFSET_HIGH + 1], aucRxBuf[DEVICE_TYPE_OFFSET_LOW + 1]);
- usManufID = Convert_Bytes_To_USHORT(aucRxBuf[MANUFACTURER_ID_OFFSET_HIGH + 1], aucRxBuf[MANUFACTURER_ID_OFFSET_LOW + 1]);
- ulHostID = Convert_Bytes_To_ULONG ( aucRxBuf[HOST_ID_OFFSET + 4],
- aucRxBuf[HOST_ID_OFFSET + 3],
- aucRxBuf[HOST_ID_OFFSET + 2],
- aucRxBuf[HOST_ID_OFFSET + 1]);
- if (ucCurrentDeviceState > REMOTE_DEVICE_STATE_LAST_VALID)
- {
- bIsValid = FALSE;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Current device state not in valid range.");
- #endif
- }
- else if ((ulHostSerialNumber != ulHostID) && ((usDeviceType != usFoundANTFSDeviceType) || (usManufID != usFoundANTFSManufacturerID)))
- {
- bIsValid = FALSE;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Host ID does not match this host and the device descriptors match do not match the found device.");
- #endif
- }
- else if (((eANTFSState >= ANTFS_HOST_STATE_TRANSPORT) && (ucCurrentDeviceState < REMOTE_DEVICE_STATE_TRANS)) ||
- ((eANTFSState >= ANTFS_HOST_STATE_CONNECTED) && (ucCurrentDeviceState == REMOTE_DEVICE_STATE_LINK)))
- {
- if (ucStrikes > 0)
- {
- ucStrikes--;
- if (ucStrikes == 0)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Device state changed; connection lost.");
- #endif
- pclANT->CloseChannel(ucChannelNumber,ANT_CLOSE_TIMEOUT);
- bIsValid = FALSE;
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_CONNECTION_LOST)
- {
- eANTFSRequest = ANTFS_REQUEST_CONNECTION_LOST;
- DSIThread_CondSignal(&stCondRequest);
- }
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- #if defined(DEBUG_FILE)
- else
- {
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Device state changed; retrying.");
- }
- #endif
- }
- }
- else
- {
- ucStrikes = STRIKE_COUNT;
- ucFoundDeviceState = ucCurrentDeviceState;
- if (ucFoundDeviceState == REMOTE_DEVICE_STATE_TRANS)
- {
- ucTransportBeaconTicks++;
- stFoundDeviceParameters.ucStatusByte1 = aucRxBuf[STATUS1_OFFSET + 1];
- }
- if (ucFoundDeviceState == REMOTE_DEVICE_STATE_AUTH)
- {
- ulFoundBeaconHostID = Convert_Bytes_To_ULONG(aucRxBuf[HOST_ID_OFFSET + 4],
- aucRxBuf[HOST_ID_OFFSET + 3],
- aucRxBuf[HOST_ID_OFFSET + 2],
- aucRxBuf[HOST_ID_OFFSET + 1]);
- }
- }
- }
- DSIThread_MutexLock(&stMutexCriticalSection);
- bFoundDevice = TRUE; // Signal that we have found the device.
- bReceivedBurst = FALSE;
- bFoundDeviceIsValid = bIsValid;
- bNewRxEvent = TRUE;
- DSIThread_CondSignal(&stCondRxEvent);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- break;
- case EVENT_RX_BURST_PACKET:
- #if 0
- #if defined(DEBUG_FILE)
- {
- UCHAR aucString[256];
- SNPRINTF((char *)aucString, 256, "ANTFSHostChannel::ANTChannelEventProcess(): EVENT_RX_BURST_PACKET received (%lu:%lu): {0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X}.", ulPacketCount, ulTransferArrayIndex / 8, aucRxBuf[0], aucRxBuf[1], aucRxBuf[2], aucRxBuf[3], aucRxBuf[4], aucRxBuf[5], aucRxBuf[6], aucRxBuf[7], aucRxBuf[8]);
- DSIDebug::ThreadWrite((char *)aucString);
- }
- #endif
- #endif
- if (!bRxError)
- {
- if ((aucRxBuf[0] & SEQUENCE_NUMBER_MASK) == 0) // Start of a burst.
- {
- // Check that the message is coming from an ANTFS Device.
- if (aucRxBuf[ANTFS_CONNECTION_OFFSET + 1] != ANTFS_BEACON_ID)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Invalid ID.");
- #endif
- bRxError = TRUE;
- }
- else
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Burst started");
- #endif
- ucFoundDeviceState = (aucRxBuf[STATUS2_OFFSET + 1] & REMOTE_DEVICE_STATE_MASK);
- }
- ulPacketCount = 1;
- bReceivedResponse = FALSE;
- }
- else
- {
- // Response packet.
- if (ulPacketCount == 1)
- {
- // Check that the response contains the correct ID
- if (aucRxBuf[ANTFS_CONNECTION_OFFSET + 1] != ANTFS_COMMAND_RESPONSE_ID)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Invalid ID2.");
- #endif
- bRxError = TRUE;
- }
- else
- {
- switch (aucRxBuf[ANTFS_COMMAND_OFFSET + 1])
- {
- case ANTFS_RESPONSE_AUTH_ID:
- case ANTFS_RESPONSE_UPLOAD_ID:
- case ANTFS_RESPONSE_ERASE_ID:
- case ANTFS_RESPONSE_UPLOAD_COMPLETE_ID:
- memcpy(aucTransferBufferFixed, &aucRxBuf[1], 8); // Always copy the response to the start of the transfer buffer.
- memset(&aucTransferBufferFixed[8],0x00,sizeof(aucTransferBufferFixed)-8); //Zero the rest of the receive buffer
- ulTransferArrayIndex = 8;
- pucTransferBuffer = aucTransferBufferFixed;
- if (aucRxBuf[0] & SEQUENCE_LAST_MESSAGE)
- {
- bReceivedResponse = TRUE;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Reception of burst complete. (0)");
- #endif
- }
- #if defined(DEBUG_FILE)
- else
- {
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Receiving burst... (0)");
- }
- #endif
- ulTransferBufferSize = sizeof(aucTransferBufferFixed);
- break;
- case ANTFS_RESPONSE_DOWNLOAD_SMALL_ID:
- if (ulTransferArrayIndex == 0)
- {
- ulTransferTotalBytesRemaining = Convert_Bytes_To_ULONG(0,
- 0,
- aucRxBuf[DATA_BLOCK_SIZE_OFFSET_HIGH + 1],
- aucRxBuf[DATA_BLOCK_SIZE_OFFSET_LOW + 1]);
- ulTransferBufferSize = ulTransferTotalBytesRemaining + 16 + 8; //+16 for the extra packet at the start and rounding up to the next 8 byte packet, + 8 for additional buffering
- if (pucTransferBufferDynamic)
- delete[] pucTransferBufferDynamic;
- try
- {
- pucTransferBufferDynamic = new UCHAR[ulTransferBufferSize];
- if (pucTransferBufferDynamic == NULL)
- throw "Memory allocation failure!";
- }
- catch(...)
- {
- bRxError = TRUE;
- pucTransferBuffer = (UCHAR*) NULL;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Unable to allocate memory for download. (1)");
- #endif
- break;
- }
- ulTransferArrayIndex = 8;
- pucTransferBuffer = pucTransferBufferDynamic;
- }
- if (pucTransferBufferDynamic == NULL)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): pucTransferBufferDynamic is NULL, ignoring transfer Packet");
- #endif
- break;
- }
- memcpy(pucTransferBufferDynamic, &aucRxBuf[1], 8); // Always copy the response to the start of the download buffer.
- if (aucRxBuf[0] & SEQUENCE_LAST_MESSAGE)
- {
- bReceivedResponse = TRUE;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Reception of burst complete. (1)");
- #endif
- }
- #if defined(DEBUG_FILE)
- else
- {
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Receiving burst... (1)");
- }
- #endif
- break;
- case ANTFS_RESPONSE_DOWNLOAD_BIG_ID:
- if (ulTransferArrayIndex == 0) //if this is the first packed of the this download session
- {
- ulTransferArrayIndex = 8;
- pucTransferBuffer = aucTransferBufferFixed; //Use the fixed buffer for now
- ulTransferBufferSize = sizeof(aucTransferBufferFixed);
- }
- ulTransferBytesInBlock = Convert_Bytes_To_ULONG(aucRxBuf[DOWNLOAD_RESPONSE_BLOCK_SIZE_OFFSET + 3 + 1],
- aucRxBuf[DOWNLOAD_RESPONSE_BLOCK_SIZE_OFFSET + 2 + 1],
- aucRxBuf[DOWNLOAD_RESPONSE_BLOCK_SIZE_OFFSET + 1 + 1],
- aucRxBuf[DOWNLOAD_RESPONSE_BLOCK_SIZE_OFFSET + 1]);
- memcpy(pucTransferBuffer, &aucRxBuf[1], 8); // Always copy the response to the start of the transfer buffer.
- if (aucRxBuf[0] & SEQUENCE_LAST_MESSAGE)
- {
- bRxError = TRUE;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Premature end of burst transfer.");
- #endif
- }
- break;
- case ANTFS_RESPONSE_SEND_DIRECT_ID:
- {
- ulTransferArrayIndex = Convert_Bytes_To_ULONG(0,
- 0,
- aucRxBuf[DATA_OFFSET_OFFSET_HIGH + 1],
- aucRxBuf[DATA_OFFSET_OFFSET_LOW + 1]);
- ulTransferArrayIndex *= 8;
- ulTransferTotalBytesRemaining = Convert_Bytes_To_ULONG(0,
- 0,
- aucRxBuf[DATA_BLOCK_SIZE_OFFSET_HIGH + 1],
- aucRxBuf[DATA_BLOCK_SIZE_OFFSET_LOW + 1]);
- ulTransferTotalBytesRemaining *= 8;
- }
- if (ulTransferArrayIndex == 0)
- {
- ulTransferBufferSize = DIRECT_TRANSFER_SIZE + 16;
- if (pucTransferBufferDynamic)
- delete[] pucTransferBufferDynamic;
- try
- {
- pucTransferBufferDynamic = new UCHAR[ulTransferBufferSize];
- if (pucTransferBufferDynamic == NULL)
- throw "Memory allocation failure!";
- }
- catch(...)
- {
- bRxError = TRUE;
- pucTransferBuffer = (UCHAR*) NULL;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Unable to allocate memory for download. (3)");
- #endif
- break;
- }
- pucTransferBuffer = pucTransferBufferDynamic;
- }
- else if (pucTransferBufferDynamic == NULL)
- {
- bRxError = TRUE;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): ANTFS_RESPONSE_SEND_DIRECT index error.");
- #endif
- break;
- }
- ulTransferArrayIndex += 8; // This offset due to the response packet.
- memcpy(pucTransferBufferDynamic, &aucRxBuf[1], 8); // Always copy the response to the start of the download buffer.
- if (aucRxBuf[0] & SEQUENCE_LAST_MESSAGE)
- {
- bReceivedResponse = TRUE;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Reception of burst complete. (2)");
- #endif
- }
- #if defined(DEBUG_FILE)
- else
- {
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Receiving burst... (1)");
- }
- #endif
- break;
- default:
- bRxError = TRUE; // BIG DL/UL and everything else are not handled right now so we fail out here.
- break;
- }
- }
- }
- else if ((ulPacketCount == 2) && (pucTransferBuffer != NULL) && (pucTransferBuffer[ANTFS_COMMAND_OFFSET] == ANTFS_RESPONSE_DOWNLOAD_BIG_ID) &&(pucTransferBuffer[ANTFS_CONNECTION_OFFSET] == ANTFS_COMMAND_RESPONSE_ID))
- {
- if (ulTransferArrayIndex == 8)
- {
- ulTransferTotalBytesRemaining = Convert_Bytes_To_ULONG(aucRxBuf[DOWNLOAD_RESPONSE_FILE_SIZE_OFFSET + 3 + 1],
- aucRxBuf[DOWNLOAD_RESPONSE_FILE_SIZE_OFFSET + 2 + 1],
- aucRxBuf[DOWNLOAD_RESPONSE_FILE_SIZE_OFFSET + 1 + 1],
- aucRxBuf[DOWNLOAD_RESPONSE_FILE_SIZE_OFFSET + 1]);
- if (ulTransferByteSize && ulTransferByteSize < ulTransferTotalBytesRemaining) //If our desired download size is less than the file size, set it.
- ulTransferTotalBytesRemaining = ulTransferByteSize;
- ulTransferBufferSize = ulTransferTotalBytesRemaining + 24 + 8 + 8;//+24 for the extra packets at the start and rounding up to the next 8 byte packet, + 8 for additional buffering +8 more for CRC
- #if defined(DEBUG_FILE)
- {
- char szString[256];
- SNPRINTF(szString, 256, "ANTFSHostChannel::ANTChannelEventProcess(): ulTransferBufferSize = %lu.", ulTransferBufferSize);
- DSIDebug::ThreadWrite(szString);
- }
- #endif
- if (pucTransferBufferDynamic)
- delete[] pucTransferBufferDynamic;
- try
- {
- pucTransferBufferDynamic = new UCHAR[ulTransferBufferSize];
- if (pucTransferBufferDynamic == NULL)
- throw "Memory allocation failure!";
- }
- catch(...)
- {
- bRxError = TRUE;
- ulTransferArrayIndex = 0;
- pucTransferBuffer = (UCHAR*) NULL;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Unable to allocate memory for download. (2)");
- #endif
- break;
- }
- memcpy(pucTransferBufferDynamic, aucTransferBufferFixed, 8); // Copy over the first packet that we saved temporarily.
- ulTransferArrayIndex = 16;
- pucTransferBuffer = pucTransferBufferDynamic;
- }
- if (pucTransferBufferDynamic == NULL)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): pucTransferBufferDynamic is NULL, ignoring transfer Packet");
- #endif
- break;
- }
- memcpy(&pucTransferBuffer[8], &aucRxBuf[1], 8); // Always copy the response to the start of the transfer buffer.
- ULONG ulReceivedDataOffset = Convert_Bytes_To_ULONG(aucRxBuf[DOWNLOAD_RESPONSE_DATA_OFFSET_OFFSET + 3 + 1],
- aucRxBuf[DOWNLOAD_RESPONSE_DATA_OFFSET_OFFSET + 2 + 1],
- aucRxBuf[DOWNLOAD_RESPONSE_DATA_OFFSET_OFFSET + 1 + 1],
- aucRxBuf[DOWNLOAD_RESPONSE_DATA_OFFSET_OFFSET + 1]);
- if ((ulReceivedDataOffset - ulTransferDataOffset) != (ulTransferArrayIndex - 16))
- {
- bRxError = TRUE;
- ulTransferArrayIndex = 0;
- pucTransferBuffer = (UCHAR*) NULL;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): DL offset does not match desired DL offset.");
- #endif
- break;
- }
- if (aucRxBuf[0] & SEQUENCE_LAST_MESSAGE)
- {
- bReceivedResponse = TRUE;
- #if defined(DEBUG_FILE)
- {
- char szString[256];
- SNPRINTF(szString, 256, "ANTFSHostChannel::ANTChannelEventProcess(): Reception of burst complete. (%lu).", ulTransferArrayIndex);
- DSIDebug::ThreadWrite(szString);
- }
- #endif
- }
- }
- else if ((ulTransferArrayIndex + 8) <= ulTransferBufferSize)
- {
- #if defined(DEBUG_FILE_V1)
- {
- char szString[256];
- SNPRINTF(szString, 256, "ANTFSHostChannel::ANTChannelEventProcess(): ulTransferArrayIndex = %lu.", ulTransferArrayIndex);
- DSIDebug::ThreadWrite(szString);
- }
- #endif
- if (pucTransferBuffer == NULL)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): pucTransferBuffer is NULL, ignoring transfer Packet");
- #endif
- break;
- }
- memcpy(&pucTransferBuffer[ulTransferArrayIndex], &aucRxBuf[1], 8);
- ulTransferArrayIndex += 8;
- if (aucRxBuf[0] & SEQUENCE_LAST_MESSAGE)
- {
- bReceivedResponse = TRUE;
- #if defined(DEBUG_FILE)
- {
- char szString[256];
- SNPRINTF(szString, 256, "ANTFSHostChannel::ANTChannelEventProcess(): Reception of burst complete. (%lu).", ulTransferArrayIndex);
- DSIDebug::ThreadWrite(szString);
- }
- #endif
- }
- #if defined(DEBUG_FILE_V1)
- else
- {
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Receiving burst... (n)");
- }
- #endif
- }
- else
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): Burst Buffer Overflow");
- #endif
- bRxError = TRUE;
- }
- ulPacketCount++;
- }
- }
- DSIThread_MutexLock(&stMutexCriticalSection);
- bReceivedBurst = TRUE;
- bNewRxEvent = TRUE;
- DSIThread_CondSignal(&stCondRxEvent);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- #if defined(DEBUG_FILE_V1)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): bReceivedBurst = TRUE");
- #endif
- break;
- case EVENT_TRANSFER_RX_FAILED:
- DSIThread_MutexLock(&stMutexCriticalSection);
- bRxError = TRUE;
- bReceivedBurst = FALSE;
- bReceivedResponse = FALSE;
- DSIThread_CondSignal(&stCondRxEvent);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): EVENT_TRANSFER_RX_FAILED");
- #endif
- break;
- case EVENT_RX_FAIL_GO_TO_SEARCH:
- if (eANTFSState == ANTFS_HOST_STATE_SEARCHING)
- {
- DSIThread_MutexLock(&stMutexCriticalSection);
- bFoundDeviceIsValid = FALSE; // Signal that this is not a valid beacon
- bFoundDevice = TRUE; // Signal that we have found the device to allow the search loop to exit.
- bReceivedBurst = FALSE;
- bNewRxEvent = TRUE;
- DSIThread_CondSignal(&stCondRxEvent);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): EVENT_RX_FAIL_GO_TO_SEARCH");
- #endif
- }
- break;
- case EVENT_RX_SEARCH_TIMEOUT:
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): EVENT_RX_SEARCH_TIMEOUT");
- #endif
- if (eANTFSState == ANTFS_HOST_STATE_SEARCHING)
- {
- pclANT->OpenChannel(ucChannelNumber); // Re-open the channel.
- }
- else if ((eANTFSState == ANTFS_HOST_STATE_DOWNLOADING) || (eANTFSState == ANTFS_HOST_STATE_UPLOADING) || (eANTFSState == ANTFS_HOST_STATE_SENDING) || (eANTFSState == ANTFS_HOST_STATE_RECEIVING))
- {
- pclANT->OpenChannel(ucChannelNumber); // Re-open the channel.
- DSIThread_MutexLock(&stMutexCriticalSection);
- bRxError = TRUE;
- bTxError = TRUE; // Can no longer transmit data, either.
- bReceivedBurst = FALSE;
- DSIThread_CondSignal(&stCondRxEvent);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- else if (eANTFSState >= ANTFS_HOST_STATE_CONNECTED)
- {
- DSIThread_MutexLock(&stMutexCriticalSection);
- if (eANTFSRequest < ANTFS_REQUEST_CONNECTION_LOST)
- {
- eANTFSRequest = ANTFS_REQUEST_CONNECTION_LOST;
- DSIThread_CondSignal(&stCondRequest);
- }
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- // any other states we don't report the timeout
- break;
- case EVENT_TRANSFER_TX_COMPLETED:
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): EVENT_TRANSFER_TX_COMPLETED");
- #endif
- break;
- case EVENT_TRANSFER_TX_FAILED:
- bTxError = TRUE;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): EVENT_TRANSFER_TX_FAILED");
- #endif
- break;
- case EVENT_TRANSFER_TX_START:
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): EVENT_TRANSFER_TX_START");
- #endif
- break;
- case EVENT_CHANNEL_CLOSED:
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::ANTChannelEventProcess(): EVENT_CHANNEL_CLOSED");
- #endif
- break;
- default:
- break;
- }
- return TRUE; // message has been handled, do not pass to application
- }
- ///////////////////////////////////////////////////////////////////////
- BOOL ANTFSHostChannel::Blackout(ULONG ulDeviceID_, USHORT usManufacturerID_, USHORT usDeviceType_, USHORT usBlackoutTime_)
- //BOOL ANTFSHost::IgnoreDevice(USHORT usBlackoutTime_)
- {
- BOOL bRetVal = TRUE;
- IGNORE_LIST_ITEM stListItem;
- IGNORE_LIST_ITEM *pstListItem;
- if (usBlackoutTime_ == 0)
- return FALSE;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Blackout(): Entering critical section.");
- #endif
- DSIThread_MutexLock(&stMutexIgnoreListAccess);
- stListItem.usID = (USHORT)ulDeviceID_;
- stListItem.usManufacturerID = usManufacturerID_;
- stListItem.usDeviceType = usDeviceType_;
- pstListItem = (IGNORE_LIST_ITEM *) bsearch(&stListItem, astIgnoreList, usListIndex, sizeof(IGNORE_LIST_ITEM), &ListCompare);
- if (pstListItem != NULL)
- {
- // If the ID is already in the list, set the blackout time.
- pstListItem->usTimeout = usBlackoutTime_;
- }
- else
- {
- // If the ID is not on the list, add it.
- if (usListIndex < MAX_IGNORE_LIST_SIZE)
- {
- astIgnoreList[usListIndex].usID = (USHORT)ulDeviceID_;
- astIgnoreList[usListIndex].usManufacturerID = usManufacturerID_;
- astIgnoreList[usListIndex].usDeviceType = usDeviceType_;
- astIgnoreList[usListIndex].usTimeout = usBlackoutTime_;
- usListIndex++;
- qsort(astIgnoreList, usListIndex, sizeof(IGNORE_LIST_ITEM), &ListCompare);
- }
- else
- {
- bRetVal = FALSE; // Can't add any more devices to the list.
- }
- }
- DSIThread_MutexUnlock(&stMutexIgnoreListAccess);
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::Blackout(): Left critical section.");
- #endif
- return bRetVal;
- }
- ///////////////////////////////////////////////////////////////////////
- BOOL ANTFSHostChannel::RemoveBlackout(ULONG ulDeviceID_, USHORT usManufacturerID_, USHORT usDeviceType_)
- {
- BOOL bRetVal = TRUE;
- IGNORE_LIST_ITEM stListItem;
- IGNORE_LIST_ITEM *pstListItem;
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::RemoveBlackout(): Entering critical section.");
- #endif
- DSIThread_MutexLock(&stMutexIgnoreListAccess);
- stListItem.usID = (USHORT)ulDeviceID_;
- stListItem.usManufacturerID = usManufacturerID_;
- stListItem.usDeviceType = usDeviceType_;
- pstListItem = (IGNORE_LIST_ITEM *) bsearch(&stListItem, astIgnoreList, usListIndex, sizeof(IGNORE_LIST_ITEM), &ListCompare);
- if (pstListItem != NULL)
- {
- USHORT usIndex = (USHORT)((pstListItem - astIgnoreList) / sizeof(IGNORE_LIST_ITEM));
- // If the ID is found on the list, set the blackout time to 0 and remove it.
- astIgnoreList[usIndex].usTimeout = 0;
- #if defined(DEBUG_FILE)
- {
- UCHAR aucString[256];
- SNPRINTF((char *)aucString,256, "Removing %u %u %u from ignore list.", astIgnoreList[usIndex].usID,astIgnoreList[usIndex].usDeviceType,astIgnoreList[usIndex].usManufacturerID);
- DSIDebug::ThreadWrite((char *)aucString);
- }
- #endif
- for (usIndex = usIndex + 1; usIndex < usListIndex; usIndex++)
- astIgnoreList[usIndex - 1] = astIgnoreList[usIndex];
- usListIndex--;
- }
- else
- {
- // If the ID is not on the list.
- bRetVal = FALSE;
- }
- DSIThread_MutexUnlock(&stMutexIgnoreListAccess);
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::RemoveBlackout(): Left critical section.");
- #endif
- return bRetVal;
- }
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::ClearBlackoutList(void)
- {
- DSIThread_MutexLock(&stMutexIgnoreListAccess);
- usListIndex = 0;
- DSIThread_MutexUnlock(&stMutexIgnoreListAccess);
- }
- ///////////////////////////////////////////////////////////////////////
- static int ListCompare(const void *puvKeyVal, const void *puvDatum)
- {
- if (((IGNORE_LIST_ITEM *) puvKeyVal)->usManufacturerID < ((IGNORE_LIST_ITEM *) puvDatum)->usManufacturerID)
- return -1;
- if (((IGNORE_LIST_ITEM *) puvKeyVal)->usDeviceType < ((IGNORE_LIST_ITEM *) puvDatum)->usDeviceType)
- return -1;
- if (((IGNORE_LIST_ITEM *) puvKeyVal)->usID < ((IGNORE_LIST_ITEM *) puvDatum)->usID)
- return -1;
- if ((((IGNORE_LIST_ITEM *) puvKeyVal)->usManufacturerID == ((IGNORE_LIST_ITEM *) puvDatum)->usManufacturerID) &&
- (((IGNORE_LIST_ITEM *) puvKeyVal)->usDeviceType == ((IGNORE_LIST_ITEM *) puvDatum)->usDeviceType) &&
- (((IGNORE_LIST_ITEM *) puvKeyVal)->usID == ((IGNORE_LIST_ITEM *) puvDatum)->usID))
- return 0;
- return 1;
- }
- ///////////////////////////////////////////////////////////////////////
- // Frequency: 1 Hz
- ///////////////////////////////////////////////////////////////////////
- DSI_THREAD_RETURN ANTFSHostChannel::QueueTimerStart(void *pvParameter_)
- {
- ((ANTFSHostChannel *)pvParameter_)->QueueTimerCallback();
- return 0;
- }
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::QueueTimerCallback(void)
- {
- USHORT usCounter = 0;
-
- if(!bTimerThreadInitDone)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadInit("Timer");
- #endif
- bTimerThreadInitDone = TRUE;
- }
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::TimerQueueTimerCall(): Entering critical section.");
- #endif
- DSIThread_MutexLock(&stMutexIgnoreListAccess);
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("Updating ignore list...");
- #endif
- while (usCounter < usListIndex)
- {
- if ((astIgnoreList[usCounter].usTimeout > 0) && (astIgnoreList[usCounter].usTimeout != MAX_USHORT))
- astIgnoreList[usCounter].usTimeout--;
- if (astIgnoreList[usCounter].usTimeout == 0) // Remove the List Item if it has expired.
- {
- USHORT usInsideLoopCounter;
- #if defined(DEBUG_FILE)
- {
- UCHAR aucString[256];
- SNPRINTF((char *)aucString,256, "Removing %u %u %u from ignore list.", astIgnoreList[usCounter].usID, astIgnoreList[usCounter].usDeviceType, astIgnoreList[usCounter].usManufacturerID);
- DSIDebug::ThreadWrite((char *)aucString);
- }
- #endif
- for (usInsideLoopCounter = usCounter + 1; usInsideLoopCounter < usListIndex; usInsideLoopCounter++)
- astIgnoreList[usInsideLoopCounter - 1] = astIgnoreList[usInsideLoopCounter];
- usListIndex--;
- }
- else
- {
- #if defined(DEBUG_FILE)
- {
- UCHAR aucString[256];
- SNPRINTF((char *)aucString,256, "%u %u %u is on ignore list. %us left.", astIgnoreList[usCounter].usID, astIgnoreList[usCounter].usDeviceType, astIgnoreList[usCounter].usManufacturerID, astIgnoreList[usCounter].usTimeout);
- DSIDebug::ThreadWrite((char *)aucString);
- }
- #endif
- usCounter++;
- }
- }
- DSIThread_MutexUnlock(&stMutexIgnoreListAccess);
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::TimerQueueTimerCall(): Left critical section.");
- #endif
- /*
- if (++usSerialWatchdog > ANTFS_SERIAL_WATCHDOG_COUNT)
- {
- usSerialWatchdog = 0;
- HandleSerialError(); //! This is where we would want to potentially add a serial watch dog, if it makes sense to do so in the future
- }
- */
- }
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::HandleSerialError(void)
- {
- // We ended up here because we did not receive the expected response to a serial message
- // Most likely, ANT was in the wrong state, so attempt to close the channel.
- // No errors raised from here, as we do not know what state we are in.
- UCHAR ucChannelStatus = 0;
- if(pclANT->CloseChannel(ucChannelNumber, ANT_CLOSE_TIMEOUT) != TRUE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::HandleSerialError(): Failed to close channel.");
- #endif
- }
- if(pclANT->UnAssignChannel(ucChannelNumber, MESSAGE_TIMEOUT) != TRUE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::HandleSerialError(): Failed to unassign channel.");
- #endif
- }
- // The following is just for information purposes...
- if(pclANT->GetChannelStatus(ucChannelNumber, &ucChannelStatus, MESSAGE_TIMEOUT) == FALSE)
- {
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::HandleSerialError(): Failed ANT_GetChannelStatus().");
- #endif
- }
- #if defined(DEBUG_FILE)
- else if ((ucChannelStatus & STATUS_CHANNEL_STATE_MASK) != STATUS_UNASSIGNED_CHANNEL)
- {
- char szString[256];
- SNPRINTF(szString, 256, "ANTFSHostChannel::HandleSerialError(): Channel state... 0x%x.", ucChannelStatus);
- DSIDebug::ThreadWrite(szString);
- }
- #endif
- DSIThread_MutexLock(&stMutexCriticalSection);
- eANTFSRequest = ANTFS_REQUEST_SERIAL_ERROR_HANDLED; // Reset state machine next
- DSIThread_CondSignal(&stCondRequest);
- DSIThread_MutexUnlock(&stMutexCriticalSection);
- }
- ///////////////////////////////////////////////////////////////////////
- // This function is called to increment the frequency stale counter
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::IncFreqStaleCount(UCHAR ucInc)
- {
- USHORT usTemp = (USHORT)ucTransportFrequencyStaleCount + (USHORT)ucInc;
- if (usTemp >= MAX_STALE_COUNT)
- ucTransportFrequencyStaleCount = MAX_STALE_COUNT;
- else
- ucTransportFrequencyStaleCount = (UCHAR)usTemp;
- }
- ///////////////////////////////////////////////////////////////////////
- // This function is called to populate/re-populate the frequency table randomly
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::PopulateTransportFreqTable(void)
- {
- UCHAR aucTemp[TRANSPORT_FREQUENCY_LIST_SIZE];
- int i = 0;
- ucTransportFrequencyStaleCount = 0;
- ucCurrentTransportFreqElement = 0;
- srand((unsigned int)time((time_t*)NULL));
- memcpy (aucTemp, aucTransportFrequencyList, TRANSPORT_FREQUENCY_LIST_SIZE);
- for (i=0; i < TRANSPORT_FREQUENCY_LIST_SIZE; i++)
- {
- UCHAR ucNewValue = (UCHAR)( 1 + (rand() % (TRANSPORT_FREQUENCY_LIST_SIZE-1)) );
- UCHAR j = 0;
- while (ucNewValue)
- {
- j = (j+1)%TRANSPORT_FREQUENCY_LIST_SIZE;
- if (aucTemp[j] != 0xFF)
- {
- ucNewValue--;
- }
- }
- aucFrequencyTable[i] = aucTemp[j];
- aucTemp[j] = 0xFF;
- }
- }
- ///////////////////////////////////////////////////////////////////////
- // This function is called to check if we need to change frequencies and return the new frequncy
- ///////////////////////////////////////////////////////////////////////
- UCHAR ANTFSHostChannel::CheckForNewTransportFreq(void)
- {
- if (ucTransportFrequencyStaleCount >= MAX_STALE_COUNT)
- {
- ucCurrentTransportFreqElement = ((ucCurrentTransportFreqElement+1) % TRANSPORT_FREQUENCY_LIST_SIZE);
- ucTransportFrequencyStaleCount = 0;
- }
- return aucFrequencyTable[ucCurrentTransportFreqElement];
- }
- ///////////////////////////////////////////////////////////////////////
- static int DeviceParametersItemCompare(const void *pvItem1, const void *pvItem2)
- {
- if (((DEVICE_PARAMETERS_ITEM *) pvItem1)->usHandle < ((DEVICE_PARAMETERS_ITEM *) pvItem2)->usHandle)
- return -1;
- if (((DEVICE_PARAMETERS_ITEM *) pvItem1)->usHandle == ((DEVICE_PARAMETERS_ITEM *) pvItem2)->usHandle)
- return 0;
- return 1;
- }
- ///////////////////////////////////////////////////////////////////////
- BOOL ANTFSHostChannel::IsDeviceMatched(ANTFS_DEVICE_PARAMETERS *psDeviceParameters_, BOOL bPartialID_)
- {
- USHORT usDeviceIndex = 0;
- ULONG ulIDMask;
- if (usDeviceListSize == 0)
- return TRUE; // There are no devices in the list, so any device is a match.
- if(bPartialID_)
- ulIDMask = MAX_USHORT;
- else
- ulIDMask = MAX_ULONG;
- while (usDeviceIndex < usDeviceListSize)
- {
- DEVICE_PARAMETERS_ITEM *psSearchDeviceItem = &asDeviceParametersList[usDeviceIndex];
- if (
- ((psDeviceParameters_->ulDeviceID & psSearchDeviceItem->sDeviceSearchMask.ulDeviceID & ulIDMask) == (psSearchDeviceItem->sDeviceParameters.ulDeviceID & psSearchDeviceItem->sDeviceSearchMask.ulDeviceID & ulIDMask))
- &&
- ((psDeviceParameters_->usManufacturerID & psSearchDeviceItem->sDeviceSearchMask.usManufacturerID) == (psSearchDeviceItem->sDeviceParameters.usManufacturerID & psSearchDeviceItem->sDeviceSearchMask.usManufacturerID))
- &&
- ((psDeviceParameters_->usDeviceType & psSearchDeviceItem->sDeviceSearchMask.usDeviceType) == (psSearchDeviceItem->sDeviceParameters.usDeviceType & psSearchDeviceItem->sDeviceSearchMask.usDeviceType))
- &&
- ((psDeviceParameters_->ucAuthenticationType & psSearchDeviceItem->sDeviceSearchMask.ucAuthenticationType) == (psSearchDeviceItem->sDeviceParameters.ucAuthenticationType & psSearchDeviceItem->sDeviceSearchMask.ucAuthenticationType))
- &&
- ((psDeviceParameters_->ucStatusByte1 & psSearchDeviceItem->sDeviceSearchMask.ucStatusByte1) == (psSearchDeviceItem->sDeviceParameters.ucStatusByte1 & psSearchDeviceItem->sDeviceSearchMask.ucStatusByte1))
- &&
- ((psDeviceParameters_->ucStatusByte2 & psSearchDeviceItem->sDeviceSearchMask.ucStatusByte2) == (psSearchDeviceItem->sDeviceParameters.ucStatusByte2 & psSearchDeviceItem->sDeviceSearchMask.ucStatusByte2))
- )
- return TRUE;
- usDeviceIndex++;
- }
- return FALSE;
- }
- ///////////////////////////////////////////////////////////////////////
- void ANTFSHostChannel::AddResponse(ANTFS_HOST_RESPONSE eResponse_)
- {
- DSIThread_MutexLock(&stMutexResponseQueue);
- clResponseQueue.AddResponse(eResponse_);
- DSIThread_CondSignal(&stCondWaitForResponse);
- DSIThread_MutexUnlock(&stMutexResponseQueue);
- }
- ///////////////////////////////////////////////////////////////////////
- //Returns a response if there is one ready, otherwise waits the specified time for one to occur
- ANTFS_HOST_RESPONSE ANTFSHostChannel::WaitForResponse(ULONG ulMilliseconds_)
- {
- ANTFS_HOST_RESPONSE stResponse = ANTFS_HOST_RESPONSE_NONE;
- if (bKillThread == TRUE)
- return ANTFS_HOST_RESPONSE_NONE;
- //Wait for response
- DSIThread_MutexLock(&stMutexResponseQueue);
- if(clResponseQueue.isEmpty())
- {
- UCHAR ucResult = DSIThread_CondTimedWait(&stCondWaitForResponse, &stMutexResponseQueue, ulMilliseconds_);
- switch(ucResult)
- {
- case DSI_THREAD_ENONE:
- stResponse = clResponseQueue.GetResponse();
- break;
- case DSI_THREAD_ETIMEDOUT:
- stResponse = ANTFS_HOST_RESPONSE_NONE;
- break;
- case DSI_THREAD_EOTHER:
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::WaitForResponse(): CondTimedWait() Failed!");
- #endif
- stResponse = ANTFS_HOST_RESPONSE_NONE;
- break;
- default:
- #if defined(DEBUG_FILE)
- DSIDebug::ThreadWrite("ANTFSHostChannel::WaitForResponse(): Error Unknown...");
- #endif
- stResponse = ANTFS_HOST_RESPONSE_NONE;
- break;
- }
- }
- else
- {
- stResponse = clResponseQueue.GetResponse();
- }
- DSIThread_MutexUnlock(&stMutexResponseQueue);
- return stResponse;
- }
|