implicit type conversions fixed
This commit is contained in:
parent
e4d27454cd
commit
0add109430
@ -15,6 +15,11 @@ typedef struct ConnBlock_ {
|
||||
PcktSieveLayer * sieveLayer; ///< Sieve layer
|
||||
} ConnBlock;
|
||||
|
||||
typedef struct ConstConnBlock_ {
|
||||
const PcktSieve * sieve; ///< Ethernet interface
|
||||
const PcktSieveLayer * sieveLayer; ///< Sieve layer
|
||||
} ConstConnBlock;
|
||||
|
||||
/**
|
||||
* Initialize non-mandatory fields to default values.
|
||||
* @param connb
|
||||
|
4
dynmem.c
4
dynmem.c
@ -17,6 +17,6 @@ void * dynmem_alloc_(uint32_t size) {
|
||||
return mp_alloc(E.mp, size);
|
||||
}
|
||||
|
||||
void dynmem_free_(void * ptr) {
|
||||
mp_free(E.mp, ptr);
|
||||
void dynmem_free_(const void * ptr) {
|
||||
mp_free(E.mp, (const uint8_t *)ptr);
|
||||
}
|
||||
|
8
dynmem.h
8
dynmem.h
@ -1,5 +1,5 @@
|
||||
#ifndef ETHERLIB_DYNMEM_H
|
||||
#define ETHERLIB_DYNMEM_H
|
||||
#ifndef CORE_ETHERLIB_DYNMEM
|
||||
#define CORE_ETHERLIB_DYNMEM
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@ -37,7 +37,7 @@ void * dynmem_alloc_(uint32_t size);
|
||||
* Release allocated block.
|
||||
* @param ptr pointer to allocated area
|
||||
*/
|
||||
void dynmem_free_(void * ptr);
|
||||
void dynmem_free_(const void * ptr);
|
||||
|
||||
#ifdef DYNMEM_DEBUG
|
||||
#define dynmem_free(ptr) MSG("FREE: %s() in %s:%d\n", __FUNCTION__, __FILE__, __LINE__), dynmem_free_(ptr)
|
||||
@ -45,6 +45,6 @@ void dynmem_free_(void * ptr);
|
||||
#define dynmem_free(p) free(p)
|
||||
#else
|
||||
#define dynmem_free(ptr) dynmem_free_(ptr)
|
||||
#endif
|
||||
#endif /* CORE_ETHERLIB_DYNMEM */
|
||||
|
||||
#endif //ETHERLIB_DYNMEM_H
|
||||
|
@ -19,7 +19,17 @@ static int ethintf_llrxnotify(EthIODef * io) {
|
||||
}
|
||||
|
||||
static int ethinf_lllinkchg(EthIODef * io, int ls) {
|
||||
ethinf_set_link_state((EthInterface *) io->tag, ls);
|
||||
EthInterface * intf = (EthInterface *) io->tag;
|
||||
ethinf_set_link_state(intf, ls);
|
||||
|
||||
if (intf->dhcp != NULL) {
|
||||
if (ls) { // if link is on
|
||||
dhcp_start(intf->dhcp);
|
||||
} else { // if link is off
|
||||
dhcp_stop(intf->dhcp);
|
||||
}
|
||||
}
|
||||
|
||||
MSG("Link state: %d\n", ls);
|
||||
return 0;
|
||||
}
|
||||
@ -32,7 +42,7 @@ static void ethintf_register(EthInterface * intf) {
|
||||
}
|
||||
|
||||
// interface processing thread
|
||||
static void * ethinf_proc_thread(void * param);
|
||||
static void task_ethinf(const void * param);
|
||||
|
||||
EthInterface *ethintf_new(EthIODef * io) {
|
||||
EthInterface * ethIntf = (EthInterface *)dynmem_alloc(sizeof(EthInterface));
|
||||
@ -49,8 +59,8 @@ EthInterface *ethintf_new(EthIODef * io) {
|
||||
ethIntf->txQ = mq_create(ETHLIB_DEF_MQ_SIZE);
|
||||
ethIntf->rxQ = mq_create(ETHLIB_DEF_MQ_SIZE);
|
||||
ETHLIB_OS_SEM_CREATE(ðIntf->rxSem, ETHLIB_DEF_MQ_SIZE);
|
||||
ETHLIB_OS_THREAD_DEFINE(ethinf_proc_thread, ethrx, osPriorityHigh, 4096, ethIntf);
|
||||
ETHLIB_OS_THREAD_CREATE(ethrx, ethIntf);
|
||||
ETHLIB_OS_THREAD_DEFINE(task_ethinf, osPriorityHigh, 512, ethIntf);
|
||||
ETHLIB_OS_THREAD_CREATE(task_ethinf, ethIntf);
|
||||
|
||||
ethIntf->ipra = ipra_new();
|
||||
|
||||
@ -65,7 +75,7 @@ EthInterface *ethintf_new(EthIODef * io) {
|
||||
return ethIntf;
|
||||
}
|
||||
|
||||
static void * ethinf_proc_thread(void * param) {
|
||||
static void task_ethinf(const void * param) {
|
||||
EthInterface * intf = (EthInterface *) param;
|
||||
while (true) {
|
||||
ETHLIB_OS_SEM_WAIT(&intf->rxSem);
|
||||
@ -76,7 +86,6 @@ static void * ethinf_proc_thread(void * param) {
|
||||
packsieve_input(&intf->sieve, &rawPckt);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ethinf_receive(EthInterface *intf, const RawPckt *rawPckt) {
|
||||
|
12
packet.h
12
packet.h
@ -34,10 +34,20 @@ typedef struct {
|
||||
uint64_t time_s; ///< Timestamp seconds part
|
||||
uint32_t time_ns; ///< Timestamp nanoseconds part.
|
||||
struct PcktHeaderElement_ * header; ///< Pointer to packet header. Points to the innermost header
|
||||
uint8_t * payload; ///< Pointer to (innermost) payload.
|
||||
const uint8_t * payload; ///< Pointer to (innermost) payload.
|
||||
uint16_t headerSize; ///< Packet header size in bytes.
|
||||
uint16_t payloadSize; ///< Payload size in bytes.
|
||||
//uint16_t type; ///< Packet class indicator (e.g. UDP, TCP, IPv4 etc.)
|
||||
} Pckt;
|
||||
|
||||
// typedef struct {
|
||||
// uint64_t time_s; ///< Timestamp seconds part
|
||||
// uint32_t time_ns; ///< Timestamp nanoseconds part.
|
||||
// struct PcktHeaderElement_ * header; ///< Pointer to packet header. Points to the innermost header
|
||||
// const uint8_t * payload; ///< Pointer to (innermost) payload.
|
||||
// uint16_t headerSize; ///< Packet header size in bytes.
|
||||
// uint16_t payloadSize; ///< Payload size in bytes.
|
||||
// //uint16_t type; ///< Packet class indicator (e.g. UDP, TCP, IPv4 etc.)
|
||||
// } ConstPckt;
|
||||
|
||||
#endif //ETHERLIB_PACKET_H
|
||||
|
@ -41,10 +41,10 @@ void packreg_add_class(PcktRegistry * packReg, const PcktClassDesc * classDesc)
|
||||
packReg->entCnt++;
|
||||
}
|
||||
|
||||
PcktClassDesc * packreg_get_by_class(const PcktRegistry * packReg, uint16_t ownClass, uint16_t containerClass) {
|
||||
PcktClassDesc * packreg_get_by_class(PcktRegistry * packReg, uint16_t ownClass, uint16_t containerClass) {
|
||||
uint32_t i;
|
||||
for (i = 0; i < packReg->entCnt; i++) {
|
||||
const PcktClassDesc * cdesc = packReg->ents + i;
|
||||
PcktClassDesc * cdesc = packReg->ents + i;
|
||||
if ((cdesc->class == ownClass) && ((cdesc->containerClass == containerClass) || (containerClass == 0))) {
|
||||
return cdesc;
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ void packreg_add_class(PcktRegistry *packReg, const PcktClassDesc *classDesc);
|
||||
* @param containerClass container packet's class (if 0, then search by container class is not considered)
|
||||
* @return pointer to descriptor on success or NULL on failure
|
||||
*/
|
||||
PcktClassDesc *packreg_get_by_class(const PcktRegistry *packReg, uint16_t ownClass, uint16_t containerClass);
|
||||
PcktClassDesc *packreg_get_by_class(PcktRegistry *packReg, uint16_t ownClass, uint16_t containerClass);
|
||||
|
||||
|
||||
|
||||
|
@ -119,11 +119,11 @@ void packsieve_input(PcktSieve *sieve, const RawPckt *rawPckt) {
|
||||
packet.time_ns = rawPckt->ext.rx.time_ns;
|
||||
|
||||
// lookup headers in the sieve
|
||||
const PcktHeaderElement *headerIter = outermostHeader;
|
||||
PcktHeaderElement *headerIter = outermostHeader;
|
||||
PcktSieveLayer *layer = &sieve->layer0; // innermost matched sieve layer
|
||||
bool found = true; // first structure is always an Ethernet-frame
|
||||
while (found && headerIter) {
|
||||
const PcktSieveLayer *nodeIter = layer->nodes;
|
||||
PcktSieveLayer *nodeIter = layer->nodes;
|
||||
found = false;
|
||||
while (nodeIter && !found) {
|
||||
found |= nodeIter->matchAny || nodeIter->filtFn(&nodeIter->filtCond, &headerIter->props, &headerIter->next->props, sieve->intf); // specific or general match
|
||||
@ -139,7 +139,7 @@ void packsieve_input(PcktSieve *sieve, const RawPckt *rawPckt) {
|
||||
packet.payload = data + offset;
|
||||
packet.headerSize = offset;
|
||||
packet.payloadSize = size - offset;
|
||||
int action = layer->cbFn(&packet, layer->tag);
|
||||
int action = layer->cbFn((Pckt *)&packet, layer->tag); // FIXME!
|
||||
|
||||
// execute special return action
|
||||
switch (action) {
|
||||
@ -233,7 +233,7 @@ PcktSieveLayer* packsieve_new_layer(PcktSieveLayer *parent, const PcktSieveFilte
|
||||
}
|
||||
}
|
||||
|
||||
bool packsieve_remove_layer(PcktSieveLayer *layer) {
|
||||
bool packsieve_remove_layer(const PcktSieveLayer *layer) {
|
||||
// avoid NULL-operations
|
||||
if (layer == NULL) {
|
||||
return true;
|
||||
@ -271,8 +271,8 @@ bool packsieve_remove_layer(PcktSieveLayer *layer) {
|
||||
void packsieve_report(const PcktSieve *sieve, const PcktSieveLayer *layer, uint32_t indent) {
|
||||
if (layer->connBReportFn != NULL) {
|
||||
INFO("%*c└─┤", indent, ' ');
|
||||
ConnBlock connBlock = { sieve, layer }; // tag not required
|
||||
layer->connBReportFn(&connBlock);
|
||||
ConstConnBlock connBlock = { sieve, layer }; // tag not required
|
||||
layer->connBReportFn((const ConnBlock *)&connBlock);
|
||||
INFO("├───\n");
|
||||
} else {
|
||||
INFO("%*c└─┤%d├───\n", indent, ' ', layer->packetClass);
|
||||
@ -288,8 +288,8 @@ void packsieve_layer_info(const PcktSieve *sieve, const PcktSieveLayer *layer) {
|
||||
const PcktSieveLayer *iter = layer;
|
||||
while (iter != NULL) { // climb up to the top in the sieve tree
|
||||
if (iter->connBReportFn != NULL) {
|
||||
ConnBlock connBlock = { sieve, iter }; // tag not required
|
||||
iter->connBReportFn(&connBlock);
|
||||
ConstConnBlock connBlock = { sieve, iter }; // tag not required
|
||||
iter->connBReportFn((const ConnBlock *)&connBlock);
|
||||
} else {
|
||||
INFO("[%d]", layer->packetClass);
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ PcktSieveLayer *packsieve_new_layer(PcktSieveLayer *parent, const PcktSieveFilte
|
||||
* Remove sieve layer from packet sieve.
|
||||
* @param layer Layer to remove and deallocate
|
||||
*/
|
||||
bool packsieve_remove_layer(PcktSieveLayer *layer);
|
||||
bool packsieve_remove_layer(const PcktSieveLayer *layer);
|
||||
|
||||
/**
|
||||
* Recursively report layer structure on terminal.
|
||||
|
@ -47,7 +47,11 @@ void arp_send(const ConnBlock * connBlock, const ArpProps * props) {
|
||||
|
||||
// Ethernet
|
||||
ethProps->length_type = ETH_ARP_PACKET_CLASS;
|
||||
memset(ethProps->destAddr, 0xFF, ETH_HW_ADDR_LEN); // broadcast destination
|
||||
if (arpProps->OPER == ARPOP_REP) { // respond in unicast
|
||||
memcpy(ethProps->destAddr, arpProps->THA, ETH_HW_ADDR_LEN); // unicast destination
|
||||
} else if(arpProps->OPER == ARPOP_REQ) { // request in broadcast
|
||||
memset(ethProps->destAddr, 0xFF, ETH_HW_ADDR_LEN); // broadcast destination
|
||||
}
|
||||
memcpy(ethProps->sourceAddr, connBlock->sieve->intf->mac, ETH_HW_ADDR_LEN); // source
|
||||
|
||||
// allocate transmit buffer
|
||||
|
@ -43,7 +43,7 @@ int cet_send(cbd d, uint8_t *dest, const uint8_t *data, uint16_t size) {
|
||||
return cet_send_arg(d, dest, data, size, 0);
|
||||
}
|
||||
|
||||
int cet_send_arg(cbd d, uint8_t *dest, const uint8_t *data, uint16_t size, uint32_t arg) {
|
||||
int cet_send_arg(cbd d, const uint8_t *dest, const uint8_t *data, uint16_t size, uint32_t arg) {
|
||||
ConnBlock connBlock;
|
||||
if (!cbdt_get_connection_block(E.cbdt, d, &connBlock)) {
|
||||
ERROR("Invalid CBD descriptor: '%d'!\n", d);
|
||||
|
@ -12,7 +12,7 @@ struct EthInterface_;
|
||||
|
||||
cbd cet_new_connblock(struct EthInterface_ * intf, uint16_t etherType, SieveCallBackFn cbFn);
|
||||
|
||||
int cet_send_arg(cbd d, uint8_t *dest, const uint8_t *data, uint16_t size, uint32_t arg);
|
||||
int cet_send_arg(cbd d, const uint8_t *dest, const uint8_t *data, uint16_t size, uint32_t arg);
|
||||
|
||||
int cet_send(cbd d, EthernetAddress dest, const uint8_t * data, uint16_t size);
|
||||
|
||||
|
@ -53,6 +53,7 @@ static int icmp_recv_cb(const Pckt * pckt, PcktSieveLayerTag tag) {
|
||||
*txIcmpProps = *icmpProps;
|
||||
txIcmpProps->type = ICMP_MT_ECHO_REPLY; // replace request with reply
|
||||
txIcmpProps->hdrInsFn = insert_icmp_header;
|
||||
txIcmpProps->checksum = 0;
|
||||
|
||||
// swap source an destination IP addresses
|
||||
IPv4Props * iPv4Props = HEADER_FETCH_PROPS(IPv4Props, pckt->header->prev);
|
||||
|
@ -2,13 +2,13 @@
|
||||
// Created by epagris on 2022.12.09..
|
||||
//
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "dhcp.h"
|
||||
#include "../../dynmem.h"
|
||||
#include "../../utils.h"
|
||||
#include "../../connection_block.h"
|
||||
#include "../conn_blocks/udp_connblock.h"
|
||||
#include "../../dynmem.h"
|
||||
#include "../../global_state.h"
|
||||
#include "../../utils.h"
|
||||
#include "../conn_blocks/udp_connblock.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
static const uint8_t DHCP_MAGIC_COOKIE[] = {99, 130, 83, 99};
|
||||
|
||||
@ -47,9 +47,9 @@ typedef enum {
|
||||
|
||||
// DHCP options
|
||||
typedef struct DhcpOption_ {
|
||||
uint8_t id; ///< Options
|
||||
uint8_t length; ///< Option data length
|
||||
struct DhcpOption_ *next; /// next DHCP option
|
||||
uint8_t id; ///< Options
|
||||
uint8_t length; ///< Option data length
|
||||
struct DhcpOption_ *next; /// next DHCP option
|
||||
uint8_t value[MAX_DHCP_OPTION_LENGTH]; ///< Option value
|
||||
} DhcpOption;
|
||||
|
||||
@ -115,9 +115,9 @@ static const DhcpOption *dhcp_get_option(const DhcpOption *opts, DhcpOptionId id
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void dhcp_send(DhcpState * s, const DhcpProps *props, const DhcpOption *opts) {
|
||||
static void dhcp_send(DhcpState *s, const DhcpProps *props, const DhcpOption *opts) {
|
||||
// construct body
|
||||
uint8_t *buf = (uint8_t *) s->buf;
|
||||
uint8_t *buf = (uint8_t *)s->buf;
|
||||
memset(buf, 0, DHCP_MIN_PACKET_SIZE);
|
||||
FILL_BYTE_ADVANCE(buf, &(props->op));
|
||||
FILL_BYTE_ADVANCE(buf, &(props->htype));
|
||||
@ -141,9 +141,9 @@ static void dhcp_send(DhcpState * s, const DhcpProps *props, const DhcpOption *o
|
||||
iter = iter->next;
|
||||
}
|
||||
|
||||
// dhcp_option_insert_msg_type(&buf, DHCPDISCOVER);
|
||||
// dhcp_option_insert_max_msg_size(&buf, 1500);
|
||||
// dhcp_option_insert_end(&buf);
|
||||
// dhcp_option_insert_msg_type(&buf, DHCPDISCOVER);
|
||||
// dhcp_option_insert_max_msg_size(&buf, 1500);
|
||||
// dhcp_option_insert_end(&buf);
|
||||
|
||||
// send packet
|
||||
udp_sendto(s->desc, s->buf, DHCP_MIN_PACKET_SIZE, IPv4_ANY_ADDR, DHCP_SERVER_PORT);
|
||||
@ -179,15 +179,14 @@ static void dhcp_parse(const uint8_t *buf, DhcpProps *props, DhcpOption **opts)
|
||||
dhcp_read_next_option(&buf, iter);
|
||||
iter->next = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define UINT16_TO_BE_BYTES(u) ((u) >> 8) & 0xFF, ((u) & 0xFF),
|
||||
#define UINT32_TO_BE_BYTES(u) ((u) >> 24) & 0xFF, ((u) >> 16) & 0xFF, ((u) >> 8) & 0xFF, ((u) & 0xFF),
|
||||
#define IPv4_ADDR_TO_BE_BYTES(addr) ((addr) & 0xFF), (((addr) >> 8) & 0xFF), (((addr) >> 16) & 0xFF), (((addr) >> 24) & 0xFF),
|
||||
#define UINT16_TO_BE_BYTES(u) (uint8_t)((u) >> 8) & 0xFF, (uint8_t)((u) & 0xFF),
|
||||
#define UINT32_TO_BE_BYTES(u) (uint8_t)((u) >> 24) & 0xFF, (uint8_t)((u) >> 16) & 0xFF, (uint8_t)((u) >> 8) & 0xFF, (uint8_t)((u) & 0xFF),
|
||||
#define IPv4_ADDR_TO_BE_BYTES(addr) (uint8_t)((addr) & 0xFF), (uint8_t)(((addr) >> 8) & 0xFF), (uint8_t)(((addr) >> 16) & 0xFF), (uint8_t)(((addr) >> 24) & 0xFF),
|
||||
#define HWADDR_TO_BE_BYTES(hwa) (hwa)[0], (hwa)[1], (hwa)[2], (hwa)[3], (hwa)[4], (hwa)[5],
|
||||
|
||||
static void dhcp_discover(DhcpState * s) {
|
||||
static void dhcp_discover(DhcpState *s) {
|
||||
s->tranId = rand();
|
||||
DhcpProps props = {0};
|
||||
|
||||
@ -213,7 +212,7 @@ static void dhcp_discover(DhcpState * s) {
|
||||
dhcp_send(s, &props, &msgType);
|
||||
}
|
||||
|
||||
void dhcp_request(DhcpState * s, ip4_addr reqAddr, ip4_addr dhcpServerAddr) {
|
||||
void dhcp_request(DhcpState *s, ip4_addr reqAddr, ip4_addr dhcpServerAddr) {
|
||||
DhcpProps props = {0};
|
||||
|
||||
props.op = DHCP_BOOTREQUEST;
|
||||
@ -243,18 +242,31 @@ void dhcp_request(DhcpState * s, ip4_addr reqAddr, ip4_addr dhcpServerAddr) {
|
||||
dhcp_send(s, &props, &msgType);
|
||||
}
|
||||
|
||||
static void dhcp_process(DhcpState * s, DhcpProps *props, DhcpOption *opts) {
|
||||
static void dhcp_retry_discover(struct Timer_ *timer, AlarmUserData user) {
|
||||
DhcpState *s = (DhcpState *)user.ptr;
|
||||
if (s->state != DHCP_BOUND) { // only retransmit DISCOVER if not BOUND
|
||||
dhcp_start(s);
|
||||
}
|
||||
s->retryAlarmId = 0; // clear schedule ID
|
||||
}
|
||||
|
||||
static void dhcp_process(DhcpState *s, DhcpProps *props, DhcpOption *opts) {
|
||||
ETHLIB_OS_MTX_LOCK(&s->procMtx); // LOCK!
|
||||
|
||||
switch (s->state) {
|
||||
case DHCP_INIT:
|
||||
case DHCP_INIT: {
|
||||
dhcp_discover(s); // send discover message
|
||||
s->state = DHCP_SELECTING;
|
||||
break;
|
||||
|
||||
// schedule the DHCP discovery retry
|
||||
AlarmUserData params;
|
||||
params.ptr = (void *)s;
|
||||
s->retryAlarmId = timer_sched_rel(E.tmr, ((int64_t)DHCP_RETRY_TIMEOUT_S) * 1000000, dhcp_retry_discover, params);
|
||||
} break;
|
||||
case DHCP_SELECTING: {
|
||||
const DhcpOption *msgType = dhcp_get_option(opts, DHCP_OPT_MsgType);
|
||||
if (msgType->value[0] == DHCPOFFER) {
|
||||
const DhcpOption * serverIdentifier = dhcp_get_option(opts, DHCP_OPT_ServerId);
|
||||
const DhcpOption *serverIdentifier = dhcp_get_option(opts, DHCP_OPT_ServerId);
|
||||
if (serverIdentifier != NULL) {
|
||||
ip4_addr serverAddr;
|
||||
FETCH_DWORD(&serverAddr, serverIdentifier->value);
|
||||
@ -264,14 +276,13 @@ static void dhcp_process(DhcpState * s, DhcpProps *props, DhcpOption *opts) {
|
||||
|
||||
s->state = DHCP_REQUESTING;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case DHCP_REQUESTING: {
|
||||
const DhcpOption *opt = dhcp_get_option(opts, DHCP_OPT_MsgType);
|
||||
uint8_t msgType = opt->value[0];
|
||||
if (msgType == DHCPNAK) {
|
||||
//dhcp_discover();
|
||||
//s.state = DHCP_SELECTING;
|
||||
// dhcp_discover();
|
||||
// s.state = DHCP_SELECTING;
|
||||
} else if (msgType == DHCPACK) {
|
||||
s->intf->ip = props->yiaddr; // fetch ip address
|
||||
|
||||
@ -289,7 +300,7 @@ static void dhcp_process(DhcpState * s, DhcpProps *props, DhcpOption *opts) {
|
||||
FETCH_DWORD_H2N(&dhcpLeaseTime_s, opt->value);
|
||||
|
||||
AlarmUserData params = {0};
|
||||
timer_sched_rel(E.tmr, ((int64_t) dhcpLeaseTime_s) * 1000000, NULL, params);
|
||||
s->renewAlarmId = timer_sched_rel(E.tmr, ((int64_t)dhcpLeaseTime_s) * 1000000, NULL, params);
|
||||
|
||||
MSG("DHCP done!\n");
|
||||
MSG("IP: ");
|
||||
@ -308,8 +319,7 @@ static void dhcp_process(DhcpState * s, DhcpProps *props, DhcpOption *opts) {
|
||||
// call event callback
|
||||
ethinf_trigger_event(s->intf, ETH_EVT_IP_CHANGE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -322,7 +332,7 @@ static int dhcp_resp_cb(const Pckt *pckt, PcktSieveLayerTag tag) {
|
||||
DhcpOption *opts = NULL;
|
||||
dhcp_parse(pckt->payload, &props, &opts);
|
||||
|
||||
DhcpState * s = (DhcpState *) tag.p;
|
||||
DhcpState *s = (DhcpState *)tag.p;
|
||||
dhcp_process(s, &props, opts);
|
||||
|
||||
dhcp_free_opt_chain(opts);
|
||||
@ -330,22 +340,47 @@ static int dhcp_resp_cb(const Pckt *pckt, PcktSieveLayerTag tag) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dhcp_start(DhcpState * s) {
|
||||
void dhcp_start(DhcpState *s) {
|
||||
s->state = DHCP_INIT;
|
||||
dhcp_process(s, NULL, NULL);
|
||||
}
|
||||
|
||||
void dhcp_stop(DhcpState *s) {
|
||||
s->state = DHCP_STOPPED;
|
||||
if (s->renewAlarmId != 0) { // unschedule renew alarm
|
||||
timer_unsched(E.tmr, s->renewAlarmId);
|
||||
s->renewAlarmId = 0;
|
||||
}
|
||||
|
||||
if (s->retryAlarmId != 0) { // unschedule discovery retry alarm
|
||||
timer_unsched(E.tmr, s->retryAlarmId);
|
||||
s->retryAlarmId = 0;
|
||||
}
|
||||
|
||||
// if it was an IP assigned to the interface, then clear that too
|
||||
if (s->intf->ip != 0) {
|
||||
s->intf->ip = 0;
|
||||
s->intf->dns = 0;
|
||||
s->intf->netmask = 0;
|
||||
s->intf->router = 0;
|
||||
ethinf_trigger_event(s->intf, ETH_EVT_IP_CHANGE);
|
||||
}
|
||||
|
||||
ETHLIB_OS_MTX_UNLOCK(&s->procMtx);
|
||||
}
|
||||
|
||||
void dhcp_initiate(EthInterface *intf) {
|
||||
DhcpState * s = (DhcpState *) dynmem_alloc(sizeof(DhcpState));
|
||||
DhcpState *s = (DhcpState *)dynmem_alloc(sizeof(DhcpState));
|
||||
|
||||
ETHLIB_OS_MTX_CREATE(&s->procMtx);
|
||||
s->state = DHCP_INIT;
|
||||
s->state = DHCP_STOPPED;
|
||||
s->buf = dynmem_alloc(DHCP_MIN_PACKET_SIZE);
|
||||
s->desc = udp_new_connblock(intf, IPv4_ANY_ADDR, DHCP_CLIENT_PORT, dhcp_resp_cb);
|
||||
PcktSieveLayerTag tag; // store pointer to DHCP state into UDP connection block tag
|
||||
tag.p = (void *)s;
|
||||
cbdt_set_tag(E.cbdt, s->desc, tag);
|
||||
s->intf = intf;
|
||||
s->renewAlarmId = 0;
|
||||
|
||||
intf->dhcp = s;
|
||||
}
|
||||
|
@ -34,7 +34,8 @@ typedef enum {
|
||||
DHCP_SELECTING,
|
||||
DHCP_REBINDING,
|
||||
DHCP_BOUND,
|
||||
DHCP_RENEWING
|
||||
DHCP_RENEWING,
|
||||
DHCP_STOPPED,
|
||||
} DhcpFSMState;
|
||||
|
||||
/**
|
||||
@ -58,8 +59,12 @@ typedef struct {
|
||||
uint32_t tranId; ///< Transaction ID
|
||||
struct EthInterface_ *intf; ///< Pointer to corresponding Ethernet interface
|
||||
ETHLIB_OS_MTX_TYPE procMtx; ///< Mutex protecting the state machine
|
||||
uint32_t renewAlarmId; ///< IP renew alarm ID (valid if nonzero)
|
||||
uint32_t retryAlarmId; ///< DISCOVER retry alarm ID (valid if nonzero)
|
||||
} DhcpState;
|
||||
|
||||
#define DHCP_RETRY_TIMEOUT_S (3)
|
||||
|
||||
/**
|
||||
* Initiate DHCP on interface
|
||||
* @param intf interface
|
||||
@ -72,4 +77,10 @@ void dhcp_initiate(struct EthInterface_ * intf);
|
||||
*/
|
||||
void dhcp_start(DhcpState * s);
|
||||
|
||||
/**
|
||||
* Stop DHCP operation.
|
||||
* @param s pointer to DhcpState structure
|
||||
*/
|
||||
void dhcp_stop(DhcpState * s);
|
||||
|
||||
#endif //ETHERLIB_DHCP_H
|
||||
|
@ -37,9 +37,9 @@ void insert_icmp_header(uint8_t *hdr, const PcktHeaderElement *headers, struct E
|
||||
FILL_ADVANCE(hdr, &icmpProps->identifier, 2);
|
||||
FILL_ADVANCE(hdr, &icmpProps->sequenceNumber, 2);
|
||||
|
||||
IPv4Props * ipProps = HEADER_FETCH_PROPS(IPv4Props, headers->prev);
|
||||
/*IPv4Props * ipProps = HEADER_FETCH_PROPS(IPv4Props, headers->prev);
|
||||
icmpProps->checksum = chksum(hdrStart, ipProps->TotalLength - ETH_IPv4_HEADER_SIZE, false);
|
||||
FILL_WORD_ADVANCE(ChkSumPtr, icmpProps->checksum);
|
||||
FILL_WORD_ADVANCE(ChkSumPtr, icmpProps->checksum);*/
|
||||
}
|
||||
|
||||
|
||||
|
59
timer.c
59
timer.c
@ -2,28 +2,30 @@
|
||||
// Created by epagris on 2022.12.21..
|
||||
//
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "timer.h"
|
||||
#include "dynmem.h"
|
||||
#include "utils.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
int64_t time_to_us(const TimePoint * t) {
|
||||
// FIXME nagyon bugos vagyok! Help me! :)
|
||||
|
||||
int64_t time_to_us(const TimePoint *t) {
|
||||
return (int64_t)t->s * 1000000 + (int64_t)t->us;
|
||||
}
|
||||
|
||||
void time_from_us(TimePoint * t, int64_t us) {
|
||||
void time_from_us(TimePoint *t, int64_t us) {
|
||||
t->s = us / 1000000;
|
||||
t->us = us - ((int64_t)t->s * 1000000);
|
||||
}
|
||||
|
||||
void time_add_us(TimePoint * t, int64_t us) {
|
||||
void time_add_us(TimePoint *t, int64_t us) {
|
||||
time_from_us(t, time_to_us(t) + us);
|
||||
}
|
||||
|
||||
// ------------------------------
|
||||
|
||||
Timer *timer_new(uint32_t maxSched) {
|
||||
Timer * tmr = (Timer *) dynmem_alloc(sizeof(Timer) + maxSched * sizeof(AlarmAssignment));
|
||||
Timer *tmr = (Timer *)dynmem_alloc(sizeof(Timer) + maxSched * sizeof(AlarmAssignment));
|
||||
ASSERT_NULL(tmr);
|
||||
|
||||
ETHLIB_OS_MTX_CREATE(&tmr->tabMtx);
|
||||
@ -37,26 +39,27 @@ Timer *timer_new(uint32_t maxSched) {
|
||||
return tmr;
|
||||
}
|
||||
|
||||
static AlarmAssignment * timer_get_alarm_by_id(Timer * tmr, uint32_t id) {
|
||||
AlarmAssignment * slot = NULL;
|
||||
for (uint32_t i = 0; (i < tmr->maxSched) && (slot == NULL); i++) {
|
||||
static AlarmAssignment *timer_get_alarm_by_id(Timer *tmr, uint32_t id) {
|
||||
AlarmAssignment *slot = NULL;
|
||||
for (uint32_t i = 0; i < tmr->maxSched; i++) {
|
||||
if (tmr->alarms[i].id == id) {
|
||||
slot = (tmr->alarms) + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return slot;
|
||||
}
|
||||
|
||||
static uint32_t timer_generate_id(Timer * tmr) {
|
||||
static uint32_t timer_generate_id(Timer *tmr) {
|
||||
uint32_t newId = 0;
|
||||
do {
|
||||
newId = ((uint32_t) rand()) | 0x01; // ID cannot be 0
|
||||
newId = ((uint32_t)rand()) | 0x01; // ID cannot be 0
|
||||
|
||||
} while (timer_get_alarm_by_id(tmr, newId) != NULL);
|
||||
return newId;
|
||||
}
|
||||
|
||||
static void timer_update_nearest_alarm(Timer * tmr) {
|
||||
static void timer_update_nearest_alarm(Timer *tmr) {
|
||||
if (tmr->nSched == 0) {
|
||||
tmr->nextAlarm = NULL;
|
||||
return;
|
||||
@ -65,7 +68,7 @@ static void timer_update_nearest_alarm(Timer * tmr) {
|
||||
int64_t t_c_us = time_to_us(&tmr->time);
|
||||
int64_t min_delta_t_us = 0;
|
||||
|
||||
AlarmAssignment * nearest = NULL;
|
||||
AlarmAssignment *nearest = NULL;
|
||||
for (uint32_t i = 0; i < tmr->maxSched; i++) {
|
||||
int64_t t_i_us = time_to_us(&(tmr->alarms[i].time));
|
||||
if ((nearest == NULL) && (tmr->alarms[i].id != 0)) {
|
||||
@ -83,7 +86,7 @@ static void timer_update_nearest_alarm(Timer * tmr) {
|
||||
tmr->nextAlarm = nearest;
|
||||
}
|
||||
|
||||
uint32_t timer_sched(Timer * tmr, const TimePoint * t, TimerAlarmCb cb, AlarmUserData params) {
|
||||
uint32_t timer_sched(Timer *tmr, const TimePoint *t, TimerAlarmCb cb, AlarmUserData params) {
|
||||
if (tmr->nSched == tmr->maxSched) { // if cannot schedule more alarm
|
||||
return TIMER_SCHED_FAILED;
|
||||
}
|
||||
@ -91,7 +94,7 @@ uint32_t timer_sched(Timer * tmr, const TimePoint * t, TimerAlarmCb cb, AlarmUse
|
||||
ETHLIB_OS_MTX_LOCK(&(tmr->tabMtx));
|
||||
|
||||
// if we can schedule get the first unused block
|
||||
AlarmAssignment * slot = timer_get_alarm_by_id(tmr, 0);
|
||||
AlarmAssignment *slot = timer_get_alarm_by_id(tmr, 0);
|
||||
|
||||
// allocate on the first free slot
|
||||
slot->id = timer_generate_id(tmr);
|
||||
@ -109,26 +112,29 @@ uint32_t timer_sched(Timer * tmr, const TimePoint * t, TimerAlarmCb cb, AlarmUse
|
||||
tmr->nextAlarm = slot;
|
||||
}
|
||||
|
||||
timer_report(tmr);
|
||||
//timer_report(tmr);
|
||||
|
||||
ETHLIB_OS_MTX_UNLOCK(&(tmr->tabMtx));
|
||||
|
||||
return slot->id;
|
||||
}
|
||||
|
||||
uint32_t timer_sched_rel(Timer * tmr, int64_t us, TimerAlarmCb cb, AlarmUserData params) {
|
||||
uint32_t timer_sched_rel(Timer *tmr, int64_t us, TimerAlarmCb cb, AlarmUserData params) {
|
||||
TimePoint t = tmr->time;
|
||||
time_add_us(&t, us);
|
||||
return timer_sched(tmr, &t, cb, params);
|
||||
}
|
||||
|
||||
void timer_unsched(Timer * tmr, uint32_t id) {
|
||||
void timer_unsched(Timer *tmr, uint32_t id) {
|
||||
ETHLIB_OS_MTX_LOCK(&(tmr->tabMtx));
|
||||
|
||||
AlarmAssignment * alarm = timer_get_alarm_by_id(tmr, id);
|
||||
if (alarm != NULL) {
|
||||
memset(alarm, 0, sizeof(AlarmAssignment));
|
||||
tmr->nSched--;
|
||||
if (tmr->nSched > 0) {
|
||||
AlarmAssignment *alarm = timer_get_alarm_by_id(tmr, id);
|
||||
if (alarm != NULL) {
|
||||
memset(alarm, 0, sizeof(AlarmAssignment));
|
||||
tmr->nSched--;
|
||||
timer_update_nearest_alarm(tmr);
|
||||
}
|
||||
}
|
||||
|
||||
ETHLIB_OS_MTX_UNLOCK(&(tmr->tabMtx));
|
||||
@ -138,15 +144,15 @@ void timer_set_time(Timer *tmr, const TimePoint *t) {
|
||||
tmr->time = *t;
|
||||
}
|
||||
|
||||
int64_t timer_get_time_us(const Timer * tmr) {
|
||||
int64_t timer_get_time_us(const Timer *tmr) {
|
||||
return time_to_us(&tmr->time);
|
||||
}
|
||||
|
||||
TimePoint timer_get_time(const Timer * tmr) {
|
||||
TimePoint timer_get_time(const Timer *tmr) {
|
||||
return tmr->time;
|
||||
}
|
||||
|
||||
void timer_tick(Timer * tmr, int64_t us) {
|
||||
void timer_tick(Timer *tmr, int64_t us) {
|
||||
// advance time
|
||||
time_add_us(&tmr->time, us);
|
||||
/*t_us += us;
|
||||
@ -161,7 +167,7 @@ void timer_tick(Timer * tmr, int64_t us) {
|
||||
return; // break from the loop, since we cannot lock the mutex
|
||||
}
|
||||
|
||||
timer_report(tmr);
|
||||
//timer_report(tmr);
|
||||
|
||||
// fetch alarm (obtain a COPY)
|
||||
AlarmAssignment alarm = *(tmr->nextAlarm);
|
||||
@ -187,10 +193,9 @@ void timer_tick(Timer * tmr, int64_t us) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void timer_report(const Timer * tmr) {
|
||||
void timer_report(const Timer *tmr) {
|
||||
MSG("Time: %u.%06u\n\n", tmr->time.s, tmr->time.us);
|
||||
|
||||
int64_t t_c_us = timer_get_time_us(tmr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user