# فناوری جاوا > برنامه‌نویسی جاوا > Java ME : نگارش میکرو جاوا >  برنامه نویسی بلوتوث

## m_zi

سلام
خسته نباشید
میشه کمی هم در مورد برنامه نویسی بلوتوث صحبت کنید .

ممنون

----------


## zehs_sha

جاوا و برنامه‌نویسی بلوتوث 

نسخه کوچک محیط جاوا موسوم به J2ME و تکنولوژی بلوتوث دو تا از هیجان‌انگیزترین تکنولوژی‌های بی‌سیم در دنیای امروز می‌باشد.. J2ME جمع و جورترین محیط بین محیطهای 3 گانه جاواست و البته مانند سایر محیط‌ها از فلسفة «یک بار نویسی، در هر کجا اجرا کن» جاوا پیروی می‌کند. و از سوی دیگر بلوتوث یک استاندارد ارتباط بی‌سیم کوتاه برد می‌باشد که کاربرد گسترده‌ای برای دیوایس‌های کوچک قابل حمل دارد. فرض کنید قادر باشید که از گوشی همراه خود برای قفل و یا باز کردن در اتومبیل خود استفاده کنید و یا در پارکینگ خود را باز و بسته کنید و یا تلویزیون و DVDplayer خود را کنترل کنید. اگر شما می‌خواهید این گونه قابلیت‌ها را به کاربران خود ارائه دهید شما باید بتوانید برنامه‌هایی با قابلیت‌های بلوتوث بنویسید و این برنامه‌ها را بر روی دیوایس‌هایی مانند تلفن‌های همراه اجرا کنید.
بلوتوث و J2ME را می‌توان برای رسیدن به این هدف مورد استفاده قرار داد. بلوتوث امکان برقراری ارتباط بی‌سیم بین دیوایس‌ها را فراهم می‌کند و J2EM به شما اجازه می‌دهد تا برنامه‌های خود را بنویسید و آن را بر روی دیوایس‌هیا قابل حمل کوچک اجرا کنید.


رابط کاربردی برنامه‌نویسی بلوتوث:

با اینکه تکنولوژی بلوتوث از نظر سخت‌افزاری بسیار پیشرفت کرده است استاندارد مشخصی برای توسعه برنامه‌های بلوتوث وجود نداشت تا اینکه استاندارد JSR81 شرکت سان معرفی شد. این استاندارد اولین پشته پروتکل‌های بلوتوث را توسط مجموعه‌ای از رابط‌های برنامه‌های بلوتوث به زبان جاوا می‌باشد. این استاندارد پیچیدگی‌های مربوط به پشته پروتکل‌های بلوتوث را توسط مجموعه‌ای از رابط‌های کاربردی برنامه‌نویسی از دید برنامه‌نویسان پنهان می‌کند و به شما اجازه می‌دهد بدون نگرانی از جزئیات سطح پائین بلوتوث به توسعه برنامه‌های خود بپردازید.
این رابط کاربردی برنامه‌نویسی برای دیوایس‌هایی با ویژگی‌های زیر طراحی شده است:


- حداقل حافظه‌ای برابر 512K حافظه مورد نیاز هر برنامه باید حمایت شود
- حمایت از ارتباط بلوتوث
دارای پیاده‌سازی مناسبی از استاندارد J2ME و پروفایل CLDCاز سوی دیگر سیستم‌های بلوتوثی که قرار است از رابط کاربردی برنامه‌نویسی بلوتوث جاوا استفاده کنند باید دارای ملزوماتی باشند:


1- این سیستم‌ها می‌باید بر اساس مشخصات نامة بلوتوث تأیید صلاحیت شده باشند.

2- این سیستم‌ها باید بر اساس مشخصات نامة بلوتوث، 3 لایه ارتباطی را حمایت کنند و رابط برنامه‌نویسی باید به این لایه‌ها دسترسی داشته باشد این 3 لایه عبارتند از پروتکل یافت خدمات (SDP) ،پروتکل ارتباطی فرکانس رادیویی (RFCOMM) و پروتکل کنترل اتصال انطباق منطقی.

