Advertisement
Guest User

Untitled

a guest
Sep 26th, 2012
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.98 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement