#include <stdlib.h>
#include <err.h>
#include "libi2c_test_util.h"
static bool
test_add(i2c_hdl_t *hdl, i2c_dev_add_req_t *req, const char *desc)
{
if (i2c_device_add_req_exec(req)) {
warnx("TEST FAILED: incomplete device add (%s) accidentally "
"succeeded", desc);
return (false);
} else if (i2c_err(hdl) != I2C_ERR_ADD_DEV_REQ_MISSING_FIELDS) {
warnx("TEST FAILED: incomplete device add (%s) failed with "
"%s (0x%x), expected I2C_ERR_ADD_DEV_REQ_MISSING_FIELDS "
"(0x%x)", desc, i2c_errtostr(hdl, i2c_err(hdl)),
i2c_err(hdl), I2C_ERR_ADD_DEV_REQ_MISSING_FIELDS);
return (false);
} else {
(void) printf("TEST PASSED: incomplete device add (%s) failed "
"with I2C_ERR_ADD_DEV_REQ_MISSING_FIELDS\n", desc);
return (true);
}
}
static bool
missing_adds(i2c_hdl_t *hdl, i2c_port_t *port)
{
bool ret = true;
i2c_dev_add_req_t *add;
if (!i2c_device_add_req_init(port, &add)) {
libi2c_test_fatal(hdl, "INTERNAL TEST FAILURE: failed to "
"initialize device add requiest");
}
if (!test_add(hdl, add, "all")) {
ret = false;
}
const i2c_addr_t addr = { I2C_ADDR_7BIT, 0x23 };
if (!i2c_device_add_req_set_addr(add, &addr)) {
libi2c_test_fatal(hdl, "INTERNAL TEST FAILURE: failed to set "
"device add address");
}
if (!test_add(hdl, add, "name")) {
ret = false;
}
i2c_device_add_req_fini(add);
if (!i2c_device_add_req_init(port, &add)) {
libi2c_test_fatal(hdl, "INTERNAL TEST FAILURE: failed to "
"initialize device add requiest");
}
if (!i2c_device_add_req_set_name(add, "foobar")) {
libi2c_test_fatal(hdl, "INTERNAL TEST FAILURE: failed to set "
"device add address");
}
if (!test_add(hdl, add, "addr")) {
ret = false;
}
i2c_device_add_req_fini(add);
return (ret);
}
static bool
test_i2c_io(i2c_hdl_t *hdl, i2c_io_req_t *req, const char *desc)
{
if (i2c_io_req_exec(req)) {
warnx("TEST FAILED: incomplete I2C I/O (%s) accidentally "
"succeeded", desc);
return (false);
} else if (i2c_err(hdl) != I2C_ERR_IO_REQ_MISSING_FIELDS) {
warnx("TEST FAILED: incomplete I2C I/O (%s) failed with "
"%s (0x%x), expected I2C_ERR_IO_REQ_MISSING_FIELDS (0x%x)",
desc, i2c_errtostr(hdl, i2c_err(hdl)), i2c_err(hdl),
I2C_ERR_IO_REQ_MISSING_FIELDS);
return (false);
} else {
(void) printf("TEST PASSED: incomplete I2C I/O (%s) failed "
"with I2C_ERR_IO_REQ_MISSING_FIELDS\n", desc);
return (true);
}
}
static bool
missing_i2c_io(i2c_hdl_t *hdl, i2c_port_t *port)
{
bool ret = true;
i2c_io_req_t *req;
if (!i2c_io_req_init(port, &req)) {
libi2c_test_fatal(hdl, "INTERNAL TEST FAILURE: failed to "
"initialize I2C I/O request");
}
if (!test_i2c_io(hdl, req, "all")) {
ret = false;
}
uint8_t rbuf[4] = { 0 };
uint8_t wbuf[4] = { 0 };
if (!i2c_io_req_set_transmit_data(req, wbuf, sizeof (wbuf))) {
libi2c_test_fatal(hdl, "INTERNAL TEST FAILURE: failed to "
"set I2C transmit buffer");
}
if (!i2c_io_req_set_receive_buf(req, rbuf, sizeof (rbuf))) {
libi2c_test_fatal(hdl, "INTERNAL TEST FAILURE: failed to "
"set I2C receive buffer");
}
if (!test_i2c_io(hdl, req, "addr")) {
ret = false;
}
i2c_io_req_fini(req);
return (ret);
}
static bool
test_smbus_io(i2c_hdl_t *hdl, smbus_io_req_t *req, const char *desc)
{
if (smbus_io_req_exec(req)) {
warnx("TEST FAILED: incomplete SMBus I/O (%s) accidentally "
"succeeded", desc);
return (false);
} else if (i2c_err(hdl) != I2C_ERR_IO_REQ_MISSING_FIELDS) {
warnx("TEST FAILED: incomplete SMBus I/O (%s) failed with "
"%s (0x%x), expected I2C_ERR_IO_REQ_MISSING_FIELDS (0x%x)",
desc, i2c_errtostr(hdl, i2c_err(hdl)), i2c_err(hdl),
I2C_ERR_IO_REQ_MISSING_FIELDS);
return (false);
} else {
(void) printf("TEST PASSED: incomplete SMBus I/O (%s) failed "
"with I2C_ERR_IO_REQ_MISSING_FIELDS\n", desc);
return (true);
}
}
static bool
missing_smbus_io(i2c_hdl_t *hdl, i2c_port_t *port)
{
bool ret = true;
smbus_io_req_t *req;
if (!smbus_io_req_init(port, &req)) {
libi2c_test_fatal(hdl, "INTERNAL TEST FAILURE: failed to "
"initialize SMBus I/O request");
}
if (!test_smbus_io(hdl, req, "all")) {
ret = false;
}
smbus_io_req_fini(req);
if (!smbus_io_req_init(port, &req)) {
libi2c_test_fatal(hdl, "INTERNAL TEST FAILURE: failed to "
"initialize SMBus I/O request");
}
const i2c_addr_t addr = { I2C_ADDR_7BIT, 0x42 };
if (!smbus_io_req_set_addr(req, &addr)) {
libi2c_test_fatal(hdl, "INTERNAL TEST FAILURE: failed to "
"set SMBus request address");
}
if (!test_smbus_io(hdl, req, "command")) {
ret = false;
}
smbus_io_req_fini(req);
if (!smbus_io_req_init(port, &req)) {
libi2c_test_fatal(hdl, "INTERNAL TEST FAILURE: failed to "
"initialize SMBus I/O request");
}
if (!smbus_io_req_set_write_u16(req, 0x23, 0x7777)) {
libi2c_test_fatal(hdl, "INTERNAL TEST FAILURE: failed to "
"set write u16 command");
}
if (!test_smbus_io(hdl, req, "addr: u16")) {
ret = false;
}
smbus_io_req_fini(req);
if (!smbus_io_req_init(port, &req)) {
libi2c_test_fatal(hdl, "INTERNAL TEST FAILURE: failed to "
"initialize SMBus I/O request");
}
uint8_t buf[4];
if (!smbus_io_req_set_read_block_i2c(req, 0x23, buf, sizeof (buf))) {
libi2c_test_fatal(hdl, "INTERNAL TEST FAILURE: failed to "
"set read I2C block command");
}
if (!test_smbus_io(hdl, req, "addr: read block i2c")) {
ret = false;
}
smbus_io_req_fini(req);
return (ret);
}
int
main(void)
{
i2c_port_t *port;
int ret = EXIT_SUCCESS;
i2c_hdl_t *hdl = i2c_init();
if (hdl == NULL) {
err(EXIT_FAILURE, "INTERNAL TEST FAILURE: failed to create "
"libi2c handle");
}
if (!i2c_port_init_by_path(hdl, "smbussim1/0", &port)) {
libi2c_test_fatal(hdl, "INTERNAL TEST FAILURE: failed to "
"initialize port smbussim1/0");
}
if (!missing_adds(hdl, port)) {
ret = EXIT_FAILURE;
}
if (!missing_i2c_io(hdl, port)) {
ret = EXIT_FAILURE;
}
if (!missing_smbus_io(hdl, port)) {
ret = EXIT_FAILURE;
}
if (ret == EXIT_SUCCESS) {
(void) printf("All tests passed successfully\n");
}
i2c_port_fini(port);
i2c_fini(hdl);
return (ret);
}