Skip to content
Snippets Groups Projects
Commit 8cb4ab71 authored by Anjan Chanda's avatar Anjan Chanda
Browse files

enhance cmdu_parse() and add handlers for rx-cmdus

parent 4944b2f0
Branches
Tags
No related merge requests found
......@@ -261,9 +261,10 @@ int cmdu_put(struct cmdu_buff *c, uint8_t *bytes, int len)
return 0;
}
int cmdu_parse_tlvs(struct cmdu_buff *c, struct tlv *tv[],
int cmdu_parse_tlvs(struct cmdu_buff *c, struct tlv *tv[][16],
struct tlv_policy *policy, int policy_len)
{
int idx[policy_len];
struct tlv *t;
int len;
int i;
......@@ -272,7 +273,10 @@ int cmdu_parse_tlvs(struct cmdu_buff *c, struct tlv *tv[],
if (!c)
return -1;
memset(tv, 0, policy_len * sizeof(struct tlv *));
for (i = 0; i < policy_len; i++) {
memset(tv[i], 0, 16 * sizeof(struct tlv *));
idx[i] = 0;
}
len = c->datalen;
cmdu_for_each_tlv(t, c->data, len) {
......@@ -288,10 +292,12 @@ int cmdu_parse_tlvs(struct cmdu_buff *c, struct tlv *tv[],
tlv_length(t) > policy[i].maxlen)
continue;
if (tv[i])
continue;
if (tv[i][0]) {
if (policy[i].present == TLV_PRESENT_ONE)
continue;
}
tv[i] = t;
tv[i][idx[i]++] = t;
}
}
......
......@@ -45,11 +45,18 @@ struct cmdu_buff {
struct list_head list;
};
enum tlv_presence {
TLV_PRESENT_UNDEFINED,
TLV_PRESENT_ONE,
TLV_PRESENT_MORE,
TLV_PRESENT_NUM,
};
struct tlv_policy {
uint8_t type;
uint16_t minlen;
uint16_t maxlen;
enum tlv_presence present;
};
struct tlv {
......@@ -80,7 +87,7 @@ uint16_t cmdu_get_next_mid(void);
int cmdu_validate(struct cmdu_buff *c, int max_tlvtype,
struct tlv_policy *policy);
int cmdu_parse_tlvs(struct cmdu_buff *c, struct tlv *tv[],
int cmdu_parse_tlvs(struct cmdu_buff *c, struct tlv *tv[][16],
struct tlv_policy *policy, int policy_len);
......
......@@ -45,12 +45,287 @@
#include "lldp_tlvs.h"
#define CMDU_TYPE_1905_START 0x0001
#define CMDU_TYPE_1905_END 0x0009
int i1905_handle_topology_discovery(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
struct tlv_policy a_policy[] = {
[0] = { .type = TLV_TYPE_AL_MAC_ADDRESS_TYPE, .present = TLV_PRESENT_ONE },
[1] = { .type = TLV_TYPE_MAC_ADDRESS_TYPE, .present = TLV_PRESENT_ONE },
};
struct tlv *tv[2][16];
uint8_t aladdr_origin[6] = {0};
uint8_t macaddr_origin[6] = {0};
int ret;
cmdu_parse_tlvs(rxf, tv, a_policy, 2);
if (tv[0][0])
memcpy(aladdr_origin, tv[0][0]->data, tlv_length(tv[0][0]));
if (tv[1][0])
memcpy(macaddr_origin, tv[1][0]->data, tlv_length(tv[1][0]));
if (hwaddr_is_zero(macaddr_origin)) {
fprintf(stderr, "%s: Discard topo discovery from src = 0!\n",
__func__);
return -1;
}
ret = i1905_dm_neighour_update(i1905_interface_priv(pif),
aladdr_origin, macaddr_origin);
if (ret) {
fprintf(stderr, "%s: Error updating DM for neighbor " MACFMT"\n",
__func__, MAC2STR(macaddr_origin));
return -1;
}
return 0;
}
int i1905_handle_topology_notification(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
struct tlv_policy a_policy[] = {
[0] = { .type = TLV_TYPE_AL_MAC_ADDRESS_TYPE, .present = TLV_PRESENT_ONE },
};
struct tlv *tv[1][16];
uint8_t aladdr_origin[6] = {0};
int ret;
cmdu_parse_tlvs(rxf, tv, a_policy, 1);
if (tv[0][0])
memcpy(aladdr_origin, tv[0][0]->data, tlv_length(tv[0][0]));
if (hwaddr_is_zero(aladdr_origin)) {
fprintf(stderr, "%s: Discard topo notification from aladdr = 0!\n",
__func__);
return -1;
}
ret = i1905_dm_neighour_update(i1905_interface_priv(pif),
aladdr_origin, NULL);
if (ret) {
fprintf(stderr, "%s: Error updating DM for neighbor " MACFMT"\n",
__func__, MAC2STR(aladdr_origin));
return -1;
}
return 0;
}
int i1905_handle_topology_query(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
//TODO
return 0;
}
int i1905_handle_topology_response(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
struct tlv_policy a_policy[] = {
[0] = { .type = TLV_TYPE_DEVICE_INFORMATION_TYPE, .present = TLV_PRESENT_ONE },
[1] = { .type = TLV_TYPE_DEVICE_BRIDGING_CAPABILITIES, .present = TLV_PRESENT_MORE },
[2] = { .type = TLV_TYPE_NON_1905_NEIGHBOR_DEVICE_LIST, .present = TLV_PRESENT_MORE },
[3] = { .type = TLV_TYPE_NEIGHBOR_DEVICE_LIST, .present = TLV_PRESENT_MORE },
[4] = { .type = TLV_TYPE_POWER_OFF_INTERFACE, .present = TLV_PRESENT_MORE},
[5] = { .type = TLV_TYPE_L2_NEIGHBOR_DEVICE, .present = TLV_PRESENT_MORE },
};
struct tlv *tv[6][16];
uint8_t aladdr_origin[6] = {0};
uint8_t macaddr_origin[6] = {0};
int ret;
cmdu_parse_tlvs(rxf, tv, a_policy, 6);
#if 0
if (hwaddr_is_zero(macaddr_origin)) {
fprintf(stderr, "%s: Discard topo discovery from src = 0!\n",
__func__);
return -1;
}
ret = i1905_dm_neighour_update(i1905_interface_priv(pif),
aladdr_origin, macaddr_origin);
if (ret) {
fprintf(stderr, "%s: Error updating DM for neighbor " MACFMT"\n",
__func__, MAC2STR(macaddr_origin));
return -1;
}
#endif
return 0;
}
int i1905_handle_vendor_request(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
//TODO
return 0;
}
int i1905_handle_link_metric_query(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
//TODO
return 0;
}
int i1905_handle_link_metric_response(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
//TODO
return 0;
}
int i1905_handle_ap_autoconfig_search(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
//TODO
return 0;
}
int i1905_handle_ap_autoconfig_response(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
//TODO
return 0;
}
int i1905_handle_ap_autoconfig_renew(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
//TODO
return 0;
}
int i1905_handle_ap_autoconfig_wsc(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
//TODO
return 0;
}
int i1905_handle_pbc_notification(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
//TODO
return 0;
}
int i1905_handle_pbc_join_notification(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
//TODO
return 0;
}
int i1905_handle_higherlayer_query(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
//TODO
return 0;
}
int i1905_handle_higherlayer_response(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
//TODO
return 0;
}
int i1905_handle_interface_power_request(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
//TODO
return 0;
}
int i1905_handle_interface_power_response(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
//TODO
return 0;
}
int i1905_handle_generic_phy_query(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
//TODO
return 0;
}
int i1905_handle_generic_phy_response(struct i1905_interface_private *pif,
struct cmdu_buff *rxf)
{
//TODO
return 0;
}
typedef int (*cmdu_handler_t)(struct i1905_interface_private *ifp,
struct cmdu_buff *rxf);
static const cmdu_handler_t i1905ftable[] = {
[0x00] = i1905_handle_topology_discovery,
[0x01] = i1905_handle_topology_notification,
[0x02] = i1905_handle_topology_query,
[0x03] = i1905_handle_topology_response,
[0x04] = i1905_handle_vendor_request,
[0x05] = i1905_handle_link_metric_query,
[0x06] = i1905_handle_link_metric_response,
[0x07] = i1905_handle_ap_autoconfig_search,
[0x08] = i1905_handle_ap_autoconfig_response,
[0x09] = i1905_handle_ap_autoconfig_wsc,
[0x0a] = i1905_handle_ap_autoconfig_renew,
[0x0b] = i1905_handle_pbc_notification,
[0x0c] = i1905_handle_pbc_join_notification,
[0x0d] = i1905_handle_higherlayer_query,
[0x0e] = i1905_handle_higherlayer_response,
[0x0f] = i1905_handle_interface_power_request,
[0x10] = i1905_handle_interface_power_response,
[0x11] = i1905_handle_generic_phy_query,
[0x11] = i1905_handle_generic_phy_response,
};
int i1905_process_cmdu(struct i1905_interface_private *pif, struct cmdu_buff *rxf)
{
uint16_t type;
int ret;
if (!rxf->cdata)
return -1;
// TODO: discard duplicates
type = buf_get_be16(rxf->cdata->hdr.type);
if (i1905ftable[type]) {
ret = i1905ftable[type](pif, rxf);
}
fprintf(stderr, "%s: ----->\n", __func__);
return 0;
return ret;
}
......@@ -71,6 +71,7 @@ extern struct i1905_dm *i1905_dm_get();
extern int i1905_dm_init(struct i1905_dm *dm);
extern int i1905_dm_free(struct i1905_dm *dm);
extern int i1905_dm_neighour_update(struct i1905_interface *iface,
uint8_t *aladdr, uint8_t *macaddr);
#endif /* I1905_H */
......@@ -30,6 +30,19 @@
int i1905_dm_neighour_update(struct i1905_interface *iface, uint8_t *aladdr,
uint8_t *macaddr)
{
//TODO: lookup aladdr/macaddr in DM
// if not available, add to DM
// if available, update tsp
//
// if tsp_lastupdated = 0 or > 10 secs, send topo query
return 0;
}
int i1905_dm_init(struct i1905_dm *dm)
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment