Download - Bluetooth alapú távolság meghatározás
Góczán Péter
Bluetooth alapú
távolság
meghatározás
Témavezető: Tihanyi Attila
Pázmány Péter Katolikus Egyetem
Információs Technológiai Kar
Műszaki Informatika Szak
2011
~ 1 ~
Alulírott Góczán Péter, a Pázmány Péter Katolikus Egyetem
Információs Technológiai Karának hallgatója kijelentem, hogy
ezt a diplomatervet meg nem engedett segítség nélkül, saját
magam készítettem, és a diplomamunkában csak a megadott
forrásokat használtam fel. Minden olyan részt, melyet szó
szerint, vagy azonos értelemben, de átfogalmazva más forrásból
átvettem, egyértelműen a forrás megadásával megjelöltem.
~ 2 ~
Tartalomjegyzék
1. A feladat rövid ismertetése 6
2. Előzmények 7
2.1 A homogén antenna karakterisztika lehetséges okai 8
2.2 Lehetséges megoldások 8
2.3 Lehetséges alternatíva 9
2.4 A HCI (Host Controller Interface) paraméterei 11
3. A tervezés részletes leírása 12
3.1 A munka során felhasznált eszközök 12
3.2 Mérések 13
4. Megvalósítás 17
4.1 Okostelefonon való implementálos szükséges ismeretek megszerzése 17
4.1.1 Az Android rövid története 17
4.1.2 Az Android felépítése 18
4.1.3 A fejlesztés során szerzett tapasztalatok 19
4.1.4 Az Android alkalmazás életciklusa 20
4.1.5 A fejlesztéshez szükséges programok, összetevők 22
4.1.6 Az Android programok felépítése 24
4.2 A fejlesztés folyamata 25
4.2.1 Az alapok elsajátítása 25
4.2.2 A felhasználó számára látható felület fölépítése 27
4.2.3 A program felülete 29
4.2.4 Aktív kapcsolat létrehozása 30
4.2.5 A ’Link Quality’ érték kinyerése 32
4.3 Az Android NDK (Native Development Kit) 35
4.3.1 Az Android NDK felépítése 35
4.3.2 Az Android NDK működési elve 36
4.3.3 Az Android NDK használata 37
4.4 Rendszergazda jogok szerzése (’Rootolás’) 40
4.5 Kapcsolat felépítése natív kóddal 41
4.5.1 A használni kívánt protokoll kiválasztása 41
4.5.2 A kapcsolódáshoz használt függvény megírása 43
4.5.3 Csatlakozással kapcsolatos problémák 44
4.5.4 A hiba okának fölkutatása 45
~ 3 ~
4.6 Újabb mérések 48
4.6.1 Kültéri mérések 49
4.6.2 Beltéri mérések 51
4.7 Az alkalmazás lehetséges funkciójának tesztelése 52
4.8 Következtetések 54
5. Összefoglalás 55
~ 4 ~
Összefoglaló
Napjaink helymeghatározásra használt, mindenki számára elérhető technológiái vagy csupán
kültéren használhatók, vagy túlságosan pontatlanok. Dolgozatomban egy bluetooth alapú,
beltéren is használható, távolság meghatározására alkalmas szoftver létrehozásának folyamatát
írtam le.
Első lépésként egy Linux operációs rendszert futtató laptop és egy Symbian alapú
mobiltelefon kapcsolódó jelének erősségét, majd egy másik paraméterét, a ’Link Quality’
értékét határoztam meg, amely nem más, mint a jel minőségét mutató, általában a ’bit error
rate’-ből, azaz a jel hibájából származtatott szám. Számos mérés elvégzése után az utóbbi
karakterisztikát alkalmasnak találtam távolság meghatározására. Valami olyat írnék, hogy
mérésekkel bebizonyítottam, hogy a link quality paraméter alkalmas távolság meghatározásra,
és erre építettem fel a rendszeremet.
Az okostelefonra való, ’Link Quailty’ paramétert kiszámító program implementálása után
kiderült, hogy mivel ez egy teljes mértékben hardware függő érték, általános esetben csupán
egy elnagyolt távolság meghatározásra alkalmazható szoftver megvalósítása lehetséges.
A program megvalósítása igen nehézkes volt, mivel az android operációs rendszer egy igen
fiatal fejlesztés, tele hiányosságokkal és hibákkal. A nehézségeket legyőzve sikerült egy
működő, nagy komplexitású szoftvert létrehoznom, amelyhez hasonló a piacon napjainkig
még nem volt elérhető.
A kész alkalmazás nem valósította ugyan meg a kitűzött funkcionalitást, ugyanakkor mégis
egyedülálló lehetőségeket nyújt a beltéri távolság meghatározás területén, és kiváló alapul
szolgálhat egy jövőbeni, jóval pontosabb program elkészítéséhez, hiszen a bluetooth
technológia és az android rendszer folyamatosan fejlődik.
A feladat elvégzése során megismerkedtem az android programozás alapjaival, betekintést
nyertem a magasabb szintű fejlesztői eszközök alkalmazásába, megismerkedtem a bluetooth
technológia rejtelmeivel, megtanultam, hogy egy adott munka elvégzése során milyen fontos
az alaposan megtervezett, lényegre törő mérések elvégzése, és sok érdekes emberrel
ismerkedtem meg a világ minden tájáról.
~ 5 ~
Abstract
Technologies of today used for measuring distances are only applicable outdoor, or they are too vague.
In this paper I've noted the process of creating a software implemented on smartphones that uses
bluetooth to be able to measure the indoor distance between our devices and another.
First I measured the signal strength and another representative of bluetooth, the ’Link Quality’
parameter between a notebook with Linux operation system, and a Symbian-based mobile phone.
’Link Quality’ is returning the quality of an active bluetooth connection generally using the ’bit error
rate’ variant, and as it seemed to be applicable for measuring distance, the next step was the
implementation of a program on a smartphone.
After it turned out, that ’Link Quality’ is completely hardware dependent, it was only possible to
create a software that measures distance vaguely, but this could still be an indoor solution.
However, implementation of the software came with its challenges, despite the fact that android
operation system is a relatively new development, it contains a lot of mistakes, and several functions
are incomplete, I’ve successfully writen an application of high complexity that functions properly, and
in its functionality it is unique in the market for now.
It’s true, that the current version of the program is not working as planned, as it only gives us a
decision about the phone being within two meters or not, but it gives us the basis for the development
of a possible, higher quality software, which shall be created, as bluetooth and android technologies
are evolving at an exponential rate.
During this project work, I got to understand the basics of android programming and some high level
development tools, and learnt the essence of bluetooth technology and how important the planning and
measuring is while working on a complex project.
~ 6 ~
1.fejezet
A feladat ismertetése
A cél egy olyan, mobiltelefonon működő szoftver írása, amely segítségével adott bluetooth
eszközök hozzánk viszonyított távolságát határozhatjuk meg. Egy ilyen program segítségével
megtalálhatnánk az előzőleg a pénztárcánkba vagy a kulcscsomónkra tett elemes jeladót, vagy
egy mobiltelefonnal rendelkező személyt a tömegben, ha az 30-50 méteres sugarú körön belül
található.
Számos hasonló eszköz készült már, amelyek rendszerint GPS, WIFI vagy rádiójelek
felhasználásával működnek, az általam kitalált megoldás várhatóan pontatlanabb lesz ugyan,
azonban mivel okostelefonra implementáljuk, bizonyos szempontból hasznosabbnak
bizonyulhat elődeinél.
A fejlett országokban már majdnem minden felnőtt ember rendelkezik mobil eszközzel,
rendszeresen maguknál tartják, így nem kell egy külön szerkezetet magukkal hordaniuk az
alkalmazás használatához, csak ami egyébként is náluk van. További előnyt jelent a beltéri
helymeghatározó képesség, amely jelen esetben sokszor jóval hasznosabbnak bizonyul egy
csupán a szabadban, vagy a telepített rádióállomások által elérhető területeken funkcionáló
eszköznél, mint például a GPS vagy a GSM esetén.
Pozitívum továbbá a bluetooth robosztus viselkedése, amely a WIFI-vel szemben igen
ellenálló az interferenciával szemben. Az általunk használt technológia 79 darab 1 MHz-es
csatornát használ 2400 MHz és 2483.5 MHz között. Ezen csatornák közt váltogat egy jeladó
1600-szor másodpercenként. Ennek az a lényege, hogy ha egy másik ISM sávot használó
eszköz kerül a hatósugarunkba, akkor azt érzékelni, azonosítani, végül kizárni tudjuk.
Ha az általam fejlesztett szoftver megvalósítása során sikerrel járok, az a bluetooth-t használó
eszközöket egy teljesen új funkcióval láthatja el, és ez a technológia számtalan ma létező
szolgáltatás minőségét teheti jobbá, igen sok feladat elvégzését gyorsíthatja fel, teheti
hatékonyabbá.
~ 7 ~
2.fejezet
Előzmények
Első elképzelésem szerint a szoftverünk alkalmas lett volna pozíció meghatározásra is. Ennek
elérése érdekében, az Önálló laboratórium I. tárgy keretein belül meg kívántuk ismerni a
mobiltelefonunk bluetooth karakterisztikáját, ami készülékenként változhat a jeladó körüli fém
alkatrészek elhelyezkedésétől függően. Egy ilyen jeladó elméletileg gömbkarakterisztikával
bír, ám ha található rajta egy „hiba” egy, az antenna mellé szerelt alkatrész miatt, akkor ez
által található rajta egy viszonyítási pont is, aminek segítségével a szerkezet telefonhoz
viszonyított irányát kaphatjuk meg. A távolságot azon tétel alapján akartam meghatározni,
miszerint egy jeladó által kibocsátott jel erőssége az adótól távolodva exponenciális
csökkenést mutat, ám, mint később kiderült, ez a beltéri körülmények miatt kialakuló fading és
reflexió miatt nem kivitelezhető. A „hiba” helyének megtalálásához, illetve a fent említett
állítások igazolásához mérőtársammal, Solymár Zórával méréseket végeztünk, melyek
távolság- és irány invariáns antennakarakterisztikát mutattak. A keresett objektum
pozíciójának meghatározása helyett csupán a vevő adótól vett távolságának megállapítását
tűztük ki célunkul. Méréseink eredményeinek pontosabb megértése érdekében számos cikket
tanulmányoztunk, melyekben konkrét leírásokat találtunk az általunk boncolt problémával
kapcsolatban.
A más-más közegekre jellemző csillapítások mértéke igen változatos lehet akár egy
hétköznapi háztartás esetén is: egy irodai ablaknak átlagosan 3dB, egy fém ajtónak már 6dB,
míg egy téglafalnak akár 12.4 dB is lehet ez az értéke. Maga a csillapítás a jel erősségének
csökkenése, melyet decibelben adhatunk meg, ami nem más, mint tízszer a beérkező jel
erősségének logaritmusa, osztva a kimenő jel erősségével (például egy iroda fala, a rádió jel
erősségét 200 milliwattról (input) 100 milliwattra (output) változtatja, ezért 3dB-es
csillapítású).
Tudtuk, hogy ha sikerrel is járunk a feladatunk megoldását illetőleg, sok esetben nem lehet
pontos a becslésünk, hiszen nem tudhatjuk, hogy a távolság, vagy egy nagy csillapítású tárgy
miatt kapunk egy adott értéket. Úgy véltük azonban, hogy megfelelő számú mérést
fölhasználva kialakíthatunk egy olyan adatbázist, amely segítségével az esetek többségében
akár méterre pontos közelítést adhatunk egy jeladó tőlünk vett távolságát illetően. Méréseink
színterének az egyetem negyedik emeletén lévő folyosót választottuk.
~ 8 ~
2.1 A homogén antenna karakterisztika lehetséges okai:
� A mérés helyének közelében működő router azonos sávban szórt jelével való interferencia
� A folyosó keskenysége következtében fellépő fading illetve reflexió
� A használt program (hcitool) alkalmatlansága
� Valóban homogén, távolságmeghatározásra alkalmatlan karakterisztika
� A notebook antennájának árnyékoltsága, gyengesége
2.2 Lehetséges megoldások:
� Mérési környezet megváltoztatása megoldhatja a lehetséges interferenciából, fadingből
illetve reflexióból adódó problémákat
� Használt eszközök, illetve a használt program cseréje további információkkal szolgálhat a
felmerült hibák okát illetően.
Az Önálló laboratórium II. tárgy keretein belül első lépésben a mérési környezetet változtattuk
meg: az általunk választott 1000 négyzetméteres kertben a legközelebbi router jele gyenge,
elhanyagolható volt, falak híján a fading, illetve a reflexió sem okozhatott problémát. Ezen
körülmények közt elvégzett méréseink ugyancsak közel homogén antennakarakterisztikáról
árulkodtak.
A következő lépés a használt eszközök cseréje volt. Lévén, hogy további kutatásaink során
sem találtunk precízen működő bluetooth jelerősség mérő szoftvert, a hcitool mellett
maradtunk, azonban az IBM ThinkPad X30 típusú laptop helyett egy HP Pavilion DV5
1160eh notebookot használtunk, amely egy jóval újabb, modernebb konstrukció, és amelynek
az antennája is erősebb elődjénél. Az így kapott értékek sem hozták meg a várt eredményeket,
mindazonáltal felfigyeltünk rá, hogy ugyan a jel erőssége a távolságtól függetlenül homogén
marad, távolodva a mérőeszköztől a mérések ideje növekedni látszik. A specifikusan ezzel a
témával kapcsolatos kutatásaink során figyelemre méltó dokumentumokat találtunk.
~ 9 ~
2.3 Lehetséges alternatíva
Egy igen érdekes értekezést olvashattunk olyan kísérletekkel kapcsolatban, miszerint egy zárt
téren belül egy jeladó pozíciója akár 1 méter pontossággal megadható 3(TOA módszer),
vagy4(DTOA módszer), fix helyen elhelyezett antenna felhasználásával.
A TOA módszer szerint (1) egy szobában
elhelyezünk 3 antennát, és a teremben mozgó
transzmitter előre meghatározott időközönként
küld egy-egy jelet mindhárom vevő felé,
amelyek ezt visszaküldve megadják a kellő
információt a jeladó számára, ugyanis az oda-
vissza út megtételének idejét megfelezve, a
késleltetést felhasználva megkaphatjuk a mobil-
és a fix egység egymáshoz vett távolságát. A három kapott távolság alapján a mozgó egység
pozíciója viszonylag pontosan, akár real-time meghatározható. Ezeket a fixen elhelyezett
egységeket azonban szinkronizálni kell, hogy egy adott órajelre, egyszerre induljanak el.
A DTOA módszer (2) bevezet egy negyedik
bázis állomást, a másik három vevő által
meghatározott síktól eltérően elhelyezve,
ezzel pontosíthatjuk méréseinket. Az egyik
transzmitter kap egy plusz feladatot, ő fog
felelni a szinkronizációért (3). Ilyenkor a
négy egységből három terjedési időt
mérhetünk, három távolságot számolhatunk.
~ 10 ~
Ugyan a homogén jelerősség
problémáját ez a módszer
kiküszöböli, mivel a jel
terjedésének idejére, illetve a
távolságból fakadó jelgyengülés
okozta nehezebb, hosszabb
kapcsolatteremtésre alapozva
becsül, azonban a több utas
terjedés problémájával ugyanúgy
számolnunk kell, mint eddig. (4)
Látható, hogy egy átlagos méretű, zárt helységben a közvetlenül haladó, illetve a reflektálódó
sugarak megérkezése között akár 100ns is eltelhet, ez az oda-vissza út alatt akár 200ns-ra is
növekedhet.
A reflexiók csökkentése érdekében a
fixen elhelyezett bázis állomást a terem
sarkába rakhatjuk, így a plafonról, illetve
a falakról visszaverődő sugarak késése
minimálisra csökkenthető, elhanyagol-
hatóvá válik. (5)
Ez a megoldás a mi feladatunk esetén
természetesen nem alkalmazható lévén,
hogy a transzmitter a felhasználó kezé-
ben lesz, a reflexióval tehát számolnunk kell, a számított értékek csak megközelítőleg lehetnek
pontosak.
Szkeptikusan fogadtuk a jelentősen, mérhetően növekvő jelterjedési időnövekedés teóriáját,
mivel nem tartottuk valószínűnek, hogy egy rádióhullám pár méteren belül jelentősen
„lelassulna”, mindazonáltal az elméletet tesztelvén méréseket végeztünk, amelyek valóban
bebizonyították számunkra, hogy ez a módszer használhatatlan. Az eddigi BASH scriptünket
átírtuk, így az eredményeket ezen túl nem decibelben, hanem nanoszekundumban kaptuk meg.
Átlagosan 5-6 századmásodpercig tartott a csomagnak az út megtétele, ha pedig a kapcsolat
felépítésének idejét is hozzávettük, akkor sem kaptunk használható eredményt, mivel 3 és 4
másodperc között, látszólag a távolságtól függetlenül változott az eredmény.
Újabb kutatásokba kezdtünk hát, a bluetooth technológia elméletének alapjait
tanulmányoztunk. Összességében annyit tudtunk meg, hogy a Host Controller Interface (HCI)
3 fő kapcsolati jellemzőhöz nyújt hozzáférést. Melyek azok hárman??
~ 11 ~
2.4 A HCI (Host Controller Interface) paraméterei
� Az LQ (Link Quality) egy 8 bites integer, ami egy 0 és 255 közötti skálán jellemzi a
bluetooth kapcsolat minőségét (mivel 2ˇ8 = 256 lehetőség). Minél nagyobb ez az érték,
annál erősebb a kapcsolat. A legtöbb esetben ezt az úgynevezett ’bit error rate’-ből (BER)
származtatják, ami a vevő oldalon mérhető, és minden egyes elküldött csomag esetén
frissül az értéke. A BER-LQ átváltás teljes mértékben készülékfüggő.
� Az RSSI (Received Signal Strength Indicator) ugyancsak egy 8-bites integer, amely azt
mutatja meg, hogy a vett jel erőssége az úgynevezett Golden Receiver Power Range
(GRPR), az ’ideális’ jelszint alatt vagy fölött van-e. Az előző félév során ezt az értéket
mértük, eredménytelenül.
� A TPL(Transmit Power Level) is egy 8 bites integer, amely a bluetooth eszköz
sugárzásának erejét adja meg decibelméterben. Ez sok esetben készülékfüggő: az első
osztályú eszközök számára, amelyeknek a maximum kimeneti jele 20 dBm erősségű,
kötelező a +4 és +20 dBm közti jeleket szabályozniuk. A második osztályba tartozó
készülékek maximum +4, míg a harmadik osztálybeliek maximum 0 dBm kimeneti erőt
képesek elérni, így a +4 dBm alatti jelek esetén nincs szükség a TPL szabályzására.
Az RSSI mérése az első félév során nem hozta meg a várt eredményt, a TPL-t pedig
bizonytalannak találtuk, mivel az első osztályba tartozó eszközök jelerősség-szabályzása túl
eltérő lehet készülékenként, a másik két osztály képviselői pedig várhatóan rövid időn belül
eltűnnek majd a piacról. Az általunk használt HCITOOL Linux alkalmazás egyaránt képes
RSSI, TPL és LQ mérésére, így az eszköz már a kezünkben volt a Link Quality kinyeréséhez.
~ 12 ~
3.fejezet
A tervezés részletes leírása Ide valami rövid bevezetőt kell írni! Formailag két cím nem követheti egymást!!!!
3.1 A munka során felhasznált eszközök
Mivel a Link Quality karakterisztikája készülékenként változik, illetve a különböző bluetooth
chipek is eltérőek lehetnek, igyekeztünk minél több, számunkra elérhető eszközt kipróbálni a
tesztelések során. Végül a munkánk során az alábbiakat felhasználva végeztük el a
kísérleteinket:
� IBM ThinkPad X30 típusú laptop
� GP Pavilion DV5 1160eh notebook
� Google G1 okostelefon
� Samsung Galaxy S okostelefon
� Samsung Galaxy 3 okostelefon
� Motorola defy okostelefon
� ZTE Blade okostelefon
� Motorola RAZR V31 mobiltelefon
� Nokia N95 mobiltelefon
~ 13 ~
3.2 Mérések
A Link Quality tesztelése során bíztató eredményeket kaptunk. Végeztünk kültéri és beltéri
méréseket egyaránt, melyek során, a fixen elhelyezett laptophoz képest egyre távolabb
mozgattuk az azzal aktív bluetooth kapcsolatban levő mobiltelefont.
A szabad téren végzett tesztek természetesen sokkal szebb eredményeket hoztak, mint a
zsúfolt házon belüliek, azonban a bent mért értékek is jól látható csökkenést mutattak a
távolság növelésével.
Egy Nokia N95 típusú mobiltelefonon méréseket végeztünk viszonylag nyílt terepen (6). A
környezet nem volt teljesen homogén, de még így is jól látható, hogy a távolság növelésével a
Link Quality értéke folyamatos csökkenést mutat. 18 méter után a notebook nem tudott többé
csatlakozni a telefonhoz, azonban az eredmények így is elég meggyőzőek voltak ahhoz, hogy
megkezdjük a beltéri méréseket (7).
~ 14 ~
Az épületen belül található volt egy 16 méteres, ajtóktól mentes szűk terület, ezen a részen
növeltük folyamatosan az adó és a vevő távolságát, így kaptuk az alábbi (7) karakterisztikát.
Ugyan ez nem mutat olyan szabályos csökkenést, mint a kültéri (6), azonban még így is sokkal
használhatóbb, mint az Önálló laboratórium I. keretein belül végzett, RSSI- re vonatkozó
méréseink. A képen a 3 feltüntetett pont 3 külön méréssorozatot jelöl, melyek rendre:
� X1: A telefont 3 méterre helyeztük el az adótól egy 20 cm vastag betonfal mögött, egy
oldalról nyitott, ajtó nélküli kis szobában.
� X2: A telefont 3 méterre egy fa szekrény fiókjába raktuk.
� X3: A vevőt egy másik, zárt ajtajú szoba egyik szekrényében helyeztük el, körülbelül
3 méterre az adótól.
Látható, hogy a kisebb csillapítású tárgyakkal vett értékek nagyjából követik az előre lemért
karakterisztika vonalát. Még ha a programunk nem is fog teljes pontossággal működni, a
hétköznapi életben való használata még ekkora hibafaktorral számolva is igen hasznos lehet.
~ 15 ~
Azonban a Link Quality egy készülékfüggő tulajdonság, ezért méréseket végeztünk egy
Motorola RAZR V3I típusú mobiltelefonnal is, amely egy jóval erősebb, a távolságra viszont
kevésbé érzékeny karakterisztikát mutatott. (8)
Ugyancsak látható, hogy ez a telefon jóval a másik készülék maximális használható távolsága,
18 méter fölött is kapcsolatot tudott kiépíteni a laptoppal. 27 méteren is egy 160-as értéket
produkált.
Az ebben a készülékben található antenna szembetűnően más viselkedést mutatott, mint
elődje. 0 és 20 méter között a jel link quality értékének csökkenése minimális, ingadozó volt.
Hogy ha egy ilyen karakterisztikát mutató készülékkel szeretnénk megtudni, hogy az általunk
keresett jeladó vajon karnyújtásnyira, avagy az épület másik sarkában van-e, sajnos nem
járnánk sikerrel.
Ugyanakkor 20 és 25 méter között a jel süllyedése számottevő, szinte lineáris, így talán az
ebben a telefonban megtalálható bluetooth chipet éppen arra lehetne használni, hogy
megtudjuk, a keresett tárgy, vagy személy a tőlünk vett, adott sugarú körgyűrűnyi területén
tartózkodik-e, vagy ha nem, akkor a gyűrűn belül, avagy kívül található.
~ 16 ~
Már a fent leírtak is demonstrálják az ’Link Quality’ készülékfüggő tulajdonságát, de azért
beltéri méréseket is végeztünk (9), amelyek hasonló eredményeket mutattak.
A feltüntetett pontok itt is akadállyal eltakart pozíciókat jelölnek:
� X1: A laptoptól 16 méterre, egy TV készülék mögött elhelyezve a telefont is igen erős,
208-cas értéket kaptunk
� X2: 8 méterre, egy fal mögé rejtve a vevőt is erős, 214-gyes értéket kaptunk
� X3: 7 méterre, egy másik, zárt ajtós szobán belül is 225-tös értéket adott.
Itt is megfigyelhető a távolsággal arányos LQ-csökkenés, azonban ebben az esetben is jól
látható, hogy nagy távolságban stabilabb kapcsolatot mérhetünk, mint a Nokia N95 esetén (7).
Sajnálatos módon a jelentős jelingadozás miatt ez a készülék beltéren valószínűleg maximum
a feljebb említett, körgyűrűben való tartózkodás eldöntésére lehet alkalmas, habár
előfordulhat, hogy egy kevésbé zsúfolt épületben, ahol kevesebb a szabad tükörfelület illetve a
jelet kiválóan elnyelő / visszaverő berendezés, talán még ez a telefon is megállná a helyét, és
alkalmazható lenne bizonyos feladatok elvégzésére. Hogy ha például arra lennénk kíváncsiak,
hogy a bluetooth antennánk hatósugarán belül elhelyezkedő jeladók tíz méteren belül, vagy
kívül találhatók, az még egy hasonló karakterisztikájú jeladó esetén is megoldható lenne
(mondjuk egy olyan automata ajtó esetén, amely a közeledő, adott fizikai című telefonnal
rendelkező embereket hivatott beengedni).
~ 17 ~
4.fejezet
Megvalósítás Rövid bevezetés kell!!!!
4.1 Okostelefonon való implementáláshoz szükséges ismeretek
megszerzése
Miután kiderült számomra, hogy mely eszközök felhasználásával célszerű nekilátnom a
feladat konkrét megvalósításának, rátértem a szoftver megírására. Az eddig használt Nokia
N95 és Motorola RAZR V3I is Symbian rendszeren működik, amely programozása
meglehetősen bonyolult és várhatóan elavulttá válik, választásom inkább az egyre népszerűbb,
és ugyancsak jól kidolgozott Android platformra esett.
4.1.1 Az Android rövid története:
Az Android platform abból a célból született, hogy egységes, nyílt forrású operációs rendszere
legyen a mobil eszközöknek (és itt elsősorban a ’smartphone’, azaz okostelefon kategóriát
értem, nem az egyszerű mobiltelefonokat). Az elképzelés alapja egy Linux alapú operációs
rendszer volt, amelyet úgy alakítanak át, hogy képes legyen problémák nélkül kezelni a mobil
eszközök integrált hardvereit (érintőképernyő, WiFi, Bluetooth…). Az első lépéseknél nem
tervezték a Java nyelv használatát, azonban a Google 2005 júliusában megvásárolta az
Android nevű céget, és új irányt adott a fejlesztésnek: a Linux kernel fölé egy virtuális gép
került, amely a felhasználói felület kezeléséért és az alkalmazások futtatásáért felelős.
Természetesen ez egy lassú folyamat volt, és a Google az első évben igen csöndesen
dolgozott, 2007 elején kezdtek kiszivárogni olyan hírek, hogy a Google belép a mobil piacra.
Az iparági pletykák végül igaznak bizonyultak, és 2007. november 5-én az Open Handset
Alliance bejelentette az Android platformot.
Napjainkra az Android platform iránt a mobiltelefon és a Tablet gyártók érthető izgalmát
leszámítva nagy érdeklődés mutatkozik a gépjárművek fedélzeti számítógépét és navigációját
szállító cégek, illetve az ipari automatizálás irányából is, hiszen minden olyan területen
kényelmes az Android, ahol alapvetően kicsi a kijelző, limitáltak az erőforrások és az
adatbevitel nem egérrel és/vagy billentyűzettel történik.
~ 18 ~
4.1.2 Az Android felépítése:
Mint azt a (10) ábra is mutatja, a platform alapját a vörös színnel jelölt Linux kernel adja,
amely tartalmazza a hardver által kezelendő eszközök meghajtó programjait. Ezeket azon
cégek készítik el, amelyek az Android platformot saját készülékükön használni kívánják,
hiszen a gyártónál jobban más nem ismerheti a mobil eszközbe integrált perifériákat. Ez a kis
méretű kernel adja a memória kezelését, a folyamatok ütemezését és az alacsony fogyasztást
elősegítő teljesítmény-kezelést is.
A kernel szolgáltatásait használják a Linux rendszerekben meglévő különféle
programkönyvtárak, mint a libc, az SSL vagy az SQLite; ezek C/C++ nyelven vannak
megvalósítva, és a közvetlenül Linux kernelen futnak. Részben ezekre épül a már korábban
említett Dalvik virtuális gép. A kék színnel jelölt részekben már csak Java forrást találunk,
amelyet a virtuális gép futtat, s ez adja az Android lényegét: a látható és tapintható operációs
rendszert, illetve a futó programokat.
~ 19 ~
4.1.3 A fejlesztés során szerzett tapasztalatok:
Ez egy teljesen új környezet volt a számomra, első lépésként az interneten található
tananyagok alapján igyekeztem megismerkedni vele. Mint megtudtam, igen sok különböző
magyar és idegen nyelvű fórum foglalkozik ezen operációs rendszer felépítésével,
működtetésével, fejlesztésével, az ezeken az oldalakon regisztrált tagok pedig igen
segítőkészek voltak, nagyban megkönnyítették a tanulási folyamatot.
Sok olyan problémával kerültem szembe a munkám során, amelyek nem nevezhetők
hétköznapinak, megoldásuk bluetooth-specifikus ismereteket igényel, azonban, mivel ez egy
igen fiatal technológia, a segítség nyújtásához kellő ismeretekkel és tapasztalattal rendelkező
emberek száma igen alacsony.
Az ilyen témákat illetően a mindenki számára elérhető, android fejlesztést segítő oldalakon
nem kaptam segítséget, a megoldáshoz vezető utat csupán a nehezen felkutatott szabadúszó
fejlesztők, illetve hivatásos, android fejlesztéssel foglalkozó cégek munkatársainak magán
email címeinek, facebook azonosítóiknak kiderítésével, az illető szakemberek személyes
megkeresésével, a kérdéseimet közvetlenül nekik feltéve sikerült megtalálnom. Közülük is
kiemelnék egy orosz, egy japán, egy brazil, egy román illetve egy amerikai fejlesztőt, akik
segítsége nélkül az általam készített szoftver valószínűleg nem készülhetett volna el időben,
segítségük felbecsülhetetlen értékű volt a munkám során.
Eddigi tanulmányaim, munkáim során elsősorban a Java programozási környezettel
ismerkedtem meg, így csupán az Android-ban megjelenő, a megszokott környezettől való
apróbb eltéréseket kellett megértenem, használatukat példaprogramokon keresztül
elsajátítanom.
Ezek közül a legszembetűnőbb az, hogy az okostelefonok nem a már megismert részekre
bontanak egy-egy java programot, ebben az esetben a fejlesztőnek úgynevezett ’Activity’-ket
kell megvalósítania, ennek megértése nem könnyű ugyan, azonban használata egyszerű,
struktúrája logikus. A lentebb felsorolt függvények közül az én programomban csak az
onCreate(), az onResume(), illetve az onDestroy() függvények kiegészítése, megvalósítása tűnt
szükségesnek, a többi az alapértelmezésben megírt funkciókat végzi el csupán.
~ 20 ~
4.1.4 Az android alkalmazás életciklusa:
Az Activity nem más, mint egy vagy több önálló egység a programon belül, amelye(ke)t a
felhasználó elérhet, használhat. Egy adott programfunkció-csomagot egy activity-n belül
írhatunk meg. Majdnem minden activity kommunikál a felhasználóval, ezért ez az osztály felel
a felhasználói felület beállításáért is.
Egy ilyen programegység ugyanúgy, akár a java-ban megismert objektumok, rendelkezik egy
’életciklussal’(14): születik, él, meghal. Ezt bővebben a következő függvényekkel
valósíthatjuk meg:
� onCreate() : Az activity futtatásának első fázisa. Itt deklarálhatunk, inicializálhatunk
változókat, beállíthatjuk a programunk kinézetét (layoutokat, View objektumokat
hozhatunk létre, beállíthatjuk őket). Ebben a függvényben célszerű mindig meghívni a
szülő osztály azonos metódusát, a ’super.onCreate()’ függvényt, így a szoftvernek csupán
a számunkra fontos részeiről kell gondoskodnunk (ez igaz a többi, alább felsorolt
függvényre is, a szülő osztály azonos metódusának meghívása nélkül a programunk
valószínűleg hibásan fog működni). Ez a függvény tárolja el a legutóbbi futtatás
befejezésekor tárolt aktuális értékeket is, hogy a legközelebbi indításkor ott folytathassuk
az alkalmazás folyamatait, ahol abbahagytuk. Mindig az onStart() függvény követi a
futási szekvenciában.
� onStart() : Amikor az activity láthatóvá válik a felhasználó számára, akkor hívódik meg
ez a függvény. Az onResume() követi, ha az activity lesz a fókuszban, és az onStop(), ha
a program a háttérbe kényszerül.
� onRestart() : Ha az activity leállt az onStop() függvény miatt, és újra előtérbe kerül, az
onRestart() fog lefutni. Mindig a Start() függvény követi a futási szekvenciában.
� onResume() : Akkor hívódik meg, amikor az activity kapcsolatba kerül a felhasználóval,
és fókuszba kerül, tehát ő szerepel az activity-k szekvenciájának elején. Mindig az
onPause() követi
� onPause() : Amikor a rendszer folytatni készül egy másik activity–t. Jellemzően ebben a
függvényben kerülnek mentésre a változók aktuális értékei, az animációk leállnak, és
minden, a processzorra nézve terhelő folyamat abbamarad. Ezen feladatok elvégzésének
gyorsnak kell lenniük, hiszen a rendszer nem adhatja át a vezérlést a kívánt activity–nek
addig, amíg az onPause() függvény minden sora le nem futott. Követheti az onResume(),
ha az activity újra fókuszba kerül, vagy onStop(), ha a futási szekvenciában tartósan hátra
kerül, láthatatlanná válik a felhasználó számára.
~ 21 ~
� onStop() : Amikor az activity többé nem látható a felhasználó számára, mert egy másik
activity kerül előtérbe, akkor hívódik meg az onStop() függvény. Követheti az
onRestart(), ha a programunk újra előtérbe kerül, vagy onDestroy(), ha az activity-t
bazárjuk.
� onDestroy() : A program futásának utolsó fázisa. Ha például létrehozunk a felületen egy
gombot, amelyet megnyomva meghívjuk a finish() parancsot, automatikusan ez a
függvény fog lefutni. Ebben a fázisban kiüríthetjük a listáinkat, leállíthatjuk a még futó
szálainkat, memóriát szabadíthatunk föl.
Az Android activity-k életciklusát a következő ábra (11) mutatja be:
~ 22 ~
Kérem konkrétam írja le hogy ez mit jelent a fejlesztés szempontjából!
4.1.5 A fejlesztéshez szükséges programok, összetevők:
Nem szerencsés jkét egymást követő sorba cím-et írni!!!
� Eclipse IDE for Java EE Developers
Ez egy Java programozási nyelvhez kifejlesztett programozási környezet, amellyel
tanulmányaim és munkám során már volt szerencsém közelebbről is megismerkedni.
Számtalan támogató funkciója, jól átlátható struktúrája és real-time kódelemzője nagyban
megkönnyíti a szoftverfejlesztő munkáját.
� SDK (Source Software Development Kit) szoftverfejlesztői környezet
Az Android operációs rendszerhez kiadott API-kból (Application Programming Interface)
álló csomag, amely elérhetőséget biztosít az előre megírt lekérdezésekhez,
metódusokhoz. Az egyetemtől kapott készülék az 1.6-os verziót támogatja, amely jóval
kevesebb lehetőséget nyújt, mint a ma kapható legújabb, 2.3-mas kiadás. Ebből
következően adódott egy igen kellemetlen problémám, miszerint ebben a változatban még
nem voltak elérhetők a bluetooth funkciói. Több napos kutatás után találtam azonban egy
úgynevezett „backport bluetooth API” – t, amely révén hozzáfértem a kívánt
parancsokhoz. Ezt az AndroidManifest.xml file-ban kellett importálni, miután magát az
API fájlt letöltöttem, és a com.bluetooth csomag mellé másoltam:
<activity android:name="backport.android.bluetooth.RequestEnableActivity"
android:label="Bluetooth Permission Request"
...
</activity>
<activity android:name="backport.android.bluetooth.RequestDiscoverableActivity"
android:label="Bluetooth Permission Request"
...
</activity>
<receiver android:name="backport.android.bluetooth.BluetoothIntentRedirector">
...
</receiver>
~ 23 ~
� Adt(Android Development Tools) Plugin
Az Eclipse-ben való fejlesztést megkönnyítő csomag, amely lehetővé teszi Android
programok futtatását, hibák keresését, programok importálását, és egyáltalán szinte
minden olyan funkciót, amit az egyszerű Java Projektek esetén megszoktunk. Ennek
segítségével hozhatunk létre új Android projektet, állíthatjuk be a futtatási paramétereket,
és az Eclipse ezen keresztül ismeri föl a számítógéphez csatlakoztatott, az adott program
futtatására alkalmas készülékeket.
� AVD (Android Virtual Device) Manager
Ennek segítségével akkor is futtathatjuk a programunkat, ha nem rendelkezünk Android
operációs rendszerrel rendelkező telefonnal. Szoftverünk működését egy virtuálisan
megjelenő készüléken követhetjük figyelemmel, amelynek operációs rendszerének
verzióját, külsejét, és még sok más paraméterét beállíthatjuk, hogy a számunkra
megfelelő típusú készülékre tervezhessük a programunkat, az esetleges teszteredmények
relevánsak legyenek. Sajnálatos módon ezen funkciót nem tudtam használni az
alkalmazásom megírása során, mivel a bluetooth-szal kapcsolatos parancsok nem
kezelhatők vele , hiszen a megjelenő telefon nem rendelkezik antennával.
� Android NDK (Native Development Kit)
Csak hosszas kutatás után derült ki, hogy szükségem lesz erre a funkcióra, mivel ennek
segítségével natív nyelveken megírt programokat építhetünk a Java nyelven megírt
szoftverünkbe. Megértése és használata nem könnyű, a fellelhető segédanyagok, illetve
hozzáértő emberek száma is alacsony. Ennek szükségességét és használatát a
későbbiekben fejtem ki.
~ 24 ~
4.16 Az Android programok felépítése:
Egy átlagos, okostelefonra írt android alkal-
mazás felépítését a saját programom struk-
túráján (12) mutatom be:
� A BlueCalizer projectben helyet foglal a
jól ismert ’src’ mappa, amely a rend-
szerezéshez szükséges csomagokat
(package), illetve az azokon belüli java
osztályokat tartalmazza.
� a ’gen’ mappa tartalmazza az R.java fájlt,
amely összeköti a programkódunkat a
külső, használni kívánt fájlokkal, és
amelyből minden android alkalmazáshoz
generálódik egy példány. Ez tartalmazza a
külső erőforrásokat, így ezen keresztül
hivatkozhatunk a ’res’ mappában található
’drawable’ képi elemekre, a layout
mappában, xml formátumban deklarált
elrendezésekre (layout-okra) és témákra,
illetve a ’values’ mappában található,
előre deklarált, statikus szövegekre
(Stringekre).
� A ’jni’ mappa tartalmazza a natív C
kódokat, header-öket és az Android.mk
fájlt.
� Az AndroidManifest.xml fájlban
leírhatjuk a program verzióját,
beállíthatjuk az ikonját, a használni kívánt
jogokat (permission), és még sok egyéb, a
programra jellemző paramétert.
� A default.properties fájlt az Android maga
generálja, a program néhány fontos
tulajdonságát írja le benne.
~ 25 ~
4.2 A fejlesztés folyamata
Ismét két cím egmés után ide is írjon egy bevezetőt.
4.2.1 Az alapok elsajátítása
A kívánt csomagok telepítése és megismerése
után elkezdtem megírni a programot, amely
igen nehéz feladatnak bizonyult. Az egész
rendszer struktúrája és a nyelvezet egy része is
új volt számomra, ám végül sikerült egy
működő szoftvert előállítanom melynek
képernyőképe a (13)ábrán látható, és ami még
fontosabb, megértenem, amely nem csinált
mást, csak kiírt a képernyőre egy adott
szöveget.
Az ehhez tartozó kód ugyan rövid, megértése
mégsem egyszerű, azonban elengedhetetlen
volt:
public class HelloAndroid extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText(„Hello Android”);
setContentView(R.layout.main);
} ez az idézet syntax hibás! Összesen két db { és csak egy db } van benne!!!!
A már korábban megismert onCreate() függvénnyel kezdünk, melynekaz előző használat során
esetlegesen elmentett állapotot adjuk paraméterként.
A kódban létrehoztam egy TextView objektumot konstruktorral együtt. A TextView() a View
osztály alosztálya, amelyet kifejezetten szövegkezelésre használunk. Ez az objektum elfogadja
a Context paramétert, amely az Android programozásban igen gyakran használt típus,
lényegének megértése mégsem volt egyszerű. A Context kezeli a rendszer által nyújtott
szolgáltatásokat, feladatai közt megtalálható az erőforrások kezelése, adatbázis kapcsolatok,
beállítások kezelése, stb. Az Activity osztály örökli a Context osztály tulajdonságait, és mivel
~ 26 ~
a fent látható osztály al-osztálya az Activity osztálynak, így az is örökli ezeket a
tulajdonságokat.
Ez után definiáltam a szöveges címkénk feliratát a setText() metódussal, végül pedig
meghívtam a szöveges címkét a SetContentView() metódussal. Ez biztosítja azt, hogy
megjelenjen a szöveg, ha ezt a metódust kihagytam volna, akkor csak egy üres képernyő jelent
volna meg. A függvény paramétereként megadott R.layout.main nem más, mint egy XML fájl
a ’res/layout’ mappában, amelyet ugye a ’gen’ mappában található R.java osztályon érhetünk
el a fent látható módon.
Úgy terveztem, hogy a kész szoftvernek tartalmaznia kell majd egy gombot, melyet
megnyomva elindíthatunk egy felderítést, amely után a képernyőn megjelenik majd az összes,
a környéken fellelhető aktív bluetooth eszköz neve és fizikai címe oly módon, hogy egy-egy
hasonló gombot rendelek minden megtalált eszközhöz. Ezen gombok bármelyikét megnyomva
a program egy, az előbbi módon megjelenített módon kiírja a kiválasztott eszköz nevét és a
távolságát méterben. Ehhez először meg kellett tudnom, hogyan lehet gombot létrehozni,
illetve megjeleníteni ebben a környezetben.
Az interneten számos fórumon találtam megoldást
erre a problémára, azonban ezen folyamat megértése
is sok időbe került. Végül, kellő mennyiségű
próbálkozás és gyakorlás után megszületett az első
működő gomb (14), a készülő szoftver alapja:
Itt a gombhoz hozzá kellett rendelnem egy
úgynevezett „action listenert”, amelyen keresztül
minden egyes lenyomáskor meghívhatunk egy
metódust, amely a képernyőre ír egy szöveget.
Korábbi tanulmányaim során többször használtam
már ilyen megoldásokat, azonban ebben az új
környezetben ez is jóval bonyolultabbnak bizonyult,
ugyanis itt már nem csak a kódot tartalmazó Java
fájlt kell megírni, hanem különböző, XML
kiterjesztésű oldalakat is.
A következő lépés bluetooth antenna használata volt, ebben az esetben már nem használhattam
az AVD-t. A korábban már említett „backport bluetooth API” felkutatása és telepítése után
több fórumot végigolvastam a témával kapcsolatban, míg végül megértettem a
programcsomag működésének elvét és annak hierarchiáját.
A kívánt funkciókat, mint az eszközök felderítését, a talált eszközök nevét és fizikai, azaz
MAC (Media Access Control) címét is a ’Bluetooth Adapteren’ keresztül érhetem el. Ez a
~ 27 ~
hexadecimális szám, a bluetooth eszköz MAC címe lesz az az azonosító, amely alapján
egyértelműen hivatkozhatok az adott készülékre, jeladóra.
Miután ezt sikerült elérnem, minden felderített eszközhöz rendeltem egy gombot, melyet az
adott berendezés nevével és fizikai címével láttam el.
Ezen a ponton abba a problémába ütköztem, miszerint ha egymás után többször léptem
felderítő üzemmódba a „Scan for devices” gomb megnyomásával, akkor nem elég, hogy az
addigi keresések eredménye nem tűnt el, de adott számú lenyomás után ugyanannyiszor
minden egyes készüléket listáztam. Ezt csupán a későbbiekben tudtam megoldani, amikor már
tisztában voltam a View típus fogalmával.
A View egy "rajzolható" objektum, ami a felhasználó számára észlelhető interfész (UI) része
lesz, úgy, mint a szöveg, kép vagy ebben a példában a gomb. Ezek alosztályai a View
osztálynak. Ha elmentettem a megjelenített gombokat egy vektorban, majd ’Button’-ként
kitöröltem a azokat, akkor csupán az adott View objektumok egy része tűnt el, azonban ha
magukat a View objektumokat töröltem, a kijelzőről eltűntek az addig megtalált bluetooth
eszközökhöz rendelt gombok.
4.2.2 A felhasználó számára látható felület fölépítése
� Először létre kellett hoznom egy úgynevezett ScrollView-t, amely nem más, mint egy
tároló, egy konténer, amely a különböző felületeket, Layoutokat tartalmazza. Ezen
keresztül görgetheti a felhasználó a kijelző tartalmát.
� Ezen helyezhetjük el a layoutokat, amelyek egymást válthatják a program más-más
felületeire lépve. Ezt futás időben, Runtime is definiálhatjuk, vagy létrehozhatunk statikus
layoutokat a layout.xml fájlban. Számomra az első, futás idejű megvalósítás volt
alkalmazható, mivel a bluetooth felderítéskor megtalált eszközökhöz dinamikusan
rendeltem gombokat. Az XML alapú módszer több lehetőséget nyújt, könnyebben és
nagyobb biztonsággal használható ugyan, azonban a dinamikus változtatásokat nem
támogatja.
� Ezeken a layoutokon helyezkednek el a View objektumok, mint a címkék, gombok vagy
akár a képek.
Igen sok időt szántam egy XML alapú felhasználói interfész létrehozására is, mivel így sokkal
rendezettebb, kifinomultabb tartalmat hozhattam létre. A gomboknak más-más hátteret
adhattam, ikont helyezhettem el rajtuk, és a rájuk írt szöveget is sokkal szebben
megformázhattam. Miután ily módon létrehoztam egy szépnek mondható felületet, a gombok
dinamikus létrehozásának problémáját nem tudtam megoldani. Könnyen kialakítható témákat,
~ 28 ~
stílusokat is létrehoztam, amelyeket arra használtam, hogy ne kelljen minden egyes gomb
létrehozásakor formázni is az új objektumot.
Egy gomb létrehozása, illetve a rá illő stílus hozzáadása XML környezetben igen egyszerű:
A gomb létrehozása a /res/layout/main.xml’-ben a következő módon történik:
<Button android:id="@+id/Matches" style="@style/Matches" />
Stílus hozzáadása a ’res/values/styles.xml’-ben:
<style name = "Matches" parent="@android:style/Widget.Button">
<item name = "android:layout_width">270dp</item>
<item name = "android:layout_height">wrap_content</item>
<item name = "android:layout_gravity">center</item>
<item name = "android:drawableLeft">@drawable/match</item>
<item name = "android:textStyle">bold</item>
<item name = "android:background">#fffafa</item>
<item name = "android:text">Match</item>
<item name = "android:textSize">30dp</item>
<item name = "android:textColor">#0000ff</item>
</style>
Érdekesség, hogy android programozás esetén a látható objektumok méreteit többféleképpen
megadhatjuk: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred
font size), in (inches), mm (millimeters). Ha a px, in, vagy a mm mértékegységek
valamelyikét használjuk, a különböző felbontású kijelzőkön egy adott kép teljesen eltérően fog
megjelenni, megváltozik az egész felület kinézete. Éppen ezért vezette be az Android a dp-t,
mint mértékegységet, hiszen így a programunk kijelzőre vetített tartalma mindig arányosan,
minden készülékben ugyanolyan külsővel fog megjelenni.
A gomb tartalmát, illetve annak a gombon vett elhelyezkedését is igen egyszerű beállítani. Itt
hivatkozhatunk a ’res’ mappában található erőforrásokra, de magában az XML-ben is
definiálhatunk hátteret, feliratot, illetve ezek megjelenítését is konfigurálhatjuk itt.
A színeket egy-egy hexadecimális szám jelöli, melyeket megtalálhatunk táblázatba szedve az
internet számos oldalán. Ezeket, és a többi, az XML-ben leírt jellemzőt számos kísérlet után
sikerült összehangolnom oly módon, hogy a felület éppen úgy nézzen ki, ahogyan azt előre
elterveztem. Igen nagy csalódás volt, amikor hosszas kutatás után kiderült, hogy munkám ezen
része fölösleges volt, hiszen a futásidejű, dinamikus objektumlétrehozást az XML alapú
fejlesztési módszer nem támogatja, így csupán a statikus objektumokhoz tudtam stílust
rendelni.
~ 29 ~
4.2.3 A program felülete:
Mint kiderült, a BluetoothAdapter.startDiscovery()
függvény, amely a felderítést végzi a „scan for devices”
gomb megnyomása esetén igen nagymértékben megterheli
a készülékben található bluetooth antennát, így a kapcsolat
létrehozásának érdekében ezt a keresési folyamatot le kell
állítani a BluetoothAdapter.cancelDiscovery() függvény
segítségével, amihez ugyancsak rendeltem egy statikus, a
képernyőn mindig megjelenő gombot, amely közvetlenül a
felderítést indító gomb alatt kapott helyet. Az
inkonzisztencia elkerülése végett ez a gomb csupán akkor
aktív, ha a már megkezdtük az eszközök felderítését, így
nem fordulhat elő, hogy megpróbálnánk leállítani a
keresést, holott az antennát még nem is kapcsoltuk
’Discovery” üzemmódba. Éppen ezért ennek az objektumnak a konstruktorában inaktívvá
tettem a felderítés leállító funkciót (stopDiscovery.setEnabled(false)), a ’Scan for devices’
gomb megnyomása esetén tettem csak aktív állapotba (stopDiscovery.setEnabled(true)),
majd a ’Stop Discovery’ használata esetén a gomb újra inaktív állapotba kerül.. Kellemetlen,
hogy az Android bluetooth API-jának ez a metódusa sem működik kifogástalanul, az általam
tesztelésre használt készülékek közül csupán a Samsung Galaxy 3-mon nem kaptam a
következő hibát a gomb megnyomásakor:
„stopDiscoveryNative: D-Bus error in StopDiscovery: org.bluez.Error.Failed (Invalid discovery
session)”
Ez a probléma számos fórumon visszatérő téma, a hivatalos támogató eszközökben megírt, a
bluetooth felderítést leállító programban található inkonzisztencia okozza, azonban a tesztjeim
során arra a következtetésre jutottam, hogy a függvény a feladatát az üzenet ellenére elvégzi.
A felületen helyet kapott még egy, a programot leállító gomb is. Az android programozása
esetén a finish() paranccsal állíthatjuk le az alkalmazásunk futását, amely meghívja a már fent
említett onDestroy() függvényt. Ekkor a létrehozott vektorokat kiürítem, a bluetooth antenna
terhelését megszüntetem, a függőben levő feladatokat (szálakat) lezárom.
Ezek alá kerülnek a dinamikusan létrehozott, aktív bluetooth eszközöket jelző gombok,
melyek sorrendje a megtalálásuk ideje szerint változhat. A mellékelt ábra (15) mutatja az
~ 30 ~
aktuális felhasználói felületet egy felderítés után, amely során két eszköz volt található a
telefon közelében.
4.2.4 Aktív kapcsolat létrehozása:
Már az Önálló Laboratórium I. kurzus kezdetekor tisztában voltam azzal a ténnyel, hogy az
általam használni kívánt „link quality” érték kinyeréséhez aktív kapcsolatra van szükség a
forrás és a célállomás közt, tehát következő lépésként ezen összeköttetés megvalósításán
kezdtem el dolgozni.
A „backport bluetooth API”-t tanulmányozva meg is találtam a szükséges metódus nevét és
működési elvét, ezt rövid időn belül sikerült is implementálnom. Azonban, habár a
programkód nem mutatott hibát, a kapcsolódás másik bluetooth eszközhöz nem sikerült, így
mélyebben el kellett merülnöm a problémában.
Számos hasonló problémát boncolgattak különböző fórumokon, így rövid böngészés után
megtudtam, hogy nem lehetséges egy aktív kapcsolat létrehozása, ha a céleszköz nem „várja”
a kapcsolatot, azaz ha nem hoz létre egy bluetooth konnektort, socketet, amelyen
folyamatosan figyel, és a beérkező kapcsolódási kéréseket külön el kell fogadnia.
Szükségessé vált tehát egy szerver interfész létrehozása a programon belül, amely elvégezte
ezeket a feladatokat, így azonban a céleszközön is futtatni kellett ugyanazt a szoftvert, amelyet
a mi készülékünkön, és a „listen for incoming connections” gombot megnyomva föl kellett
készíteni a telefont, hogy készüljön föl az esetleges kérelmek elbírálására, elfogadására. Ezt a
gombot megnyomva a telefon automatikusan „discoverable”, azaz felderíthető módba került,
hogy egy aktív eszközök utáni keresés esetén ő is megjelenjen az eredménylistában, majd
létrehozott egy socketet, amelyen beérkező csatlakozási kérelmet várt, és ha kapott, elfogadta
azt, így az aktív kapcsolat létrejött.
Ezen függvény megírása során ismerkedtem meg az úgynevezett UUID (Universally Unique
Identifier) fogalmával, amely az adott alkalmazás egyértelmű megkülönböztetése során játszik
szerepet, ahogyan az autók esetében a rendszám is.
Az UUID nem más, mint egy 16 byte (128 bit) hosszú szám, tehát összesen 3 × 1038 ilyen
érték létezik, mivel a számunkra is feldolgozható alakjában 32 hexadecimális karakterből áll 5
csoportra bontva. Az interneten számos UUID generátor található, amely elméletileg egyedi
azonosítót biztosít, a programunknak, így én is generáltam magamnak egyet, amelyet
fölhasználva, érdekes módon, a csatlakozás sikertelennek bizonyult. Újabb kutatásaim során
megtudtam, hogy a bluetooth kapcsolódást megvalósító programoknak ’érdemes’ a következő
UUID-t használniuk a következő módon:
static final UUID MyUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
~ 31 ~
Ahhoz, hogy a szoftvert futtató készülék kliensként csatlakozni tudjon a fent leírt módon
szerverként viselkedő más eszközökhöz, az alkalmazásomnak rendszergazda jogokat kellett
adnom, de mivel a telefont előzőleg ’rootoltam’, ez megoldható volt. Mivel ez a folyamat
hivatalosan nem támogatott, kénytelen voltam olyan módszerek után nézni, amelyeket
magánemberek találtak ki és publikáltak, használatuk sikerére nincs garancia. Végül mégis
sikerült rendszergazdaként futtatnom a szoftvert a következő sor használatával:
Process p=Runtime.getRuntime().exec("su");
Így elindítva az alkalmazást, majd kapcsolatot kezdeményezve felugrott egy ablak, amely
megerősítést várt, hogy akarok-e a programnak ’SuperUser’, azaz rendszergazda jogokat adni.
Az ilyen esetekben, ha a felhasználó az ’OK’ opciót választja, a kérdés többé nem fog
megjelenni, a ’rootolás’-t végző program automatikusan megjegyzi, hogy az adott
alkalmazásnak megadhatja a jogokat.
Ezt a kódot használva a kapcsolat létrehozása végre sikerült. Tisztában voltam ugyan azzal,
hogy ezt a módszert alkalmazva a programom alkalmazhatósága nagyban csökken, mivel csak
olyan bluetooth eszközökhöz enged csatlakozni, amelyek futtatják ugyanazt a programot
szerverként, mint amit a felhasználó kliensként.
A sikeres csatlakozás érdekében először párosítani kellett a használni kívánt készülékeket, úgy
éreztem azonban, hogy ez nem válik kárára az alkalmazásomnak, bizonyos szempontból
inkább pozitívumként fogható föl, hiszen így mindenkinek először engedélyeznie kell majd a
program használójának az ő készülékére vonatkozó távolság meghatározást.
Az okostelefonoknak van egy olyan, a szoftverem megírásának szempontjából elég
kellemetlen tulajdonsága, hogy ha az eszközt ’discoverable’ üzemmódba állítjuk, ez az állapot
mindössze két percig áll fönn, utána újból meg kell nyomnunk a ’listen for incoming
connections’ gombot. Ezt végül csak részben sikerült kiküszöbölnöm oly módon, hogy a gomb
megnyomásakor elindítottam egy időmérő számlálót, és amikor az adott időtartam letelt, az
eszköz automatikusan egy felugró ablakkal jelezte a felhasználónak, hogy a felderíthető
üzemmód bekapcsolása újbóli engedélyezésre szorul, és ekkor az ’OK’ gombra kattintva a
folyamat újból elindul, a készülék látható lesz a többi telefon számára.
Érezhetően akadtak a csatlakozáshoz használt módszernek kellemetlen tulajdonságai, a
szoftverem tervezett felhasználhatóságát csorbították a különböző megszorítások és feltételek,
azonban ennek teljes mértékben maga az android volt az oka, az operációs rendszer alapjainak
átírásához pedig sem kellő szakmai tudásom, sem kellő időm nem volt, így kénytelen voltam
elfogadni az implementáláshoz használni kívánt platform hasonló, nem kívánt mellékhatásait.
~ 32 ~
4.2.5 A ’Link Quality’ érték kinyerése:
Ettől a ponttól kezdve már csupán egy dolog volt hátra, az LQ kinyerése, hiszen ezt az értéket
egy cikluson belül százszor lekérdezve, a kapott számok átlagát egy előre deklarált változónak
értékül adva megvalósíthatom azt, amelyet már egykori mérőtársammal számítógépen sikerült
elérnem.
Az Önálló laboratórium II. kurzus folyamán azonban egy Linux operációs rendszert futtató
számítógépet használtunk, amely terminálján keresztül sokkal több funkciót állt módunkban
elérni, mint a viszonylag új Android technológia szegényes, már-már hiányos SDK-ját
felhasználva. Ismételten meglátogattam a már jól megszokott fórumokat és fejlesztői
oldalakat, számtalan levelet küldtem különböző embereknek, azonban mindössze egy, link
quality lekérdezéssel kapcsolatos témát találtam a hosszú hetek alatt, amely megoldás híján a
feledésbe merült. Felderítetlen témát boncolgattam, nem kaptam segítséget.
Végül egy amerikai szoftverfejlesztő cég programozója adott tanácsot, miszerint létezik ennek
az operációs rendszernek egy kevéssé ismert kiegészítője, nevezetesen az Android NDK
(Native Development Kit), amely segítségével valószínűleg megkaphatnám a kívánt értéket.
Az új szempontok alapján kutatva több fórumot is találtam, amelyeken feltehettem
kérdéseimet.
Az enyémhez hasonló problémát nagyon keveset találtam, és azok is már mind régiek,
megválaszolatlanok voltak. Többnyire a jelerősség (RSSI) lekérdezésével álltak kapcsolatban,
és az egyik bejegyzés tartalmazott is egy linket, amely egy olyan oldalra hivatkozott, ahol az
összes HCI Linux parancsot implementálták, azonban nem Java, hanem C nyelven.
Megtaláltam az általam keresett metódust is:
int hci_read_link_quality(int dd, uint16_t handle, uint8_t *link_quality, int to)
Ez azonban nem volt megvalósítható Java-ban, mivel ez egy alacsony szintű, hardver-közeli
nyelven íródott, az általa használt parancsok többségének nem létezik megfelelője a magas
szintű eszköztárakban. Kénytelen voltam áthidaló megoldás után nézni, így az egyetlen járható
útnak a C-ben megírt kód beépítése bizonyult a saját programomba. Erre az Android NDK
nyújt lehetőséget.
Számos leírást tanulmányoztam az NDK-val kapcsolatban, ezek többsége azon témákkal
foglalkozott, amelyek implementálására a jelenleg létező legfrissebb eszköztár
felhasználásával nincs mód, azonban célomul tűztem ki egy teljesen alapszintű, natív kód Java
projektben való felhasználásával kapcsolatos szoftver megírását.
~ 33 ~
Az NDK-ra csupán a ’Link Quality’ érték lekérdezéséhez volt szükségem, így létrehoztam egy
új Java osztályt (Lq), amelyben deklaráltam az általam használni kívánt függvényt:
public native int LinkQuality(int handle, String mac, int dd);
Ha C nyelven szeretnénk egy függvényt megvalósítani, akkor ezt mindig jeleznünk kell a
’native’ előtaggal. Az argumentumok is fontosak, ebben az esetben a ’handle’ paraméter jelzi
az aktív bluetooth kapcsolatot, a ’mac’ tartalmazza a céleszköz MAC címét, a ’dd’ pedig a
kapcsolathoz használt bluetooth konnektort, socketet jelöli.
Azonban ezen paraméterek közül csupán a céleszköz fizikai címét ismerem, hiszen azt
megkaptam akkor, amikor felderítettem a környéken fellelhető aktív bluetooth eszközöket.
A ’dd’ kinyerése nehéz feladatnak bizonyult. Mivel a kapcsolatot az android API
felhasználásával hoztam létre, a már meglévő kapcsolatból kellett valahogy megkapnom ezt az
értéket. Újabb kutatásokba kezdtem, hogy módot találjak a feladat elvégzésére, azonban ez
már olyannyira egyedinek mondható probléma volt, hogy a fórumokon és cikkekben szinte
semmit nem találtam a témát illetően. Annyi minden esetre bizonyosnak látszott, hogy a Java
API-val létrehozott kapcsolatból nem nyerhető ki a kapcsolódásra használt socket száma
ugyanazon Java API használatával. Kénytelen voltam hát újból az NDK-hoz fordulni, és
magamnak megírni ezt a függvényt C nyelven.
A Linux operációs rendszer egy bizonyos Bluez API-n keresztül kezeli a bluetooth funkciókat,
ugyanez jellemző az Androidra is. Ez nem más, mint előre megírt, C nyelvű programkódok
gyűjteménye, amelyek megvalósítják ezeket a funkciókat. Azonban sajnálatos módon az
Android operációs rendszer Bluez API-ja sokkal kezdetlegesebb, kevésbé kifinomult, mint a
Linux-szé. Számos problémát még nem oldottak meg benne, és számtalan része hiányos is,
ezek ma is fejlesztés alatt állnak. Sajnálatos módon én nem tudtam éveket várni, hogy ezeket a
részeket megírják, kijavítsák, így kénytelen voltam a Linux-hoz kiadott API alapján megírni a
magam függvényét, amelynek segítségével a bluetooth kapcsolathoz használt socket számát
kívántam kinyerni.
Miután felvettem a kapcsolatot az Android Bluez API-jának fejlesztőivel és más, hasonló
problémákkal rendelkező programozókkal, végre képes voltam kinyerni a kívánt értéket.
Szerencsére ehhez föl tudtam használni már meglévő, kész Bluez funkciókat is, így a
függvényt magát nem volt túl nehéz megírni, a lényege a következő:
gethcisockbt:
hci_close_dev(old);
dev_id = hci_get_route(NULL);
dd = hci_open_dev(dev_id);
~ 34 ~
A hci_close_dev() függvénynek (-1)-et adva paraméterként bezárhatjuk az esetlegesen
folyamatban levő kapcsolathoz tartozó socketet. A hci_get_route függvénynek NULL-t adva
paraméterként megkaphatjuk az első elérhető bluetooth adaptert, majd ennek nyithatunk egy
socketet a hci_open_dev() metódussal.
A következő paraméter, amelyet meg szeretnénk kapni a ’handle’, ezt adjuk majd magát a
bluetooth kapcsolatot a read_link_quality() függvénynek. Szerencsére egy hasonló metódus
már megvalósításra került a Bluez API-ban, így ezt már jóval egyszerűbb volt létrehoznom.
Így született meg a
jint Java_com_bluetooth_Lq_getinfo(JNIEnv* env, jobject this, jstring mac, int dd)
metódus, amelynek használatához elegendő a fent leírt gethcisock függvény visszatérési
értékének behelyettesítése a ’dd’ paraméter helyére.
Ahhoz, hogy ezeket a kódokat, a gethcisockbt és a gethcisock függvényeket fölhasználhassam
a projektemben, az ’Lq.java’ osztályban ugyanúgy deklarálnom kellett az őket reprezentáló,
azonos szignatúrájú függvényeket, mint ahogy azt a hci_read_link_quality esetében tettem,
ezért létrehoztam a következő, java-ban meghívható metódusokat:
public native int gethcisock(int old);
public native int getinfo(String mac, int dd);
Ha a C programnyelven megírt alprogramok bármelyikét használni kívántam, nem volt más
dolgom, mint létrehozni a megfelelő helyen egy példányt az ’Lq.java’ osztályból, és arra
vonatkoztatva, a már megszokott módon meghívni ezen függvényeket.
Így, hogy minden paraméter elérhetővé vált, az Android NDK használata lett a következő
lépés, amely ugyancsak elég bonyolultnak bizonyult számomra.
~ 35 ~
4.3 Az Android NDK (Native Development Kit)
Azt, hogy a megírt C nyelvű kódokhoz hozzáférjek, használhassam őket, az Android NDK
teszi lehetővé, amely nem más, mint egy eszköztár, amely segítségével natív kódokat
ágyazhatunk be az Android alkalmazásunkba. Ennek segítségével megvalósíthatunk olyan
funkciókat is, amelyekhez az Android SDK nem nyújt hozzáférést, vagy felgyorsíthatjuk
alkalmazásunkat, ha magunk írjuk meg az adott függvényeket, és nem a kiadott Android API-t
használjuk.
4.3.1 Az Android NDK felépítése:
Az NDK az úgynevezett „Dalvik virtuális gép” - en fut, ami, nem más, mint egy regiszter
alapú virtuális gép, melyet Den Bornstein tervezett és írt meg a Google egyéb mérnökei
hozzájárulásával. Alacsony memória igényre optimalizálták, és úgy tervezték, hogy több
virtuális folyamatot tudjon kezelni oly módon, hogy egy folyamatként kezeli őket. Elkülöníti
az operációs rendszer műveletsorait és az alkalmazások műveletsorait. Nagyon hasonló a Java
virtuális géphez, viszont a Dalvik virtuális gép által futtatott bájtkód különbözik a Java
bájtkódjától. A Java bájtkód helyett egy ’dx’ nevű eszköz tartalmazza az Android SDK-t,
transzformálja a kódot egy szabájos Java osztállyá, és ezt fordítja le egy szabályos Java
bájtkóddá, melynek kiterjesztése ’.dex’(Dalvik Execute file) lesz. Ha több Java Class létezik a
projektünkben, akkor azokat egy dex állományba tömöríti, a duplikált ’szavakat’ (Stringeket)
csak egyszer csatolja. Általában egy tömörítetlen dex állomány csak pár százalékkal hosszabb,
mint egy tömörített .jar (Java ARchive, azaz java osztályokat, és hozzájuk tartozó
metaadatokat tartalmaó, zip formátumban tömörített állomány). Ezt a .dex állományt
tömörítik az android alkalmazások .apk formátumúvá, amelyet már az okostelefon futtatni
képes.
Ezek az optimalizációk, és ez a kódolási architektúra teszi annyira hatékonnyá, és gyorssá az
Android operációs rendszert.
~ 36 ~
4.3.2 Az Android NDK működési elve:
Az Android NDK letöltésével a következő funkciókhoz kapunk hozzáférést:
� Eszközök és ’build fájlok’ egy csoportja, melyek segítségével natív kód könyvtárakat
(’libraries’) generálhatunk C, vagy C++ nyelven
� az ily módon generált natív kód könyvtárakat beágyazhatjuk az NDK segítségével egy
.apk kiterjesztésű alkalmazásba, amelyet futtathatunk az Android operációs rendszert
használó okostelefonunkon
� natív rendszerfájlok, header fájlok, amelyeket az összes, legalább 1.5 – tös verziójú
Android operációs rendszer támogat, és támogatni is fogja a jövőben, így a régen megírt
programjaink kompatibilisek maradnak az újabb környezetekkel
� Dokumentációk, mintakódok és oktató anyagok
~ 37 ~
4.3.3 Az Android NDK használata
� Java osztály megírása, ennek tartalmaznia kell a megvalósítani kívánt metódusok típusait,
neveit és argumentumait
� Android NDK legfrissebb verziójának letöltése, kitömörítése tetszőleges helyre. Erre a
mappára mostantól %NDK_HOME%-ként hivatkozom
� Header fájl generálása a fent említett Java osztályból. Ez tartalmazni fogja az osztályban
deklarált metódusokat, azonban hozzájuk ad egy ’JNIEnv *’, illetve egy ’jobject’ típusú
argumentumot. Ezekre a C-ben való implementáláskor lehet szükség.
� A teljes projekt átmásolása az %NDK_HOME%/apps mappába
� Natív kód megírása
� A projekten belül egy ’jni’ könyvtár létrehozása, ez számos fájlt fog tartalmazni
� Az %NDK_HOME%/ ndk-build script futtatása
� A projekt, eredeti helyére való visszamásolása
Ahhoz, hogy a programom képes legyen natív kódokat kezelni, először le kellett töltenem a
ma létező legfrissebb NDK csomagot (android-ndk-r5-windows.zip), majd ezt kitömörítenem
a winchesteremre.
Ez után létrehoztam a projektemen belül egy „jni” könyvtárat, amely a C fájlokat és header
fájlokat hivatott tárolni, illetve az Android.mk-t, amely a natív kódokat írja le, és ennek
segítségével bonthatom a programokat úgynevezett modulokra. Ezek az egységek lehetnek
statikus-, illetve megosztott könyvtárak, ám csak az utóbbiak lesznek a telefonra másolva, és
az előbbiek segítségével hozhatom létre őket.
Ennek a struktúrának a megértése igen bonyolult volt, jelentős mennyiségű időt és energiát
emésztett fel, ám végül ezzel is elkészültem. Szükség volt továbbá egy Application.mk nevű
fájl megírására is, amely leírja a használni kívánt android operációs rendszer verzióját, rámutat
a feldolgozni (buildelni) kívánt projektre, és még számos funkciót határozhat meg. Az én
Application.mk fájlom a következő:
APP_PROJECT_PATH := $(call my-dir)
APP_MODULES := get_hci_lq_value
APP_PLATFORM := android-8
A következő fázisok teljesítéséhez Linux környezetre van szükség, vagy egy, a Windows
felhasználók számára kialakított Cygwin programra, amely szimulálni képes a szükséges
körülményeket. Ennek a programnak a letöltése és telepítése nehézkes és hosszadalmas
~ 38 ~
munkának bizonyult, mivel csupán kis teljesítményű külföldi szerverekről szerezhető be a
több, mint hat gigabájtos szoftver, ami nem más, mint egy Windows alatt futó terminál ablak a
hozzá tartozó funkciókkal, kiegészítőkkel.
Megtaláltam a szükséges módosításokat, amelyek segítségével az elkészíteni kívánt C kódra
hivatkozva kapcsolatot teremthetek a két programrész, a natív és a magas szintű nyelv között.
Ezeket az elképzeléseimnek megfelelőre alakítottam, végül implementáltam.
A következő lépésben úgynevezett header-öket kellett generálnom a már létező Java class-
fájlokból, ezen kódokhoz köthettem hozzá az előbb említett hardver közeli programot,
azonban ezen a ponton újabb akadályokba ütköztem. Az interneten nem találtam a kérdéses
feladattal kapcsolatos használható leírást, csupán egy Linux környezetben megvalósítható
parancsot:
’javah –jni packagename.DemoActivity’
Valamilyen okból kifolyólag ez a Cygwin-t használva hibásnak bizonyult, mivel egy létező,
TryNDK.class nevű fájl hiányára hivatkozva nem futott le, holott a kérdéses elem létezett és a
megfelelő helyen volt megtalálható.
Mint kiderült, a Cygwin nem is alkalmas erre a feladatra, a windows parancssort használva
már sikerült header fájlt generálnom, a projectem ’bin’ könyvtárából futtatva a következő
parancsot:
’javah -d "D:\...\%header_library%" -classpath "D:\...\%project_library%\bin %package.Lq%’
Itt a %header_library% azt a könyvtárat jelöli, ahova a legenerált fájlokat menteni kívánom, a
%project_library% a saját projektem könyvtára, a %package.Lq% pedig annak a .java fájlnak
(Lq) az elérése, amelynek függvényeit le szeretném generálni, viszont szeretném látni a natív
kódomban.
Ezek után a teljes Java projektemet átmásoltam az %NDK_HOME%/apps mappába, mellette
kapott helyet a már említett Application.mk fájl. Az %NDK_HOME%/apps/projekt/jni
könyvtárba került az újonnan létrehozozz header fájl, a hozzá tartozó C nyelvű implementáció,
illetve az Android.mk fájl.
A következő lépés a program felépítése, buildelése volt. Ennek két módja létezik:
� az android NDK r4b verzióból fennmaradt make APP=%projekt neve% parancs, melyet
az %NDK_HOME%-ból futtathatunk a Cygwin segítségével
� az android NDK r5b verzióban újdonságnak számító ndk-build script, melyet úgy tudunk
használni, ha az %NDK_HOME%/apps/%projekt neve% mappából futtatjuk az
%NDK_HOME%/ndk-build parancsot Cygwin segítségével
~ 39 ~
Az eredmény mindkét esetben ugyanaz volt, miszerint a fordító hiányolta a futtatáshoz
szükséges header fájlokat, melyeket az
%NDK_HOME% \platforms\android-8\arch-arm\usr\include\bluetooth
mappában keresett. Mivel az Application.mk fájlban definiáltam a használni kívánt, android-
8-cas verziót, valóban ott kellett volna lenniük, de mint kiderült, az Android NDK még nem
támogatja a bluetooth funkciókat, így magamnak kellett megkeresnem ezeket a fájlokat, és
manuálisan bemásolni őket a kívánt helyre.
A Bluez API-ban meg is találtam a keresett bluetooth.h, bnep.h, cmtp.h, hci.h, hci_lib.h,
hidp.h, l2cap.h, Makefile.am, rfcomm.h, sco.h, sdp.h, és sdp_lib.h fájlokat, így azonban az
ndk-build egy másik összetevő hiánya miatt nem tudta fölépíteni a programomat, nevezetesen
a libbluetooth.so fájlt kereste az
%NDK_HOME% \platforms\android-8\arch-arm\usr\lib
mappában, amelynek fölkutatása már nehezebbnek bizonyult, mint a header fájlok
megtalálása. Mivel az android operációs rendszer bluetooth támogatása igen szegényes, ezt a
fájlt sem tartalmazza az NDK, így csupán magánemberek oldalairól tölthető le. Mivel nem
létezik hivatalos verziója, tartottam tőle, hogy a benne található funkciók elavultak, nem
működnek majd, azonban szerencsére tévedtem, és a megfelelő mappába másolva az ndk-
build hiba nélkül futott le.
Ezzel a lépéssel el is érkeztem projektem egy igen izgalmas fázisához, magához a futtatáshoz,
amikor is szerettem volna viszont látni a kijelzőn a mért link quality értéket. Ehhez először
létre kellett hoznom egy példányt az Lq osztályból a kapcsolat létrehozásáért felelős
matódusomban, meg kellett hívnom a natív függvényeimet, futtatnom a programomat a
szerver és a kliens oldalon, és felépítenem egy aktív kapcsolatot.
Szerverként egy ZTE Blade típusú okostelefont használtam, kliensként pedig egy Google G1
készüléket. A kapcsolat ugyan sikeresen létrejött, azonban a log-ban egy, a natív kódban
kiíratott hibát kaptam, miszerint a ’handle’ paramétert kiszámító függvény nem futott le, és a
’socketet’ visszaadó metódus is hibát észlelt.
Hosszas próbálkozás és hasonló problémák utáni böngészés után kiderült számomra, hogy az
ilyen típusú natív kódok használatához ’rootolt’ készülék szükséges.
~ 40 ~
4.4 Rendszergazda jogok szerzése (’Rootolás’)
Alapesetben a telefonunk operációs rendeszén korlátozott felhasználók vagyunk. Ahhoz, hogy
rendszergazdai jogokat kapjunk, rootolnunk kell a telefonunkat, amely nem legális ugyan, az
okostelefonok használóinak igen nagy százaléka mégis elvégzi ezt a műveletet. Ez nem
veszélytelen, akár tönkre is teheti a telefonunkat, ugyanakkor igen sok funkció nem érhető el
nélküle.
Alapos tájékozódás után megértettem, hogy ehhez egyszerűen le kell töltenem majd futtatnom
egy alkalmazást, azonban, mint kiderült, az operációs rendszerem verziója nem volt
kompatibilis a fájllal. Igen sok oldal foglalkozott ezzel a kérdéssel, és mindenhol azt
javasolták, hogy állítsam vissza az operációs rendszerem verzióját, hogy rootolhassam a
telefonom. Ehhez mindössze le kell töltenem egy fájlt, amelyet fölmásolva a telefonban
található SD kártyára, majd a készüléket egy úgynevezett „bootloader” módban elindítva
feltelepíthetek egy új rendszert az eszközre, amelyen már probléma nélkül futtathatom a
rootolást végző alkalmazást.
A fájl letöltése, a bootloader módban való indítás és a telefon operációs rendszerének
újratelepítése után azonban a készülék csak egy adott szolgáltatónál kiváltott SIM kártyával,
egy bizonyos szolgáltatás megvásárlása után indult volna el, így a folyamat sikertelennek
bizonyult.
Ezek után szereztem egy Samsung Galaxy S típusú okostelefont, amelyet sikeresen rootoltam,
rendszergazda jogokat adtam az alkalmazásomnak, azonban a szoftverem így sem működött, a
hiba nem tűnt el.
Újfent kénytelen voltam új megoldás után nézni, azonban előbb meg kellett találnom a hiba
okát. A programkódomat elküldtem a már jól ismert segítőkész fejlesztőknek, azonban, mivel
ők még nem készítettek hasonló lekérdezéseket, nem tudták megmagyarázni a hibás működés
okát.
Miután két héten keresztül kutattam, illetve próbáltam alternatív megoldásokat találni, egy
orosz fiatalember jelezte, hogy megtalálta több hozzászólásomat az interneten, és segítséget
kért. Miután válaszoltam az általa feltett kérdésekre, szólt, hogy a kapcsolódás problémáját
minden bizonnyal csak úgy lehet elhárítani, ha magát a kapcsolat felépítést is alacsony szintű
programnyelven valósítom meg, mivel a megírt gethcisockbt metódus nem alkalmazható a
Java API-t használva létrehozott kapcsolat konnektorának kinyerésére. Kénytelen voltam tehát
magát a csatlakozást is hardware közeli nyelven, C-ben megírva, majd az Android NDK-val
felépítve (buildelve) megvalósítani, de szerencsére ebben az orosz szoftverfejlesző társam is
segítséget nyújtott.
~ 41 ~
4.5 Kapcsolat felépítése natív kóddal
Ahhoz, hogy két eszköz között aktív bluetooth kapcsolat jöhessen létre, a már előre definiált
’protokollok’ valamelyikét kell használnunk. Ahogy a számítógépek esetén, az esetleges
kapcsoódás menetét számos szabály határozhatja meg. Ebben az esetben ezeket a definíciókat
a ’Bluetooth SIG’ (Bluetooth Special Interest Group) határozta meg, amely az összes, a
bluetooth-szal kapcsolatos technológiáért felelő szervezet.
4.5.1 A használni kívánt protokoll kiválasztása:
Ezek a protokollok két csoportra oszthatók, a ’Controller stack’, amely az alacsony
szintű, az időzítésre nagyon kényes ügyekért felel, és a ’Host stack’, amely a magas
szintű adatkapcsolatokért felel.
� Controller részei:
• ACL(Asynchronous connection-oriented)
• SCO(Synchronous connection-oriented) link
• LMP(Link management protocol)
• HCI(Host/controller interface
• LELL(Low Energy Link Layer)
� Host részei:
• L2CAP(Logical link control and adaptation protocol)
• BNEP(Bluetooth network control and adaptation protocol)
• RFCOMM(Radio frequency communication)
• SDP(Service discovery protocol)
• TCP(Telephony Control protocol)
• AVCTP(Audio/visual control transport protocol)
• AVDTP(Audio/visual data transport protocol)
• OBEX(Object exchange)
• ATT(Low Energy Attribute Protocol)
• SMP(Low Energy Security Manager Protocol)
~ 42 ~
A Controller interfészt általában egy olcsó, szilikon alapú eszközre implementálják, amely
tartalmaz egy bluetooth antennát és egy mikroprocesszort. A Host interfész általában az
operációs rendszer részeként jelenik meg, vagy mint egy, a rendszerre külön telepíthető
csomag.
A fent említett protokollok közül a Controller típusúak közül ugyebár a HCI (Host/controller
interface) volt a használni kívánt definíció, azonban a Host típusúak közül nem volt
egyértelmű a választás.
Az SDP, a TCP, az AVCTP, az AVDTP, az ATT, és az SMP láthatóan nem voltak alkalmasak
az általam implementálni kívánt feladat elvégzésére, mivel ezek feltérképezték a fellelhető
eszközök szolgáltatásait, vagy hangátvitelre, zene kezelésére, eszközök párosítására
használhatók. A fennmaradó 4 protokoll közül kellett tehát kiválasztanom a leginkább a
feladatomhoz illőt.
� Az L2CAP adatcsomagokat kezel a HCI interfésszel kommunikálva ACL (Asynchronous
Connectionless) linken keresztül, és a következő funkciókkal rendelkezik:
• különböző, magasabb szintű protokollokat összekapcsolva adat multiplexálás
• csomagok darabolása és újraillesztése
• egyirányú, egyszerre több céleszközt tartalmazó (’multicast’) adatfolyam hálózat
kiépítése
• szolgáltatás minőségének (QoS – Quality of Service) szinten tartása, javítása a
magasabb szintű protokollok számára
� A BNEP az L2CAP–on keresztül továbbít hálózati csomagokat bluetooth-on keresztül.
Ezt főleg a PAN-ok (Personal Area Networking), azaz személyi hálózatok használják.
� Az RFCOMM, vagy más néven soros port emuláció (serial port emulation) is az L2CAP
fölött fut. Ez egy egyszerű, adat szállításra alkalmazott protokoll, amely egyszerre akár 60
egyidejű kapcsolatot képes kezelni. Egy egyszerű, mégis megbízható csatornát hoz létre,
többek között az OBEX is ezt használja. Igen sok alkalmazás ezt a megoldást választja,
mivel igen sok operációs rendszer támogatja és soros portokat használ.
� Az OBEX (vagy más néven IrOBEX) bináris objektumokat szállít az eszközök között.
Főleg fájl átvitelre, nyomtatásra, telefonkönyvekhez való hozzáféréshez alkalmazzák, az
RFCOMM protokoll fölötti szinten helyezkedik el.
Választásom végül az RFCOMM-ra esett, mivel kifinomultabb az alatta elhelyezkedő L2CAP
protokollnál, és az androiddal foglalkozó fórumok, illetve a megkérdezett fejlesztők
tanácsainak tanúbizonysága alapján az API-ja remekül használható, az okostelefonok a
bluetooth kapcsolatok létrehozása során is ezt használják.
~ 43 ~
4.5.2 A kapcsolódáshoz használt függvény megírása:
A protokoll kiválasztása után a kapcsolat felépítéséért felelő kódot C programnyelven kellett
megírnom. Így született meg a következő függvény:
jint Java_com_bluetooth_Lq_connect(JNIEnv* env, jobject this, jstring mac)
Ennek használatához a már megszokott módon létre kellett hoznom egy, erre a kódra
vonatkozó referenciát az Lq.java osztályomban:
public native int connect(String mac);
Látható, hogy a kapcsolat felépítéséhez mindössze egy MAC címre van szükség, eltérően a
Java API-t használó megoldásomtól, itt nincs szükség UUID-re. További előnye, hogy ebben
az esetben a céleszköznek nem kell futtatnia egy szerver-oldali, beérkező kapcsolódási
kérelmeket figyelő, és elbíráló alkalmazást, így, ha az eszközöket előzőleg párosítottuk, és a
céleszköz felderíthető, azaz ’discoverable’ üzemmódban van, a kapcsolódás sikeresen létre
fog jönni.
Magát a kódot megírni igen nehéz volt lévén, hogy kevés tapasztalattal rendelkezem a C
programozás területén, és a igen kevés segédanyag lelhető föl a témával kapcsolatban, ám
végül, a hivatalos, Linux által használt Bluez API-ban megtaláltam a függvény
megvalósításához szükséges alapvető sort:
int s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
Ebben a sorban a paraméterként beadott AF_BLUETOOTH, SOCK_STREAM és
BTPROTO_RFCOMM a Bluez API-ban deklarált és megvalósított függvények, így a
használatához már nem kellett újabb kódokat implementálnom. Ugyanakkor ezzel még csak
egy kapcsolódáshoz alkalmas konnektor (’socket’) jön létre, ezért a következő sorral még
kísérletet kell tenni magára a csatlakozásra:
status = connect(s, (struct sockaddr *)&addr, sizeof(addr));
Ez a függvény megpróbál létrehozni egy aktív bluetooth kapcsolatot adott című telefonnal, az
adott konnektoron (’socketon’) keresztül.
~ 44 ~
4.5.3 Csatlakozással kapcsolatos problémák:
Miután a függvények használatához szükséges változókat definiáltam, és az ellenőrizhetőség
végett több helyen kiírattam a program aktuális állapotait ’log’-ok használatával,
újrageneráltam az Lq.java osztályhoz tartozó header fájlt, és a fent leírt módon, az android
NDK segítségével újra felépítettem (’buildeltem’) a kódomat.
A csatlakozásért felelős .java osztályomat úgy alakítottam, hogy egy, az esetlegesen felderített
készülékhez rendelt gombot megnyomva próbáljon meg a megírt függvény használatával
kapcsolódni a céleszközhöz. Először a az újonnan megírt függvényt hívja meg, majd utána a
fennálló kapcsolatot használva hívja meg a már korábban megírt ’gethcisock’, ’handle’ és
’LinkQuality’ kódokat, azonban sajnálatos módon a tesztelés során a folyamat már a kapcsolat
létrehozásakor megszakadt, valami rosszul működött.
A következő időkben még az eddigieknél is többet böngésztem a fórumokat, számtalan levelet
írtam a felkutatott szakembereknek, melyekben megkérdeztem, hogy szerintük mi lehet a
probléma, miért nem tudok a kész kódommal kapcsolatot létrehozni. A válasz mindig ugyanaz
volt, miszerint a program elméletileg jó, nem tudják, mi lehet a baj. Mivel a programfordító
nem jelzett hibát, és futás-időben sem történt semmi abnormális, nem tudtam, mi lehet a baj.
Végül elküldtem a projektemet a már korábban említett orosz fejlesztőnek, aki annyit
válaszolt, hogy nem tudja, mi a baj, de az ő telefonján hibátlanul működik a kapcsolat
létrehozása, mi több, a link quality érték lekérdezése is. Azt tanácsolta, hogy használjam az
úgynevezett ’errno” változót a hiba megfejtésére, mivel ennek segítségével kinyerhetem az
esetlegesen felmerükő hibák kódját és leírását.
Mivel a C programnyelvet még nem sajátítottam el teljesen, először az ’errno’ fogalmát kellett
megértenem, de szerencsére az ehhez fűződő cikkek száma igen magas, így végül sokkal
egyszerűbb dolgom volt, mint általában.
Unix esetén egy függvényhívás következtében fellépő hiba esetén a legtöbb függvény (-1)
értéket térít vissza. Ilyen esetekben a hiba kódját az ’errno’ globális változó tartalmazza. Ez
azonban nem egy elfogadott szabály, hiszen egyes függvények NULL értéket adnak vissza.
Az ’errno.h’deklarációs fájlban van definiálva az ’errno’ változó, valamint azon szimbolikus
konstansok értékei, amelyeket ez a változó felvehet. Az ’errno’ nem veheti fel a 0 értéket, és a
szimbolikus konstansok között sincs 0 értékű.
Amennyiben egy függvény nem hibával zárul, az előző errno érték megmarad. A standard C
két függvényt definiál a hibaüzenetek kiírására (szöveggel történő meghatározására ). Az
egyik az strerror, amelynek alakja:
~ 45 ~
#include <string.h>
char *strerror(int nrerr);
A függvény egy pointert térít vissza a hiba szövegéhez. Az ’nrerr’ rendszerint az ’errno’
változó szokott lenni, de megadhatunk tetszőleges hibakódot is.
A másik hibaértelmező függvény a ’perror’ ennek szintaxisa:
#include <stdio.h>
void perror(const char *msg);
A függvény a standard hibacsatornára kiírja az ’msg’ szöveget, egy kettőspontot, majd az
’errno’ változó által meghatározott hibaüzenetet.
Végül a javasolt sor beillesztése után a következő hibaüzenetet kaptam:
strerror = Host is down
Ez a hibaüzenet azt jelenti, hogy az alkalmazást futtató készülék nem tud kapcsolatot létesíteni
a céleszközzel, amely valószínűleg vagy nincs a bluetooth antenna hatósugarában, vagy ki van
kapcsolva. Ezek közül természetesen egyik sem volt igaz.
Problémát okozhatott volna továbbá, ha az eszközök nem lettek volna párosítva, illetve ha úgy
próbáltam volna kapcsolatot létesíteni, hogy közben a bluetooth antenna felderítő
üzemmódban van, de ezeket a lehetőségeket is kizártam.
Tovább kerestem tehát a probléma lehetséges kiváltó okait, újra futtattam a szoftvert a
rendelkezésemre álló telefonokon, a Samsung Galaxy S-en és a ZTE Blade-en,
eredménytelenül.
4.5.4 A hiba okának fölkutatása
Mivel az orosz fejlesztő elmondása alapján az ő HTC Hero típusú okostelefonján az
alkalmazás működött, összehasonlítottam a készüléke paramétereit a saját telefonoméval, és
négy számottevő különbséget találtam.
A belső memória, a processzor, az android operációs rendszer (’Firmware’) és a bluetooth
antenna is fejlettebb az én készülékemben, mint az övében, így egyértelmű volt, hogy a
telefonom fizikailag alkalmas a program futtatására.
~ 46 ~
Samsung Galaxy S HTC Hero
belső memória 8 GB/16GB storage, 512 MB
RAM, 2GB ROM
288 MB RAM, 512 MB ROM
bluetooth antenna 2.0 verzió v3.0 verzió
operációs rendszer v2.1 (Eclair) v1.5 (Cupcake)
CPU 1 GHz ARM Cortex-A8 528 MHz ARM 11
Utánanéztem hát a különböző verziójú bluetooth adapterek közti eltéréseknek, és a
következőket találtam:
� a bluetooth 2.0 elődeihez képest jóval gyorsabbnak mondható, mivel ebben a verzióban
vezették be az EDR-t(Enchanted Data Rate), amely elméletileg 3Mbit/s, gyakorlatilag
csak körülbelül 2.1 Mbit/s adatátviteli sebességre képes. Ez a módszer elődeinél újabb jel
modulációt használ, a GFSK(Gaussian shaped Frequency Shift Keying) és a PSK (Phase
Shift Keying) egyfajta kombinációját, és, mivel az őt megelőző1.2-tes verzióhoz képest
lecsökkentette a bluetooth antenna aktív állapotának idejét, a működési periódust (’duty
cycle’), az energiafogyasztása is jóval alacsonyabb lett. Az előtte kiadott verziókkal
kompatibilis.
� a bluetooth 2.1 is kompatibilis a korábbi fejlesztésekkel, és ugyanúgy EDR technológiát
használ, mint a bluetooth 2.0. Két fő újítást vezettek be ebben a verzióban. Az SSP
(Secure Simple Pairing) megkönnyíti az eszközök párosítását, mégis jobban ügyel a
biztonságra elődeinél az EIR (Extended Inquiry Response) pedig minél több információt
kér le a felderített készülékekről, ezzel is megkönnyítve az esetleges csatlakozást.
� a bluetooth 3.0 már nem EDR-t használ, ugyanis ebben a verzióban bevezették a HS-t
(High Speed). Ebben az esetben az elméleti adatátviteli sebesség 24Mbit/s, de ez nem
magán a bluetooth konnektoron folyik, ugyanis az már csak a kapcsolat felépítéséért és
fenntartásáért felel. A nagy sebességű adatátvitel ehelyett a ’802.11’-es linken történik,
amely a verzió legnagyobb újítása az AMP (Alternate MAC/PHY) mellett, amely azért
felel, hogy az antenna csak az esetleges nagysebességű adatátvitel folyamán
fogyaszthasson sok energiát. A korábbi verziókkal kompatibilis, de a nagysebességű
adatátvitel csak olyan eszközök közt létezhet, amelyek mindketten 3.0-ás antennával
bírnak és implementálva van rajtuk a HS (High Speed) funkció.
~ 47 ~
Jól látható, hogy a bluetooth 3.0 verziója igen drasztikusan megváltoztatta az előtte kiadott
2.1-est, és habár a programom funkcionalitását konkrétan ezek az átalakítások nem érintették,
eddigi, bluetooth-szal kapcsolatos tapasztalataim alapján nem lehettem benne biztos, hogy a
HTC Hero és a Samsung Galaxy S ebbéli eltérése nem okozhatja-e az alkalmazásom hibás
működését. A két készülék nagy mértékben eltérő operációs rendszere azonban felkeltette a
figyelmemet, mivel az 1.5-tös verzióról több helyen is azt olvastam, hogy számos, a bluetooth-
szal kapcsolatos funkció nem működik kielégítően ezt a kiadást használva.
Írtam egy újabb levelet az orosz fejlesztőnek, amelyben megérdeklődtem, hogy ezt a verziót
futtatja-e a készüléke, vagy esetleg feljavította azt. Mint kiderült, ő már a 2.2-tes (Froyo)
kiadást használja.
Ekkor sikerült kipróbálnom a szoftveremet egy Samsung Galaxy 3 típusú okostelefonon,
amelyen ugyanazzal, a fent leírt hibával szembesültem, a kapcsolódás sikertelen maradt. Ez a
telefon ugyan 2.2-tes verziójú android operációs rendszert futtatott, azonban ugyanolyan
bluetooth 3.0 chip volt benne, mint a már korábban tesztelt Samsung Galaxy S-ben.
Egykori mérőtársamtól sikerült végül szereznem egy egyetemi tulajdonban lévő Motorola defy
okostelefont, amely minden szükséges kritériumnak megfelelt. 2.2-tes verziójú android
operációs rendszerrel és bluetooth 3.0-lás chippel rendelkezett, és ’rootolva’ volt. Ezt a
készüléket használva a kapcsolódás végre sikerrel járt, és a többi natív kód is hibátlanul
lefutott.
~ 48 ~
Ide kellen írni valami hurrá szöveget, sikerült összeállítani a programot, működik és
használható tehát méréssel tudjuk igazolni az eredményeket. Ebben a fejezetben a mérési
módszereket és eredményket, de lehet, hogy a 4.6 elejére is írható!
4.6 Újabb mérések
A sikeres csatlakozás érdekében az készülékeket előzőleg párosítani kellett ugyan, azonban
semmiféle szerver-oldali programfuttatására sincs szükség, így nem csak android operációs
rendszert futtató okostelefonhoz kapcsolódhatunk, hanem akármilyen, felderíthető
üzemmódba kapcsolt bluetooth chippel rendelkező eszközhöz.
Mivel a korábbi félévekben végzett mérések során a Nokia N95 mobiltelefon alkalmasnak tűnt
bluetooth alapú távolság meghatározásra, úgy döntöttem, hogy az újabb tesztelésekhez is ezt a
készüléket fogom használni.
Kezdetben szabadtéren végeztem méréseket oly módon, hogy a Motorola defy okostelefont
összekapcsoltam egy számítógéppel, így a kijelzőn nyomon tudtam követni az aktuális
eredményeket, esetleges hibákat, hiszen ezek kiíratása a telefon kijelzőjére igen bonyolult,
időigényes és kényelmetlen lett volna. A programban elhelyezett, a számítógép monitorjára
történő kiíratásokhoz a naplózás (’log’) módszert használtam a következő képpen:
import android.util.Log; Log.v("OwnLog", „kiíratandó szöveg”);
Az ’OwnLog’ szó jelöli, hogy az üzenetet én magam írattam ki, nem pedig az okostelefon
éppen futó valamely szolgáltatása, a ’kiíratandó szöveg’ pedig az üzenetet magát testesíti meg,
amely lehet egyszerű szöveg, egy, vagy több változó aktuális értéke, vagy amire éppen
szükségünk van. Ezeket a sorokat az android SDK-val együtt föltelepített ’LogCat’ virtuális
naplón keresztül tekinthetjük meg.
Ahhoz, hogy releváns eredményeket kapjak, igen sok mérést végeztem minden egyes tesztelni
kívánt távolság esetén. A Nokia N95 mobiltelefont elhelyeztem a Motorola defy
okostelefontól egy méterre majd egymás után ezerszer csatlakoztattam a két eszközt, és
megmértem a közöttük fennálló ’link quality’ értékét.
Ekkor észrevettem, hogy a mérések hibásak, hiszen igaz, hogy igen sok ’link quality’ értéket
kaptam, azonban csatlakozni csak egyszer tudtam. Rögtön rájöttem, hogy az első alkalommal
létrehozott kapcsolat sohasem szakad meg, ezért kénytelen voltam írni egy újabb függvényt,
amely bontja a kapcsolatot. Sajnos ezt is C programnyelven kellett megírnom, azonban
szerencsére gyorsan elkészültem vele, mivel ugyanazt a forrást böngészve, amelyet a ’connect’
függvény megírásakor használtam, megtaláltam az általam használni kívánt metódust, majd a
szükségleteimhez idomítva implementáltam azt.
~ 49 ~
Ekkor már a ’header’ újra generálása, és a friss projektem, android NDK-val történő
újraépítése (’buildelése’) gyorsan és gond nélkül sikerült, majd az új program okostelefonra
való telepítése után újra elkezdtem a tesztelést.
4.6.1 Kültéri mérések
Ismét ezer mérést végeztem méterenként, és habár ebből a csatlakozás nem volt
mindannyiszor sikeres, számos eredményes volt közülük. A kapott értékeket átlagoltam,
feljegyeztem, majd növeltem a távolságot, és újrakezdtem a folyamatot.
Mivel hiba esetén a natív függvények visszatérési értéke (-100), vagy (-2) volt attól függően,
hogy a ’getinfo’ vagy a ’LinkQuality’ metódus nem futott le sikeresen, ezeket az eredményeket
nem számoltam bele az átlagba. Kikísérleteztem, hogy egy 100 milliszekundumos késleltetést
elhelyezve minden mérés után az eredmények korrelációja elhanyagolható lesz, így minden
mérés függetlenként lesz kezelhető.
Méterenként haladva, húsz méteren át végeztem méréseket, amelyek eredményét mind
följegyeztem, ezeket a következő ábra (17) mutatja be.
Szemmel láthatóan az így kapott eredmények szinte távolság invariánsak, habár három és
tizennégy méter között a ’link quality’ érték szignifikáns csökkenést mutat. Szerencsére
minden távolság esetén feljegyeztem azt is, hogy ezer mérésből mennyi volt sikeres, és arra
gondoltam, talán ezt a paramétert fölhasználva a négy méternél közelebbi, illetve a tizennégy
méternél távolabbi ’link quality’ értékek is alkalmasak lehetnek távolság meghatározására. Ha
~ 50 ~
a távolság növelésével esetleg egyre kevesebbszer tudunk eredményes mérést végezni, akkor
ha esetleg száz mérésből kevés sikerül, de azok magas ’link quality’ értéket adnak, a távolság
valószínűleg nagyobb lesz tizennégy méternél.
A sikeres mérések számát a távolság függvényében a következő ábra (18) mutatja be.
Sajnálatos módon az így kapott eredmények sem használhatók föl a remélt módon, de mivel a
’link quality’ tulajdonság teljes mértékben készülékfüggő, más eszközöket is hasonló képpen
próbára kellett tennem.
Az első félév során két, teljesen eltérő karakterisztikát mutatott a Nokia N95, és a Motorola
RAZR V31 típusú mobiltelefon. Minden esetre, ha a szoftver tökéletesen használható is
valamely okostelefonon, a határok miatt, amelyeket az android operációs rendszer, a bluetooth
chip típusa és a gyártó által implementált ’link quality’ definíciója szabnak, sajnálatos módon
nem teszik lehetővé az alkalmazás platform-független használatát.
~ 51 ~
4.6.2 Beltéri mérések
A Motorola defy okostelefonnal beltéri méréseket is végeztem. Ennek eredményeit a
következő ábra (19) mutatja be.
Ebben az esetben a jel csak tíz méterig volt elég erős egy kapcsolat kiépítéséhez, és a távolság
meghatározására láthatóan még kevésbé mutatkozik alkalmasnak. Kijelenthető tehát, hogy az
általam tesztelt készülék nem alkalmas bluetooth alapú távolság meghatározásra, ebben a
formájában legalábbis.
~ 52 ~
4.7 Az alkalmazás lehetséges funkciójának tesztelése
Figyelemre méltónak találtam, hogy a bel-, és kültéri mérések során is a két méteres
távolságban, vagy annál közelebb kapott eredmények kirívóan alacsonyabbak, mint a két
méter fölött kapott értékek. Habár a kültéri teszteredményekről készült grafikon az öt, és
tizenöt méter közötti értékeket is alacsonyaknak mutatja, a részeredményeket is figyelembe
véve ez csupán a számos, igen magas mérési eredmény következménye.
Ebből következik, hogy az alkalmazásom nem végzi el ugyan a célként kitűzött feladatot,
azonban ez nem jelenti azt, hogy használhatatlan lenne. Azt nem fogja tudni ugyan megmérni,
hogy a keresett bluetooth eszköz hány méterre helyezkedik el tőlünk, azt viszont igen, hogy a
telefonunk bluetooth antennájának hatósugarában található-e, és ha igen, akkor két méteres
sugarú körön belül, vagy kívül van-e.
Ez a működés leszűkíti ugyan a szoftverem funkcionalitását, azonban önmagában még így is
egyedülálló a maga nemében lévén, hogy napjainkig nem született még használható bluetooth
alapú, távolság meghatározására alkalmas program.
Valószínűnek találom, hogy létezik olyan okostelefon, amely alkalmas arra, hogy elvégezze a
viszonylag pontos távolságbecslést, azonban ez annyira platform specifikus megoldást
igényelne, hogy fölösleges lenne egy ilyen készülék felkutatása, tesztelése és a szoftver
mögött álló esetleges adatbázis, mért értékekkel való feltöltése. Az adott sugarú körön belül
való tartózkodás problémájának eldöntése azonban megoldhatónak tűnt.
Ennek bizonyítása érdekében újabb méréseket végeztem, egytől tíz méterig növelve a
távolságot a ’Motorola defy’ okostelefon és a Nokia N95 között, minden méteren négyszer
száz tesztet végeztem beltéren, és kültéren egyaránt, tehát összesen nyolc-ezret, ezek
eredményeinek átlagait következő táblázatok mutatják.
A beltéri mérések eredményei:
1m 2m 3m 4m 5m 6m 7m 8m 9m 10m
53 95 93 89 84 118 82 100 80 101
27 82 79 87 82 126 91 113 97 71
38 89 85 74 84 123 83 117 75 106
27 79 89 89 85 119 85 102 101 94
~ 53 ~
Habár úgy tűnhet, hogy ezek az értékek teljességgel távolság invariánsak, azonban amikor
jobban megvizsgáltam az eredményeket, észrevettem, hogy a nagy számok nagy
mennyiségben csupán három méternél jelennek meg, egy és két méternél alig találhatunk
magas értéket. Míg egy száz mérésből álló sorozatban egy méternél egyáltalán nem találunk
száznál nagyobb számot, két méternél pedig maximum az eredmények harminc százaléka lépi
át ezt a határértéket, három és négy méternél átlagosan harmincöt százalékban, távolodva
pedig már ennél is nagyobb mennyiségben fordulnak elő a magas értékek.
A kültéri mérések eredményei:
1m 2m 3m 4m 5m 6m 7m 8m 9m 10m
90 98 113 112 105 119 110 89 82 82
84 96 110 108 106 109 105 95 90 84
83 93 116 108 106 107 108 102 91 86
84 89 118 104 107 102 109 98 93 93
Ebben az esetben már szemmel látható, hogy két méter fölött magasabb eredményeket kaptam,
és habár kilenc és tíz méteren ez a tendencia megszakadt, ilyen távolságban is jóval magasabb
arányban jelentek meg nagy értékek, mint az első két méter esetén.
Míg az első két oszlopban látható számokat úgy kaptam meg, hogy maximum húsz
százalékban tartalmazott száznál magasabb értékeket a sorozat, az utolsó két oszlop esetében
ez harminc-negyven százalék volt, így végre sikerült releváns eltérést találnom az adott
távolságokra jellemző bluetooth karakterisztikákban.
~ 54 ~
4.8 Következtetések
Ezen eredmények szerint ugyanaz a szoftver használható bel-, illetve kültéren, nincs szükség a
program által használt ’adatbázis’ módosítására.
Mindössze meg kellett vizsgálnom, hogy a telefon által végzett száz mérés eredményei hány
százalékban tartalmaznak száznál magasabb számot, és ha ez meghaladta az egy-ötöd arányt, a
programnak azt kellett jeleznie, hogy a két bluetooth eszköz több mint két méterre van
egymástól.
A tesztelés során megvizsgáltam ezt a funkciót egy méteren, és az esetek száz százalékában
döntött helyesen a ’Motorola defy’ készüléken futó alkalmazásom. Két méteren ez az arány
visszaesett kilencven százalékra, három és nyolc méter között azonban újra kilencven-száz
százalékban határozott helyesen a program. Kilenc és tíz méteren sajnos már csak hetven,
illetve nyolcvan százalékos pontossággal dolgozott a szoftver, ugyanakkor ez még így is
egyedülálló eredmény, nem található hasonló a piacon.
Úgy érzem, ez egy elfogadható hiba, amely egy hasonló, bizonytalan technológiával dolgozó
program esetén várható is volt, és hogy a munkám sikeresen zárult, hiszen egy olyan szoftvert
sikerült alkotnom, amelyhez hasonló eddig nem létezett.
Ugyan a bluetooth eszközöket a program futtatásához először párosítani kell, az alkalmazást
futtató okostelefonon minimum 2.2-es verziójú android operációs rendszer futhat és maximum
2.1-es bluetooth chippel rendelkezhet, de ha ezek a körülmények állnak fenn, a program
megfelelő működést produkál.
Noha a kezdetben kitűzött célt nem sikerült megvalósítanom, véleményem szerint egy igen
hasznos, a lehetőségeimhez képest robosztus és innovatív szoftvert sikerült alkotnom, amely
több készüléken is tesztelve, majd tovább fejlesztve hasznosnak bizonyulhat, és segítséget
nyújthat az esetlegesen bárki által megvalósítandó, hasonló funkciókat használni kívánó
szoftverek fejlesztése során.
A fejlesztés során többször éreztem úgy, illetve több fórumon is azt válaszolták a kérdéseimre,
hogy egy hasonló szoftver egyszerűen nem megvalósítható a bluetooth technológia
bizonytalansága miatt. Mindazonáltal az a sok segítség és támogatás, melyet a már korábban
említett fejlesztőktől, évfolyamtársaimtól, tanáraimtól és családomtól kaptam segített
megcáfolnom ezeket a cinikus hozzászólásokat.
~ 55 ~
5.fejezet
Összefoglalás
Célom egy olyan, android operációs rendszert futtató okostelefonon működő szoftver
megírása volt, amely segítségével megtalálhatjuk a pénztárcánkba, kulcscsomónkra tett
bluetooth jeladót, vagy egy mobiltelefonnal rendelkező személyt a tömegben, ha az 30-50
méteres sugarú körön belül található.
A szabad téren való helymeghatározásra már számos technológia és módszer létezik, mint a
GPS, vagy a DGPS, azonban az épületen belüli keresésre még nincs kiforrott, mindenki
számára elérhető és korszerű technológia. A távolság meghatározásához azt a tételt kívántam
fölhasználni, miszerint a kibocsátott bluetooth jel erőssége (RSSI –recieved Signal Strength) az
antennától távolodva négyzetesen csökken. Ezen állítás igazolásához mérések voltak
szükségesek, amelyek azonban nem hozták meg a várt eredményt, homogén
iránykarakterisztikájú antennáról, és távolság invariáns jelerősségről tanúskodtak.
További kutatásaink során új lehetőségre leltünk a Linq Quality tulajdonságban, amely
érzékenyen reagált a távolság növelésére, ezért kinti és benti méréseket is végeztünk, ahol egy
mobiltelefon és egy notebook között kiépített aktív bluetooth kapcsolatot teszteltük, majd ezt
megismételtük egy másik telefonnal is, mivel Link Quality számítási módja, és így a
lehetséges értékei is teljes mértékben hardware-függőek. Ezek a tesztek eredményesek voltak
annyira, hogy nekiláthassak az okostelefonra való implementációnak.
A kezdeti nehézségek után sikerült fölállítanom a megfelelő fejlesztői környezetet, így
lépésről lépésre megvalósítottam egy olyan alkalmazást, amely felderíti a környéken található,
földeríthető bluetooth állapotú készülékeket, mindegyikhez rendel egy gombot a kijelzőn,
amelyek bármelyikét megnyomva megkapjuk az adott eszköz nevét és MAC címét.
A Link Quality kinyeréséhez aktív bluetooth kapcsolatra van szükség, de mivel az android egy
igen fiatal technológia, számos funkciójának támogatása hiányos, vagy éppen hibás. Az
android alkalmazások Java nyelven készülnek, amely ugyebár a már korábban implementált
natív függvényeket használja, azonban a bluetooth megvalósítása ebben az operációs
~ 56 ~
rendszerben sajnálatos módon a projektem szempontjából használhatatlan, így magamnak
kellett megvalósítanom az általam használni kívánt függvényeket.
Erre egy alacsony szintű programozási környezetben, a C nyelven volt lehetőségem, mivel az
ily módon elkészített programokat beleágyazhattam a Java nyelven írt projektembe.
Számos akadály leküzdése után elkészült a szoftver, amely sajnálatos módon nem valósítja
meg a kezdetben célul kitűzött funkciókat. Ennek okai a Link Quality megvalósításának
készülékfüggősége, a bluetooth technológia bizonytalansága és az android operációs rendszer
mérsékelt használhatósága.
A kész alkalmazás segítségével megtudhatjuk, hogy egy adott bluetooth eszköz a mi
készülékünk antennájának hatósugarán belül van-e, és ha igen akkor két méternél, közelebb,
vagy távolabb helyezkedik el tőlünk. Bel- és kültéren egyaránt használható átlagosan 90%-os
pontossággal, így folyamatosan változtatva a pozíciónkat segíthet megtalálni a keresett jeladót,
még ha nem is képes méterre pontosan megmérni az adó tőlünk vett távolságát. Azonban
ehhez a telefonunknak számos követelménynek meg kell felelnie, amely ellehetetleníti a
program terjesztését, értékesítését.
Habár jelenleg a fent említett okok miatt a célomul kitűzött feladat nem valósítható meg, az
elkészült alkalmazásom igen hasznos lehet bárkinek, aki hasonló funkciókat kíván
megvalósítani, és mivel az android operációs rendszer és a bluetooth technológia jelenleg is
folyamatos fejlesztés alatt állnak, néhány éven belül minden bizonnyal lehetségessé válik egy
hasonló szoftver elkészítése.
~ 57 ~
Köszönetnyilvánítás
Ez úton szeretnék köszönetet mondani a konzulensemnek, Tihanyi Attilának, aki a munkám
folyamán hasznos tanácsokkal látott el, ötletei és támogatása nélkül valószínűleg már a
megvalósítás legelején elbuktam volna.
Köszönettel tartozom egykori mérőtársamnak, Solymár Zórának kitartó bíztatásáért, a
munkába fektetett idejéért és energiájáért, amely élvezetessé tette úgy az izgalmas tervezést és
lelkes kutatást, mint az unalmas, egyetemi folyosón, vagy más mérési területen eltöltött hosszú
órákat.
Szeretném továbbá hálámat kifejezni az egyetem számos segítőkész diákjának, az internetes
fórumokon megismert amatőr, vagy éppen hozzáértő programozóknak, és fent már említett
orosz, amerikai, japán és román szakembereknek, akik idejüket nem sajnálva, viszonzást sem
várva segítették munkám előre haladtát, befejezését.
~ 58 ~
Irodalomjegyzék
[1]Bluetooth SIG, Inc., "Bluetooth Basics", 2009. Elérhető:
http://www.bluetooth.com.
[2]Takács György, "Bluetooth, ZigBee, WiFi, WiMAX", digitus.itk.ppke.hu,
2009.Nov.30, Elérhető:
https://digitus.itk.ppke.hu/~takacsgy/Komea12_09.ppt
[3]Anil Madhavapeddy és Alastair Tse, A Study of Bluetooth Propagation Using
Accurate Indoor Location Mapping, Cambridge: University of Cambridge
Computer Laboratory, 2005. Elérhető:
http://anil.recoil.org/papers/2005-ubicomp-bluetooth.pdf
[4]Oliver Keiser, Philipp Sommer: Infrastructure for Bluetooth Enabled Mobile
Devices(Semester Thesis (WS 05/06)SA-2006-03), Elérhető:
ftp://ftp.tik.ee.ethz.ch/pub/students/2005-2006-Wi/SA-2006-03.pdf
[5] F. WINKLER, E. FISCHER, E. GRASS, P. LANGENDÖRFER: An Indoor
Localization System Based on DTDOA for Different Wireless LAN Systems, Elérhető:
http://www.wpnc.net/fileadmin/WPNC06/Proceedings/29_An_Indoor_Localization_System_
Based_on_DTDOA_for_Different.pdf
[6] A. K. M. Mahtab Hossain and Wee-Seng Soh: A COMPREHENSIVE STUDY OF
BLUETOOTH SIGNAL PARAMETERS FOR LOCALIZATION, Elérhető:
http://www.ece-i2r.nus.edu.sg/journal/pimrc07.pdf
[7] Mark L. Murphy: Beginning Android, Elérhető:
http://www.akae.cn/study/akaedu/android.pdf
~ 59 ~
[8] Sayed Y. Hashimi and Satya Komatineni: Pro Android ,Elérhető:
http://www.akae.cn/study/akaedu/ProAndroid.pdf