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

📄 mapping.c

📁 Vista 核心Rally技术之-LLTD 实现源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * LICENSE NOTICE.
 *
 * Use of the Microsoft Windows Rally Development Kit is covered under
 * the Microsoft Windows Rally Development Kit License Agreement,
 * which is provided within the Microsoft Windows Rally Development
 * Kit or at http://www.microsoft.com/whdc/rally/rallykit.mspx. If you
 * want a license from Microsoft to use the software in the Microsoft
 * Windows Rally Development Kit, you must (1) complete the designated
 * "licensee" information in the Windows Rally Development Kit License
 * Agreement, and (2) sign and return the Agreement AS IS to Microsoft
 * at the address provided in the Agreement.
 */

/*
 * Copyright (c) Microsoft Corporation 2005.  All rights reserved.
 * This software is provided with NO WARRANTY.
 */

/* This is the state machine that controls the topology mapping process, smT.
 * Once enumeration by a Topology-Discovery Mapper has been completed, that
 * mapper alone is enabled to make other requests of the Responder, until it
 * relinquishes its lock on the Responder, either by sending a Reset or by
 * timing out (Inactivity timeout).
 *
 * A session conceptually represents the association of a Mapper with this
 * Responder, throughout the lifetime of that association. State-information
 * for smT is maintained in one area of the process globals, since there is
 * at most one session associated with the Responder process at a time.
 *
 **/

#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "globals.h"

#include "statemachines.h"
#include "packetio.h"

static
int
SufficientChargeAvailable()
{
    IF_DEBUG
        dbgprintf("SCA: ctc_pkts=" FMT_UINT32 "   pkts_needed=" FMT_UINT32 \
                  "    ctc_bytes=" FMT_UINT32 "   bytes_needed=" FMT_UINT32 "\n",
                  g_ctc_packets, g_neededPackets, g_ctc_bytes, g_neededBytes);
    END_DEBUG

    if ((g_ctc_packets >= g_neededPackets) && (g_ctc_bytes >= g_neededBytes))
        return TRUE;
    else
        return FALSE;
}

static void
ProcessEmits()
{
    topo_ether_header_t    *ehdr;	/* pointer to ethernet header in emit buf */
    topo_base_header_t     *bhdr;	/* pointer to base header in emit buf */
    topo_emit_header_t     *emit;	/* pointer to emit header in emit buf */

    /* copy current rxbuf into the emit buffer */
    memcpy(g_emitbuf, g_rxbuf, g_rcvd_pkt_len);

    /* setup the emit machinery */
    assert(g_emit_remaining == 0);
    g_emit_remaining = g_this_event.numDescrs;
    g_emit_seqnum = g_sequencenum;		   /* might be zero for an unreliable Emit */
    ehdr = (topo_ether_header_t*)(g_emitbuf);
    bhdr = (topo_base_header_t*)(ehdr + 1);
    emit = (topo_emit_header_t*)(bhdr + 1);
    g_emitdesc = (topo_emitee_desc_t*)(emit + 1);  // pointer to the first descriptor
}

static
void
ChargeAdd(int pktlen)
{
    struct timeval now;

    g_ctc_packets++;
    if (g_ctc_packets > TOPO_CTC_PACKETS_MAX)
	g_ctc_packets = TOPO_CTC_PACKETS_MAX;

    g_ctc_bytes += pktlen;
    if (g_ctc_bytes > TOPO_CTC_BYTES_MAX)
	g_ctc_bytes = TOPO_CTC_BYTES_MAX;

    IF_TRACED(TRC_CHARGE)
	dbgprintf("ChargeAdd: CTC now has bytes=" FMT_UINT32 " & packets=" FMT_UINT32 "\n",
		g_ctc_bytes, g_ctc_packets);
    END_TRACE

    /* Reset charge timer */
    gettimeofday(&now, NULL);
    timeval_add_ms(&now, TOPO_CHARGE_TIMEOUT);
    CANCEL(g_charge_timer);
    g_charge_timer = event_add(&now, state_charge_timeout, /*state:*/NULL);
}


static
void
ChargeConsume(int pktlen)
{
    struct timeval now;

    if (g_ctc_packets)
        g_ctc_packets--;

    if (g_ctc_bytes)
        g_ctc_bytes -= pktlen;

    IF_TRACED(TRC_CHARGE)
	dbgprintf("ChargeConsume: CTC now has bytes=" FMT_UINT32 " & packets=" FMT_UINT32 "\n",
		g_ctc_bytes, g_ctc_packets);
    END_TRACE

    /* Reset charge timer */

    gettimeofday(&now, NULL);
    timeval_add_ms(&now, TOPO_CHARGE_TIMEOUT);
    CANCEL(g_charge_timer);
    g_charge_timer = event_add(&now, state_charge_timeout, /*state:*/NULL);
}


/***********************  Q U I E S C E N T   S T A T E  ***********************/

static
enum sm_Status
smT_QuiescentHandler( protocol_event_t* evt )
{
    IF_TRACED(TRC_STATE)
        if (evt->evtType != evtBlockTimeout)
        {
            printf("smT (Quiescent): 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_Charge:
          case Opcode_Probe:
          case Opcode_Query:
          case Opcode_QueryLargeTlv:
            IF_TRACED(TRC_PACKET)
                printf("smT (Quiescent): Hoisting packet ignored.\n");
            END_TRACE
            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_Hello:
          case Opcode_Train:
          case Opcode_ACK:
          case Opcode_QueryResp:
          case Opcode_Flat:
          case Opcode_QueryLargeTlvResp:
            IF_TRACED(TRC_STATE)
                printf("smT (Quiescent): Ignored packet w/ known opcode: %s\n",
                       Topo_opcode_names[g_opcode]);
            END_TRACE
            break;

          default:
            warn("smT (Quiescent): Ignored packet w/ unknown opcode: %d\n",g_opcode);
            return PROCESSING_ABORTED;
        }   /*** end of switch (g_opcode) ***/
        break;

      case evtDiscoverRcvd:
        if (evt->isAckingMe)
        {
            uint16_t	gen = ntohs(g_discover_hdr->mh_gen);
            if (evt->isInternalEvt == FALSE  &&  // if a real acking-Discover,
                gen != 0                     &&  // has a non-zero gen,
                g_generation != gen)             // that differs from ours,
            {   g_generation = gen;   }   // then save it for future Hellos.
            IF_TRACED(TRC_STATE)
                printf("smT (Quiescent): Leaving for Command state\n");
            END_TRACE
            g_smT_state = smT_Command;
        }
        break;

      case evtInactivityTimeout:
      case evtResetRcvd:
        /* If the Topo-session was reset, */
        if (evt->ssn == g_topo_session)
        {
            /* zero the credits, and clear the charge-timer */
            g_ctc_packets = g_ctc_bytes = 0;
            CANCEL(g_charge_timer);
            /* and NULL the g_topo_session ptr */
            g_topo_session = NULL;
        }
        break;

      case evtEmitRcvd:
        IF_TRACED(TRC_PACKET)
            printf("smT (Quiescent): Hoisting packet (Emit) ignored.\n");
        END_TRACE
        break;

      case evtBlockTimeout:
        break;

      case evtChargeTimeout:
      case evtEmitTimeout:
      case evtHelloDelayTimeout:
      default:
        IF_DEBUG
            printf("smT (Quiescent): Ignored event %s\n",smEvent_names[evt->evtType]);
        END_DEBUG
        break;
    }   /*** end of switch (eventType) ***/

    return PROCESSING_COMPLETED;
}

/***********************  C O M M A N D   S T A T E  ***********************/

static
enum sm_Status
smT_CommandHandler( protocol_event_t* evt )
{
    IF_TRACED(TRC_STATE)
        if (evt->evtType != evtBlockTimeout)
        {
            printf("smT (Command): 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_Charge:
            ChargeAdd(g_rcvd_pkt_len);		// also restarts the charge-timeout timer
            if (g_sequencenum)
            {
                packetio_tx_flat();
                ChargeConsume(g_tx_len);
            }
            break;

          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_Query:
            IF_TRACED(TRC_PACKET)
                printf("smT (Command): Sending query-Resp\n");
            END_TRACE
            packetio_tx_queryresp();
            break;

          case Opcode_QueryLargeTlv:
            {
                tlv_desc_t *tlvDescr = Tlvs;

                /* search the TLVs, which may not be consecutive or in order, for one with the given number */
                for (;tlvDescr->number != 0; tlvDescr++)
                {
                    if (tlvDescr->number == g_qltlv_hdr->qh_type)
                    {
                        size_t    offset;

                        IF_TRACED(TRC_PACKET)
                            printf("smT (Command): Sending qltlv-Resp with LTLV # 0x%X\n", tlvDescr->number);
                        END_TRACE
                        
                        offset = ntohs(g_qltlv_hdr->qh_offset) + (g_qltlv_hdr->qh_rsvd1 << 16);
                        packetio_tx_qltlvResp(g_sequencenum, tlvDescr, offset);
                        break;
                    }
                }
                /* if it falls out without finding a match, nothing will be sent */
            }
            break;

          case Opcode_Emit:	// should never occur - explicit event
          case Opcode_Reset:	// should never occur - explicit event

⌨️ 快捷键说明

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