Página 1 de 1

bluetooth como serial.

MensagemEnviado: 03 Jan 2012 12:41
por fabim
Pessoal, eu a uns dois anos consegui usar o bluetooth no pc como se fosse uma serial comum no windows, e também encontrei um tutorial para o WinCE para fazer o mesmo.
Agora eu estou a uns 5 dias procurando uma forma, de eu usar o bluetooth made R$3,50, espetado no meu notebook como Serial, e mesmo no meu desktop.

O que eu quero fazer é algo bem simples.
Para meu aprendizado, pelo menos na teoria.

comunicação S2S, hehehe!!! terminal de um note versus terminal do pc. O que digita aqui, sai lá do outro lado, e vice e versa.
Com isso eu vou aprender a:

Conceitos da USB no Linux.
Conceitos das possíveis gambiarras.
Orientação da programação.
Conceito da portabilidade entre distros, ou embedded que seja. "librarys etc".

Não sei se tem muita gente querendo aprender estes macetes, e caso existam pessoas querendo. Ficaria muito legal uma cooperação mutua entre imbecis sem ter o que fazer além de querer FAZER uma coisa e aprender 100 ao mesmo tempo.!!

Minha distro é UBUNTU, Kernel 3.xxx, recompilada pra arrancar tudo que não prestava.

Abraços

MensagemEnviado: 03 Jan 2012 15:46
por chipselect
eu uso BlueZ, segue link que podem ser úteis a você:
http://www.hanscees.com/bluezhowto.html
http://people.csail.mit.edu/albert/blue ... /x502.html
http://www.linuxquestions.org/questions ... ez-806692/

Não segui essas referências quando desenvolvi a parte de bluetooth (SPP), mas aparentemente trazem informações bem úteis.

Código que inicia a conexão bluetooth usando o protocolo SPP. O handle retornado você usa como se estivesse usando uma stream para uma porta serial. Também assume que você configurou o RFCOMM para master e que o dispositivo slave não possui código de acesso além de suportar SPP.

Código: Selecionar todos


/**
* Efetua a conexão com o endereço MAC fornecido
* @param enderecoMac string contendo o endereço MAC do dispositivo
* @return stream de conexão ou -1 em caso de falha.
**/
int bluetoothConnect(char *enderecoMac){
    struct sockaddr_rc addr;
    int s, status;
    int sock_flags;
    TAddr address;
    pthread_t th;
    memset(&addr, 0, sizeof(addr));
    gboolean finalizado;

    if (enderecoMac == NULL) return -1;

    s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
    if (s < 0)
        return s;
    addr.rc_family = AF_BLUETOOTH;
    addr.rc_channel = 1;
    str2ba( enderecoMac, &addr.rc_bdaddr );

    sock_flags = fcntl( s, F_GETFL, 0 );
    fcntl( s, F_SETFL, sock_flags | O_NONBLOCK );
    address.addr = (struct sockaddr *) &addr;
    address.size = sizeof(addr);
    address.finalizado = FALSE;
    address.status = -1;
    address.soc = s;
    status = pthread_create(&th,
                            NULL,
                            connect_w_to,
                            (void *)(&address));
    if (status < 0){
        g_usleep(1000);
        logDebug("Erro criando thread de conexão\n");
    }
    status = 0;
    //winShowAnimatedScreen("animatedBar.gif", "Aguarde, conectando...", &(address.finalizado), &finalizado);
    if (finalizado) pthread_cancel(th);

    //todo: verificar se foi finalizado pelo usuário.
    while (!address.finalizado && !finalizado) {
        //logDebug("Aguardando conexão %d\n", status++);
    }
    pthread_detach(th);
    logDebug("Conexão com bluetooth: fd= %d, status= %d\n", s, address.status);
    if (finalizado || address.status < 0) {
        close(s);
        s = -1;
    }
    return s;
}


Esse código roda dentro de uma thread, fiz um pooling para aguardar a conexão (POG...) mas um dia vou melhorar isso e fazer direito.

TAddr eu defini assim:

typedef struct {
struct sockaddr *addr;
int soc;
int size;
gboolean finalizado;
int status;
gboolean finalizar;
}TAddr;

