Linux에서 BLE 프린터를 연결하는 것에 대해 혼란스러워함

Linux에서 BLE 프린터를 연결하는 것에 대해 혼란스러워함

저는 임베디드 Linux 시스템(kernel-5.10.24)을 개발 중이며 시스템에 BT 컨트롤러가 있습니다.

이제 BLE 프린터로 테스트 중입니다.
다음 테스트를 실행할 때 혼란스럽습니다.

  1. 달리기bluetoothd -- -d -n -C &
  2. 달리기bluetooth power on
  3. 달리기bluetooth scan on
  4. 달리기bluetooth scan off
  5. 달리기bluetooth devices
  6. Linux 보드를 프린터와 페어링bluetooth trust 02:00:7A:05:BF:6C
  7. 실행 rctest -s 02:00:7A:05:BF:6C하고 프린터가 작동을 시작할 때까지 약 15초 정도 기다립니다.

그런 다음 rfcomm_client.c를 얻었습니다.https://github.com/balle/bluetooth-snippets/blob/master/rfcomm-client.c.

/*
  BlueZ example code to build an rfcomm client.
  This code just creates a socket and connects
  to a remote bluetooth device and sends a string.

  Programmed by Bastian Ballmann
  http://www.geektown.de

  Compile with gcc -lbluetooth <executable> <source>
*/

#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
#include <bluetooth/hci.h>

int main(int argc, char *argv[])
{
  int sock, d;
  struct sockaddr_rc laddr, raddr;
  struct hci_dev_info di;

  if(argc < 4)
    {
      printf("%s <btaddr> <channel> <cmd>\n", argv[0]);
      exit(0);
    }

  if(hci_devinfo(0, &di) < 0) 
    {
      perror("HCI device info failed");
      exit(1);
    }

  printf("Local device %s\n", batostr(&di.bdaddr));

  laddr.rc_family = AF_BLUETOOTH;
  laddr.rc_bdaddr = di.bdaddr;
  laddr.rc_channel = 0;

  raddr.rc_family = AF_BLUETOOTH;
  str2ba(argv[1],&raddr.rc_bdaddr);
  raddr.rc_channel = atoi(argv[2]);  

  if( (sock = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0)
    {
      perror("socket");
    }

  if(bind(sock, (struct sockaddr *)&laddr, sizeof(laddr)) < 0)
    {
      perror("bind");
      exit(1);
    }

  printf("Remote device %s\n", argv[1]);

  if(connect(sock, (struct sockaddr *)&raddr, sizeof(raddr)) < 0)
    {
      perror("connect");
      exit(1);
    }
  
  printf("Connected.\nSending data %s\n",argv[3]);
  send(sock,argv[3],strlen(argv[3]),0);
  printf("Disconnect.\n");
  close(sock);
  return 0;
}

rctest.c를 참조하여 위의 코드를 Linux 보드에서 실행했는데, rfcomm_client 02:00:7A:05:BF:6C 10 "Hello world""Hello World"가 프린터로 전송되었고 로그에는 작동한다고 했으나 아무것도 인쇄되지 않았습니다.

# ./rfcomm_client 02:00:7A:05:BF:6C 10 "Hello world"
Local device CD:9C:8C:87:95:30
Remote device 02:00:7A:05:BF:6C

Connected.
Sending data Hello world
Disconnect.

커널 로그는

[ 3377.840051] Bluetooth: hu 031a528d retransmitting 1 pkts
[ 3377.846977] rtk_btcoex: hci create connection, start paging
[ 3378.017929] rtk_btcoex: connected, handle 000a, status 0x00
[ 3378.023824] rtk_btcoex: Page success
[ 3378.047249] rtk_btcoex: io capability request
[ 3378.888706] rtk_btcoex: link key notify
[ 3378.932547] rtk_btcoex: l2cap op 2, len 16, out 1
[ 3378.937489] rtk_btcoex: TX l2cap conn req, hndl 0x000a, PSM 0x0003, scid 0x0040
[ 3378.945664] rtk_btcoex: l2cap op 3, len 20, out 0
[ 3378.950647] rtk_btcoex: RX l2cap conn rsp, hndl 0x000a, dcid 0x0051, scid 0x0040, result 0x0000
[ 3378.959714] rtk_btcoex: l2cap connection success, update connection
[ 3378.966218] rtk_btcoex: update_profile_connection: is_add 1, profile_index 3
[ 3378.973533] rtk_btcoex: update_profile_connection: phci_conn->profile_bitmap 0x08
[ 3378.981289] rtk_btcoex: rtk_notify_profileinfo_to_fw: BufferSize 5
[ 3378.987690] rtk_btcoex: rtk_notify_profileinfo_to_fw: NumberOfHandles 1
[ 3378.994553] rtk_btcoex: rtk_notify_profileinfo_to_fw: handle 0x000a
[ 3379.001058] rtk_btcoex: rtk_notify_profileinfo_to_fw: profile_bitmap 0x08
[ 3379.008117] rtk_btcoex: rtk_vendor_cmd_to_fw: opcode 0xfc19
[ 3379.053843] rtk_btcoex: l2cap op 6, len 16, out 1
[ 3379.058794] rtk_btcoex: TX l2cap disconn req, hndl 0x000a, dcid 0x0051, scid 0x0040
[ 3379.066767] rtk_btcoex: handle_l2cap_discon_req: handle 0x000a, dcid 0x0051, scid 0x0040, dir 1
[ 3379.075799] rtk_btcoex: update_profile_connection: is_add 0, profile_index 3
[ 3379.083122] rtk_btcoex: rtk_check_del_timer: handle 0x   a
[ 3379.088817] rtk_btcoex: update_profile_connection: phci_conn->profile_bitmap 0x00
[ 3379.096592] rtk_btcoex: rtk_notify_profileinfo_to_fw: BufferSize 2
[ 3379.103003] rtk_btcoex: rtk_notify_profileinfo_to_fw: NumberOfHandles 0
[ 3379.109845] rtk_btcoex: rtk_vendor_cmd_to_fw: opcode 0xfc19
[ 3379.115646] rtk_btcoex: Delete profile: hndl 0x000a, psm 0x0003, dcid 0x0051, scid 0x0040
[ 3379.714324] rtk_btcoex: disconn cmpl evt: status 0x00, handle 000a, reason 0x13
[ 3379.721942] rtk_btcoex: process disconn complete event.

do_send()rctest.c(do_connect() 함수에서 프린터에 연결하는 데 사용되며 channel=10실행 시 동일한 채널 10을 사용함 ) 를 다시 확인한 rfcomm_client결과 다음 코드를 찾았습니다.

577     seq = 0;
578     while ((num_frames == -1) || (num_frames-- > 0)) {
579         put_le32(seq, buf);
580         put_le16(data_size, buf + 4);
581
582         seq++;
583
584         if (send(sk, buf, data_size, 0) <= 0) {
585             syslog(LOG_ERR, "Send failed: %s (%d)",
586                             strerror(errno), errno);
587             exit(1);
588         }
589
590         if (num_frames && delay && count && !(seq % count))
591             usleep(delay);
592     }

num_frames = -1;, count = 1, delay = 0, 은 긴밀한 루프에서 127바이트를 보내는 것으로 data_size=127보이며 rctest프린터가 작동합니다.

그러나 rfcomm_client.c그것은 소용이 없습니다.

문제가 무엇입니까? 어떻게 해결하나요?

답변1

많은 테스트 끝에 뭔가를 찾은 것 같습니다.

rctest일부 데이터가 프린터로 전송되고 해당 데이터가 유효한 프린터 명령이기 때문에 프린터가 작동합니다 .

따라서 프린터를 완벽하게 제어하려면 프린터 제조업체로부터 프린터 SDK를 찾아야 합니다.

지금까지 프린터에서 응답할 수 있는 두 개의 데이터 프레임을 찾았습니다. 프린터의 SDK에 대해 문의하고 싶습니다.

답변2

보내는 줄에 줄 끝 \n문자가 포함되어 있지 않습니다(또는 \r\n프린터 구성에 따라 포함되지 않을 수도 있음).

대부분의 프로그레시브 프린터는 인쇄하기 전에 전체 라인이 수신될 때까지 기다린 다음 라인을 한 번에 인쇄하여 기계적 오류의 영향을 최소화합니다.

레이저 프린터는 일반적으로 전체 페이지를 한 번에 인쇄하므로 페이지를 완전히 채울 만큼 충분한 텍스트 줄이 확보되거나 폼 피드 문자가 나올 때까지 인쇄가 시작되지 않습니다 \f.

관련 정보