📄 channels.c
字号:
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 + -