3.1. Perencanaan Aplikasi 3.1.1. Arsitektur Sistem.
Dalam pembuatan aplikasi Java untuk chatting pada telepon selular dengan media Bluetooth ini memakai bahasa pemrograman Java dengan jenis atau edisi bahasa pemrogaraman Java yang digunakan adalah Java 2 Micro Edition (J2ME). Hal tersebut dikarenakan sebagian besar telepon selular yang ada pada saat ini menggunakan Java sebagai bahasa pemrograman dasar bagi aplikasi telepon selular. Selain itu, menurut Antonius Aditya Hartanto dalam bukunya yang berjudul Java 2 Micro Edition : Mobile Interface Device Programming, penggunaan aplikasi yang dibuat dengan bahasa pemrograman Java dapat dikatakan cukup aman. Hal tersebut dikarenakan jika terjadi kesalahan atau error, maka dampak yang terburuk hanya akan mengacaukan Java Virtual Machine (JVM) sebagai lingkungan untuk menjalankan aplikasi Java tersebut.
Koneksi aplikasi chatting ini akan dibuat koneksi antar 2 unit (peer to peer) dengan status hubungan yang terjadi adalah server dengan client. Unit yang berstatus sebagai server akan menyediakan pelayanan (service) untuk mengadakan chatting bagi unit yang berstatus sebagai client. Hubungan ini dipilih dengan alasan untuk memudahkan manajemen koneksi dan jaringannya.
Sistem server yang ada, dapat dibagi menjadi 2 jenis, yaitu : run-before- connect services dan connect-anytime services. run-before-connect service adalah sistem yang untuk terjadinya koneksi, aplikasi server harus berjalan terlebih dahulu dan dalam posisi siap untuk menerima client, sebelum aplikasi client dapat mengadakan proses meminta dan melakukan koneksi pada server. Sedangkan connect-anytime services adalah sistem yang dimana client dapat melakukan koneksi kapan saja, tidak terpengaruh dengan aktif atau tidaknya aplikasi server.
connect-anytime services dapat dilakukan pada waktu server dalam posisi tidak aktif, dikarenakan service record dalam Service Discovery Database (SDDB) tidak dihapus, sehingga client masih dapat melakukan koneksi dan aplikasi server akan menjadi aktif secara otomatis jika ada koneksi dari client. Oleh karena
aplikasi chatting ditujukan untuk telepon selular yang mempunyai keterbatasan memori (RAM), maka jenis sistem server yang dipakai adalah sistem run-before- connect service. Gambar 3.1. adalah gambar arsitektur sistem dari aplikasi Java untuk chatting pada telepon selular dengan menggunakan Bluetooth.
Gambar 3.1. Arsitektur sistem aplikasi chatting.
Berdasarkan gambar 3.1. diatas, arsitektur sistem aplikasi ini terbagi atas 3 layer. CLDC bertugas untuk mengatur koneksi pada telepon selular, MIDP bertugas mengatur jalan dan interface aplikasi pada telepon selular, dan Bluetooth bertugas untuk mengadakan koneksi dengan unit lain melalui class dan protokol yang ada pada Bluetooth.
3.1.2. Class dan Protokol
Aplikasi Chatting ini memakai beberapa class dan protokol-protokol yang berhubungan dengan MIDP, CLDC maupun Bluetooth.
3.1.2.1. Class
Class yang akan digunakan pada aplikasi ini adalah:
1. Class yang berhubungan dengan MIDP adalah:
-. javax.microedition.midlet
javax.microedition.midlet adalah class yang menyediakan interaksi antar aplikasi dengan lingkungan dimana aplikasi tersebut berjalan, class ini mempunyai 3 kondisi atau state. State tersebut yang akan menjaga kestabilan tindakan dari suatu aplikasi. 3 state itu adalah Pause, active dan
CLDC - Network Management
Bluetooth - Connection Management
Bluetooth - Connection Management
CLDC - Network Management
Client MIDP -
User Interface + AplicationController
Server
Aplikasi Chatting Aplikasi Chatting MIDP -
User Interface + AplicationController
destroy. Pause adalah state dimana aplikasi dalam keadaan berhenti sementara untuk menunggu proses selanjutnya. Active adalah state dimana aplikasi berjalan secara normal. Destroy adalah state dimana aplikasi ditutup/ dimatikan. Dari ketiga state inilah dapat dibetuk lifecycle dari sebuah aplikasi MIDP, seperti pada gambar dibawah ini.
Gambar 3.2. Lifecycle dari sebuah aplikasi MIDP
Sumber: Sun Microsystem. Mobile Information Device Profile (JSR-37). Palo Alto: Sun Microsystem ,inc., 15 December 2000 : 121 (telah diolah kembali)
-. javax.microedition.lcdu
javax.microedition.lcdui adalah class UI API yang menyediakan fasilitas interface bagi user untuk aplikasi MIDP. Pusat abtraksi dari class ini adalah pada layar. Layar adalah suatu objek alat encapsulasi, terutama pada rendering grafik input user. Hanya satu layar yang dapat tampil disaat tersebut dan user dapat menjelajah melalui item yang ada pada layar. MIDP UI terbagi menjadi 2 bagian API, yaitu High Level API dan Low Level API.
High Level API biasa digunakan pada aplikasi yang bagian client berjalan pada MIDP. Untuk aplikasi semacam ini, kecocokan untuk digunakan alat jenis lain sangat tinggi. High Level API dapat diasumsikan adalah API yang harus dapat beradaptasi dengan perangkat keras peralatan lain serta UI yang lain. Implementasi dari High Level API adalah Layar dengan subclass screen. Low Level API didisain untuk aplikasi yang membutuhkan ketepatan
New
PauseApp() DestroyApp()
Keluar jika ada
Exception StartApp()
Pause
DestroyApp() Destroy Active
penempatan dan pengontrolan elemen grafik, serta akses pada low level input event. Dengan memakai Low Level API, aplikasi dapat melakukan kontrol penuh dalam penggambaran grafik, merespon pada event sederhana seperti tombol ditekan dan dilepas, akses pada tombol yang konkrit dan input lainya. Implementasi dari Low Level API class canvas dan graphic.
2. Class yang berhubungan dengan CLDC adalah:
-. javax.microedition.io
javax.microedition.io adalah class untuk koneksi secara umum pada CLDC. Class ini yang menangani manajemen jaringan pada sebuah aplikasi.
-. java.util
java.util adalah class yang berisi kumpulan framework, turunan dari class, fasilitas tanggal dan waktu, dan macam-macam class utility.
Class ini merupakan class yang juga terdapat pada Java 2 standard edtion (J2SE).
-. java.io
java.io adalah class yang menyediakan sistem input dan output melalui data stream. Class ini menangani bidang data stream pada suatu apikasi, juga menangani pengubahan data pada bentuk binary stream.
3. Class yang berhubungan dengan Bluetoooth adalah : -. javax.bluetooth
3.1.2.2. Protokol
Supaya aplikasi ini dapat berjalan, aplikasi chatting ini juga membutuhkan protokol-protokol. Protokol yang ada pada aplikasi ini dapat dibagi menjadi 2, yaitu protokol aplikasi Java untuk Chatting pada telepon selular dengan menggunakan Bluetooth dan protokol komunikasi Bluetooth L2CAP.
1. Protokol aplikasi Java untuk Chatting pada telepon selular dengan menggunakan Bluetooth
Protokol aplikasi Java untuk Chatting pada telepon selular dengan menggunakan Bluetooth adalah suatu kondisi yang harus dipenuhi oleh aplikasi chatting ini agar aplikasi chatting ini dapat mengadakan koneksi dan pertukaran data. Protokol aplikasi ini mempunyai 5 tahap untuk dapat berjalan dengan baik.
Tahap tersebut adalah:
1. Mencari dan menemukan unit server (Device Discovery).
2. Terkoneksi pada unit server.
3. Mencari service yang ada pada unit server.
4. Mengadakan koneksi dan melakukan pemeriksaan atribut aplikasi pada service record.
5. Terkoneksi pada service dan siap untuk mengadakan chatting.
Gambar 3.3. adalah gambar time sequence diagram berdasarkan pada desain protokol aplikasi chatting dengan Bluetooth.
Server Client
Search Device
- Device Discovery Mode
Discoverable Ack
- Device Found and make connection to device
Search Service
- Service Discovery
Gambar 3.3. Time Sequence diagram dari desain Protokol aplikasi chatting dengan Bluetooth
Services atribute in
service record - Service Found
- Establish Connection and check service atribute
Check
Ack
Accept Client Ack
- connect to service and ready to chatting
2. Protokol komunikasi Bluetooth L2CAP
Dalam pertukaran data, aplikasi akan memakai protokol komunikasi yang dipakai adalah protokol L2CAP. Protokol L2CAP ini digunakan sebagai protokol komunikasi dalam aplikasi ini karena protokol L2CAP adalah protokol terbawah dari Bluetooth yang dapat diakses oleh aplikasi.
Letak pada posisi yang terbawah menyebabkan protokol L2CAP mempunyai kelebihan pada penggunaanya lebih mudah, serta mempunyai waktu respon dan proses yang lebih singkat. Kemudahan pada protokol L2CAP disebabkan oleh karena sistem pengiriman data protokol L2CAP berbentuk datagram, sedangkan pada RFCOMM pengiriman datanya berbentuk aliran atau stream. Oleh karena pengiriman datanya berbentuk datagram, maka L2CAP mempunyai waktu untuk pergantian antara menerima dengan mengirim yang lebih sedikit daripada RFCOMM.
Proses waktu respon dan proses yang singkat disebabkan overhead dari protokol L2CAP adalah sebesar 4 bytes, sedangkan pada protokol komunikasi RFCOMM yang berada diatas dan berdasarkan L2CAP, mempunyai overhead protokol 4 sampai 5 bytes untuk sebuah paket berukuran kecil dan setiap 127 bytes data, besar header paket tersebut akan bertambah 1 bytes. Sehingga untuk keseluruhan besar overhead protokol dari RFCOMM adalah berkisar 8 sampai 9 bytes ( 4 bytes dari L2CAP + 4 atau 5 bytes dari RFCOMM ) dengan pertambahan 1 bytes setiap 127 bytes data. Oleh karena hal-hal tesebut, maka protokol L2CAP sangat cocok digunakan sebagai protokol komunikasi bagi pembuatan aplikasi chatting ini.
Pada protokol L2CAP, data yang dikirim berupa paket dengan ukuran bytes. Di aplikasi ini, pesan yang akan dikirim ditulis dalam bentuk string lalu di ubah menjadi array bytes sebelum dikirim. Dalam menerima pesan, paket yang diterima dalam bentuk array bytes akan diubah menjadi string sebelum ditampilkan pada layar. Format data dari L2CAP dapat dilihat pada gambar 3.4.
berikut.
Gambar 3.4. Format data paket dari L2CAP
Kode dari Channel Identifier (CID) tergantung pada implementasi, dapat diletakkan pada beberapa channel yang beberapa dengan antara 0x0040-0xFFFF.
Contohnya adalah jika kita ingin mengirimkan data sebesar 10 bytes, maka susunan dari format datanya dapat dilihat seperti ini:
0x0A =>L2CAP Length LSB 0x00 =>L2CAP Length MSB 0x40 =>CID LSB
0x00 =>CID MSB
0x01 – 0x0A =>Data yang dikirim atau diterima…..
3.1.3. Perencanaan Interface.
Tampilan yang dipakai dalam aplikasi ini adalah berbentuk console . Bentuk console adalah bentuk yang menampilkan semua text yang terjadi dalam satu layar, pada implementasinya object yang menangani tampilan console ini adalah object terima. Gambar 3.5. adalah gambar console.
Option Exit
Gambar 3.5. Tampilan awal console aplikasi chatting.
Sedangkan untuk interface aplikasi akan meliputi “Start server”, “Connect to server”, “Exit”,” Select”,” Write”, “Clear”, “Send”, dan “Back”. Interface start server, connect to server, exit akan ditampilkan pada awal aplikasi berjalan, tujuan interface ini adalah agar user dapat memilih apakah user ingin
menjalankan aplikasi sebagai server atau client. Gambar 3.6. adalah interface start server, connect to server, exit
Status:
Connect to Server Start Server Exit
Gambar 3.6. Interface “Start server”, “Connect to server”, “Exit”
Jika dipilih “Start server”, maka akan berjalan sebagai server dan tampilan akan berubah menjadi console setelah ada koneksi dari client. Jika dipilih sebagai
“Client”, maka berikutnya akan masuk pada interface “Select” untuk memilih unit yang berhasil ditemukan dan jika memilih “Exit”, maka aplikasi akan ditutup.
Gambar 3.7. adalah gambar interface “Select”.
Status :
● Andi Nokia 6600
○ Budi Nokia 6600
Select
Gambar 3.7. Interface “Select”.
Interface pada console untuk waktu terjadi pertukaran pesan adalah interface “Write”, “Clear”, dan “Exit”. Interface “Clear” adalah untuk membersihkan layar tampilan, interface ”Exit” adalah untuk keluar dari aplikasi.
Gambar 3.8. adalah gambar tampilan interface “Write”,” Clear”, dan “Exit”.
Send : halo Receive: apa kabar Send: baik
WriteWrite Write Clear Exit
Gambar 3.8. Gambar tampilan interface console
Interface “Write” adalah untuk menulis pesan. Pesan akan ditulis pada form penulisan pesan. Pada tahap implementasinya, object yang menangani form penulisan adalah object tulis. Gambar 3.9. adalah gambar form untuk penulisan pesan.
Write :
Gambar 3.9. Gambar form penulisan pesan.
Pada tampilan form penulisan pesan, interface yang terdapat didalamnya adalah
“Send” dan “Back”. “Send” berguna untuk mengirim pesan yang telah ditulis pada form, dan “Back” adalah untuk kembali ketampilan console.
3.2. Implementasi Aplikasi
Aplikasi chatting dibagi menjadi 2 sesuai dengan fungsi yang dipilih oleh user. Aplikasi dapat sebagai server atau aplikasi dapat sebagai client. Aplikasi sebagai server akan melakukan proses pembuatan service dan persiapan untuk
Hallo !!!
Send Back
menerima koneksi dari client. Aplikasi sebagai client akan melakukan proses pencarian unit lain, pencarian service pada unit yang telah dipilih dan melakukan koneksi pada unit yang dipilih, memeriksa service yang ditemukan serta mengadakan koneksi dengan service.
3.2.1. Pembuatan Aplikasi Sebagai Server
Aplikasi sebagai server dapat dikatakan secara umum sebagai tempat untuk mengadakan koneksi untuk chatting. Dengan kata lain sebuah aplikasi sebagai server adalah aplikasi yang berinsisiatif untuk membangun sebuah jaringan chatting. Proses yang terjadi pada server dalam membagun sebuah jaringan adalah membuat sebuah service agar client dapat melakukan koneksi, menetapkan tipe koneksi yang dipakai client untuk mengadakan koneksi, menetapkan security dalam jaringan yang dibangun, dan memberi informasi kepada client tentang service yang ada, agar client dapat melakukan koneksi dengan server. Cara kerja dari aplikasi sebagai server dapat dilihat pada gambar 3.10.
Start
Mengkonfigurasi mode Server Terhadap Device
Discovery
Membuat Service Record
Persiapan untuk menerima koneksi dan menyimpan ServiceRecord pada SDDB
di layer SDP
Gambar 3.10. Flowchart aplikasi sebagai server
Ada permintaan
koneksi?
Mengirim atau menerima pesan
Proses pengiriman
pesan
Proses penerimaan
pesan Y
N
Terima
Kirim
N Interface
“Exit”
dipilih ?
Y Idle
End
3.2.1.1. Mengkonfigurasi Mode Server Terhadap Device Discovery.
Proses pertama kali yang dilakukan oleh server adalah menentukan mode server terhadap proses Device Discovery oleh client. Pada proses ini, perintah yang digunakan dapat dilihat dibawah ini.
localDevice.setDiscoverable(DiscoveryAgent.GIAC);
localDevice.setDiscoverable adalah perintah agar server dipasang pada mode dapat ditemukan atau discoverable atau tidak dapat ditemukan oleh unit lain yang melakukan pencarian atau inquiry. Nilai dari localDevice.setDiscoverable yaitu GIAC dan LIAC. localDevice.setDiscoverable dengan parameter GIAC mempunyai arti bahwa tidak larangan atau batasan-batasan yang dipasang pada server bagi unit-unit lain untuk menemukan server, dengan kata lain yaitu unit server dapat dengan mudah ditemukan oleh unit lain yang melakukan pencarian atau inquiry.
Nilai dari kode akses General/Unlimited Inquiry Access Code (GIAC), yaitu 0x9E8B33 (10390323) menurut dokumen Bluetooth Assigned Numbers. Jika
localDevice.setDiscoverable mempunyai parameter LIAC, maka unit server tersebut tidak dapat ditemukan oleh unit lain yang melakukan pencarian atau inquiry, untuk dapat melakukan koneksi dengan unit server, maka diperlukan kondisi- kondisi tertentu dalam pencarian yang dilakukan oleh unit client. LIAC kepanjangan dari Limited Dedicated Inquiry Access Code, nilai kode akses dari LIAC adalah 0x9E8B00 (10390272) menurut dokumen Bluetooth Assigned Numbers.
3.2.1.2. Membuat Service Record.
Proses selanjutnya setelah unit server ditetapkan mode discoverable adalah membuat service record pada server agar client dapat melakukan koneksi.
Isi service record tersebut meliputi: jenis protokol komunikasi yang dipakai, UUID service yang berjenis string dengan jumlah karakter 32 buah atau 128 bit, dan nama service yang dipakai.
private static final String UUID_STRING =
"11112233445566778899AABBCCDDEEFF";
…….
L2CAPConnectionNotifier notifier = (L2CAPConnectionNotifier)
Connector.open("btl2cap://localhost:" + UUID_STRING + "; name=BTL2Chat");
L2CAPConnectionNotifier adalah sebuah interface yang disediakan oleh L2CAP connection notifier. Untuk membuat sebuah koneksi server L2CAP, protokol harus diisi dengan btl2cap dan target dari btl2cap diisi dengan localhost dan UUID dari service. Universally Unique Identifiers (UUID) service yang terdiri dari 32 karakter atau 128 bit dan diisi dengan “11112233445566778899AABBCCDDEEFF“ . dan ServiceName adalah nama dari service yang disediakan oleh server yaitu
“BTL2Chat”. Method Connector.open adalah method dari CLDC untuk menciptakan dan membuka sebuah koneksi dengan sebuah service record. Service record yang telah dibuat, disimpan pada variabel notifier dengan tipe data
L2CAPConnectionNotifier.
3.2.1.3. Server Siap Untuk Menerima Koneksi
Setelah semua proses pembuatan service, maka selanjutnya adalah membuat server siap untuk menerima koneksi. Server dikatakan siap untuk menerima koneksi dari client setelah aplikasi memanggil method acceptAndOpen
pada L2CAPConnectionNotifier.
conn = notifier.acceptAndOpen();
Method acceptAndOpen dipakai untuk menyatakan bahwa server siap untuk menerima koneksi dari client dan siap menyimpan ServiceRecord pada service discovery database (SDDB). SDDB adalah suatu tempat pada unit lokal yang berfungsi untuk menyimpan ServiceRecord. SDDB terletak pada layer SDP. Layer SDP bertugas sebagai tempat untuk menangani informasi unit, informasi service dan karakteristik service. Method acceptAndOpen akan menahan aplikasi untuk berjalan lebih lanjut sampai terjadinya koneksi dengan client.
Pada saat aplikasi sebagai server mendapat koneksi dari client, maka aplikasi sebagai server akan berjalan pada proses selanjutnya, yaitu bersiap untuk menerima pesan atau mengirim pesan. Proses pengiriman dan penerimaan pesan
ini adalah subuah sub routine dari proses tersendiri yang akan dijelaskan pada sub bab 3.2.3.Pengiriman dan Penerimaan Pesan.
3.2.2. Pembuatan Aplikasi Sebagai Client
Aplikasi sebagai client secara umum mempunyai tugas yaitu melakukan device discovery, melakukan koneksi dengan server, melakukan service discovery dan melakukan koneksi dengan service. Device discovery adalah proses yang dilakukan client untuk menemukan unit-unit lain yang aktif. Proses pada device discovery meliputi pencarian unit-unit yang aktif dan mendata semua unit yang berhasil ditemukan dengan tujuan agar user dapat memilih sebuah unit dari unit- unit yang telah ditemukan. Service discovery adalah proses yang dilakukan oleh client untuk dapat menemukan service pada unit yang telah dipilih oleh user dari unit-unit yang telah ditemukan pada proses device discovery. Proses pada service discovery meliputi pencarian service pada unit yang telah dipilih oleh user, melakukan filter pada service-service yang telah ditemukan dan meminta koneksi pada service yang berhasil ditemukan. Proses yang terdapat dalam melakukan koneksi dengan server adalah menerima informasi service atau nilai balik dari server dan menggunakan informasi atau nilai balik tersebut untuk mengadakan koneksi dengan server. Gambar dibawah adalah flowchart dari aplikasi sebagai client.
Start
Device Discovery
Gambar 3.11. Flowchart aplikasi sebagai client
Mendaftar unit
Service search
Menerima informasi service dan
menyaring service Permintaan koneksi pd unit
Menggunakan informasi service utk melakukan koneksi pd service
Mengirim atau menerima pesan?
Mengirim pesan N
Ada unit ditemukan ?
Y
N
Ada service?
Y
terima
Menerima Pesan
Kirim
Interface N
“exit”
dipilih
End Y
Idle
3.2.2.1. Device Discovery
Proses pertama yang dilakukan oleh client adalah device discovery.
Device discovery meliputi pencarian unit lain yang aktif serta mendata unit-unit yang berhasil ditemukan oleh client. Sebelum melakukan pencarian, pertama-tama yang terpenting adalah menentukan parameter dari pencarian tersebut. Tujuan penentuan parameter tersebut adalah agar unit-unit yang ditemukan dapat sesuai dengan apa yang diinginkan. Proses pencarian unit disebut juga sebagai device inquiry.
private DiscoveryAgent agent;
agent = localDevice.getDiscoveryAgent();
agent.startInquiry(DiscoveryAgent.GIAC, discoverer);
Perintah diatas adalah untuk device inquiry dan menetapkan parameter dari device inquiry. Untuk mencari unit lain, digunakan method
localDevice.getDiscoveryAgent() dari DiscoveryAgent. Untuk menempatkan client pada mode inquiry, digunakan Method startInquiry. Method startInquiry yang digunakan mempunyai parameter GIAC. Dengan parameter GIAC, berarti pencarian unit akan mencari semua unit-unit yang dapat ditemukan. Jika parameter yang digunakan adalah LIAC, maka pencarian akan terbatas pada unit- unit yang memakai mode discoverable LIAC saja yang akan ditemukan. Setiap pencarian berhasil menemukan sebuah unit, maka sistem memanggil Method
deviceDiscovered.
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) ) { remoteDevices.addElement(btDevice); }
Pada method deviceDiscovered terdapat perintah
remoteDevices.addElement(btDevice) yang tujuan dari perintah ini adalah mengkonfigurasi sistem untuk menyaring semua unit yang ditemukan, penyaringan tersebut dilakukan karena sebuah pencarian unit akan mencari unit yang dapat ditemukan dan sebuah unit yang dapat ditemukan akan dapat ditemukan lagi oleh pencarian sampai berkali-kali ditemukan.
Setelah pencarian selesai, maka method inquiryCompleted dipanggil oleh implementasi. Tujuan dari dipanggil method inquiryCompleted adalah untuk memberikan keterangan kepada user tentang status dari proses device inquiry.
public void inquiryCompleted(int discType) { String message = null;
if (discType == INQUIRY_COMPLETED) { message = "Inquiry completed";
} else if (discType == INQUIRY_TERMINATED) { message = "Inquiry terminated";
} else if (discType == INQUIRY_ERROR) { message = "Inquiry error";}
Nilai yang terdapat pada variabel disctype adalah salah satu dari 3 nilai yang didefinisikan oleh interface DiscoveryListener, Nilai tersebut adalah :
1. INQUIRY_COMPLETED mengindikasikan bahwa inquiry berhasil dan berjalan secara normal.
2. INQUIRY_TERMINATED mengindikasikan bahwa inquiry telah dibatalkan oleh aplikasi melalui cancelInquiry dari DiscoveryAgent.
3. INQUIRY_ERROR mengindikasikan bahwa inquiry telah gagal tetapi bukan karena dibatalkan. Nilai tersebut akan ditampilkan dilayar dengan tujuan agar user dapat mengetahui status dari inquiry.
Hasil dari pencarian unit yang telah difilter diproses lebih lanjut, dengan tujuan untuk mendata semua unit yang dapat ditemukan dan ditampilkan untuk dipilih oleh user.
RemoteDevice[] devices = new RemoteDevice[remoteDevices.size()];
for(int i = 0; i < remoteDevices.size(); i++) {
devices[i] = (RemoteDevice)remoteDevices.elementAt(i);}
controller.deviceInquiryFinished(devices, message);
remoteDevices = null;
controller = null;
Perintah diatas adalah untuk mendata semua unit yang berhasil ditemukan, setelah pencarian unit selesai. Dari hasil yang disimpan sementara pada remoteDevices
akan diambil dan dimasukkan pada array devices[i] , proses ini akan dilakukan berulang-ulang sampai tidak ada lagi unit pada remoteDevices. Setelah selesai, maka pesan status inquiry akan ditampilkan pada layar dan hasil yang tersimpan pada remoteDevices akan digantikan oleh nama yang user friendly sesuai dengan nama unit yang ditemukan sebelum ditemukan. Tujuan dari proses ini adalah agar user dapat lebih mengenal unit-unit yang ditemukan dan user dapat memilih unit tersebut. Perintah dibawah ini adalah untuk mengganti nama unit yang ditemukan dengan nama yang user friendly.
for(int i = 0; i < remoteDevices.length; i++) { try {
String name = remoteDevices[i].getFriendlyName(false);
names[i] = name;
for(int i = 0; i < names.length; i++) { devices.append(names[i], null);
Semua unit yang berhasil ditemukan dan didata, hasil tersebut ditampilkan pada layar untuk dapat dipilih oleh user. Proses device discovery selesai sampai disini, selanjutnya adalah kondisi pause sampai user memilih salah satu unit yang berhasil ditemukan. Setelah user memilih salah satu unit, maka proses selanjutnya adalah service discovery. Diagram dibawah ini adalah diagram tentang Device Discovery.
Aplikasi Aplikasi
Gambar 3.12. Diagram Garis Besar Device Discovery.
3.2.2.2. Service Discovery
Service discovery akan dilakukan setelah user memilih sebuah unit dari daftar unit yang telah ditemukan device discovery. Setelah user memilih unit, maka aplikasi akan mengadakan koneksi pada unit tersebut untuk melakukan Service discovery. Tujuan dari service discovery adalah menemukan service pada unit yang telah dipilih oleh user. Setelah menemukan service tersebut, maka client akan meminta koneksi pada service. Dalam menemukan service yang ada pada server, digunakan method searchServices dari DiscoveryAgent. Pencarian informasi tentang service yang ada, ilakukan dengan mencari informasi tersebut pada SDDB yang berada di layer SDP unit Bluetooth yang berkalan sebagai server.
ServiceDiscoverer serviceDiscoverer = new ServiceDiscoverer(ChatController.this);
int[] attrSet = {0x0100};
UUID[] uuidSet = new UUID[1];
uuidSet[0] = new UUID(UUID_STRING, false);
agent.searchServices(attrSet, uuidSet, remoteDevices[index], serviceDiscoverer);
L2CAP Baseband
L2CAP Baseband
1 Client
server
3 4
2
1. aplikasi melakukan pencarian atau inquiry.
2. Baseband melakukan pencarian atau inquiry.
3. Baseband Inquiry respon.
4. hasil pencarian dilaporkan.
Perintah diatas adalah langkah awal untuk mencari service, yaitu menentukan parameter service yang dicari. Perintah searchServices adalah perintah untuk mencari service dan mempunyai 4 parameter. Keempat parameter tersebut adalah
attrSet, uuidSet, remoteDevices[index], serviceDiscoverer. Nilai dari int[] attrSet berisi atribut yang diambil dari ServiceRecord yang berasal dari spesifikasi UUID yang ada pada uuidSet. Nilai 0x0100 menunjukan pada nilai atribut dari nama service.
uuidSet adalah nilai array dari UUID yang harus terdapat pada service yang dicari.
Sedangkan Parameter remoteDevice adalah RemoteDevice yang harus dicari untuk service yang ada padanya, dan serviceDiscovery adalah Objek DeviceListener yang akan diberitahukan jika ada service yang ditemukan.
Dalam pencarian service, jika suatu service ditemukan, maka proses selanjutnya adalah mengecek apakah service tersebut sesuai dengan client. Jika sesuai, client dapat mengadakan koneksi. Jika tidak, maka client tidak dapat mengadakan koneksi. Perintah dibawah ini adalah perintah untuk mengecek service, apakah sesuai dengan client atau tidak.
public void servicesDiscovered(int transID, ServiceRecord[] servRecord) { for(int i = 0; i < servRecord.length; i++) {
DataElement serviceNameElement = servRecord[i].getAttributeValue(0x0100);
String serviceName = (String)serviceNameElement.getValue();
if(serviceName.equals(SERVICE_NAME)){
serviceRecord = servRecord[0]; } } }
Dalam pemeriksaan ini method serviceDiscovered akan dipanggil. yang menjadi parameter dari pemeriksaan ini adalah ServiceName dari service yang diperiksa.
Perintah getAttributeValue(0x0100) adalah perintah untuk mengambil nilai dari atribut 0x0100, yaitu ServiceName dari service. Perintah
serviceName.equals(SERVICE_NAME) adalah untuk melakukan pemeriksaan apakah service name sesuai dengan yang ada pada client atau tidak. Jika sama, maka service tersebut dapat diterima oleh client.
Setelah seluruh pencarian dan pemeriksaan service selesai, maka seperti pada device inquiry, pada service search juga terdapat nilai balik yang digunakan untuk melihat berhasil atau tidaknya service seach.
public void serviceSearchCompleted(int transID, int respCode) { String message = null;
if (respCode ==
DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE) { message = "Device not reachable"; }
else if (respCode ==
DiscoveryListener.SERVICE_SEARCH_NO_RECORDS) { message = "Service not available"; }
else if (respCode ==
DiscoveryListener.SERVICE_SEARCH_COMPLETED) { message = "Service search completed"; }
else if (respCode ==
DiscoveryListener.SERVICE_SEARCH_TERMINATED) { message = "Service search terminated"; }
else if (respCode == DiscoveryListener.SERVICE_SEARCH_ERROR) { message = "Service search error"; }
controller.serviceSearchFinished(serviceRecord, message);
controller = null;
serviceRecord = null; }
status.setText("Bluetooth Exception: " + bse.getMessage()
Perintah diatas adalah method searchComplete yang dipanggil oleh sistem setelah pencarian service selesai. Keberhasilan pencarian service dapat dilihat dan dipastikan dari nilai variabel respCode yang ditampilkan dilayar. respCode
mempunyai 5 nilai nilai yang didefinisikan oleh interface DiscoveryListener. Nilai tersebut adalah :
1. SERVICE_SEARCH_DEVICE_NOT_REACHABLE : mengindikasikan bahwa pencarian tidak dapat diselesaikan disebabkan
DiscoveryAgent.searchServices() tidak dapat dijangkau.
2. SERVICE_SEARCH_NO_RECORDS : mengindikasikan bahwa pencarian selesai tanpa ada satupun service yang berhasil ditemukan.
3. SERVICE_SEARCH_COMPLETED : mengidikasikan bahwa service discovery selesai secara normal.
4. SERVICE_SEARCH_TERMINATED : mengindikasikan bahwa service search dibatalkan oleh aplikasi dan belum selesai melakukan prosesnya.
5. SERVICE_SEARCH_ERROR : mengindikasikan pencarian dibatalkan karena ada error. Untuk lebih jelas lagi tentang service discovery, dapat dilihat pada diagram service discovery secara garis besar dibawah ini.
Gambar 3.13. Diagram garis besar service discovery
3.2.2.3. Koneksi Dengan Service
Setelah device discovery dan service discovery selesai, maka proses selanjutnya adalah mengadakan koneksi dengan service. Untuk dapat mengadakan koneksi, terlebih dahulu perlu diketahui adalah komponen yang ada pada service.
Komponen tersebut dapat diketahui dari return value yang dikirmkan oleh server ketika client mengajukan permintaan koneksi pada service.
String url =
serviceRecord.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOEN CRYPT, false);
Aplikasi
L2CAP Baseband
1 4
Aplikasi
server Client
3
2
1. Client mencari service dan melakukan koneksi pada unit server
2. Baseband melakukan pengiriman.
3. Server menerima permintaan dari client.
4. Server memberi respon.
L2CAP
6 5
Baseband
5. Baseband mengirim respon.
6. Hasil diterima oleh Client dan memeriksa service record server, jika cocok, maka melakukan koneksi ke service.
Method getConnectionURL diatas dipakai untuk menerima nilai balik atau return value yang diberikan oleh server ketika client melakukan permintaan koneksi dengan service. Ada 2 parameter pada getConnectionURL. Parameter pertama adalah authentication dan encrytion, NOAUTHENTICATE_NOENCRYPT pada aplikasi menunjukan bahwa tidak diperlukan adanya authentication dan encrytion untuk melakukan koneksi. Parameter kedua adalah boolean mustBeMaster. Parameter kedua ini berisi nilai false, yang artinya unit lokal dapat bertindak sebagai master atau slave. Jika berisi true, maka unit ini atau client harus sebagai master dalam koneksi dengan service. Unit yang menjadi slave harus melakukan sinkronisasi dengan unit yang menjadi master, baik secara frekuensi hoping maupun yang lainya.
Melalui ServiceRecord yang didapat dan disimpan dalam variabel url dari server melalui return value, maka koneksi dapat dilakukan..
conn = (L2CAPConnection)Connector.open(url);
method Connector.open digunakan perintah untuk dapat berkoneksi dengan service dengan menggunakan variabel url yang telah didapat. Setelah koneksi dapat dibagun, maka proses mengirim dan menerima pesan dapat dilakukan. Untuk proses pengiriman dan penerimaan pesan ini adalah subuah sub routine dari sebuah proses tersendiri yang akan dijelaskan pada sub bab 3.2.3.Pengiriman dan Penerimaan Pesan.
3.2.3. Pengiriman Dan Penerimaan Pesan
Proses chatting pada dasarnya dapat dibagi menjadi 2, yaitu proses menerima pesan dan proses mengirim pesan pada unit lain yang telah terkoneksi.
Pada protokol komunikasi L2CAP, pengiriman dan penerimaan pesan tergantung pada besarnya MTU. MTU adalah Maximum Transmission Unit, besar maksimun unit yang dapat dikirimkan dan diterima pada komunkasi L2CAP. Untuk pengiriman pesan , digunakan TransmitMTU dan untuk menerima pesan digunakan ReceiveMTU. Besar default dari MTU adalah 0x02A0 (672 byte) dan
besar minimun MTU untuk connection-oriented channels adalah 48 bytes. Jika pesan yang diterima atau yang dikirimkan melebihi besar MTU, maka data yang lebih tersebut hilang.
3.2.3.1. Penerimaan Pesan
Dalam menerima pesan, yang harus diperhatikan adalah besar ReceiveMTU dan apakah koneksi dalam keadaan siap dalam menerima pesan.gambar 3.14. adalah gambar FlowChart cara kerja penerimaan pesan.
Start
Gambar 3.14. Flowchart menerima pesan
Kapasitas penerimaan Disesuaikan dgn receiveMTU
Connection ready
Mengambil besar receive MTU
mengubah menjadi String dari array Byte
Dimasukan kedalam paket sementara
Di tampilkan dilayar
Pesan diterima
End
Pengecekan pertama adalah apakah koneksi sudah siap untuk menerima pesan. Jika sudah siap, maka tampilan diubah dalam bentuk console dengan perintah display.setCurrent(terima).
public MessageUI terima;
…….
display.setCurrent(terima);
Setelah itu, proses selanjutnya adalah mengambil nilai ReceiveMTU dari koneksi. Perintah conn.getReceiveMTU() adalah perintah untuk mengambil ReceiveMTU dan disimpan pada variabel receiveMTU.
private L2CAPConnection conn;
…….
if(conn.ready()){
int receiveMTU = conn.getReceiveMTU();
byte[] data = new byte[receiveMTU];
int length = conn.receive(data);
Method ready mengembalikan nilai true jika sebuah pemberitahuan untuk menerima tidak di dihalangi. Paket yang diterima besarnya tidak boleh lebih besar dari ReceiveMTU. Karena jika lebih besar, maka sebagian paket yang lebih tersebut akan hilang. Nilai default dari ReceiveMTU adalah 672 byte. new byte[receiveMTU] adalah untuk menerima pesan yang dikirimkan dan
conn.receive(data) adalah untuk mengetehui besar data yang diterima.setelah diterima, maka data aka diproses lebih lanjut sebelum ditampilkan.
String message = new String(data, 0, length);
Karena L2CAP mengirim data dalam bentuk Byte, maka paket data diterima juga dalam bentuk byte. Proses selanjutnya sebelum dtampilkan dilayar adalah mengubah dari bentuk byte menjadi string dengan perintah new String(data, 0, length).
ChatPacket packet = new ChatPacket (name, message);
Pesan yang telah diterima disimpan pada sebuah paket sementara bernama
ChatPacket sebelum ditampilkan.
terima.msgs.addElement(packet);
terima.repaint();
Lalu pesan yang berada pada paket sementara ditampilkan di layar dengan cara melakukan refresh pada tampilan layar dengan perintah terima.repaint().
3.2.3.2. Pengiriman Pesan
Pengiriman pesan tidak terlalu berbeda dengan penerimaan pesan. Hanya saja dalam pengiriman pesan, yang dipakai sebagai pembatas adalah banyak karakter yang dikonfigurasi dari MIDP, yaitu maksimum 150 karakter dan TransmitMTU. Gambar 3.15. adalah Flowchart pengiriman pesan.
Start
Pesan ditulis
Pesan disimpan di paket sementara
Pesan ditampilkan di layar
Diubah menjadi array Byte dari string
Mengambil besar TransmitMTU
Int index = 0 Byte[ ] temp = null
Gambar 3.15. Flowchart pengiriman pesan
Pesan dikirim N
Y (data.length – Index) <
transmitMTU
End Index <
data.length
temp = new
byte[data.length-index]
System.arraycopy(data, index, temp, 0, data.length-index)
temp = new byte[transmitMTU]
Y
System.arraycopy(data, index, temp, 0,
transmitMTU)
index +=
transmitMTU N
Pertama dalam menulis pesan yang diperlukan form untuk menulis pesan tersebut.
Tampilan console diubah menjadi bentuk form untuk menulis pesan yang akan dikirimkan.
display.setCurrent(tulis);
display.setCurrent(tulis) adalah perintah untuk mengubah tampilan kedalam bentuk form untuk menulis pesan, form penulisan pesan tersebut dikonfigurasi maksimum 150 karakter yang dapat dituliskan.
String message = new String (tulis.getString());
Setelah selesai menulis, Pesan dalam form diambil untuk dikirimkan dengan perintah String (tulis.getString()). Pesan yang diambil dari form adalah dalam bentuk data string.
String name = new String ("send : ");
byte[] data = message.getBytes();
int transmitMTU = conn.getTransmitMTU();
Paket yang dikirim oleh L2CAP harus diubah kedalam bentuk array Byte dari bentuk string. Pengiriman paket pada L2CAP juga tergantung pada besar MTU.
Nilai TransmitMTU untuk adalah sama dengan ReceiveMTU yaitu 672 byte, jika paket yang dikirim melebih besar MTU, maka paket tersebut akan hilang. Agar pesan yang mempunyai ukuran lebih besar dari TransmitMTU dapat dikirimkan secara sempurna, maka pesan tersebut dibagi dan dikirim dalam beberapa bagian.
byte[] temp = null;
int index = 0
temp = new byte[transmitMTU]
Dengan sebuah variabel index yang nilai mula-mulanya adalah 0 sebagai pointer, maka dapat diketahui apakah pesan sudah terkirim seluruhnya atau belum.
Variabel temp bertipe array byte diinisialisasi dengan array sebanyak besar
transmitMTU dan bertujuan untuk menampung pesan sementara sebelum dikirim.
while (index < data.length)
{ if ((data.length - index) < transmitMTU) { temp = new byte[data.length-index];
System.arraycopy(data, index, temp, 0, data.length-index);
} else {
temp = new byte[transmitMTU];
System.arraycopy(data, index, temp, 0, transmitMTU); }
Ketika variabel index tidak lebih kecil dari besar data, maka kemungkinan tidak ada data yang akan dikirimkan. Jika variabel index lebih kecil dari besar data, maka ada data yang akan dikirmkan. Besar data diperiksa terlebih dahulu, apakah lebih kecil dari transmitMTU atau tidak. Jika lebih kecil, maka array dari variabel
temp diubah sebanyak besar data dikurangi variabel index, lalu dari isi array byte variabel data diposisi array yang sesuai variabel index dikopikan pada array byte variabel temp diposisi array 0 sebanyak besar data dikurangi variabel index. Jika besar data lebih besar atau sama dengan transmitMTU, maka isi array byte variabel
data diposisi array yang sesuai variabel index dikopikan pada array byte variabel
temp diposisi array 0 sebanyak besar transmitMTU. conn.send(temp);
index += transmitMTU
Setelah pemeriksaan besar data dengan transmitMTU, maka pesan yang disimpan pada variabel temp dikirimkan dengan method send. Setelah itu variabel index
ditambahkan dengan besar transmitMTU dan diperiksa ulang dengan cara dibandingkan dengan besar data untuk mengetahui apakah semua pesan sudah dikirimkan. Jika variabel index lebih besar atau sama dengan besar data, maka semua pesan sudah dikirmkan.
ChatPacket packet = new ChatPacket(name, message);
Pesan yang akan dikirim dicopy dan disimpan pada sebuah paket sementara bernama ChatPacket sebelum ditampilkan.
terima.msgs.addElement(packet);
display.setCurrent(terima);
terima.repaint();
Tampilan dikembalikan pada tampilan console dengan perintah
display.setCurrent(terima) dan pesan yang berada pada paket sementara ditampilkan di layar dengan cara melakukan refresh pada tampilan layar dengan perintah terima.repaint().