前一章我们主要分析了hello_world_service的运行过程进行了简单的分析,这一章我们会对client进行更深层次的分析。
这里初始化其实和之前service端类似,也是注册了几个回调函数,其中比service端多注册了一个回调函数就是on_availability_cbk这个函数,这个函数在上一章也提到了,service端在offer server操作成功后,会通知client端,最终就调用到了这个函数。
// Get the vSomeIP runtime and
// create a application via the runtime, we could pass the application name
// here otherwise the name supplied via the VSOMEIP_APPLICATION_NAME
// environment variable is used
hello_world_client() :
rtm_(vsomeip::runtime::get()),
app_(rtm_->create_application())
{
}
bool init(){
// init the application
if (!app_->init()) {
LOG_ERR ("Couldn't initialize application");
return false;
}
// register a state handler to get called back after registration at the
// runtime was successful
app_->register_state_handler(
std::bind(&hello_world_client::on_state_cbk, this,
std::placeholders::_1));
// register a callback for responses from the service
app_->register_message_handler(vsomeip::ANY_SERVICE,
service_instance_id, vsomeip::ANY_METHOD,
std::bind(&hello_world_client::on_message_cbk, this,
std::placeholders::_1));
// register a callback which is called as soon as the service is available
app_->register_availability_handler(service_id, service_instance_id,
std::bind(&hello_world_client::on_availability_cbk, this,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3));
return true;
}
当服务连接成功后调用。这个函数中主要先判断了当前连接的是否时helloworld服务,然后创建对应的request message,发送对应的请求。
//当服务连接成功时,调用该回调函数
void on_availability_cbk(vsomeip::service_t _service,
vsomeip::instance_t _instance, bool _is_available)
{
//检查当前连接的服务是否时helloworld服务
// Check if the available service is the the hello world service
if(service_id == _service && service_instance_id == _instance
&& _is_available)
{
// The service is available then we send the request
// Create a new request
//创建一个request的message,默认的requst message还需要自己设置对应的service信息
std::shared_ptr rq = rtm_->create_request();
// Set the hello world service as target of the request
//设置request中的相关参数,someip包头的部分
rq->set_service(service_id);
rq->set_instance(service_instance_id);
rq->set_method(service_method_id);
// Create a payload which will be sent to the service
//创建对应的payload
std::shared_ptr pl = rtm_->create_payload();
std::string str("World");
std::vector pl_data(std::begin(str), std::end(str));
pl->set_data(pl_data);
rq->set_payload(pl);
// Send the request to the service. Response will be delivered to the
// registered message handler
LOG_INF("Sending: %s", str.c_str());
//发送request
app_->send(rq);
}
}
runtime层默认处理了request message中需要的一些信息。
std::shared_ptr runtime_impl::create_request(bool _reliable) const {
std::shared_ptr its_request =
std::make_shared();
its_request->set_protocol_version(VSOMEIP_PROTOCOL_VERSION);
its_request->set_message_type(message_type_e::MT_REQUEST);
its_request->set_return_code(return_code_e::E_OK);
its_request->set_reliable(_reliable);
its_request->set_interface_version(DEFAULT_MAJOR);
return (its_request);
}
void application_impl::send(std::shared_ptr _message) {
bool is_request = utility::is_request(_message);
//如果logging功能开启了,这里先记录client的行为
if (client_side_logging_
&& (client_side_logging_filter_.empty()
|| (1 == client_side_logging_filter_.count(std::make_tuple(_message->get_service(), ANY_INSTANCE)))
|| (1 == client_side_logging_filter_.count(std::make_tuple(_message->get_service(), _message->get_instance()))))) {
...
}
//如果routing存在,请求routing
if (routing_) {
// in case of requests set the request-id (client-id|session-id)
if (is_request) {
//如果时request message,在message里面设置对应的client和session信息
_message->set_client(client_);
_message->set_session(get_session());
}
// Always increment the session-id
//发送给routing proxy
(void)routing_->send(client_, _message);
}
}
由于helloworld client没有注册对应的routing,因此这里去调用routing proxy处理
//序列化相关消息,然后交给其他函数继续发送
bool routing_manager_base::send(client_t _client,
std::shared_ptr _message) {
bool is_sent(false);
if (utility::is_request(_message->get_message_type())) {
_message->set_client(_client);
}
std::shared_ptr its_serializer(get_serializer());
if (its_serializer->serialize(_message.get())) {
is_sent = send(_client, its_serializer->get_data(),
its_serializer->get_size(), _message->get_instance(),
_message->is_reliable(), get_client(), std::make_pair(ANY_UID, ANY_GID), 0, false);
its_serializer->reset();
put_serializer(its_serializer);
} else {
VSOMEIP_ERROR << "Failed to serialize message. Check message size!";
}
return (is_sent);
}
然后调用proxy的send函数
bool routing_manager_proxy::send(client_t _client, const byte_t *_data,
length_t _size, instance_t _instance,
bool _reliable,
client_t _bound_client,
credentials_t _credentials,
uint8_t _status_check,
bool _sent_from_remote) {
...
//如果当前状态不是registered,那么直接返回false
{
std::lock_guard its_lock(state_mutex_);
if (state_ != inner_state_type_e::ST_REGISTERED) {
return false;
}
}
//打开了logging功能的话,记录相关信息
if (client_side_logging_) {
if (_size > VSOMEIP_MESSAGE_TYPE_POS) {
service_t its_service = VSOMEIP_BYTES_TO_WORD(
_data[VSOMEIP_SERVICE_POS_MIN],
_data[VSOMEIP_SERVICE_POS_MAX]);
if (client_side_logging_filter_.empty()
|| (1 == client_side_logging_filter_.count(std::make_tuple(its_service, ANY_INSTANCE)))
|| (1 == client_side_logging_filter_.count(std::make_tuple(its_service, _instance)))) {
method_t its_method = VSOMEIP_BYTES_TO_WORD(
_data[VSOMEIP_METHOD_POS_MIN],
_data[VSOMEIP_METHOD_POS_MAX]);
session_t its_session = VSOMEIP_BYTES_TO_WORD(
_data[VSOMEIP_SESSION_POS_MIN],
_data[VSOMEIP_SESSION_POS_MAX]);
client_t its_client = VSOMEIP_BYTES_TO_WORD(
_data[VSOMEIP_CLIENT_POS_MIN],
_data[VSOMEIP_CLIENT_POS_MAX]);
...
}
} else {
...
}
}
//检查message 长度是否合法
if (_size > VSOMEIP_MESSAGE_TYPE_POS) {
std::shared_ptr its_target;
if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
// Request
//从message中读取service id信息
service_t its_service = VSOMEIP_BYTES_TO_WORD(
_data[VSOMEIP_SERVICE_POS_MIN],
_data[VSOMEIP_SERVICE_POS_MAX]);
//查找本地缓存中是否存在对应的service信息
client_t its_client = find_local_client(its_service, _instance);
//这里如果已经查到,那么直接用已有的ep连接
if (its_client != VSOMEIP_ROUTING_CLIENT) {
if (is_client_known(its_client)) {
its_target = ep_mgr_->find_or_create_local(its_client);
}
}
} else if (!utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
...
} else if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]) &&
_client == VSOMEIP_ROUTING_CLIENT) {
...
} else if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]) &&
_client != VSOMEIP_ROUTING_CLIENT) {
// notify_one
its_target = ep_mgr_->find_local(_client);
if (its_target) {
...
return send_local(its_target, get_client(), _data, _size,
_instance, _reliable, VSOMEIP_SEND, _status_check);
}
}
// If no direct endpoint could be found
// or for notifications ~> route to routing_manager_stub
//如果找不到endpoint或通知-> 那么直接路由到routing_manager_stub
#ifdef USE_DLT
bool message_to_stub(false);
#endif
if (!its_target) {
std::lock_guard its_lock(sender_mutex_);
//如果之前没有连接过,这里路由到routing_manager_stub。
if (sender_) {
its_target = sender_;
#ifdef USE_DLT
message_to_stub = true;
#endif
} else {
return false;
}
}
bool send(true);
uint8_t command = VSOMEIP_SEND;
if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
if (_client != VSOMEIP_ROUTING_CLIENT) {
command = VSOMEIP_NOTIFY_ONE;
} else {
command = VSOMEIP_NOTIFY;
// Do we need to deliver a notification to the routing manager?
// Only for services which already have remote clients subscribed to
send = has_remote_subscribers;
}
}
...
if (send) {
//发送消息给对应的routing_stub
is_sent = send_local(its_target,
(command == VSOMEIP_NOTIFY_ONE ? _client : get_client()),
_data, _size, _instance, _reliable, command, _status_check);
}
}
return (is_sent);
}
紧接着,设置本地socket通信的相关header,然后转发消息给stub
bool routing_manager_base::send_local(
std::shared_ptr& _target, client_t _client,
const byte_t *_data, uint32_t _size, instance_t _instance,
bool _reliable, uint8_t _command, uint8_t _status_check) const {
const std::size_t its_complete_size = VSOMEIP_SEND_COMMAND_SIZE
- VSOMEIP_COMMAND_HEADER_SIZE + _size;
const client_t sender = get_client();
//设置本地socket通信的相关header信息
std::vector its_command_header(VSOMEIP_SEND_COMMAND_SIZE);
its_command_header[VSOMEIP_COMMAND_TYPE_POS] = _command;
std::memcpy(&its_command_header[VSOMEIP_COMMAND_CLIENT_POS],
&sender, sizeof(client_t));
std::memcpy(&its_command_header[VSOMEIP_COMMAND_SIZE_POS_MIN],
&its_complete_size, sizeof(_size));
std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN],
&_instance, sizeof(instance_t));
std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_RELIABLE_POS],
&_reliable, sizeof(bool));
std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS],
&_status_check, sizeof(uint8_t));
// Add target client, only relevant for selective notifications
std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MIN],
&_client, sizeof(client_t));
return _target->send(its_command_header, _data, _size);
}
这里主要做了如下的几件事,解析对应的command获取service信息,然后对client进行安全检查
case VSOMEIP_SEND: {
if (_size < VSOMEIP_SEND_COMMAND_SIZE + VSOMEIP_FULL_HEADER_SIZE) {
VSOMEIP_WARNING << "Received a SEND command with too small size ~> skip!";
break;
}
//获取payload信息
its_data = &_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS];
its_service = VSOMEIP_BYTES_TO_WORD(
its_data[VSOMEIP_SERVICE_POS_MIN],
its_data[VSOMEIP_SERVICE_POS_MAX]);
its_client_from_header = VSOMEIP_BYTES_TO_WORD(
its_data[VSOMEIP_CLIENT_POS_MIN],
its_data[VSOMEIP_CLIENT_POS_MAX]);
its_method = VSOMEIP_BYTES_TO_WORD(
its_data[VSOMEIP_METHOD_POS_MIN],
its_data[VSOMEIP_METHOD_POS_MAX]);
std::memcpy(&its_instance, &_data[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN],
sizeof(its_instance));
std::memcpy(&its_reliable, &_data[VSOMEIP_SEND_COMMAND_RELIABLE_POS],
sizeof(its_reliable));
std::memcpy(&its_check_status, &_data[VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS],
sizeof(its_check_status));
// Allow response messages from local proxies as answer to remote requests
// but check requests sent by local proxies to remote against policy.
//允许来自本地代理的响应消息作为对远程请求的应答,但根据策略检查本地代理发送到远程的请求。
//这里如果时response可以正常回复,但是如果时request,那么就要检查策略
if (utility::is_request(its_data[VSOMEIP_MESSAGE_TYPE_POS])) {
if (!security::get()->is_client_allowed(its_sender_uid, its_sender_gid,
its_client_from_header, its_service, its_instance, its_method)) {
...
return;
}
}
// reduce by size of instance, flush, reliable, client and is_valid_crc flag
const std::uint32_t its_message_size = its_size -
(VSOMEIP_SEND_COMMAND_SIZE - VSOMEIP_COMMAND_HEADER_SIZE);
if (its_message_size !=
VSOMEIP_BYTES_TO_LONG(_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN],
_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 1],
_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 2],
_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 3])
+ VSOMEIP_SOMEIP_HEADER_SIZE) {
...
break;
}
host_->on_message(its_service, its_instance, its_data, its_message_size,
its_reliable, _bound_client, _credentials, its_check_status, false);
break;
}
对相关client发来的消息进行检查后,会吧对应的消息转发给routing_manager_impl做进一步处理
这里首先去获取routing进程中存储的service的信息,相关的service可能存在2种情况、
bool routing_manager_impl::on_message(
service_t _service, instance_t _instance,
const byte_t *_data, length_t _size,
bool _reliable, client_t _bound_client,
credentials_t _credentials,
uint8_t _check_status,
bool _is_from_remote) {
...
client_t its_client;
bool is_forwarded(true);
if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
its_client = find_local_client(_service, _instance);
} else {
its_client = VSOMEIP_BYTES_TO_WORD(
_data[VSOMEIP_CLIENT_POS_MIN],
_data[VSOMEIP_CLIENT_POS_MAX]);
}
if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
is_forwarded = deliver_notification(_service, _instance, _data, _size,
_reliable, _bound_client, _credentials, _check_status, _is_from_remote);
} else if (its_client == host_->get_client()) {
//如果需要发送的client就是host自己的话,直接转发给自己
deliver_message(_data, _size, _instance,
_reliable, _bound_client, _credentials, _check_status, _is_from_remote);
} else {
//这里说明是远程的连接,继续send消息
send(its_client, _data, _size, _instance, _reliable,
_bound_client, _credentials, _check_status, _is_from_remote); //send to proxy
}
return is_forwarded;
}
由于我们的hellowrld service自己本身就是routing进程,因此这里直接转发给自己去处理消息。
这里主要是解析了对应的ipc消息,然后重新组织成someip的message供上层使用。
其次在此基础上做了相关的安全检查,检查client是否可以去send操作。
bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size,
instance_t _instance, bool _reliable, client_t _bound_client, credentials_t _credentials,
uint8_t _status_check, bool _is_from_remote) {
bool is_delivered(false);
std::uint32_t its_sender_uid = std::get<0>(_credentials);
std::uint32_t its_sender_gid = std::get<1>(_credentials);
auto its_deserializer = get_deserializer();
its_deserializer->set_data(_data, _size);
std::shared_ptr its_message(its_deserializer->deserialize_message());
its_deserializer->reset();
put_deserializer(its_deserializer);
if (its_message) {
//重新设置message的信息
its_message->set_instance(_instance);
its_message->set_reliable(_reliable);
its_message->set_check_result(_status_check);
its_message->set_uid(std::get<0>(_credentials));
its_message->set_gid(std::get<1>(_credentials));
//本地检查对应的uid,gid信息,但是远程,只去检查is_remote_client_allowed
//检查需要转发的消息是来自本地还是远程的
if (!_is_from_remote) {
...
//如果该消息是一个request消息
} else if (utility::is_request(its_message->get_message_type())) {
if (security::get()->is_enabled()
&& its_message->get_client() != _bound_client) {
...
return false;
}
//检查策略,当前的uid是否可以request对应的服务
if (!security::get()->is_client_allowed(its_sender_uid, its_sender_gid,
its_message->get_client(), its_message->get_service(),
its_message->get_instance(), its_message->get_method())) {
...
return false;
}
...
host_->on_message(std::move(its_message));
is_delivered = true;
} else {
VSOMEIP_ERROR << "Routing manager: deliver_message: "
<< "SomeIP-Header deserialization failed!";
}
return is_delivered;
}
对应的routing_impl会调回到自身进程的application_impl函数。
service进程在注册对应on_message回调函数的时候,会将对应的信息存储在members中,这里主要做的事情就是查找members存储的回调函数。
然后调用对应的回调函数
//消息过来时,遍历对应的回调函数,然后根据serviceid,instanceid,methodid查找对应的回调函数
void application_impl::on_message(std::shared_ptr &&_message) {
const service_t its_service = _message->get_service();
const instance_t its_instance = _message->get_instance();
const method_t its_method = _message->get_method();
if (_message->get_message_type() == message_type_e::MT_NOTIFICATION) {
if (!check_for_active_subscription(its_service, its_instance,
static_cast(its_method))) {
...
return;
}
}
{
std::lock_guard its_lock(members_mutex_);
std::set its_handlers;
auto found_service = members_.find(its_service);
if (found_service != members_.end()) {
auto found_instance = found_service->second.find(its_instance);
if (found_instance != found_service->second.end()) {
auto found_method = found_instance->second.find(its_method);
if (found_method != found_instance->second.end()) {
its_handlers.insert(found_method->second);
}
auto found_any_method = found_instance->second.find(ANY_METHOD);
if (found_any_method != found_instance->second.end()) {
its_handlers.insert(found_any_method->second);
}
}
auto found_any_instance = found_service->second.find(ANY_INSTANCE);
if (found_any_instance != found_service->second.end()) {
auto found_method = found_any_instance->second.find(its_method);
if (found_method != found_any_instance->second.end()) {
its_handlers.insert(found_method->second);
}
auto found_any_method = found_any_instance->second.find(ANY_METHOD);
if (found_any_method != found_any_instance->second.end()) {
its_handlers.insert(found_any_method->second);
}
}
}
auto found_any_service = members_.find(ANY_SERVICE);
if (found_any_service != members_.end()) {
auto found_instance = found_any_service->second.find(its_instance);
if (found_instance != found_any_service->second.end()) {
auto found_method = found_instance->second.find(its_method);
if (found_method != found_instance->second.end()) {
its_handlers.insert(found_method->second);
}
auto found_any_method = found_instance->second.find(ANY_METHOD);
if (found_any_method != found_instance->second.end()) {
its_handlers.insert(found_any_method->second);
}
}
auto found_any_instance = found_any_service->second.find(ANY_INSTANCE);
if (found_any_instance != found_any_service->second.end()) {
auto found_method = found_any_instance->second.find(its_method);
if (found_method != found_any_instance->second.end()) {
its_handlers.insert(found_method->second);
}
auto found_any_method = found_any_instance->second.find(ANY_METHOD);
if (found_any_method != found_any_instance->second.end()) {
its_handlers.insert(found_any_method->second);
}
}
}
if (its_handlers.size()) {
std::lock_guard its_lock(handlers_mutex_);
for (const auto &its_handler : its_handlers) {
auto handler = its_handler.handler_;
std::shared_ptr its_sync_handler =
std::make_shared([handler, _message]() {
handler(_message);
});
its_sync_handler->handler_type_ = handler_type_e::MESSAGE;
its_sync_handler->service_id_ = _message->get_service();
its_sync_handler->instance_id_ = _message->get_instance();
its_sync_handler->method_id_ = _message->get_method();
its_sync_handler->session_id_ = _message->get_session();
handlers_.push_back(its_sync_handler);
}
dispatcher_condition_.notify_one();
}
}
}
这里在注册回调函数的时候,对应的服务的on_message回调函数会存储在members_里面。因此这里可以找到对应的members里的回调函数,调用hellworld的on_message函数
如果需要请求的服务不是routing进程本身,routing继续发送对应的消息给真正的service
//routing代理发给_client对应的服务,send的客户端的id是_bound_client
bool routing_manager_impl::send(client_t _client, const byte_t *_data,
length_t _size, instance_t _instance, bool _reliable,
client_t _bound_client,
credentials_t _credentials,
uint8_t _status_check, bool _sent_from_remote) {
bool is_sent(false);
if (_size > VSOMEIP_MESSAGE_TYPE_POS) {
std::shared_ptr its_target;
bool is_request = utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS]);
bool is_notification = utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]);
bool is_response = utility::is_response(_data[VSOMEIP_MESSAGE_TYPE_POS]);
client_t its_client = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_CLIENT_POS_MIN],
_data[VSOMEIP_CLIENT_POS_MAX]);
service_t its_service = VSOMEIP_BYTES_TO_WORD(
_data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]);
method_t its_method = VSOMEIP_BYTES_TO_WORD(
_data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]);
bool is_service_discovery
= (its_service == sd::service && its_method == sd::method);
if (is_request) {
its_target = ep_mgr_->find_local(its_service, _instance);
} else if (!is_notification) {
its_target = find_local(its_client);
} else if (is_notification && _client && !is_service_discovery) { // Selective notifications!
if (_client == get_client()) {
...
}
if (its_target) {
#ifdef USE_DLT
if ((is_request && its_client == get_client()) ||
(is_response && find_local_client(its_service, _instance) == get_client())) {
const uint16_t its_data_size
= uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size);
trace::header its_header;
if (its_header.prepare(its_target, true, _instance))
tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE,
_data, its_data_size);
}
#endif
//通过本地socket发送消息给对应的服务端
is_sent = send_local(its_target, get_client(), _data, _size, _instance, _reliable, VSOMEIP_SEND, _status_check);
重新序列化ipc的消息,发送对应的消息给proxy
bool routing_manager_base::send_local(
std::shared_ptr& _target, client_t _client,
const byte_t *_data, uint32_t _size, instance_t _instance,
bool _reliable, uint8_t _command, uint8_t _status_check) const {
const std::size_t its_complete_size = VSOMEIP_SEND_COMMAND_SIZE
- VSOMEIP_COMMAND_HEADER_SIZE + _size;
const client_t sender = get_client();
//设置本地socket通信的相关header信息
std::vector its_command_header(VSOMEIP_SEND_COMMAND_SIZE);
its_command_header[VSOMEIP_COMMAND_TYPE_POS] = _command;
std::memcpy(&its_command_header[VSOMEIP_COMMAND_CLIENT_POS],
&sender, sizeof(client_t));
std::memcpy(&its_command_header[VSOMEIP_COMMAND_SIZE_POS_MIN],
&its_complete_size, sizeof(_size));
std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN],
&_instance, sizeof(instance_t));
std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_RELIABLE_POS],
&_reliable, sizeof(bool));
std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS],
&_status_check, sizeof(uint8_t));
// Add target client, only relevant for selective notifications
std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MIN],
&_client, sizeof(client_t));
return _target->send(its_command_header, _data, _size);
}
这里的proxy应该是server端的proxy,首先解析相关的命令,然后做了一些安全检查,最后调用host_->on_message
void routing_manager_proxy::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) {
(void)_receiver;
(void)_destination;
(void)_remote_address;
(void)_remote_port;
...
bool message_from_routing(false);
if (its_security->is_enabled()) {
// if security is enabled, client ID of routing must be configured
// and credential passing is active. Otherwise bound client is zero by default
message_from_routing = (_bound_client == routing_host_id);
} else {
message_from_routing = (its_client == routing_host_id);
}
//如果这里安全功能打开了,那么这里proxy收到的消息必须是routing的,或者是他自己
if (its_security->is_enabled() && !message_from_routing &&
_bound_client != its_client) {
VSOMEIP_WARNING << std::hex << "Client " << std::setw(4) << std::setfill('0') << get_client()
<< " received a message with command " << (uint32_t)its_command
<< " from " << std::setw(4) << std::setfill('0')
<< its_client << " which doesn't match the bound client "
<< std::setw(4) << std::setfill('0') << _bound_client
<< " ~> skip message!";
return;
}
...
case VSOMEIP_SEND: {
if (_size < VSOMEIP_SEND_COMMAND_SIZE + VSOMEIP_FULL_HEADER_SIZE) {
VSOMEIP_WARNING << "Received a SEND command with too small size -> skip!";
break;
}
instance_t its_instance;
bool its_reliable;
uint8_t its_check_status;
std::memcpy(&its_instance,&_data[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN],
sizeof(instance_t));
std::memcpy(&its_reliable, &_data[VSOMEIP_SEND_COMMAND_RELIABLE_POS],
sizeof(its_reliable));
std::memcpy(&its_check_status, &_data[VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS],
sizeof(its_check_status));
...
if (its_message) {
//重组对应的someip的message
its_message->set_instance(its_instance);
its_message->set_reliable(its_reliable);
its_message->set_check_result(its_check_status);
its_message->set_uid(std::get<0>(_credentials));
its_message->set_gid(std::get<1>(_credentials));
if (!message_from_routing) {
//做对应的安全检查
...
}
host_->on_message(std::move(its_message));
这里整个发消息的过程实际上
由于helloworld的测试程序都是在本地运行的,因此整个过程实际上是不涉及远程的网络通信的,都是本地的ipc通信。但是其实整个过程中,由于routing的存在,someip本身的消息实际上是被转了好几道手。
首先,在client进程到routing进程这段,会先把原本的someip message转换成本地ipc的message,其次,在routing进程转发service的过程中,由于也是ipc通信,因此也是使用的本地ipc的message格式。最终,到达service端,会将对应的message还原成someip的message。