void ConfigureUnsol::ConfigureRequest(APDU& arAPDU) { arAPDU.Set(mIsEnable ? FC_ENABLE_UNSOLICITED : FC_DISABLE_UNSOLICITED); if(mClassMask & PC_CLASS_1) arAPDU.DoPlaceholderWrite(Group60Var2::Inst()); if(mClassMask & PC_CLASS_2) arAPDU.DoPlaceholderWrite(Group60Var3::Inst()); if(mClassMask & PC_CLASS_3) arAPDU.DoPlaceholderWrite(Group60Var4::Inst()); }
OneByteFrame::OneByteFrame(const APDU& apdu) { m_frame_len = 1; m_frame_mem = new UCHAR[1]; if ( apdu.IsAck() ) { m_frame_mem[0] = 0xCC; m_type = ACK_FRAME; } else if ( apdu.IsNack() ) { m_frame_mem[0] = 0x0C; m_type = NACK_FRAME; } else if ( apdu.IsBusy() ) { m_frame_mem[0] = 0xC0; m_type = BUSY_FRAME; } else if ( apdu.IsNackbusy() ) { m_frame_mem[0] = 0x00; m_type = NACKBUSY_FRAME; } else { // ... abort(); } }
void Master::OnFinalResponse(const APDU& arAPDU) { this->UpdateState(MS_COMMS_UP); mLastIIN = arAPDU.GetIIN(); this->ProcessIIN(arAPDU.GetIIN()); mpState->OnFinalResponse(this, arAPDU); }
void ClearRestartIIN::ConfigureRequest(APDU& arAPDU) { arAPDU.Set(FC_WRITE); Group80Var1* pObj = Group80Var1::Inst(); // Internal indications object ObjectWriteIterator i = arAPDU.WriteContiguous(pObj, 7, 7); // index 7 == device restart pObj->Write(*i, 7, 7, false); }
Array < eibaddr_t > Layer7_Broadcast::A_IndividualAddress_Read (unsigned timeout) { Array < eibaddr_t > addrs; A_IndividualAddress_Read_PDU r; APDU *a; l4->Send (r.ToPacket ()); pth_event_t t = pth_event (PTH_EVENT_RTIME, pth_time (timeout, 0)); while (pth_event_status (t) != PTH_STATUS_OCCURRED) { BroadcastComm *c = l4->Get (t); if (c) { a = APDU::fromPacket (c->data); if (a->isResponse (&r)) { addrs.resize (addrs () + 1); addrs[addrs () - 1] = c->src; } delete a; delete c; } } pth_event_free (t, PTH_FREE_THIS); return addrs; }
void AppLayerTest::SendUp(FunctionCodes aCode, bool aFIR, bool aFIN, bool aCON, bool aUNS, int aSEQ) { APDU f; f.SetFunction(aCode); f.SetControl(aFIR, aFIN, aCON, aUNS, aSEQ); lower.SendUp(f.GetBuffer(), f.Size()); }
int Frame::Response(Frame*& resp)const // 旧代码.以后要废弃!!!! { int retcode = 0; APDU *apdu = NULL, *apdu2 = NULL; std::vector<APDU*> apdus; apdu = APDU::BuildAPDUFromFrame(*this); if ( NULL == apdu ) { retcode = -11; goto _out; } retcode = apdu->Response(apdu2, apdus); if ( 0 != retcode || NULL == apdu2 ) { retcode = -12; goto _out; } resp = Frame::BuildFrameFromAPDU(*apdu2); _out: delete apdu2; delete apdu; for ( int i = 0; i < apdus.size(); i++ ) { delete apdus[i]; } return retcode; }
void MockAppLayer::SendUnsolicited(APDU& arAPDU) { LOG_BLOCK(LEV_COMM, "=> " << toHex(arAPDU.GetBuffer(), arAPDU.Size(), true)); LOG_BLOCK(LEV_INTERPRET, "=> " << arAPDU.ToString()); mFragments.push_back(arAPDU); this->DoSendUnsol(); }
APDU * Layer7_Individual::Request_Response (APDU * r) { APDU *a; CArray *c; l4->Send (r->ToPacket ()); pth_event_t t = pth_event (PTH_EVENT_RTIME, pth_time (6, 100)); while (pth_event_status (t) != PTH_STATUS_OCCURRED) { c = l4->Get (t); if (c) { if (c->len () == 0) { delete c; pth_event_free (t, PTH_FREE_THIS); return 0; } a = APDU::fromPacket (*c, this->t); delete c; if (a->isResponse (r)) { pth_event_free (t, PTH_FREE_THIS); return a; } delete a; pth_event_free (t, PTH_FREE_THIS); return 0; } } pth_event_free (t, PTH_FREE_THIS); return 0; }
void Slave::SendUnsolicited(APDU& arAPDU) { mRspIIN.BitwiseOR(mIIN); arAPDU.SetIIN(mRspIIN); mpAppLayer->SendUnsolicited(arAPDU); mUnsolExpectCON = (arAPDU.GetControl()).CON; }
void AS_Base::SwitchOnFunction(AsyncSlave* c, AS_Base* apNext, const APDU& arRequest, SequenceInfo aSeqInfo) { switch(arRequest.GetFunction()) { case(FC_READ): { ChangeState(c, apNext); c->mRspContext.Reset(); IINField iin = c->mRspContext.Configure(arRequest); c->mRspContext.LoadResponse(c->mResponse); c->Send(c->mResponse, iin); break; } case(FC_WRITE): ChangeState(c, apNext); c->HandleWrite(arRequest); c->ConfigureAndSendSimpleResponse(); break; case(FC_SELECT): ChangeState(c, apNext); c->HandleSelect(arRequest, aSeqInfo); c->Send(c->mResponse); break; case(FC_OPERATE): ChangeState(c, apNext); c->HandleOperate(arRequest, aSeqInfo); c->Send(c->mResponse); break; case(FC_DIRECT_OPERATE): ChangeState(c, apNext); c->HandleDirectOperate(arRequest, aSeqInfo); c->Send(c->mResponse); break; case(FC_DIRECT_OPERATE_NO_ACK): c->HandleDirectOperate(arRequest, aSeqInfo); break; case(FC_ENABLE_UNSOLICITED): ChangeState(c, apNext); c->HandleEnableUnsolicited(arRequest, true); c->Send(c->mResponse); break; case(FC_DISABLE_UNSOLICITED): ChangeState(c, apNext); c->HandleEnableUnsolicited(arRequest, false); c->Send(c->mResponse); break; case(FC_DELAY_MEASURE): ChangeState(c, apNext); c->ConfigureDelayMeasurement(arRequest); c->Send(c->mResponse); break; default: { std::ostringstream oss; oss << "Function not supported: " << arRequest.GetFunction(); throw NotSupportedException(LOCATION, oss.str(), SERR_FUNC_NOT_SUPPORTED); } } }
void VtoTransmitTask::ConfigureRequest(APDU& arAPDU) { /* * Masters never request confirmed data. The response from the * slave is all that's required for reliable delivery. */ arAPDU.Set(mUseNonStandardCode ? FC_PROPRIETARY_VTO_TRANSFER : FC_WRITE); const size_t MAX_VTO_EVENTS = 7; /* Get all of the data objects in the buffer. */ size_t numObjects = this->mBuffer.Select(PC_ALL_EVENTS, MAX_VTO_EVENTS); LOG_BLOCK(LEV_INTERPRET, "VtoTransmitTask Sending: " << numObjects << " of " << this->mBuffer.Size()); /* If there are no objects to write, skip the remainder. */ if (numObjects == 0) { return; } /* * Loop through the selected data and add corresponding objects to * the arAPDU instance. */ VtoDataEventIter vto = this->mBuffer.Begin(); for (size_t i = 0; i < numObjects; ++i) { /* Insert a new object into the APDU message. */ IndexedWriteIterator itr = arAPDU.WriteIndexed( Group112Var0::Inst(), vto->mValue.GetSize(), vto->mIndex ); /* * Check to see if the APDU fragment has enough room for the * data segment. If the fragment is full, return out of this * function and let the fragment send. */ if (itr.IsEnd()) { return; } /* Set the object index */ itr.SetIndex(vto->mIndex); /* Write the data to the APDU message */ Group112Var0::Inst()->Write( *itr, vto->mValue.GetSize(), vto->mValue.mpData ); /* Mark the data segment as being written */ vto->mWritten = true; /* Move to the next data segment in the buffer */ ++vto; } }
APDU MockAppLayer::Read() { if(mFragments.size() == 0) throw InvalidStateException(LOCATION, "no more fragments"); APDU frag = mFragments.front(); frag.Interpret(); mFragments.pop_front(); return frag; }
void AppLayer::SendResponse(APDU& arAPDU) { this->Validate(arAPDU.GetControl(), false, false, true, false); if(arAPDU.GetFunction() != FC_RESPONSE) throw ArgumentException(LOCATION, "Non-response function code"); mSolicited.Send(arAPDU, this->GetRetries(FC_RESPONSE)); }
void AppLayer::SendUnsolicited(APDU& arAPDU) { this->Validate(arAPDU.GetControl(), false, true, true, true); if(arAPDU.GetFunction() != FC_UNSOLICITED_RESPONSE ) throw ArgumentException(LOCATION, "Non-unsolicited function code"); mUnsolicited.Send(arAPDU, this->GetRetries(FC_UNSOLICITED_RESPONSE)); }
void AppLayer::SendRequest(APDU& arAPDU) { this->Validate(arAPDU.GetControl(), true, true, false, false); if(!IsRequest(arAPDU.GetFunction())) throw ArgumentException(LOCATION, "Non-request function code"); mSolicited.Send(arAPDU, this->GetRetries(arAPDU.GetFunction())); }
void ACS_Idle::Send(AppLayerChannel* c, APDU& arAPDU, size_t aNumRetry) { AppControlField acf = arAPDU.GetControl(); FunctionCodes func = arAPDU.GetFunction(); acf.SEQ = (acf.FIR && func == FC_RESPONSE) ? c->Sequence() : c->IncrSequence(); arAPDU.SetControl(acf); c->ChangeState(NextState(c, arAPDU.GetFunction(), acf.CON)); c->SetRetry(aNumRetry); c->QueueSend(arAPDU); }
int main() { SCard card; try { card.setContext(SCARD_SCOPE_SYSTEM); card.connect(); cout << card.getReader() << endl; char input[256]; for (;;) { cout << "apdu> "; cin.getline(input, sizeof(input)); String in(input); in = in.trim().toLower(); if (in == "quit") { cout << "Bye" << endl; break; } APDU cmd(in,APDU::Separator::SPACE); APDU resp; try { card.transmit(cmd,resp); cout << resp.toString() << endl; } catch (SCardException& e) { cerr << e.what() << endl; } } } catch (SCardException& e) { cerr << e.what() << endl; } return 0; }
void TimeSync::ConfigureRequest(APDU& arAPDU) { if(mDelay < 0) { arAPDU.Set(FC_DELAY_MEASURE); mStart = mpTimeSrc->GetUTC(); } else { arAPDU.Set(FC_WRITE); ObjectWriteIterator owi = arAPDU.WriteContiguous(Group50Var1::Inst(), 0, 0, QC_1B_CNT); Group50Var1::Inst()->mTime.Set(*owi, mpTimeSrc->GetTimeStampUTC() + mDelay); } }
void ClassPoll::ConfigureRequest(APDU& arAPDU) { if (mClassMask == PC_INVALID) { throw InvalidStateException(LOCATION, "Class mask has not been set"); } arAPDU.Set(FC_READ); if (mClassMask & PC_CLASS_0) arAPDU.DoPlaceholderWrite(Group60Var1::Inst()); if (mClassMask & PC_CLASS_1) arAPDU.DoPlaceholderWrite(Group60Var2::Inst()); if (mClassMask & PC_CLASS_2) arAPDU.DoPlaceholderWrite(Group60Var3::Inst()); if (mClassMask & PC_CLASS_3) arAPDU.DoPlaceholderWrite(Group60Var4::Inst()); }
// Response的新版本. int Frame::Response(std::vector<Frame*>& resps)const { int retcode = 0; APDU *apdu = NULL, *apdu2 = NULL; std::vector<APDU*> apdus; Frame* frame = NULL; resps.clear(); apdu = APDU::BuildAPDUFromFrame(*this); if ( NULL == apdu ) { retcode = -11; goto _out; } retcode = apdu->Response(apdu2, apdus); if ( 0 != retcode && NULL == apdu2 && apdus.empty() ) { retcode = -12; goto _out; } if ( NULL != apdu2 ) { frame = Frame::BuildFrameFromAPDU(*apdu2); if ( NULL != frame ) { resps.push_back(frame); } } for ( int i = 0; i < apdus.size(); i++ ) { frame = Frame::BuildFrameFromAPDU(*apdus[i]); if ( NULL != frame ) { resps.push_back(frame); } } _out: delete apdu2; delete apdu; for ( int i = 0; i < apdus.size(); i++ ) { delete apdus[i]; } return retcode; }
APDUType Frame::GetAPDUType() { APDU* apdu = APDU::BuildAPDUFromFrame(*this); if ( NULL != apdu ) { APDUType apdu_type = apdu->GetAPDUType(); delete apdu; return apdu_type; } else { return AT_UNAVAILABLE; } }
void ResponseLoaderTestObject::Load(const std::string& arAPDU) { fdo.Clear(); HexSequence hs(arAPDU); APDU f; f.Write(hs, hs.Size()); f.Interpret(); ResponseLoader rl(mpLogger, &fdo); for(HeaderReadIterator hdr = f.BeginRead(); !hdr.IsEnd(); ++hdr) { rl.Process(hdr); } }
void ACS_Base::ProcessResponse(AppLayerChannel* c, APDU& arAPDU, bool aExpectFIR) { AppControlField acf = arAPDU.GetControl(); if(acf.SEQ == c->Sequence()) { if(acf.FIR == aExpectFIR) { c->CancelTimer(); if(acf.FIN) { c->ChangeState(ACS_Idle::Inst()); c->DoFinalResponse(arAPDU); } else { c->IncrSequence(); c->ChangeState(ACS_WaitForFinalResponse::Inst()); c->StartTimer(); c->DoPartialResponse(arAPDU); } } else { ERROR_LOGGER_BLOCK(c->GetLogger(), LEV_WARNING, "Unexpected fir bit " << acf.FIR, ALERR_BAD_FIR_FIN); } } else { ERROR_LOGGER_BLOCK(c->GetLogger(), LEV_WARNING, "Bad sequence number " << acf.SEQ, ALERR_BAD_SEQUENCE); } }
void Slave::Send(APDU& arAPDU, const IINField& arIIN) { mRspIIN.BitwiseOR(mIIN); mRspIIN.BitwiseOR(arIIN); arAPDU.SetIIN(mRspIIN); mpAppLayer->SendResponse(arAPDU); }
void Slave::HandleEnableUnsolicited(const APDU& arRequest, bool aIsEnable) { mResponse.Set(FC_RESPONSE); if (mConfig.mDisableUnsol) { mRspIIN.SetFuncNotSupported(true); } else { if (aIsEnable) { this->mDeferredUnsol = true; } for (HeaderReadIterator hdr = arRequest.BeginRead(); !hdr.IsEnd(); ++hdr) { switch (MACRO_DNP_RADIX(hdr->GetGroup(), hdr->GetVariation())) { case (MACRO_DNP_RADIX(60, 2)): mConfig.mUnsolMask.class1 = aIsEnable; break; case (MACRO_DNP_RADIX(60, 3)): mConfig.mUnsolMask.class2 = aIsEnable; break; case (MACRO_DNP_RADIX(60, 4)): mConfig.mUnsolMask.class3 = aIsEnable; break; default: mRspIIN.SetFuncNotSupported(true); LOG_BLOCK(LEV_WARNING, "Cannot enable/disable unsol for " << hdr->GetBaseObject()->Name()); break; } } } }
void DataPoll::ReadData(const APDU& f) { ResponseLoader loader(mpLogger, mpObs, mpVtoReader); HeaderReadIterator hdr = f.BeginRead(); for ( ; !hdr.IsEnd(); ++hdr) { loader.Process(hdr); } }
TaskResult SimpleRspBase::_OnFinalResponse(const APDU& arAPDU) { if(arAPDU.BeginRead().Count() > 0) { LOG_BLOCK(LEV_WARNING, "Unexpected object headers in response: " << this->Name()); } return TR_SUCCESS; }
void AS_Base::SwitchOnFunction(Slave* c, AS_Base* apNext, const APDU& arRequest, SequenceInfo aSeqInfo) { switch (arRequest.GetFunction()) { case (FC_READ): { ChangeState(c, apNext); c->mRspContext.Reset(); IINField iin = c->mRspContext.Configure(arRequest); c->mRspContext.LoadResponse(c->mResponse); c->Send(c->mResponse, iin); break; } case (FC_WRITE): ChangeState(c, apNext); if(aSeqInfo != SI_PREV) c->HandleWrite(arRequest); c->ConfigureAndSendSimpleResponse(); break; case (FC_PROPRIETARY_VTO_TRANSFER): ChangeState(c, apNext); if(aSeqInfo != SI_PREV) c->HandleVtoTransfer(arRequest); c->ConfigureAndSendSimpleResponse(); break; case (FC_SELECT): ChangeState(c, apNext); c->HandleSelect(arRequest, aSeqInfo); c->Send(c->mResponse); break; case (FC_OPERATE): ChangeState(c, apNext); c->HandleOperate(arRequest, aSeqInfo); c->Send(c->mResponse); break; case (FC_DIRECT_OPERATE): ChangeState(c, apNext); c->HandleDirectOperate(arRequest, aSeqInfo); c->Send(c->mResponse); break; case (FC_DIRECT_OPERATE_NO_ACK): c->HandleDirectOperate(arRequest, aSeqInfo); break; case (FC_ENABLE_UNSOLICITED): ChangeState(c, apNext); c->HandleEnableUnsolicited(arRequest, true); c->Send(c->mResponse); break; case (FC_DISABLE_UNSOLICITED): ChangeState(c, apNext); c->HandleEnableUnsolicited(arRequest, false); c->Send(c->mResponse); break; case (FC_DELAY_MEASURE): ChangeState(c, apNext); c->ConfigureDelayMeasurement(arRequest); c->Send(c->mResponse); break; default: MACRO_THROW_EXCEPTION_COMPLEX_WITH_CODE(NotSupportedException, "Function not supported: " << arRequest.GetFunction() , SERR_FUNC_NOT_SUPPORTED); } }
void GetBalance(Smartcard& pSmartcard) { pSmartcard.Connect(10000); BYTE aid[] = {(BYTE)0xA0,(BYTE)0x00,(BYTE)0x00,(BYTE)0x00,(BYTE)0x99,(BYTE)0x01}; APDU selectAID = APDU(0x00,0xA4,0x04,0x00); selectAID.AddData( ByteBuffer(aid,sizeof(aid)) ); pSmartcard.Transmit(selectAID); LOGGER_INFO<<_T("GetBalance select AID")<<endl<<selectAID; APDU send = APDU(0xB0,0x50,0x00,0x00); send.SetLe(2); pSmartcard.Transmit(send); LOGGER_INFO<<_T("GetBalance")<<endl<<send; }