3- سیستم مورد نظر باید مرکز کنترل بلوتوث ارائه کرده باشد که بتوان توسط آن پارامترهای پیکربندی را تعریف کرد.

مرکز کنترل بلوتوث (BCC) چیست؟

      دیوایس‌های بلوتوثی که می‌خواهند از این رابط کاربردی برنامه‌نویسی استفاده کنند ممکن است بخواهند چندین برنامه را به صورت همزمان اجرا کنند. BCC از تداخل این گونه برنامه‌ها با هم جلوگیری می‌کند. BCC به کاربر و یا برنامه‌ها این اجازه می‌دهد تا با تعریف مقادیری به عنوان پارامترهای پیکربندی درپشتة بلوتوث بروز مشکلات این چنین را حل کند. در واقع BCC مرکز مدیریت و کنترل تنظیمات دیوایس‌های بلوتوث است. BCC ممکن است یک برنامه native و یا برنامه نوشته شده توسط یک رابط کاربر برنامه‌نویسی جداگانه باشد و یا حتی ممکن است تنها مجموعه‌ای از تنظیمات پیش‌فرض باشد که توسط کارخانة تولید کننده دیوایس تعریف شده باشد و قابل تغییر نیز نباشد.
JSR  چیست؟
رای تعریف این واژه ابتدا می بایست به تعریف واژه JCP بپردازیم.JCP در واقع یک گروه از توسعه دهندگان جاوا هستند که کارشان توسعه و یا تجدید نظر در خصوصیات API های استاندارد جاوا می باشد.API هایی که توسط این گروه منتشر و یا بروز رسانی و اصلاح می شود تحت نام JSR به همراه یک شماره منتشر می شود.این JSR ها می توانند در هر یک از سه تکنولوژی جاوا وجود داشته باشند.من در اینجا قصد دارم JSR هایی که مربوط به برنامه نویسی در موبایل می شوند را خدمت شما  معرفی کنم.برای مثال JSR82 مربوط به برنامه نویسی Bluetooth است و یا JSR75 مربوط به برنامه نویسی فایلها در J2ME است.برای اطلاعات بیشتر و دریافت Document های مربوط به هر JSR به وب سایت www.jcp.org مراجعه کنید.

قابلیت‌های ارائه شده توسط JSR82:

رابط کاربر برنامه‌نویس بلوتوث به شما امکانات زیر را ارائه می‌کند:
1- ثبت خدمات
2- کشف و تشخیص دیوایس‌ها و خدمات آنها
3- برقراری ارتباطات OBEX, L2CAP, RECOMM پین دیوایس‌ها
4- کنترل و مدیریت پروتکل‌های ارتباطی
5- ارائه خدمات امنیتی برای تمام فعالیت‌های ذکر شده

در شکل زیر چگونگی لایه‌بندی و معماری (CLDC/MIDP)J2ME و بلوتوث را مشاهده می‌کنید.


پکیج‌ها:

رابط کاربردی برنامه نویسی جاوا برای بلوتوث در پکیج را تعریف کرده است که وابسته به پکیج javax.microeditron.io از نسخة (CLDC)J2ME می‌باشد:


- Javax.buetooth & Javax.obex

البته رابط کاربردی obex مستقل از امکانات بلوتوث می‌باشد و می‌توان از آن با پروتکل‌های ارتباطی دیگری نیز استفاده نمود و به همین دلیل هم در پکیج‌ جداگانه‌ای قرار گرفته است. این دو پکیج، پکیج‌های اختیاری هستند و شرکت‌های تولید کننده اجباری برای پیاده‌سازی آنها و ارائه خدمات آنها بر روی دیوایس‌های J2ME ندارند.




