* ensure that CMD_ACK is used exclusively for the very last response of each PM3 operation. All Dbprintf() must be before.
* always switch off field before exiting
* append null packet for USB transfers % 64 bytes
* reformatting and whitespace fixes
//-----------------------------------------------------------------------------
// Perform the PACE protocol by replaying given APDUs
//-----------------------------------------------------------------------------
-void EPA_PACE_Replay(UsbCommand *c)
-{
+void EPA_PACE_Replay(UsbCommand *c) {
uint32_t timings[sizeof(apdu_lengths_replay) / sizeof(apdu_lengths_replay[0])] = {0};
- // if an APDU has been passed, save it
+ // if an APDU has been passed, just save it
if (c->arg[0] != 0) {
// make sure it's not too big
- if(c->arg[2] > apdus_replay[c->arg[0] - 1].len)
- {
+ if(c->arg[2] > apdus_replay[c->arg[0] - 1].len) {
cmd_send(CMD_ACK, 1, 0, 0, NULL, 0);
+ return;
}
- memcpy(apdus_replay[c->arg[0] - 1].data + c->arg[1],
- c->d.asBytes,
- c->arg[2]);
+ memcpy(apdus_replay[c->arg[0] - 1].data + c->arg[1], c->d.asBytes, c->arg[2]);
// save/update APDU length
if (c->arg[1] == 0) {
apdu_lengths_replay[c->arg[0] - 1] = c->arg[2];
// Send act_all
ReaderTransmitIClass(act_all, 1, &start_time);
// Card present?
- if (GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_ACTALL, eof_time) < 0) return false;//Fail
+ if (GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_ACTALL, eof_time) < 0) return false; //Fail
//Send Identify
start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
ReaderTransmitIClass(identify, 1, &start_time);
//We expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC
uint8_t len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time);
- if (len != 10) return false;//Fail
+ if (len != 10) return false; //Fail
//Copy the Anti-collision CSN to our select-packet
memcpy(&select[1], resp, 8);
ReaderTransmitIClass(select, sizeof(select), &start_time);
//We expect a 10-byte response here, 8 byte CSN and 2 byte CRC
len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time);
- if (len != 10) return false;//Fail
+ if (len != 10) return false; //Fail
//Success - we got CSN
//Save CSN in response data
if (selectIclassTag(resp, &eof_time)) {
result_status = FLAG_ICLASS_READER_CSN;
memcpy(card_data, resp, 8);
- }
- start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
+ start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
- //Read block 1, config
- if (flags & FLAG_ICLASS_READER_CONF) {
- if (sendCmdGetResponseWithRetries(readConf, sizeof(readConf), resp, sizeof(resp), 10, 10, start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time)) {
- result_status |= FLAG_ICLASS_READER_CONF;
- memcpy(card_data+8, resp, 8);
- } else {
- Dbprintf("Failed to read config block");
+ //Read block 1, config
+ if (flags & FLAG_ICLASS_READER_CONF) {
+ if (sendCmdGetResponseWithRetries(readConf, sizeof(readConf), resp, sizeof(resp), 10, 10, start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time)) {
+ result_status |= FLAG_ICLASS_READER_CONF;
+ memcpy(card_data+8, resp, 8);
+ } else {
+ Dbprintf("Failed to read config block");
+ }
+ start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
}
- start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
- }
- //Read block 2, e-purse
- if (flags & FLAG_ICLASS_READER_CC) {
- if (sendCmdGetResponseWithRetries(readEpurse, sizeof(readEpurse), resp, sizeof(resp), 10, 10, start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time)) {
- result_status |= FLAG_ICLASS_READER_CC;
- memcpy(card_data + (8*2), resp, 8);
- } else {
- Dbprintf("Failed to read e-purse");
+ //Read block 2, e-purse
+ if (flags & FLAG_ICLASS_READER_CC) {
+ if (sendCmdGetResponseWithRetries(readEpurse, sizeof(readEpurse), resp, sizeof(resp), 10, 10, start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time)) {
+ result_status |= FLAG_ICLASS_READER_CC;
+ memcpy(card_data + (8*2), resp, 8);
+ } else {
+ Dbprintf("Failed to read e-purse");
+ }
+ start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
}
- start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
- }
- //Read block 5, AA
- if (flags & FLAG_ICLASS_READER_AA) {
- if (sendCmdGetResponseWithRetries(readAA, sizeof(readAA), resp, sizeof(resp), 10, 10, start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time)) {
- result_status |= FLAG_ICLASS_READER_AA;
- memcpy(card_data + (8*5), resp, 8);
- } else {
- Dbprintf("Failed to read AA block");
+ //Read block 5, AA
+ if (flags & FLAG_ICLASS_READER_AA) {
+ if (sendCmdGetResponseWithRetries(readAA, sizeof(readAA), resp, sizeof(resp), 10, 10, start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time)) {
+ result_status |= FLAG_ICLASS_READER_AA;
+ memcpy(card_data + (8*5), resp, 8);
+ } else {
+ Dbprintf("Failed to read AA block");
+ }
}
}
-
+
cmd_send(CMD_ACK, result_status, 0, 0, card_data, sizeof(card_data));
LED_A_OFF();
uint8_t readblockdata[10];
bool isOK = iClass_ReadBlock(blockno, readblockdata);
- cmd_send(CMD_ACK, isOK, 0, 0, readblockdata, 8);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_D_OFF();
+ cmd_send(CMD_ACK, isOK, 0, 0, readblockdata, 8);
LED_A_OFF();
}
} else {
Dbprintf("Write block [%02x] failed", blockNo);
}
- cmd_send(CMD_ACK, isOK, 0, 0, 0, 0);
-
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_D_OFF();
+ cmd_send(CMD_ACK, isOK, 0, 0, 0, 0);
LED_A_OFF();
}
LED_D_OFF();
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
-
LED_A_OFF();
}
set_tracing(true);
- if(param & ISO14A_CLEAR_TRACE) {
+ if (param & ISO14A_CLEAR_TRACE) {
clear_trace();
}
- if(param & ISO14A_REQUEST_TRIGGER) {
+ if (param & ISO14A_REQUEST_TRIGGER) {
iso14a_set_trigger(true);
}
- if(param & ISO14A_CONNECT) {
+ if (param & ISO14A_CONNECT) {
LED_A_ON();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
if(!(param & ISO14A_NO_SELECT)) {
}
FpgaDisableTracing();
LED_B_ON();
- cmd_send(CMD_ACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t));
+ cmd_send(CMD_NACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t));
LED_B_OFF();
}
}
- if(param & ISO14A_SET_TIMEOUT) {
+ if (param & ISO14A_SET_TIMEOUT) {
iso14a_set_timeout(timeout);
}
- if(param & ISO14A_APDU && !cantSELECT) {
+ if (param & ISO14A_APDU && !cantSELECT) {
uint8_t res;
arg0 = iso14_apdu(cmd, len, (param & ISO14A_SEND_CHAINING), buf, &res);
FpgaDisableTracing();
LED_B_OFF();
}
- if(param & ISO14A_RAW && !cantSELECT) {
- if(param & ISO14A_APPEND_CRC) {
+ if (param & ISO14A_RAW && !cantSELECT) {
+ if (param & ISO14A_APPEND_CRC) {
if(param & ISO14A_TOPAZMODE) {
AppendCrc14443b(cmd,len);
} else {
len += 2;
if (lenbits) lenbits += 16;
}
- if(lenbits>0) { // want to send a specific number of bits (e.g. short commands)
- if(param & ISO14A_TOPAZMODE) {
+ if (lenbits > 0) { // want to send a specific number of bits (e.g. short commands)
+ if (param & ISO14A_TOPAZMODE) {
int bits_to_send = lenbits;
uint16_t i = 0;
ReaderTransmitBitsPar(&cmd[i++], MIN(bits_to_send, 7), NULL, NULL); // first byte is always short (7bits) and no parity
ReaderTransmitBitsPar(cmd, lenbits, par, NULL); // bytes are 8 bit with odd parity
}
} else { // want to send complete bytes only
- if(param & ISO14A_TOPAZMODE) {
+ if (param & ISO14A_TOPAZMODE) {
uint16_t i = 0;
ReaderTransmitBitsPar(&cmd[i++], 7, NULL, NULL); // first byte: 7 bits, no paritiy
while (i < len) {
FpgaDisableTracing();
LED_B_ON();
- cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
+ cmd_send(CMD_ACK, arg0, 0, 0, buf, sizeof(buf));
LED_B_OFF();
}
- if(param & ISO14A_REQUEST_TRIGGER) {
+ if (param & ISO14A_REQUEST_TRIGGER) {
iso14a_set_trigger(false);
}
- if(param & ISO14A_NO_DISCONNECT) {
+ if (param & ISO14A_NO_DISCONNECT) {
return;
}
\r
if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");\r
\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
LED_B_ON();\r
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);\r
LED_B_OFF();\r
\r
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
}\r
\r
return;\r
}\r
\r
- cmd_send(CMD_ACK,1,0,0,dataout,16);\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LED_D_OFF();\r
+\r
+ cmd_send(CMD_ACK,1,0,0,dataout,16);\r
LED_A_OFF();\r
}\r
\r
\r
if (MF_DBGLEVEL >= 2) DbpString("READ SECTOR FINISHED");\r
\r
+ // Thats it...\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
LED_B_ON();\r
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16*NumBlocksPerSector(sectorNo));\r
LED_B_OFF();\r
\r
- // Thats it...\r
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
}\r
\r
\r
if (MF_DBGLEVEL >= MF_DBG_DEBUG) Dbprintf("Blocks read %d", countblocks);\r
\r
- cmd_send(CMD_ACK, 1, countblocks*4, BigBuf_max_traceLen(), 0, 0);\r
-\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LED_D_OFF();\r
+\r
+ cmd_send(CMD_ACK, 1, countblocks*4, BigBuf_max_traceLen(), 0, 0);\r
+\r
BigBuf_free();\r
LED_A_OFF();\r
}\r
\r
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
\r
+ // Thats it...\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
LED_B_ON();\r
cmd_send(CMD_ACK,isOK,0,0,0,0);\r
LED_B_OFF();\r
\r
\r
- // Thats it...\r
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
}\r
\r
\r
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
\r
- cmd_send(CMD_ACK,1,0,0,0,0);\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
+ cmd_send(CMD_ACK,1,0,0,0,0);\r
LEDsoff();\r
}\r
*/\r
\r
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
\r
- cmd_send(CMD_ACK,1,0,0,0,0);\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
+ cmd_send(CMD_ACK,1,0,0,0,0);\r
LEDsoff();\r
}\r
\r
return;\r
};\r
\r
- cmd_send(CMD_ACK,1,0,0,0,0);\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
+ cmd_send(CMD_ACK,1,0,0,0,0);\r
LEDsoff();\r
}\r
\r
\r
crypto1_destroy(pcs);\r
\r
+ if (field_off) {\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+ LEDsoff();\r
+ }\r
+\r
LED_B_ON();\r
cmd_send(CMD_ACK, isOK, cuid, num_nonces, buf, sizeof(buf));\r
LED_B_OFF();\r
\r
if (MF_DBGLEVEL >= 3) DbpString("AcquireEncryptedNonces finished");\r
\r
- if (field_off) {\r
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
- LEDsoff();\r
- }\r
}\r
\r
\r
memcpy(buf+16, &target_ks[1], 4);\r
memcpy(buf+20, &authentication_timeout, 4);\r
\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
+ if (MF_DBGLEVEL >= 3) DbpString("NESTED FINISHED");\r
+\r
LED_B_ON();\r
cmd_send(CMD_ACK, isOK, 0, targetBlockNo + (targetKeyType * 0x100), buf, sizeof(buf));\r
LED_B_OFF();\r
\r
- if (MF_DBGLEVEL >= 3) DbpString("NESTED FINISHED");\r
-\r
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
}\r
\r
break;\r
}\r
\r
+ // reset fpga\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
// send USB response\r
LED_B_ON();\r
cmd_send(CMD_ACK,isOK,0,0,NULL,0);\r
LED_B_OFF();\r
\r
- // reset fpga\r
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
\r
return;\r
break;\r
}\r
\r
+ if ((workFlags & 0x10) || (!isOK)) {\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+ }\r
+\r
LED_B_ON();\r
cmd_send(CMD_ACK,isOK,0,0,uid,4);\r
LED_B_OFF();\r
\r
- if ((workFlags & 0x10) || (!isOK)) {\r
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
- LEDsoff();\r
- }\r
+ LEDsoff();\r
}\r
\r
\r
break;\r
}\r
\r
+ if ((workFlags & 0x10) || (!isOK)) {\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+ }\r
+\r
LED_B_ON();\r
if (workFlags & 0x20) {\r
if (isOK)\r
cmd_send(CMD_ACK,isOK,0,0,data,18);\r
LED_B_OFF();\r
\r
- if ((workFlags & 0x10) || (!isOK)) {\r
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
- LEDsoff();\r
- }\r
+ LEDsoff();\r
}\r
\r
void MifareCIdent(){\r
// From iceman1001: removed the if, since some magic tags misbehavies and send an answer to it.\r
mifare_classic_halt(NULL, 0);\r
\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
LED_B_ON();\r
cmd_send(CMD_ACK,isOK,0,0,0,0);\r
LED_B_OFF();\r
\r
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
}\r
\r
}\r
\r
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 1 FINISHED");\r
- cmd_send(CMD_ACK,1,cuid,0,dataout, sizeof(dataout));\r
+\r
+ cmd_send(CMD_ACK, 1, cuid, 0, dataout, sizeof(dataout));\r
}\r
\r
void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){\r
\r
isOK = mifare_desfire_des_auth2(cuid, key, dataout);\r
\r
- if( isOK) {\r
+ if (isOK) {\r
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Authentication part2: Failed");\r
OnError(4);\r
return;\r
}\r
\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 2 FINISHED");\r
\r
cmd_send(CMD_ACK, isOK, 0, 0, dataout, sizeof(dataout));\r
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
}\r
\r
while (pckLen > 0) {
pckSize = MIN(USB_CMD_DATA_SIZE, pckLen);
LED_B_ON();
- cmd_send(CMD_ACK, 1, BigBuf_get_traceLen(), pckSize, trace + BigBuf_get_traceLen() - pckLen, pckSize);
+ cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, 1, BigBuf_get_traceLen(), pckSize, trace + BigBuf_get_traceLen() - pckLen, pckSize);
LED_B_OFF();
pckLen -= pckSize;
}
LED_B_ON();
- cmd_send(CMD_ACK,2,0,0,0,0);
+ cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,2,0,0,0,0);
LED_B_OFF();
clear_trace();
return 0;
}
-int Hf14443_4aGetCardData(iso14a_card_select_t * card) {
+int Hf14443_4aGetCardData(iso14a_card_select_t *card) {
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};
SendCommand(&c);
UsbCommand resp;
- WaitForResponse(CMD_ACK,&resp);
+ WaitForResponse(CMD_NACK, &resp);
memcpy(card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
uint64_t select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
- if(select_status == 0) {
+ if (select_status == 0) {
PrintAndLog("E->iso14443a card select failed");
return 1;
}
- if(select_status == 2) {
+ if (select_status == 2) {
PrintAndLog("E->Card doesn't support iso14443-4 mode");
return 1;
}
- if(select_status == 3) {
+ if (select_status == 3) {
PrintAndLog("E->Card doesn't support standard iso14443-3 anticollision");
PrintAndLog("\tATQA : %02x %02x", card->atqa[1], card->atqa[0]);
return 1;
return 0;
}
-int CmdHF14AInfo(const char *Cmd)
-{
+
+int CmdHF14AInfo(const char *Cmd) {
+
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};
SendCommand(&c);
UsbCommand resp;
- WaitForResponse(CMD_ACK,&resp);
-
+ if (!WaitForResponseTimeout(CMD_NACK, &resp, 500)) {
+ if (Cmd[0] != 's') PrintAndLog("Error: No response from Proxmark.\n");
+ return 0;
+ }
+
iso14a_card_select_t card;
memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
uint64_t select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
- if(select_status == 0) {
+ if (select_status == 0) {
if (Cmd[0] != 's') PrintAndLog("iso14443a card select failed");
// disconnect
c.arg[0] = 0;
SendCommand(&c);
UsbCommand resp;
- WaitForResponse(CMD_ACK,&resp);
+ WaitForResponse(CMD_NACK,&resp);
memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS
- if(select_status == 0) {
+ if (select_status == 0) {
//PrintAndLog("iso14443a card select failed");
// disconnect
c.arg[0] = 0;
// Double & triple sized UID, can be mapped to a manufacturer.
// HACK: does this apply for Ultralight cards?
- if ( card.uidlen > 4 ) {
+ if (card.uidlen > 4) {
PrintAndLog("MANUFACTURER : %s", getManufacturerName(card.uid[0]));
}
(void)mfCIdentify();
if (isMifareClassic) {
- switch(DetectClassicPrng()) {
+ switch (DetectClassicPrng()) {
case 0:
PrintAndLog("Prng detection: HARDENED (hardnested)");
break;
SendCommand(&c);
UsbCommand resp;
- WaitForResponse(CMD_ACK,&resp);
+ WaitForResponse(CMD_NACK,&resp);
iso14a_card_select_t *card = (iso14a_card_select_t *) resp.d.asBytes;
while (!ukbhit()) {
SendCommand(&c);
- if (WaitForResponseTimeout(CMD_ACK,&resp, 4500)) {
+ if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
uint8_t readStatus = resp.arg[0] & 0xff;
uint8_t *data = resp.d.asBytes;
if (tagFound && !loop) return 1;
} else {
- if (verbose) PrintAndLog("Command execute timeout");
+ if (verbose) PrintAndLog("Error: No response from Proxmark.");
+ break;
}
if (!loop) break;
}
}\r
\r
UsbCommand resp;\r
- if (WaitForResponseTimeoutW(CMD_ACK, &resp, 2000, false)) {\r
+ if (WaitForResponseTimeoutW(CMD_UNKNOWN, &resp, 2000, false)) {\r
res = resp.arg[0] & 0xff;\r
uint16_t traceLen = resp.arg[1];\r
len = resp.arg[2];\r
#include "comms.h"
+#include <stdio.h>
#include <pthread.h>
#include <inttypes.h>
#if defined(__linux__) && !defined(NO_UNLINK)
-#include <unistd.h> // for unlink()
+#include <unistd.h> // for unlink()
#endif
#include "uart.h"
#include "ui.h"
typedef struct {
bool run; // If TRUE, continue running the uart_communication thread
- bool block_after_ACK; // if true, block after receiving an ACK package
} communication_arg_t;
static communication_arg_t conn;
if (offline) {
PrintAndLog("Sending bytes to proxmark failed - offline");
return;
- }
+ }
pthread_mutex_lock(&txBufferMutex);
/**
- This causes hangups at times, when the pm3 unit is unresponsive or disconnected. The main console thread is alive,
+ This causes hangups at times, when the pm3 unit is unresponsive or disconnected. The main console thread is alive,
but comm thread just spins here. Not good.../holiman
**/
while (txBuffer_pending) {
} break;
default:
- storeCommand(UC);
+ storeCommand(UC);
break;
}
*received_len = 0;
// we eventually need to call uart_receive several times if it times out in the middle of a transfer
while (uart_receive(sp, rx_buf + *received_len, len - *received_len, &bytes_read) && bytes_read && *received_len < len) {
+ #ifdef COMMS_DEBUG
if (bytes_read != len - *received_len) {
printf("uart_receive() returned true but not enough bytes could be received. received: %d, wanted to receive: %d, already received before: %d\n",
bytes_read, len - *received_len, *received_len);
}
+ #endif
*received_len += bytes_read;
bytes_read = 0;
}
return (*received_len == len);
}
-
+
static void
#ifdef __has_attribute
#if __has_attribute(force_align_arg_pointer)
-__attribute__((force_align_arg_pointer))
+__attribute__((force_align_arg_pointer))
#endif
#endif
*uart_communication(void *targ) {
if (receive_from_serial(sp, prx, bytes_to_read, &rxlen)) {
prx += rxlen;
if (response->cmd & CMD_VARIABLE_SIZE_FLAG) { // new style response with variable size
- // printf("received new style response %04" PRIx16 ", datalen = %d, arg[0] = %08" PRIx32 ", arg[1] = %08" PRIx32 ", arg[2] = %08" PRIx32 "\n",
+ // PrintAndLog("received new style response %04" PRIx16 ", datalen = %d, arg[0] = %08" PRIx32 ", arg[1] = %08" PRIx32 ", arg[2] = %08" PRIx32 "\n",
// response->cmd, response->datalen, response->arg[0], response->arg[1], response->arg[2]);
bytes_to_read = response->datalen;
if (receive_from_serial(sp, prx, bytes_to_read, &rxlen)) {
UsbCommand resp;
- resp.cmd = response->cmd & ~CMD_VARIABLE_SIZE_FLAG;
+ resp.cmd = response->cmd & ~CMD_VARIABLE_SIZE_FLAG; // remove the flag
resp.arg[0] = response->arg[0];
resp.arg[1] = response->arg[1];
resp.arg[2] = response->arg[2];
}
}
} else { // old style response uses same data structure as commands. Fixed size.
- // printf("received old style response %016" PRIx64 ", arg[0] = %016" PRIx64 "\n", command->cmd, command->arg[0]);
+ // PrintAndLog("received old style response %016" PRIx64 ", arg[0] = %016" PRIx64 "\n", command->cmd, command->arg[0]);
bytes_to_read = sizeof(UsbCommand) - bytes_to_read;
- if (receive_from_serial(sp, prx, bytes_to_read, &rxlen)) {
+ if (receive_from_serial(sp, prx, bytes_to_read, &rxlen)) {
UsbCommandReceived(command);
if (command->cmd == CMD_ACK) {
ACK_received = true;
}
}
}
-
- pthread_mutex_lock(&txBufferMutex);
- if (conn->block_after_ACK) {
- // if we just received an ACK, wait here until a new command is to be transmitted
- if (ACK_received) {
- while (!txBuffer_pending) {
- pthread_cond_wait(&txBufferSig, &txBufferMutex);
- }
+ pthread_mutex_lock(&txBufferMutex);
+ // if we received an ACK the PM has done its job and waits for another command.
+ // We therefore can wait here as well until a new command is to be transmitted.
+ // The advantage is that the next command will be transmitted immediately without the need to wait for a receive timeout
+ if (ACK_received) {
+ while (!txBuffer_pending) {
+ pthread_cond_wait(&txBufferSig, &txBufferMutex);
}
}
-
- if(txBuffer_pending) {
+ if (txBuffer_pending) {
if (!uart_send(sp, (uint8_t*) &txBuffer, sizeof(UsbCommand))) {
PrintAndLog("Sending bytes to proxmark failed");
}
txBuffer_pending = false;
- pthread_cond_signal(&txBufferSig); // tell main thread that txBuffer is empty
}
-
+ pthread_cond_signal(&txBufferSig); // tell main thread that txBuffer is empty
pthread_mutex_unlock(&txBufferMutex);
}
uint64_t start_time = msclock();
UsbCommand resp;
- if (response == NULL) {
+ if (response == NULL) {
response = &resp;
}
return false;
}
-
+
bool GetFromFpgaRAM(uint8_t *dest, int bytes)
{
UsbCommand c = {CMD_HF_PLOT, {0, 0, 0}};
uint64_t start_time = msclock();
UsbCommand response;
-
+
int bytes_completed = 0;
bool show_warning = true;
while(true) {
}
-bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode) {
+bool OpenProxmark(void *port, bool wait_for_port, int timeout) {
char *portname = (char *)port;
if (!wait_for_port) {
sp = uart_open(portname);
// start the USB communication thread
serial_port_name = portname;
conn.run = true;
- conn.block_after_ACK = flash_mode;
pthread_create(&USB_communication_thread, NULL, &uart_communication, &conn);
return true;
}
// Wait until the command is received
while (true) {
- while(getCommand(response)) {
+ while (getCommand(response)) {
if (cmd == CMD_UNKNOWN || response->cmd == cmd) {
return true;
}
extern void SetOffline(bool new_offline);
extern bool IsOffline();
-extern bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode);
+extern bool OpenProxmark(void *port, bool wait_for_port, int timeout);
extern void CloseProxmark(void);
extern void SendCommand(UsbCommand *c);
extern void clearCommandBuffer();
msleep(100);
CloseProxmark();
- bool opened = OpenProxmark(serial_port_name, true, 120, true); // wait for 2 minutes
+ bool opened = OpenProxmark(serial_port_name, true, 120); // wait for 2 minutes
if (opened) {
fprintf(stderr," Found.\n");
return 0;
char* serial_port_name = argv[1];
- if (!OpenProxmark(serial_port_name, true, 120, true)) { // wait for 2 minutes
+ if (!OpenProxmark(serial_port_name, true, 120)) { // wait for 2 minutes
fprintf(stderr, "Could not find Proxmark on %s.\n\n", serial_port_name);
return -1;
} else {
clearCommandBuffer();
SendCommand(&c);
- if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
+ if (!WaitForResponseTimeout(CMD_NACK, &resp, 2000)) {
PrintAndLog("PRNG UID: Reply timeout.");
return -1;
}
set_my_executable_path();
// try to open USB connection to Proxmark
- usb_present = OpenProxmark(argv[1], waitCOMPort, 20, false);
+ usb_present = OpenProxmark(argv[1], waitCOMPort, 20);
#ifdef HAVE_GUI
#ifdef _WIN32
main_loop(script_cmds_file, script_cmd, usb_present);
#endif
- // Clean up the port
+ // Switch off field and clean up the port
if (usb_present) {
+ UsbCommand c = {CMD_FPGA_MAJOR_MODE_OFF};
+ SendCommand(&c);
CloseProxmark();
}
\r
\r
// Bitmap for all status bits in CSR which must be written as 1 to cause no effect\r
-#define REG_NO_EFFECT_1_ALL AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1 \\r
- |AT91C_UDP_STALLSENT | AT91C_UDP_RXSETUP \\r
- |AT91C_UDP_TXCOMP\r
+#define REG_NO_EFFECT_1_ALL (AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1 | AT91C_UDP_STALLSENT | AT91C_UDP_RXSETUP | AT91C_UDP_TXCOMP)\r
\r
\r
// Clear flags in the UDP_CSR register\r
#define UDP_CLEAR_EP_FLAGS(endpoint, flags) { \\r
volatile unsigned int reg; \\r
- reg = pUdp->UDP_CSR[(endpoint)]; \\r
+ reg = AT91C_BASE_UDP->UDP_CSR[(endpoint)]; \\r
reg |= REG_NO_EFFECT_1_ALL; \\r
reg &= ~(flags); \\r
- pUdp->UDP_CSR[(endpoint)] = reg; \\r
+ AT91C_BASE_UDP->UDP_CSR[(endpoint)] = reg; \\r
}\r
\r
\r
// Set flags in the UDP_CSR register\r
#define UDP_SET_EP_FLAGS(endpoint, flags) { \\r
volatile unsigned int reg; \\r
- reg = pUdp->UDP_CSR[(endpoint)]; \\r
+ reg = AT91C_BASE_UDP->UDP_CSR[(endpoint)]; \\r
reg |= REG_NO_EFFECT_1_ALL; \\r
reg |= (flags); \\r
- pUdp->UDP_CSR[(endpoint)] = reg; \\r
+ AT91C_BASE_UDP->UDP_CSR[(endpoint)] = reg; \\r
}\r
\r
\r
} AT91S_CDC_LINE_CODING, *AT91PS_CDC_LINE_CODING;\r
\r
\r
-AT91S_CDC_LINE_CODING line = {\r
+static AT91S_CDC_LINE_CODING line = {\r
115200, // baudrate\r
0, // 1 Stop Bit\r
0, // None Parity\r
8}; // 8 Data bits\r
\r
\r
-static void AT91F_CDC_Enumerate();\r
-\r
-AT91PS_UDP pUdp = AT91C_BASE_UDP;\r
-uint8_t btConfiguration = 0;\r
-uint8_t btConnection = 0;\r
-uint8_t btReceiveBank = AT91C_UDP_RX_DATA_BK0;\r
+static uint8_t btConfiguration = 0;\r
+static uint8_t btConnection = 0;\r
+static uint8_t btReceiveBank = AT91C_UDP_RX_DATA_BK0;\r
\r
\r
//*----------------------------------------------------------------------------\r
AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU;\r
\r
// Clear all lingering interrupts\r
- if (pUdp->UDP_ISR & AT91C_UDP_ENDBUSRES) {\r
- pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;\r
+ if (AT91C_BASE_UDP->UDP_ISR & AT91C_UDP_ENDBUSRES) {\r
+ AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_ENDBUSRES;\r
}\r
}\r
\r
\r
\r
//*----------------------------------------------------------------------------\r
-//* \fn usb_check\r
-//* \brief Test if the device is configured and handle enumeration\r
-//*----------------------------------------------------------------------------\r
-static bool usb_check() {\r
- AT91_REG isr = pUdp->UDP_ISR;\r
-\r
- if (isr & AT91C_UDP_ENDBUSRES) {\r
- pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;\r
- // reset all endpoints\r
- pUdp->UDP_RSTEP = (unsigned int)-1;\r
- pUdp->UDP_RSTEP = 0;\r
- // Enable the function\r
- pUdp->UDP_FADDR = AT91C_UDP_FEN;\r
- // Configure endpoint 0\r
- pUdp->UDP_CSR[AT91C_EP_CONTROL] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);\r
- } else if (isr & AT91C_UDP_EPINT0) {\r
- pUdp->UDP_ICR = AT91C_UDP_EPINT0;\r
- AT91F_CDC_Enumerate();\r
- }\r
- return (btConfiguration) ? true : false;\r
-}\r
-\r
-\r
-bool usb_poll() {\r
- if (!usb_check()) return false;\r
- return (pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank);\r
-}\r
-\r
-\r
-/**\r
- In github PR #129, some users appears to get a false positive from\r
- usb_poll, which returns true, but the usb_read operation\r
- still returns 0.\r
- This check is basically the same as above, but also checks\r
- that the length available to read is non-zero, thus hopefully fixes the\r
- bug.\r
-**/\r
-bool usb_poll_validate_length() {\r
- if (!usb_check()) return false;\r
- if (!(pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank)) return false;\r
- return (pUdp->UDP_CSR[AT91C_EP_OUT] >> 16) > 0;\r
-}\r
-\r
-\r
-//*----------------------------------------------------------------------------\r
-//* \fn usb_read\r
-//* \brief Read available data from Endpoint OUT\r
-//*----------------------------------------------------------------------------\r
-static uint32_t usb_read(uint8_t* data, size_t len) {\r
- uint8_t bank = btReceiveBank;\r
- uint32_t packetSize, nbBytesRcv = 0;\r
- uint32_t time_out = 0;\r
-\r
- while (len) {\r
- if (!usb_check()) break;\r
-\r
- if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) {\r
- packetSize = MIN(pUdp->UDP_CSR[AT91C_EP_OUT] >> 16, len);\r
- len -= packetSize;\r
- while (packetSize--)\r
- data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT];\r
- UDP_CLEAR_EP_FLAGS(AT91C_EP_OUT, bank);\r
- if (bank == AT91C_UDP_RX_DATA_BK0) {\r
- bank = AT91C_UDP_RX_DATA_BK1;\r
- } else {\r
- bank = AT91C_UDP_RX_DATA_BK0;\r
- }\r
- }\r
- if (time_out++ == 0x1fff) break;\r
- }\r
-\r
- btReceiveBank = bank;\r
- return nbBytesRcv;\r
-}\r
-\r
-\r
-//*----------------------------------------------------------------------------\r
-//* \fn usb_write\r
-//* \brief Send through endpoint 2\r
+//* \fn AT91F_USB_SendZlp\r
+//* \brief Send zero length packet through an endpoint\r
//*----------------------------------------------------------------------------\r
-static uint32_t usb_write(const uint8_t* data, const size_t len) {\r
- size_t length = len;\r
- uint32_t cpt = 0;\r
-\r
- if (!length) return 0;\r
- if (!usb_check()) return 0;\r
-\r
- // Send the first packet\r
- cpt = MIN(length, AT91C_EP_IN_SIZE);\r
- length -= cpt;\r
- while (cpt--) {\r
- pUdp->UDP_FDR[AT91C_EP_IN] = *data++;\r
- }\r
- UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);\r
-\r
- while (length) {\r
- // Fill the next bank\r
- cpt = MIN(length, AT91C_EP_IN_SIZE);\r
- length -= cpt;\r
- while (cpt--) {\r
- pUdp->UDP_FDR[AT91C_EP_IN] = *data++;\r
- }\r
- // Wait for the previous bank to be sent\r
- while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {\r
- if (!usb_check()) return length;\r
- }\r
- UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);\r
- while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)\r
- /* wait */;\r
- UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);\r
- }\r
-\r
- // Wait for the end of transfer\r
- while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {\r
- if (!usb_check()) return length;\r
- }\r
-\r
- UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);\r
- while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)\r
+static void AT91F_USB_SendZlp(uint8_t endpoint) {\r
+ UDP_SET_EP_FLAGS(endpoint, AT91C_UDP_TXPKTRDY);\r
+ while (!(AT91C_BASE_UDP->UDP_CSR[endpoint] & AT91C_UDP_TXCOMP))\r
+ /* wait */;\r
+ UDP_CLEAR_EP_FLAGS(endpoint, AT91C_UDP_TXCOMP);\r
+ while (AT91C_BASE_UDP->UDP_CSR[endpoint] & AT91C_UDP_TXCOMP)\r
/* wait */;\r
-\r
- return length;\r
}\r
\r
\r
//* \fn AT91F_USB_SendData\r
//* \brief Send Data through the control endpoint\r
//*----------------------------------------------------------------------------\r
-static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) {\r
+static void AT91F_USB_SendData(const char *pData, uint32_t length) {\r
uint32_t cpt = 0;\r
AT91_REG csr;\r
\r
length -= cpt;\r
\r
while (cpt--)\r
- pUdp->UDP_FDR[0] = *pData++;\r
+ AT91C_BASE_UDP->UDP_FDR[0] = *pData++;\r
\r
- if (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {\r
+ if (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {\r
UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP);\r
- while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP)\r
+ while (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP)\r
/* wait */;\r
}\r
\r
UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY);\r
do {\r
- csr = pUdp->UDP_CSR[AT91C_EP_CONTROL];\r
+ csr = AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL];\r
\r
// Data IN stage has been stopped by a status OUT\r
if (csr & AT91C_UDP_RX_DATA_BK0) {\r
\r
} while (length);\r
\r
- if (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {\r
+ if (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {\r
UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP);\r
- while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP)\r
+ while (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP)\r
/* wait */;\r
}\r
}\r
\r
\r
-//*----------------------------------------------------------------------------\r
-//* \fn AT91F_USB_SendZlp\r
-//* \brief Send zero length packet through the control endpoint\r
-//*----------------------------------------------------------------------------\r
-static void AT91F_USB_SendZlp(AT91PS_UDP pUdp) {\r
- UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY);\r
- while (!(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP))\r
- /* wait */;\r
- UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP);\r
- while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP)\r
- /* wait */;\r
-}\r
-\r
-\r
//*----------------------------------------------------------------------------\r
//* \fn AT91F_USB_SendStall\r
//* \brief Stall the control endpoint\r
//*----------------------------------------------------------------------------\r
-static void AT91F_USB_SendStall(AT91PS_UDP pUdp) {\r
+static void AT91F_USB_SendStall(void) {\r
UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_FORCESTALL);\r
- while (!(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_ISOERROR))\r
+ while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_ISOERROR))\r
/* wait */;\r
UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR);\r
- while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR))\r
+ while (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR))\r
/* wait */;\r
}\r
\r
uint8_t bmRequestType, bRequest;\r
uint16_t wValue, wIndex, wLength, wStatus;\r
\r
- if (!(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP))\r
+ if (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP))\r
return;\r
\r
- bmRequestType = pUdp->UDP_FDR[AT91C_EP_CONTROL];\r
- bRequest = pUdp->UDP_FDR[AT91C_EP_CONTROL];\r
- wValue = (pUdp->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);\r
- wValue |= (pUdp->UDP_FDR[AT91C_EP_CONTROL] << 8);\r
- wIndex = (pUdp->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);\r
- wIndex |= (pUdp->UDP_FDR[AT91C_EP_CONTROL] << 8);\r
- wLength = (pUdp->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);\r
- wLength |= (pUdp->UDP_FDR[AT91C_EP_CONTROL] << 8);\r
+ bmRequestType = AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL];\r
+ bRequest = AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL];\r
+ wValue = (AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);\r
+ wValue |= (AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL] << 8);\r
+ wIndex = (AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);\r
+ wIndex |= (AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL] << 8);\r
+ wLength = (AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);\r
+ wLength |= (AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL] << 8);\r
\r
if (bmRequestType & 0x80) { // Data Phase Transfer Direction Device to Host\r
UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_DIR);\r
- while (!(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_DIR))\r
+ while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_DIR))\r
/* wait */;\r
}\r
UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RXSETUP);\r
- while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP)\r
+ while (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP)\r
/* wait */;\r
\r
// Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1\r
switch ((bRequest << 8) | bmRequestType) {\r
case STD_GET_DESCRIPTOR:\r
if (wValue == 0x100) // Return Device Descriptor\r
- AT91F_USB_SendData(pUdp, devDescriptor, MIN(sizeof(devDescriptor), wLength));\r
+ AT91F_USB_SendData(devDescriptor, MIN(sizeof(devDescriptor), wLength));\r
else if (wValue == 0x200) // Return Configuration Descriptor\r
- AT91F_USB_SendData(pUdp, cfgDescriptor, MIN(sizeof(cfgDescriptor), wLength));\r
+ AT91F_USB_SendData(cfgDescriptor, MIN(sizeof(cfgDescriptor), wLength));\r
else if ((wValue & 0xF00) == 0x300) { // Return String Descriptor\r
const char *strDescriptor = getStringDescriptor(wValue & 0xff);\r
if (strDescriptor != NULL) {\r
- AT91F_USB_SendData(pUdp, strDescriptor, MIN(strDescriptor[0], wLength));\r
+ AT91F_USB_SendData(strDescriptor, MIN(strDescriptor[0], wLength));\r
} else {\r
- AT91F_USB_SendStall(pUdp);\r
+ AT91F_USB_SendStall();\r
}\r
}\r
else\r
- AT91F_USB_SendStall(pUdp);\r
+ AT91F_USB_SendStall();\r
break;\r
case STD_SET_ADDRESS:\r
- AT91F_USB_SendZlp(pUdp);\r
- pUdp->UDP_FADDR = (AT91C_UDP_FEN | wValue);\r
- pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_FADDEN : 0;\r
+ AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
+ AT91C_BASE_UDP->UDP_FADDR = (AT91C_UDP_FEN | wValue);\r
+ AT91C_BASE_UDP->UDP_GLBSTATE = (wValue) ? AT91C_UDP_FADDEN : 0;\r
break;\r
case STD_SET_CONFIGURATION:\r
btConfiguration = wValue;\r
- AT91F_USB_SendZlp(pUdp);\r
- pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;\r
- pUdp->UDP_CSR[AT91C_EP_OUT] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0;\r
- pUdp->UDP_CSR[AT91C_EP_IN] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN) : 0;\r
- pUdp->UDP_CSR[AT91C_EP_NOTIFY] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN) : 0;\r
+ AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
+ AT91C_BASE_UDP->UDP_GLBSTATE = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;\r
+ AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0;\r
+ AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN) : 0;\r
+ AT91C_BASE_UDP->UDP_CSR[AT91C_EP_NOTIFY] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN) : 0;\r
break;\r
case STD_GET_CONFIGURATION:\r
- AT91F_USB_SendData(pUdp, (char *) &(btConfiguration), sizeof(btConfiguration));\r
+ AT91F_USB_SendData((char *) &(btConfiguration), sizeof(btConfiguration));\r
break;\r
case STD_GET_STATUS_ZERO:\r
wStatus = 0; // Device is Bus powered, remote wakeup disabled\r
- AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));\r
+ AT91F_USB_SendData((char *) &wStatus, sizeof(wStatus));\r
break;\r
case STD_GET_STATUS_INTERFACE:\r
wStatus = 0; // reserved for future use\r
- AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));\r
+ AT91F_USB_SendData((char *) &wStatus, sizeof(wStatus));\r
break;\r
case STD_GET_STATUS_ENDPOINT:\r
wStatus = 0;\r
wIndex &= 0x0F;\r
- if ((pUdp->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= AT91C_EP_NOTIFY)) {\r
- wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;\r
- AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));\r
- } else if ((pUdp->UDP_GLBSTATE & AT91C_UDP_FADDEN) && (wIndex == AT91C_EP_CONTROL)) {\r
- wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;\r
- AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));\r
+ if ((AT91C_BASE_UDP->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= AT91C_EP_NOTIFY)) {\r
+ wStatus = (AT91C_BASE_UDP->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;\r
+ AT91F_USB_SendData((char *) &wStatus, sizeof(wStatus));\r
+ } else if ((AT91C_BASE_UDP->UDP_GLBSTATE & AT91C_UDP_FADDEN) && (wIndex == AT91C_EP_CONTROL)) {\r
+ wStatus = (AT91C_BASE_UDP->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;\r
+ AT91F_USB_SendData((char *) &wStatus, sizeof(wStatus));\r
} else\r
- AT91F_USB_SendStall(pUdp);\r
+ AT91F_USB_SendStall();\r
break;\r
case STD_SET_FEATURE_ZERO:\r
- AT91F_USB_SendStall(pUdp);\r
+ AT91F_USB_SendStall();\r
break;\r
case STD_SET_FEATURE_INTERFACE:\r
- AT91F_USB_SendZlp(pUdp);\r
+ AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
break;\r
case STD_SET_FEATURE_ENDPOINT:\r
wIndex &= 0x0F;\r
if ((wValue == 0) && (wIndex >= AT91C_EP_OUT) && (wIndex <= AT91C_EP_NOTIFY)) {\r
- pUdp->UDP_CSR[wIndex] = 0;\r
- AT91F_USB_SendZlp(pUdp);\r
+ AT91C_BASE_UDP->UDP_CSR[wIndex] = 0;\r
+ AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
} else\r
- AT91F_USB_SendStall(pUdp);\r
+ AT91F_USB_SendStall();\r
break;\r
case STD_CLEAR_FEATURE_ZERO:\r
- AT91F_USB_SendStall(pUdp);\r
+ AT91F_USB_SendStall();\r
break;\r
case STD_CLEAR_FEATURE_INTERFACE:\r
- AT91F_USB_SendZlp(pUdp);\r
+ AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
break;\r
case STD_CLEAR_FEATURE_ENDPOINT:\r
wIndex &= 0x0F;\r
if ((wValue == 0) && (wIndex >= AT91C_EP_OUT) && (wIndex <= AT91C_EP_NOTIFY)) {\r
if (wIndex == AT91C_EP_OUT)\r
- pUdp->UDP_CSR[AT91C_EP_OUT] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT);\r
+ AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT);\r
else if (wIndex == AT91C_EP_IN)\r
- pUdp->UDP_CSR[AT91C_EP_IN] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);\r
+ AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);\r
else if (wIndex == AT91C_EP_NOTIFY)\r
- pUdp->UDP_CSR[AT91C_EP_NOTIFY] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN);\r
- AT91F_USB_SendZlp(pUdp);\r
+ AT91C_BASE_UDP->UDP_CSR[AT91C_EP_NOTIFY] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN);\r
+ AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
}\r
else\r
- AT91F_USB_SendStall(pUdp);\r
+ AT91F_USB_SendStall();\r
break;\r
\r
// handle CDC class requests\r
case SET_LINE_CODING:\r
- while (!(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RX_DATA_BK0))\r
+ while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RX_DATA_BK0))\r
/* wait */;\r
UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RX_DATA_BK0);\r
- AT91F_USB_SendZlp(pUdp);\r
+ AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
break;\r
case GET_LINE_CODING:\r
- AT91F_USB_SendData(pUdp, (char *) &line, MIN(sizeof(line), wLength));\r
+ AT91F_USB_SendData((char *) &line, MIN(sizeof(line), wLength));\r
break;\r
case SET_CONTROL_LINE_STATE:\r
btConnection = wValue;\r
- AT91F_USB_SendZlp(pUdp);\r
+ AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
break;\r
default:\r
- AT91F_USB_SendStall(pUdp);\r
+ AT91F_USB_SendStall();\r
break;\r
}\r
}\r
\r
\r
+//*----------------------------------------------------------------------------\r
+//* \fn usb_check\r
+//* \brief Test if the device is configured and handle enumeration\r
+//*----------------------------------------------------------------------------\r
+static bool usb_check() {\r
+ AT91_REG isr = AT91C_BASE_UDP->UDP_ISR;\r
+\r
+ if (isr & AT91C_UDP_ENDBUSRES) {\r
+ AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_ENDBUSRES;\r
+ // reset all endpoints\r
+ AT91C_BASE_UDP->UDP_RSTEP = (unsigned int)-1;\r
+ AT91C_BASE_UDP->UDP_RSTEP = 0;\r
+ // Enable the function\r
+ AT91C_BASE_UDP->UDP_FADDR = AT91C_UDP_FEN;\r
+ // Configure endpoint 0\r
+ AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);\r
+ } else if (isr & AT91C_UDP_EPINT0) {\r
+ AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_EPINT0;\r
+ AT91F_CDC_Enumerate();\r
+ }\r
+ return (btConfiguration) ? true : false;\r
+}\r
+\r
+\r
+bool usb_poll() {\r
+ if (!usb_check()) return false;\r
+ return (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] & btReceiveBank);\r
+}\r
+\r
+\r
+/**\r
+ In github PR #129, some users appears to get a false positive from\r
+ usb_poll, which returns true, but the usb_read operation\r
+ still returns 0.\r
+ This check is basically the same as above, but also checks\r
+ that the length available to read is non-zero, thus hopefully fixes the\r
+ bug.\r
+**/\r
+bool usb_poll_validate_length() {\r
+ if (!usb_check()) return false;\r
+ if (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] & btReceiveBank)) return false;\r
+ return (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] >> 16) > 0;\r
+}\r
+\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn usb_read\r
+//* \brief Read available data from Endpoint OUT\r
+//*----------------------------------------------------------------------------\r
+static uint32_t usb_read(uint8_t* data, size_t len) {\r
+ uint8_t bank = btReceiveBank;\r
+ uint32_t packetSize, nbBytesRcv = 0;\r
+ uint32_t time_out = 0;\r
+\r
+ while (len) {\r
+ if (!usb_check()) break;\r
+\r
+ if ( AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] & bank ) {\r
+ packetSize = MIN(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] >> 16, len);\r
+ len -= packetSize;\r
+ while (packetSize--)\r
+ data[nbBytesRcv++] = AT91C_BASE_UDP->UDP_FDR[AT91C_EP_OUT];\r
+ UDP_CLEAR_EP_FLAGS(AT91C_EP_OUT, bank);\r
+ if (bank == AT91C_UDP_RX_DATA_BK0) {\r
+ bank = AT91C_UDP_RX_DATA_BK1;\r
+ } else {\r
+ bank = AT91C_UDP_RX_DATA_BK0;\r
+ }\r
+ }\r
+ if (time_out++ == 0x1fff) break;\r
+ }\r
+\r
+ btReceiveBank = bank;\r
+ return nbBytesRcv;\r
+}\r
+\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn usb_write\r
+//* \brief Send through endpoint 2\r
+//*----------------------------------------------------------------------------\r
+static uint32_t usb_write(const uint8_t* data, const size_t len) {\r
+ size_t length = len;\r
+ uint32_t cpt = 0;\r
+\r
+ if (!length) return 0;\r
+ if (!usb_check()) return 0;\r
+\r
+ // Send the first packet\r
+ cpt = MIN(length, AT91C_EP_IN_SIZE);\r
+ length -= cpt;\r
+ while (cpt--) {\r
+ AT91C_BASE_UDP->UDP_FDR[AT91C_EP_IN] = *data++;\r
+ }\r
+ UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);\r
+ while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY))\r
+ /* wait */;\r
+\r
+ while (length) {\r
+ // Fill the next bank\r
+ cpt = MIN(length, AT91C_EP_IN_SIZE);\r
+ length -= cpt;\r
+ while (cpt--) {\r
+ AT91C_BASE_UDP->UDP_FDR[AT91C_EP_IN] = *data++;\r
+ }\r
+ // Wait for the previous bank to be sent\r
+ while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {\r
+ if (!usb_check()) return length;\r
+ }\r
+ UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);\r
+ while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY))\r
+ /* wait */;\r
+ UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);\r
+ while (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)\r
+ /* wait */;\r
+ }\r
+\r
+ // Wait for the end of transfer\r
+ while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {\r
+ if (!usb_check()) return length;\r
+ }\r
+ UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);\r
+ while (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)\r
+ /* wait */;\r
+\r
+ if (len % AT91C_EP_IN_SIZE == 0) { // need to send a zero length packet to complete the transfer\r
+ AT91F_USB_SendZlp(AT91C_EP_IN);\r
+ }\r
+\r
+ return length;\r
+}\r
+\r
+\r
//***************************************************************************\r
// Interface to the main program\r
//***************************************************************************\r
txcmd.d.asBytes[i] = ((uint8_t*)data)[i];\r
}\r
}\r
- \r
+\r
// Send frame and make sure all bytes are transmitted\r
if (usb_write((uint8_t*)&txcmd, sizeof(UsbCommand)) != 0) return false;\r
\r
* @file uart.h
*/
-#ifndef _PM3_UART_H_
-#define _PM3_UART_H_
+#ifndef PM3_UART_H__
+#define PM3_UART_H__
-#include <stdio.h>
-#include <string.h>
#include <stdlib.h>
-
#include <stdint.h>
#include <stdbool.h>
/* Used to substitute for an example serial port path on each platform.
*/
#ifdef _WIN32
-#define SERIAL_PORT_H "com3"
+#define SERIAL_PORT_H "com3"
#elif __APPLE__
-#define SERIAL_PORT_H "/dev/tty.usbmodem*"
+#define SERIAL_PORT_H "/dev/tty.usbmodem*"
#else
-#define SERIAL_PORT_H "/dev/ttyACM0"
+#define SERIAL_PORT_H "/dev/ttyACM0"
#endif
/* serial_port is declared as a void*, which you should cast to whatever type
*
* On errors, this method returns INVALID_SERIAL_PORT or CLAIMED_SERIAL_PORT.
*/
-serial_port uart_open(const char* pcPortName);
+extern serial_port uart_open(const char* pcPortName);
/* Closes the given port.
*/
-void uart_close(const serial_port sp);
+extern void uart_close(const serial_port sp);
/* Reads from the given serial port for up to 30ms.
* pbtRx: A pointer to a buffer for the returned data to be written to.
*
* Returns FALSE if there was an error reading from the device. Note that a
* partial read may have completed into the buffer by the corresponding
- * implementation, so pszRxLen should be checked to see if any data was written.
+ * implementation, so pszRxLen should be checked to see if any data was written.
*/
-bool uart_receive(const serial_port sp, uint8_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen);
+extern bool uart_receive(const serial_port sp, uint8_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen);
/* Sends a buffer to a given serial port.
* pbtTx: A pointer to a buffer containing the data to send.
* szTxLen: The amount of data to be sent.
*/
-bool uart_send(const serial_port sp, const uint8_t* pbtTx, const size_t szTxLen);
+extern bool uart_send(const serial_port sp, const uint8_t* pbtTx, const size_t szTxLen);
/* Sets the current speed of the serial port, in baud.
*/
/* Gets the current speed of the serial port, in baud.
*/
-uint32_t uart_get_speed(const serial_port sp);
+extern uint32_t uart_get_speed(const serial_port sp);
#endif // _PM3_UART_H_
#include "uart.h"
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+
// The windows serial port implementation
#ifdef _WIN32
#include <windows.h>
typedef struct {
- HANDLE hPort; // Serial port handle
- DCB dcb; // Device control settings
- COMMTIMEOUTS ct; // Serial port time-out configuration
+ HANDLE hPort; // Serial port handle
+ DCB dcb; // Device control settings
+ COMMTIMEOUTS ct; // Serial port time-out configuration
} serial_port_windows;
+
void upcase(char *p) {
- while(*p != '\0') {
- if(*p >= 97 && *p <= 122) {
- *p -= 32;
- }
- ++p;
- }
+ while(*p != '\0') {
+ if(*p >= 97 && *p <= 122) {
+ *p -= 32;
+ }
+ ++p;
+ }
}
-serial_port uart_open(const char* pcPortName) {
- char acPortName[255];
- serial_port_windows* sp = malloc(sizeof(serial_port_windows));
-
- // Copy the input "com?" to "\\.\COM?" format
- sprintf(acPortName,"\\\\.\\%s",pcPortName);
- upcase(acPortName);
-
- // Try to open the serial port
- sp->hPort = CreateFileA(acPortName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
- if (sp->hPort == INVALID_HANDLE_VALUE) {
- uart_close(sp);
- return INVALID_SERIAL_PORT;
- }
-
- // Prepare the device control
- memset(&sp->dcb, 0, sizeof(DCB));
- sp->dcb.DCBlength = sizeof(DCB);
- if(!BuildCommDCBA("baud=9600 data=8 parity=N stop=1",&sp->dcb)) {
- uart_close(sp);
- return INVALID_SERIAL_PORT;
- }
-
- // Update the active serial port
- if(!SetCommState(sp->hPort,&sp->dcb)) {
- uart_close(sp);
- return INVALID_SERIAL_PORT;
- }
-
- sp->ct.ReadIntervalTimeout = 0;
- sp->ct.ReadTotalTimeoutMultiplier = 0;
- sp->ct.ReadTotalTimeoutConstant = 30;
- sp->ct.WriteTotalTimeoutMultiplier = 0;
- sp->ct.WriteTotalTimeoutConstant = 30;
-
- if(!SetCommTimeouts(sp->hPort,&sp->ct)) {
- uart_close(sp);
- return INVALID_SERIAL_PORT;
- }
-
- PurgeComm(sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
-
- return sp;
-}
void uart_close(const serial_port sp) {
- CloseHandle(((serial_port_windows*)sp)->hPort);
- free(sp);
+ CloseHandle(((serial_port_windows*)sp)->hPort);
+ free(sp);
}
+
+serial_port uart_open(const char* pcPortName) {
+ char acPortName[255];
+ serial_port_windows* sp = malloc(sizeof(serial_port_windows));
+
+ // Copy the input "com?" to "\\.\COM?" format
+ sprintf(acPortName,"\\\\.\\%s",pcPortName);
+ upcase(acPortName);
+
+ // Try to open the serial port
+ sp->hPort = CreateFileA(acPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
+ if (sp->hPort == INVALID_HANDLE_VALUE) {
+ uart_close(sp);
+ return INVALID_SERIAL_PORT;
+ }
+
+ // Prepare the device control
+ memset(&sp->dcb, 0, sizeof(DCB));
+ sp->dcb.DCBlength = sizeof(DCB);
+ if (!BuildCommDCBA("baud=9600 data=8 parity=N stop=1",&sp->dcb)) {
+ uart_close(sp);
+ return INVALID_SERIAL_PORT;
+ }
+
+ // Update the active serial port
+ if (!SetCommState(sp->hPort,&sp->dcb)) {
+ uart_close(sp);
+ return INVALID_SERIAL_PORT;
+ }
+
+ sp->ct.ReadIntervalTimeout = 0;
+ sp->ct.ReadTotalTimeoutMultiplier = 0;
+ sp->ct.ReadTotalTimeoutConstant = 30;
+ sp->ct.WriteTotalTimeoutMultiplier = 0;
+ sp->ct.WriteTotalTimeoutConstant = 30;
+
+ if (!SetCommTimeouts(sp->hPort, &sp->ct)) {
+ uart_close(sp);
+ return INVALID_SERIAL_PORT;
+ }
+
+ PurgeComm(sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
+
+ return sp;
+}
+
+
bool uart_receive(const serial_port sp, uint8_t *pbtRx, size_t pszMaxRxLen, size_t *pszRxLen) {
- return ReadFile(((serial_port_windows*)sp)->hPort, pbtRx, pszMaxRxLen, (LPDWORD)pszRxLen, NULL);
+ return ReadFile(((serial_port_windows*)sp)->hPort, pbtRx, pszMaxRxLen, (LPDWORD)pszRxLen, NULL);
}
+
bool uart_send(const serial_port sp, const uint8_t* pbtTx, const size_t szTxLen) {
- DWORD dwTxLen = 0;
- return WriteFile(((serial_port_windows*)sp)->hPort, pbtTx, szTxLen, &dwTxLen, NULL);
+ DWORD dwTxLen = 0;
+ return WriteFile(((serial_port_windows*)sp)->hPort, pbtTx, szTxLen, &dwTxLen, NULL);
}
+
bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) {
- serial_port_windows* spw;
- spw = (serial_port_windows*)sp;
- spw->dcb.BaudRate = uiPortSpeed;
- return SetCommState(spw->hPort, &spw->dcb);
+ serial_port_windows* spw;
+ spw = (serial_port_windows*)sp;
+ spw->dcb.BaudRate = uiPortSpeed;
+ return SetCommState(spw->hPort, &spw->dcb);
}
+
uint32_t uart_get_speed(const serial_port sp) {
- const serial_port_windows* spw = (serial_port_windows*)sp;
- if (!GetCommState(spw->hPort, (serial_port)&spw->dcb)) {
- return spw->dcb.BaudRate;
- }
- return 0;
+ const serial_port_windows* spw = (serial_port_windows*)sp;
+ if (!GetCommState(spw->hPort, (serial_port)&spw->dcb)) {
+ return spw->dcb.BaudRate;
+ }
+ return 0;
}
#endif