// this function implements the CDCACM usb setup control transfer.
static int
cdcacm_control_transfer(struct setup *setup, byte *buffer, int length)
{
#if SODEBUG
    if ((setup->requesttype & 0x60) != (SETUP_TYPE_CLASS<<5)) {
        return 0;
    }
    if ((setup->requesttype & 0x1f) != (SETUP_RECIP_INTERFACE<<0)) {
        return 0;
    }
    if (setup->index != 0 /*comm*/) {
        return 0;
    }
#endif
    switch(setup->request) {
        case CDCRQ_SEND_ENCAPSULATED_COMMAND:
            assert(! (setup->requesttype & 0x80));
            length = 0;
            break;
        case CDCRQ_GET_ENCAPSULATED_RESPONSE:
            assert(setup->requesttype & 0x80);
            assert(length <= 64);
            ilmemset(buffer, 0, length);
            break;
        case CDCRQ_SET_LINE_CODING:
            assert(! (setup->requesttype & 0x80));
            assert(length == sizeof(line_coding));
            ilmemcpy(line_coding, buffer, sizeof(line_coding));
            length = 0;
            break;
        case CDCRQ_GET_LINE_CODING:
            assert(setup->requesttype & 0x80);
            assert(length == sizeof(line_coding));
            ilmemcpy(buffer, line_coding, sizeof(line_coding));
            break;
        case CDCRQ_SET_CONTROL_LINE_STATE:
            assert(! (setup->requesttype & 0x80));
            length = 0;
            break;
        case CDCRQ_SEND_BREAK:
            length = 0;
            break;
        default:
            assert(0);
            length = 0;
            break;
    }
    
    return length;
}
// this function implements the CDCACM usb setup control transfer.
static int
cdcacm_control_transfer(struct setup *setup, byte *buffer, int length)
{
#if SODEBUG
    if ((setup->requesttype & 0x60) != (SETUP_TYPE_CLASS<<5)) {
        return 0;
    }
    if ((setup->requesttype & 0x1f) != (SETUP_RECIP_INTERFACE<<0)) {
        return 0;
    }
    if (setup->index != 0 /*comm*/) {
        return 0;
    }
#endif
    switch(setup->request) {
        case CDCRQ_SEND_ENCAPSULATED_COMMAND:
            assert(! (setup->requesttype & 0x80));
            length = 0;
            break;
        case CDCRQ_GET_ENCAPSULATED_RESPONSE:
            assert(setup->requesttype & 0x80);
            assert(length <= 64);
            ilmemset(buffer, 0, length);
            break;
        case CDCRQ_SET_LINE_CODING:
            assert(! (setup->requesttype & 0x80));
            assert(length == sizeof(line_coding));
            ilmemcpy(line_coding, buffer, sizeof(line_coding));
            length = 0;
            break;
        case CDCRQ_GET_LINE_CODING:
            assert(setup->requesttype & 0x80);
            assert(length == sizeof(line_coding));
            ilmemcpy(buffer, line_coding, sizeof(line_coding));
            break;
        case CDCRQ_SET_CONTROL_LINE_STATE:
            assert(! (setup->requesttype & 0x80));
			// We can sense RTS and DTR here, that's it.
			// Bit 0 of setup->value is the state of DTR, and
			// bit 1 is the state of RTS.
//			if (setup->value & 0x01) {
//				TRISDbits.TRISD0 = 0;
//				PORTDbits.RD0 = 1;
//			}
//			else {
//				TRISDbits.TRISD0 = 0;
//				PORTDbits.RD0 = 0;
//			}
//			if (setup->value & 0x02) {
//				TRISDbits.TRISD1 = 0;
//				PORTDbits.RD1 = 1;
//			}
//			else {
//				TRISDbits.TRISD1 = 0;
//				PORTDbits.RD1 = 0;
//			}
            length = 0;
            break;
        case CDCRQ_SEND_BREAK:
            length = 0;
            break;
        default:
            assert(0);
            length = 0;
            break;
    }
    
    return length;
}