SOME/IP开源库Vsomeip分析4-服务注册过程
前言
前面主要对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-服务注册过程相关推荐
- SOME/IP开源库Vsomeip E2E保护实现分析
1. 背景 E2E保护是autosar标准中定义的,主要是为了保护通信安全(功能安全相关).因此在原有的通信协议上增加了对应E2E的保护头部分.相关E2E会修改整体的通信协议的payload部分,因此 ...
- DICOM:DICOM开源库多线程分析之“ThreadPoolQueue in fo-dicom”
背景: 上篇博文介绍了dcm4chee中使用的Leader/Follower线程池模型,主要目的是节省上下文切换,提高运行效率.本博文同属[DICOM开源库多线程分析]系列,着重介绍fo-dicom中 ...
- 【转】DICOM:DICOM三大开源库对比分析之“数据加载”
背景: 上一篇博文DICOM:DICOM万能编辑工具之Sante DICOM Editor介绍了DICOM万能编辑工具,在日常使用过程中发现,"只要Sante DICOM Editor打不开 ...
- SDWebImage开源库阅读分析(全)
汇总记录: 本文基于SDWebImage 4.2.3版本进行分析和整理(链接地址). 整体目录结构: SDWebImage |----SDWebImageCompat 处理不同平台(iOS.TV.OS ...
- SEAL全同态加密开源库(七) rns剩余数系统-源码解析
SEAL全同态加密开源库(七) rns剩余数系统-源码解析 2021SC@SDUSC 2021-11-14 前言 这是SEAL开源库代码分析报告第六篇,本篇将分析util文件夹中的rns.h和rns. ...
- SEAL全同态加密开源库(八) rns源码解析(2)
SEAL全同态加密开源库(七) rns剩余数系统-源码解析 2021SC@SDUSC 2021-11-21 前言 这是SEAL开源库代码分析报告第七篇,本篇将继续分析util文件夹中的rns.h和rn ...
- 【深度学习】EfficientNetV2分析总结和flops的开源库
[深度学习]EfficientNetV2分析总结和flops的开源库 1 EfficientNetV1中存在的问题 2 EfficientNetV2中做出的贡献 3 NAS 搜索 4 Efficien ...
- DICOM医学图像处理:开源库mDCM与DCMTK的比较分析(一),JPEG无损压缩DCM图像(续)...
2019独角兽企业重金招聘Python工程师标准>>> 背景: 上周通过单步调试,找出了开源库mDCM与DCMTK在对DICOM图像进行JPEG无损压缩时的细小区别,并顺利实现了在C ...
- 【转】DICOM医学图像处理:开源库mDCM与DCMTK的比較分析(一),JPEG无损压缩DCM图像
转自:https://www.cnblogs.com/mfrbuaa/p/4004114.html 有修订 背景介绍: 近期项目需求,需要使用C#进行最新的UI和相关DICOM3.0医学图像模块的开发 ...
最新文章
- python使用openweathermap API获取全世界主要城市天气信息
- 计算机二级msoffice操作题如何评分,2017年计算机二级MSOffice操作题及答案解析
- 开发日记-20190629 关键词 读书笔记《Linux 系统管理技术手册(第二版)》DAY 6
- mysql网络安装教程_详细教程--MySQL的安装与配置
- content属性的4种用途
- 微信上线“拍一拍”功能,结果被网友激情吐槽...
- 解锁秋天\秋季借势的海波设计密码!
- 1.5.7 Python匿名函数
- python的基础_毫无基础的人如何入门 Python ?
- Hyperledger Fabric教程--Peer命令
- 参加IBM武汉分公司10周年庆
- 单件模式(Singleton Pattern
- C++规范编码引涉语法点之(8)trivial和non-trivial构造/析构/复制/赋值函数 及POD类型
- Report Categories修改LDB选择屏幕
- 《大厂面试》面试官看了直呼想要的简历
- 趣店创新园举办开工奠基仪式 罗敏:总部迁至厦门 带来上千人才
- rs.next()为false导致resultset遍历不出数据
- 根据判断PC浏览器类型和手机屏幕像素自动调用不同CSS
- Boring Old Menu Bar for Mac(菜单栏美化工具)
- MVC AJAXPro