# Card service APIs to transmit APDU This sample application demonstrates how to use card service APIs to transmit APDU. 1. Implement ResponseCallback interface to receive subsystem initialization status std::promise cbProm = std::promise(); void initResponseCb(telux::common::ServiceStatus status) { if (subSystemsStatus == SERVICE_AVAILABLE) { std::cout << Card Manager subsystem is ready << std::endl; } else if(subSystemsStatus == SERVICE_FAILED) { std::cout << Card Manager subsystem initialization failed << std::endl; } cbProm.set_value(status); } Copy to clipboard 2. Get the PhoneFactory and CardManager instances auto &phoneFactory = PhoneFactory::getInstance(); auto cardManager = phoneFactory.getCardManager(initResponseCb); if (cardManager == NULL) { std::cout << " Failed to get Card Manager instance" << std::endl; return -1; } Copy to clipboard 3.Check if CardManager subsystem is ready telux::common::ServiceStatus status = cardManager.getServiceStatus(); Copy to clipboard 3.1 Wait for the CardManager subsystem initialization telux::common::ServiceStatus status = cbProm.get_future().get(); if (status != SERVICE_AVAILABLE) { std::cout << Unable to initialize Card Manager subsystem << std::endl; return -1; } Copy to clipboard 4. Get number of slots, their IDs and card instance int slotCount; cardManager->getSlotCount(slotCount); std::cout << "Slots Count is :" << slotCount << std::endl; std::vector slotIds; cardManager->getSlotIds(slotIds); std::cout << "Slot Ids are : { "; for(auto id : slotIds) { std::cout << id << " "; } std::cout << "}" << std::endl; std::shared_ptr cardImpl = cardManager->getCard(slotIds.front()); Copy to clipboard 5. Get supported applications from the card std::vector> applications; if(cardImpl) { std::cout << "\nApplications available are : " << std::endl; applications = cardImpl->getApplications(); for(auto cardApp : applications) { std::cout << "AppId : " << cardApp->getAppId() << std::endl; } } Copy to clipboard 6. Instantiate optional IOpenLogicalChannelCallback, ICommandResponseCallback and ITransmitApduResponseCallback auto myOpenLogicalCb = std::make_shared(); auto myCloseLogicalCb = std::make_shared(); auto myTransmitApduResponseCb = std::make_shared(); Copy to clipboard 6.1 Implementation of ICardChannelCallback interface for receiving notifications on card event like open logical channel class MyOpenLogicalChannelCallback : public ICardChannelCallback { public: void onChannelResponse(int channel, IccResult result, ErrorCode error) override; }; void MyOpenLogicalChannelCallback::onChannelResponse(int channel, IccResult result, ErrorCode error) { std::cout << "onChannelResponse, error: " << (int)error << std::endl; std::unique_lock lock(eventMutex); errorCode = error; openChannel = channel; std::cout << "onChannelResponse: " << result.toString() << std::endl; if(cardEventExpected == CardEvent::OPEN_LOGICAL_CHANNEL) { std::cout << "Card Event OPEN_LOGICAL_CHANNEL found with code :" << int(error) << std::endl; eventCV.notify_one(); } } Copy to clipboard 6.2. Implementation of ICommandResponseCallback interface for receiving notifications on card event like close logical channel class MyCloseLogicalChannelCallback : public ICommandResponseCallback { public: void commandResponse(ErrorCode error) override; }; void MyCloseLogicalChannelCallback::commandResponse(ErrorCode error) { std::cout << "commandResponse, error: " << (int)error << std::endl; std::unique_lock lock(eventMutex); errorCode = error; if(cardEventExpected == CardEvent::CLOSE_LOGICAL_CHANNEL) { std::cout << "Card Event CLOSE_LOGICAL_CHANNEL found with code :" << int(error) << std::endl; eventCV.notify_one(); } } Copy to clipboard 6.3. Implementation of ICardCommandCallback interface for receiving notifications on card event like transmit APDU logical channel and transmit APDU basic channel class MyTransmitApduResponseCallback : public ICardCommandCallback { public: void onResponse(IccResult result, ErrorCode error) override; }; void MyTransmitApduResponseCallback::onResponse(IccResult result, ErrorCode error) { std::cout << "onResponse, error: " << (int)error << std::endl; std::unique_lock lock(eventMutex); errorCode = error; std::cout << "onResponse: " << result.toString() << std::endl; if(cardEventExpected == CardEvent::TRANSMIT_APDU_CHANNEL) { std::cout << "Card Event TRANSMIT_APDU_CHANNEL found with code :" << int(error) << std::endl; eventCV.notify_one(); } } Copy to clipboard 7. Open logical channel and wait for request to complete std::string aid; for(auto app : applications) { if(app->getAppType() == APPTYPE_USIM) { aid = app->getAppId(); break; } } cardImpl->openLogicalChannel(aid, myOpenLogicalCb); std::cout << "Opening Logical Channel to Transmit the APDU..." << std::endl; Copy to clipboard 8. Transmit APDU on logical channel, wait for request to complete cardImpl->transmitApduLogicalChannel(openChannel, CLA, INSTRUCTION, P1, P2, P3, DATA, myTransmitApduResponseCb); std::cout << "Transmit APDU request made..." << std::endl; Copy to clipboard 9. Close the opened logical channel and wait for the completion cardImpl->closeLogicalChannel(openChannel, myCloseLogicalCb); std::cout << "Close the Logical Channel..." << std::endl; Copy to clipboard 10. Transmit APDU on basic channel and wait for completion cardImpl->transmitApduBasicChannel(CLA, INSTRUCTION, P1, P2, P3, DATA, myTransmitApduResponseCb); std::cout << "Transmit APDU request on Basic channel made..." << std::endl; Copy to clipboard Last Published: Aug 05, 2026 [Previous Topic Get network subscription information](https://docs.qualcomm.com/bundle/publicresource/80-PF458-9/topics/get_subscription.md) [Next Topic Using SAP APIs](https://docs.qualcomm.com/bundle/publicresource/80-PF458-9/topics/sap_api_and_listener.md)