Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve GetField API (breaking changes) #37

Merged
merged 33 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
1aef5af
New API for Avtp_GetField
adriaan-niess Aug 23, 2024
b0ebae0
Update Avtp_GetField
adriaan-niess Aug 23, 2024
f0bac7b
Update CommonHeader.h/c
adriaan-niess Aug 23, 2024
624603e
Update CommonHeader.h/c
adriaan-niess Aug 23, 2024
d197673
Update CommonHeader.h/c and Crf.h/c
adriaan-niess Aug 23, 2024
81a4fe5
Update GetField API
adriaan-niess Aug 23, 2024
a83c1e2
Update GetField API for ACF CAN
adriaan-niess Aug 23, 2024
5d41360
Update GetField API for ACF CAN Brief
adriaan-niess Aug 23, 2024
a79ed6e
Update ACF CAN API
adriaan-niess Aug 23, 2024
271b8b8
Update GetField API for Tscf.h/c
adriaan-niess Aug 24, 2024
4f28c35
Update GetField API for Ntscf.h/c
adriaan-niess Aug 24, 2024
92d42f4
Update GetField API for Udp.h/c
adriaan-niess Aug 25, 2024
78b032e
Update GetField API for Rvf.h/c
adriaan-niess Aug 25, 2024
3577868
Update GetField API for Can.h/c
adriaan-niess Aug 25, 2024
7777a6c
Update GetField API for CanBrief.h/c
adriaan-niess Aug 25, 2024
998e3c0
Update GetField API for AcfCommon.h/c
adriaan-niess Aug 25, 2024
1e224c1
Update GetField API for AcfCommon.h/c and FlexRay.h/c
adriaan-niess Aug 26, 2024
074aa81
Update GetField API for Gpc.h/c
adriaan-niess Aug 26, 2024
ec6bae4
Update GetField API for Lin.h/c
adriaan-niess Aug 26, 2024
0217470
Update GetField API for Most.h/c
adriaan-niess Aug 26, 2024
305ece2
Update GetField API for Sensor.h/c
adriaan-niess Aug 26, 2024
fc27853
Update GetField API for SensorBrief.h/c
adriaan-niess Aug 26, 2024
efc35bf
Update GetField API for Aaf.h/c
adriaan-niess Aug 27, 2024
2936574
Update GetField API for Pcm.h/c
adriaan-niess Aug 27, 2024
b96c221
Update GetField API for Cvf.h/c
adriaan-niess Aug 27, 2024
55c816a
Update GetField API for H264.h/c
adriaan-niess Aug 28, 2024
d793cb3
Update GetField API for Jpeg2000.h/c
adriaan-niess Aug 28, 2024
b78ff98
Update GetField API for Mjpeg.h/c
adriaan-niess Aug 28, 2024
64c4d6d
Update examples and tests to be compliant with new GetField API
adriaan-niess Aug 28, 2024
9a0f74c
Make tests conform to new GetField API
adriaan-niess Aug 28, 2024
ea37bb9
Return and set using enum types for get/set APIs.
nayakned Sep 4, 2024
9561ae2
Reworked CAN SetPayload/GetPayload APIs.
nayakned Sep 4, 2024
6e87eff
Fixed warnings due casting of ptr.
nayakned Sep 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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