+COMMAND_HANDLER(jlink_handle_emucom_write_command)
+{
+ int ret;
+ size_t tmp;
+ uint32_t channel;
+ uint32_t length;
+ uint8_t *buf;
+ size_t dummy;
+
+ if (CMD_ARGC != 2)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_EMUCOM)) {
+ LOG_ERROR("Device does not support EMUCOM.");
+ return ERROR_FAIL;
+ }
+
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], channel);
+
+ tmp = strlen(CMD_ARGV[1]);
+
+ if (tmp % 2 != 0) {
+ LOG_ERROR("Data must be encoded as hexadecimal pairs.");
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+
+ buf = malloc(tmp / 2);
+
+ if (!buf) {
+ LOG_ERROR("Failed to allocate buffer.");
+ return ERROR_FAIL;
+ }
+
+ dummy = unhexify(buf, CMD_ARGV[1], tmp / 2);
+
+ if (dummy != (tmp / 2)) {
+ LOG_ERROR("Data must be encoded as hexadecimal pairs.");
+ free(buf);
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+
+ length = tmp / 2;
+ ret = jaylink_emucom_write(devh, channel, buf, &length);
+
+ free(buf);
+
+ if (ret == JAYLINK_ERR_DEV_NOT_SUPPORTED) {
+ LOG_ERROR("Channel not supported by the device.");
+ return ERROR_FAIL;
+ } else if (ret != JAYLINK_OK) {
+ LOG_ERROR("Failed to write to channel: %s.", jaylink_strerror(ret));
+ return ERROR_FAIL;
+ }
+
+ if (length != (tmp / 2))
+ LOG_WARNING("Only %" PRIu32 " bytes written to the channel.", length);
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(jlink_handle_emucom_read_command)
+{
+ int ret;
+ uint32_t channel;
+ uint32_t length;
+ uint8_t *buf;
+ size_t tmp;
+
+ if (CMD_ARGC != 2)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_EMUCOM)) {
+ LOG_ERROR("Device does not support EMUCOM.");
+ return ERROR_FAIL;
+ }
+
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], channel);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
+
+ buf = malloc(length * 3 + 1);
+
+ if (!buf) {
+ LOG_ERROR("Failed to allocate buffer.");
+ return ERROR_FAIL;
+ }
+
+ ret = jaylink_emucom_read(devh, channel, buf, &length);
+
+ if (ret == JAYLINK_ERR_DEV_NOT_SUPPORTED) {
+ LOG_ERROR("Channel is not supported by the device.");
+ free(buf);
+ return ERROR_FAIL;
+ } else if (ret == JAYLINK_ERR_DEV_NOT_AVAILABLE) {
+ LOG_ERROR("Channel is not available for the requested amount of data. "
+ "%" PRIu32 " bytes are avilable.", length);
+ free(buf);
+ return ERROR_FAIL;
+ } else if (ret != JAYLINK_OK) {
+ LOG_ERROR("Failed to read from channel: %s.", jaylink_strerror(ret));
+ free(buf);
+ return ERROR_FAIL;
+ }
+
+ tmp = hexify((char *)buf + length, buf, length, 2 * length + 1);
+
+ if (tmp != 2 * length) {
+ LOG_ERROR("Failed to convert data into hexadecimal string.");
+ free(buf);
+ return ERROR_FAIL;
+ }
+
+ command_print(CMD_CTX, "%s", buf + length);
+ free(buf);
+
+ return ERROR_OK;
+}
+