Пример #1
0
void CommandService::on_message(Requestor* requestor, const PACKET& packet, void* body, const int64_t body_len) {
    Super::on_message(requestor, packet, body, body_len);
    // make command
    Command* command;
    GENERATE_ID(m_command_id);

    if(packet.option & OPT_BODY_IS_OBJECT_POINTER) {
        ASSERT(static_cast<size_t>(body_len) >= sizeof(Object*));
        Object* obj =*reinterpret_cast< Object** >(body);
        command =SafeNew<Command>(m_command_id, packet, static_cast< Bytes* >(0), requestor, this);
        command->setRequest(obj);
    }
    else {
        Bytes* bs =SafeNew< Bytes >();
        bs->set(body, body_len);
        command =SafeNew<Command>(m_command_id, packet, bs, requestor, this);
    }

    // dispatch
    if(packet.option & OPT_REQUEST) {
        _append_request(command);
        _process_request(packet.who);
    }
    else if(packet.option & OPT_RESPOND) {
        _process_respond(command);
    }
}
Пример #2
0
void CommandService::_process_timeout(const int64_t now) {
    /* clear timeout command */
    if(m_queue_tb->size()>0) {
        Int64Array* ls =0;
        HashIterator* it =static_cast< HashIterator* >(m_queue_tb->iterator());
        while(it->next()) {
            const int64_t who =static_cast< Int64* >(it->getKey())->getValue();
            Array* queue =static_cast< Array* >(it->getValue());
            while(Command* cmd =dynamic_cast< Command* >(queue->front())) {
                if(cmd->isTimeout(now)) {
                    if(cmd->isProcessing()) {
                        WARN("service %s(%lld) who %lld command %lld cancel", name(), (long long)m_id, (long long)cmd->getWho(), (long long)cmd->getCommand());
                    }
                    queue->pop_front();
                }
                else {
                    break;
                }
            }
            if(Command* cmd =dynamic_cast< Command* >(queue->front())) {
                if(cmd->isProcessing()) {
                    continue;
                }
                ASSERT(cmd->isInit());
                if(!ls) {
                    ls =SafeNew<Int64Array>();
                }
                ls->push_back(who);
            }
        }
        const int64_t n= ls ? ls->size() : 0;
        for(int64_t i=0; i<n; ++i) {
            _process_request(ls->get(i));
        }
    }
    /* clear timeout rpc */
    if(m_rpc_tb->size()>0) {
        Array* ls =0;
        HashIterator* it =static_cast< HashIterator* >(m_rpc_tb->iterator());
        while(it->next()) {
            RpcInfo* ri =static_cast< RpcInfo* >(it->getValue());
            if(now >= ri->getExpireTime()) {
                if(!ls) {
                    ls =SafeNew<Array>();
                }
                ls->push_back(ri);
                it->remove();
            }
        }
        const int64_t n =ls ? ls->size() : 0;
        for(int64_t i=0; i<n; ++i) {
            RpcInfo* ri =static_cast< RpcInfo* >(ls->get(i));
            WARN("service %s(%lld) rpc %lld cancel", name(), (long long)m_id, (long long)ri->getId());
            ri->timeout();
        }
    }
}
Пример #3
0
void
MavlinkFTP::handle_message(Mavlink* mavlink, mavlink_message_t *msg)
{
	// get a free request
	struct Request* req = _get_request();

	// if we couldn't get a request slot, just drop it
	if (req == nullptr) {
		warnx("Dropping FTP request: queue full\n");
		return;
	}

	if (msg->msgid == MAVLINK_MSG_ID_FILE_TRANSFER_PROTOCOL) {
		mavlink_msg_file_transfer_protocol_decode(msg, &req->message);
		
#ifdef MAVLINK_FTP_UNIT_TEST
		if (!_utRcvMsgFunc) {
			warnx("Incorrectly written unit test\n");
			return;
		}
		// We use fake ids when unit testing
		req->serverSystemId = MavlinkFtpTest::serverSystemId;
		req->serverComponentId = MavlinkFtpTest::serverComponentId;
		req->serverChannel = MavlinkFtpTest::serverChannel;
#else
		// Not unit testing, use the real thing
		req->serverSystemId = mavlink->get_system_id();
		req->serverComponentId = mavlink->get_component_id();
		req->serverChannel = mavlink->get_channel();
#endif
		
		// This is the system id we want to target when sending
		req->targetSystemId = msg->sysid;
			
		if (req->message.target_system == req->serverSystemId) {
			req->mavlink = mavlink;
#ifdef MAVLINK_FTP_UNIT_TEST
			// We are running in Unit Test mode. Don't queue, just call _worket directly.
			_process_request(req);
#else
			// We are running in normal mode. Queue the request to the worker
			work_queue(LPWORK, &req->work, &MavlinkFTP::_worker_trampoline, req, 0);
#endif
            return;
		}
	}

	_return_request(req);
}
Пример #4
0
void
MavlinkFTP::handle_message(const mavlink_message_t *msg)
{
	//warnx("MavlinkFTP::handle_message %d %d", buf_size_1, buf_size_2);

	if (msg->msgid == MAVLINK_MSG_ID_FILE_TRANSFER_PROTOCOL) {
		mavlink_file_transfer_protocol_t ftp_request;
		mavlink_msg_file_transfer_protocol_decode(msg, &ftp_request);

#ifdef MAVLINK_FTP_DEBUG
		warnx("FTP: received ftp protocol message target_system: %d", ftp_request.target_system);
#endif

		if (ftp_request.target_system == _getServerSystemId()) {
			_process_request(&ftp_request, msg->sysid);
		}
	}
}
Пример #5
0
int main( int argc,char * argv[] )
{
	crypt_buffer_ctx ctx ;

	crypt_buffer_result r ;
	ssize_t n ;

	char * encryption_key ;
	size_t encryption_key_length ;

	int network_port             = PORT_NUMBER ;
	const char * network_address = NETWORK_ADDRESS ;
	socket_t c ;

	char * e ;

	#define buffer_size sizeof( zuluKey_t ) * 2
	char buffer[ buffer_size ] ;

	socket_t s ;

	struct sigaction sa ;

	if( argc < 2 ){

		puts( "error: invalid number of arguments" ) ;
		return 1 ;
	}else if( argc >= 4 ){

		network_address = *( argv + 2 ) ;
		network_port    = atoi( *( argv + 3 ) ) ;
	}

	memset( &sa,'\0',sizeof( struct sigaction ) ) ;
	sa.sa_handler = _closeServer ;
	sigaction( SIGTERM,&sa,NULL ) ;

	e = *( argv + 1 ) ;

	encryption_key_length = strlen( e ) ;

	encryption_key = malloc( sizeof( char ) * encryption_key_length ) ;
	memcpy( encryption_key,e,encryption_key_length ) ;

	memset( e,'\0',encryption_key_length ) ;

	s = SocketNet( network_address,network_port ) ;

	_clean_on_exit.s             = s ;
	_clean_on_exit.buffer        = encryption_key ;
	_clean_on_exit.buffer_length = encryption_key_length ;

	_debug( "server started" ) ;

	if( !SocketBind( s ) ){

		return _exitServer( "socket bind failed" ) ;
	}

	if( !SocketListen( s ) ){

		return _exitServer( "socket listen failed" ) ;
	}

	if( crypt_buffer_init( &ctx,encryption_key,encryption_key_length ) ){

		_clean_on_exit.ctx = ctx ;

		while( 1 ){

			c = SocketAccept( s ) ;

			n = SocketGetData_3( c,buffer,buffer_size,4 ) ;

			if( n != -1 ){

				if( crypt_buffer_decrypt( ctx,buffer,n,&r ) ){

					_process_request( c,ctx,&r ) ;
				}else{
					_debug( "failed to decrypt data" ) ;
				}
			}else{
				_debug( "network timed out" ) ;
			}

			SocketClose( &c ) ;
		}

	}else{
		_debug( "failed to initialize encryption routine" ) ;
	}

	return 0 ;
}
Пример #6
0
void CommandService::_process_respond(Command* rpc_res) {
    const int64_t who =static_cast<int64_t>(rpc_res->getWho());
    const int64_t rpc_id =static_cast<int64_t>(rpc_res->getSn());
    bool done =true;
    do {
        RpcInfo* rpc =_get_rpc(rpc_id);
        if(rpc == 0) {
            WARN("service %s(%lld) who %lld rpc %lld respond, not exist", name(), (long long)m_id, (long long)who, (long long)rpc_id);
            break;
        }
        if(Command* cmd=rpc->getCommand()) {
            // check & prepare command
            Array* queue =static_cast< Array* >(m_queue_tb->get(who));
            if(queue == 0) {
                WARN("service %s(%lld) who %lld rpc %lld respond, command not exist", name(), (long long)m_id, (long long)who, (long long)rpc_id);
                break;
            }
            Command* front =static_cast< Command* >(queue->front());
            if(!front) {
                WARN("service %s(%lld) who %lld rpc %lld respond, command not exist", name(), (long long)m_id, (long long)who, (long long)rpc_id);
                break;
            }
            if(front != cmd) {
                WARN("service %s(%lld) who %lld rpc %lld respond, command mismatch", name(), (long long)m_id, (long long)who, (long long)rpc_id);
                break;
            }

            // call rpc
            m_processing_command =front;
            const int64_t result =rpc->invoke(rpc_res);
            m_processing_command =0;

            // done
            if(rpc->isDone() == false) {
                done =false;
            }

            // process result
            const int64_t cmd_id =front->getCommand();
            if(result == Command::STATE_COMPLETE) {
                front->setState(Command::STATE_COMPLETE);
                queue->pop_front();
                INFO("service %s(%lld) who %lld rpc %lld respond, command %lld complete", name(), (long long)m_id, (long long)who, (long long)rpc_id, (long long)cmd_id);
            }
            else if(result > 0) {
                front->setState(Command::STATE_PROCESSING);
                INFO("service %s(%lld) who %lld rpc %lld respond, command %lld processing", name(), (long long)m_id, (long long)who, (long long)rpc_id, (long long)cmd_id);
            }
            else {
                front->setState(Command::STATE_ERROR);
                queue->pop_front();
                ERROR("service %s(%lld) who %lld rpc %lld respond, command %lld error %lld", name(), (long long)m_id, (long long)who, (long long)rpc_id, (long long)cmd_id, (long long)result);
            }

            // post process
            if(cmd_id==LOGOUT_REQUEST && queue->empty()) {
                m_queue_tb->remove(who);
            }
            else if(queue->size()) {
                _process_request(who);
            }
        }
        else {
            const int64_t result =rpc->invoke(rpc_res);
            if(result == Command::STATE_COMPLETE) {
                INFO("service %s(%lld) who %lld rpc %lld respond, complete", name(), (long long)m_id, (long long)who, (long long)rpc_id);
            }
            else if(result > 0) {
                INFO("service %s(%lld) who %lld rpc %lld respond, processing", name(), (long long)m_id, (long long)who, (long long)rpc_id);
            }
            else {
                ERROR("service %s(%lld) who %lld rpc %lld respond, error %lld", name(), (long long)m_id, (long long)who, (long long)rpc_id, (long long)result);
            }
        }
    } while(0);
    // remove rpc info
    if(done) {
        m_rpc_tb->remove(rpc_id);
    }
}