-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
215 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,39 @@ | ||
#pragma once | ||
|
||
#include "vlcb/common/can.h" | ||
#include "vlcb/platform/time.h" | ||
#include <stdint.h> | ||
|
||
typedef enum { | ||
VLCB_MEDIUM_CAN, | ||
} VlcbNetMedium; | ||
|
||
typedef enum { | ||
VLCB_NET_WIRE_CAN_STATE_UNINITIALIZED = 0, | ||
VLCB_NET_WIRE_CAN_STATE_ENUMERATING, | ||
VLCB_NET_WIRE_CAN_STATE_INITIALIZED, | ||
VLCB_NET_WIRE_CAN_STATE_RESPONDING, | ||
} VlcbNetWireCanState; | ||
|
||
typedef union { | ||
VlcbCanId can_id; | ||
} VlcbNetHwAddr; | ||
VlcbCanId can; | ||
} VlcbNetWireAddr; | ||
|
||
typedef struct { | ||
union { | ||
struct { | ||
clock_t lastTimestamp; | ||
VlcbNetWireCanState state; | ||
uint8_t occupiedIdCache[16]; | ||
} can; | ||
} meta; | ||
VlcbNetWireAddr addr; | ||
} VlcbNetWireEndpoint; | ||
|
||
typedef VlcbNetWireEndpoint *const VlcbNetWireEndpointHandle; | ||
|
||
bool vlcb_net_IsWireEndpointValid(VlcbNetWireEndpointHandle endpoint); | ||
|
||
bool vlcb_net_IsHwAddrValid(VlcbNetMedium medium, VlcbNetHwAddr addr); | ||
bool vlcb_net_IsWireAddrValid(VlcbNetMedium medium, VlcbNetWireAddr addr); | ||
|
||
VlcbNetHwAddr vlcb_net_NewCanIdHwAddr(VlcbCanId id); | ||
VlcbNetWireAddr vlcb_net_NewCanWireAddr(VlcbCanId id); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
#include "vlcb/common/can.h" | ||
#include "vlcb/net/adapter.h" | ||
#include "vlcb/net/addr.h" | ||
#include "vlcb/net/iface.h" | ||
#include "vlcb/platform/interface.h" | ||
#include "vlcb/platform/time.h" | ||
#include <stdint.h> | ||
|
||
typedef struct { | ||
enum { CAN_PKT_INGEST } type; | ||
union { | ||
struct { | ||
const VlcbNetAdptPkt *const pkt; | ||
} ingest; | ||
} data; | ||
} CanSvcEvent; | ||
|
||
static inline VlcbCanId ResolveFreeId(const uint8_t (*const idCache)[16]) { | ||
for (uint8_t i = 0; i < 16; i++) { | ||
for (uint8_t j = 0; j < 8 && (i * 8 + j) < 128; j++) { | ||
if (!(*idCache[i] & ((uint8_t)(1 << j)))) { | ||
return i * 8 + j; | ||
} // TODO: fix these two fnctions | ||
} | ||
} | ||
return VLCB_CAN_ID_EMPTY; | ||
} | ||
|
||
static inline void ToggleUsedId(uint8_t (*const idCache)[16], VlcbCanId id) {} | ||
|
||
inline void CanSvcEventConsume(VlcbNetWireEndpointHandle endpoint, | ||
CanSvcEvent event) { | ||
switch (event.type) { | ||
case CAN_PKT_INGEST: | ||
if (endpoint->meta.can.state == VLCB_NET_WIRE_CAN_STATE_INITIALIZED) { | ||
if (endpoint->addr.can == event.data.ingest.pkt->srcAddr.can) { | ||
// handle collisions | ||
endpoint->meta.can.state = VLCB_NET_WIRE_CAN_STATE_UNINITIALIZED; | ||
endpoint->addr.can = VLCB_CAN_ID_EMPTY; | ||
} else if (event.data.ingest.pkt->meta.can.is_rtr) { | ||
// handle response to enumeration of other nodes | ||
endpoint->meta.can.state = VLCB_NET_WIRE_CAN_STATE_RESPONDING; | ||
} | ||
} else if (endpoint->meta.can.state == | ||
VLCB_NET_WIRE_CAN_STATE_ENUMERATING) { | ||
// handle enumeration | ||
ToggleUsedId(&endpoint->meta.can.occupiedIdCache, | ||
event.data.ingest.pkt->srcAddr.can); | ||
} | ||
break; | ||
} | ||
} | ||
|
||
inline void CanSvcProcess(VlcbNetIface *const iface, | ||
VlcbNetWireEndpointHandle endpoint, clock_t now) { | ||
VlcbNetAdptPkt pkt; | ||
VlcbNetAdptErr err; | ||
switch (endpoint->meta.can.state) { | ||
case VLCB_NET_WIRE_CAN_STATE_UNINITIALIZED:; | ||
pkt = (VlcbNetAdptPkt){ | ||
.medium = VLCB_MEDIUM_CAN, | ||
.srcAddr = {.can = VLCB_CAN_ID_EMPTY}, | ||
.payloadLen = 0, | ||
.meta = {.can = {.prio = VLCB_CAN_PRIO_SELF_ENUM, .is_rtr = true}}}; | ||
err = _INTERFACE_PTR_CALL(iface->adpt, SendPkt, &pkt); | ||
if (err != VLCB_NET_ADPT_ERR_OK) { | ||
if (err == VLCB_NET_ADPT_ERR_WOULD_BLOCK) { | ||
break; | ||
} | ||
// TODO: log error | ||
} | ||
endpoint->meta.can.state = VLCB_NET_WIRE_CAN_STATE_ENUMERATING; | ||
endpoint->meta.can.lastTimestamp = now; | ||
break; | ||
case VLCB_NET_WIRE_CAN_STATE_ENUMERATING: | ||
if (vlcb_platform_time_DiffInMs(endpoint->meta.can.lastTimestamp, now) > | ||
100) { | ||
endpoint->meta.can.state = VLCB_NET_WIRE_CAN_STATE_INITIALIZED; | ||
VlcbCanId newId = ResolveFreeId(&endpoint->meta.can.occupiedIdCache); | ||
ToggleUsedId(&endpoint->meta.can.occupiedIdCache, newId); | ||
endpoint->addr.can = newId; | ||
} | ||
break; | ||
case VLCB_NET_WIRE_CAN_STATE_RESPONDING:; | ||
pkt = (VlcbNetAdptPkt){ | ||
.medium = VLCB_MEDIUM_CAN, | ||
.srcAddr = endpoint->addr, | ||
.payloadLen = 0, | ||
.meta = {.can = {.prio = VLCB_CAN_PRIO_SELF_ENUM, .is_rtr = true}}}; | ||
err = _INTERFACE_PTR_CALL(iface->adpt, SendPkt, &pkt); | ||
if (err != VLCB_NET_ADPT_ERR_OK) { | ||
if (err == VLCB_NET_ADPT_ERR_WOULD_BLOCK) { | ||
break; | ||
} | ||
// TODO: log error | ||
} | ||
endpoint->meta.can.state = VLCB_NET_WIRE_CAN_STATE_INITIALIZED; | ||
break; | ||
default: | ||
break; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters