1. 设置 commonAPI+someip
可以参考
CommonAPI新版本配置_C_Silence_K的博客-CSDN博客_commonapi 配置
去设置和编译你的 commonAPI + someip, 确保在你的开发板或linux服务器单机上能正确运行。
本文的测试程序来自下面链接:
https://github.com/COVESA/capicxx-core-tools/tree/master/CommonAPI-Examples
E01HelloWorld, 我将基于这个测试程序, 修改 fidl/E01HelloWorld-SomeIP.fdepl, fidl/E01HelloWorld.fidl, src/E01HelloWorldClient.cpp, src/E01HelloWorldStubImpl.cpp 和src/E01HelloWorldStubImpl.hpp 做基于两个独立IP地址的不同板子间的数据流或文件传输。
2. 本文数据流传输测试网络架构
192.168.225.1 ( server ) < ----- > 192.168.225.2 ( client )
udp
3. 确保两个开发板之间能正常通信
确保以太网接口能工作, 需要的话,可以配置 iptables 规则允许进来的数据包:
iptables -t filter -I INPUT -j ACCEPT
服务器端IP地址配置为192.168.225.1, 客户端IP地址配置为192.168.225.2
4. 注意, 一定要添加以下组播地址的路由,要不然整个测试都进行不下去
在客户端:
route add -net 224.0.0.0/4 dev eth0;
其中eth0为192.168.225.2所在接口
在服务器端:
route add -net 224.0.0.0/4 dev bridge0
其中bridge0为192.168.225.1所在接口
5. 增加 API sendBuff()的 idl 定义,在原来 E01HelloWorld.fidl 的基础上
interface E01HelloWorld {
version { major 0 minor 1 }
method sayHello {
in {
String name
}
out {
String message
}
}
method sendBuff {
in {
ByteBuffer dataBuff
}
}
}
6. 在服务器端添加sendBuff()函数的实现代码
添加 virtual void sendBuff(const std::shared_ptr<CommonAPI::ClientId> _client, CommonAPI::ByteBuffer _dataBuff, sendBuffReply_t _reply);
到 E01HelloWorldStubImpl.hpp
添加以下代码到 E01HelloWorldStubImpl.cpp
#include <unistd.h>
#include <fcntl.h>
static int IsFileReadStart=0;
static int FileFd = 0;
#define WRITE_BUFF_LEN 1024
void E01HelloWorldStubImpl::sendBuff(const std::shared_ptr<CommonAPI::ClientId> _client,
CommonAPI::ByteBuffer _dataBuff, sendBuffReply_t _reply) {
if ( IsFileReadStart == 0)
{
system("rm testfile.txt");
FileFd = open("testfile.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
IsFileReadStart = 1;
}
if (_dataBuff.size() > 0)
{
int len = _dataBuff.size();
write(FileFd, &_dataBuff[0], len);
}
else
{
close(FileFd);
IsFileReadStart = 0;
}
}
7. 在客户端添加sendBuff()函数的实现代码
添加以下代码到 E01HelloWorldClient.cpp
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
int sendFile(const char* filename)
{
CommonAPI::CallStatus callStatus;
CommonAPI::CallInfo info(1000);
info.sender_ = 1234;
int fd = open(filename, O_RDONLY);
if (fd <0)
{
printf("File %s open fail!\n", filename);
return -1;
}
printf("File %s open success!\n", filename);
struct stat srcStat;
if (fstat(fd, &srcStat) != 0)
{
printf("Unable to obtain status of %s", filename);
close(fd);
return 0;
}
long flen = srcStat.st_size;
long mlen = flen;
printf("File %s %ld bytes\n", filename, flen);
int32_t readLen;
unsigned char* recBuff = NULL;
while (mlen > 0)
{
recBuff = (unsigned char*)malloc(mlen);
if (recBuff != NULL)
{
break;
}
mlen=mlen/2;
}
if (recBuff == NULL)
{
printf("Malloc fail\n", filename);
close(fd);
return 0;
}
printf("Malloc %ld bytes\n", mlen);
while ((readLen = read( fd, recBuff, mlen )))
{
CommonAPI::ByteBuffer data(recBuff, recBuff+readLen);
myProxy->sendBuff(data, callStatus, &info);
}
// Send empty buff to tell peer file is end
CommonAPI::ByteBuffer data;
data.clear();
myProxy->sendBuff(data, callStatus, &info);
close(fd);
free(recBuff);
return 0;
}
在 main() 函数, 调用 sendFile("testfile.txt"); 发送文件到服务器
8. 修改 vsomeip 的服务器端配置文件vsomeip-service.json, 替换为以下内容
{
"unicast" : "192.168.225.1",
"logging" :
{
"level" : "debug",
"console" : "true",
"file" : { "enable" : "false", "path" : "/var/log/vsomeip.log" },
"dlt" : "false"
},
"applications" :
[
{
"name" : "service-sample",
"id" : "0x1277"
}
],
"services" :
[
{
"service" : "0x1234",
"instance" : "0x5678",
"reliable" : { "port" : "30509", "enable-magic-cookies" : "false" },
"unreliable" : "31000",
"someip-tp": {
"service-to-client": [
"0x7531"
]
}
}
],
"routing" : "service-sample",
"service-discovery" :
{
"enable" : "true",
"multicast" : "224.244.224.245",
"port" : "30490",
"protocol" : "udp"
}
}
"unicast" : "192.168.225.1", 服务器端IP地址
"name" : "service-sample", 必须和 E01HelloWorldService.cpp 中的 std::string connection = "service-sample"; in main(). 相同
"service" : "0x1234", 和 E01HelloWorld-SomeIP.fdepl 中的 SomeIpServiceID = 4660(0x1234) 相同
"instance" : "0x5678", 和E01HelloWorld-SomeIP.fdepl 中的 SomeIpInstanceID = 22136(0x5678) 相同
"someip-tp": 开启 someip-tp 协议,即udp payload大于1400 byte时进行分段传输
8. 修改 vsomeip 的客户端配置文件vsomeip-client.json, 替换为以下内
{
"unicast" : "192.168.225.2",
"netmask" : "255.255.255.0",
"logging" :
{
"level" : "debug",
"console" : "true",
"file" : { "enable" : "true", "path" : "/var/log/vsomeip.log" },
"dlt" : "true"
},
"applications" :
[
{
"name" : "client-sample",
"id" : "0x1343"
}
],
"services" :
[
{
"service" : "0x1234",
"instance" : "0x5678",
"unicast" : "192.168.225.1",
"unreliable" : "31000",
"someip-tp": {
"client-to-service": [
"0x7531"
]
}
}
],
"routing" : "client-sample",
"service-discovery" :
{
"enable" : "true",
"multicast" : "224.244.224.245",
"port" : "30490",
"protocol" : "udp"
}
}
"unicast" : "192.168.225.2", 客户端IP地址
"name" : "client-sample", 必须和 E01HelloWorldClient.cpp std::string connection = "client-sample"; in main(). 相同
"id" : "0x1343", 必须不同于服务器中的id
"someip-tp": 开启 someip-tp 协议,即udp payload大于1400 byte时进行分段传输
"service-discovery" :
{
"enable" : "true",
"multicast" : "224.244.224.245",
"port" : "30490",
"protocol" : "udp"
}, 必须和服务器端 "service-discovery" 配置相同
9. 服务器端测试结果
运行E01HelloWorldService前,进行环境变量的设置,如下:
root@linux:/tmp/commonAPI/E01HelloWorld# pwd
/tmp/commonAPI/E01HelloWorld
export COMMONAPI_CONFIG=/tmp/commonAPI/E01HelloWorld/commonapi4someip.ini;
export VSOMEIP_APPLICATION_NAME=service-sample;
export VSOMEIP_CONFIGURATION=/tmp/commonAPI/E01HelloWorld/vsomeip-service.json;
10. 客户端测试结果
运行E01HelloWorldClient前,进行环境变量的设置,如下:
root@linux:/tmp/commonAPI/E01HelloWorld# pwd
/tmp/commonAPI/E01HelloWorld
export COMMONAPI_CONFIG=/tmp/commonAPI/E01HelloWorld/commonapi4someip.ini;
export VSOMEIP_APPLICATION_NAME=client-sample;
export VSOMEIP_CONFIGURATION=/tmp/commonAPI/E01HelloWorld/vsomeip-client.json;
承接软件项目,联系:504529092@qq.com