xbee_err _xbee_pktUnlink(struct xbee_con *con, struct xbee_pkt *pkt, int needsLLLock) { xbee_err ret; if (!con || !pkt) return XBEE_EMISSINGPARAM; #ifndef XBEE_DISABLE_STRICT_OBJECTS if (xbee_conValidate(con) != XBEE_ENONE) return XBEE_EINVAL; if (xbee_pktValidate(pkt) != XBEE_ENONE) return XBEE_EINVAL; #endif /* XBEE_DISABLE_STRICT_OBJECTS */ if ((ret = _xbee_ll_ext_item(con->pktList, pkt, needsLLLock)) == XBEE_ENONE) { pkt->xbee = NULL; pkt->con = NULL; } return ret; }
xbee_err xbee_netTx(struct xbee *xbee, void *arg, struct xbee_sbuf *buf) { int pos, ret; int fd; size_t txSize; size_t memSize; struct xbee_buf *iBuf; size_t *txBufSize; struct xbee_buf **txBuf; if (!xbee || !buf) return XBEE_EMISSINGPARAM; if (arg) { /* this is on the server end */ struct xbee_netClientInfo *info; info = arg; if (xbee != info->xbee) return XBEE_EINVAL; fd = info->fd; txBufSize = &info->txBufSize; txBuf = &info->txBuf; } else { /* this is on the client end */ struct xbee_modeData *info; info = xbee->modeData; fd = info->netInfo.fd; txBufSize = &info->netInfo.txBufSize; txBuf = &info->netInfo.txBuf; } txSize = 3 + buf->len; memSize = txSize + sizeof(*iBuf); iBuf = *txBuf; if (!iBuf || *txBufSize < memSize) { void *p; /* make sure we save this buffer... */ xbee_ll_lock(needsFree); if ((p = realloc(iBuf, memSize)) == NULL) { xbee_ll_unlock(needsFree); return XBEE_ENOMEM; } if (iBuf) _xbee_ll_ext_item(needsFree, iBuf, 0); _xbee_ll_add_tail(needsFree, p, 0); xbee_ll_unlock(needsFree); iBuf = p; *txBuf = iBuf; *txBufSize = memSize; } iBuf->len = txSize; iBuf->data[0] = 0x7E; iBuf->data[1] = ((buf->len - 1) >> 8) & 0xFF; iBuf->data[2] = ((buf->len - 1) ) & 0xFF; memcpy(&(iBuf->data[3]), buf->data, buf->len); for (pos = 0; pos < iBuf->len; pos += ret) { ret = send(fd, iBuf->data, iBuf->len - pos, MSG_NOSIGNAL); if (ret >= 0) continue; return XBEE_EIO; } return XBEE_ENONE; }