前言

前面主要对vsomeip中helloworld程序运行进行了分析,本篇文章主要针对helloworld运行时的服务注册过程进行深入分析。

hello_world_service::offer_service

首先还是从examples/hello_world/hello_world_service.hpp文件开始。
void on_state_cbk(vsomeip::state_type_e _state) { if(_state ==
vsomeip::state_type_e::ST_REGISTERED) { // we are registered at the runtime and
can offer our service // 对应提供服务 app_->offer_service(service_id,
service_instance_id); } }
这里会去调用application的offer_service函数。

application_impl::offer_service
void application_impl::offer_service(service_t _service, instance_t _instance,
major_version_t _major, minor_version_t _minor) { // 先找到对应的routing,然后再继续 if
(routing_) routing_->offer_service(client_, _service, _instance, _major,
_minor); }
这里会对应两个offer_service,如果自身进程注册了routing服务的话,这里应该调用的是impl,否则调用的就是proxy了。

routing_manager_proxy::offer_service

我们先来看看proxy的实现。
bool routing_manager_proxy::offer_service(client_t _client, service_t
_service, instance_t _instance, major_version_t _major, minor_version_t _minor)
{ if(!routing_manager_base::offer_service(_client, _service, _instance, _major,
_minor)) { VSOMEIP_WARNING << "routing_manager_proxy::offer_service," <<
"routing_manager_base::offer_service returned false"; } {
std::lock_guard<std::mutex> its_lock(state_mutex_); if (state_ ==
inner_state_type_e::ST_REGISTERED) { send_offer_service(_client, _service,
_instance, _major, _minor); } service_data_t offer = { _service, _instance,
_major, _minor }; pending_offers_.insert(offer); } return true; }
routing_manager_base里面会先去查询对应的服务信息,如果没有找到,那么创建一个,并将对应的服务信息存储在内存中。
//发送给routing_host执行offer_service void
routing_manager_proxy::send_offer_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major, minor_version_t _minor) {
(void)_client; byte_t its_command[VSOMEIP_OFFER_SERVICE_COMMAND_SIZE]; uint32_t
its_size = VSOMEIP_OFFER_SERVICE_COMMAND_SIZE - VSOMEIP_COMMAND_HEADER_SIZE;
its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_OFFER_SERVICE;
std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
sizeof(client_)); std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN],
&its_size, sizeof(its_size));
std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
sizeof(_service)); std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
&_instance, sizeof(_instance)); its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4] =
_major; std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5], &_minor,
sizeof(_minor)); { std::lock_guard<std::mutex> its_lock(sender_mutex_); if
(sender_) { sender_->send(its_command, sizeof(its_command)); } } }
本地处理完之后,调用send函数去创建local command,然后发送对应的请求给routing进程。

进入routing进程,stub::on_message,解析相关的参数
void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
endpoint *_receiver, const boost::asio::ip::address &_destination, client_t
_bound_client, credentials_t _credentials, const boost::asio::ip::address
&_remote_address, std::uint16_t _remote_port) { ... // offer_service操作 case
VSOMEIP_OFFER_SERVICE: if (_size != VSOMEIP_OFFER_SERVICE_COMMAND_SIZE) {
VSOMEIP_WARNING << "Received a OFFER_SERVICE command with wrong size ~> skip!";
break; } std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
sizeof(its_service)); std::memcpy(&its_instance,
&_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], sizeof(its_instance));
std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
sizeof(its_major)); std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS
+ 5], sizeof(its_minor)); //判断是否允许提供服务 if
(security::get()->is_offer_allowed(its_sender_uid, its_sender_gid, its_client,
its_service, its_instance)) { host_->offer_service(its_client, its_service,
its_instance, its_major, its_minor); } else { VSOMEIP_WARNING << "vSomeIP
Security: Client 0x" << std::hex << its_client << " :
routing_manager_stub::on_message: isn't allowed to offer " << "the following
service/instance " << its_service << "/" << its_instance << " ~> Skip offer!";
} break; ... }

