516{
517
519
523 {
524 std::string reason = dataStr.empty() ? "PORT_INIT_FAILED" : dataStr;
525 for (char &ch : reason)
526 {
527 if (ch == '\r' || ch == '\n' || ch == ';')
528 ch = ' ';
529 }
530
531 std::string code = "PORT_INIT_FAILED";
532 if (reason == "PORT_OPEN_FAILED")
533 code = "PORT_OPEN_FAILED";
534 else if (reason.rfind("DLL_LOAD_FAILED", 0) == 0)
535 code = "DLL_LOAD_FAILED";
536 else if (reason == "DUMMY_WINDOW_CREATE_FAILED")
537 code = "WINDOW_CREATE_FAILED";
538
539 const std::string detailPayload = "CODE=" + code + ";MESSAGE=" + reason;
540
542 {
545 }
546
548 if (wReason.empty())
549 wReason.assign(reason.begin(), reason.end());
550 Logger::error(L"ED785 초기화 실패 이벤트 수신: " + wReason);
551
552 std::vector<std::weak_ptr<TcpServer::Session>> targets;
553 {
557 {
559 cancelResp.
rcd = 0xFF;
560 cancelResp.data = "DEVICE_NOT_READY";
561 try
562 {
563 pending.second->promise.set_value(cancelResp);
564 }
565 catch (const std::exception &)
566 {
567 }
568 targets.emplace_back(pending.second->session);
569 }
571 }
572
573 for (auto &target : targets)
574 {
575 if (auto session = target.lock())
576 {
577 std::ostringstream os;
578 os << "EVENT=DEVICE_ERROR;" << detailPayload;
579 session->sendLine(os.str());
580 }
581 }
582
583 return;
584 }
585
586
587 {
588 std::wstringstream ss;
589 ss << L
"ED785 응답: cmd=0x" << std::hex << resp.
cmd
590 << L
" gcd=0x" << resp.
gcd
591 << L
" jcd=0x" << resp.
jcd
593 << L
" dataLen=" << std::dec << resp.
dataLen;
594 Logger::debug(ss.str());
595 }
596
597
598 if (resp.
gcd == 0x14 && resp.
jcd == 0x09)
599 {
600 std::string statusCode;
602 {
603 statusCode.assign(
reinterpret_cast<const char *
>(resp.
data.data()), 2);
604 }
605 else if (!dataStr.empty())
606 {
607 statusCode = dataStr.substr(0, 2);
608 }
609
610 std::wstring wStatus(statusCode.begin(), statusCode.end());
611 std::wstring desc = L"알수없음";
612 if (statusCode == "01")
613 desc = L"신용카드 투입";
614 else if (statusCode == "02")
615 desc = L"서버로 접속 시도";
616 else if (statusCode == "03")
617 desc = L"FALLBACK 상황 발생";
618 else if (statusCode == "04")
619 desc = L"승인 불가능한 카드 인입";
620
622 std::wstring wRc(rcA, rcA + strlen(rcA));
623
624 std::wstringstream ss;
625 ss << L"단말기 상태 이벤트 수신 (0x14/0x09) - RC=" << wRc
626 << L", STATUS=" << wStatus << L" (" << desc << L")";
627 Logger::info(ss.str());
628
629 std::vector<std::pair<uint64_t, std::weak_ptr<TcpServer::Session>>> targets;
630 {
634 {
635 targets.emplace_back(pending.first, pending.second->session);
636 }
637 }
638
639 std::string detail = "UNKNOWN";
640 if (statusCode == "01")
641 detail = "CARD_INSERTED";
642 else if (statusCode == "02")
643 detail = "SERVER_CONNECTING";
644 else if (statusCode == "03")
645 detail = "FALLBACK";
646 else if (statusCode == "04")
647 detail = "CARD_REJECTED";
648
649 for (auto &target : targets)
650 {
651 if (auto session = target.second.lock())
652 {
653 std::ostringstream os;
654 os << "EVENT=TERMINAL_STATUS;CODE=" << statusCode << ";DETAIL=" << detail << ";TXID=" << target.first;
655 session->sendLine(os.str());
656 }
657 }
658
659
660 return;
661 }
662
663
665
666 uint64_t matchedTx = 0;
668
670 {
672 if (resp.
cmd == 0xFB && resp.
gcd == pending->expectGcd && resp.
jcd == pending->expectJcd)
673 {
674 matchedTx = pair.first;
675 matchedPending = pending;
676 break;
677 }
678 }
679
680 if (matchedPending)
681 {
682
685
686 if (resp.
gcd == 0x01 && resp.
jcd == 0x06 && resp.
hexLen > 0)
688 else
689 txResp.data = dataStr;
690
691 {
692 std::wstringstream ss;
693 ss << L"응답 매칭 성공: TX#" << matchedTx
694 << L
" gcd=0x" << std::hex << resp.
gcd
695 << L
" jcd=0x" << resp.
jcd
697 Logger::info(ss.str());
698 }
699
700 matchedPending->promise.set_value(std::move(txResp));
701 }
702 else
703 {
704
705 std::wstringstream ss;
706 ss << L
"응답 매칭 실패: 대기 중인 트랜잭션 없음 (현재 " <<
m_pendingTxs.size() << L
"개 대기 중)"
707 << L
" gcd=0x" << std::hex << resp.
gcd
708 << L
" jcd=0x" << resp.
jcd;
709 Logger::warn(ss.str());
710 }
711}
static std::string BytesToHexUpper(const std::vector< byte > &buf, size_t len)
Definition ProtocolAdapter.cpp:86
static std::wstring Utf8ToWide(const std::string &text)
Definition ProtocolAdapter.cpp:101
static constexpr int ResponseJcdInitializationFailure
Definition ED785Worker.h:18
static constexpr int ResponseGcdInitializationFailure
Definition ED785Worker.h:17
static constexpr int ResponseCmdInternal
Definition ED785Worker.h:16
static const char * rcToText(int rcd)
Definition ProtocolAdapter.cpp:138
static std::string bytesToUtf8String(const std::vector< byte > &buf, size_t len)
Definition ProtocolAdapter.cpp:157
int gcd
Definition ED785Worker.h:33
size_t hexLen
Definition ED785Worker.h:39
int cmd
Definition ED785Worker.h:32
int rcd
Definition ED785Worker.h:35
int jcd
Definition ED785Worker.h:34
size_t dataLen
Definition ED785Worker.h:37
std::vector< byte > data
Definition ED785Worker.h:36
std::vector< byte > hex
Definition ED785Worker.h:38
Definition ProtocolAdapter.h:32