利用commonAPI + someip 在不同板子间发送数据流或文件

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

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值