Пример #1
0
int main(int argc, char *argv[]) {
	struct xbee *xbee;
	xbee_err ret;
	int level;

	if ((ret = xbee_setup(&xbee, "xbee1", "/dev/ttyUSB0", 57600)) != XBEE_ENONE) {
		printf("ret: %d (%s)\n", ret, xbee_errorToStr(ret));
		return ret;
	}

	if ((ret = xbee_logLevelGet(xbee, &level)) != XBEE_ENONE) {
		printf("xbee_logLevelGet() returned: %d\n", ret);
		return ret;
	}
	printf("libxbee log level is currently: %d\n", level);
	printf("\nDon't forget you can set the log level via the environment, for example:\n\tXBEE_LOG_LEVEL=100 %s\n\n", argv[0]);

	xbee_log(xbee, 50, "Test Message 1...");

	printf("setting libxbee log level to: 100\n");
	if ((ret = xbee_logLevelSet(xbee, 100)) != XBEE_ENONE) {
		printf("xbee_logLevelSet() returned: %d\n", ret);
		return ret;
	}

	xbee_log(xbee, 50, "Test Message 2...");

	xbee_shutdown(xbee);

	return 0;
}
Пример #2
0
/* get a packet from a connection
   if no packet is avaliable or an error occurs, then NULL is returned */
EXPORT struct xbee_pkt *xbee_conRx(struct xbee *xbee, struct xbee_con *con) {
	struct xbee_pkt *pkt;
	
	/* check parameters */
	if (!xbee) {
		if (!xbee_default) return NULL;
		xbee = xbee_default;
	}
	if (!xbee_validate(xbee)) return NULL;
	if (!con) return NULL;
	
	/* check the provided connection */
	if (_xbee_conValidate(xbee, con, NULL)) return NULL;
	
	/* you aren't allowed at the packets this way if a callback is enabled... */
	if (con->callback) {
		xbee_log(1,"Cannot retrieve a packet while callback is enabled for connection @ %p", con);
		return NULL;
	}
	
	/* try to get a packet */
	if ((pkt = (struct xbee_pkt*)ll_ext_head(&(con->rxList))) == NULL) {
		/* if there isnt one, then log a message */
		xbee_log(10,"No packets for connection @ %p", con);
		return NULL;
	}
	/* if there is one, then log its details and return it */
	xbee_log(2,"Gave a packet @ %p to the user from connection @ %p, %d remain...", pkt, con, ll_count_items(&(con->rxList)));
	return pkt;
}
Пример #3
0
int main(void) {
	void *d;
	struct xbee *xbee;
	struct xbee_con *con;
	char txRet;
	xbee_err ret;

	if ((ret = xbee_setup(&xbee, "xbee2", "/dev/ttyUSB1", 57600)) != XBEE_ENONE) {
		printf("ret: %d (%s)\n", ret, xbee_errorToStr(ret));
		return ret;
	}
	if ((ret = xbee_conNew(xbee, &con, "Identify", NULL)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conNew() returned: %d (%s)", ret, xbee_errorToStr(ret));
		return ret;
	}

	if ((ret = xbee_conCallbackSet(con, myCB, NULL)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conCallbackSet() returned: %d", ret);
		return ret;
	}
	
	sleep(3000);
	
	if ((ret = xbee_conEnd(con)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conEnd() returned: %d", ret);
		return ret;
	}

	xbee_shutdown(xbee);

	return 0;
}
Пример #4
0
void catchallCB(struct xbee *xbee, struct xbee_con *con, struct xbee_pkt **pkt, void **data) {
	xbee_err ret;
	struct xbee_con *newCon;
	
	printf("Got packet from new node!\n");
	if ((*pkt)->address.addr16_enabled) {
		printf("    16-bit (0x%02X%02X)\n", (*pkt)->address.addr16[0], (*pkt)->address.addr16[1]);
	}
	if ((*pkt)->address.addr64_enabled) {
		printf("    64-bit (0x%02X%02X%02X%02X 0x%02X%02X%02X%02X)\n", (*pkt)->address.addr64[0], (*pkt)->address.addr64[1],
		                                                               (*pkt)->address.addr64[2], (*pkt)->address.addr64[3],
		                                                               (*pkt)->address.addr64[4], (*pkt)->address.addr64[5],
		                                                               (*pkt)->address.addr64[6], (*pkt)->address.addr64[7]);
	}
	if ((*pkt)->address.endpoints_enabled) {
		printf("    Endpoints (local: 0x%02X, remote: 0x%02X)\n", (*pkt)->address.endpoint_local,
		                                                          (*pkt)->address.endpoint_remote);
	}
	
	/* you should really hold on to the returned newCon somehow, but for the sample it is just let loose! */
	if ((ret = xbee_conNew(xbee, &newCon, (*pkt)->conType, &(*pkt)->address)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conNew() returned: %d (%s)", ret, xbee_errorToStr(ret));
		return;
	}

	if ((ret = xbee_conCallbackSet(newCon, specificCB, NULL)) != XBEE_ENONE) {
		xbee_conEnd(newCon);
		xbee_log(xbee, -1, "xbee_conCallbackSet() returned: %d", ret);
		return;
	}
	
	specificCB(xbee, newCon, pkt, data);
}
Пример #5
0
int main(void) {
	void *d;
	struct xbee *xbee;
	struct xbee_con *con;
	struct xbee_conAddress address;
	xbee_err ret;

	if ((ret = xbee_setup(&xbee, "xbee1", "/dev/ttyUSB0", 9600)) != XBEE_ENONE) {
		printf("ret: %d (%s)\n", ret, xbee_errorToStr(ret));
		return ret;
	}

	memset(&address, 0, sizeof(address));
	address.addr64_enabled = 1;
	address.addr64[0] = 0x00;
	address.addr64[1] = 0x13;
	address.addr64[2] = 0xA2;
	address.addr64[3] = 0x00;
	address.addr64[4] = 0x40;
	address.addr64[5] = 0x08;
	address.addr64[6] = 0x18;
	address.addr64[7] = 0x26;
	if ((ret = xbee_conNew(xbee, &con, "64-bit Data", &address)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conNew() returned: %d (%s)", ret, xbee_errorToStr(ret));
		return ret;
	}

	if ((ret = xbee_conDataSet(con, xbee, NULL)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conDataSet() returned: %d", ret);
		return ret;
	}

	if ((ret = xbee_conCallbackSet(con, myCB, NULL)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conCallbackSet() returned: %d", ret);
		return ret;
	}

	for (;;) {
		void *p;

		if ((ret = xbee_conCallbackGet(con, (xbee_t_conCallback*)&p)) != XBEE_ENONE) {
			xbee_log(xbee, -1, "xbee_conCallbackGet() returned: %d", ret);
			return ret;
		}

		if (p == NULL) break;

		usleep(1000000);
	}

	if ((ret = xbee_conEnd(con)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conEnd() returned: %d", ret);
		return ret;
	}

	xbee_shutdown(xbee);

	return 0;
}
Пример #6
0
int main(void) {
	void *d;
	struct xbee *xbee;
	struct xbee_con *con;
	struct xbee_pkt *pkt;
	struct xbee_conAddress address;
	char txRet;
	int i;
	xbee_err ret;

	if ((ret = xbee_setup(&xbee, "xbee2", "/dev/ttyUSB1", 57600)) != XBEE_ENONE) {
		printf("ret: %d (%s)\n", ret, xbee_errorToStr(ret));
		return ret;
	}

	memset(&address, 0, sizeof(address));
	address.addr64_enabled = 1;
	address.addr64[0] = 0x00;
	address.addr64[1] = 0x13;
	address.addr64[2] = 0xA2;
	address.addr64[3] = 0x00;
	address.addr64[4] = 0x40;
	address.addr64[5] = 0x2D;
	address.addr64[6] = 0x60;
	address.addr64[7] = 0x7B;
	if ((ret = xbee_conNew(xbee, &con, "Remote AT", &address)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conNew() returned: %d (%s)", ret, xbee_errorToStr(ret));
		return ret;
	}
	
	for (i = 0; i < 60 * 4; i++) {
		unsigned char value;
		if ((ret = xbee_conTx(con, NULL, "IS")) != XBEE_ENONE) break;
		if ((ret = xbee_conRx(con, &pkt, NULL)) != XBEE_ENONE) break;
		
		if ((ret = xbee_pktDigitalGet(pkt, 3, 0, &value)) != XBEE_ENONE) {
			printf("xbee_pktDigitalGet(channel=3): ret %d\n", ret);
		} else {
			printf("D3: %d\n", value);
		}
		
		xbee_pktFree(pkt);
		usleep(250000);
	}
	if (ret != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conTx() or xbee_conRx() returned: %d", ret);
		return ret;
	}
	
	if ((ret = xbee_conEnd(con)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conEnd() returned: %d", ret);
		return ret;
	}

	xbee_shutdown(xbee);

	return 0;
}
Пример #7
0
int main(void) {
	void *d;
	struct xbee *xbee;
	struct xbee_con *con;
	unsigned char txRet;
	xbee_err ret;

	/* setup libxbee, using the USB to Serial adapter '/dev/ttyUSB0' at 57600 baud */
	if ((ret = xbee_setup(&xbee, "xbee1", "/dev/ttyUSB0", 57600)) != XBEE_ENONE) {
		printf("ret: %d (%s)\n", ret, xbee_errorToStr(ret));
		return ret;
	}

	/* create a new AT connection to the local XBee */
	if ((ret = xbee_conNew(xbee, &con, "Local AT", NULL)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conNew() returned: %d (%s)", ret, xbee_errorToStr(ret));
		return ret;
	}

	/* send the AT command 'NI' (request the Node Identifier)
	   when the response is recieved, the packet will be directed to the callback function */
	ret = xbee_conTx(con, &txRet, "NI");
	/* print out the return value
	   if this is non-zero, then check 'enum xbee_errors' in xbee.h for its meaning
	   alternatively look at the xbee_errorToStr() function */
	printf("tx: %d\n", ret);
	if (ret) {
		/* if ret was non-zero, then some error occured
		   if ret == XBEE_ETX then it is possible that txRet is now -17 / XBEE_ETIMEOUT
		   alternatively, txRet will contain the status code returned by the XBee */
		printf("txRet: %d\n", txRet);
	} else {
		struct xbee_pkt *pkt;
		if ((ret = xbee_conRx(con, &pkt, NULL)) != XBEE_ENONE) {
			printf("Error after calling xbee_conRx(): %s\n", xbee_errorToStr(ret));
		} else {
			int i;
			printf("Response is %d bytes long:\n", pkt->dataLen);
			for (i = 0; i < pkt->dataLen; i++) {
				printf("%3d: 0x%02X - %c\n", i, pkt->data[i], (((pkt->data[i] >= ' ') && (pkt->data[i] <= '~'))?pkt->data[i]:'.'));
			}
		}
	}
	
	/* shutdown the connection */
	if ((ret = xbee_conEnd(con)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conEnd() returned: %d", ret);
		return ret;
	}

	/* shutdown libxbee */
	xbee_shutdown(xbee);

	return 0;
}
Пример #8
0
int main(void) {
	void *d;
	struct xbee *xbee;
	struct xbee_con *con;
	xbee_err ret;
	unsigned char txRet;
	struct timespec to;

	if (sem_init(&ndComplete, 0, 0) != 0) {
		printf("sem_init() returned an error: %d - %s\n", errno, strerror(errno));
		return -1;
	}
	
	if ((ret = xbee_setup(&xbee, "xbee1", "/dev/ttyUSB0", 57600)) != XBEE_ENONE) {
		printf("ret: %d (%s)\n", ret, xbee_errorToStr(ret));
		return ret;
	}

	if ((ret = xbee_conNew(xbee, &con, "Local AT", NULL)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conNew() returned: %d (%s)", ret, xbee_errorToStr(ret));
		return ret;
	}

	if ((ret = xbee_conCallbackSet(con, nodeCB, NULL)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conCallbackSet() returned: %d", ret);
		return ret;
	}

	if ((ret = xbee_conTx(con, &txRet, "ND")) != XBEE_ENONE && (ret != XBEE_ETX && ret != XBEE_ETIMEOUT)) {
		xbee_log(xbee, -1, "xbee_conTx() returned: %d-%d", ret, txRet);
		return ret;
	}

	printf("ND Sent!... waiting for completion\n");

	clock_gettime(CLOCK_REALTIME, &to);
	to.tv_sec  += 10;
	if (sem_timedwait(&ndComplete, &to) != 0) {
		if (errno == ETIMEDOUT) {
			printf("Timeout while waiting for ND command to complete...\n");
		} else {
			printf("Error calling sem_timedwait()... sleeping for 10 seconds instead\n");
			sleep(10);
		}
	}

	if ((ret = xbee_conEnd(con)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conEnd() returned: %d", ret);
		return ret;
	}

	xbee_shutdown(xbee);

	return 0;
}
Пример #9
0
int main(void) {
	void *d;
	struct xbee *xbee;
	struct xbee_con *con;
	struct xbee_conAddress address;
	struct xbee_conSettings settings;
	xbee_err ret;

	if ((ret = xbee_setup(&xbee, "xbee2", "/dev/ttyUSB1", 57600)) != XBEE_ENONE) {
		printf("ret: %d (%s)\n", ret, xbee_errorToStr(ret));
		return ret;
	}

	memset(&address, 0, sizeof(address));
	address.addr64_enabled = 1;
	address.addr64[0] = 0x00;
	address.addr64[1] = 0x00;
	address.addr64[2] = 0x00;
	address.addr64[3] = 0x00;
	address.addr64[4] = 0x00;
	address.addr64[5] = 0x00;
	address.addr64[6] = 0xFF;
	address.addr64[7] = 0xFF;
	if ((ret = xbee_conNew(xbee, &con, "Data", &address)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conNew() returned: %d (%s)", ret, xbee_errorToStr(ret));
		return ret;
	}

	if ((ret = xbee_conCallbackSet(con, myCB, NULL)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conCallbackSet() returned: %d", ret);
		return ret;
	}

	/* getting an ACK for a broadcast message is kinda pointless... */
	xbee_conSettings(con, NULL, &settings);
	settings.disableAck = 1;
	xbee_conSettings(con, &settings, NULL);

	for (;;) {
		xbee_conTx(con, NULL, "Hello...\r\n");

		/* you probrably don't want to transmit much quicker than once per 2 seconds... read the datashee for more info */
		sleep(2);
	}

	if ((ret = xbee_conEnd(con)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conEnd() returned: %d", ret);
		return ret;
	}

	xbee_shutdown(xbee);

	return 0;
}
Пример #10
0
int main(void) {
	void *d;
	struct xbee *xbee;
	struct xbee_con *con;
	struct xbee_conAddress address;
	unsigned char txRet;
	xbee_err ret;

	if ((ret = xbee_setup(&xbee, "xbee2", "/dev/ttyUSB1", 57600)) != XBEE_ENONE) {
		printf("ret: %d (%s)\n", ret, xbee_errorToStr(ret));
		return ret;
	}

	/* this is the 64-bit address of the remote XBee module
	   it should be entered with the MSB first, so the address below is
	   SH = 0x0013A200    SL = 0x40081826 */
	memset(&address, 0, sizeof(address));
	address.addr64_enabled = 1;
	address.addr64[0] = 0x00;
	address.addr64[1] = 0x13;
	address.addr64[2] = 0xA2;
	address.addr64[3] = 0x00;
	address.addr64[4] = 0x40;
	address.addr64[5] = 0x2D;
	address.addr64[6] = 0x60;
	address.addr64[7] = 0x7B;
	if ((ret = xbee_conNew(xbee, &con, "Remote AT", &address)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conNew() returned: %d (%s)", ret, xbee_errorToStr(ret));
		return ret;
	}

	if ((ret = xbee_conCallbackSet(con, myCB, NULL)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conCallbackSet() returned: %d", ret);
		return ret;
	}
	
	ret = xbee_conTx(con, &txRet, "NI");
	printf("tx: %d\n", ret);
	if (ret) {
		printf("txRet: %d\n", txRet);
	} else {
		usleep(1000000);
	}
	
	if ((ret = xbee_conEnd(con)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conEnd() returned: %d", ret);
		return ret;
	}

	xbee_shutdown(xbee);

	return 0;
}
Пример #11
0
/* write the provided address information to the log */
void xbee_conLogAddress(struct xbee *xbee, struct xbee_conAddress *address) {
	if (address->addr16_enabled) {
		xbee_log(6,"16-bit address: 0x%02X%02X", address->addr16[0], address->addr16[1]);
	}
	if (address->addr64_enabled) {
		xbee_log(6,"64-bit address: 0x%02X%02X%02X%02X 0x%02X%02X%02X%02X",
							 address->addr64[0], address->addr64[1], address->addr64[2], address->addr64[3],
							 address->addr64[4], address->addr64[5], address->addr64[6], address->addr64[7]);
	}
	if (address->endpoints_enabled) {
		xbee_log(6,"Endpoints (local/remote): 0x%02X/0x%02X", address->local_endpoint, address->remote_endpoint);
	}
}
Пример #12
0
int main(void) {
	void *d;
	struct xbee *xbee;
	struct xbee_con *con;
	struct xbee_conAddress address;
	struct xbee_conSettings settings;
	xbee_err ret;

	if ((ret = xbee_setup(&xbee, "xbee1", "/dev/ttyUSB0", 57600)) != XBEE_ENONE) {
		printf("ret: %d (%s)\n", ret, xbee_errorToStr(ret));
		return ret;
	}

	memset(&address, 0, sizeof(address));
	address.addr64_enabled = 1;
	address.addr64[0] = 0x00;
	address.addr64[1] = 0x00;
	address.addr64[2] = 0x00;
	address.addr64[3] = 0x00;
	address.addr64[4] = 0x00;
	address.addr64[5] = 0x00;
	address.addr64[6] = 0xFF;
	address.addr64[7] = 0xFF;
	if ((ret = xbee_conNew(xbee, &con, "64-bit Data", &address)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conNew() returned: %d (%s)", ret, xbee_errorToStr(ret));
		return ret;
	}

	xbee_conSettings(con, NULL, &settings);
	settings.catchAll = 1;
	xbee_conSettings(con, &settings, NULL);

	if ((ret = xbee_conCallbackSet(con, catchallCB, NULL)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conCallbackSet() returned: %d", ret);
		return ret;
	}

	printf("Ready!... waiting for 30 secs\n");
	
	usleep(30000000);

	if ((ret = xbee_conEnd(con)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conEnd() returned: %d", ret);
		return ret;
	}

	xbee_shutdown(xbee);

	return 0;
}
Пример #13
0
int main(void) {
	void *d;
	struct xbee *xbee;
	struct xbee_con *con;
	struct xbee_conAddress address;
	char txRet;
	xbee_err ret;

	if ((ret = xbee_setup(&xbee, "xbee2", "/dev/ttyUSB1", 57600)) != XBEE_ENONE) {
		printf("ret: %d (%s)\n", ret, xbee_errorToStr(ret));
		return ret;
	}

	memset(&address, 0, sizeof(address));
	address.addr64_enabled = 1;
	address.addr64[0] = 0x00;
	address.addr64[1] = 0x13;
	address.addr64[2] = 0xA2;
	address.addr64[3] = 0x00;
	address.addr64[4] = 0x40;
	address.addr64[5] = 0x2D;
	address.addr64[6] = 0x60;
	address.addr64[7] = 0x7B;
	if ((ret = xbee_conNew(xbee, &con, "Remote AT", &address)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conNew() returned: %d (%s)", ret, xbee_errorToStr(ret));
		return ret;
	}

	if ((ret = xbee_conCallbackSet(con, myCB, NULL)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conCallbackSet() returned: %d", ret);
		return ret;
	}
	
	ret = xbee_conTx(con, &txRet, "NI");
	printf("tx: %d\n", ret);
	if (ret) {
		printf("txRet: %d\n", txRet);
	} else {
		sleep(1);
	}
	
	if ((ret = xbee_conEnd(con)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conEnd() returned: %d", ret);
		return ret;
	}

	xbee_shutdown(xbee);

	return 0;
}
Пример #14
0
xbee_err _xbee_logData(const char *file, int line, const char *function, struct xbee *xbee, int minLevel, char *label, unsigned char *data, size_t length) {
	int i;
	int l;
	/* format:
		0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00  | ........
	*/
	char lineBufA[41];
	char lineBufB[9];
	
	/* prepare the format string */
	for (l = 0; l < sizeof(lineBufA) - 1; l++) {
		switch (l % 5) {
			case 0: case 2: case 3:
				lineBufA[l] = '0'; break;
			case 1:
				lineBufA[l] = 'x'; break;
			case 4:
				lineBufA[l] = ' '; break;
		}
	}
	lineBufA[l] = '\0';
	lineBufB[sizeof(lineBufB) - 1] = '\0';
	
	xbee_log(25, "%s length: %d", label, length);
	
	for (i = 0; i < length; i += l) {
		/* fill in the data */
		for (l = 0; l < 8 && i + l < length; l++) {
			snprintf(&(lineBufA[(5 * l) + 2]), 3, "%02X", data[i + l]);
			lineBufA[(5 * l) + 4] = ' ';
			lineBufB[l] = ((data[i + l] >= ' ' && data[i + l] <= '~')?data[i + l]:'.');
		}
		/* wipe out the unneeded space */
		for (; l < 8; l++) {
			strncpy(&(lineBufA[5 * l]), "     ", 6);
			lineBufB[l] = ' ';
		}
		xbee_log(25, "%s: 0x%04X : %s | %s", label, i, lineBufA, lineBufB);
	}
	
	return XBEE_ENONE;
}
Пример #15
0
xbee_err xbee_rx(struct xbee *xbee, int *restart, void *arg) {
	xbee_err ret;
	struct xbee_rxInfo *info;
	struct xbee_tbuf *buf;
	
	info = arg;
	if (!info->bufList || !info->ioFunc) {
		*restart = 0;
		return XBEE_EINVAL;
	}
	
	while (!xbee->die) {
		buf = NULL;
		if ((ret = info->ioFunc(xbee, info->ioArg, &buf)) != XBEE_ENONE) {
			if (ret == XBEE_EEOF) {
				*restart = 0;
				if (info->eofCallback) info->eofCallback(xbee, info);
				return XBEE_EEOF;
			} else if (ret == XBEE_ESHUTDOWN && xbee->die) {
				break;
			}
			xbee_log(1, "rx() returned %d (%s)... retrying in 10 ms", ret, xbee_errorToStr(ret));
			usleep(10000); /* 10 ms */
			continue;
		}

#ifndef XBEE_DISABLE_LOGGING
#ifndef XBEE_LOG_NO_RX
		if (xbee->log->enable_rx) {
			/* format: tx[0x0000000000000000] */
			char label[42]; /* enough space for a 64-bit pointer and ANSI color codes */
#ifndef XBEE_LOG_NO_COLOR
			if (xbee->log->use_color) {
				snprintf(label, sizeof(label), "Rx[%c[%dm%p%c[0m]", 27, 30 + info->logColor, info,  27);
			} else {
#endif /* !XBEE_LOG_NO_COLOR */
				snprintf(label, sizeof(label), "Rx[%p]", info);
#ifndef XBEE_LOG_NO_COLOR
			}
#endif /* !XBEE_LOG_NO_COLOR */
			xbee_logData(25, label, buf->data, buf->len);
		}
#endif /* !XBEE_LOG_NO_RX */
#endif /* !XBEE_DISABLE_LOGGING */
		
		if (xbee_ll_add_tail(info->bufList, buf) != XBEE_ENONE) return XBEE_ELINKEDLIST;
		buf = NULL;
		if (xsys_sem_post(&info->sem) != 0) return XBEE_ESEMAPHORE;
	}
	
	return XBEE_ESHUTDOWN;
}
Пример #16
0
int main(void) {
	void *d;
	struct xbee *xbee;
	struct xbee_con *con;
	char txRet;
	xbee_err ret;

	if ((ret = xbee_setup(&xbee, "xbee1", "/dev/ttyUSB0", 57600)) != XBEE_ENONE) {
		printf("ret: %d (%s)\n", ret, xbee_errorToStr(ret));
		return ret;
	}

	if ((ret = xbee_conNew(xbee, &con, "Local AT", NULL)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conNew() returned: %d (%s)", ret, xbee_errorToStr(ret));
		return ret;
	}

	if ((ret = xbee_conCallbackSet(con, myCB, NULL)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conCallbackSet() returned: %d", ret);
		return ret;
	}
	
	ret = xbee_conTx(con, &txRet, "NI");
	printf("tx: %d\n", ret);
	if (ret) {
		printf("txRet: %d\n", txRet);
	} else {
		sleep(1);
	}
	
	if ((ret = xbee_conEnd(con)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conEnd() returned: %d", ret);
		return ret;
	}

	xbee_shutdown(xbee);

	return 0;
}
Пример #17
0
int main(void) {
	void *d;
	struct xbee *xbee;
	struct xbee_con *con;
	struct xbee_conAddress address;
	xbee_err ret;

	if ((ret = xbee_setup(&xbee, "debug", "xbee1")) != XBEE_ENONE) {
		printf("ret: %d (%s)\n", ret, xbee_errorToStr(ret));
		return ret;
	}

	memset(&address, 0, sizeof(address));
	address.addr64_enabled = 1;
	address.addr64[0] = 0x00;
	address.addr64[1] = 0x13;
	address.addr64[2] = 0xA2;
	address.addr64[3] = 0x00;
	address.addr64[4] = 0x40;
	address.addr64[5] = 0x08;
	address.addr64[6] = 0x18;
	address.addr64[7] = 0x26;
	if ((ret = xbee_conNew(xbee, &con, "64-bit Data", &address)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conNew() returned: %d (%s)", ret, xbee_errorToStr(ret));
		return ret;
	}

	xbee_conTx(con, NULL, "testing...");

	if ((ret = xbee_conEnd(con)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conEnd() returned: %d", ret);
		return ret;
	}

	xbee_shutdown(xbee);

	return 0;
}
Пример #18
0
EXPORT xbee_err xbee_logTargetSet(struct xbee *xbee, FILE *f) {
	if (!xbee) return XBEE_EMISSINGPARAM;
#ifndef XBEE_DISABLE_STRICT_OBJECTS
	if (xbee_validate(xbee) != XBEE_ENONE) return XBEE_EINVAL;
#endif /* XBEE_DISABLE_STRICT_OBJECTS */
	if (!xbee->log) return XBEE_ENOTIMPLEMENTED;
	
	xbee_mutex_lock(&xbee->log->mutex);
	xbee->log->f = f;
	xbee_mutex_unlock(&xbee->log->mutex);
	xbee_log(xbee->log->logLevel, "Set log target to: %p (fd:%d)", f, xsys_fileno(f));
	
	return XBEE_ENONE;
}
Пример #19
0
EXPORT xbee_err xbee_logLevelSet(struct xbee *xbee, int level) {
	if (!xbee) return XBEE_EMISSINGPARAM;
#ifndef XBEE_DISABLE_STRICT_OBJECTS
	if (xbee_validate(xbee) != XBEE_ENONE) return XBEE_EINVAL;
#endif /* XBEE_DISABLE_STRICT_OBJECTS */
	if (!xbee->log) return XBEE_ENOTIMPLEMENTED;
	
	xbee_mutex_lock(&xbee->log->mutex);
	xbee->log->logLevel = level;
	xbee_mutex_unlock(&xbee->log->mutex);
	xbee_log(xbee->log->logLevel, "Set log level to: %d", level);
	
	return XBEE_ENONE;
}
Пример #20
0
/* set the callback for a connection
   this function can provide the previously set callback, as well as assign a new one */
EXPORT int xbee_conAttachCallback(struct xbee *xbee, struct xbee_con *con, void(*callback)(struct xbee *xbee, struct xbee_con *con, struct xbee_pkt **pkt, void **userData), void **prevCallback) {
	struct xbee_conType *conType;
	
	/* check parameters */
	if (!xbee) {
		if (!xbee_default) return XBEE_ENOXBEE;
		xbee = xbee_default;
	}
	if (!xbee_validate(xbee)) return XBEE_ENOXBEE;
	if (!con) return XBEE_EMISSINGPARAM;
	
	/* check the connection */
	if (_xbee_conValidate(xbee, con, &conType)) return XBEE_EINVAL;
	
	/* give the currently assigned callback */
	if (prevCallback) *prevCallback = con->callback;
	
	/* we don't need to kill the existing callback, because it is refreshed each time the callback function returns */
	
	/* assign the new callback */
	con->callback = callback;
	
	/* and if a callback was assigned, kick it off */
	if (callback) {
		xbee_log(5,"Attached callback to connection @ %p", con);
		/* but only kick it off if there are packets in the queue */
		if (ll_count_items(&con->rxList)) {
			xbee_log(5,"... and triggering callback due to packets in queue");
			xbee_triggerCallback(xbee, con);
		}
	} else {
		/* otherwise log that we disabled callbacks for this connection */
		xbee_log(5,"Detached callback from connection @ %p", con);
	}
	
	return XBEE_ENONE;
}
Пример #21
0
int setupXbee(struct xbee **xbee, char *port, struct xbee_con **con, unsigned int addrH, unsigned int addrL) {
	int ret;
	char conType;
	struct xbee_conAddress addr;

	/* make a lixbee instance, and connect it to /dev/ttyUSB1 @ 57600 baud
	   you don't have to keep hold of the returned xbee, in which case you can pass NULL and the most recently started instance will be used! */
	if ((ret = xbee_setup(port, 57600, xbee)) != 0) {
		fprintf(stderr,"xbee_setup(): failed... (%d)\n", ret);
		return 1;
	}

	/* setup libxbee to use the series 1 packets - you have to do this before you do anything else! */
	xbee_modeSet(*xbee, "series2");

	/* get the connection type ID, you pass in a string, it returns an ID */
	if ((ret = xbee_conTypeIdFromName(*xbee, "Data (explicit)", &conType)) != 0) {
		fprintf(stderr, "xbee_conTypeIdFromName(): failed... (%d)\n", ret);
		return 2;
	}
	
	/* clear the address field */
	memset(&addr, 0, sizeof(addr));
	/* build a connection to the following address */
	addr.addr64_enabled = 1;
	addr.addr64[0] = ((addrH >> 24) & 0xFF);
	addr.addr64[1] = ((addrH >> 16) & 0xFF);
	addr.addr64[2] = ((addrH >> 8)  & 0xFF);
	addr.addr64[3] = ((addrH)       & 0xFF);
	addr.addr64[4] = ((addrL >> 24) & 0xFF);
	addr.addr64[5] = ((addrL >> 16) & 0xFF);
	addr.addr64[6] = ((addrL >> 8)  & 0xFF);
	addr.addr64[7] = ((addrL)       & 0xFF);
	addr.endpoints_enabled = 0;
	if ((ret = xbee_conNew(*xbee, con, conType, &addr, NULL)) != 0) {
		fprintf(stderr, "xbee_newcon(): failed... (%d)\n", ret);
		return 3;
	}

	if ((ret = xbee_conAttachCallback(*xbee, *con, myCB, NULL)) != 0) {
		fprintf(stderr, "xbee_conAttachCallback(): failed (%d)\n", ret);
		return 4;
	}

	/* you have access to the error log! Your messages will be prefixed with "DEV:" */
	xbee_log(*xbee,0,"Hello! [%s]", port);

	return 0;
}
Пример #22
0
/* just echo it back */
void callback(struct xbee *xbee, struct xbee_con *con, struct xbee_pkt **pkt, void **data) {
	xbee_err ret;
	unsigned char retVal;
	int seq;
	int pktLen;

	if ((*pkt)->dataLen < 6) {
		xbee_log(xbee, -10, "SHRT - short packet...");
		ret = xbee_conTx(con, &retVal, "SHRT");
	} else {

		seq  = ((*pkt)->data[0] << 24) & 0xFF000000;
		seq |= ((*pkt)->data[1] << 16) & 0xFF0000;
		seq |= ((*pkt)->data[2] <<  8) & 0xFF00;
		seq |= ((*pkt)->data[3]      ) & 0xFF;

		pktLen  = (((*pkt)->data[4]) << 8) & 0xFF00;
		pktLen |= (((*pkt)->data[5])     ) & 0xFF;

		if (pktLen < 6 || pktLen != (*pkt)->dataLen - 6) {
			xbee_log(xbee, -10, "XLEN - packet length mismatch... (rx'd %d / expected %d bytes)", (*pkt)->dataLen - 6, pktLen);
			ret = xbee_conTx(con, &retVal, "XLEN");
		} else if (seq >= PACKET_COUNT) {
			xbee_log(xbee, -10, "DONE - test complete!");
			ret = xbee_conTx(con, &retVal, "DONE");
			*data = NULL;
		} else {
			xbee_log(xbee, -10, "Tx #%d", seq);
			ret = xbee_connTx(con, &retVal, (*pkt)->data, (*pkt)->dataLen);
		}
	}

	if (ret != XBEE_ENONE) {
		xbee_log(xbee, -1, "ret = %d      retVal = %d", ret, retVal);
	}
}
Пример #23
0
/* end a connection
   the userData parameter can be used to retrieve the data stored with the connection */
EXPORT int xbee_conEnd(struct xbee *xbee, struct xbee_con *con, void **userData) {
	struct xbee_conType *conType;
	struct xbee_pkt *pkt;
	int i;
	
	/* check parameters */
	if (!xbee) {
		if (!xbee_default) return XBEE_ENOXBEE;
		xbee = xbee_default;
	}
	if (!xbee_validate(xbee)) return XBEE_ENOXBEE;
	if (!con) return XBEE_EMISSINGPARAM;
	
	/* check the connection */
	if (_xbee_conValidate(xbee, con, &conType)) return XBEE_EINVAL;
	
	/* remove the connection from the list */
	if (ll_ext_item(&(conType->conList), con)) return XBEE_EINVAL;
	
	/* chop up any queued packets */
	for (i = 0; (pkt = ll_ext_head(&(con->rxList))) != NULL; i++) {
		xbee_pktFree(pkt);
	}
	xbee_log(2,"Ended '%s' connection @ %p (destroyed %d packet%s)", conType->name, con, i, (i!=1)?"s":"");

	/* if the userData parameter is provided, then give the con's userData back to the caller */
	if (userData) *userData = con->userData;

	/* if there is a callback thread running, then kill it off */
	if (con->callbackRunning) {
		con->destroySelf = 1;
		xsys_sem_post(&con->callbackSem);
		
		/* inform the caller that we are waiting for the callback to complete */
		return XBEE_ECALLBACK;
	}

	/* it is only safe to call _xbee_conEnd2() once the callback thread has completed, this will finish tidying up the connection */
	return _xbee_conEnd2(xbee, con);
}
Пример #24
0
/* the thread monitoring thread... hmm */
void xbee_threadMonitor(struct xbee *xbee) {
	struct threadInfo *info;
	void *tRet;
	int ret;
	int count, joined, restarted;
	
	/* detach self, so that resources are free'd as soon as we return */
	xsys_thread_detach_self();
	
	while (xbee->running) {
		/* wait for 10 seconds, unless prodded */
		xsys_sem_timedwait(&xbee->semMonitor, 10, 0);
		
		xbee_log(15,"Scanning for dead threads...");
		
		/* keep track of some stats */
		count = 0;
		joined = 0;
		restarted = 0;
		
		/* iterate through each monitored thread */
		for (info = NULL; (info = ll_get_next(&xbee->threadList, info)) != NULL;) {
			/* if thread is supposed to be running */
			if (info->running) {
#warning TODO - find an alternative to pthread_tryjoin_np()
				/* try to join with the thread */
				if ((ret = xsys_thread_tryjoin(*info->thread, &tRet)) == 0) {
					/* apparently it died! mark it dead, and report it */
					info->running = 0;
					xbee_log(15,"Thread 0x%X died (%s), it returned 0x%X", info->thread, info->funcName, ret);
					joined++;
				} else {
					/* if the join failed, then find out why (to the best of our ability) and log the details */
					if (ret == EBUSY) {
						xbee_log(10,"xsys_thread_tryjoin(): 0x%X (%s) EBUSY", info->thread, info->funcName);
					} else if (ret == ETIMEDOUT) {
						xbee_log(10,"xsys_thread_tryjoin(): 0x%X (%s) ETIMEDOUT", info->thread, info->funcName);
					} else if (ret == EINVAL) {
						xbee_log(10,"xsys_thread_tryjoin(): 0x%X (%s) EINVAL", info->thread, info->funcName);
					} else {
						xbee_log(10,"xsys_thread_tryjoin(): 0x%X (%s) unknown (%d)", info->thread, info->funcName, ret);
					}
					count++;
				}
			}
			
			/* we need to re-test info->running, because it may have just been marked dead */
			if (!info->running) {
				/* try to restart the thread */
				if (xsys_thread_create(info->thread, info->start_routine, info->arg) == 0) {
					/* success! keep the stats */
					restarted++;
					info->restartCount++;
					info->running = 1;
				} else {
					/* otherwise log the info */
					xbee_log(10,"Failed to restart thread (%s)...\n", info->funcName);
				}
			}
		}
		
		/* log the stats */
		xbee_log(15,"Scan complete! joined/restarted/remain %d/%d/%d threads", joined, restarted, count);
	}
}
Пример #25
0
/* transmit a message on the provided connection
   this function takes the raw data and its length */
EXPORT int xbee_connTx(struct xbee *xbee, struct xbee_con *con, char *data, int length) {
	int ret = XBEE_ENONE;
	struct bufData *buf;
	struct xbee_conType *conType;
	int waitForAckEnabled;
	
	/* check parameters */
	if (!xbee) {
		if (!xbee_default) return XBEE_ENOXBEE;
		xbee = xbee_default;
	}
	if (!xbee_validate(xbee)) return XBEE_ENOXBEE;
	if (!con) return XBEE_EMISSINGPARAM;
	
	/* check the provided connection */
	if (_xbee_conValidate(xbee, con, &conType)) return XBEE_EINVAL;
	
	/* check that we are able to send the message,
	   if there is no xbee->f->connTx mapping, then we need a conType->txHandler */
	if (!conType->txHandler && !xbee->f->connTx) return XBEE_ECANTTX;
	
	/* allocate a buffer, 1 byte is already held within the bufData struct, and we don't send the trailing '\0' */
	if ((buf = calloc(1, sizeof(struct bufData) + (sizeof(unsigned char) * (length - 1)))) == NULL) {
		ret = XBEE_ENOMEM;
		goto die1;
	}
	
	/* populate the buffer */
	buf->len = length;
	memcpy(buf->buf, data, length);
	
	/* cache the value of waitForAck, because it may change halfway through! */
	waitForAckEnabled = con->options.waitForAck;
	
	/* if the connection has 'waitForAck' enabled, then we need to get a free FrameID that can be used */
	if (waitForAckEnabled) {
		/* if we are configured to wait for an Ack, then we need to lock down the connection */
		xbee_log(4,"Locking txMutex for con @ %p", con);
		xsys_mutex_lock(&con->txMutex);
		if ((con->frameID = xbee_frameIdGet(xbee, con)) == 0) {
			/* currently we don't inform the user (BAD), but this is unlikely unless you are communicating with >256 remote nodes */
			xbee_log(1,"No avaliable frame IDs... we can't validate delivery");
			xbee_log(4,"Unlocking txMutex for con @ %p (failed to get FrameID)", con);
			xsys_mutex_unlock(&con->txMutex);
		} else {
			/* mark the FrameID as present */
			con->frameID_enabled = 1;
		}
	}
	
	/* if there is a custom mapping for connTx, then the handlers are skipped (but can be called from within the mapping!) */
	if (!xbee->f->connTx) {
		struct bufData *oBuf;
		oBuf = buf;
		
		/* execute the conType handler, this should take the data provided, and convert it into an XBee formatted block of data
		   this is given, and returned via the 'buf' argument */
		xbee_log(6,"Executing handler (%s)...", conType->txHandler->handlerName);
		if ((ret = conType->txHandler->handler(xbee, conType->txHandler, 0, &buf, con, NULL)) != XBEE_ENONE) goto die2;
		
		/* a bit of sanity checking... */
		if (!buf || buf == oBuf) {
			ret = XBEE_EUNKNOWN;
			goto die2;
		}
		free(oBuf);
	}
	
	if (!xbee->f->connTx) {
		/* if there is no connTx mapped, then add the packet to libxbee's txlist, and prod the tx thread */
		ll_add_tail(&xbee->txList, buf);
		xsys_sem_post(&xbee->txSem);
	} else {
		/* same as before, if a mapping is registered, then the packet isn't queued for Tx, at least not here
		   instead we execute the mapped function */
		if ((ret = xbee->f->connTx(xbee, con, buf)) != XBEE_ENONE) goto die2;
	}
	
	/* if we should be waiting for an Ack, we now need to wait */
	if (waitForAckEnabled && con->frameID) {
		xbee_log(4,"Waiting for txSem for con @ %p", con);
		/* the wait occurs inside xbee_frameIdGetACK() */
		ret = xbee_frameIdGetACK(xbee, con, con->frameID);
		if (ret) xbee_log(4,"--- xbee_frameIdGetACK() returned: %d",ret);
		/* unlock the connection so that other transmitters may follow on */
		xbee_log(4,"Unlocking txMutex for con @ %p", con);
		xsys_mutex_unlock(&con->txMutex);
	}
	/* disable the frameID */
	con->frameID_enabled = 0;
	
	goto done;
die2:
	free(buf);
die1:
done:
	return ret;
}
Пример #26
0
static xbee_err prepare_backchannel(struct xbee *xbee) {
	xbee_err ret;
	struct xbee_modeData *data;
	unsigned char retVal;
	struct xbee_conAddress address;
	struct xbee_pkt *pkt;
	int callbackCount;
	int i, pos, slen;
	struct xbee_con *bc_start;
	
	data = xbee->modeData;
	pkt = NULL;
	
	/* create the 'start' backchannel connection - this is ALWAYS ON ENDPOINT 0x00 */
	memset(&address, 0, sizeof(address));
	address.endpoints_enabled = 1;
	address.endpoint_local = 0;
	address.endpoint_remote = 0;
	
	if ((ret = _xbee_conNew(xbee, &xbee->iface, 1, &bc_start, "backchannel", &address)) != XBEE_ENONE) return ret;
	
	/* transmit our libxbee_commit string - the git commit id */
	if ((ret = xbee_conTx(bc_start, &retVal, "%s", libxbee_commit)) != XBEE_ENONE) {
		switch (retVal) {
			case 1:
				xbee_log(0, "The server encountered an internal error");
				break;
			case 2:
				xbee_log(0, "The server is running a different version of libxbee");
				break;
			default:
				xbee_log(0, "Failed to initialize connection to server for an unknown reason...");
		}
		goto done;
	}
	
	/* grab the returned data (an in-order list of the back channel endpoints, starting at 0x01) */
	if ((ret = xbee_conRx(bc_start, &pkt, NULL)) != XBEE_ENONE) goto done;
	
	/* pick out the remote system's mode name, and try to locate it */
	for (i = 0; i < pkt->dataLen && pkt->data[i] != '\0'; i++);
	if (i > 0) {
		if ((data->serverModeName = malloc(sizeof(char) * (i + 1))) == NULL) {
			ret = XBEE_ENOMEM;
			goto done;
		}
		strncpy(data->serverModeName, (char*)pkt->data, i);
		data->serverModeName[i] = '\0';
		
		if (xbee_modeRetrieve(data->serverModeName, &data->serverMode) != XBEE_ENONE) {
			xbee_log(-10, "WARNING: remote mode '%s' is not avaliable on this system... Some packets may not be fully processed", data->serverModeName);
		}
	}
	
	callbackCount = pkt->data[i + 1];
	
	memset(&address, 0, sizeof(address));
	address.endpoints_enabled = 1;
	
	for (pos = i + 2, i = 1; pos < pkt->dataLen && i < callbackCount + 1; pos += slen + 1, i++) {
		char *name;
		struct xbee_con **retCon;
		
		name = (char *)&(pkt->data[pos]);
		slen = strlen(name);
		
		/* check for a buffer overflow */
		if (slen > pkt->dataLen - pos) {
			slen = pkt->dataLen - pos;
			name[slen] = '\0';
		}
		
		retCon = NULL;
		
		/* try to match the string with an element in struct xbee_modeData */
#define TRY(conName)  if (!data->bc_##conName && !strncasecmp(name, #conName, slen))
		TRY (conValidate) {
			retCon = &data->bc_conValidate;
		} else TRY (conSleep) {
			retCon = &data->bc_conSleep;
		} else TRY (conSettings) {
Пример #27
0
/* Init kmsg input */
int in_xbee_init(struct flb_config *config)
{
    int ret;
    int opt_baudrate = 9600;
    char *tmp;
    char *opt_device = FLB_XBEE_DEFAULT_DEVICE;
    struct stat dev_st;
	struct xbee *xbee;
	struct xbee_con *con;
	struct xbee_conAddress address;
    struct flb_in_xbee_config *ctx;

    /* Check an optional baudrate */
    tmp = getenv("FLB_XBEE_BAUDRATE");
    if (tmp) {
        opt_baudrate = atoi(tmp);
    }

    /* Get the target device entry */
    tmp = getenv("FLB_XBEE_DEVICE");
    if (tmp) {
        opt_device = strdup(tmp);
    }
    flb_info("XBee device=%s, baudrate=%i", opt_device, opt_baudrate);

    ret = stat(opt_device, &dev_st);
    if (ret < 0) {
        printf("Error: could not open %s device\n", opt_device);
        exit(EXIT_FAILURE);
    }

    if (!S_ISCHR(dev_st.st_mode)) {
        printf("Error: invalid device %s \n", opt_device);
        exit(EXIT_FAILURE);
    }

    if (access(opt_device, R_OK | W_OK) == -1) {
        printf("Error: cannot open the device %s (permission denied ?)\n",
               opt_device);
        exit(EXIT_FAILURE);
    }

    /* Init library */
    xbee_init();

	ret = xbee_setup(&xbee, "xbeeZB", opt_device, opt_baudrate);
    if (ret != XBEE_ENONE) {
        flb_utils_error_c("xbee_setup");
		return ret;
	}

    /* FIXME: just a built-in example */
	memset(&address, 0, sizeof(address));
	address.addr64_enabled = 1;
	address.addr64[0] = 0x00;
	address.addr64[1] = 0x13;
	address.addr64[2] = 0xA2;
	address.addr64[3] = 0x00;
    address.addr64[4] = 0x40;
    address.addr64[5] = 0xB7;
    address.addr64[6] = 0xB1;
    address.addr64[7] = 0xEB;

    /* Prepare a connection with the peer XBee */
	if ((ret = xbee_conNew(xbee, &con, "Data", &address)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conNew() returned: %d (%s)", ret, xbee_errorToStr(ret));
		return ret;
	}

    /* Prepare the configuration context */
    ctx = calloc(1, sizeof(struct flb_in_xbee_config));
    if (!ctx) {
        perror("calloc");
        return -1;
    }
    ctx->device     = opt_device;
    ctx->baudrate   = opt_baudrate;
    ctx->con        = con;
    ctx->buffer_len = 0;

	if ((ret = xbee_conDataSet(con, ctx, NULL)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conDataSet() returned: %d", ret);
		return ret;
	}


	if ((ret = xbee_conCallbackSet(con, in_xbee_cb, NULL)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conCallbackSet() returned: %d", ret);
		return ret;
	}


    /* Set the context */
    ret = flb_input_set_context("xbee", ctx, config);
    if (ret == -1) {
        flb_utils_error_c("Could not set configuration for xbee input plugin");
    }

    /*
     * Set our collector based on time. We will trigger a collection at certain
     * intervals. For now it works but it's not the ideal implementation. I am
     * talking with libxbee maintainer to check possible workarounds and use
     * proper events mechanism.
     */
    ret = flb_input_set_collector_time("xbee",
                                       in_xbee_collect,
                                       IN_XBEE_COLLECT_SEC,
                                       IN_XBEE_COLLECT_NSEC,
                                       config);
    if (ret == -1) {
        flb_utils_error_c("Could not set collector for xbee input plugin");
    }

    return 0;
}
Пример #28
0
int main(void) {
	void *d;
	struct xbee *xbee;
	struct xbee_con *con;
	char txRet;
	xbee_err ret;
	int i, o, t;

	sem_init(&sem, 0, 0);

	if ((ret = xbee_setup(&xbee, "xbee1", "/dev/ttyUSB0", 57600)) != XBEE_ENONE) {
		printf("ret: %d (%s)\n", ret, xbee_errorToStr(ret));
		return ret;
	}

	if ((ret = xbee_conNew(xbee, &con, "Local AT", NULL)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conNew() returned: %d (%s)", ret, xbee_errorToStr(ret));
		return ret;
	}

	if ((ret = xbee_conCallbackSet(con, myCB, NULL)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conCallbackSet() returned: %d", ret);
		return ret;
	}
	
	o = 0;
	t = 0;

	for (i = 0; i < 1000; i++) {
		ret = xbee_conTx(con, &txRet, "NI");
		printf("tx: %d\n", ret);
		if (ret) {
			printf("txRet: %d\n", txRet);
			sleep(1);
		} else {
			struct timespec to;
			clock_gettime(CLOCK_REALTIME, &to);
			to.tv_sec++;
			if (sem_timedwait(&sem, &to) == 0) {
				o++;
				usleep(10000);
			} else {
				printf("             TIMEOUT!\n");
				usleep(250000);
				t++;
			}
		}
	}

	printf("%d / %d / %d - success/timeout/total - success rate (%2.1f%%) / timeout rate (%2.1f%%)\n",
		o, t, i, (double)((double)o/(double)i)*100.0, (double)((double)t/(double)i)*100.0);
	
	if ((ret = xbee_conEnd(con)) != XBEE_ENONE) {
		xbee_log(xbee, -1, "xbee_conEnd() returned: %d", ret);
		return ret;
	}

	xbee_shutdown(xbee);

	return 0;
}
Пример #29
0
int main(int argc, char *argv[]) {
	int ret;
	sem_t sem;
	void *p;
	
	/* this is our xbee instance... from 'user' space you don't have access to the struct */
	struct xbee *xbee;
	
	/* this is the connection we will make... again, you don't have access to the struct */
	struct xbee_con *con;
	struct xbee_conAddress addr;
	
	/* the packet that is recieved... you have access to this! (see xbee.h) */
	struct xbee_pkt *pkt;
	
	/* make a lixbee instance, and connect it to /dev/ttyUSB1 @ 57600 baud
	   you don't have to keep hold of the returned xbee, in which case you can pass NULL and the most recently started instance will be used! */
	if ((ret = xbee_setup("/dev/ttyUSB0", 57600, &xbee)) != 0) {
		xbee_log(NULL,-1,"xbee_setup(): failed... (%d)", ret);
		exit(1);
	}
	/* setup libxbee to use the series 1 packets - you have to do this before you do anything else! */
	xbee_modeSet(xbee, "series1");
	
	/* get the connection type ID, you pass in a string, it returns an ID */
	if ((ret = xbee_conTypeIdFromName(xbee, "Remote AT", &conType)) != 0) {
		xbee_log(xbee,-1,"xbee_conTypeIdFromName(): failed... (%d)", ret);
		exit(1);
	}
	
	if ((ret = sem_init(&sem, 0, 0)) != 0) {
		xbee_log(xbee,-1,"sem_init(): failed... (%d)", ret);
		exit(1);
	}
	
	/* clear the address field */
	memset(&addr, 0, sizeof(addr));
	/* build a connection to the following address */
	addr.addr64_enabled = 1;
	addr.addr64[0] = 0x00;
	addr.addr64[1] = 0x13;
	addr.addr64[2] = 0xA2;
	addr.addr64[3] = 0x00;
	addr.addr64[4] = 0x40;
	addr.addr64[5] = 0x33;
	addr.addr64[6] = 0xCA;
	addr.addr64[7] = 0xCB;
	if ((ret = xbee_conNew(xbee, &con, conType, &addr, &sem)) != 0) {
		xbee_log(xbee,-1,"xbee_newcon(): failed... (%d)", ret);
		exit(1);
	}
	{
    struct xbee_conOptions opts;
    /* enable waitForAck... this allows us to see if the packet was sent successfully! */
    xbee_conOptions(xbee, con, &opts, NULL);
    opts.waitForAck = 1;
    xbee_conOptions(xbee, con, NULL, &opts);
	}
	/* attach the callback */
	xbee_conAttachCallback(xbee, con, myCB, NULL);

	/* send the request */
	if ((ret = xbee_conTx(xbee, con, "NI")) != 0) {
		xbee_log(xbee,-1,"Something went wrong... (%d)", ret);
	} else {
		struct timespec to;
		clock_gettime(CLOCK_REALTIME, &to);
		to.tv_sec += 5;
		if (sem_timedwait(&sem, &to)) {
			printf("Timeout...\n");
		}
	}

	sem_destroy(&sem);

	/* shutdown the connection */
	xbee_conEnd(xbee, con, NULL);
	
	/* shutdown the libxbee instance */
	xbee_shutdown(xbee);
	
	return 0;
}
Пример #30
0
xbee_err xbee_s2_io_parseInputs(struct xbee *xbee, struct xbee_pkt *pkt, unsigned char *data, int len) {
	int sampleCount;
	int sample, channel;
	int ioMask;

	if (len < 4) return XBEE_ELENGTH;
	
	sampleCount = data[0];
	data++; len--;

	/* mask is ordered:
	    MSB - Supply Voltage
	          * n/a *
	          * n/a *
	          * n/a *
	          AD3
	          AD2
	          AD1
	       -  AD0
	       -  * n/a *
	          * n/a *
	          * n/a *
	          CD/DIO12
	          PWM/DIO11
	          RSSI/DIO10
	          * n/a *
	       -  * n/a *
	       -  CTS/DIO7
	          RTS/DIO6
	          Assoc/DIO5
	          DIO4
	          AD3/DIO3
	          AD2/DIO2
	          AD1/DIO1
	    LSB - AD0/DIO0
	*/
	ioMask = ((data[2] << 16) & 0xFF0000) | ((data[0] << 8) & 0xFF00) | (data[1] & 0xFF);
	data += 3; len -= 3;
	
	/* poke out the n/a fields, just incase */
	ioMask &= 0x8F1CFF;
	
	for (sample = 0; sample < sampleCount; sample++) {
		int mask;

		
		if (ioMask & 0x001CFF) {
			int digitalValue;
			
			if (len < 2) return XBEE_ELENGTH;
			
			digitalValue = ((data[0] << 8) & 0xFF00) | (data[1] & 0xFF);
			/* poke out the n/a fields */
			digitalValue &= 0x1CFF;

			mask = 0x000001;
			for (channel = 0; channel <= 12; channel++, mask <<= 1) {
				if (ioMask & mask) {
					if (xbee_pktDigitalAdd(pkt, channel, digitalValue & mask)) {
						xbee_log(1,"Failed to add digital sample information to packet (channel D%d)", channel);
					}
				}
			}
			data += 2; len -= 2;
		}

		mask = 0x010000;
		for (channel = 0; channel <= 4; channel++, mask <<= 1) {
			if (channel == 4) mask = 0x800000;
			if (ioMask & mask) {
				
				if (len < 2) return XBEE_ELENGTH;
				
				if (xbee_pktAnalogAdd(pkt, channel, ((data[0] << 8) & 0x3F00) | (data[1] & 0xFF))) {
					xbee_log(1,"Failed to add analog sample information to packet (channel A%d)", channel);
				}
				data += 2; len -= 2;
			}
		}
	}

	return XBEE_ENONE;
}