- 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;
|
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) {
|
void cbdt_report(const CbdTable *cbdt) {
|
||||||
INFO("CBDT listing (%d/%d):\n---------------\n\n", cbdt->level, cbdt->maxEntries);
|
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);
|
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.
|
* Print report on connection block descriptors.
|
||||||
* @param cbdt pointer to CBD table
|
* @param cbdt pointer to CBD table
|
||||||
|
@ -18,10 +18,17 @@ static int ethintf_llrxnotify(EthIODef * io) {
|
|||||||
return 0;
|
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) {
|
static void ethintf_register(EthInterface * intf) {
|
||||||
intf->ioDef->tag = intf;
|
intf->ioDef->tag = intf;
|
||||||
intf->ioDef->llRxStore = ethintf_llrecv;
|
intf->ioDef->llRxStore = ethintf_llrecv;
|
||||||
intf->ioDef->llRxNotify = ethintf_llrxnotify;
|
intf->ioDef->llRxNotify = ethintf_llrxnotify;
|
||||||
|
intf->ioDef->llLinkChg = ethinf_lllinkchg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// interface processing thread
|
// interface processing thread
|
||||||
@ -49,6 +56,12 @@ EthInterface *ethintf_new(EthIODef * io) {
|
|||||||
|
|
||||||
ethIntf->capabilities = 0;
|
ethIntf->capabilities = 0;
|
||||||
|
|
||||||
|
ethIntf->dhcp = NULL;
|
||||||
|
|
||||||
|
memset(ðIntf->evtCbTable, 0, sizeof(EthIntfEventCbTable));
|
||||||
|
|
||||||
|
ethIntf->linkState = false;
|
||||||
|
|
||||||
return ethIntf;
|
return ethIntf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,3 +100,25 @@ void ethinf_notify(EthInterface *intf) {
|
|||||||
void ethinf_set_capabilities(EthInterface *intf, uint32_t cap) {
|
void ethinf_set_capabilities(EthInterface *intf, uint32_t cap) {
|
||||||
intf->capabilities = 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
|
#ifndef ETHERLIB_ETH_INTERFACE_H
|
||||||
#define ETHERLIB_ETH_INTERFACE_H
|
#define ETHERLIB_ETH_INTERFACE_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "packet_sieve.h"
|
#include "packet_sieve.h"
|
||||||
#include "prefab/packet_parsers/packet_parsers.h"
|
#include "prefab/packet_parsers/packet_parsers.h"
|
||||||
#include "prefab/packet_parsers/ipv4_types.h"
|
#include "prefab/packet_parsers/ipv4_types.h"
|
||||||
@ -9,6 +11,7 @@
|
|||||||
#include "msg_queue.h"
|
#include "msg_queue.h"
|
||||||
#include "prefab/conn_blocks/ipv4/ip_assembler.h"
|
#include "prefab/conn_blocks/ipv4/ip_assembler.h"
|
||||||
#include "etherlib_options.h"
|
#include "etherlib_options.h"
|
||||||
|
#include "etherlib/prefab/packet_parsers/dhcp.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ethernet interface low level definition.
|
* Ethernet interface low level definition.
|
||||||
@ -38,6 +41,23 @@ typedef enum {
|
|||||||
ETHINF_CAP_ALL_RX_TX_CHECKSUM_OFFLOADS = 0b11111,
|
ETHINF_CAP_ALL_RX_TX_CHECKSUM_OFFLOADS = 0b11111,
|
||||||
} EthIntfCap;
|
} 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.
|
* Ethernet interface representation.
|
||||||
*/
|
*/
|
||||||
@ -46,6 +66,7 @@ typedef struct EthInterface_ {
|
|||||||
EthIODef * ioDef; ///< Low-level IO definitions
|
EthIODef * ioDef; ///< Low-level IO definitions
|
||||||
EthernetAddress mac; ///< Ethernet address
|
EthernetAddress mac; ///< Ethernet address
|
||||||
uint32_t capabilities; ///< Ethernet interface capabilities
|
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 ip; ///< IP address
|
||||||
ip4_addr router; ///< Router IP address
|
ip4_addr router; ///< Router IP address
|
||||||
ip4_addr netmask; ///< Subnet mask
|
ip4_addr netmask; ///< Subnet mask
|
||||||
@ -56,6 +77,8 @@ typedef struct EthInterface_ {
|
|||||||
MsgQueue * rxQ; ///< Receive queue
|
MsgQueue * rxQ; ///< Receive queue
|
||||||
ETHLIB_OS_SEM_TYPE rxSem; ///< Receive queue semaphore
|
ETHLIB_OS_SEM_TYPE rxSem; ///< Receive queue semaphore
|
||||||
IPv4Assembler * ipra; ///< IPv4 reassembler
|
IPv4Assembler * ipra; ///< IPv4 reassembler
|
||||||
|
EthIntfEventCbTable evtCbTable; ///< Event callback table
|
||||||
|
bool linkState; ///< Interface link state
|
||||||
} EthInterface;
|
} EthInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -90,4 +113,32 @@ void ethinf_transmit(EthInterface *intf, const RawPckt *rawPckt);
|
|||||||
*/
|
*/
|
||||||
void ethinf_set_capabilities(EthInterface *intf, uint32_t cap);
|
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
|
#endif //ETHERLIB_ETH_INTERFACE_H
|
||||||
|
@ -10,15 +10,6 @@
|
|||||||
#include "../conn_blocks/udp_connblock.h"
|
#include "../conn_blocks/udp_connblock.h"
|
||||||
#include "../../global_state.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};
|
static const uint8_t DHCP_MAGIC_COOKIE[] = {99, 130, 83, 99};
|
||||||
|
|
||||||
#define SNAME_LEN (64)
|
#define SNAME_LEN (64)
|
||||||
@ -124,9 +115,9 @@ static const DhcpOption *dhcp_get_option(const DhcpOption *opts, DhcpOptionId id
|
|||||||
return NULL;
|
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
|
// construct body
|
||||||
uint8_t *buf = (uint8_t *) s.buf;
|
uint8_t *buf = (uint8_t *) s->buf;
|
||||||
memset(buf, 0, DHCP_MIN_PACKET_SIZE);
|
memset(buf, 0, DHCP_MIN_PACKET_SIZE);
|
||||||
FILL_BYTE_ADVANCE(buf, &(props->op));
|
FILL_BYTE_ADVANCE(buf, &(props->op));
|
||||||
FILL_BYTE_ADVANCE(buf, &(props->htype));
|
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);
|
// dhcp_option_insert_end(&buf);
|
||||||
|
|
||||||
// send packet
|
// 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) {
|
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 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],
|
#define HWADDR_TO_BE_BYTES(hwa) (hwa)[0], (hwa)[1], (hwa)[2], (hwa)[3], (hwa)[4], (hwa)[5],
|
||||||
|
|
||||||
static void dhcp_discover() {
|
static void dhcp_discover(DhcpState * s) {
|
||||||
s.tranId = rand();
|
s->tranId = rand();
|
||||||
DhcpProps props = {0};
|
DhcpProps props = {0};
|
||||||
|
|
||||||
props.op = DHCP_BOOTREQUEST;
|
props.op = DHCP_BOOTREQUEST;
|
||||||
props.htype = DHCP_HW_TYPE_ETHERNET;
|
props.htype = DHCP_HW_TYPE_ETHERNET;
|
||||||
props.hlen = 6;
|
props.hlen = 6;
|
||||||
props.hops = 0;
|
props.hops = 0;
|
||||||
props.xid = s.tranId;
|
props.xid = s->tranId;
|
||||||
props.secs = 0;
|
props.secs = 0;
|
||||||
props.flags = 0;
|
props.flags = 0;
|
||||||
props.ciaddr = 0;
|
props.ciaddr = 0;
|
||||||
@ -212,24 +203,24 @@ static void dhcp_discover() {
|
|||||||
props.siaddr = 0;
|
props.siaddr = 0;
|
||||||
props.giaddr = 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};
|
DhcpOption optEnd = {DHCP_OPT_End, 0, NULL};
|
||||||
uint16_t maxSize = 1500; // TODO...
|
uint16_t maxSize = 1500; // TODO...
|
||||||
DhcpOption maxMsgSize = {DHCP_OPT_MaxMsgSize, 2, &optEnd, {UINT16_TO_BE_BYTES(maxSize)}};
|
DhcpOption maxMsgSize = {DHCP_OPT_MaxMsgSize, 2, &optEnd, {UINT16_TO_BE_BYTES(maxSize)}};
|
||||||
DhcpOption msgType = {DHCP_OPT_MsgType, 1, &maxMsgSize, {DHCPDISCOVER}};
|
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};
|
DhcpProps props = {0};
|
||||||
|
|
||||||
props.op = DHCP_BOOTREQUEST;
|
props.op = DHCP_BOOTREQUEST;
|
||||||
props.htype = DHCP_HW_TYPE_ETHERNET;
|
props.htype = DHCP_HW_TYPE_ETHERNET;
|
||||||
props.hlen = 6;
|
props.hlen = 6;
|
||||||
props.hops = 0;
|
props.hops = 0;
|
||||||
props.xid = s.tranId;
|
props.xid = s->tranId;
|
||||||
props.secs = 0;
|
props.secs = 0;
|
||||||
props.flags = 0;
|
props.flags = 0;
|
||||||
props.ciaddr = 0;
|
props.ciaddr = 0;
|
||||||
@ -237,7 +228,7 @@ void dhcp_request(ip4_addr reqAddr, ip4_addr dhcpServerAddr) {
|
|||||||
props.siaddr = 0;
|
props.siaddr = 0;
|
||||||
props.giaddr = 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...
|
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 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 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 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 maxMsgSize = {DHCP_OPT_MaxMsgSize, 2, &clId, {UINT16_TO_BE_BYTES(maxSize)}};
|
||||||
DhcpOption msgType = {DHCP_OPT_MsgType, 1, &maxMsgSize, {DHCPREQUEST}};
|
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) {
|
static void dhcp_process(DhcpState * s, DhcpProps *props, DhcpOption *opts) {
|
||||||
ETHLIB_OS_MTX_LOCK(&s.procMtx); // LOCK!
|
ETHLIB_OS_MTX_LOCK(&s->procMtx); // LOCK!
|
||||||
|
|
||||||
switch (s.state) {
|
switch (s->state) {
|
||||||
case DHCP_INIT:
|
case DHCP_INIT:
|
||||||
dhcp_discover(); // send discover message
|
dhcp_discover(s); // send discover message
|
||||||
s.state = DHCP_SELECTING;
|
s->state = DHCP_SELECTING;
|
||||||
break;
|
break;
|
||||||
case DHCP_SELECTING: {
|
case DHCP_SELECTING: {
|
||||||
const DhcpOption *msgType = dhcp_get_option(opts, DHCP_OPT_MsgType);
|
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;
|
ip4_addr serverAddr;
|
||||||
FETCH_DWORD(&serverAddr, serverIdentifier->value);
|
FETCH_DWORD(&serverAddr, serverIdentifier->value);
|
||||||
ip4_addr addrOffer = props->yiaddr;
|
ip4_addr addrOffer = props->yiaddr;
|
||||||
dhcp_request(addrOffer, serverAddr);
|
dhcp_request(s, addrOffer, serverAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
s.state = DHCP_REQUESTING;
|
s->state = DHCP_REQUESTING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -282,16 +273,16 @@ static void dhcp_process(DhcpProps *props, DhcpOption *opts) {
|
|||||||
//dhcp_discover();
|
//dhcp_discover();
|
||||||
//s.state = DHCP_SELECTING;
|
//s.state = DHCP_SELECTING;
|
||||||
} else if (msgType == DHCPACK) {
|
} 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
|
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
|
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
|
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
|
opt = dhcp_get_option(opts, DHCP_OPT_IPAddrLeaseTime); // fetch Lease Time
|
||||||
uint32_t dhcpLeaseTime_s;
|
uint32_t dhcpLeaseTime_s;
|
||||||
@ -302,17 +293,20 @@ static void dhcp_process(DhcpProps *props, DhcpOption *opts) {
|
|||||||
|
|
||||||
MSG("DHCP done!\n");
|
MSG("DHCP done!\n");
|
||||||
MSG("IP: ");
|
MSG("IP: ");
|
||||||
PRINT_IPv4(s.intf->ip);
|
PRINT_IPv4(s->intf->ip);
|
||||||
MSG("\nRouter: ");
|
MSG("\nRouter: ");
|
||||||
PRINT_IPv4(s.intf->router);
|
PRINT_IPv4(s->intf->router);
|
||||||
MSG("\nNetmask: ");
|
MSG("\nNetmask: ");
|
||||||
PRINT_IPv4(s.intf->netmask);
|
PRINT_IPv4(s->intf->netmask);
|
||||||
MSG("\nDNS: ");
|
MSG("\nDNS: ");
|
||||||
PRINT_IPv4(s.intf->dns);
|
PRINT_IPv4(s->intf->dns);
|
||||||
MSG("\nLease time: %u s\n", dhcpLeaseTime_s);
|
MSG("\nLease time: %u s\n", dhcpLeaseTime_s);
|
||||||
MSG("\n");
|
MSG("\n");
|
||||||
|
|
||||||
s.state = DHCP_BOUND;
|
s->state = DHCP_BOUND;
|
||||||
|
|
||||||
|
// call event callback
|
||||||
|
ethinf_trigger_event(s->intf, ETH_EVT_IP_CHANGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -320,7 +314,7 @@ static void dhcp_process(DhcpProps *props, DhcpOption *opts) {
|
|||||||
break;
|
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) {
|
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;
|
DhcpOption *opts = NULL;
|
||||||
dhcp_parse(pckt->payload, &props, &opts);
|
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);
|
dhcp_free_opt_chain(opts);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dhcp_start() {
|
void dhcp_start(DhcpState * s) {
|
||||||
s.state = DHCP_INIT;
|
s->state = DHCP_INIT;
|
||||||
dhcp_process(NULL, NULL);
|
dhcp_process(s, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dhcp_initiate(EthInterface *intf) {
|
void dhcp_initiate(EthInterface *intf) {
|
||||||
ETHLIB_OS_MTX_CREATE(&s.procMtx);
|
DhcpState * s = (DhcpState *) dynmem_alloc(sizeof(DhcpState));
|
||||||
s.state = DHCP_INIT;
|
|
||||||
s.buf = dynmem_alloc(DHCP_MIN_PACKET_SIZE);
|
ETHLIB_OS_MTX_CREATE(&s->procMtx);
|
||||||
s.desc = udp_new_connblock(intf, IPv4_ANY_ADDR, DHCP_CLIENT_PORT, dhcp_resp_cb);
|
s->state = DHCP_INIT;
|
||||||
s.intf = intf;
|
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
|
#define ETHERLIB_DHCP_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "../../eth_interface.h"
|
//#include "../../eth_interface.h"
|
||||||
|
#include "etherlib/cbd_table.h"
|
||||||
|
#include "etherlib_options.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t op; ///< Operations
|
uint8_t op; ///< Operations
|
||||||
@ -33,7 +35,7 @@ typedef enum {
|
|||||||
DHCP_REBINDING,
|
DHCP_REBINDING,
|
||||||
DHCP_BOUND,
|
DHCP_BOUND,
|
||||||
DHCP_RENEWING
|
DHCP_RENEWING
|
||||||
} DhcpState;
|
} DhcpFSMState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DHCP id codes.
|
* DHCP id codes.
|
||||||
@ -47,15 +49,27 @@ typedef enum {
|
|||||||
#define DHCP_CLIENT_PORT (68)
|
#define DHCP_CLIENT_PORT (68)
|
||||||
#define DHCP_SERVER_PORT (67)
|
#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
|
* Initiate DHCP on interface
|
||||||
* @param intf 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
|
#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));
|
Timer * tmr = (Timer *) dynmem_alloc(sizeof(Timer) + maxSched * sizeof(AlarmAssignment));
|
||||||
ASSERT_NULL(tmr);
|
ASSERT_NULL(tmr);
|
||||||
|
|
||||||
|
ETHLIB_OS_MTX_CREATE(&tmr->tabMtx);
|
||||||
tmr->maxSched = maxSched;
|
tmr->maxSched = maxSched;
|
||||||
tmr->nSched = 0;
|
tmr->nSched = 0;
|
||||||
tmr->nextAlarm = NULL;
|
tmr->nextAlarm = NULL;
|
||||||
@ -87,6 +88,8 @@ uint32_t timer_sched(Timer * tmr, const TimePoint * t, TimerAlarmCb cb, AlarmUse
|
|||||||
return TIMER_SCHED_FAILED;
|
return TIMER_SCHED_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ETHLIB_OS_MTX_LOCK(&(tmr->tabMtx));
|
||||||
|
|
||||||
// if we can schedule get the first unused block
|
// 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);
|
||||||
|
|
||||||
@ -106,6 +109,10 @@ uint32_t timer_sched(Timer * tmr, const TimePoint * t, TimerAlarmCb cb, AlarmUse
|
|||||||
tmr->nextAlarm = slot;
|
tmr->nextAlarm = slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timer_report(tmr);
|
||||||
|
|
||||||
|
ETHLIB_OS_MTX_UNLOCK(&(tmr->tabMtx));
|
||||||
|
|
||||||
return slot->id;
|
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) {
|
void timer_unsched(Timer * tmr, uint32_t id) {
|
||||||
|
ETHLIB_OS_MTX_LOCK(&(tmr->tabMtx));
|
||||||
|
|
||||||
AlarmAssignment * alarm = timer_get_alarm_by_id(tmr, id);
|
AlarmAssignment * alarm = timer_get_alarm_by_id(tmr, id);
|
||||||
if (alarm != NULL) {
|
if (alarm != NULL) {
|
||||||
memset(alarm, 0, sizeof(AlarmAssignment));
|
memset(alarm, 0, sizeof(AlarmAssignment));
|
||||||
tmr->nSched--;
|
tmr->nSched--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ETHLIB_OS_MTX_UNLOCK(&(tmr->tabMtx));
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_set_time(Timer *tmr, const TimePoint *t) {
|
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)) {
|
if ((tmr->nSched > 0) && (tmr->nextAlarm != NULL)) {
|
||||||
int64_t t_alarm = time_to_us(&(tmr->nextAlarm->time));
|
int64_t t_alarm = time_to_us(&(tmr->nextAlarm->time));
|
||||||
while (((t_alarm - t_us) <= 0) && (tmr->nSched > 0)) {
|
while (((t_alarm - t_us) <= 0) && (tmr->nSched > 0)) {
|
||||||
// invoke callback
|
if (ETHLIB_OS_MTX_LOCK(&(tmr->tabMtx)) != 0) {
|
||||||
if (tmr->nextAlarm->cb != NULL) {
|
return; // break from the loop, since we cannot lock the mutex
|
||||||
tmr->nextAlarm->cb(tmr, tmr->nextAlarm->params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timer_report(tmr);
|
||||||
|
|
||||||
|
// fetch alarm (obtain a COPY)
|
||||||
|
AlarmAssignment alarm = *(tmr->nextAlarm);
|
||||||
|
|
||||||
// clear alarm descriptor
|
// clear alarm descriptor
|
||||||
memset(tmr->nextAlarm, 0, sizeof(AlarmAssignment));
|
memset(tmr->nextAlarm, 0, sizeof(AlarmAssignment));
|
||||||
|
|
||||||
@ -159,11 +174,20 @@ void timer_tick(Timer * tmr, int64_t us) {
|
|||||||
|
|
||||||
// update nearest alarm
|
// update nearest alarm
|
||||||
timer_update_nearest_alarm(tmr);
|
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) {
|
if (tmr->nextAlarm != NULL) {
|
||||||
t_alarm = time_to_us(&(tmr->nextAlarm->time));
|
t_alarm = time_to_us(&(tmr->nextAlarm->time));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_report(const Timer * tmr) {
|
void timer_report(const Timer * tmr) {
|
||||||
|
3
timer.h
3
timer.h
@ -4,6 +4,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <etherlib_options.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A single point in time
|
* A single point in time
|
||||||
*/
|
*/
|
||||||
@ -61,6 +63,7 @@ typedef struct {
|
|||||||
* Timer class
|
* Timer class
|
||||||
*/
|
*/
|
||||||
typedef struct Timer_ {
|
typedef struct Timer_ {
|
||||||
|
ETHLIB_OS_MTX_TYPE tabMtx; ///< Mutex protecting the scheduling table
|
||||||
TimePoint time; ///< Absolute time
|
TimePoint time; ///< Absolute time
|
||||||
AlarmAssignment * nextAlarm; ///< Nearest alarm
|
AlarmAssignment * nextAlarm; ///< Nearest alarm
|
||||||
uint32_t maxSched; ///< Maximum number of scheduled alarms
|
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 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_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_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__)
|
#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