Esempio n. 1
0
EXPORT xbee_err xbee_vsetup(struct xbee **retXbee, const char *mode, va_list ap) {
	xbee_err ret;
	const struct xbee_mode *xbeeMode;
	struct xbee *xbee;
	
	if (!retXbee || !mode) return XBEE_EMISSINGPARAM;
	
	if ((ret = xbee_modeRetrieve(mode, &xbeeMode)) != XBEE_ENONE) return ret;
	
	if ((ret = xbee_alloc(&xbee)) != XBEE_ENONE) return ret;
	
	if ((ret = xbee_modeImport(&xbee->iface.conTypes, xbeeMode)) != XBEE_ENONE) goto die;
	xbee->mode = xbeeMode;
	
	xbee->iface.rx->ioFunc = xbee->mode->rx_io;
	xbee->iface.rx->fBlock = xbee->fBlock;
	xbee->iface.rx->conTypes = &xbee->iface.conTypes;
	
	xbee->iface.tx->ioFunc = xbee->mode->tx_io;
	
	if ((ret = xbee->mode->init(xbee, ap)) != XBEE_ENONE) goto die;
	
	if ((ret = xbee_threadStart(xbee, NULL, 150000, 0, xbee_rx, xbee->iface.rx)) != XBEE_ENONE)                                goto die;
	if ((ret = xbee_threadStart(xbee, NULL, 150000, 0, xbee_rxHandler, xbee->iface.rx)) != XBEE_ENONE)                         goto die;
	if ((ret = xbee_threadStart(xbee, NULL, 150000, 0, xbee_tx, xbee->iface.tx)) != XBEE_ENONE)                                goto die;
	
	if (xbee->mode->prepare) if ((ret = xbee->mode->prepare(xbee)) != XBEE_ENONE)                                              goto die;
	
	if (xbee->mode->thread) if ((ret = xbee_threadStart(xbee, NULL, 150000, 0, xbee->mode->thread, NULL)) != XBEE_ENONE)       goto die;
	
	xbee_ll_add_tail(xbeeList, xbee);
	
	*retXbee = xbee;
	
	return XBEE_ENONE;

die:
	xbee_free(xbee);
	return ret;
}
Esempio n. 2
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) {