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); } }
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(); } } }
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); }
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); } } }
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 ; }
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); } }