توسعه برنامه‌های بلوتوث:
مراحل کار J2me,blutooth
سرویس گیرنده های FRCOMM
سرویس گیرنده های Client  عموما یک Inquery  و Service Discovery  را قبل از اتصال به یک سرور انجام دهند.
سرویس دهنده های RECOMM
وقتی که یک سرویس دهنده سفارش Custom   برای سرویس دهنده Bluetooth  ایجاد شود باید به آن یک آدرس UUID  منحصر به فرد داد این کار این اطمینان را می دهد که سرویس شما توسط کاربران با دیگر سرویس ها اشتباه گرفته نمی شود.
Authenticate
مربوط به کد گشایی و اطلاعات اعتبار سنجی همه به امنیت مربوط می شوند .
Service Record :
سرویس رکوردها در هنگام Service Discovery   واکشی می شود تا بتوانند جزئیات کاملی را از سرویس ها را در اختیار ما قرار بدهند. سرویس ها در SDDB  ذخیره می شوند وقتی Client  ها به دنبال سرویس ها می گردند سرویس رکورد های مناسب از SDDB   به Client  داده می شود.
نوع داده های صفات Service Record 
صفات شامل انواع مختلفی از نوع داده ها است مانند Int و String  این اطلاعات در یک ساختار از نوع DataElement  ذخیره می شود 


سرویس گیرنده های FRCOMM
سرویس گیرنده های Client  عموما یک Inquery  و Service Discovery  را قبل از اتصال به یک سرور انجام دهند.
سرویس دهنده های RECOMM
وقتی که یک سرویس دهنده سفارش Custom   برای سرویس دهنده Bluetooth  ایجاد شود باید به آن یک آدرس UUID  منحصر به فرد داد این کار این اطمینان را می دهد که سرویس شما توسط کاربران با دیگر سرویس ها اشتباه گرفته نمی شود.
Authenticate
مربوط به کد گشایی و اطلاعات اعتبار سنجی همه به امنیت مربوط می شوند .
Service Record :
سرویس رکوردها در هنگام Service Discovery   واکشی می شود تا بتوانند جزئیات کاملی را از سرویس ها را در اختیار ما قرار بدهند. سرویس ها در SDDB  ذخیره می شوند وقتی Client  ها به دنبال سرویس ها می گردند سرویس رکورد های مناسب از SDDB   به Client  داده می شود.
نوع داده های صفات Service Record 
صفات شامل انواع مختلفی از نوع داده ها است مانند Int و String  این اطلاعات در یک ساختار از نوع DataElement  ذخیره می شود 

ساختار برنامه‌های بلوتوث شامل 5 بخش اصلی می‌باشد که عبارتند از: مقداردهی اولیه پشتة پروتکل مدیریت دیوایس، کشف و تشخیص دیوایس، کشف و تشخیص خدمات و برقراری ارتباط.


مقدار دهی اولیه پشتة پروتکل:

پشته بلوتوث مسئول کنترل  Device‌های بلوتوث می‌باشد. بنابراین قبل از استفاده از بلوتوث این پشته را آماده و مهیا کنید. البته بسیاری از شرکت‌ تولید کننده Device‌های مقادیری را به صورت پیش فرض در نظر گرفته‌اند ولی بهرحال برای برخی از Device‌ها انجام این تنظیمات باید توسط برنامه‌نویس انجام شود، قطعه کد زیر نمونه‌ای از این کار است (توجه کنید که این قطعه کد جزء رابط کاربردی برنامه‌نویسی بلوتوث جاوا نمی‌باشد)
...
// set the port number
BCC.setPortNumber("COM1");
// set the baud rate
BCC.setBaudRate(50000);
// set the connectable mode
BCC.setConnectable(true);
// set the discovery mode to Limited Inquiry Access Code
BCC.setDiscoverable(DiscoveryAgent.LIAC);
...

مدیریت Device:

رابط کاربری برنامه‌نویسی بلوتوث شامل دو کلاس با نامهای RemotDevice , LocalDevice می‌باشد که قابلیت‌های مدیریت Device را تعریف و ارائه کرده‌اند.

LocalDevice وابسته به کلاس javax.bluetooth.DeviceClass می‌باشد و اطلاعات مربوط به نوع Device و خدماتی را که ارائه می‌کند را استخراج می‌نماید و از سوی دیگر کلاس RemoteDevice معرف Device دیگری است که ما می‌خواهیم با آن ارتباط برقرار کنیم و این کلاس متدهایی برای استخراج اطلاعات راجع به آن Device مانند نام و یا آدرس بلوتوث آن را به ما ارائه کرده است.

قطعه کد زیر با استفاده از کلاس LocalDevice اطلاعاتی را راجع به Device جاری استخراج کرده است.
...
// retrieve the local Bluetooth device object
LocalDevice local = LocalDevice.getLocalDevice();
// retrieve the Bluetooth address of the local device
String address = local.getBluetoothAddress();
// retrieve the name of the local Bluetooth device
String name = local.getFriendlyName();
...

و این قطعه که هم اطلاعاتی را راجع به Device دیگری که می‌خواهیم با آن ارتباط برقرار کنیم استخراج کرده است:
...
// retrieve the device that is at the other end of
// the Bluetooth Serial Port Profile connection,
// L2CAP connection, or OBEX over RFCOMM connection
RemoteDevice remote = 
RemoteDevice.getRemoteDevice(
javax.microedition.io.Connection c);
// retrieve the Bluetooth address of the remote device
String remoteAddress = remote.getBluetoothAddress();
// retrieve the name of the remote Bluetooth device
String remoteName = local.getFriendlyName(true);
...

کشف و تشخیص Device‌ها:
به دلیل اینکه Device‌های بی‌سیم عموماً متحرک هستند نیاز به مکانیزمی دارند تا بتوانند یکدیگر را پیدا کنند و با هم ارتباط برقرار کنند. دو کلاس DiscoveryAgent و DiscoveryListener دو رابط کاربردی برنامه‌نویسی بلوتوث چنین خدماتی را به شما ارائه می‌دهند.

Device‌های بلوتوث می‌توانند با استفاده از نمونه‌ای از کلاس DiscoveryAgent به 3 روش لیستی از Device‌های قابل دسترسی را پیدا کنند:


فراخوانی متد ) starInquiry از کلاس DiscoveryAgent Device جاری را اصطلاحاً در وضعیت جستجو قرار می‌دهد برای بهره‌بردن از این وضعیت برنامه باید از یک event listener (ناظر رویدادها استفاده کند. شما میتوانید برای این منظور از کلاس DiscoveryListener استفاده کنید، هنگامی که Device جاری، Device جدیدی را پیدا کند متود deviceDiscovered() از این کلاس فراخوانی می‌شود و هر گاه که عملیات جستجو به پایان برسد و یا به هر دلیل cancel شودInquiryCompleted فراخوانی می‌شود.اما اگر شما نخواهید که منتظر عملیاتی جستجو برای یافتن Device‌ها شوید می‌توانید از متد retireveDevices() از کلاس DiscoreyAgent برای استخراج لیست Device‌هایی که درفرآیند جتسجوی قبلی یافت شده‌اند و یا به صورت پیش فرض توسط سیستم شناخته می‌شود، استفاده نمائید. 


3 قطعه کد زیر این روشها را نشان می‌دهد:
...
// retrieve the discovery agent 
DiscoveryAgent agent = local.getDiscoveryAgent();
// place the device in inquiry mode
boolean complete = agent.startInquiry();
...
...
// retrieve the discovery agent 
DiscoveryAgent agent = local.getDiscoveryAgent();
// return an array of pre-known devices
RemoteDevice[] devices = 
agent.retrieveDevices(DiscoveryAgent.PREKNOWN);
...
...
// retrieve the discovery agent 
DiscoveryAgent agent = local.getDiscoveryAgent();
// return an array of devices found in a previous inquiry
RemoteDevice[] devices =
agent.retrieveDevices(DiscoveryAgent.CACHED);
...

کشف و تشخیص خدمات:

هنگامی که Device جاری حداقل یک Device دیگر را پیدا کرد می‌تواند شروع به جستجوی خدمات ارائه شده توسط آن Device بکند بدلیل اینکه کشف و تشخیص خدمات بسیار شبیه کشف و تشخیص Device‌ها می‌باشد، کلاس DiscoveryAgent برای این منظور هم متودهایی ارائه کرده است.

قبل از هر چیز اگر بخواهیم سرویس را ارائه کنیم باید آن را ثبت کنیم که فرآیند ثبت یک سرویس به صورت زیر خواهد بود.

1-ایجادیک رکورد سرویس که معرف سرویس است که ما می‌خواهیم ارائه دهیم که برای این منظور باید با سرور ارتباط برقرار کنیم:
...
StreamConnectionNotifier service =
(StreamConnectionNotifier) Connector.open("someURL");
2- دریافت رکورد سرویس ایجاد شده توسط سرور:
ServiceRecord sr = local.getRecord(service);
3- امکان برقراری ارتباط سایر Device‌ها با سرویس جاری
StreamConnection connection =
(StreamConnection) service.acceptAndOpen();


برقراری ارتباط:

پروتکل RFCOMM که بر پایه پروتکل L2CAP پیاده سازی شده است، ارتباط سریال RS-232 را شبیه سازی کرده است. برخی از قابلیت‌ها و محدودیت‌های این پروتکل به شرح زیر است:
- دو دیواس تنها می‌توانند از یک ارتباط RFCOMM در یک زمان استفاده کنند.
- هر Device بلوتوث می‌تواند حداکثر 30 سرویس فعال RFCOMM داشته باشد.
-هر Device تنها می‌تواند یک ارتباط با هر سرویس را حمایت کند.


URL که برای برقراری ارتباط استفاده می‌شود به صورت زیر می‌باشد:


btspp://102030405060740AIBICIDIE100:5


این بدین معناست که ارتباط از نوع bluetoothSerialPortPorotocol خواهد بود و کانال ارتباطی سرور 5 می‌باشد با آدرس 10203040506070AIBICIDIE100


... // assuming the service UID has been retrieved String serviceURL = "btspp://localhost:"+serviceUID.toString()); // more explicitly: String ServiceURL = "btspp://localhost:10203040607040A1B1C1DE100;name=SPP Server1"; try { // create a server connection StreamConnectionNotifier notifier = (StreamConnectionNotifier) Connector.open(serviceURL); // accept client connections StreamConnection connection = notifier.acceptAndOpen(); // prepare to send/receive data byte buffer[] = new byte[100]; String msg = "hello there, client"; InputStream is = connection.openInputStream(); OutputStream os = connection.openOutputStream(); // send data to the client os.write(msg.getBytes()); // read data from client is.read(buffer); connection.close(); } catch(IOException e) { e.printStackTrace(); } ...

و کد سمت کاربر نیز به صورت زیر می‌باشد: 
...
// (assuming we have the service record)
// use record to retrieve a connection URL
String url =
record.getConnectionURL(
record.NOAUTHENTICATE_NOENCRYPT, false);
// open a connection to the server
StreamConnection connection =
(StreamConnection) Connector.open(url);
// Send/receive data
try {
byte buffer[] = new byte[100];
String msg = "hello there, server";
InputStream is = connection.openInputStream();
OutputStream os = connection.openOutputStream();
// send data to the server
os.write(msg.getBytes);
// read data from the server
is.read(buffer);
connection.close();
} catch(IOException e) {
e.printStackTrace();
}
...

----------


## SaeidSsa

خيلي ممنون
saeid3sa@gmail.com

----------

