Пример #1
0
xbee_err xbee_frameWait(struct xbee_frameBlock *fBlock, struct xbee_con *con, unsigned char *retVal, struct timespec *timeout) {
	xbee_err ret;
	struct xbee_frame *frame;
	int i, o;
	
	if (!fBlock || !con) return XBEE_EMISSINGPARAM;

	ret = XBEE_EINVAL;
	xbee_mutex_lock(&fBlock->mutex);
	frame = NULL;
	for (i = 0, o = fBlock->lastFrame; i < fBlock->numFrames; i++, o--) {
		if (o < 0) o = fBlock->numFrames - 1;
		if (fBlock->frame[o].id != con->frameId) continue;

		if (fBlock->frame[o].status == 0 || fBlock->frame[o].con != con) {
			ret = XBEE_ESTALE;
		} else {
			frame = &fBlock->frame[o];
			frame->status |= XBEE_FRAME_STATUS_WAITING;
		}
		break;
	}
	xbee_mutex_unlock(&fBlock->mutex);
	if (!frame) return ret;

	ret = XBEE_ENONE;
	if (timeout) {
		if (xsys_sem_timedwait(&frame->sem, timeout)) {
			if (errno == ETIMEDOUT) {
				ret = XBEE_ETIMEOUT;
			} else {
				ret = XBEE_ESEMAPHORE;
			}
		}
	} else {
		if (xsys_sem_wait(&frame->sem)) {
			ret = XBEE_ESEMAPHORE;
		}
	}
	
	xbee_mutex_lock(&fBlock->mutex);
	con->frameId = 0;
	frame->con = NULL;
	if (frame->status & XBEE_FRAME_STATUS_COMPLETE && ret == XBEE_ENONE) {
		if (retVal) *retVal = frame->retVal;
		frame->status = 0;
	} else {
		frame->status &= ~XBEE_FRAME_STATUS_WAITING;
	}
	xbee_mutex_unlock(&fBlock->mutex);
	
	return ret;
}
Пример #2
0
xbee_err _xbee_ll_add_tail(void *list, void *item, int needMutex) {
	struct xbee_ll_head *h;
	struct xbee_ll_info *i, *p;
	xbee_err ret;
	ret = XBEE_ENONE;
	if (!list) return XBEE_EMISSINGPARAM;
	i = list;
	h = i->head;
	if (!(h && h->is_head && h->self == h)) return XBEE_EINVAL;
	if (needMutex) xbee_mutex_lock(&h->mutex);
	p = h->tail;
	if (!(h->tail = calloc(1, sizeof(struct xbee_ll_info)))) {
		h->tail = p;
		ret = XBEE_ENOMEM;
		goto out;
	}
	h->tail->head = h;
	h->tail->next = NULL;
	if (p) {
		h->tail->prev = p;
		p->next = h->tail;
	} else {
		h->tail->prev = NULL;
		h->head = h->tail;
	}
	h->tail->item = item;
out:
	if (needMutex) xbee_mutex_unlock(&h->mutex);
	return ret;
}
Пример #3
0
xbee_err xbee_frameGetID(struct xbee_frameBlock *fBlock, struct xbee_con *con, char abandon) {
	xbee_err ret;
	int i, o;
	
	if (!fBlock || !con) return XBEE_EMISSINGPARAM;
	ret = XBEE_EFAILED;
	
	xbee_mutex_lock(&fBlock->mutex);
	for (i = 0, o = fBlock->lastFrame + 1; i < fBlock->numFrames; i++, o++) {
		o %= fBlock->numFrames;

		/* skip frame '0x00', this indicates that no ACK is requested */
		if (fBlock->frame[o].id == 0) continue;
		/* skip busy frames */
		if (fBlock->frame[o].status) continue;
		
		fBlock->lastFrame = o;
		fBlock->frame[o].status = XBEE_FRAME_STATUS_SCHEDULED;
		if (abandon) {
			fBlock->frame[o].status |= XBEE_FRAME_STATUS_ABANDONED;
		} else {
			fBlock->frame[o].con = con;
		}
		con->frameId = fBlock->frame[o].id;
		ret = XBEE_ENONE;
		break;
	}
	xbee_mutex_unlock(&fBlock->mutex);
	
	return ret;
}
Пример #4
0
xbee_err _xbee_logWrite(struct xbee_log *log, const char *file, int line, const char *function, struct xbee *xbee, int minLevel, char *preStr, char *format, va_list ap) {
	char tBuf[XBEE_LOG_MAXLEN];
	int len;
	const char * const truncStr = XBEE_LOG_TRUNC_STR;
	static int truncLen = 0;
	
	if (!log || !file || !function || !xbee || !preStr || !format) return XBEE_EMISSINGPARAM;
	if (!log->f) return XBEE_EINVAL;
	
	len = vsnprintf(tBuf, XBEE_LOG_MAXLEN, format, ap);
	
	if (len >= XBEE_LOG_MAXLEN) {
		if (truncLen == 0) {
			truncLen = strlen(truncStr);
		}
		strcpy(&(tBuf[XBEE_LOG_MAXLEN - (truncLen + 1)]), truncStr);
	}
	
	xbee_mutex_lock(&log->mutex);
	
	if (!xbee) {
		fprintf(log->f, "%s%3d#[%s:%d] %s(): %s\n",      preStr, minLevel, file, line, function,       tBuf);
	} else if (xbee_validate(xbee) == XBEE_ENONE) {
		fprintf(log->f, "%s%3d#[%s:%d] %s() %p: %s\n",   preStr, minLevel, file, line, function, xbee, tBuf);
	} else {
		fprintf(log->f, "%s%3d#[%s:%d] %s() !%p!: %s\n", preStr, minLevel, file, line, function, xbee, tBuf);
	}
	
	xbee_mutex_unlock(&log->mutex);
	
	return XBEE_ENONE;
}
Пример #5
0
xbee_err _xbee_ll_ext_tail(void *list, void **retItem, int needMutex) {
	struct xbee_ll_head *h;
	struct xbee_ll_info *i, *p;
	void *ret;
	if (!list || !retItem) return XBEE_EMISSINGPARAM;
	i = list;
	h = i->head;
	if (!(h && h->is_head && h->self == h)) return XBEE_EINVAL;
	if (needMutex) xbee_mutex_lock(&h->mutex);
	p = h->tail;
	if (!p) {
		ret = NULL;
		goto out;
	}
	ret = p->item;
	h->tail = p->prev;
	if (h->tail) h->tail->next = NULL;
	if (h->head == p) h->head = NULL;
	free(p);
out:
	if (needMutex) xbee_mutex_unlock(&h->mutex);
	*retItem = ret;
	if (!ret) return XBEE_ERANGE;
	return XBEE_ENONE;
}
Пример #6
0
xbee_err xbee_ll_unlock(void *list) {
	struct xbee_ll_head *h;
	struct xbee_ll_info *i;
	if (!list) return XBEE_EMISSINGPARAM;
	i = list;
	h = i->head;
	if (!(h && h->is_head && h->self == h)) return XBEE_EINVAL;
	xbee_mutex_unlock(&h->mutex);
	return XBEE_ENONE;
}
Пример #7
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);
	
	return XBEE_ENONE;
}
Пример #8
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;
}
Пример #9
0
xbee_err _xbee_ll_count_items(void *list, unsigned int *retCount, int needMutex) {
	struct xbee_ll_head *h;
	struct xbee_ll_info *i, *p;
	int count;
	if (!list || !retCount) return XBEE_EMISSINGPARAM;
	i = list;
	h = i->head;
	if (!(h && h->is_head && h->self == h)) return XBEE_EINVAL;
	if (needMutex) xbee_mutex_lock(&h->mutex);
	for (p = h->head, count = 0; p; p = p->next, count++);
	if (needMutex) xbee_mutex_unlock(&h->mutex);
	*retCount = count;
	return XBEE_ENONE;
}
Пример #10
0
xbee_err _xbee_ll_modify_item(void *list, void *oldItem, void *newItem, int needMutex) {
	struct xbee_ll_head *h;
	struct xbee_ll_info *i, *p;
	xbee_err ret;
	if (!list) return XBEE_EMISSINGPARAM;
	i = list;
	h = i->head;
	if (!(h && h->is_head && h->self == h)) return XBEE_EINVAL;
	if (needMutex) xbee_mutex_lock(&h->mutex);
	if ((ret = __xbee_ll_get_item(h, oldItem, &p, 0)) == XBEE_ENONE) {
		p->item = newItem;
	}
	if (needMutex) xbee_mutex_unlock(&h->mutex);
	return ret;
}
Пример #11
0
xbee_err xbee_ll_combine(void *head, void *tail) {
	struct xbee_ll_head *hH, *hT;
	struct xbee_ll_info *iH, *iT;
	void *v;
	xbee_err ret;
	ret = XBEE_ENONE;
	if (!head || !tail) return XBEE_EMISSINGPARAM;
	if (head == tail) return XBEE_EINVAL;
	iH = head;
	hH = iH->head;
	if (!(hH && hH->is_head && hH->self == hH)) return XBEE_EINVAL;
	xbee_mutex_lock(&hH->mutex);
	iT = tail;
	hT = iT->head;
	if (!(hT && hT->is_head && hT->self == hT)) { ret = XBEE_EINVAL; goto out; }
	xbee_mutex_lock(&hT->mutex);
	while ((ret = _xbee_ll_ext_head(tail, &v, 0)) == XBEE_ENONE && v) {
		_xbee_ll_add_tail(head, v, 0);
	}
	xbee_mutex_unlock(&hH->mutex);
out:
	xbee_mutex_unlock(&hT->mutex);
	return XBEE_ENONE;
}
Пример #12
0
xbee_err xbee_frameReturnID(struct xbee_frameBlock *fBlock, struct xbee_con *con) {
	xbee_err ret;
	int i;
	unsigned char frameId;
	struct xbee_frame *frame;

	if (!fBlock || !con) return XBEE_EMISSINGPARAM;
	ret = XBEE_EFAILED;

	xbee_mutex_lock(&fBlock->mutex);

	frameId = con->frameId;
	if (frameId < fBlock->numFrames) {
		frame = &(fBlock->frame[frameId]);
	} else {
		frame = NULL;
	}

	if ((frame == NULL) ||
	    (frame->id != frameId)) {
		frame = NULL;

		for (i = 0; i < fBlock->numFrames; i++) {
			if (fBlock->frame[i].id == frameId) {
				frame = &(fBlock->frame[i]);
				break;
			}
		}
	}

	if ((frame == NULL) ||
	    (frame->con != con)) {
		ret = XBEE_ESTALE;
		goto done;
	}

	/* clean down the frame */

	con->frameId = 0;

	frame->con = NULL;
	frame->status = 0;

done:
	xbee_mutex_unlock(&fBlock->mutex);

	return ret;
}
Пример #13
0
xbee_err _xbee_ll_get_tail(void *list, void **retItem, int needMutex) {
	struct xbee_ll_head *h;
	struct xbee_ll_info *i;
	xbee_err ret;
	if (!list || !retItem) return XBEE_EMISSINGPARAM;
	i = list;
	h = i->head;
	if (!(h && h->is_head && h->self == h)) return XBEE_EINVAL;
	if (needMutex) xbee_mutex_lock(&h->mutex);
	if (h->tail) {
		*retItem = h->tail->item;
		ret = XBEE_ENONE;
	} else {
		ret = XBEE_ERANGE;
	}
	if (needMutex) xbee_mutex_unlock(&h->mutex);
	return ret;
}
Пример #14
0
/* returns struct xbee_ll_info* or NULL - don't touch the pointer if you don't know what you're doing ;) */
xbee_err __xbee_ll_get_item(void *list, const void *item, struct xbee_ll_info **retItem, int needMutex) {
	struct xbee_ll_head *h;
	struct xbee_ll_info *i;
	if (!list) return XBEE_EMISSINGPARAM;
	i = list;
	h = i->head;
	if (!(h && h->is_head && h->self == h)) return XBEE_EINVAL;
	if (needMutex) xbee_mutex_lock(&h->mutex);
	i = h->head;
	while (i) {
		if (i->item == item) break;
		i = i->next;
	}
	if (needMutex) xbee_mutex_unlock(&h->mutex);
	if (retItem) *retItem = (void*)i;
	if (!i) return XBEE_ENOTEXISTS;
	return XBEE_ENONE;
}
Пример #15
0
xbee_err xbee_framePost(struct xbee_frameBlock *fBlock, unsigned char frameId, unsigned char retVal) {
	xbee_err ret;
	struct xbee_frame *frame;
	int i;
	
	if (!fBlock) return XBEE_EMISSINGPARAM;
	if (frameId == 0) return XBEE_ENONE;
	
	xbee_mutex_lock(&fBlock->mutex);

	frame = NULL;
	for (i = 0; i < fBlock->numFrames; i++) {
		if (fBlock->frame[i].id != frameId) continue;

		if (fBlock->frame[i].status != 0) {
			frame = &fBlock->frame[i];
		}
		
		break;
	}

	if (!frame) {
		ret = XBEE_EINVAL;
	} else if (frame->con && (frame->status & XBEE_FRAME_STATUS_WAITING)) {
		ret = XBEE_ENONE;
		frame->status |= XBEE_FRAME_STATUS_COMPLETE;
		frame->retVal = retVal;
		xsys_sem_post(&frame->sem);
	} else {
		if (!(frame->status & XBEE_FRAME_STATUS_ABANDONED)) {
			ret = XBEE_ETIMEOUT;
		}
		if (frame->con) {
			frame->con->frameId = 0;
			frame->con = NULL;
		}
		frame->status = 0;
	}

	xbee_mutex_unlock(&fBlock->mutex);
	
	return ret;
}
Пример #16
0
xbee_err _xbee_ll_get_prev(void *list, void *ref, void **retItem, int needMutex) {
	struct xbee_ll_head *h;
	struct xbee_ll_info *i;
	void *ret = NULL;
	if (!list || !retItem) return XBEE_EMISSINGPARAM;
	if (!ref) return _xbee_ll_get_tail(list, retItem, needMutex);
	i = list;
	h = i->head;
	if (!(h && h->is_head && h->self == h)) return XBEE_EINVAL;
	if (needMutex) xbee_mutex_lock(&h->mutex);
	i = h->head;
	if (__xbee_ll_get_item(h, ref, &i, 0) != XBEE_ENONE) goto out;
	if (!i) goto out;
	i = i->prev;
	if (i) ret = i->item;
out:
	if (needMutex) xbee_mutex_unlock(&h->mutex);
	*retItem = ret;
	if (!ret) return XBEE_ERANGE;
	return XBEE_ENONE;
}
Пример #17
0
/* NULL ref will add to head */
xbee_err _xbee_ll_add_before(void *list, void *ref, void *item, int needMutex) {
	struct xbee_ll_head *h;
	struct xbee_ll_info *i, *t;
	xbee_err ret;
	ret = XBEE_ENONE;
	if (!list) return XBEE_EMISSINGPARAM;
	i = list;
	h = i->head;
	if (!(h && h->is_head && h->self == h)) return XBEE_EINVAL;
	if (!ref) return xbee_ll_add_tail(h, item);
	if (needMutex) xbee_mutex_lock(&h->mutex);
	i = h->head;
	while (i) {
		if (i->item == ref) break;
		i = i->next;
	}
	if (!i) {
		ret = XBEE_ENOTEXISTS;
		goto out;
	}
	if (!(t = calloc(1, sizeof(struct xbee_ll_info)))) {
		ret = XBEE_ENOMEM;
		goto out;
	}
	t->head = i->head;
	if (!i->prev) {
		h->head = t;
		t->prev = NULL;
	} else {
		i->prev->next = t;
		t->prev = i->prev;
	}
	i->prev = t;
	t->next = i;
	t->item = item;
out:
	if (needMutex) xbee_mutex_unlock(&h->mutex);
	return ret;
}
Пример #18
0
xbee_err _xbee_ll_get_index(void *list, unsigned int index, void **retItem, int needMutex) {
	struct xbee_ll_head *h;
	struct xbee_ll_info *i;
	int o;
	if (!list || !retItem) return XBEE_EMISSINGPARAM;
	i = list;
	h = i->head;
	if (!(h && h->is_head && h->self == h)) return XBEE_EINVAL;
	if (needMutex) xbee_mutex_lock(&h->mutex);
	i = h->head;
	for (o = 0; o < index; o++) {
		i = i->next;
		if (!i) break;
	}
	if (needMutex) xbee_mutex_unlock(&h->mutex);
	if (!i) {
		*retItem = NULL;
		return XBEE_ERANGE;
	}
	*retItem = i->item;
	return XBEE_ENONE;
}
Пример #19
0
xbee_err _xbee_ll_ext_index(void *list, unsigned int index, void **retItem, int needMutex) {
	struct xbee_ll_head *h;
	struct xbee_ll_info *i;
	int o;
	xbee_err ret;
	if (!list || !retItem) return XBEE_EMISSINGPARAM;
	i = list;
	h = i->head;
	if (!(h && h->is_head && h->self == h)) return XBEE_EINVAL;
	if (needMutex) xbee_mutex_lock(&h->mutex);
	i = h->head;
	for (o = 0; o < index; o++) {
		i = i->next;
		if (!i) break;
	}
	if (!i) {
		*retItem = NULL;
		ret = XBEE_ERANGE;
		goto out;
	}
	*retItem = i->item;
	if (i->next) {
		i->next->prev = i->prev;
	} else {
		h->tail = i->prev;
	}
	if (i->prev) {
		i->prev->next = i->next;
	} else {
		h->head = i->next;
	}
	free(i);
	ret = XBEE_ENONE;
out:
	if (needMutex) xbee_mutex_unlock(&h->mutex);
	return ret;
}
Пример #20
0
xbee_err _xbee_ll_ext_item(void *list, void *item, int needMutex) {
	struct xbee_ll_head *h;
	struct xbee_ll_info *i, *p;
	xbee_err ret;
	if (!list) return XBEE_EMISSINGPARAM;
	i = list;
	h = i->head;
	if (!(h && h->is_head && h->self == h)) return XBEE_EINVAL;
	if (needMutex) xbee_mutex_lock(&h->mutex);
	p = h->head;
	ret = XBEE_ENONE;
	while (p) {
		if (p->is_head) {
			ret = XBEE_ELINKEDLIST;
			break;
		}
		if (p->item == item) {
			if (p->next) {
				p->next->prev = p->prev;
			} else {
				h->tail = p->prev;
			}
			if (p->prev) {
				p->prev->next = p->next;
			} else {
				h->head = p->next;
			}
			free(p);
			break;
		}
		p = p->next;
	}
	if (needMutex) xbee_mutex_unlock(&h->mutex);
	if (!p) return XBEE_ENOTEXISTS;
	return ret;
}