void ApnsChannel::eventReadData (size_t len) { ApnsResponsePacket rpk; //PWSHOWMETHOD(); do { switch(m_recv_state) { case RecvState::START: { rpk.clear(); m_recv_state = RecvState::HEADER; }// Fall to RecvState::HEADER /* no break */ case RecvState::HEADER: { //PWTRACE("RecvState::HEADER: %p", this); if ( m_rbuf->getReadableSize() < 6/* rpk.getPacketSize() */ ) { //PWTRACE("not yet: min:%jd", intmax_t(MsgPacket::limit_type::MIN_HEADER_SIZE) ); // 아직 헤더 크기를 받지 못함. return; } IoBuffer::blob_type b; m_rbuf->grabRead(b); rpk.m_cmd = static_cast<ApnsPacket::Command>(b.buf[0]); rpk.m_status = static_cast<ApnsResponsePacket::Status>(b.buf[1]); memcpy(&(rpk.m_noti_id), &(b.buf[2]), sizeof(rpk.m_noti_id)); m_rbuf->moveRead(6); }// Fall to RecvState::BODY /* no break */ case RecvState::BODY: /* no break */ case RecvState::DONE: { //PWTRACE("RecvState::DONE: %p", this); hookReadPacket(rpk, reinterpret_cast<const char*>(&rpk.m_noti_id), sizeof(rpk.m_noti_id)); m_recv_state = RecvState::START; break; }// case RecvState::DONE case RecvState::ERROR: { //PROC_ERROR: //PWTRACE("RecvState::ERROR: %p", this); eventError(Error::INVALID_PACKET, 0); m_recv_state = RecvState::START; if ( isInstDeleteOrExpired() ) return; } /* no break */ default: { PWLOGLIB("Invalid state: %d", static_cast<int>(m_recv_state)); m_recv_state = RecvState::START; break; } }// switch(m_recv_state) } while ( true ); }
ushort TGroup::execute() { do { endState = 0; do { TEvent e; getEvent(e); handleEvent(e); if (e.what != evNothing) eventError(e); } while (endState == 0); } while (!valid(endState)); return endState; }
int IcqProtocol::parsePacket(const Packet &p) { int ret = 0; // Login? debug() << "Packet "; switch (p.hdr().channel()) { case 1: //if (SPacket::isType<PktSConnAck>(p)) //{ debug() << "> ConnAck" << endl; if (_istate==AUTHORIZER) { // New connection Negotiation // Request cookie debug() << "Requesting cookie" << endl; m_net->sendData(PktCCookieRequest(_seq++, m_conf.child("user")["username"], m_conf.child("user")["password"])); } else if (_istate == BOS) { m_net->sendData(PktCSignon(_seq++, _cookie)); } //} //else //{ // packetError(&p, "Unknown packet on channel 1\n"); //} break; case 2: // FNAC data ret = parseFnac(p); break; case 3: // FLAP level errors break; case 4: // Close Connection Negotiation if (_istate == AUTHORIZER) { PktSCookieReply r(p); if (r.ok()) { debug() << "> CookieReply" << endl; _cookie = r.cookie(); // DEBUG_PRINT(8, "connecting to %s:%d", r.addr().c_str(), r.port()); m_net->disconnect(); m_net->connectTo(r.addr(), r.port()); m_state = S_connecting; _istate=BOS; break; } else { debug() << "> Error" << endl; TLV t; string uin, strerror; uint16 interror=0; Packet tmp = p; while(tmp.getTLV(t)) { if (t.type() == TLV::TLV_UIN) uin = t.value(); else if (t.type() == TLV::TLV_ERRORCODE) interror = charToU16(t.value()); else if (t.type() == TLV::TLV_ERRORMSG) strerror = t.value(); } switch (interror) { case 0x0005: // Wrong password m_state = S_offline; m_net->disconnect(); eventError(interror, "Bad password"); eventLoggedOut(); break; case 0x0018: //Reconnecting too fast or something... m_state = S_offline; m_net->disconnect(); eventError(interror, "Reconnecting too fast: " + strerror); eventLoggedOut(); //icq_loggedOut("0x0018: Reconnecting too fast: " + string(msg.value())); break; default: cerr << "Error in cookie reply" << endl; cerr << "Uin: " << uin << endl; cerr << "Error: 0x" << interror << endl; cerr << "Msg: " << strerror << endl; packetError(&p, ""); m_state = S_offline; m_net->disconnect(); eventError(interror, "Authorizer error:" + strerror); eventLoggedOut(); break; } ret = -1; break; } } m_state = S_offline; m_net->disconnect(); eventLoggedOut(); break; default: debug() << "> Unknown" << endl; packetError(&p, "Unknown channel ID: %d\n", p.hdr().channel()); break; } return ret; }
void MsgChannel::eventReadData(size_t len) { //PWSHOWMETHOD(); do { switch(m_recv_state) { case RecvState::START: { //PWTRACE("RecvState::START: %p", this); m_recv.clear(); m_recv_bodylen = 0; m_dest_bodylen = 0; m_recv_state = RecvState::HEADER; }// Fall to RecvState::HEADER /* no break */ case RecvState::HEADER: { //PWTRACE("RecvState::HEADER: %p", this); if ( m_rbuf->getReadableSize() < size_t(MsgPacket::limit_type::MIN_HEADER_SIZE) ) { //PWTRACE("not yet: min:%jd", intmax_t(MsgPacket::limit_type::MIN_HEADER_SIZE) ); // 아직 헤더 크기를 받지 못함. return; } IoBuffer::blob_type b; m_rbuf->grabRead(b); const char* eol(PWStr::findLine(b.buf, b.size)); if ( nullptr == eol ) { if ( b.size > size_t(MsgPacket::limit_type::MAX_HEADER_SIZE) ) { PWLOGLIB("too long header: input:%jd", intmax_t(b.size)); m_recv_state = RecvState::ERROR; goto PROC_ERROR; } return; } const size_t cplen(eol - b.buf); if ( not m_recv.setHeader(b.buf, cplen) ) { // invalid packet std::string out; PWEnc::encodeHex(out, b.buf, cplen); PWLOGLIB("invalid packet: ch:%p chtype:%s header:%s", this, typeid(*this).name(), out.c_str()); m_rbuf->moveRead(cplen+2); m_recv_state = RecvState::ERROR; goto PROC_ERROR; } m_rbuf->moveRead(cplen+2); if ( (m_dest_bodylen = m_recv.getBodySize()) > 0 ) { m_recv_state = RecvState::BODY; } else { //m_recv_state = RecvState::DONE; //PWTRACE("RecvState::DONE: %p", this); //eventReadPacket(m_recv, m_recv.m_body.buf, m_recv.m_body.size); hookReadPacket(m_recv, m_recv.m_body.buf, m_recv.m_body.size); m_recv_state = RecvState::START; break; } }// Fall to RecvState::BODY /* no break */ case RecvState::BODY: { //PWTRACE("RecvState::BODY: %p", this); blob_type& body(m_recv.m_body); if ( body.buf == nullptr ) { if ( not body.allocate(m_dest_bodylen) ) { PWLOGLIB("not enough memory"); m_recv_state = RecvState::ERROR; break; } }// if (body.buf) IoBuffer::blob_type b; m_rbuf->grabRead(b); const size_t cplen(std::min(b.size, (m_dest_bodylen - m_recv_bodylen)) ); if ( cplen > 0 ) { char* p(const_cast<char*>(body.buf) + m_recv_bodylen); ::memcpy(p, b.buf, cplen); m_recv_bodylen += cplen; m_rbuf->moveRead(cplen); } // 아직 더 받아야할 패킷이 있으면 반환한다. if ( m_recv_bodylen not_eq m_dest_bodylen ) { return; } m_recv_state = RecvState::DONE; } /* no break */ case RecvState::DONE: { //PWTRACE("RecvState::DONE: %p", this); hookReadPacket(m_recv, m_recv.m_body.buf, m_recv.m_body.size); m_recv_state = RecvState::START; break; }// case RecvState::DONE case RecvState::ERROR: { PROC_ERROR: //PWTRACE("RecvState::ERROR: %p", this); eventError(Error::INVALID_PACKET, 0); m_recv_state = RecvState::START; if ( isInstDeleteOrExpired() ) return; } /* no break */ default: { PWLOGLIB("Invalid state: %d", static_cast<int>(m_recv_state)); m_recv_state = RecvState::START; break; } }// switch(m_recv_state) } while ( true ); }