📄 xbee_gpio_client.c
字号:
if (resp->length & 0x80) {
range = (xbee_gpio_rec_ar_resp_range_t *) &data[record_len];
record_len += 8;
} else {
range = NULL;
}
if (record_len > datalen) {
#ifdef GPIO_VERBOSE
printf(" %s(%3d): decode error, record (%d) too long for" \
" remaining payload (%d)\n", gpio_signal[resp->signal].name,
resp->signal, record_len, datalen);
#endif
return;
}
#ifdef GPIO_VERBOSE
if (resp->length & 0x70) {
printf(" %s(%3d): warning, extra flags set: 0x%02x\n",
gpio_signal[resp->signal].name, resp->signal, resp->length & 0x70);
}
#endif
memcpy(units, resp->units, units_len);
units[units_len] = '\0';
if (range) {
printf(" %s range: %.3f to %.3f, units=[%s]\n",
gpio_signal[resp->signal].name, range->lower, range->upper,
units);
} else {
printf(" %s(%3d): no range, units=[%s]\n",
gpio_signal[resp->signal].name, resp->signal, units);
}
datalen -= record_len;
data += record_len;
if (gpio_device[gpio_index].ep_count) {
gpio_device[gpio_index].ep_count--;
}
}
}
#ifdef GPIO_VERBOSE
if (datalen)
{
printf(" bad packet, 1 extra byte at end (0x%02x)\n", *data);
}
#endif
if (gpio_device[gpio_index].ep_count) {
gpio_device[gpio_index].state = CLIENT_STATE_REQ_ANARANGE;
}
}
int request_gpio_read(int node_index, int io_start, int io_end)
{
int rc;
rc = request_gpio_iorange(node_index, XBEE_GPIO_CLUST_READ, io_start,
io_end);
if (!rc) {
gpio_device[gpio_index].state = CLIENT_STATE_PARSE_READ;
gpio_device[gpio_index].last_ep = io_end;
gpio_device[gpio_index].ep_count = io_end - io_start + 1;
}
return rc;
}
typedef struct {
byte signal;
byte type;
union {
byte digital;
float analog;
} value;
} xbee_gpio_rec_read_response_t;
void xbeeGpioReadResp(char *data, int datalen)
{
xbee_gpio_rec_read_response_t *resp;
int record_len;
char digital, buf[32];
#ifdef GPIO_VERBOSE
printf("parsing read response\n");
xb_hexdump(data, datalen);
#endif
while (datalen >= 2) {
digital = 0;
resp = (xbee_gpio_rec_read_response_t *) data;
switch (resp->type) {
case XBEE_GPIO_TYPE_DISABLED:
printf(" %s: disabled\n", gpio_signal[resp->signal].name);
record_len = 2;
break;
case XBEE_GPIO_TYPE_INVALID:
printf(" %s: invalid\n", gpio_signal[resp->signal].name);
record_len = 2;
break;
case XBEE_GPIO_TYPE_SWITCH_IN:
strcpy(buf, "Switch Input, value = ");
strcpy(buf + 22, (resp->value.digital ? "CLOSED" : "OPEN"));
digital = 1;
break;
case XBEE_GPIO_TYPE_LED_OUT:
strcpy(buf, "LED Output, value = ");
strcpy(buf + 20, (resp->value.digital ? "ON" : "OFF"));
digital = 1;
break;
case XBEE_GPIO_TYPE_DIGITAL_OUT:
case XBEE_GPIO_TYPE_DIGITAL_IN:
strcpy(buf, (resp->type == XBEE_GPIO_TYPE_DIGITAL_IN ?
"Digital Input, value = " : "Digital Output, value = "));
strcpy(buf + 24, (resp->value.digital ? "HIGH" : "LOW"));
digital = 1;
break;
case XBEE_GPIO_TYPE_SINK_OUT:
strcpy(buf, "Sinking Output, value = ");
strcpy(buf + 24, (resp->value.digital ? "TRI" : "LOW"));
digital = 1;
break;
case XBEE_GPIO_TYPE_SOURCE_OUT:
strcpy(buf, "Source Output, value = ");
strcpy(buf + 23, (resp->value.digital == 1 ? "HIGH" : "TRI"));
digital = 1;
break;
case XBEE_GPIO_TYPE_TRISTATE_OUT:
strcpy(buf, "Tri-State Output, value = ");
strcpy(buf + 26, (resp->value.digital ? (resp->value.digital == 1 ?
"HIGH" : "TRI") : "LOW"));
digital = 1;
break;
case XBEE_GPIO_TYPE_ANALOG_OUT:
case XBEE_GPIO_TYPE_ANALOG_IN:
record_len = 6;
if (datalen < record_len) {
printf(" %s: error, record to short\n",
gpio_signal[resp->signal].name);
return;
}
printf(" %s: type Analog %s, value = %.3f\n",
gpio_signal[resp->signal].name,
(resp->type == XBEE_GPIO_TYPE_ANALOG_IN ? "In" : "Out"),
resp->value.analog);
break;
default:
printf(" %s: unknown type 0x%02x, rest of packet ignored\n",
gpio_signal[resp->signal].name, resp->type);
return;
}
if (digital) {
record_len = 3;
if (datalen < record_len) {
printf(" %s: error, record to short\n",
gpio_signal[resp->signal].name);
return;
}
printf(" %s: type %s\n", gpio_signal[resp->signal].name, buf);
}
datalen -= record_len;
data += record_len;
if (gpio_device[gpio_index].ep_count)
{
gpio_device[gpio_index].ep_count--;
}
}
if (datalen)
{
printf(" bad packet, 1 extra byte at end (0x%02x)\n", *data);
}
if (gpio_device[gpio_index].ep_count) {
gpio_device[gpio_index].state = CLIENT_STATE_REQ_READ;
}
}
typedef struct {
byte length;
byte payload[XBEE_MAX_RFPAYLOAD];
} xbee_payload_t;
void xbee_payload_clear(xbee_payload_t *fp)
{
memset(fp, 0, sizeof(*fp));
}
int request_gpio_write(int node_index, xbee_payload_t *fp)
{
int err;
gpio_device[gpio_index].state = CLIENT_STATE_PARSE_WRITE;
gpio_device[gpio_index].ep_count = 1;
err = request_gpio(node_index, XBEE_GPIO_CLUST_WRITE, fp->payload,
(int) fp->length);
if (err)
{
printf("error %d sending write request\n", err);
}
return err;
}
int request_gpio_append_int(xbee_payload_t *fp, int signal, int type,
int value)
{
char *p;
// make sure there's enough room in the payload
if (fp->length + 3 > XBEE_MAX_RFPAYLOAD) return -1;
p = &fp->payload[fp->length];
*p++ = signal;
*p++ = type;
*p = value;
fp->length += 3;
return 0;
}
int request_gpio_append_float(xbee_payload_t *fp, int signal, int type,
float value)
{
char *p;
// make sure there's enough room in the payload
if (fp->length + 6 > XBEE_MAX_RFPAYLOAD) return -1;
p = &fp->payload[fp->length];
*p++ = signal;
*p++ = type;
memcpy(p, &value, 4);
fp->length += 6;
return 0;
}
void xbeeGpioWriteResp(char *data, int datalen)
{
char *status;
char buffer[20];
#ifdef GPIO_VERBOSE
printf("parsing write response\n");
xb_hexdump(data, datalen);
#endif
// data[0] is the signal index, data[1] is the signal status
while (datalen >= 2) {
switch (data[1]) {
case XBEE_GPIO_STATUS_SUCCESS:
status = "success";
break;
case XBEE_GPIO_STATUS_DISABLED:
status = "failed, I/O is disabled";
break;
case XBEE_GPIO_STATUS_BAD_TYPE:
status = "failed, wrong I/O type";
break;
case XBEE_GPIO_STATUS_OUT_OF_RANGE:
status = "failed, out of analog range";
break;
case XBEE_GPIO_STATUS_INVALID:
status = "failed, invalid I/O signal";
break;
default:
sprintf(buffer, "unknown error 0x%02x", data[1]);
status = buffer;
}
gpio_device[gpio_index].ep_count = 0;
printf(" %s: %s\n", gpio_signal[data[0]].name, status);
data += 2;
datalen -= 2;
}
if (datalen)
{
printf(" bad packet, 1 extra byte at end (0x%02x)\n", *data);
}
}
void gpio_write_digital(int node_index, int signal, int value)
{
xbee_payload_t zp;
xbee_payload_clear(&zp);
request_gpio_append_int(&zp, signal, gpio_signal[signal].type, value);
request_gpio_write(node_index, &zp);
}
void gpio_write_analog(int node_index, int signal, float value)
{
xbee_payload_t zp;
xbee_payload_clear(&zp);
request_gpio_append_float(&zp, signal, XBEE_GPIO_TYPE_ANALOG_OUT, value);
request_gpio_write(node_index, &zp);
}
int gpio_open_node(int node)
{
if ((gpio_device[node].io_count) && (gpio_device[node].node_index >= 0)) {
gpio_index = node;
gpio_device[node].state = CLIENT_STATE_NEW_NAME;
printf("\n\nGPIO server %d opened\n\n", node);
return ZB_NODE_OPEN;
}
else {
return ZB_IDLE;
}
}
void gpio_help(int flags)
{
int i, analog;
if (flags & SHOW_NET_HELP) {
printf("\nValid Network Commands\n");
printf("-------------------------------------\n");
printf("D Discover new nodes on the network and scan\n");
if (gpio_last) {
printf("N List available GPIO servers on discovered nodes\n");
printf("0 - %d Attach to the specified GPIO server\n", gpio_last-1);
}
printf("H Show this help menu\n");
printf("X Exit the GPIO client program\n\nN> ");
}
if (flags & SHOW_SIGNALS) {
printf("GPIO Signals\n-------------------------------------\n");
for (i = analog = 0; i < gpio_device[gpio_index].io_count; i++)
{
// Print out names of signals on GPIO server
printf(" %3d) %s is ", i, gpio_signal[i].name);
switch (gpio_signal[i].type) {
case XBEE_GPIO_TYPE_ANALOG_IN:
analog = 1;
printf("an analog input.\n");
break;
case XBEE_GPIO_TYPE_DIGITAL_IN:
printf("a digital input\n");
break;
case XBEE_GPIO_TYPE_SWITCH_IN:
printf("a switch input\n");
break;
case XBEE_GPIO_TYPE_ANALOG_OUT:
printf("an analog output.\n");
break;
case XBEE_GPIO_TYPE_DIGITAL_OUT:
printf("a digital output\n");
break;
case XBEE_GPIO_TYPE_LED_OUT:
printf("an LED output\n");
break;
case XBEE_GPIO_TYPE_SINK_OUT:
printf("a sinking output\n");
break;
case XBEE_GPIO_TYPE_SOURCE_OUT:
printf("a sourcing output\n");
break;
case XBEE_GPIO_TYPE_TRISTATE_OUT:
printf("a tri-state output\n");
break;
default:
printf("an unknown signal\n");
break;
}
}
if (analog) {
printf("\n Analog Ranges\n-----------------\n");
gpio_device[gpio_index].state = CLIENT_STATE_REQ_ANARANGE;
return; // Don't allow help now if analog inputs are present
}
}
if (flags & SHOW_GPIO_HELP) {
printf("\nValid GPIO Commands\n-------------------------------------\n");
printf("GET ALL Get values from all signals\n");
printf("GET name Get value from named signal\n");
printf("SET name value Set value of named signal\n");
printf(" (If digital: value can be LOW, HI, TRI, ON or OFF)\n");
printf("CLOSE Close the GPIO device - Back to Network menu\n");
printf("NAMES Show signal names for the current GPIO device\n");
printf("HELP Show this menu\n\nG> ");
}
}
#define PARSE_MAX_BUF 128 // Maximum command string size
int parse_cmd(int ch)
{
static char buf[PARSE_MAX_BUF + 1];
static char * ptr;
int state, i, cmd, signal, value, type, max;
float fp_value;
char *end;
if (ch < 0)
{
// Clear command string buffer
ptr = buf;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -