Skip to content

Commit

Permalink
Merge pull request #37 from boschglobal/feat/get-field
Browse files Browse the repository at this point in the history
Improve GetField API (breaking changes)
  • Loading branch information
nayakned authored Sep 4, 2024
2 parents e7fba30 + 6e87eff commit 5a51e07
Show file tree
Hide file tree
Showing 60 changed files with 3,330 additions and 1,021 deletions.
6 changes: 3 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ add_library(open1722 SHARED
"src/avtp/Rvf.c"
"src/avtp/Udp.c"
"src/avtp/Utils.c"
"src/avtp/aaf/CommonStream.c"
"src/avtp/aaf/PcmStream.c"
"src/avtp/aaf/Aaf.c"
"src/avtp/aaf/Pcm.c"
"src/avtp/acf/FlexRay.c"
"src/avtp/acf/Gpc.c"
"src/avtp/acf/Can.c"
"src/avtp/acf/CanBrief.c"
"src/avtp/acf/Lin.c"
"src/avtp/acf/Most.c"
"src/avtp/acf/Common.c"
"src/avtp/acf/AcfCommon.c"
"src/avtp/acf/Ntscf.c"
"src/avtp/acf/Sensor.c"
"src/avtp/acf/SensorBrief.c"
Expand Down
59 changes: 59 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,62 @@ To execute the IEEE 1722 CAN Talker application:
```
$ ./bin/acf-can-talker
```

### De/Serialization IEEE 1722 PDUs

Here's a small example how the Open1722 library can be used to build and parse IEEE 1722 PDUs. First we define a C struct for a custom IEEE 1722 packet that can be used to transport a CAN, a LIN and a Flexray message. The frame begins with a Time-synchronous Control Format (TSCF) header. After the TSCF header a list of AVTP Control Format (ACF) messages follows. The first ACF message is a ACF CAN message which consists of ACF CAN header as well as a payload section to carry a 2Byte CAN frame. Similar than with the CAN message another ACF messages for LIN is added.

``` C
// my_1722_pdu.h

#define CAN_PAYLOAD_LEN 2
#define LIN_PAYLOAD_LEN 3

typedef struct {
// IEEE 1722 UDP encapsulation header (optional)
Avtp_Udp_t udp;
// IEEE 1722 TSCF header
Avtp_Tscf_t tscf;
// IEEE 1722 ACF message #1
Avtp_Can_t can;
uint8_t canPayload[CAN_PAYLOAD_LEN];
// IEEE 1722 ACF message #2
Avtp_Lin_t lin;
uint8_t linPayload[LIN_PAYLOAD_LEN];
} My1722Pdu_t;
```

In the next step we're going to c

``` C
// talker.h

#include "my_1722_pdu.h"

int main()
{
My1722Pdu_t pdu;

// Init UDP encapsulation header
Avtp_Udp_Init(&pdu.udp);

// Init TSCF header
Avtp_Tscf_Init(&pdu.tscf);
Avtp_Tscf_SetVersion(&pdu.tscf, 0);
Avtp_Tscf_SetSequenceNum(&pdu.tscf, 12345);
Avtp_Tscf_SetStreamId(&pdu.tscf, 0xAABBCCDDEEFF);
Avtp_Tscf_SetTv(&pdu.tscf, 1);
Avtp_Tscf_SetAvtpTimestamp(&pdu.tscf, 0x11223344);

// Init CAN ACF message
Avtp_Can_Init(&pdu.can);
Avtp_Can_SetCanBusId(&pdu.can, 4);
uint8_t canFrame[CAN_PAYLOAD_LEN] = {0x11, 0x22};

// Init LIN ACF message
Avtp_Lin_Init(&pdu.lin);
uint8_t linFrame[LIN_PAYLOAD_LEN] = {0x11, 0x22, 0x33};

// Send packet to network
}
```
2 changes: 1 addition & 1 deletion examples/aaf/aaf-listener.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
#include <unistd.h>
#include <inttypes.h>

#include "avtp/aaf/PcmStream.h"
#include "avtp/aaf/Pcm.h"
#include "common/common.h"
#include "avtp/CommonHeader.h"

Expand Down
2 changes: 1 addition & 1 deletion examples/aaf/aaf-talker.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
#include <string.h>
#include <unistd.h>

#include "avtp/aaf/PcmStream.h"
#include "avtp/aaf/Pcm.h"
#include "common/common.h"
#include "avtp/CommonHeader.h"

Expand Down
123 changes: 56 additions & 67 deletions examples/acf-can/acf-can-listener.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
#include "avtp/Udp.h"
#include "avtp/acf/Ntscf.h"
#include "avtp/acf/Tscf.h"
#include "avtp/acf/Common.h"
#include "avtp/acf/AcfCommon.h"
#include "avtp/acf/Can.h"
#include "avtp/CommonHeader.h"
#include "acf-can-common.h"
Expand Down Expand Up @@ -139,14 +139,13 @@ static error_t parser(int key, char *arg, struct argp_state *state)

static struct argp argp = { options, parser, args_doc, doc };

static int is_valid_acf_packet(uint8_t* acf_pdu) {

uint64_t val64;

Avtp_AcfCommon_GetField((Avtp_AcfCommon_t*)acf_pdu, AVTP_ACF_FIELD_ACF_MSG_TYPE, &val64);
if (val64 != AVTP_ACF_TYPE_CAN) {
fprintf(stderr, "ACF type mismatch: expected %u, got %lu\n",
AVTP_ACF_TYPE_CAN, val64);
static int is_valid_acf_packet(uint8_t* acf_pdu)
{
Avtp_AcfCommon_t *pdu = (Avtp_AcfCommon_t*) acf_pdu;
uint8_t acf_msg_type = Avtp_AcfCommon_GetAcfMsgType(pdu);
if (acf_msg_type != AVTP_ACF_TYPE_CAN) {
fprintf(stderr, "ACF type mismatch: expected %"PRIu8", got %"PRIu8"\n",
AVTP_ACF_TYPE_CAN, acf_msg_type);
return 0;
}

Expand All @@ -155,71 +154,63 @@ static int is_valid_acf_packet(uint8_t* acf_pdu) {

void print_can_acf(uint8_t* acf_pdu)
{
uint64_t acf_msg_len, can_bus_id, timestamp, can_identifier, pad;

Avtp_Can_t *pdu = (Avtp_Can_t*) acf_pdu;

Avtp_Can_GetField(pdu, AVTP_CAN_FIELD_ACF_MSG_LENGTH, &acf_msg_len);
Avtp_Can_GetField(pdu, AVTP_CAN_FIELD_CAN_BUS_ID, &can_bus_id);
Avtp_Can_GetField(pdu, AVTP_CAN_FIELD_MESSAGE_TIMESTAMP, &timestamp);
Avtp_Can_GetField(pdu, AVTP_CAN_FIELD_CAN_IDENTIFIER, &can_identifier);
Avtp_Can_GetField(pdu, AVTP_CAN_FIELD_PAD, &pad);
uint16_t acf_msg_len = Avtp_Can_GetAcfMsgLength(pdu);
uint8_t can_bus_id = Avtp_Can_GetCanBusId(pdu);
uint64_t timestamp = Avtp_Can_GetMessageTimestamp(pdu);
uint32_t can_identifier = Avtp_Can_GetCanIdentifier(pdu);
uint8_t pad = Avtp_Can_GetPad(pdu);

fprintf(stderr, "------------------------------------\n");
fprintf(stderr, "Msg Length: %"PRIu64"\n", acf_msg_len);
fprintf(stderr, "Can Bus ID: %"PRIu64"\n", can_bus_id);
fprintf(stderr, "Timestamp: %#lx\n", timestamp);
fprintf(stderr, "Can Identifier: %#lx\n", can_identifier);
fprintf(stderr, "Pad: %"PRIu64"\n", pad);
fprintf(stderr, "Msg Length: %"PRIu16"\n", acf_msg_len);
fprintf(stderr, "Can Bus ID: %"PRIu8"\n", can_bus_id);
fprintf(stderr, "Timestamp: %"PRIu64"", timestamp);
fprintf(stderr, "Can Identifier: %"PRIu32"\n", can_identifier);
fprintf(stderr, "Pad: %"PRIu8"\n", pad);
}

static int new_packet(int sk_fd, int can_socket) {

int res;
uint64_t msg_length, proc_bytes = 0, msg_proc_bytes = 0;
uint64_t can_frame_id, udp_seq_num, subtype, flag;
uint16_t payload_length, pdu_length;
int res = 0;
uint64_t proc_bytes = 0, msg_proc_bytes = 0;
uint32_t udp_seq_num;
uint16_t msg_length, can_payload_length, acf_msg_length;
uint8_t subtype;
uint8_t pdu[MAX_PDU_SIZE], i;
uint8_t *cf_pdu, *acf_pdu, *udp_pdu, *can_payload;
frame_t frame;
canid_t can_id;

memset(&frame, 0, sizeof(struct canfd_frame));
res = recv(sk_fd, pdu, MAX_PDU_SIZE, 0);

if (res < 0 || res > MAX_PDU_SIZE) {
perror("Failed to receive data");
return -1;
}

if (use_udp) {
udp_pdu = pdu;
Avtp_Udp_GetField((Avtp_Udp_t *)udp_pdu, AVTP_UDP_FIELD_ENCAPSULATION_SEQ_NO, &udp_seq_num);
udp_seq_num = Avtp_Udp_GetEncapsulationSeqNo((Avtp_Udp_t *)udp_pdu);
cf_pdu = pdu + AVTP_UDP_HEADER_LEN;
proc_bytes += AVTP_UDP_HEADER_LEN;
} else {
cf_pdu = pdu;
}

res = Avtp_CommonHeader_GetField((Avtp_CommonHeader_t*)cf_pdu, AVTP_COMMON_HEADER_FIELD_SUBTYPE, &subtype);
if (res < 0) {
fprintf(stderr, "Failed to get subtype field: %d\n", res);
return -1;
}

subtype = Avtp_CommonHeader_GetSubtype((Avtp_CommonHeader_t*)cf_pdu);
if (!((subtype == AVTP_SUBTYPE_NTSCF) ||
(subtype == AVTP_SUBTYPE_TSCF))) {
fprintf(stderr, "Subtype mismatch: expected %u or %u, got %"PRIu64". Dropping packet\n",
fprintf(stderr, "Subtype mismatch: expected %u or %u, got %"PRIu8". Dropping packet\n",
AVTP_SUBTYPE_NTSCF, AVTP_SUBTYPE_TSCF, subtype);
return -1;
}

if(subtype == AVTP_SUBTYPE_TSCF){
if (subtype == AVTP_SUBTYPE_TSCF){
proc_bytes += AVTP_TSCF_HEADER_LEN;
Avtp_Tscf_GetField((Avtp_Tscf_t*)cf_pdu, AVTP_TSCF_FIELD_STREAM_DATA_LENGTH, (uint64_t *) &msg_length);
}else{
msg_length = Avtp_Tscf_GetStreamDataLength((Avtp_Tscf_t*)cf_pdu);
} else {
proc_bytes += AVTP_NTSCF_HEADER_LEN;
Avtp_Ntscf_GetField((Avtp_Ntscf_t*)cf_pdu, AVTP_NTSCF_FIELD_NTSCF_DATA_LENGTH, (uint64_t *) &msg_length);
msg_length = Avtp_Ntscf_GetNtscfDataLength((Avtp_Ntscf_t*)cf_pdu);
}

while (msg_proc_bytes < msg_length) {
Expand All @@ -231,46 +222,44 @@ static int new_packet(int sk_fd, int can_socket) {
return -1;
}

Avtp_Can_GetField((Avtp_Can_t*)acf_pdu, AVTP_CAN_FIELD_CAN_IDENTIFIER,
&(can_frame_id));
can_id = can_frame_id;
can_id = Avtp_Can_GetCanIdentifier((Avtp_Can_t*)acf_pdu);

can_payload = Avtp_Can_GetPayload((Avtp_Can_t*)acf_pdu, &payload_length, &pdu_length);
msg_proc_bytes += pdu_length*4;
can_payload = Avtp_Can_GetPayload((Avtp_Can_t*)acf_pdu);
acf_msg_length = Avtp_Can_GetAcfMsgLength((Avtp_Can_t*)acf_pdu)*4;
can_payload_length = Avtp_Can_GetCanPayloadLength((Avtp_Can_t*)acf_pdu);
msg_proc_bytes += acf_msg_length;

// Handle EFF Flag
Avtp_Can_GetField((Avtp_Can_t*)acf_pdu, AVTP_CAN_FIELD_EFF, &flag);
if (can_id > 0x7FF && !flag) {
fprintf(stderr, "Error: CAN ID is > 0x7FF but the EFF bit is not set.\n");
return -1;
if (Avtp_Can_GetEff((Avtp_Can_t*)acf_pdu)) {
can_id |= CAN_EFF_FLAG;
} else if (can_id > 0x7FF) {
fprintf(stderr, "Error: CAN ID is > 0x7FF but the EFF bit is not set.\n");
return -1;
}
if (flag) can_id |= CAN_EFF_FLAG;

// Handle RTR Flag
Avtp_Can_GetField((Avtp_Can_t*)acf_pdu, AVTP_CAN_FIELD_RTR, &flag);
if (flag) can_id |= CAN_RTR_FLAG;
if (Avtp_Can_GetRtr((Avtp_Can_t*)acf_pdu)) {
can_id |= CAN_RTR_FLAG;
}

if (can_variant == AVTP_CAN_FD) {

Avtp_Can_GetField((Avtp_Can_t*)acf_pdu, AVTP_CAN_FIELD_BRS, &flag);
if (flag) frame.fd.flags |= CANFD_BRS;

Avtp_Can_GetField((Avtp_Can_t*)acf_pdu, AVTP_CAN_FIELD_FDF, &flag);
if (flag) frame.fd.flags |= CANFD_FDF;

Avtp_Can_GetField((Avtp_Can_t*)acf_pdu, AVTP_CAN_FIELD_ESI, &flag);
if (flag) frame.fd.flags |= CANFD_ESI;

if (Avtp_Can_GetBrs((Avtp_Can_t*)acf_pdu)) {
frame.fd.flags |= CANFD_BRS;
}
if (Avtp_Can_GetFdf((Avtp_Can_t*)acf_pdu)) {
frame.fd.flags |= CANFD_FDF;
}
if (Avtp_Can_GetEsi((Avtp_Can_t*)acf_pdu)) {
frame.fd.flags |= CANFD_ESI;
}
frame.fd.can_id = can_id;
frame.fd.len = payload_length;
memcpy(frame.fd.data, can_payload, payload_length);
frame.fd.len = can_payload_length;
memcpy(frame.fd.data, can_payload, can_payload_length);
res = write(can_socket, &frame.fd, sizeof(struct canfd_frame));

} else {

frame.cc.can_id = can_id;
frame.cc.len = payload_length;
memcpy(frame.cc.data, can_payload, payload_length);
frame.cc.len = can_payload_length;
memcpy(frame.cc.data, can_payload, can_payload_length);
res = write(can_socket, &frame.cc, sizeof(struct can_frame));
}

Expand Down
6 changes: 3 additions & 3 deletions examples/acf-can/acf-can-talker.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,13 @@ static int prepare_acf_packet(uint8_t* acf_pdu,

// Copy payload to ACF CAN PDU
if(can_variant == AVTP_CAN_FD)
processedBytes = Avtp_Can_SetPayload(pdu, frame.fd.can_id & CAN_EFF_MASK, frame.fd.data,
Avtp_Can_CreateAcfMessage(pdu, frame.fd.can_id & CAN_EFF_MASK, frame.fd.data,
frame.fd.len, can_variant);
else
processedBytes = Avtp_Can_SetPayload(pdu, frame.cc.can_id & CAN_EFF_MASK, frame.cc.data,
Avtp_Can_CreateAcfMessage(pdu, frame.cc.can_id & CAN_EFF_MASK, frame.cc.data,
frame.cc.len, can_variant);

return processedBytes;
return Avtp_Can_GetAcfMsgLength(pdu)*4;
}

int main(int argc, char *argv[])
Expand Down
2 changes: 1 addition & 1 deletion examples/crf/crf-listener.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
#include <inttypes.h>

#include "avtp/Crf.h"
#include "avtp/aaf/PcmStream.h"
#include "avtp/aaf/Pcm.h"
#include "common/common.h"
#include "avtp/CommonHeader.h"

Expand Down
Loading

0 comments on commit 5a51e07

Please sign in to comment.