前言

前面主要对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 _WIN32std::uint32_t its_routing_uid = ANY_UID;std::uint32_t its_routing_gid = ANY_GID;
#elsestd::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的endpointinit_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);
}

SOME/IP开源库Vsomeip分析4-服务注册过程相关推荐

  1. SOME/IP开源库Vsomeip E2E保护实现分析

    1. 背景 E2E保护是autosar标准中定义的,主要是为了保护通信安全(功能安全相关).因此在原有的通信协议上增加了对应E2E的保护头部分.相关E2E会修改整体的通信协议的payload部分,因此 ...

  2. DICOM:DICOM开源库多线程分析之“ThreadPoolQueue in fo-dicom”

    背景: 上篇博文介绍了dcm4chee中使用的Leader/Follower线程池模型,主要目的是节省上下文切换,提高运行效率.本博文同属[DICOM开源库多线程分析]系列,着重介绍fo-dicom中 ...

  3. 【转】DICOM:DICOM三大开源库对比分析之“数据加载”

    背景: 上一篇博文DICOM:DICOM万能编辑工具之Sante DICOM Editor介绍了DICOM万能编辑工具,在日常使用过程中发现,"只要Sante DICOM Editor打不开 ...

  4. SDWebImage开源库阅读分析(全)

    汇总记录: 本文基于SDWebImage 4.2.3版本进行分析和整理(链接地址). 整体目录结构: SDWebImage |----SDWebImageCompat 处理不同平台(iOS.TV.OS ...

  5. SEAL全同态加密开源库(七) rns剩余数系统-源码解析

    SEAL全同态加密开源库(七) rns剩余数系统-源码解析 2021SC@SDUSC 2021-11-14 前言 这是SEAL开源库代码分析报告第六篇,本篇将分析util文件夹中的rns.h和rns. ...

  6. SEAL全同态加密开源库(八) rns源码解析(2)

    SEAL全同态加密开源库(七) rns剩余数系统-源码解析 2021SC@SDUSC 2021-11-21 前言 这是SEAL开源库代码分析报告第七篇,本篇将继续分析util文件夹中的rns.h和rn ...

  7. 【深度学习】EfficientNetV2分析总结和flops的开源库

    [深度学习]EfficientNetV2分析总结和flops的开源库 1 EfficientNetV1中存在的问题 2 EfficientNetV2中做出的贡献 3 NAS 搜索 4 Efficien ...

  8. DICOM医学图像处理:开源库mDCM与DCMTK的比较分析(一),JPEG无损压缩DCM图像(续)...

    2019独角兽企业重金招聘Python工程师标准>>> 背景: 上周通过单步调试,找出了开源库mDCM与DCMTK在对DICOM图像进行JPEG无损压缩时的细小区别,并顺利实现了在C ...

  9. 【转】DICOM医学图像处理:开源库mDCM与DCMTK的比較分析(一),JPEG无损压缩DCM图像

    转自:https://www.cnblogs.com/mfrbuaa/p/4004114.html 有修订 背景介绍: 近期项目需求,需要使用C#进行最新的UI和相关DICOM3.0医学图像模块的开发 ...

最新文章

  1. python使用openweathermap API获取全世界主要城市天气信息
  2. 计算机二级msoffice操作题如何评分,2017年计算机二级MSOffice操作题及答案解析
  3. 开发日记-20190629 关键词 读书笔记《Linux 系统管理技术手册(第二版)》DAY 6
  4. mysql网络安装教程_详细教程--MySQL的安装与配置
  5. content属性的4种用途
  6. 微信上线“拍一拍”功能,结果被网友激情吐槽...
  7. 解锁秋天\秋季借势的海波设计密码!
  8. 1.5.7 Python匿名函数
  9. python的基础_毫无基础的人如何入门 Python ?
  10. Hyperledger Fabric教程--Peer命令
  11. 参加IBM武汉分公司10周年庆
  12. 单件模式(Singleton Pattern
  13. C++规范编码引涉语法点之(8)trivial和non-trivial构造/析构/复制/赋值函数 及POD类型
  14. Report Categories修改LDB选择屏幕
  15. 《大厂面试》面试官看了直呼想要的简历
  16. 趣店创新园举办开工奠基仪式 罗敏:总部迁至厦门 带来上千人才
  17. rs.next()为false导致resultset遍历不出数据
  18. 根据判断PC浏览器类型和手机屏幕像素自动调用不同CSS
  19. Boring Old Menu Bar for Mac(菜单栏美化工具)
  20. MVC AJAXPro

热门文章

  1. Python枚举类Enum用法详解
  2. 建筑结构中常见的CAD技巧
  3. find命令 查找指定后缀文件
  4. 消费者追捧iPhone,在于它的性价比超越国产手机
  5. 平板电脑性价比排行,新发布的荣耀平板V6强不强?
  6. 自制开源的安卓浏览器
  7. Win10永久删除的文件怎么恢复?实用指南!
  8. CSS/SCSS 做一个心跳的动画:keyframe
  9. yum命令与yum仓库
  10. OCR学习神器,除了作业帮你还要有福昕扫描王