IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Linux Discussion :

[ bluez, hci ] && [ python || C ] multidevices (bluetooth)


Sujet :

Linux

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 1
    Points : 2
    Points
    2
    Par défaut [ bluez, hci ] && [ python || C ] multidevices (bluetooth)
    Bonjour a tous,

    Vue que ce message est mon premier post j'espère que le sujet parrait cohérent et que je suis dans le bon forum.

    Bref allons a l'essentiel....

    Je suis entrain de chercher comment récupérer le RSSI des inquiry devices sur plusieurs dongle USB bluetooth via les lib de bluez.




    J'ai trouvé plusieurs codes:

    Code 1:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
     
    #include <netdb.h>
    #include <bluetooth/bluetooth.h>
    #include <bluetooth/hci.h>
    #include <bluetooth/hci_lib.h>
    #include <sys/types.h>
    #include <sys/socket.h>
     
    int main (int argc, char **argv)
    {
    	int sock, retval;
    	int i;
    	unsigned char buf[HCI_MAX_FRAME_SIZE];
    	struct sockaddr_hci addr;
    	struct hci_filter filter;
    	unsigned char cmd[] = {0x01, 0x01, 0x04, 0x05, 0x33, 0x8B, 0x9E, 0x08, 0x0A};
    	int cmd_len = sizeof(cmd);
    	int encore = 1;
     
    	sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
    	if (-1 == sock) exit(1);
     
    	hci_filter_clear(&filter);
    	hci_filter_all_ptypes(&filter);
    	hci_filter_all_events(&filter);
     
    	retval = setsockopt(sock, SOL_HCI, HCI_FILTER, &filter, sizeof(filter)); 
    	if (-1 == retval) exit(1);
     
    	addr.hci_family = AF_BLUETOOTH;
    	addr.hci_dev = 0;
    	retval = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
    	if (-1 == retval) exit(1);
     
    	retval = send (sock, cmd, cmd_len, 0);
    	if (-1 == retval) exit(1);
     
    	do {
    		memset (buf, 0, sizeof(buf));
    		retval = recv (sock, buf, sizeof(buf), 0);
    		if (-1 == retval) exit(1);
    		switch (buf[1]) {
    			case EVT_CMD_STATUS:
    				if (buf[3]) {
    					printf ("Erreur !\n");
    					encore = 0;
    				} else {
    					printf ("Commande en cours\n");
    				}
    				break;
    			case EVT_INQUIRY_RESULT: 
    				printf ("Périphérique trouvé:\n");
    				printf ("  * Adresse : %02x:%02x:%02x:%02x:%02x:%02x\n",
    					buf[9], buf[8],
    					buf[7], buf[6],
    					buf[5], buf[4]);
    				printf ("  * Classe : 0x%02x%02x%02x\n",
    					buf[15], buf[14], buf[13]);
    				break;
    			case EVT_INQUIRY_COMPLETE:
    				encore = 0;
    				break;
    			default:
    				break;
    		}
    	} while (encore);
     
    	close (sock);
     
    	return 0;
    }
    code 2:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
     
    # performs a simple device inquiry, followed by a remote name request of each
    # discovered device
     
    import os
    import sys
    import struct
    import bluetooth._bluetooth as bluez
     
    def printpacket(pkt):
        for c in pkt:
            sys.stdout.write("%02x " % struct.unpack("B",c)[0])
        print 
     
     
    def read_inquiry_mode(sock):
        """returns the current mode, or -1 on failure"""
        # save current filter
        old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14)
     
        # Setup socket filter to receive only events related to the
        # read_inquiry_mode command
        flt = bluez.hci_filter_new()
        opcode = bluez.cmd_opcode_pack(bluez.OGF_HOST_CTL, 
                bluez.OCF_READ_INQUIRY_MODE)
        bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT)
        bluez.hci_filter_set_event(flt, bluez.EVT_CMD_COMPLETE);
        bluez.hci_filter_set_opcode(flt, opcode)
        sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt )
     
        # first read the current inquiry mode.
        bluez.hci_send_cmd(sock, bluez.OGF_HOST_CTL, 
                bluez.OCF_READ_INQUIRY_MODE )
     
        pkt = sock.recv(255)
     
        status,mode = struct.unpack("xxxxxxBB", pkt)
        if status != 0: mode = -1
     
        # restore old filter
        sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter )
        return mode
     
    def write_inquiry_mode(sock, mode):
        """returns 0 on success, -1 on failure"""
        # save current filter
        old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14)
     
        # Setup socket filter to receive only events related to the
        # write_inquiry_mode command
        flt = bluez.hci_filter_new()
        opcode = bluez.cmd_opcode_pack(bluez.OGF_HOST_CTL, 
                bluez.OCF_WRITE_INQUIRY_MODE)
        bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT)
        bluez.hci_filter_set_event(flt, bluez.EVT_CMD_COMPLETE);
        bluez.hci_filter_set_opcode(flt, opcode)
        sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt )
     
        # send the command!
        bluez.hci_send_cmd(sock, bluez.OGF_HOST_CTL, 
                bluez.OCF_WRITE_INQUIRY_MODE, struct.pack("B", mode) )
     
        pkt = sock.recv(255)
     
        status = struct.unpack("xxxxxxB", pkt)[0]
     
        # restore old filter
        sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter )
        if status != 0: return -1
        return 0
     
    def device_inquiry_with_with_rssi(sock):
        # save current filter
        old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14)
     
        # perform a device inquiry on bluetooth device #0
        # The inquiry should last 8 * 1.28 = 10.24 seconds
        # before the inquiry is performed, bluez should flush its cache of
        # previously discovered devices
        flt = bluez.hci_filter_new()
        bluez.hci_filter_all_events(flt)
        bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT)
        sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt )
     
        duration = 4
        max_responses = 255
        cmd_pkt = struct.pack("BBBBB", 0x33, 0x8b, 0x9e, duration, max_responses)
        bluez.hci_send_cmd(sock, bluez.OGF_LINK_CTL, bluez.OCF_INQUIRY, cmd_pkt)
     
        results = []
     
        done = False
        while not done:
            pkt = sock.recv(255)
            ptype, event, plen = struct.unpack("BBB", pkt[:3])
            if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI:
                pkt = pkt[3:]
                nrsp = struct.unpack("B", pkt[0])[0]
                for i in range(nrsp):
                    addr = bluez.ba2str( pkt[1+6*i:1+6*i+6] )
                    rssi = struct.unpack("b", pkt[1+13*nrsp+i])[0]
                    results.append( ( addr, rssi ) )
                    print "[%s] RSSI: [%d]" % (addr, rssi)
            elif event == bluez.EVT_INQUIRY_COMPLETE:
                done = True
            elif event == bluez.EVT_CMD_STATUS:
                status, ncmd, opcode = struct.unpack("BBH", pkt[3:7])
                if status != 0:
                    print "uh oh..."
                    printpacket(pkt[3:7])
                    done = True
            else:
                print "unrecognized packet type 0x%02x" % ptype
     
     
        # restore old filter
        sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter )
     
        return results
     
    dev_id = 0
    try:
        sock = bluez.hci_open_dev(dev_id)
    except:
        print "error accessing bluetooth device..."
        sys.exit(1)
     
    try:
        mode = read_inquiry_mode(sock)
    except Exception, e:
        print "error reading inquiry mode.  "
        print "Are you sure this a bluetooth 1.2 device?"
        print e
        sys.exit(1)
    print "current inquiry mode is %d" % mode
     
    if mode != 1:
        print "writing inquiry mode..."
        try:
            result = write_inquiry_mode(sock, 1)
        except Exception, e:
            print "error writing inquiry mode.  Are you sure you're root?"
            print e
            sys.exit(1)
        if result != 0:
            print "error while setting inquiry mode"
        print "result: %d" % result
     
    device_inquiry_with_with_rssi(sock)


    Si quelqu'un a une petite idée vite fait sur comment ajouter l'affichage du RSSI pour le code en C je suis preneur... Sinon je chercherai.

    Sinon la question essentiel, je ne suis pas arriver a comprendre comment je pouvais scanner plusieurs périphériques en meme temps soit par exemple hci0, hci1, ...., hcin.

    J'ai essayé en adaptant le script python pour mettre en argument le hci (exemple: python inquiry.py hci0) et ai fait un petit script pour lancer ceci en parallèle, ce qui execute python inquiry.py hci0 python inquiry.py hci1 ...etc.

    Malheureusement le premier s'exécute correctement puis les autres ne semblent pas passer...

    Je n'ai que des bases en C et en python... J'avais pensé aux thread pour le code en C...

    Voila j'espère que vous avez comprit et que quelqu'un pourra m'aider...

    Merci d'avance!

  2. #2
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2008
    Messages : 21
    Points : 13
    Points
    13
    Par défaut
    Pour parcourir tes différentes interfaces il faut que tu réalise une boucle sur le nombre d'interface que tu as sur ta machine en changeant le paramètre hci_dev de ta variable addr exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int i;
    for(i=0;i<nbInterface;i++){
     addr.hci_family = AF_BLUETOOTH;
     addr.hci_dev = i;
     ....//ton traitement.
    Pour ce qui est de faire des threads pour ce genre de traitement... Je saurais faire mais je peux t'expliquer le fonctionnement des threads en C sur un topic... Il y a beaucoup de tutoriaux à ce sujet. Mais je ne vois pas bien l'utilité de faire ce genre de traitement dans des threads. Ce ne sont pas de gros traitements. Mais bon si jamais c'est vraiment nécessaire renseigne toi (via google) sur les threads. Mais ce n'est pas très sorcier. Et sans aller dans les threads à proprement parler tu pourrais te cantonner à faire des processus fils au processus principal via des fork() c'est ultra simple et déjà suffisant e fonction de ce que tu fais.

    Voilà pour le C j'espère ne pas avoir mis trop d'anneries. Je sais que ce post est déjà vieux mais si vous êtes comme moi que vous cherchez quelque chose et que vous tombez sur ce post peut être ma réponse vous aidera.

    Pour ce qui est du python j'en sais rien et je n'ai même pas regarder. Je connais rien au python!!!

  3. #3
    Membre expérimenté
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Points : 1 742
    Points
    1 742
    Par défaut
    Salut les gars, je suis un python.
    Je suis tomber sur ce post en faisant une recherche internet visant a trouver un document listant les familles de commandes hci et celles çi (en opcode|hex|bin) mais je suis bredouille et comme je suis membre du site j'aimerai savoir si un tel document existe ?
    Si quelqu'un connait un|des liens vers de la documentation plus spécifique sur le langage hci il serai sympa de le|les poster.
    Merci d'avance.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo