コード例 #1
0
ファイル: bridge.c プロジェクト: sonntam/obp-utils
//******************************************************************************
/// \brief Read MXT messages and send them to other end
/// \return #mxt_rc
static int handle_messages(struct mxt_device *mxt, int sockfd)
{
  int count, i;
  char *msg;
  int ret;

  ret = mxt_get_msg_count(mxt, &count);
  if (ret)
    return ret;

  if (count > 0) {
    for (i = 0; i < count; i++) {
      msg = mxt_get_msg_string(mxt);
      if (msg == NULL) {
        mxt_warn(mxt->ctx, "Failed to retrieve message");
        return MXT_SUCCESS;
      }

      ret = write(sockfd, msg, strlen(msg));
      if (ret < 0) {
        mxt_err(mxt->ctx, "Write failure: %s (%d)", strerror(errno), errno);
        return mxt_errno_to_rc(ret);
      }

      ret = write(sockfd, "\n", 1);
      if (ret < 0) {
        mxt_err(mxt->ctx, "Write failure: %s (%d)", strerror(errno), errno);
        return mxt_errno_to_rc(ret);
      }
    }
  }

  return MXT_SUCCESS;
}
コード例 #2
0
ファイル: sysfs_device.c プロジェクト: drxaero/mxt-app
//******************************************************************************
/// \brief  Get messages (V2 interface)
/// \param  mxt Device context
/// \param  count Number of messages retrieved
/// \return #mxt_rc
int sysfs_get_msgs_v2(struct mxt_device *mxt, int *count)
{
  int num_bytes;
  uint16_t t5_size;
  char *filename;
  struct stat filestat;
  int ret;
  int fd;

  sysfs_reopen_notify_fd(mxt);

  filename = make_path(mxt, "debug_msg");

  ret = stat(filename, &filestat);
  if (ret < 0) {
    mxt_err(mxt->ctx, "Could not stat %s, error %s (%d)",
            filename, strerror(errno), errno);
    return mxt_errno_to_rc(errno);
  }

  mxt->sysfs.debug_v2_size = filestat.st_size;

  if (mxt->sysfs.debug_v2_msg_buf) {
    free(mxt->sysfs.debug_v2_msg_buf);
    mxt->sysfs.debug_v2_msg_buf = NULL;
  }

  mxt->sysfs.debug_v2_msg_buf = calloc(mxt->sysfs.debug_v2_size, sizeof(uint8_t));

  fd = open(filename, O_RDWR);
  if (fd < 0) {
    mxt_err(mxt->ctx, "Could not open %s, error %s (%d)", filename, strerror(errno), errno);
    ret = mxt_errno_to_rc(errno);
    goto close;
  }

  t5_size = mxt_get_object_size(mxt, GEN_MESSAGEPROCESSOR_T5) - 1;

  num_bytes = read(fd, mxt->sysfs.debug_v2_msg_buf, mxt->sysfs.debug_v2_size);
  if (num_bytes < 0) {
    mxt_err(mxt->ctx, "read error %s (%d)", strerror(errno), errno);
    ret = mxt_errno_to_rc(errno);
    goto close;
  }

  mxt->sysfs.debug_v2_msg_count = num_bytes / t5_size;
  mxt->sysfs.debug_v2_msg_ptr = 0;

  ret = MXT_SUCCESS;
  *count = mxt->sysfs.debug_v2_msg_count;
  mxt_verb(mxt->ctx, "count = %d", mxt->sysfs.debug_v2_msg_count);

close:
  close(fd);
  return ret;
}
コード例 #3
0
ファイル: hidraw_device.c プロジェクト: aceyang1018/obp-utils
//******************************************************************************
/// \brief  Write packet to MXT chip
/// \return Number of databytes sent
static int hidraw_write_packet(struct mxt_device *mxt, struct hid_packet *write_pkt, uint8_t *byte_count)
{
  int ret;
  uint8_t pkt_size = write_pkt->rx_bytes + 4; /* allowing for header */

  if ((ret = write(mxt->conn->hidraw.fd, write_pkt, pkt_size)) != pkt_size) {
    mxt_verb(mxt->ctx, "HIDRAW retry");
    usleep(HIDRAW_WRITE_RETRY_DELAY_US);
    if ((ret = write(mxt->conn->hidraw.fd, &write_pkt, pkt_size)) != pkt_size) {
      mxt_err(mxt->ctx, "Error %s (%d) writing to hidraw",
              strerror(errno), errno);
      ret = mxt_errno_to_rc(errno);
    }
  }

  mxt_log_buffer(mxt->ctx, LOG_VERBOSE, "PKT TX:",
                 (const unsigned char *) write_pkt, pkt_size);

  *byte_count = ret - 6;

  mxt_dbg(mxt->ctx, "Sending packet: size: %d No. data bytes TX: %d",
          pkt_size, *byte_count);

  return MXT_SUCCESS;
}
コード例 #4
0
ファイル: sysinfo.c プロジェクト: prajoshpremdas/obp-utils
//******************************************************************************
/// \brief  Get system uptime in seconds since boot
int get_uptime(unsigned long *uptime)
{
  FILE *fp;
  int ret;
  unsigned long upsecs;
  char buf[64];
  char *b;

  fp = fopen("/proc/uptime", "r");
  if (!fp)
    return mxt_errno_to_rc(errno);

  b = fgets(buf, BUFSIZ, fp);
  if (b == buf)
  {
    /* The following sscanf must use the C locale.  */
    setlocale(LC_NUMERIC, "C");
    ret = sscanf(buf, "%lf", &upsecs);
    setlocale(LC_NUMERIC, "");
    if (ret == 1) {
      *uptime = upsecs;
      ret = MXT_SUCCESS;
    }
  }
  else
  {
    ret = MXT_ERROR_IO;
  }

  fclose(fp);

  return ret;
}
コード例 #5
0
//******************************************************************************
/// \brief  Read packet from MXT chip
/// \return #mxt_rc
static int hidraw_read_response(struct mxt_device *mxt, struct hid_packet *read_pkt,
                                size_t count)
{
  ssize_t ret = 0;
  size_t t_count = 0;
  int timeout = 0;

  do {
    ret = read(mxt->conn->hidraw.fd, read_pkt + t_count, count);
    if ((size_t)ret != count) {
      mxt_dbg(mxt->ctx, "Error %s (%d) reading from hidraw",
              strerror(errno), errno);
      ret = mxt_errno_to_rc(errno);
    } else {
      t_count += (size_t)ret;
    }
    usleep(HIDRAW_READ_RETRY_DELAY_US);
  } while (timeout++ <= HIDRAW_TIMEOUT_DELAY_US && t_count != count);

  mxt_dbg(mxt->ctx, "No. bytes requested: %zu, No. of bytes read: %zu",
          count, t_count);
  mxt_log_buffer(mxt->ctx, LOG_VERBOSE, "RD PKT RX:",
                 (const unsigned char *) read_pkt, count);
  return MXT_SUCCESS;
}
コード例 #6
0
ファイル: hidraw_device.c プロジェクト: aceyang1018/obp-utils
//******************************************************************************
/// \brief  Read register from MXT chip
/// \return #mxt_rc
int hidraw_read_register(struct mxt_device *mxt, unsigned char *buf, uint16_t start_register, int count)
{

  int ret;
  struct hid_packet read_pkt = { 0 };

  mxt_dbg(mxt->ctx, "%s - start_register:%d No. bytes requested:%d",
          __func__, start_register, count);

  ret = hidraw_open(mxt);
  if (ret)
    return ret;

  int bytes_read = 0;
  while (bytes_read < count) {
    ret = hidraw_read_packet(mxt, &read_pkt,
                             start_register + bytes_read,
                             (count - bytes_read <= MXT_HID_READ_DATA_SIZE ? count - bytes_read : MXT_HID_READ_DATA_SIZE));
    if (ret < 0) {
      mxt_dbg(mxt->ctx, "read error %s (%d)", strerror(errno), errno);
      ret = mxt_errno_to_rc(errno);
    }

    memcpy(buf + bytes_read, read_pkt.read_data, ret);

    bytes_read += ret;
  }

  close(mxt->conn->hidraw.fd);
  mxt->conn->hidraw.fd = 0;
  return MXT_SUCCESS;
}
コード例 #7
0
ファイル: sysfs_device.c プロジェクト: drxaero/mxt-app
//******************************************************************************
/// \brief  Read boolean from file as ASCII 0/1
/// \param  mxt Device context
/// \param  filename Name of file to read
/// \param  value Value read from file
/// \return #mxt_rc
static int read_boolean_file(struct mxt_device *mxt, char *filename,
                             bool *value)
{
  FILE *file;
  char val;
  bool ret;

  file = fopen(filename, "r");
  if (!file) {
    mxt_err(mxt->ctx, "Could not open %s, error %s (%d)", filename, strerror(errno), errno);
    return mxt_errno_to_rc(errno);
  }

  ret = fread(&val, sizeof(char), 1, file);
  if (ret < 0) {
    mxt_err(mxt->ctx, "Error reading files");
    return MXT_ERROR_IO;
  }

  if (val == 49) { // ASCII '0'
    *value = true;
  } else {
    *value = false;
  }

  fclose(file);

  return MXT_SUCCESS;
}
コード例 #8
0
ファイル: bridge.c プロジェクト: sub77-bkp/mxt-app
//******************************************************************************
/// \brief Read MXT messages and send them to other end
/// \return #mxt_rc
static int handle_messages(struct mxt_device *mxt, struct bridge_context *bridge_ctx)
{
  int msg_count, length;
  int ret;
  int i, j;

  unsigned char databuf[20];

  if (!bridge_ctx->msgs_enabled)
    return MXT_SUCCESS;

  ret = mxt_get_msg_count(mxt, &msg_count);
  if (ret)
    return ret;

  for (i = 0; i < msg_count; i++) {
    int num_bytes;
    ret = mxt_get_msg_bytes(mxt, databuf, sizeof(databuf), &num_bytes);
    if (ret == MXT_ERROR_NO_MESSAGE)
      continue;
    else if (ret)
      return ret;

    length = snprintf(mxt->msg_string, sizeof(mxt->msg_string),
                      MXT_ADB_CLIENT_MSG_PREFIX);

    for (j = 0; j < num_bytes; j++) {
      length += snprintf(mxt->msg_string + length,
                         sizeof(mxt->msg_string) - length,
                         "%02X", databuf[j]);
    }

    ret = write(bridge_ctx->sockfd, mxt->msg_string, strlen(mxt->msg_string));
    if (ret < 0) {
      mxt_err(mxt->ctx, "Write failure: %s (%d)", strerror(errno), errno);
      return mxt_errno_to_rc(ret);
    }

    ret = write(bridge_ctx->sockfd, "\n", 1);
    if (ret < 0) {
      mxt_err(mxt->ctx, "Write failure: %s (%d)", strerror(errno), errno);
      return mxt_errno_to_rc(ret);
    }
  }

  return MXT_SUCCESS;
}
コード例 #9
0
ファイル: bridge.c プロジェクト: sonntam/obp-utils
//******************************************************************************
/// \brief Handle bridge read
/// \return #mxt_rc
static int bridge_rea_cmd(struct mxt_device *mxt, int sockfd,
                          uint16_t address, uint16_t count)
{
  int ret;
  uint8_t *databuf;
  char *response;
  const char * const PREFIX = "RRP ";
  size_t response_len;
  int i;

  databuf = calloc(count, sizeof(uint8_t));
  if (!databuf) {
    mxt_err(mxt->ctx, "Failed to allocate memory");
    return MXT_ERROR_NO_MEM;
  }

  /* Allow for newline/null byte */
  response_len = strlen(PREFIX) + count*2 + 1;
  response = calloc(response_len, sizeof(uint8_t));
  if (!response) {
    mxt_err(mxt->ctx, "Failed to allocate memory");
    ret = MXT_ERROR_NO_MEM;
    goto free_databuf;
  }

  strcpy(response, PREFIX);
  ret = mxt_read_register(mxt, databuf, address, count);
  if (ret) {
    mxt_warn(mxt->ctx, "RRP ERR");
    strcpy(response + strlen(PREFIX), "ERR\n");
    response_len = strlen(response);
  } else {
    for (i = 0; i < count; i++) {
      sprintf(response + strlen(PREFIX) + i*2, "%02X", databuf[i]);
    }
    mxt_info(mxt->ctx, "%s", response);
    response[response_len - 1] = '\n';
  }

  ret = write(sockfd, response, response_len);
  if (ret < 0) {
    mxt_err(mxt->ctx, "Socket write error: %s (%d)", strerror(errno), errno);
    ret = mxt_errno_to_rc(errno);
    goto free;
  }

  ret = MXT_SUCCESS;

free:
  free(response);
free_databuf:
  free(databuf);
  return ret;
}
コード例 #10
0
ファイル: dmesg.c プロジェクト: drxaero/mxt-app
//******************************************************************************
/// \brief Allocate kernel log buffer
int dmesg_alloc_buffer(struct mxt_device *mxt)
{
  int size;

  size = klogctl(SYSLOG_ACTION_SIZE_BUFFER, NULL, 0);
  if (size == -1) {
    mxt_err(mxt->ctx, "klogctl error %d (%s)", errno, strerror(errno));
    return mxt_errno_to_rc(errno);
  }

  // Allocate buffer space
  mxt->sysfs.debug_msg_buf_size = size;
  mxt->sysfs.debug_msg_buf = (char *)calloc(size, sizeof(char));
  if (mxt->sysfs.debug_msg_buf == NULL) {
    mxt_err(mxt->ctx, "Error allocating debug_msg_buf");
    return mxt_errno_to_rc(errno);
  }

  return 0;
}
コード例 #11
0
ファイル: sysinfo.c プロジェクト: prajoshpremdas/obp-utils
//******************************************************************************
/// \brief  Get system uptime in seconds since boot
/// \return #mxt_rc
int get_uptime(unsigned long *uptime)
{
  int ret;
  struct sysinfo sys_info;

  ret = sysinfo(&sys_info);
  if (ret)
    return mxt_errno_to_rc(errno);

  *uptime = sys_info.uptime;
  return MXT_SUCCESS;
}
コード例 #12
0
ファイル: sysfs_device.c プロジェクト: drxaero/mxt-app
//******************************************************************************
/// \brief Open sysfs MSG notify attribute
/// \return #mxt_rc
static int sysfs_open_notify_fd(struct mxt_device *mxt)
{
  char *filename = make_path(mxt, "debug_notify");

  mxt->sysfs.debug_notify_fd = open(filename, O_RDONLY);
  if (mxt->sysfs.debug_notify_fd < 0) {
    mxt_err(mxt->ctx, "Could not open %s, error %s (%d)", filename, strerror(errno), errno);
    return mxt_errno_to_rc(errno);
  }

  return MXT_SUCCESS;
}
コード例 #13
0
ファイル: bridge.c プロジェクト: sonntam/obp-utils
//******************************************************************************
/// \brief Send chip attach message
/// \return #mxt_rc
static int send_chip_attach(struct mxt_device *mxt, int sockfd)
{
  int ret;
  const char * const msg = "CAT\n";

  ret = write(sockfd, msg, strlen(msg));
  if (ret < 0) {
    mxt_err(mxt->ctx, "Socket write error: %s (%d)", strerror(errno), errno);
    ret = mxt_errno_to_rc(errno);
  }

  return MXT_SUCCESS;
}
コード例 #14
0
ファイル: sysfs_device.c プロジェクト: drxaero/mxt-app
//******************************************************************************
/// \brief  Write register to MXT chip
/// \return #mxt_rc
int sysfs_write_register(struct mxt_device *mxt, unsigned char const *buf,
                         int start_register, size_t count)
{
  int fd = -ENODEV;
  int ret;
  size_t bytes_written;

  ret = open_device_file(mxt, &fd);
  if (ret)
    return ret;

  if (lseek(fd, start_register, 0) < 0) {
    mxt_err(mxt->ctx, "lseek error %s (%d)", strerror(errno), errno);
    ret = mxt_errno_to_rc(errno);
    goto close;
  }

  bytes_written = 0;
  while (bytes_written < count) {
    ret = write(fd, buf+bytes_written, count - bytes_written);
    if (ret == 0) {
      ret = MXT_ERROR_IO;
      goto close;
    } else if (ret < 0) {
      mxt_err(mxt->ctx, "Error %s (%d) writing to register", strerror(errno), errno);
      ret = mxt_errno_to_rc(errno);
      goto close;
    }

    bytes_written += ret;
  }

  ret = MXT_SUCCESS;

close:
  close(fd);

  return ret;
}
コード例 #15
0
ファイル: bridge.c プロジェクト: sub77-bkp/mxt-app
//******************************************************************************
/// \brief Send chip detach message
/// \return #mxt_rc
static int send_chip_detach(struct mxt_device *mxt,
                            struct bridge_context *bridge_ctx)
{
  int ret;
  const char * const msg = "CDT\n";

  ret = write(bridge_ctx->sockfd, msg, strlen(msg));
  if (ret < 0) {
    mxt_err(mxt->ctx, "Socket write error: %s (%d)", strerror(errno), errno);
    ret = mxt_errno_to_rc(errno);
  }

  return MXT_SUCCESS;
}
コード例 #16
0
ファイル: sysfs_device.c プロジェクト: drxaero/mxt-app
//******************************************************************************
/// \brief  Read register from MXT chip
/// \return #mxt_rc
int sysfs_read_register(struct mxt_device *mxt, unsigned char *buf,
                        int start_register, size_t count, size_t *bytes_read)
{
  int fd = -ENODEV;
  int ret;

  ret = open_device_file(mxt, &fd);
  if (ret)
    return ret;

  if (lseek(fd, start_register, 0) < 0) {
    mxt_err(mxt->ctx, "lseek error %s (%d)", strerror(errno), errno);
    ret = mxt_errno_to_rc(errno);
    goto close;
  }

  *bytes_read = 0;
  while (*bytes_read < count) {
    ret = read(fd, buf + *bytes_read, count - *bytes_read);
    if (ret == 0) {
      ret = MXT_ERROR_IO;
      goto close;
    } else if (ret < 0) {
      mxt_err(mxt->ctx, "read error %s (%d)", strerror(errno), errno);
      ret = mxt_errno_to_rc(errno);
      goto close;
    }

    *bytes_read += ret;
  }

  ret = MXT_SUCCESS;

close:
  close(fd);
  return ret;
}
コード例 #17
0
ファイル: hidraw_device.c プロジェクト: aceyang1018/obp-utils
//******************************************************************************
/// \brief  Write register from MXT chip
/// \return #mxt_rc
int hidraw_write_register(struct mxt_device *mxt, unsigned char const *val, uint16_t start_register, int datalength)
{
  int ret;
  uint8_t byte_count;
  struct hid_packet write_pkt;
  memset(&write_pkt, 0x00, sizeof(struct hid_packet));

  write_pkt.report_id = mxt->conn->hidraw.report_id;
  write_pkt.cmd = 0x51;
  write_pkt.tx_bytes = 0;

  mxt_dbg(mxt->ctx, "%s - start_register:%d No. bytes to write:%d",
          __func__, start_register, datalength);

  ret = hidraw_open(mxt);
  if (ret)
    return ret;

  int bytes_written = 0;

  while (bytes_written < datalength) {
    write_pkt.rx_bytes = MXT_HID_ADDR_SIZE +
                         (datalength - bytes_written <= MXT_HID_WRITE_DATA_SIZE ? datalength - bytes_written : MXT_HID_WRITE_DATA_SIZE);
    write_pkt.address = htole16(start_register + bytes_written);
    memcpy(write_pkt.write_data, val + bytes_written, write_pkt.rx_bytes);

    ret =  hidraw_write_packet(mxt, &write_pkt, &byte_count);
    if (ret) {
      mxt_err(mxt->ctx, "read error %s (%d)", strerror(errno), errno);
      ret = mxt_errno_to_rc(errno);
      goto close;
    }
    bytes_written += byte_count;
    mxt_dbg(mxt->ctx, "Bytes Written:%d", bytes_written);

    struct hid_packet response_pkt;
    memset(&response_pkt, 0x00, sizeof(struct hid_packet));

    ret = hidraw_read_response(mxt, &response_pkt, 2);
    if (response_pkt.result != MXT_HID_READ_SUCCESS)
      mxt_err(mxt->ctx, "HIDRAW write failed: 0x%x",
              response_pkt.result);
  }

close:
  close(mxt->conn->hidraw.fd);
  mxt->conn->hidraw.fd = 0;
  return MXT_SUCCESS;
}
コード例 #18
0
ファイル: hidraw_device.c プロジェクト: aceyang1018/obp-utils
//******************************************************************************
/// \brief  Open the hidraw dev interface and set the slave address
/// \return #mxt_rc
static int hidraw_open(struct mxt_device *mxt)
{
  char filename[20];

  snprintf(filename, sizeof(filename), "%s", mxt->conn->hidraw.node);
  mxt->conn->hidraw.fd = open(filename, O_RDWR|O_NONBLOCK);
  if (mxt->conn->hidraw.fd < 0) {
    mxt_err(mxt->ctx, "Could not open %s, error %s (%d)",
            filename, strerror(errno), errno);
    return mxt_errno_to_rc(errno);
  }
  mxt_dbg(mxt->ctx, "Opened %s, fd: %d", filename, mxt->conn->hidraw.fd);

  return MXT_SUCCESS;
}
コード例 #19
0
ファイル: sysfs_device.c プロジェクト: vincentbernat/mxt-app
//******************************************************************************
/// \brief  Set debug state
/// \param  mxt Device context
/// \param  debug_state true = debug enabled, false = debug disabled
/// \return #mxt_rc
int sysfs_set_debug(struct mxt_device *mxt, bool debug_state)
{
  int ret;

  // Check device is initialised
  if (!mxt) {
    mxt_err(mxt->ctx, "Device uninitialised");
    return MXT_ERROR_NO_DEVICE;
  }

  if (mxt->sysfs.debug_v2 == true) {
    ret = write_boolean_file(mxt, make_path(mxt, "debug_v2_enable"), debug_state);
    if (ret)
      ret = write_boolean_file(mxt, make_path(mxt, "debug_enable"), debug_state);

    if (debug_state) {
      ret = sysfs_open_notify_fd(mxt);
      if (ret)
        return ret;
    } else {
      close(mxt->sysfs.debug_notify_fd);
    }
  } else {
    ret = MXT_SUCCESS;

    if (debug_state) {
      // Allocate buffer space
      mxt->sysfs.debug_msg_buf_size = dmesg_buf_size();
      mxt->sysfs.debug_msg_buf =
        (char *)calloc(mxt->sysfs.debug_msg_buf_size, sizeof(char));
      if (mxt->sysfs.debug_msg_buf == NULL) {
        mxt_err(mxt->ctx, "Error allocating memory for debug_msg_buf_size");
        ret = mxt_errno_to_rc(errno);
      }
    } else if (mxt->sysfs.debug_msg_buf) {
      // Free up the message buffer
      free(mxt->sysfs.debug_msg_buf);
      mxt->sysfs.debug_msg_buf = NULL;
    }

    if (ret == MXT_SUCCESS)
      ret = write_boolean_file(mxt, make_path(mxt, "debug_enable"), debug_state);
  }

  return ret;
}
コード例 #20
0
ファイル: bridge.c プロジェクト: sub77-bkp/mxt-app
//******************************************************************************
/// \brief Handle bridge reset command
/// \return #mxt_rc
static int bridge_handle_reset(struct mxt_device *mxt,
                               struct bridge_context *bridge_ctx,
                               uint16_t address)
{
  int ret;
  char *response;
  const char * const PREFIX = "RST ";
  size_t response_len = 8;

  /* Allow for newline/null byte */
  response = calloc(response_len, sizeof(uint8_t));
  if (!response) {
    mxt_err(mxt->ctx, "Failed to allocate memory");
    ret = MXT_ERROR_NO_MEM;
    goto free;
  }

  strcpy(response, PREFIX);
  ret =  mxt_reset_chip(mxt, false);
  if (ret) {
    mxt_warn(mxt->ctx, "RST ERR");
    strcpy(response + strlen(PREFIX), "ERR\n");
    response_len = strlen(response);
  } else {
    mxt_info(mxt->ctx, "RST OK");
    strcpy(response + strlen(PREFIX), "OK\n");
    response_len = strlen(response);
  }

  ret = write(bridge_ctx->sockfd, response, response_len);
  if (ret < 0) {
    mxt_err(mxt->ctx, "Socket write error: %s (%d)", strerror(errno), errno);
    ret = mxt_errno_to_rc(errno);
    goto free;
  }

  ret = MXT_SUCCESS;

free:
  free(response);
  return ret;
}
コード例 #21
0
ファイル: sysfs_device.c プロジェクト: drxaero/mxt-app
//******************************************************************************
/// \brief  Open device
/// \return #mxt_rc
int sysfs_open(struct mxt_device *mxt)
{
  struct sysfs_conn_info *conn = &mxt->conn->sysfs;
  char *filename;
  struct stat filestat;
  int ret;

  mxt->sysfs.path_max = strlen(conn->path) + 20;

  // Allocate temporary path space
  mxt->sysfs.temp_path = calloc(mxt->sysfs.path_max + 1, sizeof(char));
  if (!mxt->sysfs.temp_path)
    return MXT_ERROR_NO_MEM;

  // Cache memory access path for fast access
  mxt->sysfs.mem_access_path = calloc(mxt->sysfs.path_max + 1, sizeof(char));
  if (!mxt->sysfs.mem_access_path)
    return MXT_ERROR_NO_MEM;

  snprintf(mxt->sysfs.mem_access_path, mxt->sysfs.path_max,
           "%s/mem_access", conn->path);

  // Check whether debug v2 or not
  filename = make_path(mxt, "debug_msg");

  ret = stat(filename, &filestat);
  if (ret < 0) {
    if (errno == ENOENT) {
      mxt->sysfs.debug_v2 = false;
    } else {
      mxt_err(mxt->ctx, "Could not stat %s, error %s (%d)",
              filename, strerror(errno), errno);
      return mxt_errno_to_rc(errno);
    }
  } else {
    mxt->sysfs.debug_v2 = true;
  }

  mxt_info(mxt->ctx, "Registered sysfs path:%s", conn->path);

  return MXT_SUCCESS;
}
コード例 #22
0
ファイル: sysfs_device.c プロジェクト: drxaero/mxt-app
//******************************************************************************
/// \brief  Write boolean to file as ASCII 0/1
/// \param  mxt Device context
/// \param  filename Name of file to write
/// \param  value Value to write
/// \return #mxt_rc
static int write_boolean_file(struct mxt_device *mxt, const char *filename,
                              bool value)
{
  FILE *file;

  file = fopen(filename, "w+");
  if (!file) {
    mxt_err(mxt->ctx, "Could not open %s, error %s (%d)", filename, strerror(errno), errno);
    return mxt_errno_to_rc(errno);
  }

  if (value == true) {
    fputs("1", file);
  } else {
    fputs("0", file);
  }

  fclose(file);

  return MXT_SUCCESS;
}
コード例 #23
0
ファイル: sysfs_device.c プロジェクト: drxaero/mxt-app
//******************************************************************************
/// \brief Open memory access file
/// \return #mxt_rc
static int open_device_file(struct mxt_device *mxt, int *fd_out)
{
  int fd;

  // Check device is initialised
  if (!mxt || !mxt->sysfs.mem_access_path) {
    mxt_err(mxt->ctx, "Device uninitialised");
    return MXT_ERROR_NO_DEVICE;
  }

  fd = open(mxt->sysfs.mem_access_path, O_RDWR);

  if (fd < 0) {
    mxt_err(mxt->ctx, "Could not open %s, error %s (%d)",
            mxt->sysfs.mem_access_path, strerror(errno), errno);

    return mxt_errno_to_rc(errno);
  }

  *fd_out = fd;
  return MXT_SUCCESS;
}
コード例 #24
0
ファイル: bridge.c プロジェクト: sonntam/obp-utils
//******************************************************************************
/// \brief Handle bridge write
/// \return #mxt_rc
static int bridge_wri_cmd(struct mxt_device *mxt, int sockfd, uint16_t address,
                          char *hex, uint16_t bytes)
{
  int ret;
  uint16_t count;
  const char * const FAIL = "WRP ERR\n";
  const char * const PASS = "******";
  const char *response;
  uint8_t *databuf;

  databuf = calloc(bytes, sizeof(uint8_t));
  if (!databuf) {
    mxt_err(mxt->ctx, "Failed to allocate memory");
    return MXT_ERROR_NO_MEM;
  }

  ret = mxt_convert_hex(hex, databuf, &count, bytes);
  if (ret) {
    response = FAIL;
  } else {
    ret = mxt_write_register(mxt, databuf, address, count);
    if (ret) {
      mxt_verb(mxt->ctx, "WRI OK");
      response = FAIL;
    } else {
      response = PASS;
    }
  }

  ret = write(sockfd, response, strlen(response));
  if (ret < 0) {
    mxt_err(mxt->ctx, "Socket write error: %s (%d)", strerror(errno), errno);
    ret = mxt_errno_to_rc(errno);
  }

  ret = MXT_SUCCESS;
  free(databuf);
  return ret;
}
コード例 #25
0
ファイル: bridge.c プロジェクト: sonntam/obp-utils
//******************************************************************************
/// \brief Read command on a single line
/// \return #mxt_rc
static int readline(struct mxt_device *mxt, int fd, struct mxt_buffer *linebuf)
{
  int ret;
  int n;
  int readcount;
  char c;

  mxt_buf_reset(linebuf);

  for (n = 1; n < MAX_LINESIZE; n++) {
    /* read 1 character at a time */
    readcount = read(fd, &c, 1);
    if (readcount == 1) {
      if ((c == '\n') || (c == '\r'))
        break;

      ret = mxt_buf_add(linebuf, c);
      if (ret)
        return ret;
    } else if (readcount == 0) {
      if (n == 1)
        return MXT_SUCCESS;
      else
        break;
    } else {
      mxt_err(mxt->ctx, "Read error: %s (%d)", strerror(errno), errno);
      return mxt_errno_to_rc(errno);
    }
  }

  /* null-terminate the buffer */
  ret = mxt_buf_add(linebuf, '\0');
  if (ret)
    return ret;

  return MXT_SUCCESS;
}
コード例 #26
0
//******************************************************************************
/// \brief  Read hex encoded data from file
/// \return #mxt_rc
static int mxt_t68_load_file(struct t68_ctx *ctx)
{
  int ret;
  uint8_t value = 0;
  FILE *fp;
  bool file_read = false;
  char buf[256];
  uint16_t hexcount;
  int c;

  /* open file */
  fp = fopen(ctx->filename, "r");
  if (fp == NULL) {
    mxt_err(ctx->lc, "Error opening %s", ctx->filename);
    return mxt_errno_to_rc(errno);
  }

  ret = mxt_buf_init(&ctx->buf);
  if (ret) {
    mxt_err(ctx->lc, "Error initialising buffer");
    goto close;
  }

  while (!file_read) {
    /* Read next value from file */
    c = getc(fp);
    if (c == EOF) {
      break;
    }
    /* skip spaces, newlines, commas*/
    else if (c == 0x20 || c == '\r' || c == '\n' || c == ',') {
      continue;
    }
    /* Ignore comment lines */
    else if (c == '[') {
      // Grab comment key
      if (fscanf(fp, "%255[^]]", buf) != 1) {
        ret = MXT_ERROR_FILE_FORMAT;
        goto fail;
      }

      mxt_verb(ctx->lc, "[%s]", buf);

      if (!strncasecmp(buf, "datatype=", 9)) {
        if (sscanf(buf + 9, "%d", &c) != 1) {
          mxt_warn(ctx->lc, "Unable to parse datatype");
        } else {
          ctx->t68_datatype = c;
          mxt_info(ctx->lc, "DATATYPE set to %u by file", ctx->t68_datatype);
        }
      }

      // Read until end of line
      while (c != '\n') {
        c = getc(fp);
      }
      continue;
    }
    /* A value looks like "0xABu," */
    else if (c == '0') {
      if (fscanf(fp, "x%2su", (char *)&buf) != 1) {
        mxt_err(ctx->lc, "Parse error");
        ret = MXT_ERROR_FILE_FORMAT;
        goto fail;
      }

      ret = mxt_convert_hex(buf, &value, &hexcount, 3);
      if (ret)
        goto fail;

      ret = mxt_buf_add(&ctx->buf, value);
      if (ret)
        goto fail;
    } else {
      mxt_err(ctx->lc, "Unexpected character \"%c\"", c);
      ret = MXT_ERROR_FILE_FORMAT;
      goto fail;
    }
  }

  mxt_info(ctx->lc, "Loaded file %s, %zu bytes", ctx->filename, ctx->buf.size);

  return MXT_SUCCESS;

fail:
  mxt_buf_free(&ctx->buf);
close:
  fclose(fp);
  return ret;
}
コード例 #27
0
ファイル: bridge.c プロジェクト: sub77-bkp/mxt-app
//******************************************************************************
/// \brief Read and deal with incoming command
/// \return #mxt_rc
static int handle_cmd(struct mxt_device *mxt, struct bridge_context *bridge_ctx)
{
  int ret;
  uint16_t address;
  uint16_t count;
  struct mxt_buffer linebuf;
  char *line;
  int offset;

  ret = mxt_buf_init(&linebuf);
  if (ret)
    return ret;

  ret = readline(mxt, bridge_ctx->sockfd, &linebuf);
  if (ret) {
    mxt_dbg(mxt->ctx, "Error reading or peer closed socket");
    goto free;
  }

  line = (char *)linebuf.data;
  if (strlen(line) == 0) {
    ret = MXT_SUCCESS;
    goto free;
  }

  mxt_verb(mxt->ctx, "%s", line);

  if (!strcmp(line, "SAT")) {
    mxt_info(mxt->ctx, "Server attached");
    ret = MXT_SUCCESS;
  } else if (!strcmp(line, "SDT")) {
    mxt_info(mxt->ctx, "Server detached");
    ret = MXT_SUCCESS;
  } else if (sscanf(line, "REA %" SCNu16 " %" SCNu16, &address, &count) == 2) {
    ret = bridge_rea_cmd(mxt, bridge_ctx, address, count);
  } else if (sscanf(line, "WRI %" SCNu16 "%n", &address, &offset) == 1) {
    /* skip space */
    offset += 1;

    ret = bridge_wri_cmd(mxt, bridge_ctx, address,
                         line + offset,
                         strlen(line) - offset);
  } else if (sscanf(line, "RST %" SCNu16 "%n", &address, &offset) == 1) {
    ret = bridge_handle_reset(mxt, bridge_ctx, address);
    ret = MXT_SUCCESS;
  } else if (sscanf(line, "MSGCFG %" SCNu16 "%n", &address, &offset) == 1) {
    mxt_info(mxt->ctx, "Configuring Messages");
    bridge_ctx->msgs_enabled = true;
    const char * const msg = "MSGCFG OK\n";

    ret = write(bridge_ctx->sockfd, msg, strlen(msg));
    if (ret < 0) {
      mxt_err(mxt->ctx, "Socket write error: %s (%d)", strerror(errno), errno);
      ret = mxt_errno_to_rc(errno);
    }
    ret = MXT_SUCCESS;
  } else {
    mxt_info(mxt->ctx, "Unrecognised cmd \"%s\"", line);
    ret = MXT_SUCCESS;
  }

free:
  mxt_buf_free(&linebuf);
  return ret;
}
コード例 #28
0
ファイル: dmesg.c プロジェクト: drxaero/mxt-app
//******************************************************************************
/// \brief  Get messages
/// \param  mxt  Maxtouch Device
/// \param  count Number of messages available
/// \param  init_timestamp Read newest dmesg line and initialise timestamp
/// \return #mxt_rc
int dmesg_get_msgs(struct mxt_device *mxt, int *count, bool init_timestamp)
{
  char msg[BUFFERSIZE];
  int ep, sp;
  int ret = MXT_SUCCESS;
  unsigned long sec, msec, lastsec = 0, lastmsec = 0;

  // Read entire kernel log buffer
  ep = klogctl(SYSLOG_ACTION_READ_ALL, mxt->sysfs.debug_msg_buf,
               mxt->sysfs.debug_msg_buf_size);
  // Return if no bytes read
  if (ep < 0) {
    mxt_warn(mxt->ctx, "klogctl error %d (%s)", errno, strerror(errno));
    ret = mxt_errno_to_rc(errno);
  } else {
    // null terminate
    mxt->sysfs.debug_msg_buf[ep] = 0;
    sp = ep;

    if (!init_timestamp)
      dmesg_list_empty(mxt);

    // Search for next new line character
    while (true) {
      sp--;
      while (sp >= 0 && *(mxt->sysfs.debug_msg_buf + sp) != '\n')
        sp--;

      if (sp <= 0)
        break;

      // Try to parse dmesg line
      if (sscanf(mxt->sysfs.debug_msg_buf+sp+1, "< %*c>[ %lu.%06lu] %255[^\n]",
                 &sec, &msec, msg) == 3) {
        if (init_timestamp) {
          mxt->sysfs.timestamp = sec;
          mxt->sysfs.mtimestamp = msec;
          mxt_verb(mxt->ctx, "%s - init [%5lu.%06lu]", __func__, sec, msec);
          break;
        }

        // Store time of last message in buffer
        if (lastsec == 0) {
          lastsec = sec;
          lastmsec = msec;
        }

        // Only 500 at a time, otherwise we overrun JNI reference limit.
        // Timestamp must be greater than previous messages, slightly
        // complicated by seconds and microseconds
        if ((mxt->sysfs.dmesg_count > MAX_DMESG_COUNT) ||
            (sec == mxt->sysfs.timestamp && msec <= mxt->sysfs.mtimestamp) ||
            (sec < mxt->sysfs.timestamp)) {
          mxt->sysfs.timestamp = lastsec;
          mxt->sysfs.mtimestamp = lastmsec;
          break;
        }

        char* msgptr;
        msg[sizeof(msg) - 1] = '\0';
        msgptr = strstr(msg, "MXT MSG");
        if (msgptr)
          dmesg_list_add(mxt, sec, msec, msgptr);
      }
    }

    if (!init_timestamp) {
      *count = mxt->sysfs.dmesg_count;
      mxt->sysfs.dmesg_ptr = mxt->sysfs.dmesg_head;
    }
  }

  return ret;
}
コード例 #29
0
ファイル: bridge.c プロジェクト: sonntam/obp-utils
//******************************************************************************
/// \brief Main bridge function to handle a single connection
/// \return #mxt_rc
static int bridge(struct mxt_device *mxt, int sockfd)
{
  int ret, pollret;
  struct pollfd fds[2];
  int fopts = 0;
  int debug_ng_fd = 0;
  int numfds = 1;
  int timeout;

  mxt_info(mxt->ctx, "Connected");

  ret = mxt_msg_reset(mxt);
  if (ret)
    mxt_err(mxt->ctx, "Failure to reset msgs");

  fds[0].fd = sockfd;
  fds[0].events = POLLIN | POLLERR;

  ret = send_chip_attach(mxt, sockfd);
  if (ret)
    return ret;

  while (1) {
    debug_ng_fd = mxt_get_msg_poll_fd(mxt);
    if (debug_ng_fd) {
      fds[1].fd = debug_ng_fd;
      fds[1].events = POLLPRI;
      numfds = 2;
      timeout = -1;
    } else {
      timeout = 100; // milliseconds
    }

    pollret = poll(fds, numfds, timeout);
    if (pollret == -1 && errno == EINTR) {
      mxt_dbg(mxt->ctx, "Interrupted");
      continue;
    } else if (pollret == -1) {
      mxt_err(mxt->ctx, "Poll returned %d (%s)", errno, strerror(errno));
      ret = mxt_errno_to_rc(errno);
      goto disconnect;
    }

    /* Detect socket disconnect */
    if (fcntl(sockfd, F_GETFL, &fopts) < 0) {
      ret = MXT_SUCCESS;
      mxt_dbg(mxt->ctx, "Socket disconnected");
      goto disconnect;
    }

    if (fds[0].revents) {
      ret = handle_cmd(mxt, sockfd);
      if (ret) {
        mxt_dbg(mxt->ctx, "handle_cmd returned %d", ret);
        goto disconnect;
      }
    }

    /* If timeout or msg poll fd event */
    if (pollret == 0 || fds[1].revents) {
      ret = handle_messages(mxt, sockfd);
      if (ret)
        goto disconnect;
    }
  }

disconnect:
  mxt_info(mxt->ctx, "Disconnected");
  return ret;
}