Eu monto uma lista de dispositivos BT que estão visíveis, mostro ao usuário para selecionar qual dispositivo ele quer se conectar, então eu pego o MAC e passo para essa função. O handle retornado eu uso fazendo IO como se fosse para uma serial.



Editado para remover o ifdef que tinha sobrado...

MensagemEnviado: 03 Jan 2012 16:43
por chipselect
segue o código que faltou.

Código: Selecionar todos

//função em thread para conexão com timeout
void *connect_w_to(void *adr) {
  int res;
  fd_set myset;
  struct timeval tv;
  int valopt;
  socklen_t lon;
  TAddr *address = (TAddr *) adr;
//  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
//  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

  res = connect(address->soc, address->addr, address->size);
  if (res < 0) {
     if (errno == EINPROGRESS) {
        do {
           tv.tv_sec = 15;
           tv.tv_usec = 0;
           FD_ZERO(&myset);
           FD_SET(address->soc, &myset);
           res = select(address->soc+1, NULL, &myset, NULL, &tv);

           if (res < 0 && errno != EINTR) {
               address->finalizado = TRUE;
           } else {
               address->finalizado = TRUE;
               if (res > 0){
                  lon = sizeof(int);
                  if(getsockopt(address->soc,
                                SOL_SOCKET,
                                SO_ERROR,
                                (void*)(&valopt),
                                &lon) >= 0){
                     if (!valopt) {
                         address->status = res;
                     }
                  }

               } else {//time out
                   address->status = -2;
               }
           }
        } while (!address->finalizado);
     } else { //erro iniciando o select
         address->status = -3;
         address->finalizado = TRUE;
     }
  }
  return NULL;
}


MensagemEnviado: 04 Jan 2012 06:53
por fabim
Chipselect.

Eu compreendi em partes, pois C é C.
Mais existem chamadas que me levam a crer que é necessario alguma library, tipo quais headers eu uso ai ?
Ta tudo no pacote blueZ ?

OBS>: é possivel eu usar o blueZ numa mini2440 por exemplo ?!

MensagemEnviado: 04 Jan 2012 08:08
por Wagner de Queiroz
Fabim, segundo o site de download do bluez, o kernel ja tem suporte ao bluez, mas por padrao, o kernel da mini2440 nao esta compilado com o bluetooth. Mas nao se desespere não.

no make menuconfig vc pode habilitar a compilacao do bluetooth
vá em Networking e habilite o suporte ao subsistema bluetooth
Código: Selecionar todos
Networking --->

<*> Bluetooth subsystem support  --->

--- Bluetooth subsystem support
<*>   L2CAP protocol support
<*>   SCO links support
<*>   RFCOMM protocol support
[*]     RFCOMM TTY support
<*>   BNEP protocol support
[*]     Multicast filter support
[*]     Protocol filter support
<M>   HIDP protocol support



Compile o kernel e seja feliz.


http://www.friendlyarm.net/forum/topic/2675

MensagemEnviado: 04 Jan 2012 08:48
por fabim
HUM!!!!!!!!!!!!!
Eu entendi !!!
Type:
Eu habilito o modulo do bluetooth. E este por sua vez vai bater papo com o bluZ.
E minha aplicação irá falar com o bluZ, que por sua vez vai falar com o kernel, que como "mandão do pedaço" irá fazer os modulos funcionarem como front-end da bagaça!!
Agora tendi o conceito !!

MensagemEnviado: 04 Jan 2012 09:45
por polesapart
chipselect escreveu:
Código: Selecionar todos
    //winShowAnimatedScreen("animatedBar.gif", "Aguarde, conectando...", &(address.finalizado), &finalizado);





Que raio é isso? :P

MensagemEnviado: 04 Jan 2012 11:24
por Wagner de Queiroz
Código: Selecionar todos
    //winShowAnimatedScreen("animatedBar.gif", "Aguarde, conectando...", &(address.finalizado), &finalizado);


// Isto é um comentario

MensagemEnviado: 05 Jan 2012 19:45
por chipselect
isso ai eh uma chamada a um raio de biblioteca que eu fiz, seria algo proximo ao form.show do delphi, que dispara os eventos OnShow, OnActivate, etc... ignore

MensagemEnviado: 05 Jan 2012 19:47
por chipselect
entre as bibliotecas que eu uso estao a GLib e a PThreads, alem das lib para rede.