之后进入到impl::offer_service
bool routing_manager_impl::offer_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major, minor_version_t _minor, bool
_must_queue) { ... // only queue commands if method was NOT called via
erase_offer_command() // 如果方法没有通过erase_offer_command()调用,则只队列命令 if
(_must_queue) { if (!insert_offer_command(_service, _instance,
VSOMEIP_OFFER_SERVICE, _client, _major, _minor)) { return false; } } // Check
if the application hosted by routing manager is allowed to offer //
offer_service requests of local proxies are checked in rms::on:message
//检查由路由管理器托管的应用程序是否允许提供本地代理的offer_service请求在rms::on:message中被检查
//这里主要是检查请求offer_service的服务端,是否可以再这个routing上提供服务 if (_client == get_client()) {
#ifdef _WIN32 std::uint32_t its_routing_uid = ANY_UID; std::uint32_t
its_routing_gid = ANY_GID; #else std::uint32_t its_routing_uid = getuid();
std::uint32_t its_routing_gid = getgid(); #endif //安全检查是否允许提供服务 if
(!security::get()->is_offer_allowed(its_routing_uid, its_routing_gid, _client,
_service, _instance)) { ... erase_offer_command(_service, _instance); return
false; } } //调用对应的服务处理函数 if (!handle_local_offer_service(_client, _service,
_instance, _major, _minor)) { erase_offer_command(_service, _instance); return
false; } { std::lock_guard<std::mutex> its_lock(pending_sd_offers_mutex_); if
(if_state_running_) { //初始化对应的服务信息,创建对应service的endpoint
init_service_info(_service, _instance, true); } else {
pending_sd_offers_.push_back(std::make_pair(_service, _instance)); } } if
(discovery_) { std::shared_ptr<serviceinfo> its_info = find_service(_service,
_instance); if (its_info) { //如果打开了服务发现,这里应该是广播对应的服务?
discovery_->offer_service(its_info); } } { std::lock_guard<std::mutex>
ist_lock(pending_subscription_mutex_); std::set<event_t>
its_already_subscribed_events; for (auto &ps : pending_subscriptions_) { if
(ps.service_ == _service && ps.instance_ == _instance && ps.major_ == _major) {
insert_subscription(ps.service_, ps.instance_, ps.eventgroup_, ps.event_,
client_, &its_already_subscribed_events); } }
send_pending_subscriptions(_service, _instance, _major); }
stub_->on_offer_service(_client, _service, _instance, _major, _minor);
on_availability(_service, _instance, true, _major, _minor);
erase_offer_command(_service, _instance); return true; }

handle_local_offer_service主要是routing进程首先先查询本地服务注册信息,其次会去查询远程的服务信息。
//查询local service表,如果没找到对应的服务信息,那么去查找远程的服务信息,如果都没有, //新建一个local service信息 bool
routing_manager_impl::handle_local_offer_service(client_t _client, service_t
_service, instance_t _instance, major_version_t _major,minor_version_t _minor)
{ { std::lock_guard<std::mutex> its_lock(local_services_mutex_); //去local
service表里面找对应的服务 auto found_service = local_services_.find(_service); if
(found_service != local_services_.end()) { ... // check if the same service
instance is already offered remotely //检查如果已经没有被远程服务提供,那么会创建一个service info, //
并加入local_service表里 if (routing_manager_base::offer_service(_client, _service,
_instance, _major, _minor)) { local_services_[_service][_instance] =
std::make_tuple(_major, _minor, _client); } else { ... return false; } } return
true; }

//发消息给请求者已经完成了offer service的操作 void
routing_manager_stub::on_offer_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major, minor_version_t _minor) { if
(_client == host_->get_client()) { create_local_receiver(); }
std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
routing_info_[_client].second[_service][_instance] = std::make_pair(_major,
_minor); if (security::get()->is_enabled()) { distribute_credentials(_client,
_service, _instance); } inform_requesters(_client, _service, _instance, _major,
_minor, routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, true); }

技术
今日推荐
PPT
阅读数 131
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:766591547
关注微信