more impl.
This commit is contained in:
@@ -78,7 +78,7 @@ CSRC = $(PORTSRC) \
|
|||||||
$(CHIBIOS)/os/various/syscalls.c \
|
$(CHIBIOS)/os/various/syscalls.c \
|
||||||
$(STMUSBSRC) \
|
$(STMUSBSRC) \
|
||||||
$(USBCDCSRC) \
|
$(USBCDCSRC) \
|
||||||
main.c hw_config.c usb_lld.c usb_desc.c usb_prop.c usb.c
|
main.c hw_config.c usb_lld.c usb_desc.c usb_prop.c usb-icc.c gpg.c
|
||||||
|
|
||||||
# List ASM source files here
|
# List ASM source files here
|
||||||
ASMSRC = $(PORTASM) \
|
ASMSRC = $(PORTASM) \
|
||||||
|
|||||||
9
src/gnuk.h
Normal file
9
src/gnuk.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
extern Thread *blinker_thread;
|
||||||
|
extern Thread *icc_thread;
|
||||||
|
extern Thread *gpg_thread;
|
||||||
|
|
||||||
|
#define EV_EXEC_FINISHED (eventmask_t)2 /* GPG Execution finished */
|
||||||
|
|
||||||
|
#define put_string(STR)
|
||||||
|
|
||||||
|
extern void _write (char *, int);
|
||||||
73
src/gpg.c
73
src/gpg.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* gpg.c --
|
* gpg.c -- OpenPGP card protocol support
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010 Free Software Initiative of Japan
|
* Copyright (C) 2010 Free Software Initiative of Japan
|
||||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
@@ -21,7 +21,11 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define RSA_SIGNATURE_LENGTH 128 /* 128 byte == 1024-bit */
|
#include "ch.h"
|
||||||
|
#include "hal.h"
|
||||||
|
#include "gnuk.h"
|
||||||
|
|
||||||
|
#define RSA_SIGNATURE_LENGTH 256 /* 256 byte == 2048-bit */
|
||||||
extern unsigned char *rsa_sign (unsigned char *);
|
extern unsigned char *rsa_sign (unsigned char *);
|
||||||
|
|
||||||
#define INS_PUT_DATA 0xDA
|
#define INS_PUT_DATA 0xDA
|
||||||
@@ -207,19 +211,20 @@ const char const do_5f50[] =
|
|||||||
* 6e L-6e [47 3 x x x ] [4f L-4f ...] [c0 L-c0 ...] ...
|
* 6e L-6e [47 3 x x x ] [4f L-4f ...] [c0 L-c0 ...] ...
|
||||||
* 7a L-7a [93 L-93 ... ]
|
* 7a L-7a [93 L-93 ... ]
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
|
|
||||||
static byte
|
static byte
|
||||||
process_command_adpu (void)
|
process_command_adpu (void)
|
||||||
{
|
{
|
||||||
if (icc_read_buf[1] == INS_GET_RESPONSE)
|
if (icc_read_buf[1] == INS_GET_RESPONSE)
|
||||||
{
|
{
|
||||||
stx_put_string (" - GET Response\r\n");
|
put_string (" - GET Response\r\n");
|
||||||
|
|
||||||
if ((icc_result_flag & ICC_RESULT_BUF))
|
if ((icc_result_flag & ICC_RESULT_BUF))
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stx_put_string ("Wrong GET Response\r\n");
|
put_string ("Wrong GET Response\r\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -239,7 +244,7 @@ INS_VERIFY
|
|||||||
|
|
||||||
if (icc_read_buf[1] == INS_PUT_DATA)
|
if (icc_read_buf[1] == INS_PUT_DATA)
|
||||||
{
|
{
|
||||||
stx_put_string (" - PUT DATA\r\n");
|
put_string (" - PUT DATA\r\n");
|
||||||
icc_result_value = 0x9000; /* 6a88: No record */
|
icc_result_value = 0x9000; /* 6a88: No record */
|
||||||
icc_result_len = 0;
|
icc_result_len = 0;
|
||||||
icc_result_flag = 0;
|
icc_result_flag = 0;
|
||||||
@@ -248,7 +253,7 @@ INS_VERIFY
|
|||||||
|
|
||||||
if (icc_read_buf[1] == INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR)
|
if (icc_read_buf[1] == INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR)
|
||||||
{
|
{
|
||||||
stx_put_string (" - Generate Asymmetric Key Pair\r\n");
|
put_string (" - Generate Asymmetric Key Pair\r\n");
|
||||||
|
|
||||||
if (icc_read_buf[2] == 0x81)
|
if (icc_read_buf[2] == 0x81)
|
||||||
{
|
{
|
||||||
@@ -346,7 +351,7 @@ INS_VERIFY
|
|||||||
}
|
}
|
||||||
else if (icc_read_buf[1] == INS_READ_BINARY)
|
else if (icc_read_buf[1] == INS_READ_BINARY)
|
||||||
{ /* it must be for DF 0x2f02 */
|
{ /* it must be for DF 0x2f02 */
|
||||||
stx_put_string (" - Read binary\r\n");
|
put_string (" - Read binary\r\n");
|
||||||
|
|
||||||
if (icc_read_buf[3] >= 6)
|
if (icc_read_buf[3] >= 6)
|
||||||
{
|
{
|
||||||
@@ -369,7 +374,7 @@ INS_VERIFY
|
|||||||
{
|
{
|
||||||
if (icc_read_buf[2] == 4) /* Selection by DF name */
|
if (icc_read_buf[2] == 4) /* Selection by DF name */
|
||||||
{
|
{
|
||||||
stx_put_string (" - select DF by name\r\n");
|
put_string (" - select DF by name\r\n");
|
||||||
/*
|
/*
|
||||||
* XXX: Should return contents.
|
* XXX: Should return contents.
|
||||||
*/
|
*/
|
||||||
@@ -385,7 +390,7 @@ INS_VERIFY
|
|||||||
&& icc_read_buf[5] == 0x2f
|
&& icc_read_buf[5] == 0x2f
|
||||||
&& icc_read_buf[6] == 02)
|
&& icc_read_buf[6] == 02)
|
||||||
{
|
{
|
||||||
stx_put_string (" - select 0x2f02 EF\r\n");
|
put_string (" - select 0x2f02 EF\r\n");
|
||||||
/*
|
/*
|
||||||
* MF.EF-GDO -- Serial number of the card and name of the owner
|
* MF.EF-GDO -- Serial number of the card and name of the owner
|
||||||
*/
|
*/
|
||||||
@@ -398,7 +403,7 @@ INS_VERIFY
|
|||||||
&& icc_read_buf[5] == 0x3f
|
&& icc_read_buf[5] == 0x3f
|
||||||
&& icc_read_buf[6] == 0)
|
&& icc_read_buf[6] == 0)
|
||||||
{
|
{
|
||||||
stx_put_string (" - select ROOT MF\r\n");
|
put_string (" - select ROOT MF\r\n");
|
||||||
if (icc_read_buf[3] == 0x0c)
|
if (icc_read_buf[3] == 0x0c)
|
||||||
{
|
{
|
||||||
icc_result_value = 0x9000;
|
icc_result_value = 0x9000;
|
||||||
@@ -414,7 +419,7 @@ INS_VERIFY
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stx_put_string (" - select ?? \r\n");
|
put_string (" - select ?? \r\n");
|
||||||
|
|
||||||
icc_result_value = 0x6a82; /* File missing */
|
icc_result_value = 0x6a82; /* File missing */
|
||||||
icc_result_len = 0;
|
icc_result_len = 0;
|
||||||
@@ -423,7 +428,7 @@ INS_VERIFY
|
|||||||
}
|
}
|
||||||
else if (icc_read_buf[1] == INS_GET_DATA)
|
else if (icc_read_buf[1] == INS_GET_DATA)
|
||||||
{
|
{
|
||||||
stx_put_string (" - Get Data\r\n");
|
put_string (" - Get Data\r\n");
|
||||||
|
|
||||||
switch (((icc_read_buf[2]<<8) | icc_read_buf[3]))
|
switch (((icc_read_buf[2]<<8) | icc_read_buf[3]))
|
||||||
{
|
{
|
||||||
@@ -535,12 +540,12 @@ INS_VERIFY
|
|||||||
}
|
}
|
||||||
else if (icc_read_buf[1] == INS_PSO)
|
else if (icc_read_buf[1] == INS_PSO)
|
||||||
{
|
{
|
||||||
stx_put_string (" - PSO\r\n");
|
put_string (" - PSO\r\n");
|
||||||
|
|
||||||
if (icc_read_buf[2] == 0x9E && icc_read_buf[3] == 0x9A)
|
if (icc_read_buf[2] == 0x9E && icc_read_buf[3] == 0x9A)
|
||||||
{
|
{
|
||||||
if (icc_read_len != 5 + 35 && icc_read_len != 5 + 35 + 1)
|
if (icc_read_len != 5 + 35 && icc_read_len != 5 + 35 + 1)
|
||||||
stx_put_string (" wrong length\r\n");
|
put_string (" wrong length\r\n");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
icc_result_value = rsa_sign (&icc_read_buf[5]);
|
icc_result_value = rsa_sign (&icc_read_buf[5]);
|
||||||
@@ -548,11 +553,11 @@ INS_VERIFY
|
|||||||
icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_RAM;
|
icc_result_flag = ICC_RESULT_BUF | ICC_RESULT_BUF_RAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
stx_put_string ("done.\r\n");
|
put_string ("done.\r\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stx_put_string (" - ???\r\n");
|
put_string (" - ???\r\n");
|
||||||
icc_result_value = 0x9000;
|
icc_result_value = 0x9000;
|
||||||
icc_result_len = 0;
|
icc_result_len = 0;
|
||||||
icc_result_flag = 0;
|
icc_result_flag = 0;
|
||||||
@@ -560,7 +565,7 @@ INS_VERIFY
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stx_put_string (" - ???\r\n");
|
put_string (" - ???\r\n");
|
||||||
icc_result_value = 0x9000;
|
icc_result_value = 0x9000;
|
||||||
icc_result_len = 0;
|
icc_result_len = 0;
|
||||||
icc_result_flag = 0;
|
icc_result_flag = 0;
|
||||||
@@ -568,3 +573,37 @@ INS_VERIFY
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Thread *gpg_thread;
|
||||||
|
|
||||||
|
msg_t
|
||||||
|
GPGthread (void *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
gpg_thread = chThdSelf ();
|
||||||
|
chEvtClear (ALL_EVENTS);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
eventmask_t m;
|
||||||
|
|
||||||
|
m = chEvtWaitOne (ALL_EVENTS);
|
||||||
|
|
||||||
|
_write ("GPG!\r\n", 6);
|
||||||
|
#if 0
|
||||||
|
receive_command_adpu ();
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
|
process_command_adpu ();
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
|
send_result_adpu ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
chEvtSignal (icc_thread, EV_EXEC_FINISHED);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
24
src/main.c
24
src/main.c
@@ -35,18 +35,22 @@
|
|||||||
#include "hw_config.h"
|
#include "hw_config.h"
|
||||||
#include "usb_pwr.h"
|
#include "usb_pwr.h"
|
||||||
|
|
||||||
|
Thread *blinker_thread;
|
||||||
/*
|
/*
|
||||||
* Red LEDs blinker thread, times are in milliseconds.
|
* Red LEDs blinker thread, times are in milliseconds.
|
||||||
*/
|
*/
|
||||||
static WORKING_AREA(waThread1, 128);
|
static WORKING_AREA(waThread1, 128);
|
||||||
static msg_t Thread1(void *arg) {
|
static msg_t
|
||||||
|
Thread1 (void *arg)
|
||||||
|
{
|
||||||
(void)arg;
|
(void)arg;
|
||||||
while (TRUE) {
|
blinker_thread = chThdSelf ();
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
palClearPad (IOPORT3, GPIOC_LED);
|
palClearPad (IOPORT3, GPIOC_LED);
|
||||||
chThdSleepMilliseconds (1000);
|
chEvtWaitOne (ALL_EVENTS);
|
||||||
palSetPad (IOPORT3, GPIOC_LED);
|
palSetPad (IOPORT3, GPIOC_LED);
|
||||||
chThdSleepMilliseconds (1000);
|
chEvtWaitOne (ALL_EVENTS);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -160,8 +164,11 @@ static msg_t Thread2 (void *arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static WORKING_AREA(waUSBThread, 128*2);
|
static WORKING_AREA(waUSBthread, 128*2);
|
||||||
extern msg_t USBThread (void *arg);
|
extern msg_t USBthread (void *arg);
|
||||||
|
|
||||||
|
static WORKING_AREA(waGPGthread, 128*4);
|
||||||
|
extern msg_t GPGthread (void *arg);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Entry point, note, the main() function is already a thread in the system
|
* Entry point, note, the main() function is already a thread in the system
|
||||||
@@ -188,7 +195,8 @@ int main(int argc, char **argv)
|
|||||||
*/
|
*/
|
||||||
chThdCreateStatic (waThread2, sizeof(waThread2), NORMALPRIO, Thread2, NULL);
|
chThdCreateStatic (waThread2, sizeof(waThread2), NORMALPRIO, Thread2, NULL);
|
||||||
|
|
||||||
chThdCreateStatic (waUSBThread, sizeof(waUSBThread), NORMALPRIO, USBThread, NULL);
|
chThdCreateStatic (waUSBthread, sizeof(waUSBthread), NORMALPRIO, USBthread, NULL);
|
||||||
|
chThdCreateStatic (waGPGthread, sizeof(waGPGthread), NORMALPRIO, GPGthread, NULL);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* usb.c --
|
* usb-icc.c -- USB CCID/ICCD protocol handling
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010 Free Software Initiative of Japan
|
* Copyright (C) 2010 Free Software Initiative of Japan
|
||||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
@@ -24,31 +24,42 @@
|
|||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
|
|
||||||
|
#include "gnuk.h"
|
||||||
|
|
||||||
#include "usb_lib.h"
|
#include "usb_lib.h"
|
||||||
#include "usb_desc.h"
|
#include "usb_desc.h"
|
||||||
#include "usb_mem.h"
|
#include "usb_mem.h"
|
||||||
#include "hw_config.h"
|
#include "hw_config.h"
|
||||||
#include "usb_istr.h"
|
#include "usb_istr.h"
|
||||||
|
|
||||||
Mutex icc_in_mutex;
|
|
||||||
|
|
||||||
static uint8_t icc_buffer_out[64];
|
static uint8_t icc_buffer_out[64];
|
||||||
static uint8_t icc_buffer_in[64];
|
static uint8_t icc_buffer_in[64];
|
||||||
|
|
||||||
static __IO uint32_t icc_count_out = 0;
|
static __IO uint32_t icc_count_out = 0;
|
||||||
static uint32_t icc_count_in = 0;
|
static uint32_t icc_count_in = 0;
|
||||||
|
|
||||||
|
Thread *icc_thread;
|
||||||
|
|
||||||
|
#define EV_RX_DATA_READY (eventmask_t)1 /* USB Rx data available */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tx done
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
EP4_IN_Callback(void)
|
EP4_IN_Callback (void)
|
||||||
{
|
{
|
||||||
icc_count_in = 0;
|
icc_count_in = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Rx data
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
EP5_OUT_Callback(void)
|
EP5_OUT_Callback (void)
|
||||||
{
|
{
|
||||||
/* Get the received data buffer and update the counter */
|
/* Get the received data buffer and update the counter */
|
||||||
icc_count_out = USB_SIL_Read (EP5_OUT, icc_buffer_out);
|
icc_count_out = USB_SIL_Read (EP5_OUT, icc_buffer_out);
|
||||||
|
chEvtSignalI (icc_thread, EV_RX_DATA_READY);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ICC_POWER_ON 0x62
|
#define ICC_POWER_ON 0x62
|
||||||
@@ -168,32 +179,31 @@ HW_ERROR 0xFB The USB-ICC detected a hardware error.
|
|||||||
|
|
||||||
all others Reserved for future use
|
all others Reserved for future use
|
||||||
(0x80 and those filling the gaps)
|
(0x80 and those filling the gaps)
|
||||||
|
|
||||||
extern const uchar *icc_power_on (void);
|
|
||||||
extern byte icc_get_status (void);
|
|
||||||
|
|
||||||
|
|
||||||
PC_to_RDR_IccPowerOff
|
|
||||||
RDR_to_PC_SlotStatus
|
|
||||||
|
|
||||||
PC_to_RDR_IccPowerOn
|
|
||||||
RDR_to_PC_DataBlock
|
|
||||||
|
|
||||||
PC_to_RDR_XfrBlock
|
|
||||||
RDR_to_PC_DataBlock
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum icc_state
|
||||||
|
{
|
||||||
|
ICC_STATE_START, /* Initial */
|
||||||
|
ICC_STATE_WAIT, /* Waiting ADPU */
|
||||||
|
/* Busy1, Busy2, Busy3, Busy5 */
|
||||||
|
ICC_STATE_EXECUTE, /* Busy4 */
|
||||||
|
ICC_STATE_RECEIVE, /* ADPU Received Partially */
|
||||||
|
ICC_STATE_SEND /* ADPU Sent Partially */
|
||||||
|
};
|
||||||
|
|
||||||
|
static enum icc_state icc_state;
|
||||||
|
|
||||||
/* Direct conversion, T=1, "FSIJ" */
|
/* Direct conversion, T=1, "FSIJ" */
|
||||||
static const char ATR[] = { '\x3B', '\x84', '\x01', 'F', 'S', 'I', 'J' };
|
static const char ATR[] = { '\x3B', '\x84', '\x01', 'F', 'S', 'I', 'J' };
|
||||||
|
|
||||||
void
|
/* Send back ATR (Answer To Reset) */
|
||||||
|
enum icc_state
|
||||||
icc_power_on (char *buf, int len)
|
icc_power_on (char *buf, int len)
|
||||||
{
|
{
|
||||||
int i, size_atr;
|
int i, size_atr;
|
||||||
|
|
||||||
size_atr = sizeof (ATR);
|
size_atr = sizeof (ATR);
|
||||||
|
|
||||||
chMtxLock (&icc_in_mutex);
|
|
||||||
icc_buffer_in[0] = 0x80;
|
icc_buffer_in[0] = 0x80;
|
||||||
icc_buffer_in[1] = size_atr;
|
icc_buffer_in[1] = size_atr;
|
||||||
/* not including '\0' at the end */
|
/* not including '\0' at the end */
|
||||||
@@ -212,16 +222,14 @@ icc_power_on (char *buf, int len)
|
|||||||
|
|
||||||
USB_SIL_Write (EP4_IN, icc_buffer_in, icc_count_in);
|
USB_SIL_Write (EP4_IN, icc_buffer_in, icc_count_in);
|
||||||
SetEPTxValid (ENDP4);
|
SetEPTxValid (ENDP4);
|
||||||
chMtxUnlock ();
|
|
||||||
|
|
||||||
_write ("ON\r\n", 4);
|
_write ("ON\r\n", 4);
|
||||||
|
return ICC_STATE_WAIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
icc_power_off (char *buf, int len)
|
icc_send_status (char *buf, int len)
|
||||||
{
|
{
|
||||||
chMtxLock (&icc_in_mutex);
|
|
||||||
|
|
||||||
icc_buffer_in[0] = 0x81;
|
icc_buffer_in[0] = 0x81;
|
||||||
icc_buffer_in[1] = 0x00;
|
icc_buffer_in[1] = 0x00;
|
||||||
icc_buffer_in[2] = 0x00;
|
icc_buffer_in[2] = 0x00;
|
||||||
@@ -229,56 +237,212 @@ icc_power_off (char *buf, int len)
|
|||||||
icc_buffer_in[4] = 0x00;
|
icc_buffer_in[4] = 0x00;
|
||||||
icc_buffer_in[5] = 0x00; /* Slot */
|
icc_buffer_in[5] = 0x00; /* Slot */
|
||||||
icc_buffer_in[ICC_MSG_SEQ_OFFSET] = buf[ICC_MSG_SEQ_OFFSET];
|
icc_buffer_in[ICC_MSG_SEQ_OFFSET] = buf[ICC_MSG_SEQ_OFFSET];
|
||||||
icc_buffer_in[ICC_MSG_STATUS_OFFSET] = 0x00;
|
if (icc_state == ICC_STATE_START)
|
||||||
|
icc_buffer_in[ICC_MSG_STATUS_OFFSET] = 2; /* No ICC present */
|
||||||
|
else
|
||||||
|
icc_buffer_in[ICC_MSG_STATUS_OFFSET] = 0; /* An ICC is present and active */
|
||||||
icc_buffer_in[ICC_MSG_ERROR_OFFSET] = 0x00;
|
icc_buffer_in[ICC_MSG_ERROR_OFFSET] = 0x00;
|
||||||
icc_buffer_in[9] = 0x00;
|
icc_buffer_in[9] = 0x00;
|
||||||
|
|
||||||
icc_count_in = 10;
|
icc_count_in = 10;
|
||||||
USB_SIL_Write (EP4_IN, icc_buffer_in, icc_count_in);
|
USB_SIL_Write (EP4_IN, icc_buffer_in, icc_count_in);
|
||||||
SetEPTxValid (ENDP4);
|
SetEPTxValid (ENDP4);
|
||||||
chMtxUnlock ();
|
|
||||||
|
|
||||||
_write ("OFF\r\n", 5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
msg_t
|
enum icc_state
|
||||||
USBThread (void *arg)
|
icc_power_off (char *buf, int len)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
icc_send_status (buf, len);
|
||||||
|
_write ("OFF\r\n", 5);
|
||||||
|
return ICC_STATE_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum icc_state
|
||||||
|
icc_handle_data (void)
|
||||||
|
{
|
||||||
|
enum icc_state next_state = icc_state;
|
||||||
|
|
||||||
|
#if 1
|
||||||
char b[3];
|
char b[3];
|
||||||
|
|
||||||
chMtxInit (&icc_in_mutex);
|
|
||||||
|
|
||||||
while (TRUE)
|
|
||||||
{
|
|
||||||
while (icc_count_out == 0)
|
|
||||||
chThdSleepMilliseconds (1);
|
|
||||||
|
|
||||||
b[0] = icc_buffer_out[0];
|
b[0] = icc_buffer_out[0];
|
||||||
b[1] = '\r';
|
b[1] = '\r';
|
||||||
b[2] = '\n';
|
b[2] = '\n';
|
||||||
|
|
||||||
_write (b, 3);
|
_write (b, 3);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (icc_state)
|
||||||
|
{
|
||||||
|
case ICC_STATE_START:
|
||||||
if (icc_buffer_out[0] == ICC_POWER_ON)
|
if (icc_buffer_out[0] == ICC_POWER_ON)
|
||||||
{
|
next_state = icc_power_on (icc_buffer_out, icc_count_out);
|
||||||
/* Send back ATR (Answer To Reset) */
|
else if (icc_buffer_out[0] == ICC_POWER_OFF)
|
||||||
icc_power_on (icc_buffer_out, icc_count_out);
|
next_state = icc_power_off (icc_buffer_out, icc_count_out);
|
||||||
}
|
else if (icc_buffer_out[0] == ICC_SLOT_STATUS)
|
||||||
else if (icc_buffer_out[0] == ICC_POWER_OFF
|
icc_send_status (icc_buffer_out, icc_count_out);
|
||||||
|| icc_buffer_out[0] == ICC_SLOT_STATUS)
|
else
|
||||||
{
|
{ /* XXX: error */
|
||||||
/* Kill ICC thread(s) and send back slot status */
|
_write ("ERR01\r\n", 7);
|
||||||
icc_power_off (icc_buffer_out, icc_count_out);
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case ICC_STATE_WAIT:
|
||||||
|
if (icc_buffer_out[0] == ICC_POWER_OFF)
|
||||||
|
next_state = icc_power_off (icc_buffer_out, icc_count_out);
|
||||||
|
else if (icc_buffer_out[0] == ICC_SLOT_STATUS)
|
||||||
|
icc_send_status (icc_buffer_out, icc_count_out);
|
||||||
else if (icc_buffer_out[0] == XFR_BLOCK)
|
else if (icc_buffer_out[0] == XFR_BLOCK)
|
||||||
{
|
{
|
||||||
/* Give this message to ICC thread */
|
if (icc_buffer_out[8] == 0 && icc_buffer_out[9] == 0)
|
||||||
|
{
|
||||||
|
/* Give this message to GPG thread */
|
||||||
|
next_state = ICC_STATE_EXECUTE;
|
||||||
|
chEvtSignal (gpg_thread, (eventmask_t)1);
|
||||||
|
}
|
||||||
|
else if (icc_buffer_out[8] == 1 && icc_buffer_out[9] == 0)
|
||||||
|
{
|
||||||
|
/* XXX: return back RDR_to_PC_DataBlock */
|
||||||
|
/* bChainParameter = 0x10, abData=empty */
|
||||||
|
next_state = ICC_STATE_RECEIVE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* XXX: error */;
|
||||||
|
_write ("ERR02\r\n", 7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* XXX: error */
|
||||||
|
_write ("ERR03\r\n", 7);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ICC_STATE_EXECUTE:
|
||||||
|
if (icc_buffer_out[0] == ICC_POWER_OFF)
|
||||||
|
{
|
||||||
|
/* XXX: Kill GPG thread */
|
||||||
|
next_state = icc_power_off (icc_buffer_out, icc_count_out);
|
||||||
|
}
|
||||||
|
else if (icc_buffer_out[0] == ICC_SLOT_STATUS)
|
||||||
|
icc_send_status (icc_buffer_out, icc_count_out);
|
||||||
|
else
|
||||||
|
{ /* XXX: error */
|
||||||
|
_write ("ERR04\r\n", 7);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ICC_STATE_RECEIVE:
|
||||||
|
if (icc_buffer_out[0] == ICC_POWER_OFF)
|
||||||
|
{
|
||||||
|
/* XXX: release partial ADPU received */
|
||||||
|
next_state = icc_power_off (icc_buffer_out, icc_count_out);
|
||||||
|
}
|
||||||
|
else if (icc_buffer_out[0] == ICC_SLOT_STATUS)
|
||||||
|
icc_send_status (icc_buffer_out, icc_count_out);
|
||||||
|
else if (icc_buffer_out[0] == XFR_BLOCK)
|
||||||
|
{
|
||||||
|
if (1 /* XXX */) /* Got final block */
|
||||||
|
{
|
||||||
|
/* Give this message to GPG thread */
|
||||||
|
next_state = ICC_STATE_EXECUTE;
|
||||||
|
chEvtSignal (gpg_thread, (eventmask_t)1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* XXX: error */
|
||||||
|
_write ("ERR05\r\n", 7);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ICC_STATE_SEND:
|
||||||
|
if (icc_buffer_out[0] == ICC_POWER_OFF)
|
||||||
|
{
|
||||||
|
/* XXX: release partial ADPU sending */
|
||||||
|
next_state = icc_power_off (icc_buffer_out, icc_count_out);
|
||||||
|
}
|
||||||
|
else if (icc_buffer_out[0] == ICC_SLOT_STATUS)
|
||||||
|
icc_send_status (icc_buffer_out, icc_count_out);
|
||||||
|
else if (icc_buffer_out[0] == XFR_BLOCK)
|
||||||
|
{
|
||||||
|
/* XXX: send back to data */
|
||||||
|
/* finished?, then go ICC_STATE_WAIT */
|
||||||
|
next_state = ICC_STATE_WAIT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* XXX: error */
|
||||||
|
_write ("ERR06\r\n", 7);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
icc_count_out = 0;
|
icc_count_out = 0;
|
||||||
SetEPRxValid (ENDP5);
|
SetEPRxValid (ENDP5);
|
||||||
|
return next_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum icc_state
|
||||||
|
icc_handle_timeout (void)
|
||||||
|
{
|
||||||
|
enum icc_state next_state = icc_state;
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* XXX: ICC_STATE_EXECUTE -> kill
|
||||||
|
* XXX: ICC_STATE_RECEIVE -> cancel
|
||||||
|
* XXX: ICC_STATE_SEND -> cancel
|
||||||
|
*/
|
||||||
|
if (icc_state == ICC_STATE_START
|
||||||
|
|| icc_state == ICC_STATE_WAIT)
|
||||||
|
;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
next_state = ICC_STATE_WAIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
chEvtSignal (blinker_thread, (eventmask_t)1);
|
||||||
|
return next_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define USB_ICC_TIMEOUT MS2ST(1000)
|
||||||
|
|
||||||
|
msg_t
|
||||||
|
USBthread (void *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
icc_thread = chThdSelf ();
|
||||||
|
chEvtClear (ALL_EVENTS);
|
||||||
|
|
||||||
|
icc_state = ICC_STATE_START;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
eventmask_t m;
|
||||||
|
|
||||||
|
m = chEvtWaitOneTimeout (ALL_EVENTS, USB_ICC_TIMEOUT);
|
||||||
|
|
||||||
|
if (m == EV_RX_DATA_READY)
|
||||||
|
icc_state = icc_handle_data ();
|
||||||
|
else if (m == EV_EXEC_FINISHED)
|
||||||
|
{
|
||||||
|
if (icc_state == ICC_STATE_EXECUTE)
|
||||||
|
{
|
||||||
|
if (1/* message is short enough*/)
|
||||||
|
{
|
||||||
|
/* XXX: send back result */;
|
||||||
|
icc_state = ICC_STATE_WAIT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* XXX: send back part of result */;
|
||||||
|
icc_state = ICC_STATE_SEND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* XXX: error */
|
||||||
|
_write ("ERR07\r\n", 7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* Timeout */
|
||||||
|
icc_state = icc_handle_timeout ();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -6,9 +6,11 @@ extern void USB_Istr (void);
|
|||||||
|
|
||||||
CH_IRQ_HANDLER (Vector90) {
|
CH_IRQ_HANDLER (Vector90) {
|
||||||
CH_IRQ_PROLOGUE();
|
CH_IRQ_PROLOGUE();
|
||||||
|
chSysLockFromIsr();
|
||||||
|
|
||||||
USB_Istr();
|
USB_Istr();
|
||||||
|
|
||||||
|
chSysUnlockFromIsr();
|
||||||
CH_IRQ_EPILOGUE();
|
CH_IRQ_EPILOGUE();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17,9 +19,9 @@ void usb_lld_init (void) {
|
|||||||
NVICEnableVector (USB_LP_CAN1_RX0_IRQn,
|
NVICEnableVector (USB_LP_CAN1_RX0_IRQn,
|
||||||
CORTEX_PRIORITY_MASK (STM32_USB_IRQ_PRIORITY));
|
CORTEX_PRIORITY_MASK (STM32_USB_IRQ_PRIORITY));
|
||||||
/*
|
/*
|
||||||
* Note that we also have other IRQs:
|
* Note that we also have other IRQ(s):
|
||||||
* USB_HP_CAN1_TX_IRQn
|
* USB_HP_CAN1_TX_IRQn (for double-buffered or isochronous)
|
||||||
* USBWakeUp_IRQn
|
* USBWakeUp_IRQn (suspend/resume)
|
||||||
*/
|
*/
|
||||||
RCC->APB1RSTR = RCC_APB1RSTR_USBRST;
|
RCC->APB1RSTR = RCC_APB1RSTR_USBRST;
|
||||||
RCC->APB1RSTR = 0;
|
RCC->APB1RSTR = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user