implicit type conversions fixed

This commit is contained in:
Wiesner András 2023-10-25 17:41:36 +02:00
parent e4d27454cd
commit 0add109430
17 changed files with 171 additions and 91 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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(&ethIntf->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) {

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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.

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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
View File

@ -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);