WebCam Bluetooth - Partie 2

Réaliser une Webcam Bluetooth sous Windows Mobile - Partie 2

Introduction

Dans la première partie de ce tutorial, nous avons vu comment automatiser la prise de photos à l'aide de la classe CameraCaptureDialog du CF.NET. Dans cette seconde partie, nous allons aborder le transfert automatique et la consultation des images sur un ordinateur distant.




Transfert via Web Services

Cette méthode est certainement la plus facile à implémenter. Un web service hébergé sur un serveur web expose une méthode permettant de transférer la photo prise. Une fois stockée sur le serveur, celle-ci peut être consultée via une simple page HTML. Le principal inconvénient de cette technique provient des coûts de communications qu'elle engendre (GPRS, UMTS), notamment pour le périphérique mobile.

Transfert via Bluetooth

L'architecture Bluetooth, comme on peut le voir sur le schéma ci-dessous, repose sur une pile de protocoles variés, permettant différents types de transferts.



Par exemple :

  • OBEX (Object Exchange) : un protocole d'échange d'objets implémenté au-dessus de WinSock
  • COM Port Emulation : permet la création de ports COM virtuels
  • RFCOMM : protocole d'émulation d'un cable série
  • SDP (Service Discovery Protocol) : permet la publication et la découverte des services actifs sur un périphérique
  • LMP (Link Manager Protocol) : gère l'encryptage et l'authentification des liaisons Bluetooth

Malheureusement, le CF.NET 3.5 ne nous offre toujours pas d'API universelle permettant d'attaquer les stacks Bluetooth des différents constructeurs. Il est bien sûr possible d'utiliser la classe SerialPort, mais celà nous impose de définir un port COM virtuel sur chacun des périphériques, ce qui trop laborieux pour les utilisateurs finaux.

Pressé d'achever mon développement, je suis donc parti à la recherche de librairies natives. Mon choix s'est porté sur BlueTools de Franson (www.franson.com) qui supporte la stack Bluetooth Widcomm qui équipe mon portable HP NX9420. Cette librairie est payante, mais vous pouvez obtenir des licenses de test sur leur site.

Un peu de code...

Nous allons commencer par définir quelques variables d'instance :

private Manager m_manager = null;
private Network m_network = null;
private RemoteDevice m_deviceCurrent = null;
private RemoteService m_serviceCurrent = null;
private FileBrowser fb = null;
private Stream m_streamCurrent = null;
private Bitmap m_bmp = null;

Ces variables représentent les différents objets que nous allons utiliser pour effectuer un transfert FTP depuis le PC distant, dans leur ordre d'utilisation.

Le Manager est un peu le chef d'orchestre de l'ensemble ; il va nous permettre d'instancier les autres types d'objets. La classe Network représente un émetteur Blueetooth (dongle). Bluetooth 1.0 ne supporte qu'un seul dongle, donc pas de soucis de ce côté-là.

La classe Network va nous permettre de découvrir les périphériques Bluetooth à proximité. Elle va nous retourner une collection d'objets de type RemoteDevice. Lors de mes tests, j'ai pû constater qu'une fois détecté, je pouvais éloigner mon iPaq d'une dizaine de mètres sans perdre le signal.

Une fois le bon périphérique détecté, il nous reste à demander la liste des services qu'il propose, afin de vérifier que le FTP est bien disponible. Enfin, la classe FileBrowser va nous permettre de naviguer dans les répertoires du Pocket PC.

void ConnectToolStripMenuItemClick(object sender, EventArgs e)
{
this.Cursor = Cursors.WaitCursor;

try {

m_manager = Manager.GetManager();
m_manager.Parent = this;

// Get your trial license or buy BlueTools at franson.com
Franson.BlueTools.License license = new Franson.BlueTools.License();
license.LicenseKey = ConfigurationManager.AppSettings["LicenseKey"].ToString();

// Get first network (BlueTools 1.0 only supports one network == one dongle)
m_network = m_manager.Networks[0];

Device[] devices = m_network.DiscoverDevices();

if (devices.Length==0)
throw new Exception("No Bluetooth devices in range.");


Device oDevice = devices[0];

this.toolStripStatusLabelDevice.Text= "Connected to " + oDevice.Name
+ " " + oDevice.Address;

m_deviceCurrent = (RemoteDevice)m_network.ConnectDevice(oDevice.Address, oDevice.Name);
Service[] services = m_deviceCurrent.DiscoverServices(ServiceType.OBEXFileTransfer);

fb = new FileBrowser();
fb.Parent = this;
m_serviceCurrent = (RemoteService)services[0];
m_streamCurrent = m_serviceCurrent.Stream;

fb.Connect(m_streamCurrent);

fb.SetPath("My Pictures");


connectToolStripMenuItem.Enabled=false;
getPicture();
timer1.Enabled = true;
}
catch(Exception ex)
{
this.Cursor = Cursors.Default;
MessageBox.Show(ex.Message,"Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}

this.Cursor = Cursors.Default;

}
A l'aide d'un Timer, nous allons à intervalle régulier récupérer la photo mise à jour sur le Pocket PC. La classe FileBrowser va nous permettre de récupérer un stream binaire afin de sauvegarder l'image sur disque. Elle sera ensuite rechargée à l'aide de la classe Bitmap, modifiée afin d'y intégrer l'heure du transfert, puis affichée à l'écran via une PictureBox.

void getPicture() {
try {
pbSnapshot.Visible=false;
if (m_bmp!=null)
m_bmp.Dispose();

string date = DateTime.Now.ToString("HH:mm:ss");
string path = ConfigurationManager.AppSettings["TempFolder"].ToString() + "\\Snapshot.jpg";
FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write);

fb.GetFile(fs, "Snapshot.jpg");
fs.Close();
m_bmp = new Bitmap(path);

Graphics g = Graphics.FromImage((Image)m_bmp);

Font fnt = new Font("Arial",12.0f);
Brush brush = new SolidBrush(Color.White);

g.DrawString(date, fnt, brush, 5,5);
g.Dispose();

pbSnapshot.Image = (Image)m_bmp;
pbSnapshot.Visible=true;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Attention de bien veiller à fermer proprement vos connections à la sortie de l'application, sous peine de devoir éteindre puis rallumer votre émetteur Bluetooth.

void quit() {
if (fb!=null)
if (fb.Connected)
fb.Disconnect();
if (m_manager!=null)
m_manager.Dispose();
Application.Exit();
}
Conclusion

Voilà qui clôture ce premier article consacré à la communication Bluetooth en .NET. Les codes sources de l'application SpyCam sont disponibles sur demande à l'adresse suivante : fabrice.kauffmann@gmail.com

Commentaires