request&respond
response模版
//创建应用,xxx是应用名称可以为空从服务中获取
app = vsomeip::runtime::get()->create_application("XXXX");
//初始化
app->init();
//注册服务处理函数
app->register_message_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID, on_message);
//提供服务
app->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
//启动服务
app->start();
request模版
//创建应用,xxx是应用名称可以为空从服务中获取
app = vsomeip::runtime::get()->create_application("XXXX");
//初始化
app->init();
//注册服务有效性回调
app->register_availability_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, on_availability);
//请求服务
app->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
//启动服务
app->start();
发送函数
void send() {
std::shared_ptr< vsomeip::message > request;
request = vsomeip::runtime::get()->create_request();
request->set_service(SAMPLE_SERVICE_ID);
request->set_instance(SAMPLE_INSTANCE_ID);
request->set_method(SAMPLE_METHOD_ID);
std::shared_ptr< vsomeip::payload > its_payload = vsomeip::runtime::get()->create_payload();
std::vector< vsomeip::byte_t > its_payload_data;
for (vsomeip::byte_t i=0; i<10; i++) {
its_payload_data.push_back(i % 256);
}
its_payload->set_data(its_payload_data);
request->set_payload(its_payload);
app->send(request);
}
notify & subscribe
notify模版
//创建应用,xxx是应用名称可以为空从服务中获取
app = vsomeip::runtime::get()->create_application("XXXX");
//初始化
app->init();
//提供服务
app->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
//加入事件组
std::set<vsomeip::eventgroup_t> its_groups;
its_groups.insert(SAMPLE_EVENTGROUP_ID);
app->offer_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, its_groups);
//开始应用
app->start();
subscribe模版
//创建应用,xxx是应用名称可以为空从服务中获取
app = vsomeip::runtime::get()->create_application("XXXX");
//初始化
app->init();
//检查服务有效性
app->register_availability_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, on_availability);
//请求服务
app->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
//注册消息处理
app->register_message_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, on_message);
std::set<vsomeip::eventgroup_t> its_groups;
its_groups.insert(SAMPLE_EVENTGROUP_ID);
app->request_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, its_groups);
app->subscribe(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENTGROUP_ID);
//启动应用
app->start();
field Get & field Set
SERVICE参考
创建应用
app_ = vsomeip::runtime::get()->create_application();
初始化
app_->init()
//field
注册服务
app_->register_message_handler(
SAMPLE_SERVICE_ID,
SAMPLE_INSTANCE_ID,
SAMPLE_GET_METHOD_ID,
field_get);
app_->register_message_handler(
SAMPLE_SERVICE_ID,
SAMPLE_INSTANCE_ID,
SAMPLE_SET_METHOD_ID,
field_set);
//注册事件
std::set<vsomeip::eventgroup_t> its_groups;
its_groups.insert(SAMPLE_EVENTGROUP_ID);
app_->offer_event(
SAMPLE_SERVICE_ID,
SAMPLE_INSTANCE_ID,
SAMPLE_FIELD_EVENT_ID,
its_groups);
app_->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, 1, 0);
app_->start();
client参考
//创建应用
app_ = vsomeip::runtime::get()->create_application();
//初始化
app_->init()
app_->register_state_handler(on_state);
//field
app_->register_message_handler(
SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_GET_METHOD_ID,
on_message);
app_->register_message_handler(
SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_SET_METHOD_ID,
on_message);
app_->register_availability_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID,
on_availability);
app_->register_message_handler(
SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_FIELD_EVENT_ID,
on_message);
std::set<vsomeip::eventgroup_t> its_groups;
its_groups.insert(SAMPLE_EVENTGROUP_ID);
app_->request_event(
SAMPLE_SERVICE_ID,
SAMPLE_INSTANCE_ID,
SAMPLE_FIELD_EVENT_ID,
its_groups,
vsomeip::event_type_e::ET_FIELD,
vsomeip::reliability_type_e::RT_BOTH);
app_->subscribe(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENTGROUP_ID);
app_->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
app_->start();
序列化与反序列化
序列化
std::shared_ptr< vsomeip::payload > its_payload = vsomeip::runtime::get()->create_payload();
std::vector< vsomeip::byte_t > its_payload_data;
const uint8_t a = 100;
const uint16_t b = 59;
const uint32_t c = 48;
const uint8_t arr[] = {1,2,3,4,5};
const std::string hello("1234455");
vsomeip_v3::serializer ser(0);
ser.serialize(a);
ser.serialize(b);
ser.serialize(c);
ser.serialize(arr, 5);
ser.serialize((const uint8_t*)hello.c_str(), (uint32_t)hello.size());
// for (std::size_t i = 0; i < 10; ++i)
// its_payload_data.push_back(vsomeip::byte_t(i % 256));
its_payload->set_data(ser.get_data(), ser.get_size());
request_->set_payload(its_payload);
app_->send(request_);
反序列化
std::shared_ptr<vsomeip::payload> its_payload = _request->get_payload();
//uint8_t *data = its_payload->get_data();
vsomeip_v3::deserializer des(its_payload->get_data(),its_payload->get_length(), 0);
uint8_t a ;
uint16_t b ;
uint32_t c ;
uint8_t arr[5];
std::string hello;
des.deserialize(a);
des.deserialize(b);
des.deserialize(c);
des.deserialize(arr, 5);
des.deserialize(hello, 7);
常见问题
1、在同一个局域网内,两方无法相互发现;
原理:运行的someip应用需要借助于各自的someipd服务来彼此发现对方;
而someipd实现的someip sd协议是借助于udp的广播来发布或收集网络中的其他someip应用的相关信息的;
所以要想两方能够彼此发现,首先要将someip sd的服务设置为同一广播地址以及服务端口号;
这个信息可以在vsomeip程序加载的vsomeip-tcp-server.json等配置文件中进行修改;
理想情况下,将两方的配置修改成一样就可以正常发现彼此;
2、将someip sd的广播地址以及服务端口号配置成一样,双方仍然是无法发现彼此;
这个首先要借助网络工具来抓包进行确认,是否可以在网络上抓取到相应的udp数据包,来检查是不是由于网络设置的原因造成的;
如果抓包工具可以确认在网络上有影响的udp广播包;
那么就要对someip的版本号配置进行确认;
在我使用vsomeip 2.10版本时发现,vsomeip 代码中的默认主版本号信息为0x00;而vector autasar的someip版本号信息不特意更改的话是0x01;
由于双方版本号不一致,虽然彼此可以收到对方发出的sd udp广播包,但在软件中彼此仍然无法相互识别。并且在vsomeip中会频繁输出warning信息;
将双方的版本号信息设置为一致时,就相互就可以识别了;
3、sd 广播地址服务端口号以及版本号都配置成一致;但彼此仍然无法发现;
这个就需要排查网络设置问题;
(1)双方是否可以彼此ping通;
(2)路由表以及gateway是否配置正确;
我就遇到双方可以ping通,但由于路由表以及gateway信息缺失使得双方无法彼此发现的问题;
4、双方可以彼此发现,但客户端一订阅或者发送request底层tcp链接就断开的情况;
这个问题,也是由于服务版本号的问题(interface version);
由于某些特殊的原因,将autosar someip的主版本号设置为255可以与vsomeip 的0版本号相互发现;
但是当进行交互时,在代码中会对interface version配置进行验证。如果双方的interface version不一致,那么就会出现一通信底层tcp的链接就会断开情况;
这个需要注意检查;
5、当vsomeip作为服务器,autosar someip作为客户端。vsomeip发送的event,autosar someip的客户端无法接收到的情况;
首先要对someip传输类型进行确认(使用的是tcp或者udp);
假如使用tcp进行传输;则需要将vsomeip 配置文件中event配置添加is_reliable为true的字段;
否则autasar someip tcp的客户端无法正常接收;
6、主机不能发送someip 消息
添加广播路由
ip route add 224.224.224.0/24 via 172.20.4.3 dev enp0s31f6.4
7、tbox不能与主机通信
tbox网络带有vlan id, 主机需要配置相同vlan id
调试工具
tcpdump 和 wireshark
tcpdump -i <网卡名称> -w <输出文件名.cap>
然后用wireshark分析cap文件