BOOL handle_vendorcommand(BYTE cmd) { BYTE request_type = SETUPDAT[0]; BYTE subcommand = SETUPDAT[2]; BYTE command = SETUPDAT[3]; BOOL direction_in = (request_type & bmREQUESTTYPE_DIRECTION) == REQUESTTYPE_DIRECTION_IN; WORD data_length = ((WORD *) SETUPDAT)[3]; if (config != CONFIG_CONFIGURED || cmd != VENDOR_COMMAND || (request_type & (bmREQUESTTYPE_TYPE | bmREQUESTTYPE_RECIPIENT)) != (REQUESTTYPE_TYPE_VENDOR | REQUESTTYPE_RECIPIENT_DEVICE)) { return FALSE; } #if 0 /* Useful for debugging from host */ if (command == COMMAND_MEMORY) { __xdata BYTE * buf = EP0BUF; BYTE count = LSB(data_length); if (data_length > 64) return FALSE; switch (subcommand) { case COMMAND_MEMORY_INTERNAL: { __data BYTE *ram = (__data BYTE *) SETUPDAT[4]; if (SETUPDAT[5]) return FALSE; if (direction_in) { while (count--) { *buf++ = *ram++; } EP0BCH = SETUPDAT[7]; SYNCDELAY; EP0BCL = SETUPDAT[6]; SYNCDELAY; } else { while (count--) { *ram++ = *buf++; } } return TRUE; } case COMMAND_MEMORY_EXTERNAL: { __xdata BYTE *ram = (__xdata BYTE *) ((WORD *) SETUPDAT)[2]; if (direction_in) { while (count--) { *buf++ = *ram++; } EP0BCH = SETUPDAT[7]; SYNCDELAY; EP0BCL = SETUPDAT[6]; SYNCDELAY; } else { while (count--) { *ram++ = *buf++; } } return TRUE; } case COMMAND_MEMORY_CODE: { __code BYTE *ram = (__code BYTE *) ((WORD *) SETUPDAT)[2]; if (direction_in) { while (count--) { *buf++ = *ram++; } EP0BCH = SETUPDAT[7]; SYNCDELAY; EP0BCL = SETUPDAT[6]; SYNCDELAY; } else { return FALSE; } return TRUE; } default: return FALSE; } } #endif switch (fpga_configure_running) { case FALSE: switch (direction_in) { case FALSE: if (data_length) { return FALSE; } switch (command) { case COMMAND_FPGA: switch (subcommand) { case COMMAND_FPGA_CONFIGURE_START: FPGAConfigureStart(); fpga_configure_running = TRUE; break; default: return FALSE; } break; /* XXX: Would it be more appropriate to make these per-endpoint instead ? */ case COMMAND_STOP: CommandStop(); break; case COMMAND_PAUSE: CommandPause(subcommand); break; default: return FALSE; } break; case TRUE: switch (command) { case COMMAND_STATUS: if (data_length != 1) { return FALSE; } EP0BUF[0] = CommandStatus(); EP0BCH = 0x00; SYNCDELAY; EP0BCL = 0x01; SYNCDELAY; break; default: return FALSE; } break; } break; case TRUE: switch (direction_in) { case FALSE: switch (command) { case COMMAND_FPGA: switch (subcommand) { case COMMAND_FPGA_CONFIGURE_START: if (data_length) { return FALSE; } FPGAConfigureStart(); fpga_configure_running = TRUE; break; case COMMAND_FPGA_CONFIGURE_WRITE: if (!data_length) { return FALSE; } while (data_length) { BYTE received; EP0BCL = 0; /* arm endpoint */ while (EP01STAT & bmEP0BSY); received = EP0BCL; if (received > data_length || FPGAConfigureWrite(EP0BUF, received)) { return FALSE; } data_length -= received; } break; case COMMAND_FPGA_CONFIGURE_STOP: if (data_length) { return FALSE; } fpga_configure_running = FALSE; FPGAConfigureStop(); break; default: return FALSE; } break; default: return FALSE; } break; case TRUE: return FALSE; break; } break; } return TRUE; }
extern "C" jobject Java_com_rtmpd_CommandsInterface_CommandPause( JNIEnv* pEnv, jobject thiz, jint contextId) { Variant result = CommandPause((uint32_t) contextId); return VariantToJObject(result, pEnv); }