static int xframe_receive_cmd(xbus_t *xbus, xframe_t *xframe) { byte *xframe_end; xpacket_t *pack; byte *p; int len; int ret; if(debug & DBG_COMMANDS) dump_xframe("RX-CMD", xbus, xframe, DBG_ANY); p = xframe->packets; xframe_end = p + XFRAME_LEN(xframe); do { pack = (xpacket_t *)p; len = XPACKET_LEN(pack); /* Sanity checks */ if(unlikely(XPACKET_OP(pack) == XPROTO_NAME(GLOBAL,PCM_READ))) { static int rate_limit; if((rate_limit++ % 1003) == 0) { XBUS_DBG(GENERAL, xbus, "A PCM packet within a Non-PCM xframe\n"); dump_xframe("In Non-PCM xframe", xbus, xframe, debug); } ret = -EPROTO; goto out; } p += len; if(p > xframe_end || len < RPACKET_HEADERSIZE) { static int rate_limit; if((rate_limit++ % 1003) == 0) { XBUS_NOTICE(xbus, "Invalid packet length %d\n", len); dump_xframe("BAD LENGTH", xbus, xframe, debug); } ret = -EPROTO; goto out; } ret = packet_process(xbus, pack); if(unlikely(ret < 0)) break; } while(p < xframe_end); out: FREE_RECV_XFRAME(xbus, xframe); return ret; }
int xframe_receive(xbus_t *xbus, xframe_t *xframe) { int ret = 0; struct timeval now; struct timeval tv_received; int usec; if(XFRAME_LEN(xframe) < RPACKET_HEADERSIZE) { static int rate_limit; if((rate_limit++ % 1003) == 0) { XBUS_NOTICE(xbus, "short xframe\n"); dump_xframe("short xframe", xbus, xframe, debug); } FREE_RECV_XFRAME(xbus, xframe); return -EPROTO; } if(!XBUS_FLAGS(xbus, CONNECTED)) { XBUS_DBG(GENERAL, xbus, "Dropped xframe. Is shutting down.\n"); return -ENODEV; } tv_received = xframe->tv_received; /* * We want to check that xframes do not mix PCM and other commands */ if(XPACKET_IS_PCM((xpacket_t *)xframe->packets)) { if(!XBUS_IS(xbus, READY)) FREE_RECV_XFRAME(xbus, xframe); else xframe_receive_pcm(xbus, xframe); } else { XBUS_COUNTER(xbus, RX_CMD)++; ret = xframe_receive_cmd(xbus, xframe); } /* Calculate total processing time */ do_gettimeofday(&now); usec = (now.tv_sec - tv_received.tv_sec) * 1000000 + now.tv_usec - tv_received.tv_usec; if(usec > xbus->max_rx_process) xbus->max_rx_process = usec; return ret; }
static int copy_pcm_tospan(xbus_t *xbus, xframe_t *xframe) { byte *xframe_end; xpacket_t *pack; byte *p; int ret = -EPROTO; /* Assume error */ if(debug & DBG_PCM) dump_xframe("RX_XFRAME_PCM", xbus, xframe, debug); /* handle content */ p = xframe->packets; xframe_end = p + XFRAME_LEN(xframe); do { int len; xpd_t *xpd; pack = (xpacket_t *)p; len = XPACKET_LEN(pack); /* Sanity checks */ if(unlikely(XPACKET_OP(pack) != XPROTO_NAME(GLOBAL,PCM_READ))) { static int rate_limit; if((rate_limit++ % 1003) == 0) { XBUS_NOTICE(xbus, "%s: Non-PCM packet within a PCM xframe. (%d)\n", __FUNCTION__, rate_limit); dump_xframe("In PCM xframe", xbus, xframe, debug); } goto out; } p += len; if(p > xframe_end || len < RPACKET_HEADERSIZE) { static int rate_limit; if((rate_limit++ % 1003) == 0) { XBUS_NOTICE(xbus, "%s: Invalid packet length %d. (%d)\n", __FUNCTION__, len, rate_limit); dump_xframe("BAD LENGTH", xbus, xframe, debug); } goto out; } xpd = xpd_byaddr(xbus, XPACKET_ADDR_UNIT(pack), XPACKET_ADDR_SUBUNIT(pack)); if(unlikely(!xpd)) { static int rate_limit; if((rate_limit++ % 1003) == 0) { notify_bad_xpd(__FUNCTION__, xbus, XPACKET_ADDR(pack), "RECEIVE PCM"); dump_xframe("Unknown XPD addr", xbus, xframe, debug); } goto out; } if(!pcm_valid(xpd, pack)) goto out; if(SPAN_REGISTERED(xpd)) { XBUS_COUNTER(xbus, RX_PACK_PCM)++; CALL_XMETHOD(card_pcm_tospan, xbus, xpd, pack); } } while(p < xframe_end); ret = 0; /* all good */ XBUS_COUNTER(xbus, RX_XFRAME_PCM)++; out: FREE_RECV_XFRAME(xbus, xframe); return ret; }