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;、、、、は密なループで127バイトを送信しているように見え、count = 1プリンタは機能します。delay = 0data_size=127rctest

しかし、rfcomm_client.cそれは役に立たない。

問題は何ですか?どうやって解決しますか?

答え1

多くのテストの最後に何かを見つけたようです。

rctest一部のデータがプリンタに送信され、そのデータが有効なプリンタコマンドであるため、プリンタは機能します。

したがって、プリンタを完全に制御するには、プリンタの製造元からプリンタSDKを見つける必要があります。

これまで、プリンタが応答できる2つのデータフレームを見つけました。プリンタのSDKについてお問い合わせしたいと思います。

答え2

送信行に行末\n文字が含まれていません(または\r\nプリンター構成によっては含まれない場合があります)。

ほとんどのプログレッシブプリンタは、印刷前にライン全体が受信されるのを待ってから、ラインを一度に印刷して機械的エラーの影響を最小限に抑えます。

レーザープリンタは通常、ページ全体を一度に印刷するため、ページを完全に埋めるのに十分なテキスト行が得られるか、フォームフィード文字が表示されるまで印刷は開始されません\f

関連情報