Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Ecrit par : Ex0ns
- * Site : ex0ns.hostei.com
- * Sources : http://people.csail.mit.edu/albert/bluez-intro/x604.html et http://people.csail.mit.edu/rudolph/Teaching/Articles/BTBook.pdf
- * Bibliothèque utilisées : bluez
- * Compilation : g++ advertise.cpp -o advertise -lbluetooth
- */
- #include <iostream>
- #include <unistd.h> // int close(int fd)
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <bluetooth/bluetooth.h>
- #include <bluetooth/sdp.h> // Fonction sdp_* (pour créer un service bluetooth)
- #include <bluetooth/sdp_lib.h> // sdp_session, sdp_close
- #include <bluetooth/rfcomm.h> // struct sockadd_rc
- #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
- #define BDADDR_LOCAL_INITIALIZER {{0, 0, 0, 0xff, 0xff, 0xff}} // De même mais pour BDADDR_LOCAL
- using namespace std;
- /*
- * Cette fonction, plutot complexe, permet d'ajouter un service à la liste des services disponible,
- * C'est l'équivalent de la fonction bluetooth.advertise_service() en python
- * La documentation sur la bibliothèque Bluez étant inexistante, cette fonction peut contenir des erreurs, mais est fonctionnelle.
- */
- sdp_session_t *advertise_service()
- {
- uint8_t rfcomm_port = 6; // Numéro de Port
- const char *service_name = "SerialPort"; // Nom du service
- uuid_t root_uuid, l2cap_uuid, rfcomm_uuid, svc_class_uuid;
- sdp_list_t *l2cap_list = 0,
- *rfcomm_list = 0,
- *root_list = 0,
- *proto_list = 0, // Contient tous les protocoles utilisés par le service (RFCOMM et L2CAP)
- *access_proto_list = 0,
- *svc_class_list = 0,
- *profile_list = 0;
- sdp_data_t *channel = 0;
- sdp_profile_desc_t profile;
- sdp_record_t record = { 0 };
- sdp_session_t *session = 0;
- // Informations sur la classe, équivalent au paramètre service_classes=[bluetooth.SERIAL_PORT_CLASS] dans le code python
- sdp_uuid16_create(&svc_class_uuid, SERIAL_PORT_SVCLASS_ID);
- svc_class_list = sdp_list_append(0, &svc_class_uuid);
- sdp_set_service_classes(&record, svc_class_list);
- // Informations sur le profile, équivalent au paramètre profiles=[bluetooth.SERIAL_PORT_PROFILE]) dans le code python
- sdp_uuid16_create(&profile.uuid, SERIAL_PORT_PROFILE_ID);
- profile.version = 0x0100;
- profile_list = sdp_list_append(0, &profile);
- sdp_set_profile_descs(&record, profile_list);
- // Rendre le service publique et detectable
- sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
- root_list = sdp_list_append(0, &root_uuid);
- sdp_set_browse_groups( &record, root_list );
- // Informations sur le protocol L2CAP (obligatoire pour la connexion, je n'ai toujours pas trouvé pourquoi)
- sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
- l2cap_list = sdp_list_append( 0, &l2cap_uuid );
- proto_list = sdp_list_append( 0, l2cap_list ); // Ajout du L2CAP à la liste des protocoles du service
- // Création de la socket RFCOMM
- sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
- channel = sdp_data_alloc(SDP_UINT8, &rfcomm_port);
- rfcomm_list = sdp_list_append( 0, &rfcomm_uuid );
- sdp_list_append( rfcomm_list, channel ); // Précise quel port (canal) utiliser
- sdp_list_append( proto_list, rfcomm_list ); // Ajout du protocol RFCOMM à la liste de ceux du service
- access_proto_list = sdp_list_append( 0, proto_list );
- sdp_set_access_protos( &record, access_proto_list );
- // Phase finale de création du service, on donne le nom, et accesoirement une description et un "fourniseur"
- sdp_set_info_attr(&record, service_name, NULL, NULL);
- // Il faut maintenant contacter le serveur SDP local pour créer et enregister un nouveau service
- bdaddr_t any = BDADDR_ANY_INITIALIZER; // Voir explications (commentaires suivants)
- bdaddr_t local = BDADDR_LOCAL_INITIALIZER; // De même
- session = sdp_connect(&any, &local, 0 ); // On contact le serveur sdp
- /*
- * Alors là, petit particularité, en théorie, la fonction sdp_connect s'appelle de la façon suivante :
- * session = sdp_connect(BDADDR_ANY, BD_ADDR_LOCAL, 0 );, mais en faisant ca, on obtient une erreur à la compilation,
- * Pour corriger on déclare deux constantes au début, BDADDR_ANY_INITIALIZER et BDADDR_LOCAL_INITIALIZER, que nous utiliserons
- */
- sdp_record_register(session, &record, 0); // On ajoute notre service à la liste des services
- // Il faut maintenant faire un peu de nettoyage dans nos structures
- sdp_data_free( channel );
- sdp_list_free( l2cap_list, 0 );
- sdp_list_free( rfcomm_list, 0 );
- sdp_list_free( root_list, 0 );
- sdp_list_free( access_proto_list, 0 );
- return session;
- }
- int main(){
- /*
- * Création d'un service bluetooth et écoute des données envoyées par le client
- * Pour reverse un protol BeeWi Helipad
- * Voir : http://ex0ns.hostei.com/article-6-Analyse-d-un-protocole-BeeWi-Helipad pour plus d'informations
- */
- int sock, client; // Nos deux sockets (client et serveur)
- socklen_t addrlen; // Taille de la structure qui contiendra les informations clients
- unsigned char buff[14];
- struct sockaddr_rc addr; // Structure des informations clients
- sock = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); // Création d'une socket bluetooth
- addr.rc_family = AF_BLUETOOTH; // On précise la famille (tout comme pour INET ou INET6)
- bdaddr_t any = BDADDR_ANY_INITIALIZER; // Même problème, vois explications dans la fonction ou au niveau de #define
- bacpy(&addr.rc_bdaddr, &any);
- addr.rc_channel = 6; // Port utilisé
- bind(sock, (struct sockaddr *)&addr, sizeof(addr)); // Rien de très étonnant
- listen(sock, 1); // On écoute un client
- sdp_session_t *session = advertise_service(); // On crée notre service, sur le même port
- addrlen = sizeof(addr);
- client = accept (sock, (struct sockaddr *)&addr, &addrlen); // Création de la socket client
- while(client){ // tant que le client est connecté
- recv(client, buff, 14, 0);
- cout << buff;
- }
- close (client); // Fermeture des sockets
- close (sock);
- sdp_close(session); // Fermeture du service
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement