/** * Process a message that may be meant for the proximity system */ virtual void processMessage(const RoutableMessageHeader& mesg, MemoryReference message_body) { internalProcessOpaqueProximityMessage(mesg.has_source_object()?&mesg.source_object():NULL, mesg, message_body.data(), message_body.size(),true); }
void TimeSyncClient::handleSyncMessage(const OHDP::Endpoint &src, const OHDP::Endpoint &dst, MemoryReference payload) { SILOG(timesync, detailed, "Received time sync reply"); Sirikata::Protocol::TimeSync sync_msg; bool parse_success = sync_msg.ParseFromArray(payload.data(), payload.size()); if (!parse_success) { LOG_INVALID_MESSAGE_BUFFER(sync, error, ((char*)payload.data()), payload.size()); return; } Time local_start_t = mRequestTimes[sync_msg.seqno()]; Time server_t = sync_msg.t(); Time local_finish_t = mContext->simTime(); // Sanity check the round trip time to avoid using outdated packets static Duration sMaxRTT = Duration::seconds(5); // this could definitely be lower Duration rtt = local_finish_t - local_start_t; if (local_finish_t < local_start_t || rtt > sMaxRTT) { SILOG(timesync, detailed, "Ignoring time sync reply: out of date or non-sensical results"); return; } // FIXME use averaging, falloff, etc instead of just replacing the value outright mOffset = server_t - (local_start_t + (rtt/2.f)); SILOG(timesync, detailed, "RTT " << rtt << " updates offset to " << mOffset); mHasBeenInitialized = true; if (mCB) mCB(); }
void Space::processMessage(const ObjectReference*ref,MemoryReference message){ RoutableMessageHeader hdr; MemoryReference message_body=hdr.ParseFromArray(message.data(),message.size()); if (!hdr.has_source_object()&&ref) { hdr.set_source_object(*ref); } this->processMessage(hdr,message_body); }
void EnvironmentSimulation::handleMessage(MemoryReference data) { ENV_LOG(insane, "Received message: " << String((char*)data.begin(), data.size())); // Currently just receiving whole thing every time std::stringstream env_json(std::string((char*)data.begin(), data.size())); read_json(env_json, mEnvironment); notifyListener(); }
void SQLiteObjectStorage::processMessage(const RoutableMessageHeader&hdr,MemoryReference ref) { if (mTransactional) { Protocol::Minitransaction *trans=createMinitransaction(0,0,0); if (trans->ParseFromArray(ref.data(),ref.size())) { transactMessage(hdr,trans); } }else { Protocol::ReadWriteSet *rws=createReadWriteSet(0,0); if (rws->ParseFromArray(ref.data(),ref.size())) { applyMessage(hdr,rws); } } }
void TimeSyncServer::handleMessage(const OHDP::Endpoint& src, const OHDP::Endpoint& dst, MemoryReference payload) { SILOG(timesync, detailed, "Received time sync message from remote node " << src.node()); Sirikata::Protocol::TimeSync sync_msg; bool parse_success = sync_msg.ParseFromArray(payload.data(), payload.size()); if (!parse_success) { LOG_INVALID_MESSAGE_BUFFER(sync, error, ((char*)payload.data()), payload.size()); return; } // Our only job is to take the existing message, fill in a timestamp, and // send it back. sync_msg.set_t(mContext->simTime()); String resp = serializePBJMessage(sync_msg); mPort->send(src, MemoryReference(resp)); SILOG(timesync, detailed, "Sent time sync message reply to remote node " << src.node()); }
void Environment::handleMessage(const ObjectReference& id, MemoryReference data) { ENV_LOG(insane, "Received message from " << id << ": " << String((char*)data.begin(), data.size())); // Currently just receiving whole thing every time json::Value new_env; bool parsed = json::read( std::string((char*)data.begin(), data.size()), new_env); if (!parsed) { ENV_LOG(error, "Couldn't parse new environment: " << String((char*)data.begin(), data.size())); return; } mEnvironment = new_env; // And notifying everyone asap for(SubscriberMap::iterator it = mSubscribers.begin(); it != mSubscribers.end(); it++) { sendUpdate(it->first); } }
bool fromBase64(std::vector<unsigned char>&retval, const MemoryReference&a) { const uint8*begin=(const uint8*)a.data(); const uint8*end=(const uint8*)begin+a.size(); int outBuffPosn=retval.size(); retval.resize(retval.size()+(((end-begin)*3)/4+3));//maximum of the size; int remainderShift=0; signed char b4[4]; uint8 b4Posn=0; for (;begin!=end;++begin) { uint8 cur=(*begin); if (cur&0x80) { return false; } uint8 sbiCrop = (uint8)(cur & 0x7f); // Only the low seven bits signed char sbiDecode = URLSAFEDECODABET[ sbiCrop ]; // Special value // White space, Equals sign, or legit Base64 character // Note the values such as -5 and -9 in the // DECODABETs at the top of the file. if( sbiDecode >= WHITE_SPACE_ENC && cur==sbiCrop ) { if( sbiDecode >= EQUALS_SIGN_ENC ) { b4[ b4Posn++ ] = sbiDecode; // Save non-whitespace if( b4Posn > 3 ) { // Time to decode? outBuffPosn += decode4to3( b4, retval, outBuffPosn ); b4Posn = 0; // If that was the equals sign, break out of 'for' loop if( sbiDecode == EQUALS_SIGN_ENC ) { break; } // end if: equals sign } // end if: quartet built } // end if: equals sign or better } // end if: white space, equals sign or better } assert(outBuffPosn<=(int)retval.size()); retval.resize(outBuffPosn); return true; }
void processMessage(const RoutableMessageHeader &hdr, MemoryReference body) { Persistence::Protocol::Response resp; resp.ParseFromArray(body.data(), body.length()); if (hdr.has_return_status() || resp.has_return_status()) { SILOG(cppoh,info,"Failed to connect to database: "<<hdr.has_return_status()<<", "<<resp.has_return_status()); mSuccess = true; return; } Protocol::UUIDListProperty uuidList; if (resp.reads(0).has_return_status()) { SILOG(cppoh,info,"Failed to find ObjectList in database."); mSuccess = true; return; } uuidList.ParseFromString(resp.reads(0).data()); for (int i = 0; i < uuidList.value_size(); i++) { SILOG(cppoh,info,"Loading object "<<ObjectReference(uuidList.value(i))); HostedObjectPtr obj = HostedObject::construct<HostedObject>(mObjectHost, uuidList.value(i)); obj->initializeRestoreFromDatabase(mSpace, HostedObjectPtr()); } mSuccess = true; }
void TCPStream::send(MemoryReference firstChunk, MemoryReference secondChunk, StreamReliability reliability) { MultiplexedSocket::RawRequest toBeSent; // only allow 3 of the four possibilities because unreliable ordered is tricky and usually useless switch(reliability) { case Unreliable: toBeSent.unordered=true; toBeSent.unreliable=true; break; case ReliableOrdered: toBeSent.unordered=false; toBeSent.unreliable=false; break; case ReliableUnordered: toBeSent.unordered=true; toBeSent.unreliable=false; break; } toBeSent.originStream=getID(); uint8 serializedStreamId[StreamID::MAX_SERIALIZED_LENGTH]; unsigned int streamIdLength=StreamID::MAX_SERIALIZED_LENGTH; unsigned int successLengthNeeded=toBeSent.originStream.serialize(serializedStreamId,streamIdLength); ///this function should never return something larger than the MAX_SERIALIZED_LEGNTH assert(successLengthNeeded<=streamIdLength); streamIdLength=successLengthNeeded; size_t totalSize=firstChunk.size()+secondChunk.size(); totalSize+=streamIdLength; vuint32 packetLength=vuint32(totalSize); uint8 packetLengthSerialized[vuint32::MAX_SERIALIZED_LENGTH]; unsigned int packetHeaderLength=packetLength.serialize(packetLengthSerialized,vuint32::MAX_SERIALIZED_LENGTH); //allocate a packet long enough to take both the length of the packet and the stream id as well as the packet data. totalSize = size of streamID + size of data and //packetHeaderLength = the length of the length component of the packet toBeSent.data=new Chunk(totalSize+packetHeaderLength); uint8 *outputBuffer=&(*toBeSent.data)[0]; std::memcpy(outputBuffer,packetLengthSerialized,packetHeaderLength); std::memcpy(outputBuffer+packetHeaderLength,serializedStreamId,streamIdLength); if (firstChunk.size()) { std::memcpy(&outputBuffer[packetHeaderLength+streamIdLength], firstChunk.data(), firstChunk.size()); } if (secondChunk.size()) { std::memcpy(&outputBuffer[packetHeaderLength+streamIdLength+firstChunk.size()], secondChunk.data(), secondChunk.size()); } bool didsend=false; //indicate to other would-be TCPStream::close()ers that we are sending and they will have to wait until we give up control to actually ack the close and shut down the stream unsigned int sendStatus=++(*mSendStatus); if ((sendStatus&(3*SendStatusClosing))==0) {///max of 3 entities can close the stream at once (FIXME: should implement |= on atomic ints), but as of now at most the recv thread the sender responsible and a user close() is all that is allowed at once...so 3 is fine) MultiplexedSocket::sendBytes(mSocket,toBeSent); didsend=true; } //relinquish control to a potential closer --(*mSendStatus); if (!didsend) { //if the data was not sent, its our job to clean it up delete toBeSent.data; SILOG(tcpsst,debug,"printing to closed stream id "<<getID().read()); } }
bool ObjectHost::send(SpaceObjectReference& sporef_src, const SpaceID& space, const ObjectMessagePort src_port, const UUID& dest, const ObjectMessagePort dest_port, MemoryReference payload) { Sirikata::SerializationCheck::Scoped sc(&mSessionSerialization); std::string payload_str( (char*)payload.begin(), (char*)payload.end() ); return send(sporef_src, space, src_port, dest, dest_port, payload_str); }
void MonoVWObjectScript::processMessage(const RoutableMessageHeader&receivedHeader , MemoryReference body){ std::string header; receivedHeader.SerializeToString(&header); MonoContext::getSingleton().push(MonoContextData()); MonoContext::getSingleton().setVWObject(mParent,mDomain); try { Mono::Object retval=mObject.send("processMessage",mDomain.ByteArray(header.data(),(unsigned int)header.size()),mDomain.ByteArray((const char*)body.data(),(unsigned int)body.size())); }catch (Mono::Exception&e) { SILOG(mono,debug,"Message Exception "<<e); } MonoContext::getSingleton().pop(); }
bool MonoVWObjectScript::processRPC(const RoutableMessageHeader &receivedHeader, const std::string &name, MemoryReference args, MemoryBuffer &returnValue){ MonoContext::getSingleton().push(MonoContextData()); MonoContext::getSingleton().setVWObject(mParent,mDomain); std::string header; receivedHeader.SerializeToString(&header); try { Mono::Object retval=mObject.send("processRPC",mDomain.ByteArray(header.data(),(unsigned int)header.size()),mDomain.String(name),mDomain.ByteArray((const char*)args.data(),(int)args.size())); if (!retval.null()) { returnValue=retval.unboxByteArray(); MonoContext::getSingleton().pop(); return true; } MonoContext::getSingleton().pop(); return false; }catch (Mono::Exception&e) { SILOG(mono,debug,"RPC Exception "<<e); MonoContext::getSingleton().pop(); return false; } MonoContext::getSingleton().pop(); return true; }