前面主要对vsomeip中helloworld程序运行进行了分析,本篇文章主要针对helloworld运行时的服务注册过程进行深入分析。
首先还是从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函数。
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了。
我们先来看看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 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 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 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 its_info = find_service(_service, _instance);
if (its_info) {
//如果打开了服务发现,这里应该是广播对应的服务?
discovery_->offer_service(its_info);
}
}
{
std::lock_guard ist_lock(pending_subscription_mutex_);
std::set 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 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 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);
}