Пример #1
0
void AsteriskManager::onReadyRead()
{
	QRegExp keyValue("^([A-Za-z0-9\\-]+):\\s(.+)$");
	QByteArray line;

    qDebug("<ami>");

	while (canReadLine()) {
		line = readLine();

        qDebug() << line.trimmed();

		if (line != "\r\n") {
            if (keyValue.indexIn(line) > -1) {
				packetBuffer[keyValue.cap(1)] = stringValue(keyValue.cap(2).trimmed());
            } else if (line.startsWith("Asterisk Call Manager")) {
                version_ = line.replace("Asterisk Call Manager/", QByteArray()).trimmed();

                emit connected(version_);
            }
		} else if (!packetBuffer.isEmpty()) {
			dispatchPacket();
		}
	}

    qDebug("</ami>");
}
Пример #2
0
/* Reads packets and processes waiting packets */
void EQPacket::processPackets (void)
{
  /* Make sure we are not called while already busy */
  if (m_busy_decoding)
     return;

  /* Set flag that we are busy decoding */
  m_busy_decoding = true;
  
  unsigned char buffer[BUFSIZ]; 
  short size;
  
  /* fetch them from pcap */
  while ((size = m_packetCapture->getPacket(buffer)))
  {
    /* Now.. we know the rest is an IP udp packet concerning the
     * host in question, because pcap takes care of that.
     */
      
    /* Now we assume its an everquest packet */
    if (m_recordPackets)
    {
      time_t now = time(NULL);
      m_vPacket->Record((const char *) buffer, size, now, PACKETVERSION);
    }
      
    dispatchPacket (size - sizeof (struct ether_header),
		  (unsigned char *) buffer + sizeof (struct ether_header) );
  }

  /* Clear decoding flag */
  m_busy_decoding = false;
}
Пример #3
0
void OSCPacketDispatcher::dispatchBundle(OSCBundle& bundle, QHostAddress& address)
{
    QDateTime& timestamp = bundle.getTimestamp();
    QList<OSCPacket>& packets = bundle.getPackets();
    for (int i = 0; i < packets.length(); i++)
    {
        dispatchPacket((OSCPacket&)packets.at(i), address, &timestamp);
    }
}
void AsteriskManager::onReadyRead()
{
  QRegExp keyValue("^([A-Za-z0-9\\-]+):\\s(.+)$");
  QByteArray line;


  while (canReadLine()) {
    line = readLine();

    if (line != "\r\n") {
      if (keyValue.indexIn(line) > -1)
        packetBuffer[keyValue.cap(1)] = stringValue(keyValue.cap(2).trimmed());
      else if (line.startsWith("ChanVariable"))
      {
        if(!packetBuffer.contains("ChanVars"))
        {
          QMap<QString, QVariant> chanvars;
          packetBuffer.insert("ChanVars",chanvars);
        }
        QMap<QString, QVariant> chanvars = packetBuffer.value("ChanVars").toMap();
        //Get the Channel Name
        QRegExp re ("^ChanVariable\\(([^)]+)\\):\\ (.*)$");
        if(re.exactMatch(line))
        {
          if(!chanvars.contains(re.cap(1)))
          {
            QMap<QString, QVariant> chanvarvals;
            chanvars.insert(re.cap(1),chanvarvals);
          }
          QMap<QString, QVariant> chanvarvals = chanvars.value(re.cap(1)).toMap();
          QRegExp re2 ("^([^=]+)=(.*)$");
          if(re2.exactMatch(re.cap(2).trimmed()))
          {
            if(re2.captureCount() == 2)
            {
              chanvarvals.insert(re2.cap(1), re2.cap(2));
            }
          }
          chanvars.insert(re.cap(1),chanvarvals);
        }
        packetBuffer.insert("ChanVars",chanvars);
      }
      else if (line.startsWith("Asterisk Call Manager"))
        emit connected(line.replace("Asterisk Call Manager/", QByteArray()).trimmed());
    } else if (!packetBuffer.isEmpty()) {
      dispatchPacket();
    }
  }
}
Пример #5
0
////////////////////////////////////////////////////
// This function decides the fate of the Everquest packet 
// and dispatches it to the correct packet stream for handling function
void EQPacket::dispatchPacket(int size, unsigned char *buffer)
{
#ifdef DEBUG_PACKET
  debug ("EQPacket::dispatchPacket()");
#endif /* DEBUG_PACKET */

  // Create an object to parse the packet
  EQUDPIPPacketFormat packet(buffer, size, false);

  dispatchPacket(packet);

  // signal a new packet. This has to be at the end so that the session is
  // filled in if possible, so that it can report on crc errors properly
  emit newPacket(packet);
}
Пример #6
0
////////////////////////////////////////////////////
// process the packets payload, decoding if necessary
void EQPacketStream::processPayload(uint8_t* data, size_t len)
{
  uint16_t opCode = *(uint16_t*)data;
  
  data += 2;
  len -= 2;
  
  if (opCode & FLAG_DECODE)
    decodePacket(data, len, opCode);
  else
  {
    emit rawPacket(data, len, m_dir, opCode);

    dispatchPacket(data, len, opCode, m_opcodeDB.find(opCode));
  }
}
Пример #7
0
/////////////////////////////////////////////////////
// Handle a protocol level packet. This could be either a top-level
// EQUDPIPPacket or a subpacket that is just an EQProtocolPacket. Either way
// we use net opcodes here.
void EQPacketStream::processPacket(EQProtocolPacket& packet, bool /*isSubpacket*/)
{
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
  seqDebug("-->EQPacketStream::processPacket, subpacket=%s on stream %s (%d)",
    (isSubpacket ? "true" : "false"), EQStreamStr[m_streamid], m_streamid);
#endif

  if (IS_APP_OPCODE(packet.getNetOpCode()))
  {
    // This is an app-opcode directly on the wire with no wrapping protocol
    // information. Weird, but whatever gets the stream read, right?
	dispatchPacket(packet.payload(), packet.payloadLength(), 
      packet.getNetOpCode(), m_opcodeDB.find(packet.getNetOpCode()));
    return;
  }

  // Process the net opcode
  switch (packet.getNetOpCode())
  {
    case OP_Combined:
    {
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
      seqDebug("EQPacket: found combined packet (net op: %04x, size %d) on stream %s (%d). Unrolling.", 
        packet.getNetOpCode(), packet.payloadLength(), 
        EQStreamStr[m_streamid], m_streamid);
#endif

      // Rolled up multiple packets inside this packet. Need to unroll them
      // and process them individually. subpacket starts after the net opcode.
      uint8_t* subpacket = packet.payload();

      while (subpacket < packet.payload() + packet.payloadLength())
      {
        // Length specified first on the wire.
        uint8_t subpacketLength = subpacket[0];

        // Move past the length
        subpacket++;

        // OpCode (in net order)
        uint16_t subOpCode = *(uint16_t*)subpacket;
        
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
        seqDebug("EQPacket: unrolling length %d bytes from combined packet on stream %s (%d). Opcode %04x", 
          subpacketLength, EQStreamStr[m_streamid], m_streamid, subOpCode);
#endif
        
        // Opcode is next. Net opcode or app opcode?
        if (subOpCode == 0)
        {
          // App opcode < 0x00ff. Skip the first byte and dispatch the app
          // opcode appropriately
          subpacket++;

          subOpCode = *(uint16_t*)subpacket;

#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
          seqDebug("EQPacket: processing unrolled special app opcode, length %d bytes from combined packet on stream %s (%d). Opcode %04x", 
            subpacketLength-3, EQStreamStr[m_streamid], m_streamid, subOpCode);
#endif

          // App opcode. Dispatch it, skipping opcode.
          dispatchPacket(&subpacket[2], subpacketLength-2, 
            subOpCode, m_opcodeDB.find(subOpCode));

        }
        else if (IS_NET_OPCODE(subOpCode))
        {
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
          seqDebug("EQPacket: processing unrolled net opcode, length %d bytes from combined packet on stream %s (%d). Opcode %04x", 
            subpacketLength, EQStreamStr[m_streamid], m_streamid, subOpCode);
#endif

          // Net opcode. false = copy. true = subpacket
          EQProtocolPacket spacket(subpacket, subpacketLength, false, true);

          processPacket(spacket, true);
        }
        else
        {
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
        seqDebug("EQPacket: processing unrolled app opcode, length %d bytes from combined packet on stream %s (%d). Opcode %04x", 
          subpacketLength-2, EQStreamStr[m_streamid], m_streamid, subOpCode);
#endif

          // App opcode. Dispatch it, skipping opcode.
          dispatchPacket(&subpacket[2], subpacketLength-2, 
            subOpCode, m_opcodeDB.find(subOpCode));
        }
        subpacket += subpacketLength;
      }
    }
    break;
    case OP_AppCombined:
    {
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
      seqDebug("EQPacket: found appcombined packet (net op: %04x, size %d) on stream %s (%d). Unrolling.", 
        packet.getNetOpCode(), packet.payloadLength(), 
        EQStreamStr[m_streamid], m_streamid);
#endif

      // Multiple app op codes in the same packet. Need to unroll and dispatch
      // them.
      uint8_t* subpacket = packet.payload();

      while (subpacket < packet.payload() + packet.payloadLength())
      {
        // Length specified first on the wire.
        uint8_t subpacketLength = subpacket[0];

        // Move past the length
        subpacket++;

        if (subpacketLength != 0xff)
        {
          // Dispatch app op code using given packet length. Net order!
          uint16_t subOpCode = *(uint16_t*)(subpacket);

          // Handle 3 byte opcodes properly
          if (subOpCode == 0)
          {
            // 3 byte opcode. Drop the first byte, opcode is byte 2 and 3
            subpacket++;
            subpacketLength--;
            subOpCode = *(uint16_t*)(subpacket);
          }

#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
        seqDebug("EQPacket: unrolling length %d bytes from combined packet on stream %s (%d). Opcode %04x", 
          subpacketLength, EQStreamStr[m_streamid], m_streamid, subOpCode);
        seqDebug("EQPacket: processing unrolled app opcode, length %d bytes from combined packet on stream %s (%d). Opcode %04x", 
          subpacketLength-2, EQStreamStr[m_streamid], m_streamid, subOpCode);
#endif

          // Dispatch, skipping op code.
          dispatchPacket(&subpacket[2], subpacketLength-2, 
            subOpCode, m_opcodeDB.find(subOpCode));

          // Move ahead
          subpacket += subpacketLength;
        }
        else
        {
          // If original length is 0xff, it means it is a long one. The length
          // is 2 bytes and next.
          uint16_t longOne = eqntohuint16(subpacket);
 
          // Move past the 2 byte length
          subpacket += 2;

          // OpCode next. Net order for op codes.
          uint16_t subOpCode = *(uint16_t*)subpacket;

          // Handle 3 byte opcodes properly
          if (subOpCode == 0)
          {
            // 3 byte opcode. Drop the first byte, opcode is byte 2 and 3
            subpacket++;
            longOne--;
            subOpCode = *(uint16_t*)(subpacket);
          }
          
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
        seqDebug("EQPacket: unrolling length %d bytes from combined packet on stream %s (%d). Opcode %04x", 
          longOne, EQStreamStr[m_streamid], m_streamid, subOpCode);
        seqDebug("EQPacket: processing unrolled app opcode, length %d bytes from combined packet on stream %s (%d). Opcode %04x", 
          longOne-2, EQStreamStr[m_streamid], m_streamid, subOpCode);
#endif

          // Dispatch, skipping op code.
          dispatchPacket(&subpacket[2], longOne-2, 
            subOpCode, m_opcodeDB.find(subOpCode));

          // Move ahead
          subpacket += longOne;
        }
      }
    }
    break;
    case OP_Packet:
    {
      // Normal unfragmented sequenced packet.
      uint16_t seq = packet.arqSeq();
      emit seqReceive(seq, (int)m_streamid);

      // Future packet?
      if (seq == m_arqSeqExp)
      {
        // Expected packet.
        m_arqSeqExp++;
        emit seqExpect(m_arqSeqExp, (int)m_streamid);

        // OpCode next. Net order for op codes.
        uint16_t subOpCode = *(uint16_t*)(packet.payload());
       
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)
        seqDebug("SEQ: Found next sequence number in data stream %s (%d), incrementing expected seq, %04x (op code %04x, sub opcode %04x)", 
          EQStreamStr[m_streamid], m_streamid, seq, 
          packet.getNetOpCode(), subOpCode);
#endif

        // Opcode is next. Net opcode or app opcode?
        if (subOpCode == 0)
        {
          // App opcode < 0x00ff. Skip the first byte and dispatch the app
          // opcode appropriately
          subOpCode = *(uint16_t*)&packet.payload()[1];

#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)
          seqDebug("EQPacket: special app opcode extracted for opcode 0000 on stream %s (%d). Opcode %04x", 
            EQStreamStr[m_streamid], m_streamid, subOpCode);
#endif

          // App opcode. Dispatch it, skipping opcode.
          dispatchPacket(&packet.payload()[3], packet.payloadLength()-3, 
            subOpCode, m_opcodeDB.find(subOpCode));

        }
        else if (IS_NET_OPCODE(subOpCode))
        {
          // Net opcode. false = no copy. true = subpacket.
          EQProtocolPacket spacket(packet.payload(), 
            packet.payloadLength(), false, true);

          processPacket(spacket, true);
        }
        else
        {
          // App opcode. Dispatch, skipping opcode.
          dispatchPacket(&packet.payload()[2], packet.payloadLength()-2,
            subOpCode, m_opcodeDB.find(subOpCode));
        }
      }
      else if ((seq > m_arqSeqExp && 
                  seq < (uint32_t(m_arqSeqExp + arqSeqWrapCutoff))) ||
               seq < (int32_t(m_arqSeqExp) - arqSeqWrapCutoff))
      {
        // Yeah, future packet. Push it on the packet cache.
#ifdef PACKET_PROCESS_DIAG
        seqDebug("SEQ: out of order sequence %04x stream %s (%d) expecting %04x, sending to cache, %04d",
          seq, EQStreamStr[m_streamid], m_streamid, 
          m_arqSeqExp, m_cache.size());
#endif
        setCache(seq, packet);
      }
      else
      {
#ifdef PACKET_PROCESS_DIAG
        // Past packet outside the cut off
        seqWarn("SEQ: received sequenced %spacket outside expected window on stream %s (%d) netopcode=%04x size=%d. Expecting seq=%04x got seq=%04x, window size %d, dropping packet as in the past.", 
          (isSubpacket ? "sub" : ""),
          EQStreamStr[m_streamid], m_streamid,
          packet.getNetOpCode(), packet.payloadLength(), 
          m_arqSeqExp, seq, arqSeqWrapCutoff);
#endif
      }
    }
    break;
    case OP_Oversized:
    {
      // Fragmented sequenced data packet.
      uint16_t seq = packet.arqSeq();
      emit seqReceive(seq, (int)m_streamid);

      // Future packet?
      if (seq == m_arqSeqExp)
      {
        // Expected packet.
        m_arqSeqExp++;
        emit seqExpect(m_arqSeqExp, (int)m_streamid);
       
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)
        seqDebug("SEQ: Found next sequence number in data stream %s (%d), incrementing expected seq, %04x (op code %04x)", 
          EQStreamStr[m_streamid], m_streamid, seq, packet.getNetOpCode());
#endif

        // Push the fragment on.
        m_fragment.addFragment(packet);

        if (m_fragment.isComplete())
        {
          // OpCode from fragment. In network order.
          uint16_t fragOpCode = *(uint16_t*)(m_fragment.data());

#ifdef PACKET_PROCESS_DIAG
        seqDebug("SEQ: Completed oversized app packet on stream %s with seq %04x, total size %d opcode %04x", 
          EQStreamStr[m_streamid], seq, m_fragment.size()-2, fragOpCode);
#endif

          // dispatch fragment. Skip opcode.
          if (fragOpCode == 0)
          {
            // Special app opcode. Skip first byte and op is byte 2 and 3.
            fragOpCode = *(uint16_t*)(&m_fragment.data()[1]);

#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)
            seqDebug("EQPacket: special app opcode on completed fragment for opcode 0000 on stream %s (%d). Opcode %04x", 
            EQStreamStr[m_streamid], m_streamid, fragOpCode);
#endif

            dispatchPacket(&m_fragment.data()[3], m_fragment.size()-3,
              fragOpCode, m_opcodeDB.find(fragOpCode)); 
          }
          else
          {
            dispatchPacket(&m_fragment.data()[2], m_fragment.size()-2,
              fragOpCode, m_opcodeDB.find(fragOpCode)); 
          }

          m_fragment.reset();
        }
      }
      else if ((seq > m_arqSeqExp && 
                  seq < (uint32_t(m_arqSeqExp + arqSeqWrapCutoff))) ||
               seq < (int32_t(m_arqSeqExp) - arqSeqWrapCutoff))
      {
        // Yeah, future packet. Push it on the packet cache.
#ifdef PACKET_PROCESS_DIAG
        seqDebug("SEQ: out of order sequence %04x stream %s (%d) expecting %04x, sending to cache, %04d",
          seq, EQStreamStr[m_streamid], m_streamid, 
          m_arqSeqExp, m_cache.size());
#endif
        setCache(seq, packet);
      }
      else
      {
#ifdef PACKET_PROCESS_DIAG
        // Past packet outside the cut off
        seqWarn("SEQ: received sequenced %spacket outside expected window on stream %s (%d) netopcode=%04x size=%d. Expecting seq=%04x got seq=%04x, window size %d, dropping packet as in the past.", 
          (isSubpacket ? "sub" : ""),
          EQStreamStr[m_streamid], m_streamid,
          packet.getNetOpCode(), packet.payloadLength(), 
          m_arqSeqExp, seq, arqSeqWrapCutoff);
#endif
      }
    }
    break;
    case OP_SessionRequest:
    {
      // Session request from client to server.
      // 
      // Sanity check the size. Don't assume any packet we see is an EQ
      // session request, since we're gonna cause a huge freakin' malloc
      // on the maxlength of the session which for some reason some people
      // won't enjoy!
      if (packet.payloadLength() != sizeof(SessionRequestStruct))
      {
          // Either SessionRequestStruct changed or this isn't a session
          // request.
#if defined(PACKET_PROCESS_DIAG) || defined(PACKET_SESSION_DIAG)
          seqDebug("EQPacket: Ignoring SessionRequest %s:%u->%s:%u with invalid size %d.",
            ((EQUDPIPPacketFormat&) packet).getIPv4SourceA().ascii(),
            ((EQUDPIPPacketFormat&) packet).getSourcePort(),
            ((EQUDPIPPacketFormat&) packet).getIPv4DestA().ascii(),
            ((EQUDPIPPacketFormat&) packet).getDestPort(),
            packet.payloadLength());
#endif
          break;
      }

      // Pull off session request information
      SessionRequestStruct* request = (SessionRequestStruct*) packet.payload();

      m_sessionId = eqntohuint32((uint8_t*)&(request->sessionId));
      m_maxLength = eqntohuint32((uint8_t*)&(request->maxLength));

      // Sanity check the max length requested
      if (m_maxLength > maxPacketSize)
      {
        seqWarn("EQPacket: SessionRequest wanted a max packet size of %d which is above our sane max packet size of %d. Using our max",
          m_maxLength, maxPacketSize);

        m_maxLength = maxPacketSize;
      }

      emit maxLength((int) m_maxLength, (int) m_streamid);

#if defined(PACKET_PROCESS_DIAG) || defined(PACKET_SESSION_DIAG)
      seqDebug("EQPacket: SessionRequest found, resetting expected seq, stream %s (%d) (session tracking %s)",
	    EQStreamStr[m_streamid], m_streamid,
        (m_session_tracking_enabled == 2 ? "locked on" : 
          (m_session_tracking_enabled == 1 ? "enabled" : "disabled")));
#endif

#if defined(PACKET_SESSION_DIAG)
      seqDebug("EQPacket: SessionRequest %s:%u->%s:%u, sessionId %u maxLength %u, awaiting key for stream %s (%d)",
        ((EQUDPIPPacketFormat&) packet).getIPv4SourceA().ascii(),
        ((EQUDPIPPacketFormat&) packet).getSourcePort(),
        ((EQUDPIPPacketFormat&) packet).getIPv4DestA().ascii(),
        ((EQUDPIPPacketFormat&) packet).getDestPort(),
        m_sessionId, m_maxLength, EQStreamStr[m_streamid], m_streamid);
#endif

#if defined(PACKET_SESSION_DIAG) && (PACKET_SESSION_DIAG > 1)
      seqDebug("EQPacket: SessionRequest contents: unknown %u, sessionId %u, maxLength %u",
        eqntohuint32((uint8_t*)&(request->unknown0000)), 
        m_sessionId, m_maxLength);
#endif

#if defined(PACKET_SESSION_DIAG) && (PACKET_SESSION_DIAG > 2)
      seqDebug("EQPacket: Raw SessionRequest: %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x",
        packet.payload()[0], packet.payload()[1], packet.payload()[2], 
        packet.payload()[3], packet.payload()[4], packet.payload()[5], 
        packet.payload()[6], packet.payload()[7], packet.payload()[8], 
        packet.payload()[9], packet.payload()[10], packet.payload()[11]);
#endif

      m_arqSeqExp = 0;
      m_arqSeqFound = true;

      if (m_session_tracking_enabled)
      {
        // Save off client port for the stream so we can match against it
        // later. SessionRequest should always be an outer protocol packet
        // so we can cast it to EQUDPIPPacketFormat to get the ip headers.
        m_sessionClientPort = ((EQUDPIPPacketFormat&) packet).getSourcePort();
      }
    }
    break;
    case OP_SessionResponse:
    {
      // Session response from server

      // Sanity check the size. Don't assume any packet we see is an EQ
      // session response, since we're gonna cause a huge freakin' malloc
      // on the maxlength of the session which for some reason some people
      // won't enjoy!
      if (packet.payloadLength() != sizeof(SessionResponseStruct))
      {
          // Either SessionResponseStruct changed or this isn't a session
          // response.
#if defined(PACKET_PROCESS_DIAG) || defined(PACKET_SESSION_DIAG)
          seqDebug("EQPacket: Ignoring SessionResponse %s:%u->%s:%u with invalid size %d.",
            ((EQUDPIPPacketFormat&) packet).getIPv4SourceA().ascii(),
            ((EQUDPIPPacketFormat&) packet).getSourcePort(),
            ((EQUDPIPPacketFormat&) packet).getIPv4DestA().ascii(),
            ((EQUDPIPPacketFormat&) packet).getDestPort(),
            packet.payloadLength());
#endif
          break;
      }

      // Pull off session response information
      SessionResponseStruct* response = 
        (SessionResponseStruct*) packet.payload();

      m_maxLength = eqntohuint32((uint8_t*)&(response->maxLength));
      m_sessionKey = eqntohuint32((uint8_t*)&(response->key));
      m_sessionId = eqntohuint32((uint8_t*)&(response->sessionId));

      // Sanity check the max length requested
      if (m_maxLength > maxPacketSize)
      {
        seqWarn("EQPacket: SessionResponse wanted a max packet size of %d which is above our sane max packet size of %d. Using our max",
          m_maxLength, maxPacketSize);

        m_maxLength = maxPacketSize;
      }

      emit maxLength((int) m_maxLength, (int) m_streamid);

#if defined(PACKET_PROCESS_DIAG) || defined(PACKET_SESSION_DIAG)
      seqDebug("EQPacket: SessionResponse found %s:%u->%s:%u, resetting expected seq, stream %s (%d) (session tracking %s)",
        ((EQUDPIPPacketFormat&) packet).getIPv4SourceA().ascii(),
        ((EQUDPIPPacketFormat&) packet).getSourcePort(),
        ((EQUDPIPPacketFormat&) packet).getIPv4DestA().ascii(),
        ((EQUDPIPPacketFormat&) packet).getDestPort(),
	    EQStreamStr[m_streamid], m_streamid,
        (m_session_tracking_enabled == 2 ? "locked on" : 
          (m_session_tracking_enabled == 1 ? "enabled" : "disabled")));
#endif
      
#if defined(PACKET_SESSION_DIAG)
      seqDebug("EQPacket: SessionResponse sessionId %u maxLength %u, key is %u for stream %s (%d)",
        m_sessionId, m_maxLength, m_sessionKey, 
        EQStreamStr[m_streamid], m_streamid);
#endif

#if defined(PACKET_SESSION_DIAG) && (PACKET_SESSION_DIAG > 1)
      seqDebug("EQPacket: SessionResponse contents: sessionId %u, key %u, unknown %u, unknown %u, maxLength %u, unknown %u",
        m_sessionId, m_sessionKey, 
        eqntohuint16((uint8_t*)&(response->unknown0008)),
        response->unknown0010, m_maxLength,
        eqntohuint32((uint8_t*) &(response->unknown0015)));
#endif

#if defined(PACKET_SESSION_DIAG) && (PACKET_SESSION_DIAG > 2)
      seqDebug("EQPacket: Raw SessionResponse: %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x",
        packet.payload()[0], packet.payload()[1], packet.payload()[2], 
        packet.payload()[3], packet.payload()[4], packet.payload()[5], 
        packet.payload()[6], packet.payload()[7], packet.payload()[8], 
        packet.payload()[9], packet.payload()[10], packet.payload()[11],
        packet.payload()[12], packet.payload()[13], packet.payload()[14], 
        packet.payload()[15], packet.payload()[16], packet.payload()[17], 
        packet.payload()[18]);
#endif

      // Provide key to corresponding stream from this session/stream
      emit sessionKey(m_sessionId, m_streamid, m_sessionKey);

      m_arqSeqExp = 0;
      m_arqSeqFound = true;

      // Session tracking
      if (m_session_tracking_enabled)
      {
        // Save off client port for the stream so we can match against it
        // later. SessionRequest should always be an outer protocol packet
        // so we can cast it to EQUDPIPPacketFormat to get the ip headers.
        m_sessionClientPort = ((EQUDPIPPacketFormat&) packet).getDestPort();

        // If this is the world server talking to us, reset session tracking if
        // it is on so we unlatch the client in case of getting kicked.
        if (m_streamid == world2client)
        {
          m_session_tracking_enabled = 1;
          emit sessionTrackingChanged(m_session_tracking_enabled);
        }
        // If this is the zone server talking to us, close the latch and lock
        else if (m_streamid == zone2client)
        {
          // SessionResponse should always be an outer protocol packet, so
          // the EQProtocolPacket passed in can be cast back to
          // EQUDPIPPacketFormat, which we need to go to get access to the IP
          // headers!
          m_session_tracking_enabled = 2;
  
          emit lockOnClient(((EQUDPIPPacketFormat&) packet).getSourcePort(), 
            ((EQUDPIPPacketFormat&) packet).getDestPort());
          emit sessionTrackingChanged(m_session_tracking_enabled);
        }
      }
    }
    break;
    case OP_SessionDisconnect:
    {
#if defined(PACKET_PROCESS_DIAG) || defined(PACKET_SESSION_DIAG)
      seqDebug("EQPacket: SessionDisconnect found %s:%u->%s:%u, resetting expected seq, stream %s (%d) (session tracking %s)",
        ((EQUDPIPPacketFormat&) packet).getIPv4SourceA().ascii(),
        ((EQUDPIPPacketFormat&) packet).getSourcePort(),
        ((EQUDPIPPacketFormat&) packet).getIPv4DestA().ascii(),
        ((EQUDPIPPacketFormat&) packet).getDestPort(),
	    EQStreamStr[m_streamid], m_streamid,
        (m_session_tracking_enabled == 2 ? "locked on" : 
          (m_session_tracking_enabled == 1 ? "enabled" : "disabled")));
#endif

#if defined(PACKET_SESSION_DIAG) && (PACKET_SESSION_DIAG > 2)
      seqDebug("EQPacket: Raw SessionDisconnect: %02x%02x %02x%02x %02x%02x %02x%02x",
        packet.payload()[0], packet.payload()[1], packet.payload()[2], 
        packet.payload()[3], packet.payload()[4], packet.payload()[5], 
        packet.payload()[6], packet.payload()[7]);
#endif

      m_arqSeqExp = 0;

      // Clear cache
      resetCache();

      // Signal closing. Unlatch session tracking if it is on.
      if (m_session_tracking_enabled)
      {
        m_session_tracking_enabled = 1;
        emit sessionTrackingChanged(m_session_tracking_enabled);

        m_sessionClientPort = 0;
      }

      emit closing(m_sessionId, m_streamid);
    }
    break;
    case OP_Ack:
    case OP_AckFuture:
    case OP_AckAfterDisconnect:
    {
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
      seqDebug("EQPacket: no-op on ACK for net opcode %04x seq %04x, stream %s (%d)",
	    packet.getNetOpCode(), eqntohuint16(packet.payload()), 
        EQStreamStr[m_streamid], m_streamid);
#endif
    }
    break;
    case OP_KeepAlive:
    case OP_SessionStatRequest:
    case OP_SessionStatResponse:
    {
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
      seqDebug("EQPacket: no-op on stats for net opcode %04x, stream %s (%d)",
	    packet.getNetOpCode(), EQStreamStr[m_streamid], m_streamid);
#endif
    }
    break;
    default :
    {
      seqWarn("EQPacket: Unhandled net opcode %04x, stream %s, size %d",
        packet.getNetOpCode(), EQStreamStr[m_streamid], packet.payloadLength());
    }
  }
}
Пример #8
0
////////////////////////////////////////////////////
// Reads packets and processes waiting packets from playback file
void EQPacket::processPlaybackPackets (void)
{
#ifdef DEBUG_PACKET
//   debug ("processPackets()");
#endif /* DEBUG_PACKET */
  /* Make sure we are not called while already busy */
  if (m_busy_decoding)
    return;

  /* Set flag that we are busy decoding */
  m_busy_decoding = true;

  unsigned char  buffer[8192];
  int            size;

  /* in packet playback mode fetch packets from VPacket class */
  time_t now;
  int timein = mTime();
  int i = 0;
    
  long version = PACKETVERSION;
  
  // decode packets from the playback buffer
  do
  {
    size = m_vPacket->Playback((char *) buffer, sizeof(buffer), &now, &version);
    
    if (size)
    {
      i++;
	
      if (PACKETVERSION == version)
      {
	dispatchPacket ( size - sizeof (struct ether_header),
		       (unsigned char *) buffer + sizeof (struct ether_header)
		       );
      }
      else
      {
	seqWarn("Error:  The version of the packet stream has " \
		 "changed since '%s' was recorded - disabling playback",
		 m_vPacket->getFileName());

	// stop the timer, nothing more can be done...
	stop();

	break;
      }
    }
    else
      break;
  } while ( (mTime() - timein) < 100);

  // check if we've reached the end of the recording
  if (m_vPacket->endOfData())
  {
    seqInfo("End of playback file '%s' reached."
	    "Playback Finished!",
	    m_vPacket->getFileName());

    // stop the timer, nothing more can be done...
    stop();
  }

  /* Clear decoding flag */
  m_busy_decoding = false;
}
Пример #9
0
////////////////////////////////////////////////////
// decode, decrypt, and unroll packet
void EQPacketStream::decodePacket(uint8_t *data, size_t len, uint16_t opCode)
{
  emit rawPacket(data, len, m_dir, opCode);

  if (opCode & FLAG_CRYPTO || opCode & FLAG_COMP) 
  {
    data = decodeOpCode (data, &len, opCode);
    if (data == NULL)
      return;

    emit rawPacket(data, len, m_dir, opCode);
  }
  
  const EQPacketOPCode* opcodeEntry = 0;

  // this works, but could really use a cleanup - mvern
  while (len > 2) 
  {
    if (opCode & FLAG_COMBINED) 
    {
      bool repeatop = false;
      uint8_t *dptr = data;
      size_t left = len;
      int32_t count = 1;
      
      if (opCode & FLAG_IMPLICIT) 
      {
	opCode = opCode & ~FLAG_IMPLICIT;
	repeatop = true;
      }

#ifdef PACKET_DECODE_DIAG
      seqDebug("unrolling on %s: 0x%04x", EQStreamStr[m_streamid], opCode);
#endif
      opCode = opCode & ~FLAG_COMBINED;
      
      while (count > 0) 
      {
	uint16_t size = 0;

	opcodeEntry = m_opcodeDB.find(opCode);

	if (opcodeEntry)
	{
	  size = opcodeEntry->implicitLen();
#ifdef PACKET_DECODE_DIAG // ZBTEMP
	  seqDebug("opcode %04x implicitlen %d",
		  opCode, size);
#endif
	}
#ifdef PACKET_DECODE_DIAG
	else 
	  seqDebug("No opcodeEntry for %04x", opCode);
#endif 
	
	if (size == 0) 
	{ // Not an implicit length opcode
	  if (dptr[0] == 0xff) 
	  { // > 255 length
	    left--;
	    dptr++;
	    size = ntohs(*((uint16_t *)dptr));
	    left -= 2;
	    dptr += 2;
	  } 
	  else 
	  { // single octet length
	    size = dptr[0];
	    left--;
	    dptr++;
	  }
	}
#ifdef PACKET_DECODE_DIAG
	seqDebug ("size on %s: %d", EQStreamStr[m_streamid], size);
#endif
		
	if (size > left) 
	{
	  seqWarn("error on %s: size > left (size=%d, left=%d, opcode=0x%04x)", 
		     EQStreamStr[m_streamid], size, left, opCode);
	  return;
	}
	
#ifdef PACKET_DECODE_DIAG
	seqDebug("sending from %s: 0x%04x, %d", 
	       EQStreamStr[m_streamid], opCode, size);
#endif
	dispatchPacket(dptr, size, opCode, opcodeEntry);
	
	// next
	dptr += size;
	left -= size;
	
	count--;
	if (repeatop) 
	{
	  count = dptr[0];
	  dptr++;
	  left--;
	  repeatop = false;
#ifdef PACKET_DECODE_DIAG
	  seqDebug ("repeating %d times on %s",
		  count, EQStreamStr[m_streamid]);
#endif
	}
      }
	    
      if (left > 2) 
      {
	opCode = *((unsigned short *)dptr);
	dptr += 2;
	left -= 2;

#ifdef PACKET_DECODE_DIAG
	seqDebug("doing leftover from %s: 0x%04x, %d", 
	       EQStreamStr[m_streamid], opCode, left);
#endif
	if (opCode & FLAG_COMBINED)
	{
	  data = dptr;
	  len = left;
	  continue;
	} 
	else 
	{
#ifdef PACKET_DECODE_DIAG
	  seqDebug("sending from %s: 0x%04x, %d", 
		 EQStreamStr[m_streamid], opCode, size);
#endif
	  dispatchPacket(dptr, left, opCode, m_opcodeDB.find(opCode));
	}
      }

      return;
    }
    else
      break;
  }
  
#ifdef PACKET_DECODE_DIAG
  seqDebug ("sending from %s: 0x%04x, %d",
	  EQStreamStr[m_streamid], opCode, size);
#endif
  dispatchPacket(data, len, opCode, m_opcodeDB.find(opCode));
}
Пример #10
0
/////////////////////////////////////////////////////
// Handle a protocol level packet. This could be either a top-level
// EQUDPIPPacket or a subpacket that is just an EQProtocolPacket. Either way
// we use net opcodes here.
void EQPacketStream::processPacket(EQProtocolPacket& packet, bool isSubpacket)
{
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
  seqDebug("-->EQPacketStream::processPacket, subpacket=%s on stream %s (%d)",
    (isSubpacket ? "true" : "false"), EQStreamStr[m_streamid], m_streamid);
#endif

  if (IS_APP_OPCODE(packet.getNetOpCode()))
  {
    // This is an app-opcode directly on the wire with no wrapping protocol
    // information. Weird, but whatever gets the stream read, right?
	dispatchPacket(packet.payload(), packet.payloadLength(), 
        packet.getNetOpCode(), m_opcodeDB.find(packet.getNetOpCode()));
    return;
  }

  // Process the net opcode
  switch (packet.getNetOpCode())
  {
    case OP_Combined:
    {
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
      seqDebug("EQPacket: found combined packet (net op: %04x, size %d) on stream %s (%d). Unrolling.", 
        packet.getNetOpCode(), packet.payloadLength(),
        EQStreamStr[m_streamid], m_streamid);
#endif

      // Rolled up multiple packets inside this packet. Need to unroll them
      // and process them individually. subpacket starts after the net opcode.
      uint8_t* subpacket = packet.payload();

      while (subpacket < packet.payload() + packet.payloadLength())
      {
        // Length specified first on the wire.
        uint8_t subpacketLength = subpacket[0];

        // Move past the length
        subpacket++;

        // OpCode (in net order)
        uint16_t subOpCode = *(uint16_t*)subpacket;
        
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
        seqDebug("EQPacket: unrolling length %d bytes from combined packet on stream %s (%d). Opcode %04x", 
          subpacketLength, EQStreamStr[m_streamid], m_streamid, subOpCode);
#endif
        
        // Opcode is next. Net opcode or app opcode?
        if (IS_NET_OPCODE(subOpCode))
        {
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
          seqDebug("EQPacket: processing unrolled net opcode, length %d bytes from combined packet on stream %s (%d). Opcode %04x", 
            subpacketLength, EQStreamStr[m_streamid], m_streamid, subOpCode);
#endif

          // Net opcode. false = copy. true = subpacket
          EQProtocolPacket spacket(subpacket, subpacketLength, false, true);

          processPacket(spacket, true);
        }
        else
        {
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
        seqDebug("EQPacket: processing unrolled app opcode, length %d bytes from combined packet on stream %s (%d). Opcode %04x", 
          subpacketLength-2, EQStreamStr[m_streamid], m_streamid, subOpCode);
#endif

          // App opcode. Dispatch it, skipping opcode.
          dispatchPacket(&subpacket[2], subpacketLength-2, 
            subOpCode, m_opcodeDB.find(subOpCode));
        }
        subpacket += subpacketLength;
      }
    }
    break;
    case OP_AppCombined:
    {
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
      seqDebug("EQPacket: found appcombined packet (net op: %04x, size %d) on stream %s (%d). Unrolling.", 
        packet.getNetOpCode(), packet.payloadLength(),
        EQStreamStr[m_streamid], m_streamid);
#endif

      // Multiple app op codes in the same packet. Need to unroll and dispatch
      // them.
      uint8_t* subpacket = packet.payload();

      while (subpacket < packet.payload() + packet.payloadLength())
      {
        // Length specified first on the wire.
        uint8_t subpacketLength = subpacket[0];

        // Move past the length
        subpacket++;

        if (subpacketLength != 0xff)
        {
          // Dispatch app op code using given packet length. Net order!
          uint16_t subOpCode = *(uint16_t*)(subpacket);

#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
        seqDebug("EQPacket: unrolling length %d bytes from combined packet on stream %s (%d). Opcode %04x", 
          subpacketLength, EQStreamStr[m_streamid], m_streamid, subOpCode);
        seqDebug("EQPacket: processing unrolled app opcode, length %d bytes from combined packet on stream %s (%d). Opcode %04x", 
          subpacketLength-2, EQStreamStr[m_streamid], m_streamid, subOpCode);
#endif

          // Dispatch, skipping op code.
          dispatchPacket(&subpacket[2], subpacketLength-2, 
            subOpCode, m_opcodeDB.find(subOpCode));

          // Move ahead
          subpacket += subpacketLength;
        }
        else
        {
          // If original length is 0xff, it means it is a long one. The length
          // is 2 bytes and next.
          uint16_t longOne = eqntohuint16(subpacket);
 
          // Move past the 2 byte length
          subpacket += 2;

          // OpCode next. Net order for op codes.
          uint16_t subOpCode = *(uint16_t*)subpacket;
          
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
        seqDebug("EQPacket: unrolling length %d bytes from combined packet on stream %s (%d). Opcode %04x", 
          longOne, EQStreamStr[m_streamid], m_streamid, subOpCode);
        seqDebug("EQPacket: processing unrolled app opcode, length %d bytes from combined packet on stream %s (%d). Opcode %04x", 
          longOne-2, EQStreamStr[m_streamid], m_streamid, subOpCode);
#endif

          // Dispatch, skipping op code.
          dispatchPacket(&subpacket[2], longOne-2, 
            subOpCode, m_opcodeDB.find(subOpCode));

          // Move ahead
          subpacket += longOne;
        }
      }
    }
    break;
    case OP_Packet:
    {
      // Normal unfragmented sequenced packet.
      uint16_t seq = eqntohuint16(packet.payload());
      emit seqReceive(seq, (int)m_streamid);

      if (seq >= m_arqSeqExp)
      {
        // Future packet?
        if (seq == m_arqSeqExp)
        {
          // Expected packet.
          m_arqSeqExp++;
          emit seqExpect(m_arqSeqExp, (int)m_streamid);

          // OpCode next. Net order for op codes.
          uint16_t subOpCode = *(uint16_t*)(&packet.payload()[2]);
       
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)
          seqDebug("SEQ: Found next sequence number in data stream %s (%d), incrementing expected seq, %04x (op code %04x, sub opcode %04x)", 
	        EQStreamStr[m_streamid], m_streamid, seq, packet.getNetOpCode(),
            subOpCode);
#endif

          // App opcode or net opcode?
          if (IS_NET_OPCODE(subOpCode))
          {
            // Net opcode. false = no copy. true = subpacket.
            EQProtocolPacket spacket(&packet.payload()[2],
              packet.payloadLength()-2, false, true);

            processPacket(spacket, true);
          }
          else
          {
            // App opcode. Dispatch, skipping seq and opcode.
            dispatchPacket(&packet.payload()[4], packet.payloadLength()-4,
              subOpCode, m_opcodeDB.find(subOpCode));
          }
        }
        else if (seq < (uint32_t(m_arqSeqExp + arqSeqWrapCutoff)) ||
                 seq < (int32_t(m_arqSeqExp - arqSeqWrapCutoff)))
        {
          // Yeah, future packet. Push it on the packet cache.
#ifdef PACKET_PROCESS_DIAG
          seqDebug("SEQ: out of order sequence %04x stream %s (%d) expecting %04x, sending to cache, %04d",
	        seq, EQStreamStr[m_streamid], m_streamid, 
            m_arqSeqExp, m_cache.size());
#endif
          setCache(seq, packet);
        }
        else
        {
          // Past packet outside the cut off
          seqWarn("SEQ: received sequenced %spacket outside the bounds of reasonableness. Expecting seq=%04x got seq=%04x, reasonableness being %d in the future.", 
            (isSubpacket ? "sub" : ""), m_arqSeqExp, seq, arqSeqWrapCutoff);
        }
      }
      else
      {
        // Spooky packet from the past. Boo!
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)
        seqDebug("discarding %spacket netopcode=%04x seq=%d size=%d on stream %s (%d). Packet is in the past. We've moved on.",
          (isSubpacket ? "sub" : ""),
          packet.getNetOpCode(), seq, packet.payloadLength(),
          EQStreamStr[m_streamid], m_streamid);
#endif
      }
    }
    break;
    case OP_Oversized:
    {
      // Fragmented sequenced data packet.
      uint16_t seq = eqntohuint16(packet.payload());
      emit seqReceive(seq, (int)m_streamid);

      if (seq >= m_arqSeqExp)
      {
        // Future packet?
        if (seq > m_arqSeqExp)
        {
          // Yeah, future packet. Push it on the packet cache.
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)
          seqDebug("SEQ: out of order sequence %04x stream %s (%d) expecting %04x, sending to cache, %04d",
	        seq, EQStreamStr[m_streamid], m_streamid, 
            m_arqSeqExp, m_cache.size());
#endif
          setCache(seq, packet);
        }
        else
        {
          // Expected packet.
          m_arqSeqExp++;
          emit seqExpect(m_arqSeqExp, (int)m_streamid);
       
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)
          seqDebug("SEQ: Found next sequence number in data stream %s (%d), incrementing expected seq, %04x (op code %04x)", 
	        EQStreamStr[m_streamid], m_streamid, seq, packet.getNetOpCode());
#endif

          // Push the fragment on.
          m_fragment.addFragment(packet);

          if (m_fragment.isComplete())
          {
            // OpCode from fragment. In network order.
            uint16_t fragOpCode = *(uint16_t*)(m_fragment.data());

#ifdef PACKET_PROCESS_DIAG
          seqDebug("SEQ: Completed oversized app packet on stream %s with seq %04x, total size %d opcode %04x", 
	        EQStreamStr[m_streamid], seq, m_fragment.size()-2, fragOpCode);
#endif

            // dispatch fragment. Skip opcode.
            dispatchPacket(&m_fragment.data()[2], m_fragment.size()-2,
              fragOpCode, m_opcodeDB.find(fragOpCode)); 

            m_fragment.reset();
          }
        }
      }
      else
      {
        // Spooky packet from the past. Boo!
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)
        seqDebug("discarding packet netopcode=%04x seq=%d size=%d on stream %s (%d). Packet is in the past. We've moved on.",
          packet.getNetOpCode(), seq, packet.payloadLength(),
          EQStreamStr[m_streamid], m_streamid);
#endif
      }
    }
    break;
    case OP_SessionRequest:
    {
      // Session request from client to server.
#if defined(PACKET_PROCESS_DIAG) || defined(PACKET_SESSION_DIAG)
      seqDebug("EQPacket: SessionRequest found, resetting expected seq, stream %s (%d) (session tracking %s)",
	    EQStreamStr[m_streamid], m_streamid,
        (m_session_tracking_enabled == 2 ? "locked on" : 
          (m_session_tracking_enabled == 1 ? "enabled" : "disabled")));
#endif
      
      // Pull off session request information
      SessionRequestStruct* request = 
        (SessionRequestStruct*) packet.payload();

      m_sessionId = eqntohuint32((uint8_t*)&(request->sessionId));
      m_maxLength = eqntohuint32((uint8_t*)&(request->maxLength));

#if defined(PACKET_SESSION_DIAG)
      seqDebug("EQPacket: SessionRequest sessionId %u maxLength %u, awaiting key for stream %s (%d)",
        m_sessionId,
        m_maxLength,
        EQStreamStr[m_streamid],
        m_streamid);
#endif

#if defined(PACKET_SESSION_DIAG) && (PACKET_SESSION_DIAG > 1)
      seqDebug("EQPacket: SessionRequest contents: unknown %u, sessionId %u, maxLength %u",
        eqntohuint32((uint8_t*)&(request->unknown0000)),
        m_sessionId,
        m_maxLength);
#endif

      m_arqSeqExp = 0;
      m_arqSeqFound = true;
    }
    break;
    case OP_SessionResponse:
    {
      // Session response from server
#if defined(PACKET_PROCESS_DIAG) || defined(PACKET_SESSION_DIAG)
      seqDebug("EQPacket: SessionResponse found, resetting expected seq, stream %s (%d) (session tracking %s)",
	    EQStreamStr[m_streamid], m_streamid,
        (m_session_tracking_enabled == 2 ? "locked on" : 
          (m_session_tracking_enabled == 1 ? "enabled" : "disabled")));
#endif
      
      // Pull off session response information
      SessionResponseStruct* response = 
        (SessionResponseStruct*) packet.payload();

      m_maxLength = eqntohuint32((uint8_t*)&(response->maxLength));
      m_sessionKey = eqntohuint32((uint8_t*)&(response->key));
      m_sessionId = eqntohuint32((uint8_t*)&(response->sessionId));

#if defined(PACKET_SESSION_DIAG)
      seqDebug("EQPacket: SessionResponse sessionId %u maxLength %u, key is %u for stream %s (%d)",
        m_sessionId,
        m_maxLength,
        m_sessionKey,
        EQStreamStr[m_streamid],
        m_streamid);
#endif

#if defined(PACKET_SESSION_DIAG) && (PACKET_SESSION_DIAG > 1)
      seqDebug("EQPacket: SessionResponse contents: sessionId %u, key %u, unknown %u, unknown %u, maxLength %u, unknown %u",
        m_sessionId,
        m_sessionKey,
        eqntohuint16((uint8_t*)&(response->unknown0008)),
        response->unknown0010,
        m_maxLength,
        eqntohuint32((uint8_t*) &(response->unknown0015)));
#endif

      // Provide key to corresponding stream from this session/stream
      emit sessionKey(m_sessionId, m_streamid, m_sessionKey);

      m_arqSeqExp = 0;
      m_arqSeqFound = true;

      // Session tracking
      if (m_session_tracking_enabled)
      {
        // If this is the world server talking to us, reset session tracking if
        // it is on so we unlatch the client in case of getting kicked.
        if (m_streamid == world2client)
        {
          m_session_tracking_enabled = 1;
          emit sessionTrackingChanged(m_session_tracking_enabled);
        }
        // If this is the zone server talking to us, close the latch and lock
        else if (m_streamid == zone2client)
        {
          // SessionResponse should always be an outer protocol packet, so
          // the EQProtocolPacket passed in can be cast back to
          // EQUDPIPPacketFormat, which we need to go to get access to the IP
          // headers!
          m_session_tracking_enabled = 2;
  
          emit lockOnClient(((EQUDPIPPacketFormat&) packet).getSourcePort(), 
            ((EQUDPIPPacketFormat&) packet).getDestPort());
          emit sessionTrackingChanged(m_session_tracking_enabled);
        }
      }
    }
    break;
    case OP_SessionDisconnect:
    {
#if defined(PACKET_PROCESS_DIAG) || defined(PACKET_SESSION_DIAG)
      seqDebug("EQPacket: SessionDisconnect found, resetting expected seq, stream %s (%d) (session tracking %s)",
	    EQStreamStr[m_streamid], m_streamid,
        (m_session_tracking_enabled == 2 ? "locked on" : 
          (m_session_tracking_enabled == 1 ? "enabled" : "disabled")));
#endif

      m_arqSeqExp = 0;

      // Clear cache
      resetCache();

      // Signal closing. Unlatch session tracking if it is on.
      if (m_session_tracking_enabled)
      {
        m_session_tracking_enabled = 1;
        emit sessionTrackingChanged(m_session_tracking_enabled);
      }

      emit closing();
    }
    break;
    case OP_Ack:
    case OP_Resend:
    {
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
      seqDebug("EQPacket: no-op on for net opcode %04x seq %04x, stream %s (%d)",
	    packet.getNetOpCode(), eqntohuint16(packet.payload()),
        EQStreamStr[m_streamid], m_streamid);
#endif
    }
    break;
    case OP_KeepAlive:
    case OP_SessionStatRequest:
    case OP_SessionStatResponse:
    {
#if defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 2)
      seqDebug("EQPacket: no-op on for net opcode %04x, stream %s (%d)",
	    packet.getNetOpCode(), EQStreamStr[m_streamid], m_streamid);
#endif
    }
    break;
    default :
    {
      seqWarn("EQPacket: Unhandled net opcode %04x, stream %s, size %d",
        packet.getNetOpCode(), EQStreamStr[m_streamid], packet.payloadLength());
    }
  }
}
Пример #11
0
// Try to read data at serial port & pass anything read to processing function
void USBMidi::poll(void)
{   while(available()) {
        dispatchPacket(readPacket());
    }
}