control_ret_t
control_read_command(control_resid_t resid, control_cmd_t cmd,
                     uint8_t payload[], size_t payload_len)
{
  unsigned b[XSCOPE_UPLOAD_MAX_WORDS];

  size_t len = control_xscope_create_upload_buffer(b,
    CONTROL_CMD_SET_READ(cmd), resid, NULL, payload_len);

  DBG(printf("%d: send read command: ", num_commands));
  DBG(print_bytes((unsigned char*)b, len));

  record_count = 0;

  if (xscope_ep_request_upload(len, (unsigned char*)b) != XSCOPE_EP_SUCCESS) {
    printf("xscope_ep_request_upload failed\n");
    return CONTROL_ERROR;
  }
  
  // wait for response on xSCOPE probe
  while (record_count == 0) {
    pause_short();
  }

  DBG(printf("response: "));
  DBG(print_bytes(last_response, last_response_length));

  // ignore returned payload length, use one supplied in request
  memcpy(payload, last_response + sizeof(struct control_xscope_response), payload_len);

  num_commands++;
  return CONTROL_SUCCESS + last_response_struct->ret;
}
control_ret_t
control_write_command(control_resid_t resid, control_cmd_t cmd,
                      const uint8_t payload[], size_t payload_len)
{
  unsigned b[XSCOPE_UPLOAD_MAX_WORDS];

  size_t len = control_xscope_create_upload_buffer(b,
    CONTROL_CMD_SET_WRITE(cmd), resid, payload, payload_len);

  if (upload_len_exceeds_xscope_limit(len))
    return CONTROL_DATA_LENGTH_ERROR;

  DBG(printf("%u: send write command: ", num_commands));
  DBG(print_bytes((unsigned char*)b, len));

  record_count = 0;

  if (xscope_ep_request_upload(len, (unsigned char*)b) != XSCOPE_EP_SUCCESS) {
    printf("xscope_ep_request_upload failed\n");
    return CONTROL_ERROR;
  }
  // wait for response on xSCOPE probe
  while (record_count == 0) { 
    pause_short();
  }

  DBG(printf("response: "));
  DBG(print_bytes(last_response, XSCOPE_HEADER_BYTES));

  num_commands++;
  return CONTROL_SUCCESS + last_response_struct->ret;
}
control_ret_t control_query_version(control_version_t *version)
{
  unsigned b[XSCOPE_UPLOAD_MAX_WORDS];

  size_t len = control_xscope_create_upload_buffer(b,
    CONTROL_GET_VERSION, CONTROL_SPECIAL_RESID, NULL, sizeof(control_version_t));

  DBG(printf("%d: send version command: ", num_commands));
  DBG(print_bytes((unsigned char*)b, len));

  record_count = 0;

  if (xscope_ep_request_upload(len, (unsigned char*)b) != XSCOPE_EP_SUCCESS) {
    printf("xscope_ep_request_upload failed\n");
    return CONTROL_ERROR;
  }
  
  // wait for response on xSCOPE probe
  while (record_count == 0) {
    pause_short();
  }

  DBG(printf("response: "));
  DBG(print_bytes(last_response, last_response_length));

  *version = *(control_version_t*)(last_response + sizeof(struct control_xscope_response));

  num_commands++;
  return CONTROL_SUCCESS + last_response_struct->ret;
}
void *console_thread(void *arg)
#endif
{
  int sockfd = *(int *)arg;
  char buffer[LINE_LENGTH + 1];
  do {
    int i = 0;
    int c = 0;

    printf("%s", g_prompt);
    for (i = 0; (i < LINE_LENGTH) && ((c = getchar()) != EOF) && (c != '\n'); i++)
      buffer[i] = tolower(c);
    buffer[i] = '\0';

    if (buffer[0] == 'q') {
      print_and_exit("Done\n");

    } else if (buffer[0] == 'e') {
      tester_command_t cmd = AVB_TESTER_EXPECT_NORMAL;
      if (get_next_char(&buffer[1]) == 'o')
        cmd = AVB_TESTER_EXPECT_OVERSUBSCRIBED;
      xscope_ep_request_upload(sockfd, 4, (unsigned char *)&cmd);

    } else if (buffer[0] == 'x') {
      tester_command_t cmd = AVB_TESTER_XSCOPE_PACKETS_DISABLE;
      if (get_next_char(&buffer[1]) == 'e')
        cmd = AVB_TESTER_XSCOPE_PACKETS_ENABLE;
      xscope_ep_request_upload(sockfd, 4, (unsigned char *)&cmd);

    } else if ((buffer[0] == 'h') || (buffer[0] == '?')) {
      print_console_usage();

    } else {
      printf("Unrecognised command '%s'\n", buffer);
      print_console_usage();
    }
  } while (1);

#ifdef _WIN32
  return 0;
#else
  return NULL;
#endif
}
JNIEXPORT void JNICALL Java_com_synapticon_somanetconnect_XscopeSocket_sendData
  (JNIEnv *env, jobject obj, jbyteArray data) {
	xscope_ep_request_upload((*env)->GetArrayLength(env, data), (*env)->GetByteArrayElements(env, data, NULL));
}