Need a unique gift idea?
A Pastebin account makes a great Christmas gift
SHARE
TWEET

Untitled

a guest Sep 26th, 2012 65 Never
Upgrade to PRO!
ENDING IN00days00hours00mins00secs
 
  1. /*
  2.  * Ecrit par : Ex0ns
  3.  * Site : ex0ns.hostei.com
  4.  * Sources : http://people.csail.mit.edu/albert/bluez-intro/x604.html et http://people.csail.mit.edu/rudolph/Teaching/Articles/BTBook.pdf
  5.  * Bibliothèque utilisées : bluez
  6.  * Compilation : g++ advertise.cpp -o advertise -lbluetooth
  7.  */
  8.  
  9. #include <iostream>
  10. #include <unistd.h> // int close(int fd)
  11. #include <sys/types.h>
  12. #include <sys/socket.h>
  13. #include <bluetooth/bluetooth.h>
  14. #include <bluetooth/sdp.h>  // Fonction sdp_* (pour créer un service bluetooth)
  15. #include <bluetooth/sdp_lib.h> // sdp_session, sdp_close
  16. #include <bluetooth/rfcomm.h> // struct sockadd_rc
  17.  
  18. #define BDADDR_ANY_INITIALIZER   {{0, 0, 0, 0, 0, 0}} // Définition pour régler un prolème de temporary addresses lié à l'utilisation de BDADDR_ANY
  19. #define BDADDR_LOCAL_INITIALIZER {{0, 0, 0, 0xff, 0xff, 0xff}} // De même mais pour BDADDR_LOCAL
  20.  
  21. using namespace std;
  22.  
  23. /*
  24.  * Cette fonction, plutot complexe, permet d'ajouter un service à la liste des services disponible,
  25.  * C'est l'équivalent de la fonction bluetooth.advertise_service() en python
  26.  * La documentation sur la bibliothèque Bluez étant inexistante, cette fonction peut contenir des erreurs, mais est fonctionnelle.
  27.  */
  28. sdp_session_t *advertise_service()
  29. {
  30.         uint8_t rfcomm_port = 6; // Numéro de Port
  31.         const char *service_name = "SerialPort"; // Nom du service
  32.         uuid_t root_uuid, l2cap_uuid, rfcomm_uuid,  svc_class_uuid;
  33.         sdp_list_t *l2cap_list = 0,
  34.                            *rfcomm_list = 0,
  35.                            *root_list = 0,
  36.                            *proto_list = 0, // Contient tous les protocoles utilisés par le service (RFCOMM et L2CAP)
  37.                            *access_proto_list = 0,
  38.                            *svc_class_list = 0,
  39.                            *profile_list = 0;
  40.         sdp_data_t *channel = 0;
  41.         sdp_profile_desc_t profile;
  42.         sdp_record_t record = { 0 };
  43.         sdp_session_t *session = 0;
  44.  
  45.         // Informations sur la classe, équivalent au paramètre  service_classes=[bluetooth.SERIAL_PORT_CLASS] dans le code python
  46.         sdp_uuid16_create(&svc_class_uuid, SERIAL_PORT_SVCLASS_ID);
  47.         svc_class_list = sdp_list_append(0, &svc_class_uuid);
  48.         sdp_set_service_classes(&record, svc_class_list);
  49.        
  50.         // Informations sur le profile, équivalent au paramètre profiles=[bluetooth.SERIAL_PORT_PROFILE]) dans le code python
  51.         sdp_uuid16_create(&profile.uuid, SERIAL_PORT_PROFILE_ID);
  52.         profile.version = 0x0100;
  53.         profile_list = sdp_list_append(0, &profile);
  54.         sdp_set_profile_descs(&record, profile_list);
  55.  
  56.  
  57.         // Rendre le service publique et detectable
  58.         sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
  59.         root_list = sdp_list_append(0, &root_uuid);
  60.         sdp_set_browse_groups( &record, root_list );
  61.  
  62.         // Informations sur le protocol L2CAP (obligatoire pour la connexion, je n'ai toujours pas trouvé pourquoi)
  63.         sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
  64.         l2cap_list = sdp_list_append( 0, &l2cap_uuid );
  65.         proto_list = sdp_list_append( 0, l2cap_list ); // Ajout du L2CAP à la liste des protocoles du service
  66.  
  67.         // Création de la socket RFCOMM
  68.         sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
  69.         channel = sdp_data_alloc(SDP_UINT8, &rfcomm_port);
  70.         rfcomm_list = sdp_list_append( 0, &rfcomm_uuid );
  71.         sdp_list_append( rfcomm_list, channel ); // Précise quel port (canal) utiliser
  72.        
  73.         sdp_list_append( proto_list, rfcomm_list ); // Ajout du protocol RFCOMM à la liste de ceux du service
  74.         access_proto_list = sdp_list_append( 0, proto_list );
  75.         sdp_set_access_protos( &record, access_proto_list );
  76.  
  77.         // Phase finale de création du service, on donne le nom, et accesoirement une description et un "fourniseur"
  78.         sdp_set_info_attr(&record, service_name, NULL, NULL);
  79.  
  80.  
  81.         // Il faut maintenant contacter le serveur SDP local pour créer et enregister un nouveau service
  82.         bdaddr_t any  = BDADDR_ANY_INITIALIZER; // Voir explications (commentaires suivants)
  83.         bdaddr_t local = BDADDR_LOCAL_INITIALIZER; // De même
  84.         session = sdp_connect(&any, &local, 0 ); // On contact le serveur sdp
  85.         /*
  86.          * Alors là, petit particularité, en théorie, la fonction sdp_connect s'appelle de la façon suivante :
  87.          * session = sdp_connect(BDADDR_ANY, BD_ADDR_LOCAL, 0 );, mais en faisant ca, on obtient une erreur à la compilation,
  88.          * Pour corriger on déclare deux constantes au début, BDADDR_ANY_INITIALIZER et BDADDR_LOCAL_INITIALIZER, que nous utiliserons
  89.          */
  90.         sdp_record_register(session, &record, 0); // On ajoute notre service à la liste des services
  91.        
  92.         // Il faut maintenant faire un peu de nettoyage dans nos structures
  93.         sdp_data_free( channel );
  94.         sdp_list_free( l2cap_list, 0 );
  95.         sdp_list_free( rfcomm_list, 0 );
  96.         sdp_list_free( root_list, 0 );
  97.         sdp_list_free( access_proto_list, 0 );
  98.        
  99.         return session;
  100. }
  101.  
  102. int main(){
  103.         /*
  104.          * Création d'un service bluetooth et écoute des données envoyées par le client
  105.          * Pour reverse un protol BeeWi Helipad
  106.          * Voir : http://ex0ns.hostei.com/article-6-Analyse-d-un-protocole-BeeWi-Helipad pour plus d'informations
  107.          */
  108.         int sock, client; // Nos deux sockets (client et serveur)
  109.         socklen_t addrlen; // Taille de la structure qui contiendra les informations clients
  110.         unsigned char buff[14];
  111.         struct sockaddr_rc addr; // Structure des informations clients
  112.        
  113.         sock = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); // Création d'une socket bluetooth
  114.  
  115.         addr.rc_family = AF_BLUETOOTH; // On précise la famille (tout comme pour INET ou INET6)
  116.         bdaddr_t any = BDADDR_ANY_INITIALIZER; // Même problème, vois explications dans la fonction ou au niveau de #define
  117.         bacpy(&addr.rc_bdaddr, &any);
  118.         addr.rc_channel = 6; // Port utilisé
  119.        
  120.         bind(sock, (struct sockaddr *)&addr, sizeof(addr)); // Rien de très étonnant
  121.         listen(sock, 1); // On écoute un client
  122.        
  123.         sdp_session_t *session = advertise_service(); // On crée notre service, sur le même port
  124.         addrlen = sizeof(addr);
  125.         client = accept (sock, (struct sockaddr *)&addr, &addrlen); // Création de la socket client
  126.         while(client){ // tant que le client est connecté
  127.                 recv(client, buff, 14, 0);
  128.                 cout << buff;
  129.         }
  130.         close (client); // Fermeture des sockets
  131.         close (sock);
  132.         sdp_close(session); // Fermeture du service
  133.         return 0;
  134. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top