- add tag to CBD
- DHCP state separated - link change handler added - timer mutex added
This commit is contained in:
parent
ab8d45932f
commit
e4d27454cd
20
cbd_table.c
20
cbd_table.c
@ -50,6 +50,26 @@ bool cbdt_get_connection_block(CbdTable *cbdt, cbd d, ConnBlock *connBlock) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cbdt_set_tag(CbdTable *cbdt, cbd d, PcktSieveLayerTag tag) {
|
||||
ConnBlock connBlock;
|
||||
if (cbdt_get_connection_block(cbdt, d, &connBlock)) {
|
||||
connBlock.sieveLayer->tag = tag;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool cbdt_get_tag(CbdTable * cbdt, cbd d, PcktSieveLayerTag * tag) {
|
||||
ConnBlock connBlock;
|
||||
if (cbdt_get_connection_block(cbdt, d, &connBlock)) {
|
||||
*tag = connBlock.sieveLayer->tag;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void cbdt_report(const CbdTable *cbdt) {
|
||||
INFO("CBDT listing (%d/%d):\n---------------\n\n", cbdt->level, cbdt->maxEntries);
|
||||
|
||||
|
18
cbd_table.h
18
cbd_table.h
@ -52,6 +52,24 @@ void cbdt_release(CbdTable * cbdt, cbd d);
|
||||
*/
|
||||
bool cbdt_get_connection_block(CbdTable * cbdt, cbd d, ConnBlock * connBlock);
|
||||
|
||||
/**
|
||||
* Set connection block sieve tag.
|
||||
* @param cbdt pointer to CBDT
|
||||
* @param d CBD value
|
||||
* @param tag tag getting stored
|
||||
* @return operation successful (d was valid)
|
||||
*/
|
||||
bool cbdt_set_tag(CbdTable * cbdt, cbd d, PcktSieveLayerTag tag);
|
||||
|
||||
/**
|
||||
* Retrieve connection block sieve tag.
|
||||
* @param cbdt pointer to CBDT
|
||||
* @param d CBD value
|
||||
* @param tag pointer to area where tag is written
|
||||
* @return operation successful (d was valid)
|
||||
*/
|
||||
bool cbdt_get_tag(CbdTable * cbdt, cbd d, PcktSieveLayerTag * tag);
|
||||
|
||||
/**
|
||||
* Print report on connection block descriptors.
|
||||
* @param cbdt pointer to CBD table
|
||||
|
@ -18,10 +18,17 @@ static int ethintf_llrxnotify(EthIODef * io) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ethinf_lllinkchg(EthIODef * io, int ls) {
|
||||
ethinf_set_link_state((EthInterface *) io->tag, ls);
|
||||
MSG("Link state: %d\n", ls);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ethintf_register(EthInterface * intf) {
|
||||
intf->ioDef->tag = intf;
|
||||
intf->ioDef->llRxStore = ethintf_llrecv;
|
||||
intf->ioDef->llRxNotify = ethintf_llrxnotify;
|
||||
intf->ioDef->llLinkChg = ethinf_lllinkchg;
|
||||
}
|
||||
|
||||
// interface processing thread
|
||||
@ -49,6 +56,12 @@ EthInterface *ethintf_new(EthIODef * io) {
|
||||
|
||||
ethIntf->capabilities = 0;
|
||||
|
||||
ethIntf->dhcp = NULL;
|
||||
|
||||
memset(ðIntf->evtCbTable, 0, sizeof(EthIntfEventCbTable));
|
||||
|
||||
ethIntf->linkState = false;
|
||||
|
||||
return ethIntf;
|
||||
}
|
||||
|
||||
@ -87,3 +100,25 @@ void ethinf_notify(EthInterface *intf) {
|
||||
void ethinf_set_capabilities(EthInterface *intf, uint32_t cap) {
|
||||
intf->capabilities = cap;
|
||||
}
|
||||
|
||||
void ethinf_set_event_callback(EthInterface *intf, EthIntfEvIndex idx, EthIntfEvtCb cb) {
|
||||
((EthIntfEvtCb *)((&(intf->evtCbTable))))[idx] = cb;
|
||||
}
|
||||
|
||||
void ethinf_trigger_event(EthInterface *intf, EthIntfEvIndex idx) {
|
||||
EthIntfEvtCb cb = ((EthIntfEvtCb *)((&(intf->evtCbTable))))[idx];
|
||||
if (cb != NULL) {
|
||||
cb(intf);
|
||||
}
|
||||
}
|
||||
|
||||
void ethinf_set_link_state(EthInterface *intf, bool ls) {
|
||||
if (intf->linkState != ls) { // trigger event only if state has actually changed
|
||||
intf->linkState = ls;
|
||||
ethinf_trigger_event(intf, ETH_EVT_LINK_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
bool ethinf_get_link_state(EthInterface *intf) {
|
||||
return intf->linkState;
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef ETHERLIB_ETH_INTERFACE_H
|
||||
#define ETHERLIB_ETH_INTERFACE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "packet_sieve.h"
|
||||
#include "prefab/packet_parsers/packet_parsers.h"
|
||||
#include "prefab/packet_parsers/ipv4_types.h"
|
||||
@ -9,6 +11,7 @@
|
||||
#include "msg_queue.h"
|
||||
#include "prefab/conn_blocks/ipv4/ip_assembler.h"
|
||||
#include "etherlib_options.h"
|
||||
#include "etherlib/prefab/packet_parsers/dhcp.h"
|
||||
|
||||
/**
|
||||
* Ethernet interface low level definition.
|
||||
@ -38,6 +41,23 @@ typedef enum {
|
||||
ETHINF_CAP_ALL_RX_TX_CHECKSUM_OFFLOADS = 0b11111,
|
||||
} EthIntfCap;
|
||||
|
||||
struct EthInterface_;
|
||||
|
||||
typedef void (*EthIntfEvtCb)(struct EthInterface_ * intf);
|
||||
|
||||
typedef enum {
|
||||
ETH_EVT_LINK_CHANGE = 0,
|
||||
ETH_EVT_IP_CHANGE = 1
|
||||
} EthIntfEvIndex;
|
||||
|
||||
/**
|
||||
* Ethernet interface event callback table
|
||||
*/
|
||||
typedef struct {
|
||||
EthIntfEvtCb linkChange; ///< Link change event
|
||||
EthIntfEvtCb ipChange; ///< IP-address changed
|
||||
} EthIntfEventCbTable;
|
||||
|
||||
/**
|
||||
* Ethernet interface representation.
|
||||
*/
|
||||
@ -46,6 +66,7 @@ typedef struct EthInterface_ {
|
||||
EthIODef * ioDef; ///< Low-level IO definitions
|
||||
EthernetAddress mac; ///< Ethernet address
|
||||
uint32_t capabilities; ///< Ethernet interface capabilities
|
||||
DhcpState * dhcp; ///< DHCP control block (allocated only, if DHCP operation is initiated)
|
||||
ip4_addr ip; ///< IP address
|
||||
ip4_addr router; ///< Router IP address
|
||||
ip4_addr netmask; ///< Subnet mask
|
||||
@ -56,6 +77,8 @@ typedef struct EthInterface_ {
|
||||
MsgQueue * rxQ; ///< Receive queue
|
||||
ETHLIB_OS_SEM_TYPE rxSem; ///< Receive queue semaphore
|
||||
IPv4Assembler * ipra; ///< IPv4 reassembler
|
||||
EthIntfEventCbTable evtCbTable; ///< Event callback table
|
||||
bool linkState; ///< Interface link state
|
||||
} EthInterface;
|
||||
|
||||
/**
|
||||
@ -90,4 +113,32 @@ void ethinf_transmit(EthInterface *intf, const RawPckt *rawPckt);
|
||||
*/
|
||||
void ethinf_set_capabilities(EthInterface *intf, uint32_t cap);
|
||||
|
||||
/**
|
||||
* Set Ethernet event callback.
|
||||
* @param intf pointer to Ethernet interface
|
||||
* @param idx index of Ethernet event
|
||||
* @param cb callback function pointer
|
||||
*/
|
||||
void ethinf_set_event_callback(EthInterface * intf, EthIntfEvIndex idx, EthIntfEvtCb cb);
|
||||
|
||||
/**
|
||||
* Trigger Ethernet event.
|
||||
* @param intf pointer to Ethernet interface
|
||||
* @param idx index of Ethernet interface event
|
||||
*/
|
||||
void ethinf_trigger_event(EthInterface * intf, EthIntfEvIndex idx);
|
||||
|
||||
/**
|
||||
* Set link state.
|
||||
* @param intf pointer to Ethernet interface
|
||||
* @param ls link state
|
||||
*/
|
||||
void ethinf_set_link_state(EthInterface * intf, bool ls);
|
||||
|
||||
/**
|
||||
* Get link state.
|
||||
* @param intf pointer to Ethernet interface
|
||||
*/
|
||||
bool ethinf_get_link_state(EthInterface * intf);
|
||||
|
||||
#endif //ETHERLIB_ETH_INTERFACE_H
|
||||
|
@ -10,15 +10,6 @@
|
||||
#include "../conn_blocks/udp_connblock.h"
|
||||
#include "../../global_state.h"
|
||||
|
||||
static struct {
|
||||
DhcpState state;
|
||||
void *buf;
|
||||
cbd desc;
|
||||
uint32_t tranId;
|
||||
EthInterface *intf;
|
||||
ETHLIB_OS_MTX_TYPE procMtx;
|
||||
} s;
|
||||
|
||||
static const uint8_t DHCP_MAGIC_COOKIE[] = {99, 130, 83, 99};
|
||||
|
||||
#define SNAME_LEN (64)
|
||||
@ -124,9 +115,9 @@ static const DhcpOption *dhcp_get_option(const DhcpOption *opts, DhcpOptionId id
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void dhcp_send(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));
|
||||
@ -155,7 +146,7 @@ static void dhcp_send(const DhcpProps *props, const DhcpOption *opts) {
|
||||
// dhcp_option_insert_end(&buf);
|
||||
|
||||
// send packet
|
||||
udp_sendto(s.desc, s.buf, DHCP_MIN_PACKET_SIZE, IPv4_ANY_ADDR, DHCP_SERVER_PORT);
|
||||
udp_sendto(s->desc, s->buf, DHCP_MIN_PACKET_SIZE, IPv4_ANY_ADDR, DHCP_SERVER_PORT);
|
||||
}
|
||||
|
||||
static void dhcp_parse(const uint8_t *buf, DhcpProps *props, DhcpOption **opts) {
|
||||
@ -196,15 +187,15 @@ static void dhcp_parse(const uint8_t *buf, DhcpProps *props, DhcpOption **opts)
|
||||
#define IPv4_ADDR_TO_BE_BYTES(addr) ((addr) & 0xFF), (((addr) >> 8) & 0xFF), (((addr) >> 16) & 0xFF), (((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() {
|
||||
s.tranId = rand();
|
||||
static void dhcp_discover(DhcpState * s) {
|
||||
s->tranId = rand();
|
||||
DhcpProps props = {0};
|
||||
|
||||
props.op = DHCP_BOOTREQUEST;
|
||||
props.htype = DHCP_HW_TYPE_ETHERNET;
|
||||
props.hlen = 6;
|
||||
props.hops = 0;
|
||||
props.xid = s.tranId;
|
||||
props.xid = s->tranId;
|
||||
props.secs = 0;
|
||||
props.flags = 0;
|
||||
props.ciaddr = 0;
|
||||
@ -212,24 +203,24 @@ static void dhcp_discover() {
|
||||
props.siaddr = 0;
|
||||
props.giaddr = 0;
|
||||
|
||||
memcpy(props.chaddr, s.intf->mac, ETH_HW_ADDR_LEN);
|
||||
memcpy(props.chaddr, s->intf->mac, ETH_HW_ADDR_LEN);
|
||||
|
||||
DhcpOption optEnd = {DHCP_OPT_End, 0, NULL};
|
||||
uint16_t maxSize = 1500; // TODO...
|
||||
DhcpOption maxMsgSize = {DHCP_OPT_MaxMsgSize, 2, &optEnd, {UINT16_TO_BE_BYTES(maxSize)}};
|
||||
DhcpOption msgType = {DHCP_OPT_MsgType, 1, &maxMsgSize, {DHCPDISCOVER}};
|
||||
|
||||
dhcp_send(&props, &msgType);
|
||||
dhcp_send(s, &props, &msgType);
|
||||
}
|
||||
|
||||
void dhcp_request(ip4_addr reqAddr, ip4_addr dhcpServerAddr) {
|
||||
void dhcp_request(DhcpState * s, ip4_addr reqAddr, ip4_addr dhcpServerAddr) {
|
||||
DhcpProps props = {0};
|
||||
|
||||
props.op = DHCP_BOOTREQUEST;
|
||||
props.htype = DHCP_HW_TYPE_ETHERNET;
|
||||
props.hlen = 6;
|
||||
props.hops = 0;
|
||||
props.xid = s.tranId;
|
||||
props.xid = s->tranId;
|
||||
props.secs = 0;
|
||||
props.flags = 0;
|
||||
props.ciaddr = 0;
|
||||
@ -237,7 +228,7 @@ void dhcp_request(ip4_addr reqAddr, ip4_addr dhcpServerAddr) {
|
||||
props.siaddr = 0;
|
||||
props.giaddr = 0;
|
||||
|
||||
memcpy(props.chaddr, s.intf->mac, ETH_HW_ADDR_LEN);
|
||||
memcpy(props.chaddr, s->intf->mac, ETH_HW_ADDR_LEN);
|
||||
|
||||
uint16_t maxSize = 1500; // TODO...
|
||||
|
||||
@ -245,20 +236,20 @@ void dhcp_request(ip4_addr reqAddr, ip4_addr dhcpServerAddr) {
|
||||
DhcpOption paramReq = {DHCP_OPT_ParamReqList, 4, &optEnd, {1, 3, 6, 51}}; // TODO...
|
||||
DhcpOption reqIp = {DHCP_OPT_RequestedIpAddress, 4, ¶mReq, {IPv4_ADDR_TO_BE_BYTES(reqAddr)}};
|
||||
DhcpOption serverIp = {DHCP_OPT_ServerId, 4, &reqIp, {IPv4_ADDR_TO_BE_BYTES(dhcpServerAddr)}};
|
||||
DhcpOption clId = {DHCP_OPT_ClientIdentifier, 7, &serverIp, {DHCP_HW_TYPE_ETHERNET, HWADDR_TO_BE_BYTES(s.intf->mac)}};
|
||||
DhcpOption clId = {DHCP_OPT_ClientIdentifier, 7, &serverIp, {DHCP_HW_TYPE_ETHERNET, HWADDR_TO_BE_BYTES(s->intf->mac)}};
|
||||
DhcpOption maxMsgSize = {DHCP_OPT_MaxMsgSize, 2, &clId, {UINT16_TO_BE_BYTES(maxSize)}};
|
||||
DhcpOption msgType = {DHCP_OPT_MsgType, 1, &maxMsgSize, {DHCPREQUEST}};
|
||||
|
||||
dhcp_send(&props, &msgType);
|
||||
dhcp_send(s, &props, &msgType);
|
||||
}
|
||||
|
||||
static void dhcp_process(DhcpProps *props, DhcpOption *opts) {
|
||||
ETHLIB_OS_MTX_LOCK(&s.procMtx); // LOCK!
|
||||
static void dhcp_process(DhcpState * s, DhcpProps *props, DhcpOption *opts) {
|
||||
ETHLIB_OS_MTX_LOCK(&s->procMtx); // LOCK!
|
||||
|
||||
switch (s.state) {
|
||||
switch (s->state) {
|
||||
case DHCP_INIT:
|
||||
dhcp_discover(); // send discover message
|
||||
s.state = DHCP_SELECTING;
|
||||
dhcp_discover(s); // send discover message
|
||||
s->state = DHCP_SELECTING;
|
||||
break;
|
||||
case DHCP_SELECTING: {
|
||||
const DhcpOption *msgType = dhcp_get_option(opts, DHCP_OPT_MsgType);
|
||||
@ -268,10 +259,10 @@ static void dhcp_process(DhcpProps *props, DhcpOption *opts) {
|
||||
ip4_addr serverAddr;
|
||||
FETCH_DWORD(&serverAddr, serverIdentifier->value);
|
||||
ip4_addr addrOffer = props->yiaddr;
|
||||
dhcp_request(addrOffer, serverAddr);
|
||||
dhcp_request(s, addrOffer, serverAddr);
|
||||
}
|
||||
|
||||
s.state = DHCP_REQUESTING;
|
||||
s->state = DHCP_REQUESTING;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -282,16 +273,16 @@ static void dhcp_process(DhcpProps *props, DhcpOption *opts) {
|
||||
//dhcp_discover();
|
||||
//s.state = DHCP_SELECTING;
|
||||
} else if (msgType == DHCPACK) {
|
||||
s.intf->ip = props->yiaddr; // fetch ip address
|
||||
s->intf->ip = props->yiaddr; // fetch ip address
|
||||
|
||||
opt = dhcp_get_option(opts, DHCP_OPT_Router); // get gateway/router address
|
||||
FETCH_DWORD(&(s.intf->router), opt->value);
|
||||
FETCH_DWORD(&(s->intf->router), opt->value);
|
||||
|
||||
opt = dhcp_get_option(opts, DHCP_OPT_SubnetMask); // get subnet mask
|
||||
FETCH_DWORD(&(s.intf->netmask), opt->value);
|
||||
FETCH_DWORD(&(s->intf->netmask), opt->value);
|
||||
|
||||
opt = dhcp_get_option(opts, DHCP_OPT_DomainNameServer); // get DNS
|
||||
FETCH_DWORD(&(s.intf->dns), opt->value);
|
||||
FETCH_DWORD(&(s->intf->dns), opt->value);
|
||||
|
||||
opt = dhcp_get_option(opts, DHCP_OPT_IPAddrLeaseTime); // fetch Lease Time
|
||||
uint32_t dhcpLeaseTime_s;
|
||||
@ -302,17 +293,20 @@ static void dhcp_process(DhcpProps *props, DhcpOption *opts) {
|
||||
|
||||
MSG("DHCP done!\n");
|
||||
MSG("IP: ");
|
||||
PRINT_IPv4(s.intf->ip);
|
||||
PRINT_IPv4(s->intf->ip);
|
||||
MSG("\nRouter: ");
|
||||
PRINT_IPv4(s.intf->router);
|
||||
PRINT_IPv4(s->intf->router);
|
||||
MSG("\nNetmask: ");
|
||||
PRINT_IPv4(s.intf->netmask);
|
||||
PRINT_IPv4(s->intf->netmask);
|
||||
MSG("\nDNS: ");
|
||||
PRINT_IPv4(s.intf->dns);
|
||||
PRINT_IPv4(s->intf->dns);
|
||||
MSG("\nLease time: %u s\n", dhcpLeaseTime_s);
|
||||
MSG("\n");
|
||||
|
||||
s.state = DHCP_BOUND;
|
||||
s->state = DHCP_BOUND;
|
||||
|
||||
// call event callback
|
||||
ethinf_trigger_event(s->intf, ETH_EVT_IP_CHANGE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -320,7 +314,7 @@ static void dhcp_process(DhcpProps *props, DhcpOption *opts) {
|
||||
break;
|
||||
}
|
||||
|
||||
ETHLIB_OS_MTX_UNLOCK(&s.procMtx); // RELEASE!
|
||||
ETHLIB_OS_MTX_UNLOCK(&s->procMtx); // RELEASE!
|
||||
}
|
||||
|
||||
static int dhcp_resp_cb(const Pckt *pckt, PcktSieveLayerTag tag) {
|
||||
@ -328,22 +322,30 @@ static int dhcp_resp_cb(const Pckt *pckt, PcktSieveLayerTag tag) {
|
||||
DhcpOption *opts = NULL;
|
||||
dhcp_parse(pckt->payload, &props, &opts);
|
||||
|
||||
dhcp_process(&props, opts);
|
||||
DhcpState * s = (DhcpState *) tag.p;
|
||||
dhcp_process(s, &props, opts);
|
||||
|
||||
dhcp_free_opt_chain(opts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dhcp_start() {
|
||||
s.state = DHCP_INIT;
|
||||
dhcp_process(NULL, NULL);
|
||||
void dhcp_start(DhcpState * s) {
|
||||
s->state = DHCP_INIT;
|
||||
dhcp_process(s, NULL, NULL);
|
||||
}
|
||||
|
||||
void dhcp_initiate(EthInterface *intf) {
|
||||
ETHLIB_OS_MTX_CREATE(&s.procMtx);
|
||||
s.state = DHCP_INIT;
|
||||
s.buf = dynmem_alloc(DHCP_MIN_PACKET_SIZE);
|
||||
s.desc = udp_new_connblock(intf, IPv4_ANY_ADDR, DHCP_CLIENT_PORT, dhcp_resp_cb);
|
||||
s.intf = intf;
|
||||
DhcpState * s = (DhcpState *) dynmem_alloc(sizeof(DhcpState));
|
||||
|
||||
ETHLIB_OS_MTX_CREATE(&s->procMtx);
|
||||
s->state = DHCP_INIT;
|
||||
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;
|
||||
|
||||
intf->dhcp = s;
|
||||
}
|
||||
|
@ -2,7 +2,9 @@
|
||||
#define ETHERLIB_DHCP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../../eth_interface.h"
|
||||
//#include "../../eth_interface.h"
|
||||
#include "etherlib/cbd_table.h"
|
||||
#include "etherlib_options.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t op; ///< Operations
|
||||
@ -33,7 +35,7 @@ typedef enum {
|
||||
DHCP_REBINDING,
|
||||
DHCP_BOUND,
|
||||
DHCP_RENEWING
|
||||
} DhcpState;
|
||||
} DhcpFSMState;
|
||||
|
||||
/**
|
||||
* DHCP id codes.
|
||||
@ -47,15 +49,27 @@ typedef enum {
|
||||
#define DHCP_CLIENT_PORT (68)
|
||||
#define DHCP_SERVER_PORT (67)
|
||||
|
||||
struct EthInterface_;
|
||||
|
||||
typedef struct {
|
||||
DhcpFSMState state; ///< DHCP state machine state
|
||||
void *buf; ///< Pointer to packet an allocated packet buffer
|
||||
cbd desc; ///< UDP connection block descriptor
|
||||
uint32_t tranId; ///< Transaction ID
|
||||
struct EthInterface_ *intf; ///< Pointer to corresponding Ethernet interface
|
||||
ETHLIB_OS_MTX_TYPE procMtx; ///< Mutex protecting the state machine
|
||||
} DhcpState;
|
||||
|
||||
/**
|
||||
* Initiate DHCP on interface
|
||||
* @param intf interface
|
||||
*/
|
||||
void dhcp_initiate(EthInterface * intf);
|
||||
void dhcp_initiate(struct EthInterface_ * intf);
|
||||
|
||||
/**
|
||||
*
|
||||
* Start DHCP operation.
|
||||
* @param s pointer to DhcpState structure
|
||||
*/
|
||||
void dhcp_start();
|
||||
void dhcp_start(DhcpState * s);
|
||||
|
||||
#endif //ETHERLIB_DHCP_H
|
||||
|
30
timer.c
30
timer.c
@ -26,6 +26,7 @@ Timer *timer_new(uint32_t maxSched) {
|
||||
Timer * tmr = (Timer *) dynmem_alloc(sizeof(Timer) + maxSched * sizeof(AlarmAssignment));
|
||||
ASSERT_NULL(tmr);
|
||||
|
||||
ETHLIB_OS_MTX_CREATE(&tmr->tabMtx);
|
||||
tmr->maxSched = maxSched;
|
||||
tmr->nSched = 0;
|
||||
tmr->nextAlarm = NULL;
|
||||
@ -87,6 +88,8 @@ uint32_t timer_sched(Timer * tmr, const TimePoint * t, TimerAlarmCb cb, AlarmUse
|
||||
return TIMER_SCHED_FAILED;
|
||||
}
|
||||
|
||||
ETHLIB_OS_MTX_LOCK(&(tmr->tabMtx));
|
||||
|
||||
// if we can schedule get the first unused block
|
||||
AlarmAssignment * slot = timer_get_alarm_by_id(tmr, 0);
|
||||
|
||||
@ -106,6 +109,10 @@ uint32_t timer_sched(Timer * tmr, const TimePoint * t, TimerAlarmCb cb, AlarmUse
|
||||
tmr->nextAlarm = slot;
|
||||
}
|
||||
|
||||
timer_report(tmr);
|
||||
|
||||
ETHLIB_OS_MTX_UNLOCK(&(tmr->tabMtx));
|
||||
|
||||
return slot->id;
|
||||
}
|
||||
|
||||
@ -116,11 +123,15 @@ uint32_t timer_sched_rel(Timer * tmr, int64_t us, TimerAlarmCb cb, AlarmUserData
|
||||
}
|
||||
|
||||
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--;
|
||||
}
|
||||
|
||||
ETHLIB_OS_MTX_UNLOCK(&(tmr->tabMtx));
|
||||
}
|
||||
|
||||
void timer_set_time(Timer *tmr, const TimePoint *t) {
|
||||
@ -146,11 +157,15 @@ void timer_tick(Timer * tmr, int64_t us) {
|
||||
if ((tmr->nSched > 0) && (tmr->nextAlarm != NULL)) {
|
||||
int64_t t_alarm = time_to_us(&(tmr->nextAlarm->time));
|
||||
while (((t_alarm - t_us) <= 0) && (tmr->nSched > 0)) {
|
||||
// invoke callback
|
||||
if (tmr->nextAlarm->cb != NULL) {
|
||||
tmr->nextAlarm->cb(tmr, tmr->nextAlarm->params);
|
||||
if (ETHLIB_OS_MTX_LOCK(&(tmr->tabMtx)) != 0) {
|
||||
return; // break from the loop, since we cannot lock the mutex
|
||||
}
|
||||
|
||||
timer_report(tmr);
|
||||
|
||||
// fetch alarm (obtain a COPY)
|
||||
AlarmAssignment alarm = *(tmr->nextAlarm);
|
||||
|
||||
// clear alarm descriptor
|
||||
memset(tmr->nextAlarm, 0, sizeof(AlarmAssignment));
|
||||
|
||||
@ -159,11 +174,20 @@ void timer_tick(Timer * tmr, int64_t us) {
|
||||
|
||||
// update nearest alarm
|
||||
timer_update_nearest_alarm(tmr);
|
||||
|
||||
ETHLIB_OS_MTX_UNLOCK(&(tmr->tabMtx));
|
||||
|
||||
// invoke callback
|
||||
if (alarm.cb != NULL) {
|
||||
alarm.cb(tmr, alarm.params);
|
||||
}
|
||||
|
||||
if (tmr->nextAlarm != NULL) {
|
||||
t_alarm = time_to_us(&(tmr->nextAlarm->time));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void timer_report(const Timer * tmr) {
|
||||
|
3
timer.h
3
timer.h
@ -4,6 +4,8 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <etherlib_options.h>
|
||||
|
||||
/**
|
||||
* A single point in time
|
||||
*/
|
||||
@ -61,6 +63,7 @@ typedef struct {
|
||||
* Timer class
|
||||
*/
|
||||
typedef struct Timer_ {
|
||||
ETHLIB_OS_MTX_TYPE tabMtx; ///< Mutex protecting the scheduling table
|
||||
TimePoint time; ///< Absolute time
|
||||
AlarmAssignment * nextAlarm; ///< Nearest alarm
|
||||
uint32_t maxSched; ///< Maximum number of scheduled alarms
|
||||
|
2
utils.h
2
utils.h
@ -39,7 +39,7 @@
|
||||
|
||||
#define IPv4(a,b,c,d) ((a) | (b << 8) | (c << 16) | (d << 24))
|
||||
#define PRINT_IPv4(ip) MSG("%u.%u.%u.%u", (ip & 0xFF), ((ip >> 8) & 0xFF), ((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF))
|
||||
#define PRINT_HWADDR(hwaddr) MSG("%02x:%02x:%02x:%02x:%02x:%02x", (hwaddr)[0], (hwaddr)[1], (hwaddr)[2], (hwaddr)[3], (hwaddr)[4], (hwaddr)[5]);
|
||||
#define PRINT_HWADDR(hwaddr) MSG("%02x:%02x:%02x:%02x:%02x:%02x", (hwaddr)[0], (hwaddr)[1], (hwaddr)[2], (hwaddr)[3], (hwaddr)[4], (hwaddr)[5])
|
||||
|
||||
#define ASSERT_BAD_ALIGN(p) if ((size_t)(p) & 0b11) ERROR("Bad memory alignment in function '%s' in file '%s' on line %d!\n", __func__, __FILE__, __LINE__)
|
||||
#define ASSERT_NULL(p) if ((p) == NULL) ERROR("NULL in function '%s' in file '%s' on line %d!\n", __func__, __FILE__, __LINE__)
|
||||
|
Loading…
x
Reference in New Issue
Block a user