⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 channels.c

📁 ARM入门的好帮手.包含了从简单到相对较复杂的程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
            rx_flags = chan_pkt[CF_FLAGS_BYTE_POS];            LogInfo(LOG_CHANNEL, ("read_callback: rx msg buffer %p chan %d with "                                  "packetseq %d, ackseq %d, rxflags 0x%x\n", chan_pkt,                                  chanid, rx_packetseq, rx_ackseq, rx_flags));            if (chanid >= CI_NUM_CHANNELS)            {                LogError(LOG_CHANNEL, ("Bad channel ID %d\n", chanid));                angel_ChannelReleaseBuffer(chan_pkt + CF_DATA_BYTE_POS);                check_flow_control();                return;            }            if (rx_flags & CF_RESEND)            {                LogInfo(LOG_CHANNEL, ("*** Resend packet received, release buffer 0x%x\n",                                        chan_pkt + CF_DATA_BYTE_POS));                /* free this buffer as we don't need it any more */                angel_ChannelReleaseBuffer(chan_pkt + CF_DATA_BYTE_POS);                /*                 * resend packets contain a rx_ackseq value which is the last packet the                 * requester got successfully. Hence, the packet we send is rx_ackseq + 1:                 */                resend_packet_from(devid, nextSEQ(rx_ackseq));                check_flow_control();                return;            }            if (rx_flags & CF_HEARTBEAT)            {                int timestamp = GET32LE(chan_pkt + CF_DATA_BYTE_POS);                LogInfo(LOG_CHANNEL, ("*** Heartbeat packet received, timestamp %d\n",                                     timestamp));                angel_ChannelReleaseBuffer(chan_pkt + CF_DATA_BYTE_POS);                                check_flow_control();                                if (rx_packetseq == dev->frameExpected)                {                    /* this is not good enough; although it's good that this isn't lower,                     * we haven't made sure yet that we actually received the real                     * packet with this sequence number (we should have...)                     */                    if (rx_packetseq == dev->lastReceived)                    {                        /* all's well */                        LogInfo(LOG_CHANNEL, ("+++ seq ok: (%d), returning ack...\n",                                              rx_packetseq));                        send_heartbeat_ack_msg(devid, timestamp);                    }                    else                    {                        LogInfo(LOG_CHANNEL, ("+++ seq low: (%d < %d), requesting resend of %d+1\n",                                              dev->lastReceived, rx_packetseq, lastSEQ(dev->frameExpected)));                        send_resend_msg(devid, lastSEQ(dev->frameExpected));                    }                }                else                {                    /*                     * The sequence number isn't the one we want. If it's already been                     * received, then that's fine... just throw it away. If it's too                     * high, we've missed something, so must request a resend.                     * When dealing with circular sequence numbers, we cannot just use                     * the < and > operators; define the midpoints in the sequence.                     */                    int low = dev->frameExpected - (MAX_SEQ/2);                    if (low < 0)                        low += MAX_SEQ;                    if (adp_between(low, rx_packetseq, dev->frameExpected))                    {                        /* sequence low;. */                        LogInfo(LOG_CHANNEL, ("+++ seq low: (%d <= %d < %d), acking anyway.\n",                                              low, rx_packetseq, dev->frameExpected));                        send_heartbeat_ack_msg(devid, timestamp);                    }                    else                    {                        /* sequence high; missed something. */                        LogInfo(LOG_CHANNEL, ("+++ seq high: (%d), requesting resend of %d+1.\n",                                              rx_packetseq, lastSEQ(dev->frameExpected)));                                                send_resend_msg(devid, lastSEQ(dev->frameExpected));                    }                }                return;            }            if (rx_flags & CF_RELIABLE)            {                LogInfo(LOG_CHANNEL, ("*** Reliable packet received, rx seq %d, ack: %d\n",                                        rx_packetseq, rx_ackseq));                /* record that we received this packet -- needed to disambiguate                 * subsequent heartbeats.                 */                if (dev->lastReceived != lastSEQ(rx_packetseq))                    LogInfo(LOG_CHANNEL, ("@@@ This packet doesn't follow on from "                                          "last received (%d)?\n", dev->lastReceived));                                    dev->lastReceived = rx_packetseq;                /* This code allows the initial reset through on Ethernet, where a                 * previous session will have left the sequence numbers in an                 * indeterminate state (on serial/serpar, the final LinkCheck will                 * reset them)                 */#if ETHERNET_SUPPORTED                if (chanid == CI_HBOOT && devid == DI_ETHERNET)                {                    int reason;                    p_Buffer data_pkt = chan_pkt + CF_DATA_BYTE_POS;                    unpack_message(BUFFERDATA(data_pkt), "%w", &reason);                                        if ((reason & 0xFFFF) == (ADP_Reset & 0xFFFF))                    {                        LogInfo(LOG_CHANNEL, ("*** Reset/Reboot packet received, "                                              "reinit sequence numbers...\n"));                        Angel_ReinitChannels();                                                /* let this packet through, whatever it's sequence numbers... */                        rx_packetseq = dev->frameExpected;                    }                }#endif                if (rx_packetseq == dev->frameExpected) /* seq ok */                {                    LogInfo(LOG_CHANNEL, ("seq ok (%d), channel %d\n", rx_packetseq, chanid));                                            INC(dev->frameExpected);                                            /* remove the buffered packet which should have been kept */                    adp_remove_pkt(devid, rx_ackseq);                }                else                {                    /*                     * The sequence number isn't the one we want. If it's already been                     * received, then that's fine... just throw it away. If it's too                     * high, we've missed something, so must request a resend.                     * When dealing with circular sequence numbers, we cannot just use                     * the < and > operators; define the midpoints in the sequence.                     */                    int low = dev->frameExpected - (MAX_SEQ/2);                    if (low < 0)                        low += MAX_SEQ;                                        check_flow_control();                    if (adp_between(low, rx_packetseq, dev->frameExpected))  /* seq low */                    {                        LogWarning(LOG_CHANNEL, ("+++ seq low (%d <= %d < %d), discarding packet\n",                                                 low, rx_packetseq, dev->frameExpected));                        angel_ChannelReleaseBuffer(chan_pkt + CF_DATA_BYTE_POS);                                                /* we have already received this packet so discard */                        return;                    }                    else                    {                        /* sequence high; missed something. */                        LogWarning(LOG_CHANNEL, ("+++ seq high (%d < %d > %d), asking host to resend\n",                                                 low, rx_packetseq, dev->frameExpected));                        angel_ChannelReleaseBuffer(chan_pkt + CF_DATA_BYTE_POS);                        /* protocol sends last frame got ok, not the frame expected... */                        send_resend_msg(devid, lastSEQ(dev->frameExpected));                        return;                    }                }            }            else            {                LogInfo(LOG_CHANNEL, ("*** Uneliable packet received: rx seq: %d, frameExpected %d\n",                                        rx_packetseq, dev->frameExpected));            }                /* packet accepted ; send it off ... */            {                p_Buffer data_pkt = chan_pkt + CF_DATA_BYTE_POS;                unsigned data_len = chan_len - CF_DATA_BYTE_POS;                if (chan_state[chanid].reader != NULL)                {                    chan_state[chanid].reader(devid, chanid, data_pkt, data_len,                                              chan_state[chanid].read_cb_data);                }                else if (chanid == read_all_channel && read_all_callback != NULL)                {                    read_all_callback(devid, chanid, data_pkt, data_len,                                      read_all_cb_data);                }                else                {                    LogWarning(LOG_CHANNEL, ("NO READER for channel %d, dropped!\n",                                               chanid));                    angel_ChannelReleaseBuffer(chan_pkt);                }            }            break;        default:            LogWarning(LOG_CHANNEL, ("\n**** Receive bad msg (0x%x) freeing it.\n", chan_pkt));            check_flow_control();            /* free this buffer as we don't need it any more */            if (chan_pkt != 0)                angel_ChannelReleaseBuffer(chan_pkt + CF_DATA_BYTE_POS);            break;    }}/* * Function: angel_InitialiseChannels *  Purpose: initialise the channels layer * * see channels.h for full description */void angel_InitialiseChannels(void){    int i;    LogInfo(LOG_CHANNEL, ( "angel_InitialiseChannels: start\n"));    /* set up channel states */    for (i = 0; i < CI_NUM_CHANNELS; ++i)    {        chan_state[i].reader = NULL;        chan_state[i].read_cb_data = NULL;        chan_state[i].read_buffer = NULL;        chan_state[i].read_blocking = FALSE;        chan_state[i].writer = NULL;        chan_state[i].write_buff = NULL;        chan_state[i].write_cb_data = NULL;        chan_state[i].write_blocking = FALSE;    }    /* set up device states... */    Angel_InitChannels();    for (i = 0; i < DI_NUM_DEVICES; ++i)    {        if (angel_IsAngelDevice(i))        {            /* ...and register callback */            if (angel_DeviceRegisterRead(i, read_callback, (void *)i,                                         angel_ChannelAllocDevBuffer, NULL,                                         DC_DBUG)                != DE_OKAY)            {                LogError(LOG_CHANNEL, ( "cannot DeviceRegisterRead\n"));            }        }    }    active_device = DE_DEFAULT_ACTIVE;    read_all_callback = NULL;    read_all_cb_data = NULL;    angel_ChannelQuerySizes(&Angel_ChanBuffSize, &Angel_ChanLongSize);    LogInfo(LOG_CHANNEL, ( "angel_InitialiseChannels: complete\n"));    return;}/* * Function: angel_ChannelQuerySizes *  Purpose: return the default and maximum buffer sizes available to user * *   Params: *              Input: - *             Output: default_size    the usual size of buffer *                     max_size        the largest size of buffer *             In/Out: - * *            Returns: - * *      Reads globals: - *   Modifies globals: - * * Other side effects: - */static void angel_ChannelQuerySizes(unsigned *default_size,                        unsigned *max_size){    ASSERT(default_size != NULL, ("Nowhere to write default buffer size\n"));    ASSERT(max_size != NULL, ("Nowhere to write max buffer size\n"));    Angel_BufferQuerySizes(default_size, max_size);    /* remove space used for channel overheads */    *default_size -= CB_CHAN_DATA_BYTE_POS;    *max_size -= CB_CHAN_DATA_BYTE_POS;}/* * Function: angel_CanAckHeartbeat *  Purpose: To return whether we can or can't acknowledge heartbeat *           packets. We set an internal variable TRUE letting us know *           that we should do so.... * *   Params:  none. * *            Returns: - always TRUE * *      Reads globals: - *   Modifies globals: - Angel_AckedHeartbeats; read by code which *                       receives hbs to determine what to do. * * Other side effects: - none */word angel_CanAckHeartbeat(){#if 1    /* this is what was intended ... */    Angel_AckedHeartbeats = TRUE;    LogInfo(LOG_CHANNEL, ( "Will Acknowledge Heartbeats\n"));    return TRUE;#else    /* this is to disable heartbeat acks for SDT211 (RIC 6.8.97) ... */    /* as they cause problems elsewhere in the ROM code */    Angel_AckedHeartbeats = FALSE;    LogInfo(LOG_CHANNEL, ( "Not Acknowledging Heartbeats\n"));    return FALSE;#endif}/* * Function: angel_ChannelAllocBuffer *  Purpose: allocate a buffer that is at least req_size bytes long * * see channels.h for full description */p_Buffer angel_ChannelAllocBuffer(unsigned req_size){    p_Buffer ret_buffer;    /* commented out as the buffer code also has v. similar info calls:*/    /* LogInfo(LOG_CHANNEL, "angel_ChannelAllocBuffer: req_size %d\n", req_size); */    /* make sure we get space for our overheads */    req_size += CB_CHAN_DATA_BYTE_POS;    ret_buffer = Angel_BufferAlloc(req_size);    if (ret_buffer != NULL)    {        /* null the link pointer */        *CB_LINK(ret_buffer) = NULL;        /* shift the returned value to the data area */        ret_buffer += CB_CHAN_DATA_BYTE_POS;    }    /* LogInfo(LOG_CHANNEL, "angel_ChannelAllocBuffer: buffer 0x%x\n", ret_buffer); */    return ret_buffer;}/* * Function: angel_ChannelReleaseBuffer *  Purpose: release a buffer back to the free pool * * see channels.h for full description */void angel_ChannelReleaseBuffer(p_Buffer buffer){    /* commented out as the buffer code also has v. similar info calls: */    /* LogInfo(LOG_CHANNEL, ("angel_ChannelReleaseBuffer: buffer 0x%x\n", buffer)); */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -