Files
ptouch_label/src/lib/libptouch_status.c
2026-04-13 11:39:31 +09:00

439 lines
9.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* libptouch — printer status (ESC i S) and human-readable dump
*
* Author: knb
* Email: knb@artif.org
*/
#include "libptouch_internal.h"
#include <stdio.h>
#include <string.h>
libptouch_err_t libptouch_get_status(libptouch_ctx *ctx, uint8_t *status)
{
if (!ctx || !status) {
if (ctx)
ptouch_set_error(ctx, LIBPTOUCH_ERR_ARG, "null argument");
return LIBPTOUCH_ERR_ARG;
}
if (!ctx->usb_handle || !ctx->bulk_out_ep || !ctx->bulk_in_ep) {
ptouch_set_error(ctx, LIBPTOUCH_ERR_IO,
"USB not open or bulk endpoints missing");
return LIBPTOUCH_ERR_IO;
}
libusb_device_handle *h = ctx->usb_handle;
static const uint8_t init[] = { 0x1B, 0x40 };
static const uint8_t req[] = { 0x1B, 0x69, 0x53 };
int r = LIBUSB_ERROR_OTHER;
for (int attempt = 0; attempt < 2; attempt++) {
if (attempt > 0) {
(void)libusb_clear_halt(h, ctx->bulk_in_ep);
(void)libusb_clear_halt(h, ctx->bulk_out_ep);
}
r = ptouch_bulk_out(h, ctx->bulk_out_ep, init, 2, 5000u);
if (r != 0) {
ptouch_set_error_usb(ctx, r, "bulk OUT ESC @");
return LIBPTOUCH_ERR_USB;
}
r = ptouch_bulk_out(h, ctx->bulk_out_ep, req, 3, 5000u);
if (r != 0) {
ptouch_set_error_usb(ctx, r, "bulk OUT ESC i S");
return LIBPTOUCH_ERR_USB;
}
r = ptouch_bulk_in_exact(h, ctx->bulk_in_ep, status,
(int)LIBPTOUCH_STATUS_LENGTH, 5000u);
if (r == 0)
break;
if (r != LIBUSB_ERROR_IO && r != LIBUSB_ERROR_PIPE)
break;
}
if (r != 0) {
ptouch_set_error_usb(ctx, r, "bulk IN status");
return LIBPTOUCH_ERR_USB;
}
ptouch_set_error(ctx, LIBPTOUCH_OK, "");
return LIBPTOUCH_OK;
}
static void fprint_model(FILE *fp, uint8_t code)
{
const char *name = "unknown";
switch (code) {
case 0x6F:
name = "PT-P900W";
break;
case 0x70:
name = "PT-P950NW";
break;
case 0x71:
name = "PT-P900";
break;
case 0x78:
name = "PT-P910BT";
break;
case 0x68:
name = "PT-P750W";
break;
case 0x76:
name = "PT-P710BT";
break;
default:
break;
}
fprintf(fp, "機種コード: 0x%02X ('%c') — %s\n", (unsigned)code,
(code >= 32 && code < 127) ? (char)code : '?', name);
}
static void fprint_media_width(FILE *fp, uint8_t w, uint8_t len_byte)
{
const char *desc = NULL;
switch (w) {
case 0x00:
desc = "テープなし / 未装着";
break;
case 0x04:
desc = "3.5 mm";
break;
case 0x06:
desc = "6 mm";
break;
case 0x09:
desc = "9 mm";
break;
case 0x0C:
desc = "12 mm";
break;
case 0x12:
desc = "18 mm";
break;
case 0x18:
desc = "24 mm";
break;
case 0x24:
desc = "36 mm";
break;
case 0x15:
desc = "FLe 21 mm 幅(長さはメディア長バイト参照)";
break;
default:
break;
}
if (desc)
fprintf(fp, "メディア幅: 0x%02X — %s\n", (unsigned)w, desc);
else
fprintf(fp, "メディア幅: 0x%02X\n", (unsigned)w);
if (w == 0x15 && len_byte != 0)
fprintf(fp, "メディア長: 0x%02X (%u mm 相当の表記参照)\n",
(unsigned)len_byte, (unsigned)len_byte);
}
static void fprint_media_kind(FILE *fp, uint8_t k)
{
const char *desc = NULL;
switch (k) {
case 0x00:
desc = "テープなし";
break;
case 0x01:
desc = "ラミネートテープ";
break;
case 0x03:
desc = "ノンラミネートテープ";
break;
case 0x04:
desc = "ファブリックテープ";
break;
case 0x11:
desc = "ヒートシュリンクチューブ (HS 2:1)";
break;
case 0x13:
desc = "FLe テープ";
break;
case 0x14:
desc = "フレキシブルIDテープ";
break;
case 0x15:
desc = "サテンテープ";
break;
case 0x17:
desc = "ヒートシュリンクチューブ (HS 3:1)";
break;
case 0xFF:
desc = "非対応テープ";
break;
default:
break;
}
if (desc)
fprintf(fp, "テープ種類: 0x%02X — %s\n", (unsigned)k, desc);
else
fprintf(fp, "テープ種類: 0x%02X\n", (unsigned)k);
}
static void fprint_battery(FILE *fp, uint8_t b)
{
const char *desc = NULL;
switch (b) {
case 0x00:
desc = "フル";
break;
case 0x01:
desc = "ハーフ";
break;
case 0x02:
desc = "ロー";
break;
case 0x03:
desc = "要充電";
break;
case 0x04:
desc = "AC アダプター使用中";
break;
case 0xFF:
desc = "不明";
break;
default:
break;
}
if (desc)
fprintf(fp, "電池残量: 0x%02X — %s\n", (unsigned)b, desc);
else
fprintf(fp, "電池残量: 0x%02X (PT-P910BT 等は別表参照)\n",
(unsigned)b);
}
static void fprint_tape_color(FILE *fp, uint8_t c)
{
const char *desc = NULL;
switch (c) {
case 0x01:
desc = "白 (White)";
break;
case 0x02:
desc = "その他 (Other)";
break;
case 0x03:
desc = "透明 (Clear)";
break;
case 0x04:
desc = "赤 (Red)";
break;
case 0x05:
desc = "青 (Blue)";
break;
case 0x06:
desc = "黄 (Yellow)";
break;
case 0x07:
desc = "緑 (Green)";
break;
case 0x08:
desc = "黒 (Black)";
break;
case 0x09:
desc = "透明(文字白)";
break;
case 0x20:
desc = "白(マット) (Matte White)";
break;
case 0x21:
desc = "透明(マット) (Matte Clear)";
break;
case 0x22:
desc = "銀(マット) (Matte Silver)";
break;
case 0x23:
desc = "金(サテン) (Satin Gold)";
break;
case 0x24:
desc = "銀(サテン) (Satin Silver)";
break;
case 0x30:
desc = "D";
break;
case 0x31:
desc = "D";
break;
case 0x40:
desc = "オレンジ(蛍光)";
break;
case 0x41:
desc = "黄(蛍光)";
break;
case 0x50:
desc = "ピンクS";
break;
case 0x51:
desc = "グレーS";
break;
case 0x52:
desc = "グリーンS";
break;
case 0x60:
desc = "イエローF";
break;
case 0x61:
desc = "ピンクF";
break;
case 0x62:
desc = "ブルーF";
break;
case 0x70:
desc = "白(チューブ)";
break;
case 0x90:
desc = "白(フレキ)";
break;
case 0x91:
desc = "黄(フレキ)";
break;
case 0xF0:
desc = "クリーニング";
break;
case 0xF1:
desc = "ステンシル";
break;
case 0xFF:
desc = "非対応";
break;
default:
break;
}
if (desc)
fprintf(fp, "テープ色: 0x%02X — %s\n", (unsigned)c, desc);
else
fprintf(fp, "テープ色: 0x%02X\n", (unsigned)c);
}
static void fprint_status_kind(FILE *fp, uint8_t s)
{
const char *desc = NULL;
switch (s) {
case 0x00:
desc = "印刷終了";
break;
case 0x01:
desc = "エラー発生";
break;
case 0x02:
desc = "IF モード終了";
break;
case 0x03:
desc = "パワーオフ(未使用扱い)";
break;
case 0x04:
desc = "通知";
break;
case 0x05:
desc = "フェーズ変更";
break;
default:
break;
}
if (desc)
fprintf(fp, "ステータス種類: 0x%02X — %s\n", (unsigned)s, desc);
else
fprintf(fp, "ステータス種類: 0x%02X\n", (unsigned)s);
}
void libptouch_status_fprint(FILE *fp, const uint8_t *status)
{
if (!fp || !status)
return;
fprintf(fp, "=== P-touch ステータス (32 バイト) ===\n");
if (status[0] != 0x80u || status[1] != 0x20u)
fprintf(fp,
"※ 先頭マーク異常: [0]=0x%02X [1]=0x%02X (通常 80 20)\n",
(unsigned)status[0], (unsigned)status[1]);
fprintf(fp, "ヘッダ: 0x%02X 0x%02X\n", (unsigned)status[0],
(unsigned)status[1]);
fprintf(fp, "Brother コード: %c (0x%02X)\n",
(status[2] >= 32 && status[2] < 127) ? (char)status[2] : '?',
(unsigned)status[2]);
fprint_model(fp, status[4]);
fprintf(fp, "国別コード: %c\n",
(status[5] >= 32 && status[5] < 127) ? (char)status[5] : '?');
fprint_battery(fp, status[6]);
if (status[7] != 0) {
fprintf(fp, "拡張エラー: 0x%02X", (unsigned)status[7]);
switch (status[7]) {
case 0x10:
fprintf(fp, " — FLE のテープエンド");
break;
case 0x1D:
fprintf(fp, " — 高解像度/ドラフト印刷エラー");
break;
case 0x1E:
fprintf(fp, " — アダプター抜き挿しエラー");
break;
case 0x21:
fprintf(fp, " — 非対応メディアエラー");
break;
default:
break;
}
fprintf(fp, "\n");
} else {
fprintf(fp, "拡張エラー: なし (0x00)\n");
}
fprintf(fp, "エラー情報1: 0x%02X\n", (unsigned)status[8]);
if (status[8] & 0x01)
fprintf(fp, " - メディア無し\n");
if (status[8] & 0x02)
fprintf(fp, " - メディア終了\n");
if (status[8] & 0x04)
fprintf(fp, " - カッタージャム\n");
if (status[8] & 0x08)
fprintf(fp, " - バッテリー弱\n");
if (status[8] & 0x40)
fprintf(fp, " - 高圧アダプター\n");
fprintf(fp, "エラー情報2: 0x%02X\n", (unsigned)status[9]);
if (status[9] & 0x01)
fprintf(fp, " - メディア交換(メディア違い)\n");
if (status[9] & 0x04)
fprintf(fp, " - 通信エラー\n");
if (status[9] & 0x08)
fprintf(fp, " - 通信バッファーフル\n");
if (status[9] & 0x10)
fprintf(fp, " - カバーオープン\n");
if (status[9] & 0x20)
fprintf(fp, " - 高温エラー\n");
if (status[9] & 0x40)
fprintf(fp, " - 先端検出エラー\n");
if (status[9] & 0x80)
fprintf(fp, " - システムエラー\n");
fprint_media_width(fp, status[10], status[17]);
fprint_media_kind(fp, status[11]);
fprintf(fp, "色数: 0x%02X フォント/日本語フォント: 0x%02X / 0x%02X\n",
(unsigned)status[12], (unsigned)status[13],
(unsigned)status[14]);
fprintf(fp, "モード: 0x%02X 濃度: 0x%02X\n", (unsigned)status[15],
(unsigned)status[16]);
fprint_status_kind(fp, status[18]);
fprintf(fp, "フェーズ種類: 0x%02X フェーズ番号: %02X %02X\n",
(unsigned)status[19], (unsigned)status[20],
(unsigned)status[21]);
fprintf(fp, "通知番号: 0x%02X\n", (unsigned)status[22]);
fprintf(fp, "拡張部バイト数: 0x%02X\n", (unsigned)status[23]);
fprint_tape_color(fp, status[24]);
fprintf(fp, "文字色: 0x%02X\n", (unsigned)status[25]);
fprintf(fp, "生データ: ");
for (unsigned i = 0; i < LIBPTOUCH_STATUS_LENGTH; i++)
fprintf(fp, "%02X%s", (unsigned)status[i],
i + 1 == LIBPTOUCH_STATUS_LENGTH ? "\n" : " ");
}