/** Creates and posts a PacketBuffer::pcClosed message to the server message que. The message contains the socket handle, and the ip address in dotted decimal format. The socket you pass in is the socket that you are removing. The socket should still be valid (not yet deleted) when this method is called. \param s Pointer to the socket that is being removed. **/ void SimpleServer::queClosedMessage(ServerSocket* s) { PacketBuffer* pktRemove = new PacketBuffer(PacketBuffer::pcClosed); *pktRemove << (signed32) s->getSocket(); *pktRemove << s->getAddr().dottedDecimal(); pktRemove->rewind(); PacketMessage* pmsg = new PacketMessage(s,pktRemove); //socket is no longer valid m_que.add(pmsg); }
void PacketEncryptionResponse::read(PacketBuffer &buffer) { varint_t secretLength; buffer.getVarInt(secretLength); sharedSecret = ubytes_t(secretLength); buffer.getUBytes(sharedSecret); varint_t tokenLength; buffer.getVarInt(tokenLength); verifyToken = ubytes_t(tokenLength); buffer.getUBytes(verifyToken); }
/** * Sends a process closed debug event to BinNavi. * * @param dbg The debug event to be sent. * * @return A NaviError code that describes whether the operation was successful * or not. **/ NaviError BaseConnection::sendProcessClosedEvent(const DBGEVT *) const { const unsigned int NUMBER_OF_ARGUMENTS = 0; PacketBuffer buffer; buffer.add(createPacketHeader(resp_process_closed, 0, NUMBER_OF_ARGUMENTS)); NaviError sendResult = send(buffer.data(), buffer.size()); if (sendResult) { msglog->log(LOG_VERBOSE, "Error: Couldn't send debug event"); return sendResult; } return NaviErrors::SUCCESS; }
/** * Sends a simple reply to BinNavi. * * @param command The type of the reply. * * @return A NaviError code that describes whether the operation was successful * or not. **/ NaviError BaseConnection::sendSimpleReply(const commandtype_t command, unsigned int id) const { const unsigned int NUMBER_OF_ARGUMENTS = 0; PacketBuffer buffer; buffer.add(createPacketHeader(command, id, NUMBER_OF_ARGUMENTS)); NaviError sendResult = send(buffer.data(), buffer.size()); if (sendResult) { msglog->log(LOG_VERBOSE, "Error: Couldn't send simple reply message"); return sendResult; } return NaviErrors::SUCCESS; }
/** * Sends a reply to a register values request to BinNavi. * * @param id The message ID of the reply. * @param regString The register data string. * * @return A NaviError code that describes whether the operation was * successful or not. **/ NaviError BaseConnection::sendRegistersReply(commandtype_t type, unsigned int id, const std::string &str) const { const unsigned int NUMBER_OF_ARGUMENTS = 1; PacketBuffer buffer; buffer.add(createPacketHeader(type, id, NUMBER_OF_ARGUMENTS)); addStringArgument(buffer, str); NaviError sendResult = send(buffer.data(), buffer.size()); if (sendResult) { msglog->log(LOG_VERBOSE, "Error: Couldn't send registers reply message"); return sendResult; } return NaviErrors::SUCCESS; }
void DataWatcher::write(PacketBuffer &buffer) { for (byte_t index = 0; index < 23; ++index) { if (type[index] == NONE) continue; buffer.putByte(type[index] << 5 | (index & 0x1f)); switch (type[index]) { case BYTE: buffer.putByte(getByte(index)); break; case SHORT: buffer.putShort(getShort(index)); break; case INT: buffer.putInt(getInt(index)); break; case FLOAT: buffer.putFloat(getFloat(index)); break; case STRING: buffer.putString(getString(index)); break; case ITEMSTACK: buffer.putItemStack(getItemStack(index)); break; } } buffer.putByte(0x7f); }
/** * Sends a reply to a memory data request to BinNavi. * * @param id The message ID of the reply. * @param address The address from the original memory request. * @param memrange The memory data. * * @return A NaviError code that describes whether the operation was * successful or not. **/ NaviError BaseConnection::sendMemoryReply(unsigned int id, CPUADDRESS address, const MemoryContainer &memrange) const { const unsigned int NUMBER_OF_ARGUMENTS = 2; PacketBuffer buffer; buffer.add(createPacketHeader(resp_read_memory, id, NUMBER_OF_ARGUMENTS)); addAddressArgument(buffer, address); addStringArgument(buffer, memrange); NaviError sendResult = send(buffer.data(), buffer.size()); if (sendResult) { msglog->log(LOG_VERBOSE, "Error: Couldn't send memory reply message"); return sendResult; } return NaviErrors::SUCCESS; }
void Injector::inject(const PacketBuffer &pb ) const { if( handle_ == NULL ) { std::cerr << "ERROR: Problems injecting packet" << std::endl; std::cerr << "NO DEVICE SET" << std::endl; exit(2); } int err = pcap_sendpacket(handle_, pb.buffer(), pb.size()); if( err ) { //clean up std::cerr << "ERROR: Problems injecting packet " << std::endl; std::cerr << pcap_geterr( handle_ ) << std::endl; exit( 2 ); } }
/** * Sends a debug reply with a variable number of integer arguments and the * given command and packet ID to BinNavi. * * @param command The type of the reply. * @param id The message ID of the reply. * @param values The integer arguments to send to BinNavi. * @param nrvalues The number of integer arguments to send to BinNavi. * * @return A NaviError code that describes whether the operation was * successful or not. **/ NaviError BaseConnection::sendIntegersReply(const commandtype_t command, unsigned int id, unsigned int *values, unsigned int nrvalues) const { PacketBuffer buffer; buffer.add(createPacketHeader(command, id, nrvalues)); for (unsigned int i = 0; i < nrvalues; i++) { addIntegerArgument(buffer, values[i]); } NaviError sendResult = send(buffer.data(), buffer.size()); if (sendResult) { msglog->log(LOG_VERBOSE, "Error: Couldn't send integer reply message"); return sendResult; } return NaviErrors::SUCCESS; }
/** * Sends a debug reply with a variable number of address arguments and the * given command and packet ID to BinNavi. * * @param command The type of the reply. * @param id The message ID of the reply. * @param addresses The address arguments to send to BinNavi. * @param nraddresses The number of address arguments to send to BinNavi. * * @return A NaviError code that describes whether the operation was * successful or not. **/ NaviError BaseConnection::sendAddressesReply(const commandtype_t command, unsigned int id, const CPUADDRESS *addresses, unsigned int nraddresses) const { PacketBuffer buffer; buffer.add(createPacketHeader(command, id, nraddresses)); for (unsigned int i = 0; i < nraddresses; ++i) { addAddressArgument(buffer, addresses[i]); } msglog->log(LOG_ALL, "%d", nraddresses); NaviError sendResult = send(buffer.data(), buffer.size()); if (sendResult) { msglog->log(LOG_VERBOSE, "Error: Couldn't send address reply message"); return sendResult; } return NaviErrors::SUCCESS; }
/** * Sends a debug reply with two integer arguments and one address argument and * the given command and packet ID * to BinNavi. * * @param command The type of the reply. * @param id The message ID of the reply. * @param value1 The first integer value to send. * @param value2 The second integer value to send. * @param address The address value to send. * * @return A NaviError code that describes whether the operation was * successful or not. **/ NaviError BaseConnection::sendIntegerIntegerAddressReply( const commandtype_t command, unsigned int id, unsigned int value1, unsigned int value2, CPUADDRESS address) const { const unsigned int NUMBER_OF_ARGUMENTS = 3; PacketBuffer buffer; buffer.add(createPacketHeader(command, id, NUMBER_OF_ARGUMENTS)); addIntegerArgument(buffer, value1); addIntegerArgument(buffer, value2); addAddressArgument(buffer, address); NaviError sendResult = send(buffer.data(), buffer.size()); if (sendResult) { msglog->log(LOG_VERBOSE, "Error: Couldn't send integer integer address reply message"); return sendResult; } return NaviErrors::SUCCESS; }
/** Reads data and returns a pointer to a new PacketBuffer object. You are responsible for deleting the returned packet when you are finished with it. You are gerented to receive a full PacketBuffer object. When data is read in, some verification is done to ensure that the packet header is valid. There is no way to validate the buffer portion of the packet. A test is done on the header to see if the cookie (just a constant value passed all the time) and to see the the command looks like it might be valid. There is no way to tell other then if the command is zero (PacketBuffer::pcInvalid). Note that a common problem with getting PacketBuffer::pcInvalid as a command is not setting the command in a packet before sending it. If a packet is sent with a size greater then 3000 bytes, the read operation will reset the internal buffer, and throw an exception. This is done to prevent bogus packets overflowing the buffer. \throw SocketInstanceException If there is a read error, or a connection was closed. \throw BufferedSocketException If a bad packet was read. **/ PacketBuffer* BufferedSocket::recvPacket() { PacketBuffer* pPacket = readFullPacket(); if(pPacket->cookie()!=PacketBuffer::pkCookie || pPacket->getCmd()==PacketBuffer::pcInvalid) { #ifdef DEBUG logs::dump(pPacket,PacketBuffer::getHeaderSize()); logs::dump(pPacket->m_Buffer,pPacket->getBufferSize()); #endif resetBuffer(); CStr msg; msg.format("bad packet received %s", pPacket->getCmd() ? "(invalid command)":"(invalid cookie)"); throwBufferedSocketException(msg); } return pPacket; }
/** * Sends a debug reply that indicates what breakpoints were correctly set and * which ones were not. * * @param command The type of the reply. * @param id The message ID of the reply. * @param result Vector that contains the error codes for the individual * breakpoints. 0 = breakpoint was set. * * @return A NaviError code that describes whether the operation was * successful or not. **/ NaviError BaseConnection::sendBreakpointsReply( const commandtype_t command, unsigned int id, const std::vector<std::pair<CPUADDRESS, unsigned int>> &results) const { const unsigned int NUMBER_OF_ARGUMENTS = 1 + 2 * results.size(); PacketBuffer buffer; buffer.add(createPacketHeader(command, id, NUMBER_OF_ARGUMENTS)); addIntegerArgument(buffer, results.size()); for (const auto &breakpoint : results) { addAddressArgument(buffer, breakpoint.first); addIntegerArgument(buffer, breakpoint.second); } NaviError sendResult = send(buffer.data(), buffer.size()); if (sendResult) { msglog->log(LOG_VERBOSE, "Error: Couldn't send integer address reply message"); return sendResult; } return NaviErrors::SUCCESS; }
int NetClientThread( void *client ) { NetClient *net_client = (NetClient *) client; char data[ PACKET_BUFFER_SIZE ] = ""; PacketBuffer Buffer; while( net_client->Connected ) { // Check for packets. int size = 0; if( ( size = SDLNet_TCP_Recv( net_client->Socket, data, PACKET_BUFFER_SIZE ) ) > 0 ) { if( ! net_client->Connected ) break; net_client->BytesReceived += size; Buffer.AddData( data, size ); while( Packet *packet = Buffer.Pop() ) { SDL_mutexP( net_client->Lock ); net_client->InBuffer.push( packet ); SDL_mutexV( net_client->Lock ); } } else { // If 0 (disconnect) or -1 (error), stop listening. if( size < 0 ) net_client->DisconnectMessage = std::string("SDLNet_TCP_Recv: ") + std::string(SDLNet_GetError()); net_client->Disconnect(); break; } // Let the thread rest a bit. SDL_Delay( 1 ); } // Set the thread pointer to NULL when we disconnect. net_client->Thread = NULL; return 0; }
/** * Sends a reply to an event that suspended the process to BinNavi. * * @param command The type of the reply. * @param id The message ID of the reply. * @param info Object that provides information about the event. * * @return A NaviError code that describes whether the operation was successful * or not. **/ NaviError BaseConnection::sendSuspendedReply(const commandtype_t command, unsigned int id, const InformationProvider &info) const { if (info.getRegisterString().size() == 0) { return NaviErrors::SUCCESS; } const unsigned int NUMBER_OF_ARGUMENTS = 3; PacketBuffer buffer; buffer.add(createPacketHeader(command, id, NUMBER_OF_ARGUMENTS)); addIntegerArgument(buffer, info.getTid()); addAddressArgument(buffer, info.getAddress(0)); addStringArgument(buffer, info.getRegisterString()); NaviError sendResult = send(buffer.data(), buffer.size()); if (sendResult) { msglog->log(LOG_VERBOSE, "Error: Couldn't send suspended reply message"); return sendResult; } return NaviErrors::SUCCESS; }
// //We do two checks to see that we have enough data to make //a full packet. One check is to see that we have enough data //the make a header. The second is to see if there is enough //to make a packet with a header plus it's data. //We return NULL if there wasn't //enough data to make a full packet. If there is enough data //we return _one_ complete packet, and make sure the buffer //is ready to extract more packets, and recieve additional //data. // //A full packet is the size of the packet header (all packets //_must_ have full header, plus the size of any data. There //doesn't always have to be any data with the packet. // PacketBuffer* BufferedSocket::parsForPacket() { PacketBuffer* pPacket = NULL; char* phead = m_pbuffer; char* ptail = phead+m_nBytesInBuf; unsigned32 nSize; if(m_nBytesInBuf<PacketBuffer::getHeaderSize()) return NULL; nSize = ntohl(*(unsigned32*)phead)+PacketBuffer::getHeaderSize(); if((unsigned32)(ptail-phead) < nSize) return NULL; //copy in the header, then copy in packet data, less the header data pPacket = new PacketBuffer(0,nSize-PacketBuffer::getHeaderSize()); //new packet memcpy(pPacket->getHeader(),phead,PacketBuffer::getHeaderSize()); pPacket->makeHostReady(true); //convert header from network byte order if(nSize>PacketBuffer::getHeaderSize()) //if we have data after the header memcpy(pPacket->getBuffer(),phead+PacketBuffer::getHeaderSize(),pPacket->getBufferSize()); phead += nSize; m_nBytesInBuf -= nSize; if(phead>=ptail) { //there is no more data in the buffer m_ptr = m_pbuffer; m_nBytesInBuf = 0; } else { //we need to move the unparsed data to the beginning of the buffer memmove(m_pbuffer,phead,m_nBytesInBuf); m_ptr = m_pbuffer+m_nBytesInBuf; } return pPacket; }
void PacketJoinGame::write(PacketBuffer &buffer) { buffer.putInt(entityId); buffer.putUByte(gameMode); buffer.putByte(dimension); buffer.putUByte(difficulty); buffer.putUByte(maxPlayers); buffer.putString(levelType); buffer.putBool(reducedDebugInfo); }
void DataWatcher::read(PacketBuffer &buffer) { byte_t item, index; do { buffer.getByte(item); if (item == 0x7f) break; index = item & 0x1f; switch (item >> 5) { case BYTE: { byte_t b; buffer.getByte(b); setByte(index, b); break; } case SHORT: { short_t s; buffer.getShort(s); setShort(index, s); break; } case INT: { int_t i; buffer.getInt(i); setInt(index, i); break; } case FLOAT: { float_t f; buffer.getFloat(f); setFloat(index, f); break; } case STRING: { string_t str; buffer.getString(str); setString(index, str); break; } case ITEMSTACK: { std::shared_ptr<ItemStack> stack; buffer.getItemStack(stack); setItemStack(index, stack); break; } } } while (true); }
void PacketEntityHeadLook::write(PacketBuffer &buffer) { buffer.putVarInt(entityId); buffer.putByte(headYaw); }
void PacketLoginStart::read(PacketBuffer &buffer) { buffer.getString(name); }
void AVDemuxThread::run() { m_buffering = false; end = false; if (audio_thread && !audio_thread->isRunning()) audio_thread->start(QThread::HighPriority); if (video_thread && !video_thread->isRunning()) video_thread->start(); int stream = 0; Packet pkt; pause(false); qDebug("get av queue a/v thread = %p %p", audio_thread, video_thread); PacketBuffer *aqueue = audio_thread ? audio_thread->packetQueue() : 0; PacketBuffer *vqueue = video_thread ? video_thread->packetQueue() : 0; // aqueue as a primary buffer: music with/without cover AVThread* thread = !video_thread || (audio_thread && demuxer->hasAttacedPicture()) ? audio_thread : video_thread; m_buffer = thread->packetQueue(); const qint64 buf2 = aqueue ? aqueue->bufferValue() : 1; // TODO: may be changed by user. Deal with audio track change if (aqueue) { aqueue->clear(); aqueue->setBlocking(true); } if (vqueue) { vqueue->clear(); vqueue->setBlocking(true); } connect(thread, SIGNAL(seekFinished(qint64)), this, SIGNAL(seekFinished(qint64)), Qt::DirectConnection); seek_tasks.clear(); bool was_end = false; if (ademuxer) { ademuxer->seek(0LL); } while (!end) { processNextSeekTask(); //vthread maybe changed by AVPlayer.setPriority() from no dec case vqueue = video_thread ? video_thread->packetQueue() : 0; if (demuxer->atEnd()) { // if avthread may skip 1st eof packet because of a/v sync if (aqueue && (!was_end || aqueue->isEmpty())) { aqueue->put(Packet::createEOF()); aqueue->blockEmpty(false); // do not block if buffer is not enough. block again on seek } if (vqueue && (!was_end || vqueue->isEmpty())) { vqueue->put(Packet::createEOF()); vqueue->blockEmpty(false); } m_buffering = false; Q_EMIT mediaStatusChanged(QtAV::BufferedMedia); was_end = true; // wait for a/v thread finished msleep(100); continue; } was_end = false; if (tryPause()) { continue; //the queue is empty and will block } updateBufferState(); if (!demuxer->readFrame()) { continue; } stream = demuxer->stream(); pkt = demuxer->packet(); Packet apkt; bool audio_has_pic = demuxer->hasAttacedPicture(); int a_ext = 0; if (ademuxer) { QMutexLocker locker(&buffer_mutex); Q_UNUSED(locker); if (ademuxer) { a_ext = -1; audio_has_pic = ademuxer->hasAttacedPicture(); // FIXME: buffer full but buffering!!! // avoid read external track everytime. aqueue may not block full // vqueue will not block if aqueue is not enough if (!aqueue->isFull() || aqueue->isBuffering()) { if (ademuxer->readFrame()) { if (ademuxer->stream() == ademuxer->audioStream()) { a_ext = 1; apkt = ademuxer->packet(); } } // no continue otherwise. ademuxer finished earlier than demuxer } } } //qDebug("vqueue: %d, aqueue: %d/isbuffering %d isfull: %d, buffer: %d/%d", vqueue->size(), aqueue->size(), aqueue->isBuffering(), aqueue->isFull(), aqueue->buffered(), aqueue->bufferValue()); //QMutexLocker locker(&buffer_mutex); //TODO: seems we do not need to lock //Q_UNUSED(locker); /*1 is empty but another is enough, then do not block to ensure the empty one can put packets immediatly. But usually it will not happen, why? */ /* demux thread will be blocked only when 1 queue is full and still put * if vqueue is full and aqueue becomes empty, then demux thread * will be blocked. so we should wake up another queue when empty(or threshold?). * TODO: the video stream and audio stream may be group by group. provide it * stream data: aaaaaaavvvvvvvaaaaaaaavvvvvvvvvaaaaaa, it happens * stream data: aavavvavvavavavavavavavavvvaavavavava, it's ok */ //TODO: use cache queue, take from cache queue if not empty? const bool a_internal = stream == demuxer->audioStream(); if (a_internal || a_ext > 0) {//apkt.isValid()) { if (a_internal && !a_ext) // internal is always read even if external audio used apkt = demuxer->packet(); /* if vqueue if not blocked and full, and aqueue is empty, then put to * vqueue will block demuex thread */ if (aqueue) { if (!audio_thread || !audio_thread->isRunning()) { aqueue->clear(); continue; } // must ensure bufferValue set correctly before continue if (m_buffer != aqueue) aqueue->setBufferValue(m_buffer->isBuffering() ? std::numeric_limits<qint64>::max() : buf2); // always block full if no vqueue because empty callback may set false // attached picture is cover for song, 1 frame aqueue->blockFull(!video_thread || !video_thread->isRunning() || !vqueue || audio_has_pic); // external audio: a_ext < 0, stream = audio_idx=>put invalid packet if (a_ext >= 0) aqueue->put(apkt); //affect video_thread } } // always check video stream if use external audio if (stream == demuxer->videoStream()) { if (vqueue) { if (!video_thread || !video_thread->isRunning()) { vqueue->clear(); continue; } vqueue->blockFull(!audio_thread || !audio_thread->isRunning() || !aqueue || aqueue->isEnough()); vqueue->put(pkt); //affect audio_thread } } else if (demuxer->subtitleStreams().contains(stream)) { //subtitle Q_EMIT internalSubtitlePacketRead(demuxer->subtitleStreams().indexOf(stream), pkt); } else { continue; } } m_buffering = false; m_buffer = 0; while (audio_thread && audio_thread->isRunning()) { qDebug("waiting audio thread......."); aqueue->blockEmpty(false); //FIXME: why need this audio_thread->wait(500); } while (video_thread && video_thread->isRunning()) { qDebug("waiting video thread......."); vqueue->blockEmpty(false); video_thread->wait(500); } thread->disconnect(this, SIGNAL(seekFinished(qint64))); qDebug("Demux thread stops running...."); emit mediaStatusChanged(QtAV::EndOfMedia); }
void PacketSetSlot::write(PacketBuffer &buffer) { buffer.putByte(windowId); buffer.putShort(slot); buffer.putItemStack(stack); }
void PacketClientStatus::read(PacketBuffer &buffer) { buffer.getVarInt(actionId); }
int SocketHandler::SendPacket(PacketBuffer& packet) { return SendPacket(&packet[0], packet.wsize()); }
/** * Adds an integer argument header and an integer argument to a packet. * * @param buffer The packet to add to. * @param value The value to add to the packet. **/ void BaseConnection::addIntegerArgument(PacketBuffer &buffer, unsigned int value) const { buffer.add(createIntegerArgumentHeader()); buffer.add(htonl(value)); }
void PacketAnimation::write(PacketBuffer &buffer) { buffer.putVarInt(entityId); buffer.putUByte(animationId); }
//send the packet void BufferedSocket::operator << (PacketBuffer& packet) { packet.transmit(this); }
/** * Transmits the given string onto the broadcast radio. * * This is a synchronous call that will wait until the transmission of the packet * has completed before returning. * * @param data The packet contents to transmit. * * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the buffer is invalid, * or the number of bytes to transmit is greater than `MICROBIT_RADIO_MAX_PACKET_SIZE + MICROBIT_RADIO_HEADER_SIZE`. */ int MicroBitRadioDatagram::send(PacketBuffer data) { return send((uint8_t *)data.getBytes(), data.length()); }
/** * Adds an address argument header and an address argument to a packet. * * @param buffer The packet to add to. * @param address The address to add to the packet. **/ void BaseConnection::addAddressArgument(PacketBuffer &buffer, CPUADDRESS address) const { buffer.add(createAddressArgumentHeader()); buffer.add(createAddressArgument(address)); }