Snapdragon® Telematics Application Framework (TelAF) Interface Specification
SOME/IP Gateway Client Service

API Reference


The SOME/IP Gateway Client Service supports SOME/IP protocol(http://some-ip.com/) through vsomeip (https://github.com/COVESA/vsomeip) library APIs. It provides a set of simple and high level TelAF APIs for applications to communicate with remote SOME/IP servers, so that the applications can discover and connect to a service, send requests and get responses, subscribe to and receive events, as well as handle errors.

IPC interfaces binding

The functions of this API are provided by the tafSomeipGWSvc application service.

The following example illustrates how to bind to the SOME/IP Gateway Client Service.

bindings:
{
    clientExe.clientComponent.taf_someipClnt -> tafSomeipGWSvc.taf_someipClnt
}

System Configuration

Before using any API of the service, the user needs to configure the system properly. Since the SOME/IP Gateway Client Service is built upon vsomeip library, the configuration follows the same JSON format as vsomeip. The user can take the default vsomeip JSON file which locates in /legato/systems/current/appsWriteable/tafSomeipGWSvc/tafSomeipGWSvc.json as a template to make their own specific configuration. The default JSON file is as below:

{
 "unicast" : "192.168.225.1",
 "device" : "bridge0",
 "logging" :
 {
     "level" : "error",
     "console" : "true",
     "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" },
     "version" : { "enable" : "false", "interval" : "10" },
     "dlt" : "false"
 },
 "applications" :
 [
     {
         "name" : "tafSomeipGWSvc",
         "id" : "0x0101"
     }
 ],
 "routing" : "tafSomeipGWSvc",
 "network" : "tafSomeipGWSvc",
 "service-discovery" :
 {
     "enable" : "true",
     "multicast" : "224.0.0.1",
     "port" : "30490",
     "protocol" : "udp",
     "initial_delay_min" : "10",
     "initial_delay_max" : "100",
     "repetitions_base_delay" : "200",
     "repetitions_max" : "3",
     "ttl" : "3",
     "cyclic_offer_delay" : "2000",
     "request_response_delay" : "1500"
 }
}

Mandatorily, the unicast and device must be set with the correct IP address and network interface in the system for SOME/IP communications. The id in applications section shall be set with a unique client ID within the given network. Optionally, the SOME/IP-SD parameters (like multicast) in service-discovery section can be changed if needed.

Restart the tafSomeipGWSvc service or reboot the device to make the new configuration take effect after any modifications.

Finally run below command to add a route entry for the SOME/IP-SD multicast address(Suppose the network interface is "bridge0" and the multicast address is "224.0.0.1"):

route add 224.0.0.1 dev bridge0

Multiple networks/VLANs configuration

The default configuration file is only for single network/VLAN which is also the default network. If the user wants to support multiple networks/VLANs in the GW service, they have to create additional configuration files. These configuration files can be tafSomeipGWSvc_1.json to tafSomeipGWSvc_7.json, which means a maximum of 8 networks/VLANs can be supported. For example, the user can create below configuration file to support the second network/VLAN in the GW service:

{
 "unicast" : "192.168.226.1",
 "device" : "eth1",
 "logging" :
 {
     "level" : "error",
     "console" : "true",
     "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" },
     "version" : { "enable" : "false", "interval" : "10" },
     "dlt" : "false"
 },
 "applications" :
 [
     {
         "name" : "tafSomeipGWSvc_1",
         "id" : "0x0102"
     }
 ],
 "routing" : "tafSomeipGWSvc_1",
 "network" : "tafSomeipGWSvc_1",
 "service-discovery" :
 {
     "enable" : "true",
     "multicast" : "225.0.0.1",
     "port" : "30490",
     "protocol" : "udp",
     "initial_delay_min" : "10",
     "initial_delay_max" : "100",
     "repetitions_base_delay" : "200",
     "repetitions_max" : "3",
     "ttl" : "3",
     "cyclic_offer_delay" : "2000",
     "request_response_delay" : "1500"
 }
}

In this case, a second configuration file tafSomeipGWSvc_1.json is created for network interface "eth1" with its own network address and multicast address.

Note
The value of name, routing, and network in the configuration file must match the file name, which is tafSomeipGWSvc_1 in this case.

Client Service APIs

Before setting up a client-service-instance, application shall first get the service reference by calling taf_someipClnt_RequestService() or taf_someipClnt_RequestServiceEx() and use the reference returned for subsequent operations.

The following example illustrates how to set up a SOME/IP client-service-instance and connect to a service on default network interface.

const uint16_t serviceId = 0x1234; // Service ID
const uint16_t instanceId = 0x5678; // Service instance
taf_someipClnt_ServiceRef_t serviceRef; // Service reference
// Get the service reference on default network interface.
serviceRef = taf_someipClnt_RequestService(serviceId, instanceId);
LE_ASSERT(serviceRef != NULL);

Application can call taf_someipClnt_AddStateChangeHandler() to register a state change handler for that service. Once the service state change happens, the handler will be called and the new state is passed as an input parameter to the application.

The following example illustrates how to register a state change handler, and get the service version once the service state becomes available.

// State change handler function.
void StateChangeHandler
(
void* contextPtr
)
{
// Logging the new service state.
LE_INFO("Service is '%s'.", state == TAF_SOMEIPCLNT_AVAILABLE ? "AVAILABLE" : "UNAVAILABLE");
// Get the service version if it's available.
{
uint8_t majVer;
uint32_t minVer;
if (LE_OK == taf_someipClnt_GetVersion(serviceRef, &majVer, &minVer))
{
LE_INFO("Service version: '0x%x/0x%x'.", majVer, minVer);
}
}
}

Applications can call taf_someipClnt_GetState() to get the current service state. Applications can also call taf_someipClnt_ReleaseService() to disconnect to the service if the application does not use the service any longer.

taf_someipClnt_State_t state; // Service state
// Get the service state.
LE_ASSERT(LE_OK != taf_someipClnt_GetState(serviceRef, &state));
LE_INFO("Service is '%s'.", state == TAF_SOMEIPCLNT_AVAILABLE ? "AVAILABLE" : "UNAVAILABLE");
// Get the service version if it is available.
{
uint8_t majVer;
uint32_t minVer;
if (LE_OK == taf_someipClnt_GetVersion(serviceRef, &majVer, &minVer))
{
LE_INFO("Service version: '0x%x/0x%x'.", majVer, minVer);
}
}
// Release the service.

Request Response Message APIs

Application can send a request message with a given method and payload data to a service after the service is available and get the response message in a callback handler later.

The following example illustrates how to create a request message, send the message, and get the response.

// Response handler function.
void ResponseHandler
(
le_result_t result,
bool isErrRsp,
uint8_t returnCode,
const uint8_t* dataPtr,
size_t dataSize,
void* contextPtr
)
{
// Check the response status.
LE_INFO("RESPONSE STATUS: [result='%s', msgType='%s', returnCode='%d']",
LE_RESULT_TXT(result), isErrRsp ? "MT_ERROR" : "MT_RESPONSE", returnCode);
// Dump the response payload data with hex string format if it is not empty.
if ((result == LE_OK) && (dataPtr != NULL) && (dataSize != 0))
{
char PayloadString[2*dataSize + 1];
le_hex_BinaryToString(dataPtr, dataSize, PayloadString, 2*dataSize + 1);
LE_INFO("RESPONSE PAYLOAD: ['%s']", PayloadString);
}
}
// Create a request message of the service with method 0x2000.
taf_someipClnt_TxMsgRef_t txMsgRef = taf_someipClnt_CreateMsg(serviceRef, 0x2000);
LE_ASSERT(txMsgRef != NULL);
// Use TCP to send the message.
// Set the response timeout to 5 seconds.
// Fill the payload data of the message.
uint8_t payload[5] = { 0x01, 0x02, 0x03, 0x04, 0x05 };
LE_ASSERT(LE_OK == taf_someipClnt_SetPayload(txMsgRef, payload, sizeof(payload)));
// Send the request message with a response handler.
taf_someipClnt_RequestResponse(txMsgRef, ResponseHandler, NULL);

Event Message APIs

The application can call taf_someipClnt_EnableEventGroup() taf_someipClnt_SubscribeEventGroup() to set up the events with the event group it is interested in for a service. It can then call taf_someipClnt_AddEventMsgHandler() to register an event message handler for that event group. Later, once a SOME/IP event message of that event group is received, the message handler will be called with the service reference and event ID passed as input parameters.

The following example illustrates how to set up two events in an event group, and register an event message handler for that event group.

// Event message handler function.
void EventMsgHandler
(
uint16_t eventId,
const uint8_t* dataPtr,
size_t dataSize,
void* contextPtr
)
{
// Logging the event ID.
LE_INFO("EVENT [ ID='0x%x'] received.", eventId);
// Dump the event payload data with hex string format if it's not empty.
if ((dataPtr != NULL) && (dataSize != 0))
{
char PayloadString[2*dataSize + 1];
le_hex_BinaryToString(dataPtr, dataSize, PayloadString, 2*dataSize + 1);
LE_INFO("EVENT PAYLOAD ['%s']", PayloadString);
}
}
// Define one event group which contains two events.
#define GROUP_ID 0x1000
#define EVENT_ID1 0x8001
#define EVENT_ID2 0x8002
// Add event 0x8001 to group 0x1000.
LE_ASSERT(LE_OK == taf_someipClnt_EnableEventGroup(serviceRef, GROUP_ID, EVENT_ID1,
// Add event 0x8002 to group 0x1000.
LE_ASSERT(LE_OK == taf_someipClnt_EnableEventGroup(serviceRef, GROUP_ID, EVENT_ID2,
// Subscribe to group 0x1000.
// Register an event handler for group 0x1000.
taf_someipClnt_AddEventMsgHandler(serviceRef, GROUP_ID, EventMsgHandler, NULL);
LE_ASSERT(eventHandlerRef != NULL);
Note
An event or an event group of a client-service-instance can be only set up by one client application.