Comunicatie Intre Dispozitive Mobile Folosind Tehnologia Bluetooth
C U P R I N S
Introducere
Capitolul I. Analiza temei de proiect. Investigarea soluțiilor posibile.
Analiza cerințelor temei de proiect
Determinarea și analizarea soluțiilor posibile
2.1 Transferul de date prin cablu
Transferul de date folosind o conexiune prin IR
Transferul de date folosind rețelele de telefonie mobilă
Analizarea soluției WLAN
Transferul de date folosind tehnologia Bluetooth
Soluții posibile de realizare a unui transfer de date între dispozitive mobile sub platforma Serie 60 de la Nokia.
3.Alegerea soluției
Capitolul II. Descrierea soluției alese. Proiectul hardware
Platforma software.
Symbian OS
Cadrul în care rulează o aplicație
Tratarea excepțiilor
Modelul client/server
Platforma Serie 60
Arhitectura
Dezvoltarea aplicațiilor folosind C++
Analiza performanțelor
Proiectul hardware
Capitolul III. Structurare software
Proiectarea software
1.1 Analiza
1.2 Proiectarea sistemului
1.3 Proiectarea obiectelor
Implementarea
1.4.1 Crearea scheletului aplicației
Crearea obiectelor specifice aplicației
2. Fluxul de informație
Alocarea resurselor
Capitolul IV. Rezultate experimentale și dezvoltări viitoare
Crearea aplicației care va rula pe dispozitivele mobile
Descrierea modului de realizare a unui transfer de date
Rezultate experimentale
Oportunități de dezvoltare
Concluzii
Bibliografie
Anexa 1. Tehnologia Bluetooth
Anexa 2. Codul sursă al obiectului principal al aplicației
Anexa 3. Calcul economic
+ aplicatia
=== _bibliografie ===
B I B L I O G R A F I E
Resurse internet:
Bluetooth Core 1.2 Specification: https://www.bluetooth.org/spec/
Bluetooth Assigned Numbers: https://www.bluetooth.org/foundry/assignnumb/document/assignednumbers
Bluetooth Tehnology Overview: http://www.forum.nokia.com/tehnologies
Bluetooth SIG: http://www.bluetooth.com/
Developer Platform 2.0 for Series 60: Introduction to Designing C++ Applications http://www.forum.nokia.com/series60
Games Over Bluetooth: Recommendations to Game Developers: http://forum.nokia.com/symbian
Nokia Corporation: http://www.nokia.com/
Symbian OS: http://www.symbian.com/
Symbian Programming Tutorial Blog: http://www.sciabara.com/blog
Symbian OS: Coding Conventions in C++
Symbian OS: Getting Started with C++ Application Development:
Symbian OS: From ANSI C/C++ To Symbian C++
Symbian OS: Designing Bluetooth Applications In C++
http://www.forum.nokia.com/symbian
Series 60 Developer Platform 2.0: Getting Started with C++ Application Development.
Understanding Bluetooth: http://www.hp.com/
=== _anexa 1 – tehnologia Bletooth ===
Anexa 1 – Tehnologia Bluetooth
1. Generalități
In 1998, cinci companii importante (Ericsson, Nokia, IBM, Toshiba și Intel) au format un grup, numit Bluetooth SIG (Special Interest Group), pentru a crea o tehnologie care să nu necesite licență destinată conexiunilor universale fără fir între dispozitivele mobile. Rezultatul este Bluetooth, o tehnologie ce a luat numele regelui care în secolul al X-lea a unit triburile de războinici Vikingi. Adoptarea acestui nume reprezintă o recunoaștere a rolului deosebit pe care companiile nordice l-au avut în dezvoltarea tehnologiei Bluetooth.
Bluetooth reprezintă un standard pentru comunicații radio pe distanțe scurte. Principalele trei scopuri avute în vedere încă din faza de proiectare sunt: dimensiune redusă, consum minim, preț scăzut. Tehnologia a fost proiectată pentru a fi simplă și pentru a deveni un standard de facto in conexiunile fără fir.
2. Specificațiile Bluetooth
Primele specificații referitoare la Bluetooth au apărut în februarie 2001 sub denumirea de Bluetooth 1.1 Specification. A urmat apoi în 2003 Bluetooth 1.2 Specification. Specificațiile sunt compuse din două părți: nucleul și profilele.
2.1 Specificațiile nucleului
Specificațiile nucleului definesc toate nivelele din stiva protocolului Bluetooth (figura 13). Stiva protocolului Bluetooth diferă în anumite privințe de modelul clasic, OSI. Aceste diferențe provin in principal din condiția impusă Bluetooth-ului de a suporta conectivitate ad-hoc între nodurile participante la care se adaugă cerința de consum redus și necesitatea implementării protocolului pe dispozitive care au resurse limitate, dispozitive pe care nu s-ar putea implementa modelul OSI.
figura 13.- Stiva protocolului Bluetooth și structura chip-ului Bluetooth
Nivelul radio (RF) se află la baza stivei. Specificațiile interfeței sale definesc caracteristicile transmisiunii radio, banda de frecvență, structura canalelor, nivelele admise ale puterii de emisie și nivelul de sensibilitate al receptorului.
Al doilea nivel este baseband. Acest nivel se ocupă cu partea fizică a Bluetooth-ului (PHY) și controlul accesului la mediu (MAC). Acestea implică sarcini cum ar fi descoperirea dispozitivelor (device discovery), formarea legăturii, comunicație sincronă sau asincronă cu dispozitivele conectate.
Dispozitivele conectate trebuie să schimbe între ele unele mesaje de control pentru configurarea și managementul conexiunilor. Structura acestor mesaje este definită la nivelul link manager protocol (LMP). Entitatea funcționala care are rolul de a îndeplini funcțiile acestui nivel se numește managerul legăturii (link manager).
Un aspect care conferă unicitate Bluetooth-ului îl reprezintă integrarea într-un singur chip Bluetooth a parții radio și a parții de control. Un chip bluetooth poate fi conectat cu procesorul dispozitivului gazdă folosind ca interfețe USB, UART sau un PC-card. In specificațiile nivelului controler interfață cu dispozitivul gazdă (Host Controller Interface – HCI) se definește o metoda de interfațare independentă pentru comunicarea cu chip-ul Bluetooth. Procesorul dispozitivului gazdă comunică cu modulul Bluetooth folosind comenzi HCI. Nivelul HCI este parte a stivei Bluetooth dar nu constituie un nivel de comunicație peer-to-peer, cu un alt dispozitiv Bluetooth, din moment ce comenzile HCI și mesajele de răspuns nu folosesc legătura radio.
Nivelul de control al legăturii logice și protocolul de adaptare (logical link control and adaptation protocol – L2CAP) poate fi considerat ca fiind Link layer-ul pentru Bluetooth. Acest nivel se ocupă de multiplexarea, reasamblarea și segmentarea pachetelor. In mod uzual nivelul L2CAP și nivelele superioare sunt implementate software. L2CAP livrează pachetele recepționate de la nivelele superioare către destinatar. Dispozitivele Bluetooth pot stabili o legătură L2CAP de îndată ce sunt unul în raza celuilalt. Un dispozitiv client trebuie să descopere mai întâi serviciile oferite de un dispozitiv server.
Nivelul protocolului de descoperire a serviciilor (Service discovery protocol – SDP) definește mijloacele prin care dispozitivul client poate descoperi atât serviciile oferite cât și atributele serviciilor. Design-ul nivelului SDP a fost optimizat pentru Bluetooth. Acesta definește doar mecanismul de descoperire, neincluzând metodele de accesare a acestor servicii.
Specificațiile nivelului RFCOMM definesc o metoda de emulare a conexiunii prin cablu RS-232 peste legătura radio Bluetooth. RFCOMM suportă aplicații derivate din aplicațiile care utilizau portul COM pentru a realiza comunicații peer-to-peer (de exemplu protocoalele point-to-point – PPP, inclusiv TCP/IP) .
Legătura radio
Bluetooth-ul operează în banda ISM la 2,4 GHz. Majoritatea țărilor alocă o lățime de bandă de 83,5 MHz (excepție face Japonia). In interiorul acestei benzi sunt definite 79 de canale radio (23 de canale în Japonia) distanțate la 1 MHz. In prezent se fac eforturi pentru a alinia toate țările la această definire a benzii pentru Bluetooth astfel încât tehnologia să poată deveni una globală.
Bluetooth este un sistem care folosește tehnica spectrului împrăștiat cu salt în frecvență. Aceasta înseamnă că purtătoarea face salturi în frecvență acoperind întreg spectrul de 79 de canale, folosind o secvență de salt pseudo-aleatoare. Rata uzuală a salturilor, 1600 salturi pe secundă, asigură o foarte buna protecție la interferențe în banda de 2,4 GHz.
figura 14.- Exemplificarea unei transmisiuni cu salt în frecvență
Un alt avantaj al salturilor rapide în frecvență îl reprezintă lungimea mică a pachetelor de date. Astfel daca un pachet nu este recepționat corect de un dispozitiv se solicită retransmisia pachetului. Cu siguranță retransmisia se va face pe o altă frecvență, în funcție de secvența de salt stabilită. Acest caz este ilustrat în figura 14, unde pachetele dispozitivului 1 (căsuțele roșii) și pachetele dispozitivului 2 (căsuțele verzi) folosesc la anumite momente de timp aceeași frecvență, rezultând coliziuni. Această situație poate să apară și atunci când un dispozitiv non-Bluetooth folosește o parte din banda alocată Bluetooth-ului.
figura 15.- Exemple de pachete de date transmise pe unul, trei sau cinci sloturi temporale.
Intervalul de comutare de 220μs care succede pachetele este necesar efectuării saltului în frecvență. Pentru emisie și recepție se folosesc sloturi temporare succesive. Lungimea nominală a unui slot este de 625μs. In mod normal un pachet de date ocupă un singur slot dar poate ocupa și trei sau cinci sloturi, ca în figura 7. In cazul pachetelor multi-slot frecvența de emisie ramane aceeași până când întregul pachet este transmis. Când se utilizează pachete multi-slot rata de bit este mai mare deoarece este nevoie doar de un singur header și un singur interval de comutare de 220μs (switching time) în fiecare pachet. Pe de altă parte, scade robustețea deoarece într-un spectru aglomerat pachetele lungi se pot transmite cu erori.
Viteza legăturii, de 1Mbps, poate fi ușor atinsă folosind o modulație GFSK. O tehnică de modulație mai complexă ar conduce la atingerea unor rate de bit mai ridicate dar ar complica structura părții radio a Bluetooth-ului și implicit ar crește costurile de producție.
In general partea radio este cel mai costisitor element al interfeței cu o rețea wireless. In receptoarele radio tipice filtrele, oscilatoarele si mixerele procesează semnalul de intrare la frecvență înaltă. Asemenea circuite sunt costisitoare. Pentru a reduce costurile specificațiile Bluetooth recomandă trecerea semnalului de intrare pe o frecvență intermediară mai mică (aproximativ 3 MHz), frecvență care permite realizarea unor filtre integrate folosind tehnologia CMOS. Trecerea pe o frecvență intermediară mai mică creează însă alte probleme cum ar fi reducerea sensibilității receptorului. Sensibilitatea recomandată a receptorului Bluetooth este de minim –70dB.
2.1.2 Rețele de tip piconet și scatternet
Un grup de dispozitive Bluetooth care folosesc același canal pentru a comunica între ele poartă numele de piconet. Așa cum se observă în figura 16b un piconet este o rețea cu o configurație de tip stea. Dispozitivul central are rolul de master celelalte dispozitive funcționează ca slave (sclav). Un rol important al master-ului este acela de a stabili secvența de salt în frecvență. Această secvență se stabilește pseudo-aleatoriu, în principiu pornind de la numărul care reprezintă adresa masterului și de la un alt număr generat aleatoriu de către master. Toate dispozitivele slave din fiecare piconet sunt sincronizate cu ceasul master-ului și urmează schema de salt stabilită de acesta. Un master poate deservi simultan maxim șapte sclavi activi. Astfel o rețea de tip piconet poate fi formată din două, trei, până la opt dispozitive (figura 16a,b) din care unul singur poate fi master. Dispozitivele slave nu pot comunica direct între ele, ci doar cu masterul. Masterul poate comunica cu oricare dintre sclavi.
O rețea de tip scatternet poate fi formată prin conexiunea a două sau mai multe rețele tip piconet.(figura 16c). Atunci când un dispozitiv face parte din mai multe piconet-uri el va trebui să se sincronizeze, de fiecare dată, cu piconet-ul cu care comunică la un anumit moment. Un dispozitiv poate fi sclav în două piconet-uri diferite sau master într-un piconet și sclav în altul dar nu poate fi master pentru mai mult de un piconet.
O caracteristică proprie rețelelor Bluetooth este dinamismul. Rețelele Bluetooth sunt rețele ad-hoc, care se formează, se modifică și se dizolvă permanent
figura 16. – Exemple de rețele de tip piconet și scatternet
piconet format din două dispozitive
piconet format din mai multe dispozitive
scatternet constituit din trei piconet-uri
2.1.3 Procedura de căutare de dispozitive (inquiry) și cererea de conectare (paging)
Conectarea cu un anumit dispozitiv se realizează prin intermediul unui mesaj de tip page. Pentru a trimite un mesaj page (procedură numită paging) masterul trebuie să cunoască adresa sclavului către care face cererea de conectare. Această adresă se obține cu ajutorul unui mesaj de tip inquiry.
Starea implicită a unui dispozitiv Bluetooth este numită standby mode. In această stare dispozitivul ascultă la intervale de 1,28 secunde eventualele mesaje inqury sau page. De fiecare dată sunt ascultate pe rând 32 de frecvențe pe care este posibil să se primească unul din mesajele amintite anterior.
Prin mesajul inquiry masterul trimite un cod numit inquiry access code. Celelalte dispozitive răspund trimițând informații despre identitatea lor și despre ceasul propriu. După aceasta urmează o procedură de căutare de servicii utilizată pentru a determina ce fel de servicii oferă fiecare dispozitiv prezent în raza masterului.
In timpul procedurii de paging, pe baza informației despre identitatea și ceasul fiecărui dispozitiv masterul determină și trimite sub forma mesajului page un cod de acces și o secvență de activare a sclavului (wake-up sequence). Un astfel de mesaj va fi trimis de master pe cele 32 de frecvențe destinate acestei proceduri astfel: inițial mesajul este transmis pe primele 16 frecvențe de 128 de ori iar dacă nu se primește nici un răspuns se continuă transmiterea mesajului pe celelalte 16 frecvențe tot de 128 de ori. Timpul maxim de așteptare a răspunsului la mesaj este de 2,56 secunde.
In urma procedurilor inquiry și page se realizează conexiunea între master și sclavi (figura 17).
figura 17. – Procedurile inquiry și page duc la stabilirea unei conexiuni
2.1.4 Transferul de date. Canalul piconet
Imediat ce s-a format o rețea de tip piconet, comunicația între master și sclav(i) poate începe. Canalul comun pe care se face comunicația se numește canalul piconet. Acest canal este împărțit în intervale de timp de câte 625μs, fiecare slot folosind o altă frecvență de transmisie. Canalul este partajat între master și sclavi folosind o schemă de tipul salt în frecvență/divizare duplex în timp (frequency-hop/time-division-duplex FH/TDD) în care comunicația în sensul master-slave și slave-master se desfășoară pe rând. Pentru transferul de date pe un canal piconet se pot defini două tipuri de legături: legătură asincronă (Asynchronous Connectionless Link – ACL) sau legătură sincronă (Synchronous Connection Oriented Link – SCO). Legătura de tip ACL este cu comutare de pachete și, desigur, se folosește pentru transmisia datelor sub forma de pachete. Debitul maxim pentru această legătură, folosind pachete multislot, este de 723 kbps într-un sens de transmisie și 57,6 kbps în celălalt sens, masterul fiind cel care controlează viteza de transmisie pe fiecare sens. Pentru conexiuni punct la punct, simetrice, cu comutare de circuite, se folosește legătura SCO (uzual pentru transmisia de voce). Debitul pentru această legătură este de 64 kbps.
Cel mai adesea datele sunt trimise sub formă de pachete (figura 18). Un astfel de pachet poate să aibă o lungime de 1, 3 sau 5 sloturi temporale. Fiecare pachet este compus din trei părți: codul de acces (access code), header-ul și datele utile (payload). Partea care conține datele utile poate avea între 0 și 2745 biți. Sunt admise și pachete de control care să fie compuse doar din codul de acces sau doar din codul de acces și header.
Codul de acces conține informații referitoare la destinatarul pachetului iar headerul conține informații referitoare la pachet (tipul pachetului, sursa, corecția erorilor, etc).
figura 18. – formatul unui pachet standard.
2.2 Specificațiile profilelor
Producătorii pot folosi serviciile oferite de stiva Bluetooth pentru a crea o varietate de aplicații. Deoarece interoperatibilitatea este crucială pentru funcționarea Bluetooth-ului, Bluetooth SIG a elaborat specificațiile profilelor. Profilele reprezintă modele de utilizare a tehnologiei Bluetooth. Acestea descriu principalele aplicații Bluetooth și dispozitivele cărora la sunt adresate.
Profilele definesc protocoalele care suporta un anumit model de utilizare. Unele profile se pot baza pe altele, între ele existând o relație de interdependență. (figura 19). De exemplu trei profile (File Transfer Profile, Object Push Profile și Synchronization Profile) sunt definite pe baza Generic Object Exchange Profile.
Aparatele Bluetooth implementează diferite seturi de profile. Pentru ca un dispozitiv să suporte un anumit profil acesta trebuie implementeze trăsăturile obligatorii ale profilului respectiv .
figura 19. – Relațiile de interdependență dintre profilele Bluetooth
Conform specificațiilor Bluetooth profilele se pot grupa astfel: profile generale, profile orientate pe model de utilizare și profile adiționale. In continuare se va prezenta fiecare grupă de profile.
2.2.1 Profilele generale
Generic Access Profile definește procedurile generale legate de descoperirea dispozitivelor Bluetooth (procedurile idle mode) și aspecte legate de managementul legăturii și conectarea dispozitivelor Bluetooth (procedurile connecting mode). Tot în acest profil sunt definite procedurile legate de diferitele nivele de securitate. Mai mult, acest profil include formatul uzual al cererilor pentru parametrii accesibili nivelului interfață utilizator. Toate dispozitivele Bluetooth trebuie să suporte acest profil.
Service Discovery Application Profile definește trăsăturile si procedurile unei aplicații ce rulează pe un device Bluetooth, necesare pentru a descoperi serviciile oferite de un alt dispozitiv Bluetooth.
Serial Port Profile definește caracteristicile obligatorii pentru dispozitivele Bluetooth, necesare pentru a putea emula conexiuni seriale peer-to-peer prin cablu, folosind nivelul RFCOMM.
Generic Object Exchange Profile specifică protocoalele și procedurile care vor fi folosite de aplicații care presupun schimbul de obiecte.
2.2.2 Profile orientate pe model de utilizare
Cordless Telephony Profile și Intercom Profile definesc caracteristicile și procedurile obligatorii pentru interoperabilitatea dintre unitățile active în modul de utilizare „three-in-one phone” (același telefon poate fi folosit ca telefon fix fără fir, walkie-talkie și telefon celular). Cordless Telephony Profile este folosit când telefonul este conectat prin Bluetooth la o stație de bază pentru telefonia fixă (cazul telefoanelor fixe cordless). Intercom Profile implementează modul de folosire „walkie-talkie” între două telefoane fixe echipate cu module Bluetooth.
Dial-up Networking Profile descrie cum se poate folosi un telefon celular sau un modem wireless, împreună cu un PC, pentru a realiza transferuri de date prin conectarea la un server pentru accesul dial-up la Internet sau pentru alte servicii dial-up.
Fax Profile descrie modul în care un PC poate folosi un telefon celular ca modem wireless pentru fax. Astfel se pot trimite și recepționa fax-uri direct pe computer.
Headset Profile stabilește cerințele necesare pentru ca dispozitivele Bluetooth să suporte atașarea unui dispozitiv de tip hands-free fără fir. Aceste dispozitive pot fi utile în cazul telefoanelor mobile, PDA-urilor și al laptop-urilor.
LAN Access Profile stabilește cum pot accesa dispozitivele echipate cu Bluetooth o rețea de tip LAN folosind PPP (Point-to-Point Protocol) bazat pe RFCOMM (protocol Bluetooth care emulează interfața RS-232). Tot aici se specifică cum poate fi utilizat același mecanism PPP, pentru a crea o rețea formată din două aparate echipate cu module Bluetooth.
File Transfer Profile stabilește cadrul care îi permite unui utilizator să caute și să editeze obiecte (fișiere și dosare) localizate pe un alt dispozitiv Bluetooth și sa transfere obiecte între cele două dispozitive. Cele mai folosite dispozitive pentru astfel de operațiuni sunt PC-urile, notebook-urile și PDA-urile.
Object Push Profile furnizează descrieri ale mijloacelor prin care utilizatorii pot trimite, primi sau face schimb de obiecte simple, de exemplu cazul schimbului de cărți de vizită între laptop-uri, PDA-uri sau telefoane mobile.
Synchronization Profile specifică modalitățile prin care se poate realiza sincronizarea automată a datelor (de obicei a notelor din agendă) atunci când un dispozitiv intră în raza de acoperire a unui PC dotat cu placă Bluetooth.
2.2.3 Profile adiționale
Inițial în specificațiile Bluetooth s-au definit treisprezece profile, descrise anterior. Pentru a garanta interoperabilitatea în cazul unei arii lărgite de aplicații, grupul de lucru Bluetooth SIG a specificat noi profile, definite separat, după cum urmează:
Generic Audio/Video Distribution Profile (GAVDP) definește un grup generic de protocoale și proceduri cu rolul de a distribui informație audio/video folosind canale ACL.
Advanced Audio Distribution Profile (A2DP) definește distribuția de informație audio/video de înaltă calitate mono sau stereo pe canale ACL. A2DP se bazează pe GAVDP.
Audio/Video Remote Control Profile (AVRCP) definește transmisia unui semnal A/V de control, activat de utilizator, către un dispozitiv Bluetooth.
Basic Imaging Profile (BIP) este un profil bazat pe OBEX care permite dispozitivelor să negocieze dimensiunea și tipul codării datelor de tip imagine care sunt schimbate.
Basic Printing Profile (BPP) este un profil bazat pe OBEX care permite printarea mail-urilor, mesajelor sau a unor documente direct de pe dispozitivele mobile.
Hardcopy Cable Replacement Profile (HCRP) este un profil ușor de implementat pentru printarea și scanarea oricărui tip de document. HCRP este implementat direct peste L2CAP evitând supraîncărcarea cu OBEX sau RFCOMM.
Bluetooth Extended Service Discovery Profile (ESDP) for Universal Plug and PlayTM (UPnPTM) este un profil destinat descoperirii altor dispozitive care suportă servicii UPnP și recepționării informațiilor despre aceste servicii.
Hands-Free Profile (HFP) definește cazul când un mobil poate fi folosit împreună cu un dispozitiv de tip hands-free. HPF asigură mijloacele realizării legăturilor de voce și de control între cele două dispozitive.
Human Interface Device Profile (HID), stabilește cadrul de utilizare a tastaturilor Bluetooth, a dispozitivelor destinate jocurilor (de exemplu un joystick wireless) și a dispozitivelor de monitorizare la distanță.
Common ISDN Access Profile definește modul în care aplicațiile pot accesa ISDN prin Bluetooth.
Personal Area Networking Profile (PAN) definește rețelele personale bazate pe IP. Acest protocol asigură suport și pentru punctele de acces ale rețelei (de exemplu LAN sau GSM).
SIM Access Profile (SAP) definește modalitatea în care poate fi accesată o cartelă SIM prin intermediul unei legături Bluetooth.
3. Securitatea unei conexiuni Bluetooth
Sistemul de securitate al tehnologiei Bluetooth include atât autentificare cât și confidențialitate și are la bază algoritmul de criptare SAFER+. La origini acesta este un cifru bloc dar în cazul Bluetooth-ului este implementat ca cifru stream. Versiunea pe 128 de biți folosită de Bluetooth este considerată ca fiind foarte solidă.
Există patru metode pentru a asigura securitatea unei legături Bluetooth:
Autentificarea, prin care se verifică identitatea fiecărui dispozitiv din rețea;
Pairing, este o procedura prin care se autentifică două dispozitive, bazată pe stabilirea de comun acord a unei parole care se introduce de către utilizatorii ambelor dispozitive. In urma procedurii de pairing cele două dispozitive apar unul celuilalt ca fiind sigur (trusted). Procedura de pairing pentru două dispozitive se realizează o singură dată, nefiind necesară la următoarele conexiuni între cele două dispozitive.
Autorizarea, este procesul prin care se decide care dispozitiv din raza de acoperire are sau nu voie să acceseze un anumit serviciu.
Criptarea, asigură confidențialitatea datelor trimise. Se folosește o cheie cu lungimea între 8 și 128 biți.
Prin aplicație, se poate specifica care dintre metodele de securitate se aplică unei anumite legături.
=== _anexa 2- engine ===
Anexa 2 – Codul sursă al obiectului principal al aplicației
/*
* ============================================================================
* Nume fisier : BluetoothPMPExampleEngine.cpp
* Nume proiect : Bluetooth piconet example
* Dezvoltat de : Marius Alexandru
* Nota :Continut initial generat de Series 60 AppWizard (codul scris cursiv).
* ============================================================================
*/
// INCLUDE
#include <aknquerydialog.h> // pentru dialogul prin care se introduce textul de trimis
#include <utf.h> //contine descriptorii de text
#include <BluetoothPMPExample.rsg>
#include "Common.h"
#include "BluetoothPMPExampleEngine.h"
#include "DeviceDiscoverer.h"
#include "ServiceAdvertiser.h"
#include "ServiceDiscoverer.h"
#include "Listener.h"
#include "Connector.h"
#include <cntdb.h> //util pt lucrul cu contacte
#include <cntitem.h>
CBluetoothPMPExampleEngine* CBluetoothPMPExampleEngine::NewL(
CBluetoothPMPExampleAppUi* aAppUi)
{
CBluetoothPMPExampleEngine* self =
CBluetoothPMPExampleEngine::NewLC(aAppUi);
CleanupStack::Pop(self);
return self;
}
CBluetoothPMPExampleEngine* CBluetoothPMPExampleEngine::NewLC(
CBluetoothPMPExampleAppUi* aAppUi)
{
CBluetoothPMPExampleEngine* self =
new (ELeave) CBluetoothPMPExampleEngine(aAppUi);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
// constructor standard EPOC, faza a doua
void CBluetoothPMPExampleEngine::ConstructL()
{
// se creaza o sesiune de lucru cu socket server-ul
User::LeaveIfError(iSocketServ.Connect());
// initializare listener
iListener = CListener::NewL(this, &iSocketServ);
// initializare device discoverer
iDeviceDiscoverer = CDeviceDiscoverer::NewL(&iSocketServ, this);
// initializare service advertiser
iServiceAdvertiser = CServiceAdvertiser::NewL();
// initializare service discoverer
iServiceDiscoverer = CServiceDiscoverer::NewL(this);
// se "goleste" tabela de conexiuni
for ( TInt idx=0; idx<KMaxConnectedDevices; idx++ )
{
iConnectedDevices[idx] = NULL;
}
}
// –––––––––––––––––––––––––-
// CBluetoothPMPExampleEngine::CBluetoothPMPExampleEngine(
// CBluetoothPMPExampleAppUi* aAppUi)
// constructorul
// –––––––––––––––––––––––––-
CBluetoothPMPExampleEngine::CBluetoothPMPExampleEngine(
CBluetoothPMPExampleAppUi* aAppUi):
iListener(NULL),
iDeviceDiscoverer(NULL),
iServiceAdvertiser(NULL),
iServiceDiscoverer(NULL),
iIsSlave(EFalse),
iMsgLines(0),
iConnectedDeviceCount(0)
{
iAppUi=aAppUi;
}
// –––––––––––––––––––––––––-
// CBluetoothPMPExampleEngine::~CBluetoothPMPExampleEngine()
// destructorul
// –––––––––––––––––––––––––-
CBluetoothPMPExampleEngine::~CBluetoothPMPExampleEngine()
{
// deconecteaza toate dispozitivele si sterge tabela de conexiuni
DisconnectDevicesL();
// se opresc si se distrug obiectele ajutatoare
delete iServiceAdvertiser;
iServiceAdvertiser=NULL;
delete iListener;
iListener=NULL;
delete iServiceDiscoverer;
iServiceDiscoverer=NULL;
iSocketServ.Close();
// stergere lista cu date despre dispozitive
iDevDataList.ResetAndDestroy();
}
// –––––––––––––––––––––––––-
// ShowMessageL(
// const TDesC& aMsg, TBool aReset=false)
// afiseaza un text referentiat de aMsg. Textul se va adauga la mesajul deja existent
// pe ecran daca aReset este false,in caz contrar se va sterge mai intai ceea ce era afisat inainte
// –––––––––––––––––––––––––-
void CBluetoothPMPExampleEngine::ShowMessageL(const TDesC& aMsg,
TBool aReset=false)
{
// daca aReset==true sau sunt deja afisate 8 linii pe display
// mai intai se sterge ce este afisat
if (aReset || iMsgLines>8)
{
iMsg.Zero();
iMsgLines=0;
}
iMsg.Append(aMsg);
iAppUi->iAppContainer->ShowMessageL(iMsg);
iMsgLines++;
}
// –––––––––––––––––––––––––-
// CBluetoothPMPExampleEngine::DiscoverDevicesL()
// descopera dispozitivele Bluetooth din raza
// –––––––––––––––––––––––––-
void CBluetoothPMPExampleEngine::DiscoverDevicesL()
{
ShowMessageL(_L("Cautare dispozitive\nasteptati…\n"), true);
iDeviceDiscoverer->DiscoverDevicesL(&iDevDataList);
}
// –––––––––––––––––––––––––-
// CBluetoothPMPExampleEngine::DiscoverServicesL()
// descopera serviciile oferite de dispozitivele descoperite anterior
// –––––––––––––––––––––––––-
void CBluetoothPMPExampleEngine::DiscoverServicesL()
{
ShowMessageL(_L("Cautare servicii\nasteptati…\n"), true);
iServiceDiscoverer->DiscoverServicesL(&iDevDataList);
}
// –––––––––––––––––––––––––-
// CBluetoothPMPExampleEngine::StartSlaveL()
// seteaza aplicatia sa ruleze in modul sclav. dispozitivul va face public serviciul
// oferit pe un anumit canal si va asculta cererile care vin pe acel canal.
// –––––––––––––––––––––––––-
void CBluetoothPMPExampleEngine::StartSlaveL()
{
if ( iIsSlave )
return;
ShowMessageL(_L("Initializare sclav…"), true);
TInt channel;
channel = iListener->StartListenerL();
TBuf<30> msg;
msg.AppendFormat(_L("\nCanal folosit: %d"), channel);
ShowMessageL(msg, false);
iServiceAdvertiser->StartAdvertiserL(channel);
ShowMessageL(_L("\nInitializat sclav!\nAstept cereri conectare"), false);
iIsSlave=ETrue;
}
// –––––––––––––––––––––––––-
// CBluetoothPMPExampleEngine::DisconnectDevicesL()
// deconecteaza dispozitivele conectate si sterge tabela de conexiuni
// –––––––––––––––––––––––––-
void CBluetoothPMPExampleEngine::DisconnectDevicesL()
{
for ( TInt idx=0; idx<KMaxConnectedDevices; idx++ )
{
if ( iConnectedDevices[idx] != NULL)
{
delete iConnectedDevices[idx];
iConnectedDevices[idx]=NULL;
}
}
}
// –––––––––––––––––––––––––-
// CBluetoothPMPExampleEngine::ConnectDevicesL()
// incearca sa se conecteze cu toate dispozitivele compatibile
// –––––––––––––––––––––––––-
void CBluetoothPMPExampleEngine::ConnectDevicesL()
{
// inchide si sterge din tabela conexiunile existente
DisconnectDevicesL();
ShowMessageL(_L("Conectare sclav(i)…\n"), true);
// incercarea de conectare
CConnector *connector = NULL;
for ( TInt idx=0; idx<(iDevDataList.Count()); idx++ )
{
if ( iConnectedDeviceCount>=KMaxConnectedDevices )
return;
TDeviceData *dev = iDevDataList[idx];
connector = CConnector::NewL(this, &iSocketServ);
// daca a fost gasit serviciul dorit pe dispozitivul departat, si portul este
// setat si > 0, se poate incerca conectarea.
if ( dev->iDeviceServicePort>0 )
{
if ( (connector->ConnectL(dev->iDeviceName,
dev->iDeviceAddr,
dev->iDeviceServicePort))==KErrNone )
{
iConnectedDevices[iConnectedDeviceCount] = connector;
iConnectedDeviceCount++;
}
else
{
// incercarea de conectare a esuat
delete connector;
}
}
}
ShowConnectedDevicesL();
}
// –––––––––––––––––––––––––-
// CBluetoothPMPExampleEngine::ShowConnectedDevicesL()
// afiseaza dispozitivele cu care au fost stabilite conexiuni
// –––––––––––––––––––––––––-
void CBluetoothPMPExampleEngine::ShowConnectedDevicesL()
{
TInt count=0;
ShowMessageL(_L("Dispoz. sclav conectate:\n"), true);
for (TInt idx=0; idx<KMaxConnectedDevices; idx++)
{
if ( iConnectedDevices[idx]!=NULL )
{
THostName name;
name = iConnectedDevices[idx]->iName;
name.Append(_L("\n"));
ShowMessageL(name, false);
count++;
}
}
if ( count==0 )
{
// nu exista conexiuni
// deoarece nu a fost descoperit nici un dispozitiv
// sau nici un dispozitiv nu ofera serviciul dorit de master.
ShowMessageL(_L("Nu exista conexiuni!"), false);
}
}
// –––––––––––––––––––––––––-
// CBluetoothPMPExampleEngine::SendMessage()
// trimite un mesaj introdus de utilizator tuturor dispozitivelor conectate.
// mesajul va avea maxim 20 de caractere.
// –––––––––––––––––––––––––-
void CBluetoothPMPExampleEngine::SendMessage()
{
// fereastra pentru introducerea textului
TBuf<20> msgtext;
CAknTextQueryDialog * dlg = CAknTextQueryDialog::NewL(msgtext);
dlg->SetMaxLength(20);
dlg->SetPromptL(_L("text"));
dlg->ExecuteLD(R_BLUETOOTHEXAMPLE_MESSAGEINPUT);
// conversie explicita de la caractere pe 16bit la caractere pe 8bit
TBuf8<20> buf;
TPtr8 msgtext8((TUint8*)buf.Ptr(), msgtext.Size());
CnvUtfConverter::ConvertFromUnicodeToUtf8(msgtext8, msgtext);
TBuf<80> msg;
if ( iIsSlave )
{
// sclavul trimite date
iListener->SendDataL(msgtext8);
msg.Format(_L("> %S\n"), &msgtext);
ShowMessageL(msg, false);
}
else
{
// masterul trimite date
for (TInt idx=0; idx<KMaxConnectedDevices; idx++)
{
if ( iConnectedDevices[idx]!=NULL )
{
iConnectedDevices[idx]->SendDataL(msgtext8);
THostName name;
name=iConnectedDevices[idx]->iName;
msg.Format(_L("> %S: %S\n"), &name, &msgtext);
ShowMessageL(msg, false);
}
}
}
}
// –––––––––––––––––––––––––-
// CBluetoothPMPExampleEngine::SendObject()
// trimite un obiect (demonstrativ) tuturor dispoziitvelor conectate
// acest obiect ar putea fi o cate de vizita
// –––––––––––––––––––––––––-
void CBluetoothPMPExampleEngine::SendObject()
{
//crearea obiectului – aici un obiect simplu, un text
TBuf<20> object=_L("*un obiect*\n");
TBuf8<20> buf;
TPtr8 object8((TUint8*)buf.Ptr(), object.Size());
CnvUtfConverter::ConvertFromUnicodeToUtf8(object8, object);
/*
//exemplu de creare a unui obiect care sa contina o carte de vizita
//deschidere "default contact database"
CContactDatabase* contactDB=CContactDatabase::OpenL();
CleanupStack::PushL(contactDB);
//pregatire citire contact
TBuf<256> contactTxt;
CContactIdArray* iContacts;
iContacts=NULL;
TInt anIndex=1;
CContactTextDef* iTextDef;
iTextDef=CContactTextDef::NewL();
iTextDef->AppendL(TContactTextDefItem(KUidContactFieldGivenName,_L("\n")));
//citire contact
contactDB->ReadContactTextDefL((*iContacts)[anIndex], contactTxt, iTextDef);
//conversie contact pentru trimitere
TBuf8<512> buffer;
TPtr8 contactTxt8((TUint8*)buffer.Ptr(), contactTxt.Size());
CnvUtfConverter::ConvertFromUnicodeToUtf8(contactTxt8, contactTxt);
CleanupStack::PopAndDestroy();
*/
if ( iIsSlave )
{
// sclavul trimite obiect
iListener->SendDataL(object8);
// eventual //iListener->SendDataL(contactTxt8);
ShowMessageL(_L("Obiect trimis!\n"), false);
}
else
{
// masterul trimite obiect
for (TInt idx=0; idx<KMaxConnectedDevices; idx++)
{
if ( iConnectedDevices[idx]!=NULL )
{
iConnectedDevices[idx]->SendDataL(object8);
//eventual //iConnectedDevices[idx]->SendDataL(contactTxt8);
THostName name;
name=iConnectedDevices[idx]->iName;
TBuf<20> txt=_L("Ob. trimis catre:");
TBuf<80> scrmsg;
scrmsg.Format(_L(" %S %S\n"), &txt, &name);
ShowMessageL(scrmsg, false);
}
}
}
}
// –––––––––––––––––––––––––-
// CBluetoothPMPExampleEngine::HandleListenerDataReceivedL(TDesC& aData)
// afiseaza datele receptionate de sclav de la master. acesta este un apel de tip
// "callback" pe care clasa CListener il invoca atunci cand primeste date.
// –––––––––––––––––––––––––-
void CBluetoothPMPExampleEngine::HandleListenerDataReceivedL(TDesC& aData)
{
TBuf<20> object=_L("*un obiect*\n");
//daca s-a receptionat un obiect
if (object==aData)
{
ShowMessageL(_L("Receptionat obiect:\n"), true);
ShowMessageL(aData, false);//aData – obiectul receptionat
}
//altfel, daca s-a receptionat text
else
{
// se afiseaza textul receptionat
TBuf<80> msg;
msg.Format(_L("< %S\n"), &aData);
ShowMessageL(msg, false);
}
}
// –––––––––––––––––––––––––-
// CBluetoothPMPExampleEngine::HandleListenerConnectedL()
// un apel de tip callback receptionat de la CListener pentru a indica faptul
// ca s-a realizat o conexiune
// –––––––––––––––––––––––––-
void CBluetoothPMPExampleEngine::HandleListenerConnectedL()
{
ShowMessageL(_L("Conectat la master!\n"), true);
}
// –––––––––––––––––––––––––-
// CBluetoothPMPExampleEngine::HandleListenerDisconnectedL()
// un apel de tip callback receptionat de la CListener pentru a indica faptul
// ca sclavul a fost deconectat de master
// –––––––––––––––––––––––––-
void CBluetoothPMPExampleEngine::HandleListenerDisconnectedL()
{
if ( !iIsSlave )
return;
// listener-ul a fost oprit, se va cere si oprirea service advertiser
iServiceAdvertiser->StopAdvertiserL();
ShowMessageL(_L("Dispoz. deconectat!\nMod sclav oprit.\n"), true);
}
// –––––––––––––––––––––––––-
// CBluetoothPMPExampleEngine::HandleConnectorDataReceivedL(THostName aName,
// TDesC& aData)
// afiseaza datele pe care masterul le primeste de la un sclav conectat.
// acesta este un callback invocat de clasa CConnector cand primeste date de la sclav.
// –––––––––––––––––––––––––-
void CBluetoothPMPExampleEngine::HandleConnectorDataReceivedL(THostName aName,
TDesC& aData)
{
TBuf<20> object=_L("*un obiect*\n");
//daca a fost primit un obiect
if (object==aData)
{
TBuf<20> txt=_L("Ob. rec. de la:");
TBuf<80> scrmsg;
scrmsg.Format(_L(" %S %S:\n"), &txt, &aName);//aName – numele sclavului
ShowMessageL(scrmsg, false);
ShowMessageL(aData, false);//aData – obiectul primit
}
//altfel, daca s-a primit text
// afiseaza textul primit alaturi de numele sclavului care l-a trimis
else
{
TBuf<80> msg;
msg.Format(_L("< %S: %S\n"), &aName, &aData);
ShowMessageL(msg, false);
}
}
// –––––––––––––––––––––––––-
// CBluetoothPMPExampleEngine::HandleDeviceDiscoveryCompleteL()
// un callback de la device discoverer pentru a semnala ca s-a terminat
// descoperirea dispozitivelor.
// –––––––––––––––––––––––––-
void CBluetoothPMPExampleEngine::HandleDeviceDiscoveryCompleteL()
{
// iteratie pentru afisarea dispozitivelor descoperite
if ( iDevDataList.Count()> 0 )
{
// dispozitivele descoperite
ShowMessageL(_L("Dispoz. in raza:\n"), true);
for (TInt idx=0; idx<(iDevDataList.Count()); idx++)
{
TDeviceData *dev = iDevDataList[idx];
TBuf<40> name;
name = dev->iDeviceName;
name.Append(_L("\n"));
ShowMessageL(name, false);
}
}
else
{
// no devices found
ShowMessageL(_L("\nNu s-au descoperit\ndispoz. in raza!"), false);
}
}
// –––––––––––––––––––––––––-
// CBluetoothPMPExampleEngine::HandleServiceDiscoveryCompleteL()
// un callback de la service discoverer pt a indica incheierea descoperirii
// serviciilor.
// –––––––––––––––––––––––––-
void CBluetoothPMPExampleEngine::HandleServiceDiscoveryCompleteL()
{
TInt count=0;
ShowMessageL(_L("S-a gasit serviciul pe:\n"), true);
// afiseaza dispozitivele care ofera serviciul dorit
for ( TInt idx=0; idx<(iDevDataList.Count()); idx++ )
{
TDeviceData *dev = iDevDataList[idx];
if ( dev->iDeviceServicePort>0 )
{
THostName name = dev->iDeviceName;
name.Append(_L("\n"));
ShowMessageL(name, false);
count++;
}
}
if ( count==0 )
{
ShowMessageL(_L("Serv. nu a fost gasit!\n"), false);
}
}
// –––––––––––––––––––––––––-
// CBluetoothPMPExampleEngine::HasConnections()
// intoarce true daca masterul are cel putin o conexiune cu undispozitiv sclav
// –––––––––––––––––––––––––-
TBool CBluetoothPMPExampleEngine::HasConnections()
{
return ( iConnectedDeviceCount>0 );
}
=== _anexa 3 – calcul economic ===
Anexa 3 – Calcul economic
Deoarece cerința formulată prin tema acestui proiect s-a rezolvat dezvoltând un produs software, prin calculul economic se va încerca să se determine costurile implicate de definitivarea acestui produs.
Pentru dezvoltarea aplicației au fost necesare:
un PC cu sistem de operare Microsoft Windows XP Professional și cu Microsoft Office XP instalat, care se evaluează la circa 1000$;
Kitt de dezvoltare software (SDK) Nokia Series 60 SDK 1.2 for MW pus la dispoziție gratuit de Nokia Corporation;
Mediu integrat de dezvoltare (IDE) Metrowerks CodeWarrior al cărui cost se ridică la aproximativ 600$. Versiunea folosită de acest proiect a fost una shareware pusă la dispoziție gratuit de firma producătoare pentru o perioadă de 90 de zile;
Placă Bluetooth pentru PC, aproximativ 100$;
Port infraroșu, aproximativ 30$;
Cel puțin două telefoane mobile marca Nokia, Serie 60, evaluate la circa 350$ fiecare;
Conexiune la Internet, care costă aproximativ 25$/lună;
Programarea, ca formă de muncă, este plătită cu circa 25$/zi la o normă de 20-30 de linii de program, această sumă fiind variabilă în funcție de țară, nivel de trai, etc.
În cazul nostru avem circa 500 de linii de program din care aproximativ 40% au fost generate automat de utilitarul Application Wizard sau reprezintă structuri standard pentru aplicațiile sub platforma Series 60. Rezultă deci, un număr de 300 linii de program care vor fi luate în considerare pentru calculul economic.
Nr. linii program scrise pe zi = 20
Nr. total linii =300
Nr. zile = Nr. total linii / Nr. linii program la zi
Nr. zile = 300 / 20 = 15 zile
Din calculul anterior rezultă că un programator lucrează 15 zile, perioadă pentru care retribuția sa este de:
Retribuție = Nr. zile *25$/zi =375$
Această sumă poate varia de la firmă la firmă în funcție de prețul pe linia de program sau de norma pe care o are un programator.
Ținând cont de anumite aspecte practice cum ar fi faptul că durata medie de utilizare a unui PC este de 3 ani iar pentru dezvoltarea programului PC-ul a fost folosit aproximativ 1 lună (3% din durata medie de utilizare), telefoanele mobile utilizate sunt necesare doar pentru teste, placa Bluetooth ca și portul IR pot fi reutilizate în alte scopuri la terminarea dezvoltării produsului software, se poate calcula un cost al aplicației. Rezultă un cost total pentru dezvoltarea produsului software de aproximativ 1000$. Acest cost este doar unul estimativ deoarece nu am luat în considerare operațiunile care sunt cele mai costisitoare în cadrul dezvoltării și lansării pe piață a unui astfel de produs și anume depanarea și mentenanța. De obicei costul acestora poate ajunge la 50% din costul unui produs software.
Dacă se dorește lansarea pe piață a produsului, adăugând costurile mai sus amintite, plus un adaos comercial de 30% se obține un preț al aplicației de 1950$. Anticipând un număr de 100 de clienți rezultă un preț final al produsului de 19,5$.
=== _capitolul I – analiza temei.solutii ===
Capitolul I . Analiza temei de proiect. Investigarea soluțiilor posibile
1. Analiza cerințelor temei de proiect
Prin tema de proiect se cere să se implementeze o comunicație de date între dispozitive mobile. In urma analizei soluțiilor posibile de realizare a comunicației se va verifica dacă într-adevăr folosirea tehnologiei Bluetooth este alegerea justă. Este de remarcat faptul că va trebui să lucrăm cu dispozitive electronice mobile deci în proiectarea soluției trebuie să se țină seama de acest aspect foarte important. Acest tip de dispozitive oferă resurse limitate. Caracteristici cum ar fi consumul, gradul de utilizare a memoriei și al procesorului dar și greutatea sau dimensiunile fizice devin extrem de importante. De asemenea conexiunile între dispozitive trebuie să fie ușor de realizat fizic iar procedura de configurare software a căii de comunicație trebuie să fie cât mai simplă. In acest sens ar fi de preferat găsirea unei soluții universale, pe cât posibil, pentru a evita procedurile repetate de configurare pentru fiecare tip de dispozitiv în parte.
Având în vedere că dispozitivele se vor afla unul în apropierea celuilalt distanța maximă la care ar funcționa conexiunea are mai puțină importanță. Totuși prezintă importanță viteza la care se va efectua transferul de date.
De remarcat și faptul că nu se precizează numărul de dispozitive mobile care vor participa la transferul de date. In acest sens vom încerca realizarea unei comunicații simultane între mai multe dispozitive mobile. Cazul comunicației între două dispozitive mobile va fi considerat unul particular.
Nu în ultimul rând se va căuta o soluție care să fie cât mai acceptabilă și din punct de vedere al costurilor pe care le implică. Implementarea soluției pe un dispozitiv mobil nu ar trebui să crească foarte mult prețul de producție al dispozitivului respectiv, din potrivă în cazul unei soluții competitive creșterea de preț ar trebui să fie nesemnificativă.
Determinarea și analizarea soluțiilor posibile
In practică există mai multe soluții pentru realizarea unui transfer de date între două sau mai multe dispozitive mobile. Se remarcă două mari categorii de soluții, în funcție de metoda de conectare fizică a dispozitivelor:
Soluții ce folosesc cabluri de date. Aceste soluții folosesc pentru transferul de date fie protocolul RS-232, fie standardul USB;
Soluții fără fir (wireless). Dintre acestea cele mai importante sunt: transmisiile de date prin IR, folosirea serviciilor de date ale rețelelor de telefonie mobilă (HSCSD, GPRS, EDGE, EV-DO, etc.), soluțiile de tip WLAN și folosirea tehnologiei Bluetooth.
In vederea determinării soluției optime pentru realizarea temei de proiect vom analiza fiecare posibilă soluție în parte.
Transferul de date prin cablu
Aceasta este soluția clasică de interconectare a diferitelor dispozitive electronice în vederea efectuării unor transferuri de date. Indiferent daca vorbim de dispozitive fixe sau mobile majoritatea sunt prevăzute cu facilitatea de a fi conectate prin cablu cu alte dispozitive. Și în cazul dispozitivelor mobile, conexiunile prin cablu reprezintă, cronologic vorbind, prima soluție adoptată de producători pentru realizarea transferurilor de date (programarea dispozitivelor, transferul de date ale utilizatorilor, transferul de voce, etc).
Această soluție are avantajul stabilității conexiunii. Perturbațiile au o influență redusă asupra comunicației de date. De asemenea consumul de putere la dispozitivului mobil este redus. Din punct de vedere economic costul unui cablu de date este redus.
Soluția prezintă o serie de dezavantaje destul de însemnate. Un inconvenient ar fi acela că nu există un model universal de cablu. Din potrivă, aproape fiecare dispozitiv mobil are un alt tip de mufă pentru conectarea cablului de date. Conexiunea prin cablu limitează mobilitatea dispozitivelor în timpul efectuării transferului de date, aceasta pe lângă inerentele probleme legate de contactele imperfecte ale cuplei dintre aparat și cablul de date.
Probleme importante ridică și software-ul folosit la astfel de transferuri. Faptul că nu se poate discuta de existența unui software universal, coroborat cu prețul destul de ridicat al produselor software (preț care în marea majoritate a cazurilor îl depășește cu mult pe cel al cablului de date), conduc la concluzia ca din punct de vedere economic nu aceasta este cea mai bună soluție. Mai mult fiecare dispozitiv necesită, pe lângă softul specific și proceduri destul de complexe de configurare a legăturii.
In cazul dispozitivelor mobile conexiunile prin cablu se folosesc în general pentru realizarea conexiunilor punct la punct. Conexiunile punct la multipunct sunt destul de dificil de realizat prin cablu.
Pentru folosirea standardului RS-232 viteza de transfer este destul de mică, 9600 baud în cele mai multe cazuri.
S-a încercat eliminarea unor dezavantaje ale conexiunilor care folosesc protocolul RS-232 odată cu introducerea standardului USB. Astfel crește mult viteza de transfer a datelor până la 12 Mbps pentru USB 1.1 și chiar până la 480 Mbps pentru USB 2.0.Noul standard a fost adoptat rapid de mai mulți producători tinzând să devină universal. Totuși nu s-au rezolvat complet problemele legate de partea software a conexiunilor. Deși procedurile de configurare s-au simplificat foarte mult este încă necesar software caracteristic fiecărui dispozitiv (drivere). De asemenea persistă problemele legate de folosirea cablurilor: mobilitate redusă în timpul transferului, diferite tipuri de mufe pentru conectarea cablurilor de date la dispozitivele între care se dorește transferul de date, probleme de contacte, etc.
Dezavantajele pe care le prezintă această soluție nu o recomandă în acest moment ca fiind soluția ideală pentru realizarea unui transfer de date în conformitate cu tema de proiect.
Transferul de date folosind o conexiune prin IR
IrDA (Infrared Data Association) reprezintă un standard definit de consorțiul IrDA. Acest standard specifică modul în care se pot transfera date printr-o conexiune fără fir folosind radiația infraroșie. Dispozitivele IrDA comunică folosind LED-uri care emit în spectrul IR. Lungimea de undă utilizată este de 875nm +/- toleranța produsului (in jur de 30nm). Pentru recepție se folosesc fotodiode PIN care lucrează în mod generator. Tensiune generată de partea optică a receptorului este direct proporțională cu energia radiației incidente.
Conform standardelor IrDA 1.0 și 1.1 dispozitivele IrDA lucrează pe o distanță de maxim 1 m cu o rată a erorii de bit (BER – numărul de biți eronați raportat la numărul total de biți transmiși) de 10-9 și la un nivel maxim de iluminare a mediului înconjurător de 10klux (intensitatea luminii naturale pe timpul zilei). Valorile sunt definite pentru un unghi de nealiniere de maxim 15 grade între cele două dispozitive. Unghiul maxim de nealiniere la care se poate realiza o legătură în infraroșu este de 30 grade. In practică, în cazul dispozitivelor mobile, o legătură prin IR este stabilă atâta timp cât dispozitivele participante se află la o distanță mai mica de 30-40 cm unul de celălalt. Există soluția folosirii LED-urilor direcționale pentru acoperirea unei distanțe mai mari. Acestea prezintă dezavantajul micșorării unghiului de radiație, dispozitivele trebuind să fie bine aliniate.
Viteza unei conexiuni IR variază între 2400 până la 115200 bps pentru IrDA 1.0. Pentru conexiuni la aceste viteze se folosește modulația pulsurilor luminoase, folosind pulsuri cu durata de 3/16 din durata inițială a unui bit.
IrDA v.1.1 definește și posibilitatea folosirii unei modulații cu durata pulsului luminos de 1/4 din durata bitului inițial pentru viteze de 0.576 și 1.152 Mbps. La aceste viteze pachetele de date sunt transmise sincron, folosind o secvență de start (figura 1.) Semnalul NRZ reprezintă semnalul original, nemodulat.
figura 1. – comparație între folosirea pulsurilor luminoase de 3/16 pentru viteze sub 1.152 Mbps și folosirea pulsurilor de 1/4 pentru viteze de 0.576 și 1.152 Mbps
Un pachet IrDA este compus din două cuvinte de start urmate de adresa destinației, datele utile și o sumă de control, de tip CRC pe 16 biți (figura 2.). Cuvintele de start și stop nu pot să apară în altă parte a pachetului de date. Pulsul luminos corespunzător acestor cuvinte are lungimea de 1,5 din durata unui bit nemodulat, deci acest puls este de șase ori mai lung decât pulsul corespunzător unui bit de date obișnuit
figura 2. – structura unui pachet de date IrDA
In figura 2. notațiile reprezintă:
STA: cuvântul de start, în binar având forma 01111110;
ADDR: câmpul de adresă pe 8 biți;
DATA: include un câmp de control de 8 biți și un câmp de 2045 biți de informație;
FCS: sumă de tip CRC pe 16 biți;
STO: cuvântul de stop, în binar având forma 01111110.
Evoluția standardului IrDA a dus la posibilitatea efectuării unor transferuri de date la viteza de 4Mbps folosind așa-numita modulație 4PPM. Prin acest tip de modulație se codează câte doi biți folosind un puls luminos care poate apărea într-una din cele patru poziții temporare posibile. Evident, pulsul luminos are o lungime de un sfert din durata bitului inițial.
Concluzionând, folosirea unei conexiuni prin IR prezintă mai multe avantaje: exclude folosirea cablurilor, suportă o viteză ridicată de transfer a datelor, nu necesită neapărat instalarea unui software suplimentar, standardul este universal, iar prețul realizării conexiunii este relativ redus. Dezavantajele alegerii unei astfel de soluții ar fi mobilitatea limitată a dispozitivelor care realizează transferul de date. Intre dispozitivele implicate în transfer trebuie să existe contact vizual iar dispozitivele trebuie să fie situate destul de aproape unul de celălalt. Un alt dezavantaj ar fi legat de consumul de putere de la dispozitivul gazdă, consun care devine un criteriu foarte important dacă se lucrează cu dispozitive ce se alimentează folosind acumulatori.
Este clar că efectuarea unui transfer de date între dispozitive mobile este de preferat să se realizeze folosind o legătură prin IR decât una prin cablu. O legătură IR este mai rapidă, mai ușor de realizat și chiar mai ieftină. Folosirea transferului de date IrDA reprezintă o soluție ce merită luată în considerare pentru realizarea temei de proiect.
Transferul de date folosind rețelele de telefonie mobilă.
In ultimii ani serviciile de date prin rețelele de telefonie mobilă au cunoscut o dezvoltare foarte rapidă. Există mai multe tehnologii care permit transferul de date prin intermediul serviciilor oferite de operatorii mobili. Principalele tehnologii de acest tip sunt HSCSD, GPRS , EDGE și WCDMA în cazul rețelelor GSM iar în cazul rețelelor CDMA pe lângă transferurile de date obișnuite se remarcă transferurile de date folosind tehnologia EV-DO.
Toate aceste tehnologii au fost concepute pentru transmiterea datelor indiferent de distanța dintre dispozitivul care emite și cel care recepționează, cu condiția ca dispozitivele să se afle în zonele de acoperire ale unei rețele de telefonie mobilă. Prețul destul de ridicat al unor astfel de conexiuni, mai ales pentru transferul unor date semnificative ca dimensiune, comparativ cu prețul celor două soluții prezentate la punctele 2.1 și 2.2 nu justifică alegerea unei astfel de soluții. In plus realizarea unei conexiuni de date prin rețeaua de telefonie mobilă este condiționată de deținerea unei cartele SIM sau a unui abonament la una dintre rețele și bineînțeles a unui telefon mobil.
Viteza la care se poate realiza un transfer de date printr-o rețea de telefonie mobilă este destul de redusă, cuprinsă între zeci de kbps pentru HCSD și GPRS (maxim 64 kbps pentru GPRS) crescând la sute de kbps dacă se folosește EDGE (maxim 384 kbps) și ajungând până debite de 2Mbps în cazul folosirii tehnologiilor de generația a 3-a cum ar fi WCDMA și EV-DO.
In ciuda dezavantajului legat de costul care îl presupune o astfel de legătură de date trebuie să ținem seama și de avantajele pe care le are o astfel de soluție. Realizarea unei legături de date prin rețeaua de telefonie mobilă este destul de simplă. Configurările dispozitivelor se fac de obicei o singură dată și sunt de cele mai multe ori efectuate de operatorul de telefonie mobilă. Nu este necesar nici un fel de soft suplimentar pentru realizarea transferului de date, dispozitivele mobile incluzând și softul ce ajută la realizarea comunicației. Odată realizată legătura este destul de stabilă.
In concluzie avem de-a face cu o soluție ce merită luată în considerare dar utilizarea sa nu ar fi tocmai justificată dacă ne propunem să realizăm transferuri de date pe distanțe mici, așa cum este cazul acestui proiect.
Analizarea soluției WLAN
O rețea locala, fără fir, de tip WLAN reprezintă un sistem sub forma grup închis de dispozitive care comunică între ele cu ajutorul undelor radio. Tehnologia WLAN a fost destinată înlocuirii rețelelor clasice de calculatoare pentru a asigura utilizatorilor mai multă flexibilitate și libertate de mișcare la locul de muncă. Utilizatorii pot accesa rețeaua internă a companiei la care lucrează sau pot avea acces la Internet oriunde s-ar afla în cadrul companiei la care lucrează.
Viteza la care lucrează o astfel de rețea depinde de tipul de configurare a dispozitivelor din rețea. Astfel viteza de transmitere a informației poate fi cuprinsă între 10 Mbps (pentru 10BaseT) și 100 Mbps (în cazul unei rețele 100BaseT). Banda de frecvențe folosită este cea de 2.4 GHz iar raza de acoperire este de 100 metri.
Rețelele WLAN au o răspândire foarte largă în multe foarte domenii. La creșterea popularității acestei soluții au contribuit decisiv avantajele deosebite pe care le oferă:
Mobilitate – rețelele WLAN permit utilizatorilor accesul în timp real la informație, oriunde s-ar afla în cadrul organizației din care fac parte fără să fie nevoiți să găsească o priză de acces la rețeaua Ethernet.
Fiabilitate – mai puține fire și mai puține cuple implică mai puține probleme.
Scalabilitate – rețelele WLAN sunt ușor de adaptat la modificarea diverselor cerințe, de exemplu se pot extinde destul de ușor
Costul implementării unor astfel de rețele este destul de ridicat. La aceasta contribuie costul componentelor hardware necesare. Dispozitivele comunică cu rețeaua folosind adaptoare radio iar acestea comunică cu un transceiver (punct de acces). De asemenea, costurile implicate de software și de procedurile de configurare a rețelei sunt semnificative. O altă problemă legată de WLAN, problemă care a generat controverse, este reprezentată de securitatea unei astfel de rețele.
In concluzie avantajele folosirii unei astfel de soluții pentru a realiza tema propusă ar fi: interoperabilitea, fiabilitatea, mobilitatea dispozitivelor (rază mare de acoperire), permite atingerea unor debite mari de date (până la 100Mbps). Dezavantajele sunt reprezentate de securitate, banda radio împărțită între membrii rețelei, costul ridicat al implementării rețelei, dificultatea realizării unor conexiuni ad-hoc.
Transferul de date folosind tehnologia Bluetooth
Bluetooth, denumire provenită de la regele viking Herald Blatand, reprezintă o tehnologie pentru transmiterea datelor prin intermediul undelor radio, excluzând astfel folosirea firelor. Această tehnologie se dorește a fi simplu de folosit pentru utilizator, „user friendly”.
Bluetooth-ul operează în banda libera ISM(Industrial Scientific Medicine), la 2,45GHz. In unele țări această bandă este rezervată in scopuri militare dar s-a început deja eliberarea ei pentru a deveni bandă de uz general. Transmisiile Bluetooth sunt transmisii cu spectru extins, folosind metoda saltului in frecvență (Frequecy hopping spread spectrum – FHSS). Rata binară brută este de 1 Mbps, folosind o modulație simplă în frecvență, anume GFSK (Gaussian Frequency Shift Keying) pentru a minimiza complexitatea părții radio. In timpul funcționării normale un canal radio este împărțit de către un grup de dispozitive care sunt sincronizate după un ceas comun și respectă aceeași schemă de salt în frecvență. Un singur dispozitiv poate da referința pentru sincronizare, dispozitiv numit master. Toate celelalte dispozitive sunt considerate dispozitive sclav. Un grup de dispozitive astfel sincronizate poartă numele de piconet. Acesta este principiul fundamental de comunicare folosind tehnologia Bluetooth. Astfel legătura Bluetooth este una foarte stabilă, interferența cu alte dispozitive nu duce la întreruperea conexiunii ci cel mult la scăderea vitezei de transmisie a datelor. Tehnologia Bluetooth suportă conexiuni punct la punct și punct la multi-punct, conexiuni care se pot stabili automat și dinamic.
Raza de acoperire pentru Bluetooth depinde de clasa de putere a emițătorului radio. Majoritatea dispozitivelor sunt echipate cu emițătoare clasa 2, având o putere de emisie nominală de 0 dBm, rezultând o rază de acoperire de până la 10 m într-un mediu fără obstacole. Aceasta rază este suficientă pentru aplicații menite a înlocui conexiunile prin cablu. Când este necesară o rază de acoperire mai mare se poate folosi un emițător radio mai puternic, de exemplu clasa 1. Consumul mai ridicat nu este o problemă dacă emițătorul este parte a unui echipament fix. In cazul echipamentelor mobile, cum ar fi telefoanele mobile, consumul are o importanță foarte mare și echiparea lor cu un emițător radio clasa 2, pentru a fi folosit de Bluetooth este singura opțiune valabilă.
Viteza legăturii, raza de acoperire și nivelul puterii de emisie au fost alese astfel încât, folosind tehnologiile de fabricație actuale, să fie posibilă o implementare a soluției la un preț scăzut, cu un consum scăzut de putere și într-un singur chip.
Sistemul Bluetooth este alcătuit dintr-o unitate radio, o unitate de control a legăturii si o unitate pentru managementul legăturii și pentru interfața cu echipamentul gazdă. Controller-ul interfeței cu echipamentul gazdă (Host Controller Interface – HCI) furnizează mijloacele prin care echipamentul gazdă poate accesa capabilitățile hardware ale Bluetooth-ului.
In ceea ce privește securitatea unei legături Bluetooth, se fac încă teste. Totuși specificațiile Bluetooth-ului includ o schemă de management a cheilor robustă cât și nivele superioare de securizare. Bluetooth folosește pentru criptare algoritmul AES și opinia generală este că sistemul de securitate al conexiunilor prin Bluetooth este puternic și robust.
Analizând sumar se poate concluziona:
Avantajele oferite de Bluetooth: interoperabilitate, scalabilitate, preț redus, compatibil atât pentru transmisii de date cât și pentru transmisii de voce,
consum de putere redus, permite formarea ad-hoc a rețelelor;
Dezavantajele acestei tehnologii: raza de acoperire relativ redusă, rata de transfer nu foarte ridicată, bandă radio partajată;
Soluții posibile de realizare a unui transfer de date între dispozitive mobile sub platforma Serie 60 de la Nokia.
In continuare vom analiza posibilele soluții de implementare a unei comunicații de date folosind una dintre tehnologiile prezentate anterior. O să încercăm realizarea unei comunicații de date între dispozitive mobile de tip smartphone având la bază platforma Serie 60 de la Nokia, dispozitive care folosesc ca sistem de operare Symbian OS. Am convingerea și o să demonstrez în continuare că această alegere nu restrânge deloc aria de aplicabilitate a soluției găsite pentru tema proiectului. Din contră, soluția finală se va putea aplica pe diverse platforme, deoarece nu codul programului în sine are importanță ci algoritmul folosit. Totuși de ce Nokia și de ce Serie 60? Pentru că dispozitivele mobile care folosesc platforma Serie 60 au avut o evoluție uimitoare pe piața de telefonie mobilă, fiind foarte repede adoptate de publicul larg. Urmare a impactului deosebit care l-a avut introducerea de către Nokia Corporation a acestei noi platforme numeroase companii de prestigiu din domeniul comunicaților au decis să adopte Serie 60 ca platformă pentru smartphone-urile produse de ele. Printre companiile care mizează pe o evoluție viitoare ascendentă a dispozitivelor Serie 60 se numără: LG Electronics, Samsung, Panasonic, Sendo și Siemens. Acești jucători importanți de pe piață apreciază numeroasele facilități oferite de platforma în discuție, cum ar fi: standardul deschis și interoperabilitatea, suportul pentru tehnologiile multimedia, pentru Java și pentru transferul rapid și ușor de date, considerând-o platforma ideală pentru telefoanele inteligente (smartphones). Larga răspândire a platformei Nokia Serie 60 și viitorul care i se prezice acestei tehnologii, numeroasele facilități pe care le oferă, standardul deschis, calitatea documentației disponibile, faptul că instrumentele soft de dezvoltare a aplicațiilor pentru această platformă sunt puse gratuit la dispoziția celor care vor să dezvolte diverse aplicații sunt suficiente motive pentru a alege Nokia Series 60 Developer Platform pentru a dezvolta o aplicație care să realizeze practic transferul de date între dispozitive mobile și care să nu prezinte un algoritm particular ci unul aplicabil pe scară largă.
Din punct de vedere al limbajului de programare folosit pentru implementarea programului care să realizeze comunicația dorită, Serie 60 oferă două alternative: folosirea limbajului Java sau Symbian C++. Desigur, la prima vedere este tentant să ne orientam spre Java. Acest limbaj are o răspândire foarte largă, multe dispozitive suportă aplicații Java iar alegerea sa ar fi o garanție în plus pentru că soluția găsită nu va fi una aplicabilă într-un număr restrâns de cazuri. Totuși trebuie știut faptul că platforma Nokia Serie 60 are la bază sistemul de operare Symbian. Acesta este cel care dispune de resursele dispozitivelor între care dorim să realizăm comunicația. Sistemul de operare Symbian este realizat folosind limbajul C++. Așadar programând în Symbian C++ (o variantă a limbajului C++ adaptată pentru realizarea de aplicații destinate să ruleze pe dispozitive care dispun de resurse limitate, de obicei dispozitive mobile) vom beneficia de anumite facilități inaccesibile din Java. Aceasta face să alegem limbajul Symbian C++ pentru dezvoltarea softului care să ajute la realizarea temei de proiect. Apreciem că astfel implementarea soluției pe care urmează să o alegem s-ar simplifica într-o oarecare măsură. Acest fapt va conduce reducerea timpului alocat implementării și depanării și la dezvoltarea unui produs software mai bun calitativ și la un preț mai scăzut.
Alegerea soluției
In urma analizei comparative ale soluțiilor prezentate la paragraful anterior se pot trage următoarele concluzii. Folosirea unei conexiuni prin cablu prezintă multiple dezavantaje cum ar fi limitarea mobilității, probleme legate de compatibilitate (interoperabilitate redusă), proceduri de configurare greoaie, necesitatea unui software adecvat. Așadar putem afirma despre această soluție că nu este una convenabilă fiind considerată de mulți producători o tehnologie depășită dar și un concept uzat moral.
De asemenea putem exclude și varianta folosirii unei conexiuni între cele două dispozitive prin rețeaua de telefonie mobilă. Spre deosebire de soluția cu cablu de date aceasta este o soluție modernă, care are multiple facilități. Nu am ales-o ca soluție pentru acest proiect deoarece am considerat că nu este tocmai potrivită pentru acest gen de aplicații – transferul de date pe distanțe scurte s-ar putea realiza mai bine și mai ieftin prin alte metode. Dacă nu ar exista constrângeri legate de cost și dispozitivele mobile ar fi întotdeauna telefoane mobile această alegere ar fi soluția cel mai comod de aplicat. Nu ar necesita nici module suplimentare atașate telefonului mobil și nici software, altul decât cel furnizat de producător.
Ar mai fi soluția folosirii unei rețele WLAN dar nici aceasta nu este tocmai convenabilă. Pentru conectarea dispozitivelor sunt necesare adaptoare radio și cel puțin un punct de acces. Conexiunile nu pot avea loc oriunde și oricând. Rețeaua wireless trebuie configurată și supravegheată de un administrator de rețea. Nici această soluție nu este imposibil de aplicat dar poate fi folosită doar dacă se cunoaște locul unde apare de obicei necesitatea realizării conexiunilor între dispozitive (de exemplu in interiorul campusului unei companii), dacă dispozitivele mobile se pot conecta la surse de alimentare externe (consumul este ridicat) și în cazul în care costul echipării dispozitivelor mobile cu adaptoare radio nu are mare importanță.
Rămân două variante aplicabile în pentru soluționarea temei acestui proiect: o conexiune prin infra-roșu sau una prin radio, folosind tehnologia Bluetooth. Acestea sunt cele două tehnologii disponibile în momentul de față pentru a realiza un transfer de date, fără folosirea firelor, intre dispozitive fixe sau mobile. Ambele au avantaje și dezavantaje iar uneori furnizează soluții complementare pentru comunicația fără fir pe distanțe scurte.
Astăzi, posibilitatea transferurilor de date fără a mai folosi cabluri a schimbat mult modul în care oamenii comunică. Se așteaptă o creștere susținută a cererii pentru dispozitive care suportă acest tip de transferuri de date, odată cu introducerea dispozitivelor electronice mobile de ultimă generație. Conform firmei de consultanță Strategy Analitics în anul 2005 cifra de afaceri la nivel mondial în domeniul high-tech va fi de 73 miliarde $, înregistrând o creștere anuală de aproximativ 10 miliarde $.
Deși Bluetooth este deseori văzut ca un „înlocuitor” pentru dispozitivele IR ale Infrared Data Association (IrDA) , de fapt cele două tehnologii sunt aproape complementare. Intenția IrDA în privința dispozitivelor IR de putere redusă este aceea de a găsi un standard care să fie adoptat pe scară largă pentru a asigura interoperabilitate la un preț scăzut în cazul comunicațiilor de date între dispozitive mobile sau fixe. Din caracteristicile IrDA amintim posibilitatea de a efectua transferuri de date punct la punct, dispozitivele trebuie să fie aliniate la un unghi mai mic de 30 grade, între porturile IrDA ale dispozitivelor participante la transfer trebuie să existe contact vizual, distanța maximă la care se poate efectua transferul este 1 metru, viteza de transmisie între 9,6 kbps până la 4 Mbps. Avantajul Bluetooth față de IrDA este posibilitatea efectuării cu ușurință a conexiunilor punct la multipunct. De asemenea Bluetooth nu presupune contact vizual între dispozitivele care realizează transfer de date. Este suficient ca dispozitivele să se afle unul în raza celuilalt, iar această rază de acoperire este de până la 10 metri, mai mult decât în cazul IrDA. Cu toate că chiar cei care au dezvoltat tehnologia Bluetooth afirmă că aceasta nu se dorește a fi un concurent pentru IrDA mulți producători adoptă rapid tehnologia Bluetooth sau chiar înlocuiesc porturile IrDA ale dispozitivelor produse cu module Bluetooth. Bluetooth devine din ce în ce mai popular în timp ce IrDA pare să fi trecut de perioada de apogeu.
In aceste codiții, este clar că soluția optimă pentru realizarea unei comunicații în conformitate cu cerințele temei de proiect o reprezintă folosirea tehnologiei Bluetooth. Pentru punerea în practică a soluției găsite, în speță a unui transfer de date prin Bluetooth, se vor folosi dispozitive mobile din categoria „smartphone”. Aceste dispozitive reprezintă telefoane mobile care, pe lângă caracteristicile clasice, dispun de numeroase alte facilității (organizer, suportă IrDA și Bluetooth, funcții foto și video, etc), realizate pe platforma Serie 60 dezvoltată de Nokia Corporation. Nucleul platformei îl reprezintă sistemul de operare special conceput pentru a gestiona resursele unui dispozitiv mobil, Symbian OS. Dezvoltarea produsului software care va realiza comunicația dorită se va face folosind facilitățile oferite de atât de Symbian OS cât și de platforma Serie 60. Cum programul va rula sub Symbian OS, limbajul de programare folosit va fi Symbian C++ (vezi 2.5.1).
=== _capitolul II – descrierea solutiei ===
Capitolul II. Descrierea soluției alese. Proiectul hardware
Soluția aleasă pentru rezolvarea cerințelor din tema de proiect are la bază două mari componente: tehnologia Bluetooth și platforma Serie 60. Detalii despre tehnologia Bluetooth sunt prezentate în anexa 1. In cadrul acestui capitol se va prezenta platforma software Serie 60, se va face o analiză a performanțelor soluției alese și în final se va face o scurtă descriere a părții hardware necesară pentru a implementa platforma software și implicit aplicația pe care ne propunem să o realizăm.
Platforma software
Platforma software pe care se va dezvolta aplicația conform cu tema proiectului are două componente principale: sistemul de operare Symbian și platforma Serie 60. In continuare vom prezenta pe rând cele două componente subliniind totodată și relațiile dintre ele.
Symbian OS
Symbian este o companie producătoare de software care dezvoltă un sistem de operare avansat, standard deschis – SymbianOS – destinat telefoanelor mobile de tip smartphone. Compania Symbian a luat ființă în Marea Britanie în anul 1998. La sfârșitul anului 2003, 18 modele de telefoane mobile, realizate de 5 companii producătoare, foloseau deja Symbian OS. Printre acestea remarcăm modele foarte apreciate pe piață cum ar fi Nokia 6600, Fujitsu F900i, Sony Ericsson P900, Motorola A925. Au urmat încă 26 de modele de smartphone-uri de la 9 producători. Se estimează că, în anul 2003, în întreaga lume 6,7 milioane de telefoane mobile foloseau Symbian OS iar până astăzi s-a ajuns la livrarea pe piață, în fiecare lună, a peste 1 milion de smartphone-uri care folosesc Symbian OS. De asemenea Symbian estimează că 85% din telefoanele livrate anual pe piață folosesc sistemul de operare dezvoltat de companie. Astfel acest sistem de operare tinde să devină standardul mondial în domeniul sistemelor de operare pentru dispozitive digitale mobile.
Symbian OS este un sistem de operare deschis, robust, multitasking, pe 32 de biți. Deseori, în cadrul acestui sistem de operare evenimentele au loc asincron iar aplicațiile pot interacționa unele cu celelalte. De exemplu primirea unui apel telefonic poate întrerupe scrierea unui e-mail, un utilizator poate folosi alternativ atât programul de scriere a e-mail-ului cât și calendarul sau sosirea unui SMS poate avertiza utilizatorul să acceseze baza de date care îl conține pentru ca, eventual, să trimită mai departe SMS-ul.
1.1.1 Cadrul în care rulează o aplicație
In continuare vom descrie modul în care lucrează o aplicație sub Symbian OS. O parte cheie a cadrului de lucru a unei aplicații este Uikon. Uikon reprezintă cadrul standard în care rulează o aplicație, comun tuturor platformelor bazate pe Symbian OS. Uikon nu furnizează numai contextul pentru rularea aplicațiilor ci și o gamă bogată de componente de control standard (de exemplu casete de dialog, editoare de numere, editoare de date, etc.) folosite de aplicație în momentul rulării. O aplicație tipică scrisă pentru Symbian conține patru componente, fiecare dintre ele având o clasă corespondentă în contextul Uikon. Aceste componente sunt:
Application shell – derivată din clasa CEikApplication. Această clasă este instanțiată prima dată de cadrul de lucru. Odată creată este responsabilă pentru inițializarea restului codului aplicației. Clasa nouă derivată din CEikApplication creează apoi Documentul;
Documentul – este derivat din CEikDocument. Toate aplicațiile au o clasă derivată din CEikDocument. Implicit, CEikDocument va crea un fișier document atunci când aplicația respectivă este rulată prima dată. Nu toate aplicațiile sunt bazate pe fișiere, deci nu vor trebui să ofere utilizatorului posibilitatea să creeze, să deschidă sau să editeze documente. In cazul unor asemenea aplicații, cum ar fi folosirea dispozitivului ca telefon, instanța clasei document este aproape o clasă goală, necesară contextului pentru a crea o instanță a clasei AppUI. In cazul aplicațiilor bazate pe fișiere clasa Document gestionează salvarea și restaurarea datelor din locul unde au fost stocate;
ApplicationUI – este derivată din Uikon, din clasa CEikAppUI. Această clasă asigură funcționalități majore tuturor aplicațiilor cum ar fi tratarea evenimentelor, controlul aplicației și numeroase apeluri către sistemul de operare. Clasa derivată din CEikAppUI este tipic responsabilă cu crearea uneia sau mai multor tipuri de înfățișări ale aplicației (application view).
View – creează ceea ce vede utilizatorul pe ecran. Toate aplicațiile au o înfățișare implicită; cele mai complexe, cum ar fi Calendarul, pot oferi mai multe înfățișări. View poate fi folosită pentru a reda date pe display sau pentru a colecționa datele introduse de utilizator în aplicațiile interactive. De exemplu, în cazul multor aplicații care necesită introducerea de date de la tastatură editoarele sunt elemente standard furnizate de Uikon și conținute în View.
Fișierele de resurse sunt fișiere caracteristice Symbian OS. Multe din informațiile referitoare la felul în care arată, felul în care se comportă sau funcționalitățile unei aplicații sunt stocate într-un fișier de resurse; în exteriorul programului principal, totul, de la status pane (partea de sus a display-ului unui smartphone, unde se afișează informații referitoare la nivelul bateriei, semnal, sau aplicația care rulează la un moment dat), la meniuri și taste rapide până la casetele de dialog poate fi definit într-un fișier de resurse. Resurse individuale sunt încărcate foarte eficient în timpul rulării, atunci când este cazul deoarece de obicei memoria este limitată.
Resursele aplicației sunt definite în fișiere text, tipic salvate cu extensia *.rss. Aceste fișiere sunt compilate și comprimate la momentul construcției rezultând fișiere binare (*.rsg) folosite în momentul rulării. Pentru descentralizare, de obicei, textul interfeței cu utilizatorul este definit separat într-un fișier header (salvat prin convenție cu extensia *.loc) și inclus în fișierul principal de resurse. Fișierele *.loc pot fi traduse în diferite limbi. Tot într-un fișier header sunt definite și constantele folosite de aplicație, constante definite de context într-un fișier special. Acest fișier se salvează prin convenție cu extensia *.hrh și va fi și el inclus în fișierul principal de resurse (*.rss).
Chiar dacă resursele apar inițial ca fiind complexe, tratate pas cu pas, apar destul de intuitive (figura 3).
Figura 3. – fișierele de resurse în Symbian OS
Fișierele cu informații despre aplicație (Application Information File – AIF) păstrează datele referitoare la aplicație și anume:
Iconițe de diferite dimensiuni folosite de sistem pentru a reprezenta aplicația;
Titluri;
Caracteristici ale aplicației cum ar fi, faptul că include anumite documente, posibilitatea de a crea noi fișiere, dacă aplicația este ascunsă sau nu, etc;
Fiecare aplicație ar trebui să aibă propriul fișier cu informații (*.aif) care conține în mod obișnuit o poză și titluri asociate cu aplicația. Fără un fișier *.aif aplicația va folosi iconițele implicite iar numele său va fi folosit ca titlu. Poza care se dorește a fi folosită pentru iconița aplicației trebuie să fie într-un format specific Symbian OS numit multi-bitmap (*.mbm).
1.1.2 Tratarea excepțiilor
Symbian OS are propriile modalități pentru tratarea excepțiilor. Metoda try-catch-throw folosită în ANSI C++ nu mai este valabilă. Macrourile TRAP și TRAPD permit codului să ruleze sub protecția unui „trap”. Macrourile sunt analog cu try-catch în ANSI C++. Excepția este aruncată de fapt de apelul User::Leave() care este analog cu throw din C++. Aceasta are și implicații asupra terminologiei: în Symbian C++ se spune că o metodă ar putea să genereze „leave” (to leave =a lăsa, a nu lua ), nu că o metodă ar putea „să arunce o excepție” („throw an exception” în engleză). De asemenea se poate vorbi despre „trapping leaves” și nu despre „prinderea excepțiilor” („catching exceptions”). In Symbian OS excepțiile sunt mai simple decât în C++. Acestea nu aruncă un obiect ci întorc către „trap harness” un cod de eroare pe 32 de biți.
Excepțiile pot duce la epuizarea memoriei sau a altor resurse. Să analizăm următorul caz:
CMyClass* p = new(ELeave) CMyClass();
p->MethodThatMightLeaveL();
delete p;
Aici poinerul p ar rămâne în stivă dacă metoda MethodThatMightLeaveL() ar genera „leave”. Din moment ce acesta este singurul pointer către obiect nu mai există nici o metodă prin care să apelăm destructorul său și să eliberăm resursele ocupate iar aceasta va conduce la epuizarea resurselor. Symbian OS asigură mecanismul necesar evitării unei astfel de situații, numit „cleanup stack”. Stiva numită cleanup stack este folosită de obicei pentru a stoca pointeri către clase derivate din CBase (clasa de bază pentru toate clasele de tip C, clase de tip heap-allocated). Când o metodă generează „leave” cleanup stack este golită și este invocată metoda delete pentru toți pointerii Cbase* din stivă (clasa CBase are un destructor virtual). Acest mecanism este ilustrat în exemplul următor:
CMyClass* p = new(ELeave) CMyClass();
CleanupStack::PushL( p );
p->MethodThatMightLeaveL();
CleanupStack::Pop();
delete p;
Cleanup stack poate reține și pointeri de tipul TAny*, caz în care este invocată metoda User::Free asupra pointerului. Din moment ce există alte metode de eliberare a resurselor în afară de apelul funcției delete din C++ sau de apelul User::Free, există un obiect generic TCleanupItem care va fi memorat în stivă. TCleanupItem este pur și simplu o clasă care conține un pointer către o funcție de ștergere și posibil un pointer TAny* . Când apare un „leave” funcția este apelată cu TAny* ca argument (dacă este specificat). Exista funcții helper pentru majoritatea funcțiilor comune de eliberare de resurse, de exemplu CleanupClosePush(T& aRef) care are ca efect apelul funcției Close() pentru referința aRef.
Este important de reamintit rolul stivei cleanup stack, acela de a preveni epuizarea memoriei când apar „leave”-uri, nicidecum de a furniza un colector automat de reziduuri. Deci programatorul nu trebuie să lase obiecte în stiva cleanup stack cu speranța că la sfârșitul execuției vor fi șterse automat. Este o stivă și un alt cod poate folosi PopAndDestroy și va aștepta ca un anumit pointer să fie în vârful stivei. O altă problemă des întâlnită este aceea a memorării variabilelor membre în cleanup stack; acestea trebuie distruse de destructorul clasei corespunzătoare, nu de cleanup stack.
Cleanup stack nu asigură totuși o protecție împotriva „leave”-urilor care apar în interiorul constructorilor claselor derivate din CBase. Să considerăm următorul exemplu:
class CMyClass : public CBase
{// variabile membre
CSomeOtherClass* iP;
CMyClass()
{iP = new(ELeave) CSomeOtherClass();}}
// acum, în cod este creată o instanță a clasei CMyClass
// ..
CMyClass* p = new(ELeave) CMyClass();
Aici trebuie menționat că, înainte de a fi invocat constructorul clasei, este rezervată memorie pentru însuși obiectul clasei CMyClass. Dacă memoria se epuizează în acest moment nu este nici o problemă decât că va apare un „leave”. Dar ce se întâmplă dacă memoria se epuizează când se execută constructorul clasei CMyClass, atunci când se creează CSomeOtherClass? Din nou va apărea un „leave” dar memoria a fost deja rezervată pentru însuși obiectul CMyClass. In acest caz cleanup stack nu ar fi de ajutor. Soluția o reprezintă construcția în două etape („two-phase construction”), o altă particularitate a Symbian OS.
Așa cum sugerează numele, construcția în două etape, împarte procesul de construcție a unui obiect nou în două părți. Prima fază este realizată de constructorul C++ standard. Pentru a preveni epuizarea memoriei, în cazul menționat anterior, constructorul standard C++ nu trebuie să conțină cod care ar putea genera „leave”. A doua fază de construcție este reprezentată de codul care ar putea genera „leave”. Această fază este reprezentată de o metodă numită prin convenție ConstructL(). Exemplul anterior implementat folosind construcția cu două faze și utilizând corect cleanup stack arată astfel:
class CMyClass : public CBase
{//variabile membre
CSomeOtherClass* iP;
CMyClass()
ConstructL()
{iP = new(ELeave) CSomeOtherClass();}}
// acum, în cod este creată o instanță a clasei CMyClass
// ..
CMyClass* p = new(ELeave) CMyClass();
CleanupStack::PushL( p );
p->ConstructL();.
De obicei clasele care necesită folosirea construcției cu două faze implementează metodele helper statice NewL și NewLC, situație în care, exemplul de mai sus ar arăta astfel:
static CMyClass* CMyClass::NewLC()
{CMyClass* self = new(ELeave) CMyClass();
CleanupStack::PushL(self);
self->ConstructL();
return self;}
static CMyClass* CMyClass::NewL()
{CMyClass* self = NewLC();
CleanupStack::Pop();
return self;}
După cum se observă metoda NewLC este de folos când s-ar folosi obiectul nou creat apelând o metodă a sa care ar putea să genereze „leave”. Folosind doar NewL vom avea ca rezultat doar memorarea și restaurarea din cleanup stack a aceluiași obiect. NewLC introduce și o convenție privitoare la numele funcțiilor, litera C la sfârșitul metodei. Acesta are semnificația că metoda respectivă lasă ceva memorat în cleanup stack și cel care o apelează are obligația să elibereze stiva la momentul potrivit (când data memorată în stivă nu mai este necesară).
Modelul client/server
Arhitectura sistemului de operare Symbian este bazată pe modelul micronucleului. In cazul acestui model nucleul în sine, din proiectare, se dorește a fi pe cât posibil minim și majoritatea serviciilor oferite de sistemul de operare sunt implementate ca server. Din moment ce majoritatea serverelor rulează procese separate, aceasta duce la comunicarea interproces între aplicațiile client și procesele de pe server. Comunicarea acesta devine o parte esențială a sistemului. In mod uzual serverele furnizează clase folosite de clienți, clase care conțin comunicația interproces. Totuși implementarea efectivă a comunicării interproces nu este vizibilă pentru client.
Majoritatea apelurilor client/server sunt tratate asincron astfel încât apelul clientului nu se blochează până când cererea este tratată. Apelurile asincrone pot fi ușor recunoscute după signatură – au un argument TRequestStatus&. Când o cerere asincronă este rezolvată serverul reține rezultatul într-un obiect TRequestStatus. Rezolvarea cererii este semnalată clientului cu ajutorul unui semafor. Semaforul nu este tratat direct ci serverul folosește metoda RequestComplete (din clasa RThread sau User) și clientul folosește una din metodele WaitFor din clasa User. In continuare se prezintă un exemplu simplu de efectuare a unei cereri asincrone:
TRequestStatus status;
provider.Request( status );
User::WaitForRequest( status );
if( status != KErrNone )
{ // error}
else // ok
{…}
Desigur, în cazul exemplului anterior execuția programului se va bloca la apelul User::WaitForRequest( status ); aplicația nu va mai răspunde la evenimente de tip UI de exemplu. Există două soluții: folosirea mai multor fire de execuție sau o buclă de așteptare. Din moment de firele de execuție conduc la folosirea excesivă a resurselor (fiecare fir are propria lui stivă, de exemplu) nu se recomandă această metodă în Symbian. În schimb cealaltă soluție, bucla de așteptare, este suportată de sistem prin folosirea metodei User::WaitForAnyRequest, care returnează, în funcție de situație, orice cerere care era în așteptare și a fost soluționată. După aceasta, depinde de codul clientului să determine care dintre cereri a fost tratată și cum prelucrează rezultatul. In Symbian OS, de obicei, programatorul nu trebuie să implementeze bucle de așteptare din moment ce sistemul furnizează clasele care conțin aceste bucle.
1.2 Platforma Serie 60
Serie 60 reprezintă o platformă software pentru smartphone-uri care are la bază sistemul de operare Symbian. Aceasta încorporează toate tehnologiile cheie ale domeniului telefoniei mobile pentru a veni în întâmpinarea așteptărilor tot mai ridicate ale publicului larg. Odată cu evoluția sa, Serie 60 a adoptat multe concepte și soluții noi ridicând standardul impus smartphone-urilor. Pe scurt, facilitățile pe care le oferă un dispozitiv bazat pe Serie 60 sunt:
Display color cu rezoluție minimă 176*208 pixeli;
Cameră digitală;
Funcții avansate de telefonie;
Browser pentru Internet;
Palyer pentru muzică și video în diferite formate;
Înregistrare audio și video, etc.
Un rol deosebit în popularizarea Seriei 60 îl are Platforma de Dezvoltare Serie 60. Aceasta reprezintă un pachet software complet pentru smartphone-uri care furnizează baza, partea obligatorie, pentru implementarea tehnologiei Serie 60. Platforma de dezvoltare permite realizarea produselor software destinate Seriei 60. Termenul „Platforma Serie 60” cuprinde tehnologiile folosite de „Platforma de Dezvoltare Serie 60” și în plus o serie de produse software rezultate în urma unor inovații, destinate doar anumitor dispozitive. Platforma de dezvoltare asigură utilizatorului un set garantat de tehnologii permițând în schimb doar producătorului să folosească acel software (numit lead software) care să particularizeze soluțiile sau să aibă acces la facilitățile particulare ale unui dispozitiv anume. Procedând astfel se obține o platformă standard pentru dezvoltarea aplicațiilor cu caracter general, menținându-se totodată un grad ridicat de flexibilitate, acesta fiind un motiv al faptului că Platforma de Dezvoltare Serie 60 este lider pe piața smartphone-urilor.
Arhitectura
Un dispozitiv mobil (smartphone) construit pe Platforma Serie 60 include două mari părți componente, hardware și software, partea software având și ea la bază mai multe componente, așa cum este sugerat în figura 4.
figura 4. – structura unui smartphone Serie 60
Părțile care alcătuiesc platforma Serie 60 sunt colorate în galben și cuprind sistemul de operare, base software și lead software. Acestea vor fi detaliate în continuare.
Sistemul de operare în cazul platformei Serie 60 este, așa cum am mai precizat, Symbian OS (vezi 1.1). El este produsul software pe baza căruia se dezvoltă în continuare platforma.
Base software se referă la totalitatea componentelor software care asigură suportul pentru tehnologiile garantat implementate de toate dispozitivele care folosesc o anumită versiune a platformei Serie 60. Din această cauză este posibil ca o aplicație la dezvoltarea căreia se folosește doar base software să fie portabilă pe toate dispozitivele care au la bază aceeași versiune a platformei Serie 60, fără a modifica deloc sursa programului.
Lead software reprezintă inovațiile tehnologice specifice fiecărui dispozitiv în parte. Este posibil ca pe viitor unele elemente ale lead software să devină parte a base software, odată cu apariția noilor versiuni ale platformei Serie 60. Cei care dezvoltă produse software trebuie să știe că nu același lead software există pe orice dispozitiv care implementează aceeași versiune a platformei. Prin folosirea lead software în dezvoltarea aplicațiilor se limitează portabilitatea.
Sistemul de operare și base software intră în componența Platformei de Dezvoltare Serie 60. Aceasta nu cuprinde și lead software.
Cât despre interfața utilizator Serie 60 stabilește stilul și furnizează API dar nu impune dimensiunea ecranului sau metodele de introducere a datelor. Cei care dețin licențe Serie 60 au libertatea de a-și personaliza interfețele cu utilizatorul. Din acest motiv programatorii trebuie să dezvolte aplicații care folosesc interfața utilizator apelând la operații de scalare din moment ce nu există dimensiuni specificate ale ecranului.
Dezvoltarea aplicațiilor folosind C++
Limbajul de programare nativ al platformei Serie 60 este C++. Programatorii pot utiliza acest limbaj pentru a dezvolta aplicații care să interacționeze cu cele deja disponibile (cum ar fi Imagini sau Agendă Telefonică), și pot avea acces la numeroase tehnologii (cum ar fi conectivitatea prin Bluetooth, prin infraroșu, multimedia, mesaje, servicii de rețea și telefonie). De asemenea pot fi dezvoltate aplicații pentru Serie 60 folosind Java Mobile Information Device Profile (MIDP) 2.0. Astfel se pot dezvolta programe în domeniul browsing XHTML și serviciului de mesaje multimedia (MMS).
Limbajul C++, în varianta folosită de platforma Serie 60 a fost optimizat pentru dispozitive de dimensiuni reduse, cu resurse limitate. Nu este suportată Standard Template Library (STL) și în plus alte modificări au fost făcute față de ANSI C++. Aplicațiile sub Symbian OS sunt dezvoltate folosind o versiune de C++ proprie Symbian-ului, care folosește majoritatea expresiilor specifice C++ dar are un nomenclator unic. ANSI C este suportat de platforma Serie 60, dar rareori folosit.
Folosirea C++ pentru dezvoltarea aplicațiilor permite programatorilor să exploateze la maxim facilitățile platformei și să realizeze o gamă largă de aplicații. De exemplu API-urile disponibile permit crearea aplicațiilor pentru manipularea camerei foto, compunerea și trimiterea mesajelor multimedia, transferul de date cu alte dispozitive prin Bluetooth sau IR, accesul la funcțiile de telefonie și navigare Internet, etc. Aplicațiile scrise în C++ pentru o anume versiune a platformei Serie 60 pot rula pe orice alt dispozitiv care folosește aceeași versiune cu condiția să nu se folosească API care aparțin zonei lead software. Cât despre portabilitatea între diferitele versiuni ale platformei de dezvoltare Nokia face eforturi pentru a minimiza problemele de compatibilitate, deși uneori apar probleme în acest domeniu, probleme care se pot rezolva prin mici ajustări aduse codului programului.
Pentru a instala aplicații pe dispozitive care fac parte din familia Serie 60 există câteva modalități de transferare a programului pe dispozitivul mobil. Acestea ar include folosirea unei conexiuni prin infraroșu, prin Bluetooth sau descărcarea aplicației de pe Internet folosind browserul disponibil pe dispozitivul mobil. Odată descărcată pe mobil aplicația este instalată cu autorul installer-ului de aplicații.
Contextul în care rulează o aplicație sub platforma Serie 60 se numește Avkon. Avkon furnizează o gamă largă de componente destinate interfeței utilizator și implementează clase derivate din Uikon (contextul unei aplicații sub Symbian OS). Analog cu aplicațiile sub Symbian OS, aplicația care rulează pe platforma Serie 60 trebuie să aibă componente obligatorii, derivate din următoarele clase:
CAknDocument – clasă care furnizează clasa de bază pentru documentul aplicației fiind derivată din CEikDocument;
CAknAppUI – toate aplicațiile Avkon derivă din această clasă. Aceasta suportă câteva funcțiuni specifice Avkon: sunetul de taste, accesorii pentru afișare, raportarea erorilor specifice Avkon provenite de la CAknAppUI::HandleError(), etc. Toate aplicațiile uzuale trebuie să derive din această clasă, care la rândul ei este derivată din CEikAppUI. Partea grafică a aplicațiilor va fi derivată din CAknView;
CAknApplication, clasă derivată din CEikApplication este folosită la startarea aplicației. Această clasă modifică CEikApplication prin reimplementarea metodelor PreDocConstructL() și OpenIniFileLC(RFs& aFs). Implicit, fișierele *.ini nu sunt suportate de aplicațiile Serie 60. Dacă totuși se dorește folosirea unui fișier *.ini aplicația va forța implementarea metodei CEikApplication::OpenIniFileLC(RFs& aFs).
Aplicațiile Serie 60 presupun tratarea evenimentelor generate de sistem, cum ar fi apăsarea unei taste, selectarea unor articole dintr-un meniu, etc. Mediul CONE furnizează contextului unei aplicații metodele pentru tratarea evenimentelor.
Modul în care se inițiază o aplicație sub platforma Serie 60 este ilustrat în figura 5.
Figura 5. – Secvența de start a unei aplicații sub platforma Serie 60
Căsuțele colorate în galben conțin task-urile sistemului de operare (Symbian OS), iar cele colorate în turcoaz evidențiază task-urile platformei Serie 60.
Dezvoltarea unei aplicații pe platforma Serie 60 implică crearea, pe lângă fișierele impuse de Symbian, a unor fișiere specifice platformei în sine. Acestea sunt: un fișier care conține definiția componentelor (bld.inf) și un alt fișier care conține definiția proiectului (*.mmp). Un proiect trebuie să aibă un fișier bld.inf și poate avea unul sau mai multe fișiere *.mmp, în funcție de complexitatea proiectului. Fișierele în care se definesc componentele și proiectul vor fi folosite pentru construirea fișierului ABLD.BAT. Acesta este apoi folosit pentru crearea proiectului.
Analiza performanțelor
Crearea unei aplicații software care să realizeze o comunicație între dispozitive mobile folosind soluția prezentată în acest capitol prezintă multiple avantaje. O parte dintre aceste avantaje provin din folosirea tehnologiei Bluetooth pentru realizarea transferului de date iar celelalte avantaje provin din alegerea platformei Serie 60 și, implicit a sistemului de operare SymbianOS, pentru implementarea soft a comunicației. Prin îmbinarea tehnologiei Bluetooth cu o platformă software modernă și special concepută pentru astfel de aplicații rezultă o soluție performantă care îndeplinește cu succes cerințele temei de proiect.
Performanțele soluției care urmează a fi implementate sunt:
Posibilitatea realizării cu ușurință unor conexiuni ad-hoc, punct la multipunct, între dispozitive mobile (maxim opt dispozitive – un master și șapte sclavi);
Realizarea conexiunilor nu necesită nici un fel de echipament hardware suplimentar și nici proceduri de configurare software.
Conectarea sau transferul de date nu sunt influențate de poziționarea în spațiu a dispozitivelor;
Conexiunea rămâne stabilă și în cazul unor interferențe radio, eventual scade viteza transferului;
Conexiunile sunt funcționale pe o distanță suficientă, dat fiind specificul aplicației, 10m;
Conexiunea stabilită poate fi folosită pentru transferul de date de tip text între dispozitivele mobile;
Costul realizării transferului de date în sine este nul;
Folosirea aplicației nu limitează în nici un fel accesul la funcțiile de bază ale unui telefon mobil, dispozitivul putând să efectueze convorbiri și transferuri de date prin rețeaua GSM pe toată durată unei conexiuni Bluetooth;
Portabilitate, atât codul programului cât mai ales algoritmul găsit pot fi cu ușurință folosite pe altă platformă;
Proiectul hardware
Din punct de vedere hadrware, realizarea unei comunicații folosind soluția prezentată în acest capitol nu necesită echipament suplimentar. Pentru transmisia radio se folosește modulul Bluetooth integrat în smartphones. De asemenea softul rulează folosind memoria și procesorul dispozitivului mobil.
In figura 6. se prezintă schema bloc a unui smartphone. Blocurile colorate în galben reprezintă părțile hardware folosite de aplicația propusă ca soluție practică a temei acestui proiect.
figura 6. – schema bloc a unui smartphone
La baza structurii hardware a unui smartphone produs de Nokia stă modulul CS7 (CS7 module). Acest modul conține blocul baseband (BB), bloc ce realizează toate funcțiile logice ale mobilului (control, memorare, procesarea semnalelor digitale, etc.), alimentarea celorlalte blocuri, procesarea digitală a semnalelor de la/pentru rețeaua GSM, comunicația de date cu alte dispozitive. Din blocul BB aplicația utilizează procesorul sistemului și memoria. In acest sens resursele disponibile la un smartphone Serie 60, modelul Nokia 3650 de exemplu, sunt:
Procesor de tip ARM9 (procesor pe 32 de biți care poate lucra atât cu instrucțiuni pe 16 biți cât și pe 32 biți) a cărui frecvență de lucru este ajustabilă intern fiind cuprinsă între 104 și 117 MHz;
Memorie de lucru de tip SDRAM care lucrează cu date memorate pe 16 biți și cu adrese pe 14 biți. Capacitatea memoriei este de 64 Mb (8MB). Viteza memoriei este de 104 MHz;
Memorie nevolatilă de tip FLASH ROM cu capacitatea de 24 MB (3 chip-uri a câte 8 MB). Această memorie folosește o magistrală multiplexată de date și adrese și lucrează la o viteză de 104 MHz.
Tot din modulul CS7 face parte și blocul Bluetooth care este realizat în conformitate cu specificațiile Bluetooth SIG descrise în prima parte a acestui capitol. Acest bloc realizează și controlează legătura radio pe frecvența de 2,45 GHz, fiind folosit și el de aplicația implementată în acest proiect. Schema blocurilor funcționale din cadrul modulului Bluetooth este prezentată în figura 7.
figura 7. – schema bloc a modului Bluetooth
In figura anterioară blocul Bluetooth radio se ocupă de emisia și recepția semnalului de înaltă frecvență, blocurile Bluetooth link controler și Bluetooth link manager & I/O realizând stabilirea și controlul legăturii Bluetooth precum și interfața cu dispozitivul gazdă. In cazul nostru dispozitivul gazdă este reprezentat de un smartphone Serie 60.
Un alt modul hardware folosit pentru implementarea unei comunicații în acord cu cerințele temei de proiect îl reprezintă interfața utilizator (UI module). Acesta este un modul de sine stătător, independent față de modulul CS7. UI module cuprinde display-ul, tastatura, microfon, cască, etc. Componentele folosite de viitoarea aplicație sunt display-ul și tastatura. Display-ul are o rezoluție de 176*208 pixeli și poate afișa 4096 culori folosind 12 biți pentru reprezentarea fiecărui pixel. Tastatura este una standard pentru platforma Serie 60, mai precis pentru dispozitivele care folosesc Symbian OS ca sistem de operare, având drept caracteristici prezența în partea superioară a două softkey, taste a căror funcție depinde de aplicație și a unui joystick cu 5 funcții.
=== _capitolul III – structura soft ===
Capitolul III. Structurare software
O parte însemnată a acestui capitol este dedicată proiectării aplicației software cu ajutorul căreia se va realiza comunicația între dispozitivele mobile. De asemenea se va prezenta modul în care circulă informația între modulele aplicației iar în final se va face o analiză a resurselor și a modului cum sunt folosite de aplicația dezvoltată.
Proiectarea software
In cadrul acestui subcapitol se vor parcurge pas cu pas etapele dezvoltării produsului software. Aceste etape cuprind: analiza, proiectarea sistemului, proiectarea obiectelor și implementarea.
Analiza
Pornind de la cerințele temei de proiect și de la caracteristicile particulare ale soluției alese pentru implementarea comunicației (tehnologia Bluetooth), este evident că produsul software care va trebui să realizeze transferul de date va avea două mari parți distincte: partea care va trebui să ruleze pe dispozitivul sclav (softul pentru sclav) și partea care va trebui să ruleze pe dispozitivul master (softul pentru master). In conformitate cu specificațiile Bluetooth fiecare dintre cele două părți va trebui să îndeplinească funcții bine stabilite pentru a se putea realiza o comunicație de date. In tabelul 1 se prezintă funcțiile ce trebuie îndeplinite de fiecare parte a programului. Tot tabelul 1 se prezintă și denumirile alese pentru obiectele necesare realizării funcțiilor amintite.
La o analiză mai atentă se observă că obiectele introduse prin tabelul 1 sunt necesare dar nu sunt și suficiente pentru realizarea temei de proiect. Nu avem încă un obiect care să realizeze transferul efectiv al datelor de la un dispozitiv la celălalt. Această problemă se poate rezolva fie prin crearea unor obiecte suplimentare, fie prin implementarea acestei funcții de către obiecte deja create. Analizând problema se remarcă faptul că masterul și sclavul trebuie să transmită datele în moduri diferite (masterul comunică cu toți sclavii conectați iar sclavul comunică doar cu dispozitivul master). Dacă am alege varianta creării unor noi obiecte ar trebui create cel puțin două sau chiar patru noi obiecte (câte un emițător și receptor separat atât pentru master cât și pentru sclav). Pentru a nu complica inutil programul se alege varianta implementării comunicației cu ajutorul obiectelor deja introduse în tabelul 1, variantă care în acest moment pare mai simplă. Astfel se optează pentru a realiza transmisia și recepția datelor de către dispozitivul master cu ajutorul obiectului numit Connector și pentru realizarea acelorași funcții ale dispozitivului sclav cu ajutorul obiectului numit Listener.
Tabelul 1. – funcțiile necesare aplicației
In acest moment putem spune că avem un model al noului produs software, model realizat în această fază prin definirea unor obiecte din domeniul aplicației (nu al programării). In urma etapei de analiză s-a reușit determinarea părților principale ale programului (softul pentru master și softul pentru sclav) și determinarea obiectelor care vor contribui la realizarea funcțiunilor dorite (Device discoverer, Service discoverer, Connector, Service advertiser, Listener).
Proiectarea sistemului
Pentru a determina strategia de proiectare care se impune în cazul acestui proiect se studiază platforma software pe care se va lucra. Symbian OS este un sistem de operare realizat el însuși folosind strategia de proiectare orientată pe obiect. Apare așadar ca evidentă, având în vedere și scopul dar și structura programului determinată la punctul anterior, necesitatea optării pentru o strategie de proiectare orientată pe obiect.
Analizând rezultatele etapei anterioare se remarcă lipsa unui modul de program, a unui obiect, care să gestioneze toate acțiunile celorlalte module. Este necesar un modul de program care să apeleze pe fiecare dintre celelalte module atunci când este cazul, să ia deciziile corespunzătoare. Desigur s-ar fi putut încerca implementarea acestor funcții distribuit, în fiecare din obiectele determinate la punctul 1.1. Am ales însă soluția unui nou obiect, denumit sugestiv Engine, pentru claritatea proiectului soft, pentru a limita interacțiunea dintre viitoarele componente ale programului și pentru a ușura procedurile viitoare de modificare sau depanare.
Din punct de vedere al resurselor disponibile viitoarei aplicații trebuie ținut cont de caracteristicile tehnice ale dispozitivelor Serie 60, caracteristici prezentate în capitolul II, subcapitolul 3. Ne propunem să folosim cât mai eficient aceste resurse, în special memoria pentru stocare (FLASH ROM) și memoria de lucru (SDRAM) dar vom ține cont și de încărcarea procesorului.
Proiectarea obiectelor
In concordanță cu strategia aleasă în etapa anterioară, aceea a proiectări orientate pe obiecte, vom detalia structura obiectelor determinate la punctele 1.1 și 1.2 ca fiind necesare realizării produsului software.
Service advertiser trebuie să includă metode pentru:
A face public serviciul oferit, prin adăugarea unui nou element în baza de date pentru descoperirea serviciilor (SDP database) și specificarea canalului/portului la care va fi făcut public serviciul;
A opri facerea publică a serviciului respectiv prin ștergerea elementului corespunzător din baza de date;
Verificarea permanentă a disponibilității serviciului făcut public și modificarea în consecință a înregistrării din baza de date;
Date membre:
Sesiune de lucru pentru descoperirea de servicii;
Bază de date pentru descoperirea de servicii;
Înregistrare de servicii;
Starea înregistrării serviciului.
Listener furnizează metode pentru:
Începerea „ascultării” prin deschiderea unui socket de ascultare. Întoarce canalul/portul pe care se face „ascultarea”;
Tratarea datelor recepționate de sclav;
Tratarea deconectării;
Oprirea procesului de ascultare;
Trimiterea datelor introduse de utilizator către master;
Verificarea existenței unei conexiuni cu un alt dispozitiv;
Setarea securității canalului Bluetooth;
Prelucrarea datelor primite de la master;
Date:
Socket-ul de „ascultare” (listening socket);
Lungimea pachetului de date primit;
Buffer pentru stocarea temporară a datelor primite;
Starea conexiunii;
Starea obiectului Listener (necunoscută, se conectează, așteaptă date, trimite date);
Device discoverer trebuie să furnizeze metodele prin care să se realizeze următoarele funcții:
Să descopere dispozitivele Bluetooth din raza de acoperire;
Sa realizeze o listă cu dispozitivele găsite;
Să „spună” dacă s-au găsit sau nu dispozitive în rază;
Ca structuri de date acest obiect trebuie să implementeze:
Numărul dispozitivelor descoperite;
Lista cu dispozitivele descoperite;
Service discoverer trebuie să aibă funcții membre care să permită:
Descoperirea serviciilor oferite de un anumit dispozitiv, descoperit anterior. Se vor folosi filtre pentru a crește viteza de căutare prin verificarea doar a dispozitivelor care au numărul de identificare al serviciului (service ID) potrivit;
Oprirea procedurii de descoperire a serviciilor;
Să se verifice dacă au fost descoperite servicii utile;
Să se prelucreze datele obținute în urma descoperirii serviciilor utile;
Date membre:
Filtru de căutare a serviciilor;
Portul/canalul găsit în urma descoperirii serviciilor;
Înregistrarea informațiilor despre un anumit dispozitiv;
Lista înregistrărilor informațiilor tuturor dispozitivelor;
Numărul serviciilor descoperite.
Connector implementează metode pentru a realiza următoarele acțiuni:
Conectarea cu un anumit dispozitiv, cunoscând numele și adresa sclavului precum și portul la care sclavul se poate conecta;
Determinarea stării conexiunii;
Trimiterea datelor către sclavi;
Recepționarea datelor de la sclavi;
Prelucrarea datelor recepționate de la sclavi;
Date utilizate:
Numele dispozitivului cu care încearcă să realizeze conectarea;
Adresa dispozitivului mai sus menționat;
Portul dispozitivului sclav la care masterul se poate conecta;
Socket-ul care realizează conectarea;
Buffer pentru stocarea temporară a datelor primite;
Lungimea datelor primite;
Starea obiectului Connector (necunoscută, se conectează, așteaptă date, trimite date).
Din structura obiectelor prezentate până acum se poate observa că anumite structuri de date sunt comune majorității obiectelor. Includ în această categorie datele despre un dispozitiv aflat în raza de acoperire (numele, adresa, și portul la care se poate face conectarea), lista cu datele despre toate dispozitivele aflate în apropiere și constanta care reprezintă identificatorul serviciului cu care lucrăm. Pentru simplificare și înțelegerea mai ușoară a structurii programului am optat pentru crearea unui nou obiect, numit sugestiv Common, care să conțină informația comună majorității obiectelor deja proiectate. Aceste obiecte vor moșteni datele din obiectul Common.
Obiectul Engine fost creat pentru a controla execuția programului în ansamblul său. Așadar el va trebui să includă toate atributele și metodele obiectelor prezentate până acum. In plus Engine va conține metode pentru:
Inițializarea celorlalte obiecte;
Afișarea pe ecran a diferitelor mesaje despre starea programului;
Crearea și trimiterea/recepția mesajelor sau obiectelor către/de la celelalte dispozitive conectate;
Pe lângă aceste obiecte utilizate pentru realizarea comunicației dintre dispozitive mai sunt necesare alte câteva obiecte, în conformitate cu cerințele platformei software folosite (platforma Nokia Serie 60). Aceste obiecte sunt:
Container, care reprezintă de fapt ceea ce utilizatorul vede pe ecran. Acest obiect moștenește metodele obiectului Engine și în plus furnizează metode pentru crearea aspectului grafic al aplicației, desenarea diverselor elemente ale interfeței grafice și pentru preluarea evenimentelor apărute în sistem (selectarea unui articol dintr-o listă, apăsarea unei taste, etc).
ApplicationUI este obiectul care conferă funcționalitate aplicației. Pe lângă metodele pe care le moștenește de la obiectele proiectate până acum acest obiect implementează metode pentru tratarea evenimentelor și pentru controlul aplicației.
Document creează documentul aplicației, componentă necesară oricărei aplicații destinată platformei Serie 60. Acest obiect nu implementează alte metode față de obiectele anterior prezentate, ale căror metode le moștenește.
Application este obiectul responsabil pentru inițializarea codului aplicației. Ca și Document nici acest obiect nu implementează funcții noi, crearea sa fiind impusă de platforma sub care se lucrează.
Tot specific platformei alese este și folosirea fișierelor de tip resursă. Vom folosi astfel de fișiere pentru a declara diverse constante folosite de aplicație, texte standard utilizate de interfața grafică precum și iconițele aplicației. Vor fi necesare următoarele fișiere de resurse:
*.loc este fișierul în care se definesc o parte din șirurile de caractere folosite de aplicație;
*.hrh reprezintă fișierul în care sunt declarate constantele folosite de program (de exemplu identificatorii pentru comenzi) ;
Ambele fișiere, *.loc și *.hrh vor fi incluse într-un fișier de resurse propriu-zis, *.rss, alături de toate celelalte resurse. Acest fișier va fi compilat de către compilatorul de resurse și va rezulta un fișier de tipul *.rsg care va fi folosit de aplicație.
Obiectele rezultate în urma acestei etapei de proiectare sunt prezentate în figura 8. In această figură se prezintă toate obiectele, inclusiv fișierele de resurse necesare realizării unui program care să corespundă temei de proiect. Obiectul Common conține structurile de date comune majorității celorlalte obiecte. Obiectele ServiceAdvertiser și Listener vor ajuta la îndeplinirea funcțiilor dispozitivelor care vor fi selectate ca sclavi. Dispozitivul master va folosi obiectele DeviceDiscoverer, ServiceDiscoverer și Connector. Transferurile de date vor fi efectuate pentru slave și master de obiectele Listener, respectiv Connector. Toate acțiunile vor fi coordonate de Engine care va folosi și informația din fișierul, compilat, de resurse *.rsg. Mai departe programul respectă structura obligatorie a aplicațiilor platformei Serie 60. Doar obiectele Container și ApplicationUI introduc și noi funcții în aplicația noastră, celelalte obiecte, Document și Application având doar o structură standard impusă de platformă.
Figura 8 . – Modelul obiectelor
1.4 Implementarea
In această etapă se urmărește traducerea într-un limbaj de programare a obiectelor (claselor) determinate la punctele anterioare precum și a relațiilor dintre ele. In cazul acestui proiect limbajul ales este Symbian C++. In debutul capitolului se va face o scurtă prezentare a instrumentelor software care folosesc la dezvoltarea aplicațiilor pentru platforma Serie60.
Pentru dezvoltarea de aplicații în Symbian C++ sunt disponibile o serie de kitt-uri de dezvoltare software (SDK). Aceste kitt-uri se utilizează de obicei împreună cu un mediu integrat de dezvoltare (IDE). Diversele versiuni de SDK-uri disponibile pentru platforma Serie 60 lucrează de obicei împreună cu unul dintre următoarele medii integrate: Metrowerks CodeWarrior, Borland C++ Mobile Edition sau Microsoft Visual C++ 6.0. Fiecare SDK include API-urile Serie 60 și Symbian, un emulator al dispozitivelor Serie 60, diverse programe utilitare, exemple de aplicații și documentație.
Pentru dezvoltarea aplicației proiectate în acest capitol se va folosi ca SDK „Nokia Series 60 SDK 1.2 for MW” iar ca mediu integrat de dezvoltare (IDE) a fost ales Metrowerks CodeWarrior.
Crearea scheletului aplicației
Scheletul unei aplicații poate fi ușor creat folosind Application Wizard, un utilitar pus la dispoziție odată cu SDK-ul. Fiecare aplicație are nevoie de un număr unic de identificare (unique identification number – UID), care poate fi obținut gratuit de la Symbian. Numărul alocat actualei aplicații este app_uid=0x101FF1C5. Odată obținut acest număr se deschide Application Wizard și se urmează pașii indicați, completându-se câmpurile cerute de program, printre care și UID. In final utilitarul Application Wizard va genera codul scheletului unei aplicații standard pentru platforma Serie 60. Fișierele generate sunt următoarele:
Fișiere care conțin codul aplicației (*.cpp):
BluetoothPMPExampleApp.cpp – implementarea clasei CBluetoothPMPExampleApp;
BluetoothPMPExampleDocument.cpp – implementarea clasei CBluetoothPMPExampleDocument;
BluetoothPMPExampleAppUI – implementarea clasei CBluetoothPMPExampleAppUI;
BluetoothPMPExampleContainer – implementarea clasei CBluetoothPMPExampleContainer;
Tot din codul sursă al aplicației mai fac parte și următoarele fișiere:
BluetoothPMPExampleApp.h, BluetoothPMPExampleDocument.h, BluetoothPMPExampleAppUI.h, BluetoothPMPExampleContainer – declarațiile claselor corespunzătoare;
Bluetoothpmpexample.loc – string-urile de localizare;
Bluetoothpmpexample.hrh – declarațiile constantelor;
Fișiere de resurse:
BluetoothPMPExample.rss, BluetoothPMPExample_caption.rss, BlueoothPMPExampleaif;
Fișiere pentru construcția proiectului (build files):
Bld.inf și BluetoothPMPExample.mmp;
Fișierul cu informații pentru instalare:
BluetoothPMPExample.pkg.
Fișierele pentru construcția proiectului (build files) sunt folosite de compilator pentru a construi proiectul și respectiv aplicația. Fișierul Bld.inf are un format tipic, prezentat mai jos, care conține calea, către fișierul BluetoothPMPExample.mmp.
PRJ_MMPFILES
..\group\bluetoothpmpexample.mmp
In fișierul BluetoothPMPExample.mmp se specifică toate componentele proiectului. Rolul celorlalte fișiere a fost prezentat în capitolul II.
Crearea obiectelor specifice aplicației
In continuare se va prezenta modul de transpunere în limbajul de programare Symbian C++ a obiectelor proiectate în subcapitolul 1.3. Pentru aceasta vom face o scurtă prezentare a Bluetooth API oferită de platforma Serie 60. După cum se poate vedea consultând anexa I, ca multe tehnologii de comunicații, și Bluetooth este alcătuită dintr-o ierarhie de componente numită stivă. In cazul Symbian OS și implicit pentru platforma Serie 60 Bluetooth API permite aplicațiilor să acceseze nivelele RFCOMM, L2CAP și SDP din stiva Bluetooth. Bluetooth API conține următoarele module importante:
Bluetooth Sockets – prin care se permite accesul la L2CAP și RFCOMM cu ajutorul unei interfețe bazate pe socket-uri, asemănător cu TCP/IP;
Baza de date pentru descoperirea serviciilor (Bluetooth Service Discovery Database) – care conține o parte a protocolului de descoperire a serviciilor, SDP.
Dispozitivul local folosește acest modul pentru a-și înregistra într-o bază de date publică serviciile și atributele serviciilor oferite astfel încât dispozitivele depărtate pot descoperi dispozitivul local și serviciile pe care acesta le oferă.
Agentul de descoperire a serviciilor (Bluetooth Service Discovery Agent) –
Acest modul permite utilizatorului să descopere serviciile disponibile pe un dispozitiv depărtat și să afle atributele acestor servicii.
Managerul de securitate (Bluetooth Security Manager) – permite serviciilor să seteze cerințele de securitate dorite, cerințe pe care conexiunile către acel dispozitiv trebuie să le îndeplinească.
Interfața utilizator pentru selectarea dispozitivelor (Bluetooth Device Selection UI) – asigură API pentru realizarea unui dialog care să permită utilizatorului selectarea dispozitivelor cu care dorește să se conecteze.
Figura 9. arată care sunt legăturile dintre diferitele module ale Bluetooth API. Bluetooth Sockets reprezintă fundamentul pe care se bazează celelalte module pentru a realiza comunicația cu alte dispozitive.
HCI (Host Controller Interface) reprezintă controller-ul interfeței cu dispozitivul gazdă și conține componentele de nivel înalt necesare pentru comunicarea cu partea hardware.
In principiu, sub Symbian socket-urile sunt folosite pentru a descoperi alte dispozitive Bluetooth și pentru a trimite date pe legăturile Bluetooth.
figura 9. – relațiile dintre modulele Bluetooth API
Obiectul Common conține în principal structura unei înregistrări de date despre un dispozitiv Bluetooth. Înregistrarea cuprinde: numele dispozitivului – iDeviceName, adresa dispozitivului – iDeviceAddress și portul folosit pentru comunicație – iDeviceServicePort. Toate aceste date sunt grupate într-o structură numită TDeviceData. Structurile TDeviceData sunt grupate într-o listă de înregistrări numită TDeviceDataList.
Acest obiect mai conține și declarația identificatorului serviciului pe care îl vor oferi dispozitivele pe care rulează aplicația prezentată.
Obiectul ServiceAdvertiser va trebui să facă public serviciul oferit de dispozitivele care vor avea rolul de sclavi pentru aplicația noastră. Fiecare serviciu Bluetooth se reprezintă printr-o înregistrare de serviciu. Symbian OS API nu furnizează o clasă a înregistrărilor de servicii. Baza de date SDP controlează direct accesul la înregistrările de servicii și la atributele serviciilor. Baza de date SDP (SDP database) este răspunzătoare pentru facerea publică a serviciilor pe care le oferă un dispozitiv Bluetooth. Pentru a fi disponibilă mai multor aplicații această bază de date este implementată ca server. Astfel aplicația noastră va trebui să se conecteze la server și să deschidă o sesiune de lucru cu acesta pentru a putea folosi facilitățile pe care le oferă baza de date. Clasa RSdp reprezintă serverul SDP database și permite aplicațiilor să se conecteze la el iar clasa RSdpDataBase reprezintă sesiunea de lucru cu serverul. O descriere completă a celor două clase se găsește în fișierul btsdp.h. Atât sesiunea de lucru cât și baza de date trebuie închise pentru a putea încheia aplicația client. Acest lucru se face prin simpla apelare a funcției Close pentru fiecare în parte.
In cazul aplicației noastre funcția CServiceAdvertiser::StartAdvertiserL(TInt aChannel) realizează și conectarea cu baza de date. Prin apelul User::LeaveIfError(iSdp.Connect()); se conectează aplicația la server iar sesiunea de lucru se deschide efectiv apelând User::LeaveIfError(iSdpDB.Open(iSdp));.
In continuare trebuie creată o înregistrare de serviciu pentru a fi pusă în baza de date. Acesta se realizează cu ajutorul apelului iSdpDB.CreateServiceRecordL(serviceUUID, iRecord);. ServiceUUID reprezintă identificatorul serviciului ales în conformitate cu specificațiile Bluetooth. IRecord reprezintă handle-ul pentru înregistrarea creată.
Acum vom avea o înregistrare în baza de date, dar este o înregistrare goală. Aceasta va trebui completată. In primul rănd se vor adăuga protocoalele pe care le poate folosi serviciul făcut public. Pentru aceasta vom adăuga la înregistrare o listă părinte care va avea două liste-fii conținând fiecare câte unul din cele două protocoale care vor fi folosite de serviciul nostru: L2CAP și RFCOMM. Specificarea protocoalelor utilizate implică folosirea listei de descriptori CSdpAttrValueDES. Identificatorii folosiți pentru a defini L2CAP și RFCOMM sunt KL2CAP respectiv KRFCOMM.
In final la înregistrare se va mai adăuga, pe lângă lista cu protocoale, un nume, o descriere a serviciului și se va seta serviciul ca fiind disponibil. Implementarea completă a funcției CServiceAdvertiser::StartAdvertiserL(TInt aChannel) este prezentată în continuare:
void CServiceAdvertiser::StartAdvertiserL(TInt aChannel)
{
User::LeaveIfError(iSdp.Connect());
User::LeaveIfError(iSdpDB.Open(iSdp));
TUUID serviceUUID(KBT_serviceID);
iSdpDB.CreateServiceRecordL(serviceUUID, iRecord);
CSdpAttrValueDES* protocolDescriptorList = CSdpAttrValueDES::NewDESL(NULL);
CleanupStack::PushL(protocolDescriptorList);
TBuf8<1> channel;
channel.Append((TChar)aChannel);
protocolDescriptorList
->StartListL()
->BuildDESL()
->StartListL()
->BuildUUIDL(KL2CAP)
->EndListL()
->BuildDESL()
->StartListL()
->BuildUUIDL(KRFCOMM)
->BuildUintL(channel)
->EndListL()
->EndListL();
iSdpDB.UpdateAttributeL(iRecord, KSdpAttrIdProtocolDescriptorList,
*protocolDescriptorList);
CleanupStack::PopAndDestroy(protocolDescriptorList);
iSdpDB.UpdateAttributeL(iRecord, KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceName, KBTServiceName);
iSdpDB.UpdateAttributeL(iRecord, KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceDescription, KBTServiceDesc);
UpdateAvailabilityL(ETrue);
}
Mai departe ServiceAdvertiser va implementa metode și pentru oprirea facerii publice a serviciului și pentru marcarea serviciului ca disponibil sau indisponibil. Pentru a nu mai face public un serviciu este necesară ștergerea înregistrării de serviciu din baza de date prin apelul funcției DeleteRecordL(iRecord) asupra bazei de date. iRecord reprezintă înregistrarea de șters. După ștergerea înregistrării, pentru închiderea aplicației care a folosit serverul va trebui închisă sesiunea de lucru și baza de date.
Obiectul Listener va implementa mai multe funcții după cum am văzut în faza de proiectare. Pe scurt, aceste funcții sunt: detectarea și tratarea eventualelor cereri de conectare venite de la master, stabilirea conexiunii cu masterul, setarea securității canalului de comunicație, trimiterea și recepționarea datelor după realizarea legăturii, tratarea datelor recepționate de la master.
Pentru “ascultarea” eventualelor cereri de servicii se va folosi un socket de ascultare (listening socket). Protocolul folosit pentru ascultare este RFCOMM. Funcția care realizează ascultarea este CListener::StartListenerL(). Pentru început este necesar să încărcăm protocolul RMCOMM. Pentru aceasta se apelează User::LeaveIfError(iSocketServ->FindProtocol(_L("RFCOMM"), pdesc)); , unde pdesc reprezintă descrierea protocolului care va fi folosit. In continuare se va deschide un socket de ascultare folosind RFCOMM prin apelarea funcției Open(). După deschiderea socket-ului se setează protocolul care va fi folosit, RFCOMM. Următoarea etapă presupune o cerere către protocol pentru obținerea unui canal liber pe server. Aceasta se realizează apelând funcția GetOpt asupra obiectului RSocket. Aplicația client specifică tipul cererii prin primul argument al funcției și protocolul în următorul argument. Cel de-al treilea argument este folosit pentru reținerea unui întreg care, după execuția funcției, va conține numărul canalului disponibil pe server. Aplicația client creează apoi obiectul TBTSockAddr specificând canalul/portul obținut anterior prin variabila channel. CMessageServer “leagă” apoi obiectul nou creat btsockarrd de portul specificat anterior. În final se setează socket-ul pentru ascultarea eventualelor date care s-ar putea recepționa apelând iListenSock.Listen(). Codul funcției CListener::StartListener() este prezentat in continuare:
TInt CListener::StartListenerL()
{
if ( iState!=ENone )
return -1;
iState=EConnecting;
TProtocolDesc pdesc;
User::LeaveIfError(iSocketServ->FindProtocol(_L("RFCOMM"), pdesc));
iListenSock.Open(*iSocketServ,pdesc.iAddrFamily,pdesc.iSockType,KRFCOMM);
TInt channel;
User::LeaveIfError(iListenSock.GetOpt(KRFCOMMGetAvailableServerChannel,
KSolBtRFCOMM, channel));
TBTSockAddr btsockaddr;
btsockaddr.SetPort(channel);
User::LeaveIfError(iListenSock.Bind(btsockaddr));
iListenSock.Listen(5);
…
return channel;
}
Funcția întoarce un întreg, channel, care va conține canalul folosit pentru ascultare.
Cerințele privitoare la securitatea canalului se setează cu ajutorul funcției SetSecurity(channel). Această funcție folosește o componentă a Bluetooth API numită Bluetooth Security Manager. Aceasta permite unei aplicații client să specifice setările referitoare la securitate. Prin aceste setări se determină dacă este necesară autorizare, autentificare sau criptare pentru conexiunea care se va stabili. Setările de securitate se aplică unui anumit server, pentru un anumit protocol (RFCOMM în cazul nostru) și pe un anumit canal (cel întors anterior de funcția GetOpt). Și Bluetooth Security Manager este implementat tot ca un server. Bluetooth API furnizează aplicației client clasa TBTServiceSecurity care conține facilități pentru specificarea setărilor de securitate. Opțiunile de securitate se specifică simplu prin setări de tipul pornit sau oprit cu ajutorul valorilor booleane. Toate cele trei funcții necesare, SetAuthentication, SetAuthorization și SetEncryption funcționează în acest mod. Security Manager fiind implementat ca server, orice aplicație client care va dori sa-l folosească va trebui să se conecteze la server și să deschidă o sesiune de lucru. Clasa RBTMan asigură conectarea cu serverul. Această clasă este definită în fișierul header btmanclient.h.După stabilirea sesiunii de lucru cu serverul se specifică serviciul, canalul și protocolul pentru care se fac setările de securitate și apoi se fac setările propriu-zise. Implementarea funcției CListener::SetSecurity pentru aplicația noastră este prezentată în continuare:
void CListener::SetSecurityL(TInt aChannel)
{
TRequestStatus status;
RBTMan secManager;
RBTSecuritySettings secDatabase;
TBTServiceSecurity secSettings;
User::LeaveIfError(secManager.Connect());
CleanupClosePushL(secManager);
User::LeaveIfError(secDatabase.Open(secManager));
CleanupClosePushL(secDatabase);
TUid settingsUID;
settingsUID.iUid = KBT_serviceID;
secSettings.SetUid(settingsUID);
secSettings.SetChannelID(aChannel);
secSettings.SetProtocolID(KSolBtRFCOMM);
secSettings.SetAuthentication(EFalse);
secSettings.SetAuthorisation(EFalse);
secSettings.SetEncryption(EFalse);
secDatabase.RegisterService(secSettings, status);
User::WaitForRequest(status);
CleanupStack::PopAndDestroy();
CleanupStack::PopAndDestroy();
}
Funcția RegisterService înregistrează setările la serverul de securitate. Apoi aplicația client așteaptă serverul să înregistreze setările. Dacă apare o eroare aplicația generează un “leave”. In final sesiunea de lucru și conexiunea cu serverul sunt închise (anterior au fost stocate în cleanup stack).
Funcția CListener::StopListener oprește procesul de ascultare închizând sesiunea de lucru și socket serverul.
Pentru recepționarea datelor se folosește funcția CListener::ReceiveData(). Cu ajutorul acestei funcții se face o cerere asincronă către socket pentru recepționarea eventualelor date sosite. Metoda care realizează cererea asincronă este RecvOneOrMore, iar eventualele date sunt stocate temporar în variabila iBuffer.
Trimiterea datelor se face cu ajutorul funcției CListener::SendData(const TDesC8 aData), unde aData reprezintă datele de tip text care vor fi trimise. Pentru trimitere este necesar ca să scriem la socket datele de trimis, aData. Cererea de scriere la socket este asincronă și se face folosind metoda Write(aData, iStatus) care primește ca argument datele de scris. iState se folosește pentru a reține răspunsul cererii asincrone de scriere venit de la “active scheduler”. Datele recepționate sunt tratate cu ajutorul funcției CListener::HandleListenerDataReceivedL (TDesC& aData) care face un callback la observer indicând că s-au primit date. Funcțiile CListener::HandleListenerConnectedL() și CListener::HandleListenerDisconnectedL() reprezintă tot câte un callback la observer indicând conectarea sau deconectarea dispozitivului.
Obiectul DeviceDiscoverer trebuie să descopere dispozitivele Bluetooth active din raza de acțiune a masterului. Aplicația interoghează fiecare dispozitiv din rază și tratează fiecare răspuns pe rând. In cadrul procedurii de interogare se cere adresa și numele dispozitivelor iar pentru aceasta este utilizată clasa RHostResolver, bazată pe socket-uri. TInquirySockAddr reprezintă o clasă a adreselor Bluetooth dar conține pe lângă adrese codul de acces al cererii (Inquiry Access Code – IAC) și include alte clase pentru dispozitive și servicii necesare în cadrul procedurii inquiry. Clasa RHostResolver este definită în fișierul header es_sock.h.
Pentru a face o cerere de aflare a adresei și numelui unui dispozitiv depărtat (inquiry) se procedează astfel:
Se realizează o conexiune cu socket serverul (RSocketServ) și se selectează protocolul care va fi folosit(RSocketServ::FindProtocol()); La nivelul stivei Bluetooth cererile de adresă și nume sunt suportate la nivelul Link Manager;
Se creează și se inițializează un obiect RHostResolver, prin apelul User::LeaveIfError(iResolver.Open(*iSocketServ, pdesc.iAddrFamily, pdesc.iProtocol));
Se setează parametrii cererii. Pentru cererea de adresă și de nume flagurile KHostResInquiry și KHostResName trebuie setate cu ajutorul funcției TInquirySockAddr::SetAction(). Cererea poate începe acum prin apelarea funcției RHostResolver::GetByAddress().
Când GetByAddress() termină execuția, va completa obiectul TNameEntry iEntry cu numele primului dispozitiv găsit iar obiectul TInqurySochAddr iAddr cu adresa aceluiași dispozitiv. Dacă nu s-a găsit nici un dispozitiv aceste obiecte nu sunt completate;
Pentru a descoperi toate dispozitivele se apelează RHostResolver::Next() repetat până când este returnat KerrHostResNoMoreResults.
Pentru aplicația noastră funcțiile care realizează descoperirea dispozitivelor arată astfel:
void CDeviceDiscoverer::DiscoverDevicesL(TDeviceDataList *aDevDataList)
{
iDiscoveredDeviceCount=0;
iDevDataList=aDevDataList;
iDevDataList->Reset();
TProtocolDesc pdesc;
User::LeaveIfError(iSocketServ->FindProtocol(_L("BTLinkManager"), pdesc));
User::LeaveIfError(iResolver.Open(*iSocketServ, pdesc.iAddrFamily, pdesc.iProtocol));
iAddr.SetIAC(KGIAC);
iAddr.SetAction(KHostResInquiry|KHostResName|KHostResIgnoreCache);
iResolver.GetByAddress(iAddr, iEntry, iStatus);
SetActive();
}
void CDeviceDiscoverer::RunL()
{
if ( iStatus!=KErrNone )
{
iObserver->HandleDeviceDiscoveryCompleteL();
}
else
{
TDeviceData *devData = new (ELeave) TDeviceData();
devData->iDeviceName = iEntry().iName;
devData->iDeviceAddr =
static_cast<TBTSockAddr>(iEntry().iAddr).BTAddr();
devData->iDeviceServicePort = 0;
iDevDataList->Append(devData);
iDiscoveredDeviceCount++;
iResolver.Next(iEntry, iStatus);
SetActive();
}
}
In specificațiile Bluetooth sunt două tipuri de IAC pentru diferite moduri de utilizare. Cazul implicit, folosit de această aplicație, este acela când dispozitivul care face căutarea găsește toate dispozitivele care pot fi descoperite în zona sa de acoperire. In acest caz se caută folosind codul generic de acces al cererii (Generic Inquiry Access Code – GIAC). In codul de mai sus am setat folosirea GIAC prin linia iAddr.SetIAC(KGIAC);. In linia următoare este efectuată cererea de căutare simultană a dispozitivelor după adresă și nume. Prin adăugarea |KHostResIgnoreCache nu se caută printre numele deja existente în cache ci se inițiază o nouă căutare. Când s-a terminat căutarea (iStatus!=KerrNone) se apelează iObserver->HandleDeviceDiscoveryCompleteL();. Dacă mai sunt dispozitive de descoperit se adaugă numele și adresa ultimului găsit pe listă executând ramura else{ , se incrementează numărul dispozitivelor descoperite, iDiscoveredDeviceCount++;, se trece la descoperirea următorului dispozitiv, iResolver.Next(iEntry, iStatus); și se așteaptă să se termine tratarea datelor, SetActive();.
Obiectul mai are metode folosite pentru oprirea procesului de descoperire a dispozitivelor void CDeviceDiscoverer::DoCancel(), și pentru a determina dacă s-au găsit sau nu dispozitive în rază, TBool CDeviceDiscoverer::HasDevices().
Acest obiect realizează o listă cu numele și adresele dispozitivelor descoperite.
Obiectul ServiceDiscoverer descoperă serviciile și atributele serviciilor oferite de dispozitivele Bluetooth active găsite de DeviceDiscoverer. Intr-o primă fază interoghează pe rând dispozitivele din raza de acoperire cu privire la serviciile pe care le oferă. Odată găsit un dispozitiv capabil să ofere serviciul căutat aplicația va cere mai multe detalii despre acel serviciu. Aceasta implică cererea atributelor serviciului respectiv. Pentru descoperirea de servicii Symbian OS pune la dispoziție Service Discovery Agent API.
Căutarea serviciilor disponibile într-un piconet poate fi un task mare consumator de timp. Din această cauză API furnizată de Symbian OS pentru realizarea acțiunii de căutare de servicii este asincronă. Aceasta înseamnă că o aplicație client trebuie să dețină o serie de funcții de notificare pentru callback numite funcții observer. Symbian Bluetooth API furnizează clasa de funcții observer MSdpAgentNotifier care definește un set de funcții observer virtuale pure folosite la implementarea aplicației client. Toate cererile de căutare sunt realizate cu ajutorul clasei CSdpAgent. Această clasă este definită în header-ul btsdp.h. Obiectul CSdpAgent se crează specificând obiectul observer de tip MSdpAgentNotifier și adresa dispozitivului Bluetooth. Crearea acestui obiect este posibilă numai atunci când aplicația client a identificat adresa dispozitivului depărtat și a fost deja creat un obiect care implementează o interfață MSdpAgentNotifier.
O altă clasă utilă pentru crearea obiectului ServiceDiscoverer este CSdpSearchPattern. Aceasta este folosită pentru a specifica un anumit model de căutare, adică un anumit set de identificatori ai serviciilor. Orice înregistrare de servicii stocată în baza de date SDP a unui dispozitiv depărtat, care conține unul din identificatorii din modelul de căutare, va fi returnată în timpul procesului de căutare. O aplicație client, ca și în cazul nostru, poate folosi funcția SetRecordFilterL a clasei CSdpAgent pentru a seta lista serviciilor care interesează. Această funcție acceptă o referință la un obiect CSdpSearchPattern.
Funcția care realizează descoperirea serviciilor pentru aplicația prezentată în acest proiect este void CServiceDiscoverer::DiscoverServicesOnDeviceL(TDeviceData *aDevData). Această funcție primește ca argument un pointer către datele unui dispozitiv descoperit anterior pe care urmează să se facă descoperirea serviciilor oferite. Modul de implementare al acestei funcții este prezentat în cele ce urmează:
void CServiceDiscoverer::DiscoverServicesOnDeviceL(TDeviceData *aDevData)
{
if(iSpat)
iSpat->Reset();
delete iSpat;
iSpat=NULL;
if(iAgent)
iAgent->Cancel();
delete iAgent;
iAgent=NULL;
iDevDataChanged=EFalse;
iDevData=aDevData;
iAgent = CSdpAgent::NewL( *this, iDevData->iDeviceAddr );
iSpat = CSdpSearchPattern::NewL();
TUUID serviceUUID(KBT_serviceID);
iSpat->AddL(serviceUUID);
iAgent->SetRecordFilterL(*iSpat);
iAgent->NextRecordRequestL();
}
Pentru a începe procesul de căutare de servicii aplicația apelează NextRecordRequestL();. Aceasta inițiază un proces de căutare asincron. Sistemul de operare va informa aplicația client despre rezultatul procesului prin intermediul clasei MSdpAgentNotifier. Funcția CServiceDiscoverer::NextRecordRequestComplete va fi apelată când se termină căutarea serviciilor. Parametrii acestei funcții sunt aError – care specifică codul unei erori, aHandle – un handle pentru înregistrarea de serviciu, aTotalRecordsCount – un întreg egal cu numărul înregistrărilor găsite care se potrivesc cu filtrul de căutare. Codul unei erori va conține unul din codurile standard ale erorilor sub Symbian; de exemplu KerrNone, care indică succesul operației (nu s-au semnalat erori). Handle-ul înregistrării de serviciu va conține prima înregistrare care se potrivește cu modelul de căutare folosit. Prin apelarea repetată a funcției CSdpAgent::NextRecordRequestL() sistemul de operare va apela funcția NextRecordRequestCompleteL cu handle-ul următoarei înregistrări de servicii care se potrivește cu modelul căutării și incrementând aTotalRecordsCount.
Funcția CServiceDiscoverer::DiscoverServicesL(TDeviceData *aDevData) realizează descoperirea de servicii, pe rând pentru fiecare dispozitiv din lista dispozitivelor descoperite.
După descoperirea serviciilor cu ajutorul funcției NextRecordRequestComplete aplicația va interoga dispozitivul depărtat pentru obținerea unor informații suplimentare cu privire la serviciul făcut public. Funcția CSdpAgent::AttributeRequestL, apelată în cazul nostru în cadrul funcției CServiceDiscoverer::NextRequestComplete(), inițiază procesul de căutare de atribute. Funcția AttributeRequestL este de asemenea asincronă. Sistemul de operare va apela funcția CServiceDiscoverer::AttributeRequestResult de fiecare dată când un atribut îndeplinește criteriile de căutare. De îndată ce toate atributele care au corespuns parametrilor căutării au fost returnate aplicației client funcția observer CServiceDiscoverer::AttributeRequestComplete() va fi invocată. Implementarea funcției CServiceDiscoverer::NextRequestComplete() este prezentată mai jos:
void CServiceDiscoverer::NextRecordRequestComplete(
TInt aError,
TSdpServRecordHandle aHandle,
TInt aTotalRecordsCount)
{
if ( aError==KErrNone && aTotalRecordsCount>0 )
{
iAgent->AttributeRequestL(aHandle, KSdpAttrIdProtocolDescriptorList);
}
else
{
if ( iDevDataChanged )
{
iDevData->iDeviceServicePort=iPort;
(*iDevDataList)[iDeviceIdx]=iDevData;
iDiscoveredServiceCount++;
}
iDeviceIdx++;
if ( iDeviceIdx<iDevDataList->Count() )
{
DiscoverServicesOnDeviceL((*iDevDataList)[iDeviceIdx]);
}
else
{
FinishDiscovery();
iObserver->HandleServiceDiscoveryCompleteL();
}
}
}
La terminarea descoperirii, fiecare atribut va fi procesat cu ajutorul funcției CServiceDiscoverer::VisitAttributeValueL(). Urmărim atributele de tipul UUID. Dacă întâlnim un atribut de tipul RFCOMM UUID valoarea acestui atribut va fi numărul canalului pe care va trebui să se realizeze conexiunea cu dispozitivul depărtat. Acest obiect realizează o listă cu dispozitivele care suportă serviciul căutat pentru aplicația noastră în listă fiind acum menționat și portul pe care se poate face conectarea cu un anumit dispozitiv.
Obiectul Connector realizează conectarea dispozitivului master cu sclavii descoperiți anterior și ale căror servicii corespund aplicației. Tot obiectul Connector trimite date către sclavii cu care a fost stabilită conexiunea, primește și tratează datele venite de la dispozitivele sclav.
Pentru conectarea cu un alt dispozitiv Bluetooth este folosită funcția TRequestStatus CConnector::ConnectL(THostName aName, TBTDevAddr aAddr,
TInt aPort). Această funcție primește ca argumente aName – numele dispozitivului sclav cu care se încearcă conectarea, aAddr – adresa aceluiași dispozitiv și aPort – portul sclavului, la care se face conectarea. Pentru conectarea cu dispozitivul dorit se încarcă mai întâi protocolul care se va folosi, RFCOMM și se deschide o sesiune de lucru cu socket serverul (obiectul iSock de tip RSocket ) specificând in același timp și protocolul folosit. Aceasta se realizează prin apelul User::LeaveIfError(iSock.Open(*iSocketServ, _L("RFCOMM")));. Se creează apoi obiectul addr de tip TBTSockAddr căruia i se setează portul și adresa dispozitivului sclav. Se încearcă apoi conectarea la socket la adresa sclavului. Cererea de conectare este asincronă și rezultatul acestei cereri va fi reținut în variabila status cu ajutorul funcției User::WaitForRequest(status);. Dacă s-a reușit conectarea (status==KerrNone) se recepționează date, tot asincron, apelând funcția WaitAndReceive();. Implementarea funcției care realizează conectarea dispozitivelor în cazul acestei aplicații este dată în continuare:
TRequestStatus CConnector::ConnectL(THostName aName, TBTDevAddr aAddr,
TInt aPort)
{
iName=aName;
iAddr=aAddr;
iPort=aPort;
TProtocolDesc pdesc;
User::LeaveIfError(iSocketServ->FindProtocol(_L("RFCOMM"), pdesc));
User::LeaveIfError(iSock.Open(*iSocketServ, _L("RFCOMM")));
TBTSockAddr addr;
addr.SetBTAddr(iAddr);
addr.SetPort(iPort);
TRequestStatus status;
iSock.Connect(addr, status);
User::WaitForRequest(status);
if ( status!=KErrNone )
{
return status;
}
iState=EConnecting;
WaitAndReceiveL();
return status;
}
Variabila satus, întoarsă de funcție, reține codul unei erori standard sub Symbian, eroare care ar putea apărea în urma încercării de conectare. In cazul unei conectări reușite status va reține codul KerrNone.
Deconectarea se realizează, în modul clasic pentru aplicațiile sub Symbian, închizând serverul și sesiunea de lucru cu acesta. Funcția care realizează deconectarea este CConnector::DisconnectL().
Trimiterea datelor la dispozitivul cu care s-a realizat conexiunea este o problemă simplă de scriere la socket-ul RSocket la care aplicația este conectată. Trimiterea datelor se face cu ajutorul funcției CConnector::SendDataL(const TDesC8& aData). Ca și în cazul obiectului Listener datele de transmis sunt de tip text și sunt reținute în aData.
Tot similar cu cazul obiectului Listener se realizează și recepționarea datelor. Pentru aceasta se folosește funcția CConector::WaitAndReceive(). Se face o cerere asincronă către server folosind RecvOneOrMore() și se așteaptă primirea datelor cu SetActive().
Funcția void CConector::RunL() controlează execuția diverselor task-uri ale obiectului Connector monitorizând starea conexiunii cu ajutorul variabilei iState. In funcție de conținutul lui iState se decid acțiunile care vor fi efectuate: conectare, primire și tratare date, trimitere date. La primirea datelor acestea sunt stocate într-un buffer iBuffer apoi transmise funcției care se ocupă de tratarea datelor primite de master HandleConnectorDataReceived().
Obiectul BluetoothPMPExampleEngine coordonează execuția întregii aplicații. Acest obiect moștenește toate funcțiile obiectelor implementate până acum. Una din metodele implementate de acest obiect este CBluetoothPMPExampleEngine::ShowMessageL(const TDesC& aMsg, TBool aReset=false). Această metodă este folosită pentru a afișa pe ecran textul referit de aMsg. Dacă aReset este false mesajul curent va fi adăugat la precedentul, în caz contrar mesajul anterior va fi șters înainte de afișarea noului mesaj. Pe display se pot afișa maxim opt linii de text.
Funcția CBluetoothPMPExampleEngine::StartSlaveL() setează aplicația pentru a rula pe un dispozitiv sclav, apelând StartAdvertiserL(channel) de la obiectul ServiceAdvertiser.
O altă funcție importantă a obiectului este CBluetoothPMPExampleEngine::ConnectDevicesL() care conectează la dispozitivul master maxim șapte dispozitive sclav. In acest scop se apelează pentru fiecare sclav funcția ConnectL asupra unui obiect de tip Connector.
Funcțiile CBluetoothPMPExampleEngine::SendMessage() și CBluetoothPMPExampleEngine::SendObject() trimit un mesaj respectiv un obiect de la sclav către master sau de la master către toți sclavii, după caz. Înainte de trimiterea textului acesta este preluat de la utilizator prin folosirea unui dialog standard și apoi prelucrat pentru a se potrivi cu tipul datelor pe care le poate trimite aplicația, text TDesC8. Textul trimis poate avea maxim 20 de caractere. Obiectele pe care le poate trimite aplicația sunt obiecte demonstrative, care nu conțin informație.
Datele recepționate atât de sclav cât și de master vor fi prelucrate cu ajutorul funcțiilor CBluetoothPMPExampleEngine::HandleListenerDataReceivedL(TDesC& aData) respectiv CBluetoothPMPExampleEngine::HandleConnectorDataReceivedL(THostName aName,TDesC& aData). Prelucrarea implică determinarea tipului datelor primite, text propriu-zis sau un obiect, formatarea textului și afișarea.
Acest obiect mai conține funcții pentru descoperirea de dispozitive și de servicii, deconectarea dispozitivelor, afișarea dispozitivelor conectate, tratare evenimentelor de tipul descoperirea dispozitivelor sau serviciilor s-a încheiat sau dispozitivele au fost deconectate, etc. Toate aceste funcții au fost implementate efectiv în interiorul obiectelor prezentate până acum, noua implementare nu aduce decât noutăți legate de afișarea pe ecran a diverselor mesaje sau aplicarea unei funcții deja implementate anterior, succesiv, pentru mai multe dispozitive.
Obiectul BluetoothPMPExampleAppUI, deși este un obiect standard generat de Series60 Application Wizard mai conține și o secvență de cod specifică aplicației. Această secvență are două părți: una prin care se crează într-un meniu standard opțiunile specifice cazului în care aplicația rulează ca master sau ca slave și o a doua parte prin care se tratează comenzile primite de aplicație prin selectarea articolelor de meniu. Tratarea acestor comenzi se face cu ajutorul funcției CBluetoothPMPExampleAppUi::HandleCommandL(TInt aCommand).
Restul codului acestui obiect corespunde implementării sale standard.
Fluxul de informație
Fluxul de informație în cadrul aplicației care satisface cerințele temei acestui proiect este reprezentat în figura 10. De remarcat că diagrama prezintă doar felul în care circulă informația nu și felul în care este controlată execuția aplicației. O diagramă în care se reprezintă modul în care se controlează execuția fiecărei etape a aplicației se va prezenta în capitolul următor, odată cu prezentarea modului de utilizare al aplicației.
In figura 10 blocurile care reprezintă obiecte ale aplicației noastre sunt colorate în galben.
Primul pas pentru realizarea conexiunii este începerea procesului de descoperire de dispozitive. Pentru aceasta dispozitivul master trimite cererea notată cu 1 pe figură. Această cerere vizează adresa și numele dispozitivelor Bluetooth din zonă, informații pe care dispozitivele interogate le pot pune la dispoziția master-ului fără a rula aplicația prezentată în acest proiect. Fiecare dispozitiv Bluetooth activ are un nume și o adresă. Dispozitivele active vor răspunde la cererea 1 comunicând în etapa 2 datele cerute de master (numele și adresa). Obiectul DeviceDiscoverer face o listă cu datele dispozitivelor găsite listă folosită mai apoi de obiectului ServiceDiscoverer (5).
Figura 10. – fluxul de date care duce la stabilirea conexiunii Bluetooth
Pe dispozitivul sclav rulează obiectul ServiceAdvertiser care pune în baza de date SDP database identificatorii și atributele serviciilor disponibile pe acest dispozitiv (3). Tranziția 3 este bidirecțională deoarece ServiceAdvertiser poate citi, șterge sau modifica înregistrările din baza de date.
Obiectul ServiceDiscoverer, care rulează pe dispozitivul master, realizează interogarea tuturor dispozitivelor din lista cu dispozitivele găsite de DeviceDiscoverer. Interogarea (6) are drept scop determinarea dispozitivelor care pot furniza serviciul dorit de master. Pentru minimizarea timpului căutării serviciilor se folosește un tipar pentru căutare. Căutarea constă în citirea informațiilor puse anterior în SDP database de către obiectul ServiceAdvertiser. Răspunsul așteptat (7) conține identificatorul serviciului căutat. După verificarea bazelor de date ale tuturor dispozitivelor din lista cu dispozitive descoperite, ServiceDiscoverer face o listă a dispozitivelor care oferă serviciul dorit. Această listă este folosită mai apoi pentru realizarea unei noi interogări(8) pentru aflarea atributelor serviciului descoperit odată cu răspunsul (7). In cazul de față singurul atribut necesar este portul pe care se poate face conectarea cu dispozitivul sclav și acesta se așteaptă a fi obținut prin răspunsul 9.
Cererile de servicii (6) și cererile de atribute (8) sunt de fapt detectate de obiectul Listener care rulează pe sclav și apoi direcționate către SDP database. Din acest motiv este figurată o săgeată bidirecțională (4) între Listener și SDP database.
După obținerea răspunsurilor (9) ServiceDiscoverer face o nouă listă care conține numele, adresa și portul la care se poate realiza conectarea pentru fiecare dispozitiv din rază de acțiune care oferă serviciul necesar aplicației noastre. Această listă este similară unui tabel care ar avea următoarele rubrici:
Tabelul 2. – structura listei realizate de ServiceDicoverer
In continuare lista este transmisă obiectului Connector care va încerca să se conecteze cu fiecare dispozitiv din listă la portul specificat. Pentru aceasta va face câte o cerere de conectare (11). Obiectul Listener, dacă acceptă conexiunea, trimite răspunsul (12). Din acest moment conexiunea între cele două dispozitive este realizată (13) și poate fi folosită pentru transmiterea datelor. Datele de la utilizator sunt preluate cu ajutorul obiectului BluetoothPMPExampleEngine, transpuse în formatul corespunzător pentru a fi trimise pe legătura Bluetooth și apoi expediate cu ajutorul unuia dintre cele două obiecte Listener sau Connector, după caz. La primire obiectul Connector sau Listener preia datele, le transmite obiectului BluetoothPMPExampleEngine care le prelucrează și le afișează pe display.
Alocarea resurselor
Sistemul de operare Symbian OS, sub care a fost programată aplicația prezentată în acest proiect este special conceput pentru a rula pe dispozitive cu resurse limitate. Limbajul de programare folosit la dezvoltarea aplicației prezintă și el numeroase facilități în acest sens, după cum au fost prezentate în capitolul II. Toate acestea contribuie la buna gestionare a resurselor sistemului pe care va rula produsul software.
După compilarea codului și după construirea aplicației pentru platforma pe care va rula rezultă un fișier BtPico.sis care are o dimensiune de 12 kB. Acest fișier va fi transferat pe dispozitivul mobil
După instalarea pe dispozitivul mobil aplicația are o dimensiune de 21 kB. Aceasta înseamnă că ea va utiliza aproximativ 0.0875% din memoria pentru stocare (FLASH ROM) de minim 24 MB cu care este echipat de producător un smartphone. Nu am luat în considerare în acest calcul faptul că, de obicei, la dispozitivele Serie 60 se poate atașa un card de memorie (de tip SD sau MMC) cu capacitate de până la 1 GB. Acest aspect face ca dimensiunea ocupată de aplicația BtPico în memoria unui smartphone să fie infimă.
In momentul lansării în execuție aplicația BtPico folosește 56 kB (20 kB pentru stivă și 36 kB pentru „heap”) din memoria de lucru (SDRAM) a dispozitivului pe care rulează. In cazul unui smartphone, care are o memorie RAM de minim 4 MB, înseamnă un grad de utilizare de aproximativ 1,4%. Spre comparație aplicația care permite realizarea convorbirilor telefonice folosește 300 kB din memoria de lucru adică aproximativ 7,5% iar aplicația care permite înregistrarea/redarea unor secvențe video folosește 628 kB, adică 15,7%. In concluzie aceste trei aplicații pot rula simultan fără probleme din punct de vedere al memoriei RAM utilizate.
Sistemul pe care va rula aplicația dispune de un procesor ARM9 care lucrează la o frecvență de minim 104 MHz. Întrucât funcțiile specifice stabilirii unei comunicații Bluetooth și transmiterii datelor sunt în cea mai mare parte realizate de modului Bluetooth încorporat și nu de procesor nu apar probleme în ceea ce privește utilizarea procesorului.
In concluzie nu există probleme legate de utilizarea excesivă a unor resurse sau de insuficiența acestora, deci se poate spune că aplicația folosește eficient resursele disponibile.
Câteva rezultate privind timpii de execuție ai diverselor comenzi ale aplicației sunt prezentate în capitolul următor în secțiunea dedicată prezentării rezultatelor experimentale.
=== _capitolul IV – rezultate exp ===
Capitolul IV. Rezultate experimentale și dezvoltări viitoare
In cadrul acestui capitol se va prezenta modul în care lucrează aplicația, rezultatele obținute în urma experimentării diverselor scenarii de utilizare dar și posibilitățile de a dezvolta noi aplicații bazate pe aplicația dezvoltată în acest proiect.
Crearea aplicației care va rula pe dispozitivele mobile
Odată editat și compilat codul sursă trebuie construită aplicația care va rula pe dispozitivele mobile. Pentru aceasta se deschide o fereastră de comandă și se alege directorul în care este salvat proiectul. Se introduc comenzile:
bldmake bldfiles – rezultând în directorul curent un fișier ABLD.BAT, folosit de comanda următoare;
abld build thumb urel – care va construi un fișier executabil cu instrucțiuni THUMB (instrucțiuni pe 16 biți pentru procesoare ARM);
makesis BtPico.pkg – va rezulta fișierul BtPico.sis, acesta fiind un fișier care poate fi instalat sub Symbian (Symbian instalation system). BtPico.sis poate fi transferat pe dispozitivul mobil folosind, de exemplu, un port IR sau poate fi trimis ca mesaj prin rețeaua GSM. Acest transfer este sugerat prin săgețile trasate cu linie punctată în figura 11. Fișierul este automat recunoscut de sistemul de operare Symbian și cu ajutorul Installer-ului de aplicații va putea fi instalat cu ușurință pe dispozitiv.
In urma instalării va apărea în meniul principal iconița programului. Selectând iconița se poate rula aplicația instalată. Folosind facilitățile acesteia se va putea crea o rețea de tip piconet compusă din dispozitivele Bluetooth pe care rulează aplicația, rețea sugerată prin săgețile trasate cu linie continuă în figura 11.
figura 11. – dezvoltarea produsului software (BtPico), instalarea pe diverse dispozitive Serie 60 și realizarea comunicației Bluetooth
2. Descrierea modului de realizare a unui transfer de date
Aplicația prezintă o interfață grafică folosită pentru a prelua date și comenzi de la utilizator dar și pentru a afișa utilizatorului diverse mesaje referitoare la stadiile în care se află programul. Modul de realizare a unei conexiuni este prezentat în figura 12. Pentru stabilirea unei conexiuni se pornește aplicația și se apasă tasta soft din stânga, „Options”. Din meniul care se deschide se selectează „Descoperă dispoz.” (2) pentru dispozitivul care va juca rolul de master sau „Incepe sclav” (1) pentru celelalte dispozitive. Comanda „Incepe sclav” are ca efect comportarea dispozitivului respectiv ca sclav. Aceasta implică rularea metodelor din obiectul ServiceAdvertiser apoi din Listener.
Pentru început se afișează confirmarea faptului că aplicația începe să ruleze ca sclav „Inițializare sclav…”, apoi este afișat portul/canalul la care se face ascultarea prin mesajul „Canal folosit:”. La terminarea inițializării socket-ului de ascultare se afișează mesajele „Inițializat sclav!” și „Aștept cereri conectare”. Din acest moment aplicația așteaptă cererile masterului pentru a se putea stabili conexiunea.
figura 12. – stabilirea unei conexiuni Bluetooth folosind aplicația BtPico
Dispozitivul master, după ce primește comanda „Descoperă dispoz. ”, va rula metodele obiectului DeviceDiscoverer. In acest moment pe ecran se va afișa „Căutare dispozitive, așteptați…”. După terminarea procesului de descoperire de dispozitive pe ecran va apare mesajul „Dispoz în raza: ” urmat de numele dispozitivelor găsite în rază sau, dacă nu s-au găsit dispozitive se va afișa „Nu s-au descoperit dispoz. în raza!”. Vom considera cazul normal, acela al existenței dispozitivelor în rază altfel încercarea de stabilire a unei conexiuni nu ar avea sens.
După ce vede mesajul „Dispoz în raza: ” utilizatorul dispozitivului master va putea alege din meniul „Options” opțiunea „Descoperă serv.”(3). Dispozitivul master va afișa mesajul ”Căutare servicii, așteptați…” , va căuta serviciile dorite folosind obiectul ServiceDiscoverer și va întoarce mesajul „S-a găsit serviciul pe:” urmat de numele dispozitivelor pe care a fost găsit serviciul. Dacă serviciul dorit nu a fost găsit se va afișa „Serv. nu a fost găsit!”. Considerăm că sunt dispozitive în rază care oferă serviciul util masterului, caz în care, utilizatorul dispozitivului master, folosind același meniu „Options” poate da comanda „Stabilește conex.” (4).Această comandă are ca efect conectarea dispozitivului master cu toți sclavii care satisfac cerințele. După efectuarea comenzii pe ecranul masterului va apărea mesajul „Dispoz. sclav conectate: ” urmat de numele sclavilor cu care s-a realizat conectarea iar pe ecranul dispozitivului sclav va apărea mesajul „Conectat la master!”. In acest moment s-a stabilit o conexiune între dispozitivele implicate în piconet și această conexiune poate fi folosită pentru a trimite date de tip text sau obiecte.
Pentru trimiterea unui text de maxim 20 de caractere se selectează din meniul „Options” opțiunea „Trimite text”. Se va deschide o fereastră de dialog pentru introducerea textului dorit apoi textul se poate trimite folosind tasta „OK”. Dacă textul este trimis/recepționat de master pe ecranul acestui dispozitiv va apărea numele sclavului care a trimis textul sau căruia i-a fost trimis textul alături de textul trimis/recepționat. In cazul dispozitivului sclav, acesta nu afișează decât textul trimis/recepționat deoarece se subînțelege că schimbul de date s-a efectuat cu masterul
Aplicația poate trimite și obiecte demonstrative, fără conținut. Pentru trimiterea unui astfel de obiect se selectează din meniul „Options” opțiunea „Trimite obiect”. Pe ecranul celui care trimite va apărea confirmarea faptului că obiectul a fost trimis iar pe ecranul celui care recepționează va apărea mesajul care informează că s-a primit un obiect și, în cazul masterului va apărea numele sclavului care a trimis obiectul „Ob. rec. de la:”. După acest mesaj se va afișa și conținutul obiectului.
Pentru încheierea sesiunii de comunicare și ieșirea din aplicație se apasă tasta soft din dreapta „Back” sau „Exit” în funcție de context, sau se selectează comanda „Ieșire” din meniul „Options”. Dacă masterul încheie aplicația pe ecranul dispozitivelor sclav va apărea mesajul „Dispoz deconectat! Mod sclav oprit”.
Rezultate experimentale
In cadrul experimentelor efectuate asupra funcționării aplicației BtPico s-a încercat simularea mai multor scenarii de utilizare. Au fost avute în vedere situațiile cele mai defavorabile precum și diversele situații care ar putea să apară în cazul când aplicația ar fi folosită de un utilizator obișnuit.
Un prim experiment a urmărit determinarea distanței maxime la care se poate realiza o conexiune Bluetooth și se pot transmite date pe acea conexiune. S-a observat că într-o încăpere în care nu există obstacole distanța maximă la care se poate realiza o conexiune se apropie de distanța prevăzută de standardul Bluetooth și anume 10 metri. Dacă însă între dispozitivele care se dorește a fi conectate apar diverse obstacole sau dispozitivele sunt situate în camere diferite această distanță scade destul de mult, până la 5-6 metri. Distanța depinde foarte mult de natura obstacolelor, ea scăzând mult în cazul interpunerii între dispozitive a unor obstacole care conțin diverse elemente metalice. La distanțe mai mari dispozitivele Bluetooth nu se pot descoperi unul pe celălalt, rezultatul comenzii „Descoperă dispoz.” fiind mesajul „Nu s-au descoperit dispoz. în rază!”.
O a doua etapă a experimentului a presupus aducerea a două dispozitive, unul în raza de acoperire a celuilalt și stabilirea unei conexiuni. Odată stabilită conexiunea a început transmisia de date depărtând progresiv dispozitivele. Intr-o încăpere fără obstacole transferul de date s-a putut efectua până la o distanță maximă de aproximativ 10 metri. In cazul prezenței obstacolelor rezultatele au fost asemănătoare realizării conexiunii. Totuși a fost descoperită o problemă. Atunci când dispozitivele ies unul din raza de acțiune a celuilalt, în cazul masterului, acest lucru nu poate fi semnalat utilizatorului. Astfel pe ecranul dispozitivului master, dacă se încearcă trimiterea unor date, apare în continuare confirmarea de trimitere chiar dacă textul trimis nu mai apare pe ecranul dispozitivului sclav care ar trebui să-l recepționeze. Această problemă ar putea fi rezolvată prin introducerea unor mesaje suplimentare, trimise automat, cu rolul de confirmare la primirea datelor. Mesaje pot fi trimise și periodic pentru a verifica dacă un dispozitiv se mai află în raza de acoperire a masterului Nu trebuie să uităm totuși că tehnologia Bluetooth și implicit aplicația pe care o testăm, este destinată transferului de date pe distanțe scurte. In acest caz se presupune că între utilizatorii care fac transfer de date folosind dispozitivele mobile există contact. In acest fel, dacă este cazul, își pot confirma foarte simplu primirea mesajelor.
Un alt inconvenient minor descoperit este legat de situația în care un dispozitiv iese din aria de acoperire a masterului apoi intră din nou. In acest caz conexiunea inițială nu mai este valabilă fiind necesar ca masterul să reia procedura de stabilire a unei conexiuni.
O concluzie importantă se referă la stabilitatea legăturii Bluetooth. Atât timp cât dispozitivele conectate rămân în raza de acoperire transferul de mesaje nu este practic influențat de perturbațiile obișnuite care ar putea să apară (folosirea telefoanelor mobile, calculatoare, radiouri, alte dispozitive Bluetooth). Acest lucru era previzibil având în vedere banda de frecvență diferită în care lucrează unele dispozitive menționate dar și ținând cont de specificațiile Bluetooth care menționau faptul că în cazul unor perturbații, legătura radio de păstrează, fiind posibilă doar micșorarea vitezei de transfer. In cazul trimiterii mesajelor text scăderea vitezei de transfer nu are o influență vizibilă.
Un alt experiment a testat dacă aplicația poate funcționa simultan cu rularea altor aplicații pe același dispozitiv. Astfel s-a deschis aplicația BtPico pe un anumit dispozitiv și după stabilirea unei conexiuni se face schimb de mesaje text cu un alt dispozitiv. In acest timp se apelează primul dispozitiv. Sistemul de operare informează utilizatorul despre primirea unui apel. Utilizatorul poate răspunde la apel apoi în timp ce vorbește la telefon (de exemplu folosind un dispozitiv hands-free) poate trimite în continuare mesaje text folosind aplicația BtPico sau poate stabili noi conexiuni, etc. Deci aplicația poate rula simultan cu alte aplicații datorită faptului că Symbian este un sistem de operare multitasking dar trebuie remarcat și că resursele sistemului sunt destul de eficient folosite de aplicația noastră. Din punct de vedere al timpilor necesari execuției comenzilor, comanda care necesită cel mai îndelungat timp de execuție este „Descoperă dispoz.”. Descoperirea dispozitivelor durează aproximativ 15 secunde. Durata descoperirii serviciilor depinde de numărul dispozitivelor descoperite anterior și este de aproximativ 1-2 secunde pentru fiecare dispozitiv pe care se face căutarea. Duratele de execuție ale celorlalte comenzi sunt foarte mici, pentru utilizator ele se execută practic instantaneu.
Oportunități de dezvoltare
Dispozitivele mobile au devenit rapid o parte integrantă a vieții noaste de zi cu zi. Pana nu demult cele mai multe dispozitive nu aveau interfețe compatibile pentru comunicații de date intre ele sau, dacă aveau, interfețele necesitau conexiuni prin cablu si proceduri de configurare greoaie. Evident se impunea găsirea unei soluții care să elimine cablurile și să simplifice etapele de configurare pentru a facilita conexiuni între dispozitive, ori de cate ori era nevoie. Legăturile Bluetooth par a fi soluția ideală. Sunt ieftine, simplu de realizat iar tehnologia este universal adoptată de producătorii de dispozitive mobile.
Partea cea mai importantă a aplicației BtPico este că realizează conexiuni Bluetooth între dispozitive mobile. Odată realizate, aceste conexiuni pot fi folosite pentru transmiterea oricăror tipuri de date. Transmiterea unor obiecte mai complexe poate constitui o temă foarte interesantă a unui alt proiect care să folosească aplicația dezvoltată aici. Acest lucru presupune documentare și folosirea altor părți din API puse la dispoziție de platforma Serie 60. De exemplu se pot imagina aplicații care să transmită cărți de vizită electronice. Serie 60 suportă un format universal pentru trimiterea cărților de vizită electronice numit vCard. Astfel un dispozitiv master ar putea să trimită un vCard – conținând nume, prenume, număr de telefon, email, etc – simultan la mai multe dispozitive sclav. Aceste dispozitive pot salva automat în agendă datele primite și pot răspunde fiecare trimițând masterului propria carte de vizită. Alte aplicații pot viza transferul de imagini, de sunete sau comunicația Bluetooth cu dispozitive mobile specializate pentru o anumită operațiune, de exemplu un cititor de coduri de bare. Folosind un astfel de cititor și unul sau mai multe dispozitive mobile gen smartphone sau PDA se pot dezvolta instrumente utile pentru inventarierea comodă a diverselor obiecte.
Desigur, se pot imagina multiple aplicații bazate pe transferul de date printr-o legătură Bluetooth. Marea majoritate a producătorilor de dispozitive mobile prevăd aparatele proprii cu module Bluetooth încorporate. Suportul furnizat de Platforma de dezvoltare Serie 60 este și el apreciabil, așa că există numeroase oportunități foarte interesante de dezvoltare a aplicației prezentate în cadrul acestei lucrări.
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Comunicatie Intre Dispozitive Mobile Folosind Tehnologia Bluetooth (ID: 149245)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
