📄 mapping.c
字号:
case Opcode_Discover: // should never occur - explicit event
case Opcode_QueryLargeTlvResp:
case Opcode_Hello:
case Opcode_Train:
case Opcode_ACK:
case Opcode_QueryResp:
case Opcode_Flat:
IF_TRACED(TRC_PACKET)
printf("smT (Command): Ignored packet w/ known opcode: %s\n",Topo_opcode_names[g_opcode]);
END_TRACE
break;
default:
IF_TRACED(TRC_PACKET)
printf("smT (Command): Ignored packet w/ unknown opcode: %d\n",g_opcode);
END_TRACE
return PROCESSING_ABORTED;
} /*** end of switch (g_opcode) ***/
break;
case evtInactivityTimeout:
case evtResetRcvd:
/* If the Topo-session timed out, or was Reset, */
IF_TRACED(TRC_PACKET)
printf("smT (Command): ResetRcvd, %s for topo-session\n",evt->ssn == g_topo_session?"is":"is not");
END_TRACE
if (evt->ssn == g_topo_session)
{
/* zero the credits, clear the charge-timer, and NULL out the topo-session ptr */
IF_DEBUG
puts("zero -> ctc, ctc-timer is cancelled");
puts("NULL -> g_topo_session");
puts("clearing seeslist");
END_DEBUG
g_ctc_packets = g_ctc_bytes = 0;
CANCEL(g_charge_timer);
/* clear the sees-list, */
seeslist_clear();
/* NULL -> g_topo_session marks the topo-session as completely invalid */
g_topo_session = NULL;
/* and return to Quiescent state. */
IF_TRACED(TRC_PACKET)
printf("smT (Command): Leaving for Quiescent (Inactive or Reset).\n");
END_TRACE
g_smT_state = smT_Quiescent;
}
break;
case evtChargeTimeout:
/* zero the credits, and clear the charge-timer */
g_ctc_packets = g_ctc_bytes = 0;
CANCEL(g_charge_timer);
break;
case evtEmitRcvd:
/* Special case: Unsequenced Emits MUST NOT have more than one emitee to match Vista
* interpretation of the spec. Any that do, MUST BE IGNORED! */
{
topo_emit_header_t* emit; /* pointer to emit header in rxbuf */
uint16_t emiteeCnt;
emit = (topo_emit_header_t*)(g_base_hdr + 1);
emiteeCnt = ntohs(emit->eh_numdescs);
if (emiteeCnt > 1 && g_sequencenum==0) break;
}
/* The response will require charge, so count this receipt */
ChargeAdd(g_rcvd_pkt_len);
/* If ctc is big enuff, process the emits */
if (SufficientChargeAvailable())
{
/* zero the credits, and clear the charge-timer,
* so we won't timeout for lack of charge */
g_ctc_packets = g_ctc_bytes = 0;
CANCEL(g_charge_timer);
/* ready the list of emitees and their count-remaining */
ProcessEmits();
DEBUG({printf("smT (Command): g_emit_remaining = %d\n",g_emit_remaining);})
if (g_emit_remaining > 0)
{
bool_t pausing;
IF_TRACED(TRC_STATE)
printf("smT (Command): Leaving for Emit\n");
END_TRACE
g_smT_state = smT_Emit;
pausing = set_emit_timer();
if (pausing!=TRUE)
{
g_this_event.evtType = evtEmitTimeout;
IF_TRACED(TRC_STATE)
printf("smT (Command): No Pause in 1st emitee: Inject an EmitTimeout immediately.\n");
END_TRACE
return KEEP_GOING;
}
} else {
/* Emit with 0 descs: valid, but not very useful.
* Stay in Command state (possibly ACKing) */
if (g_emit_seqnum)
{
packetio_tx_ack(g_emit_seqnum);
ChargeConsume(g_tx_len);
}
}
} else {
/* Otherwise, tx-Flat */
packetio_tx_flat();
ChargeConsume(g_tx_len);
}
break;
case evtBlockTimeout:
break;
case evtDiscoverRcvd:
{ /* need block for declarations */
uint16_t gen = ntohs(g_discover_hdr->mh_gen);
if (evt->isInternalEvt == FALSE && // if a real Discover packet,
gen != 0 && // has a non-zero gen,
g_generation != gen) // that differs from ours,
g_generation = gen; // then save it for future Hellos.
}
break;
case evtEmitTimeout:
case evtHelloDelayTimeout:
default :
IF_TRACED(TRC_STATE)
printf("smT (Command): Ignored event %s\n",smEvent_names[evt->evtType]);
END_TRACE
break;
}
return PROCESSING_COMPLETED;
}
/*********************** E M I T S T A T E ***********************/
static
enum sm_Status
smT_EmitHandler( protocol_event_t* evt )
{
IF_TRACED(TRC_STATE)
printf("smT (Emit): Entered with event %s",smEvent_names[evt->evtType]);
if (g_this_event.evtType==evtPacketRcvd)
{
printf(" (%s)\n",Topo_opcode_names[g_opcode]);
} else {
puts("");
}
END_TRACE
switch (evt->evtType)
{
case evtPacketRcvd:
switch (g_opcode)
{
case Opcode_Probe:
IF_TRACED(TRC_PACKET)
printf("smT (Command): Logging Probe from " ETHERADDR_FMT "\n",ETHERADDR_PRINT(&g_base_hdr->tbh_realsrc));
END_TRACE
seeslist_enqueue(FALSE, &g_base_hdr->tbh_realsrc);
break;
case Opcode_Emit: // should never occur - explicit event
case Opcode_Reset: // should never occur - explicit event
case Opcode_Discover: // should never occur - explicit event
case Opcode_Charge:
case Opcode_Hello:
case Opcode_Train:
case Opcode_ACK:
case Opcode_Query:
case Opcode_QueryResp:
case Opcode_Flat:
case Opcode_QueryLargeTlv:
case Opcode_QueryLargeTlvResp:
IF_TRACED(TRC_PACKET)
printf("smT (Emit): Ignored packet w/ known opcode: %s\n",Topo_opcode_names[g_opcode]);
END_TRACE
break;
default:
IF_TRACED(TRC_PACKET)
printf("smT (Emit): Ignored packet w/ unknown opcode: %d\n",g_opcode);
END_TRACE
return PROCESSING_ABORTED;
} /*** end of switch (g_opcode) ***/
break;
case evtInactivityTimeout:
case evtResetRcvd:
/* If the Topo-session was reset, */
if (evt->ssn == g_topo_session)
{
/* zero the credits & the emits-left, and clear the charge-timer and emit-timer, */
g_ctc_packets = g_ctc_bytes = g_emit_remaining = 0;
CANCEL(g_charge_timer);
CANCEL(g_emit_timer);
/* clear the sees-list, */
seeslist_clear();
/* NULL -> g_topo_session marks the topo-session as completely invalid */
g_topo_session = NULL;
/* and return to Quiescent state. */
IF_TRACED(TRC_STATE)
printf("smT (Emit): Leaving for Quiescent (Reset or Inactive)\n");
END_TRACE
g_smT_state = smT_Quiescent;
}
break;
case evtEmitTimeout:
packetio_tx_emitee(g_emitdesc);
g_emit_remaining--;
g_emitdesc++;
/* any more? */
if (g_emit_remaining == 0)
{
/* go back to Command state (possibly sending ACK as we leave) */
IF_TRACED(TRC_STATE)
printf("smT (Emit): Leaving for Command\n");
END_TRACE
g_smT_state = smT_Command;
CANCEL(g_emit_timer);
if (g_emit_seqnum)
packetio_tx_ack(g_emit_seqnum);
} else {
/* schedule the transmission */
if (set_emit_timer() == FALSE)
{
/* send next with no pause, by re-processing this event */
return KEEP_GOING;
}
}
break;
case evtDiscoverRcvd:
case evtEmitRcvd:
case evtBlockTimeout:
case evtChargeTimeout:
case evtHelloDelayTimeout:
default :
IF_TRACED(TRC_STATE)
printf("smT (Emit): Ignored event %s\n",smEvent_names[evt->evtType]);
END_TRACE
break;
}
return PROCESSING_COMPLETED;
}
/*********************** ***********************/
/*********************** S T A T E M A C H I N E ***********************/
/*********************** ***********************/
/* smT_process_event() - process an incoming event (rcvd pkt or timeout)
* and distribute to the current state's handler */
enum sm_Status
smT_process_event( protocol_event_t* evt )
{
enum sm_Status ClockControl = PROCESSING_COMPLETED;
// g_topo_session->ssn_is_valid != TRUE ||
if (g_topo_session == NULL || /* if there is no valid topo-session, or */
(evt->ssn && evt->ssn != g_topo_session)) /* this ssn doesn't match the valid topo... */
{
return PROCESSING_ABORTED; /* Fail with an Abort */
}
IF_DEBUG
//*/ printf("smT_process_event: Entered with event %s\n",smEvent_names[evt->evtType]);
END_DEBUG
/* allow this state machine to autoclock itself, and request further processing */
do {
IF_DEBUG
//*/ printf("smT_process_event: Processing event %s\n",smEvent_names[evt->evtType]);
END_DEBUG
switch (g_smT_state)
{
case smT_Quiescent:
ClockControl = smT_QuiescentHandler( evt );
break;
case smT_Command:
ClockControl = smT_CommandHandler( evt );
break;
case smT_Emit:
ClockControl = smT_EmitHandler( evt );
break;
default:
ClockControl = PROCESSING_ABORTED; /* Stop! smT in unknown state! */
break;
}
IF_TRACED(TRC_STATE)
if (ClockControl == KEEP_GOING) puts("smT: auto-clocking...");
END_TRACE
} while (ClockControl == KEEP_GOING);
return ClockControl;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -