diff --git a/src/topo_ieee1905.c b/src/topo_ieee1905.c index 00c827a24106ac5af06d1338a5a71fa3fa7c37f9..e72b08c1825c9f7707834a7fa7b997e4e65294ba 100644 --- a/src/topo_ieee1905.c +++ b/src/topo_ieee1905.c @@ -56,6 +56,11 @@ static int topologyd_copy_update_node(struct node *dest, struct node *src) for (j = 0; j < src->local_intf_nbr; j++) { memcpy(dest->node_intf[j].interface_id, src->node_intf[j].interface_id, 6); dest->node_intf[j].media_type = src->node_intf[j].media_type; + //Here we fill the power status data also + dest->node_intf[j].power_status = src->node_intf[j].power_status; + memset(dest->node_intf[j].generic_phy_oui, 0, sizeof(dest->node_intf[j].generic_phy_oui)); + dest->node_intf[j].generic_phy_variant = 0; + memset(dest->node_intf[j].generic_phy_url, 0, sizeof(dest->node_intf[j].generic_phy_url)); //Here we also need to fill the media specific //data for the interface dest->node_intf[j].media_specific_data_size = src->node_intf[j].media_specific_data_size; @@ -237,6 +242,9 @@ void topologyd_algo_run(struct topologyd_private *priv) dbg("sending linkmetric req to " MACFMT "\n", MAC2STR(p->hwaddr)); //topologyd_getdata_lnmetric_query(&tlv_metric); topologyd_send_ieee1905_query(priv, p->hwaddr, CMDU_TYPE_LINK_METRIC_QUERY, p->ingress_ifr_name, NULL); + //Here sending the generic phy query + dbg("sending generic phy query req to " MACFMT "\n", MAC2STR(p->hwaddr)); + topologyd_send_ieee1905_query(priv, p->hwaddr, CMDU_TYPE_GENERIC_PHY_QUERY, p->ingress_ifr_name, NULL); } } diff --git a/src/topologyd.c b/src/topologyd.c index 8ea40c3f05244368e04a72a3b89b3ab0bdb636ba..065887d18430e62faa056ed66e812849c563ae35 100644 --- a/src/topologyd.c +++ b/src/topologyd.c @@ -196,7 +196,7 @@ void topologyd_event_handler(struct ubus_context *ctx, dbg("Inside topology event handler %hu %hu %s", msg_type, msg_mid, itfr_name); - if (!((msg_type == CMDU_TYPE_TOPOLOGY_RESPONSE) || (msg_type == CMDU_TYPE_TOPOLOGY_NOTIFICATION) || (msg_type == CMDU_TYPE_AP_AUTOCONFIGURATION_RESPONSE) || (msg_type == CMDU_TYPE_HIGHER_LAYER_RESPONSE) || (msg_type == CMDU_TYPE_LINK_METRIC_RESPONSE))) { + if (!((msg_type == CMDU_TYPE_TOPOLOGY_RESPONSE) || (msg_type == CMDU_TYPE_TOPOLOGY_NOTIFICATION) || (msg_type == CMDU_TYPE_AP_AUTOCONFIGURATION_RESPONSE) || (msg_type == CMDU_TYPE_HIGHER_LAYER_RESPONSE) || (msg_type == CMDU_TYPE_LINK_METRIC_RESPONSE) || (msg_type == CMDU_TYPE_GENERIC_PHY_RESPONSE))) { if (tlv != NULL) free(tlv); return; @@ -245,6 +245,12 @@ void topologyd_event_handler(struct ubus_context *ctx, } break; + case CMDU_TYPE_GENERIC_PHY_RESPONSE: + { + dbg("Received a generic phy response\n"); + topologyd_process_generic_phy_response(cstruct, priv); + } + break; default: dbg("Event handler received default message\n"); break; @@ -288,6 +294,8 @@ void topologyd_process_topology_response(struct cmdu_cstruct *cstruct, struct to for (j = 0; j < n.local_intf_nbr; j++) { memcpy(n.node_intf[j].interface_id, &tlv->local_interfaces[j].mac_address, 6); n.node_intf[j].media_type = tlv->local_interfaces[j].media_type; + //Here we by default make the interface power as on + n.node_intf[j].power_status = 0; //Here we also need to fill the media specific //data for the interface @@ -306,6 +314,21 @@ void topologyd_process_topology_response(struct cmdu_cstruct *cstruct, struct to } } break; + case TLV_TYPE_POWER_OFF_INTERFACE: + { + struct powerOffInterfaceTLV *tlv = (struct powerOffInterfaceTLV *)p; + int res = 0; + + for (j = 0; j < tlv->power_off_interfaces_nr; j++) { + for (k = 0; k < n.local_intf_nbr; k++) { + res = memcmp(tlv->power_off_interfaces[j].interface_address, n.node_intf[k].interface_id, 6); + if (res != 0) + continue; + n.node_intf[k].power_status = 1; + } + } + } + break; case TLV_TYPE_NEIGHBOR_DEVICE_LIST: { struct neighborDeviceListTLV *tlv = @@ -685,7 +708,81 @@ void topology_add_txrx_data(uint8_t *metric, struct topologyd_private *priv) } } +void topologyd_process_generic_phy_response(struct cmdu_cstruct *cstruct, struct topologyd_private *priv) +{ + int i = 0; + uint8_t *p; + if (cstruct == NULL || priv == NULL) + return; + + dbg("Inside Geniric Phy response\n"); + while (NULL != (p = cstruct->tlv_cstruct_list[i])) { + + switch (*p) { + case TLV_TYPE_GENERIC_PHY_DEVICE_INFORMATION: + { + dbg(" Inside generic_phy_device_info\n"); + topology_add_generic_phy_data(p, priv); + //struct genericPhyDeviceInformationTypeTLV t = (struct genericPhyDeviceInformationTypeTLV *)p; + + } + break; + case TLV_TYPE_VENDOR_SPECIFIC: + { + //Nothing to do with the vendor tlv now + } + break; + } + i++; + } +} + +void topology_add_generic_phy_data(uint8_t *phy, struct topologyd_private *priv) +{ + uint8_t fr_al_mac_id[6]; + uint32_t i, j, res; + struct node *n = NULL; + + if (phy == NULL) + return; + + err("Updating Node with the generic phy response message\n"); + + if (*phy == TLV_TYPE_GENERIC_PHY_DEVICE_INFORMATION) { + dbg(" Inside the generic phy info tlv\n"); + struct genericPhyDeviceInformationTypeTLV *ptr; + + ptr = (struct genericPhyDeviceInformationTypeTLV *)phy; + + memcpy(fr_al_mac_id, ptr->al_mac_address, 6); + + res = memcmp(fr_al_mac_id, priv->selfnode.hwaddr, 6); + if (res == 0) { + dbg(" The generic phy resp corresponds to the self node we are ignoring this details\n"); + return; + } + + n = node_lookup(priv->topo.node_htable, fr_al_mac_id); + + //If we find the node in our devices + if (n != NULL) { + //getting the interface for which this information is given + for (i = 0; i < ptr->local_interfaces_nr; i++) { + for (j = 0; j < n->local_intf_nbr; j++) { + + res = memcmp(ptr->local_interfaces[i].local_interface_address, n->node_intf[j].interface_id, 6); + if (res != 0) + continue; + memcpy(n->node_intf[j].generic_phy_oui, ptr->local_interfaces[i].generic_phy_common_data.oui, 3); + n->node_intf[j].generic_phy_variant = ptr->local_interfaces[i].generic_phy_common_data.variant_index; + if (ptr->local_interfaces[i].generic_phy_description_xml_url_len > 0) + memcpy(n->node_intf[j].generic_phy_url, ptr->local_interfaces[i].generic_phy_description_xml_url, ptr->local_interfaces[i].generic_phy_description_xml_url_len); + } + } + } + } +} void topologyd_dump_node(struct blob_buf *bb, struct node *p, int is_self) { @@ -699,6 +796,7 @@ void topologyd_dump_node(struct blob_buf *bb, struct node *p, int is_self) int j, k, flag = 0, i = 0; char addr[16] = {0}; char addr_v6[40] = {0}; + char oui[10] = {0}; hwaddr_ntoa(p->hwaddr, mac_str); blobmsg_add_string(bb, "ieee1905_macaddr", mac_str); @@ -775,6 +873,15 @@ void topologyd_dump_node(struct blob_buf *bb, struct node *p, int is_self) hwaddr_ntoa(p->node_intf[j].interface_id, mac_str); blobmsg_add_string(bb, "interface_id", mac_str); blobmsg_add_string(bb, "media_type", get_interface_type_string(p->node_intf[j].media_type)); + blobmsg_add_string(bb, "power_status", + p->node_intf[j].power_status ? "off" : "on"); + sprintf(oui, "%02x.%02x.%02x", + p->node_intf[j].generic_phy_oui[0], p->node_intf[j].generic_phy_oui[1], p->node_intf[j].generic_phy_oui[2]); + oui[9] = '\0'; + blobmsg_add_string(bb, "generic_phy_oui", oui); + blobmsg_add_u8(bb, "generic_phy_variant", p->node_intf[j].generic_phy_variant); + blobmsg_add_string(bb, "generic_phy_url", p->node_intf[j].generic_phy_url); + blobmsg_add_u32(bb, "ap_channel_band", p->node_intf[j].ap_channel_band); if (p->node_intf[j].media_specific_data_size == 10) { hwaddr_ntoa(p->node_intf[j].network_membership, mac_str); blobmsg_add_string(bb, "network_membership", mac_str); @@ -1330,13 +1437,14 @@ int topologyd_start(void) priv->refresh_timer.cb = topologyd_periodic_refresh; priv->heartbeat.cb = topologyd_start_heartbeat; - priv->topo.changelog = (struct topology_changelog *) malloc - ((priv->config.maxlog)*sizeof(struct topology_changelog)); + priv->topo.changelog = (struct topology_changelog *) calloc + ((priv->config.maxlog), sizeof(struct topology_changelog)); if (priv->topo.changelog == NULL) goto out_and_exit; topology_log_max = priv->config.maxlog; dbg("Dynamic array size %d", priv->config.maxlog); + priv->topo.changelog_front = priv->topo.changelog_rear = -1; priv->status = 0; priv->status_timer.cb = topologyd_change_status; diff --git a/src/topologyd.h b/src/topologyd.h index d983623fc3adf9c8b2bcbe780c313c8d50de8012..9e4811d486387b517288e23c76e18e75113ab4d9 100644 --- a/src/topologyd.h +++ b/src/topologyd.h @@ -46,12 +46,6 @@ typedef uint32_t ieee1905_object_t; #define MDNS_TXT_RECORDS_MAX 16 #define MDNS_NO_SERVICES_MAX 16 -enum power_state { - POWER_ON = 0, - POWER_OFF, - POWER_SAVE, - POWER_UNSUPPORTED -}; struct text_record_t { char key[256]; @@ -116,9 +110,9 @@ struct l2_nbr_t { struct node_interface { uint8_t interface_id[6]; uint16_t media_type; - enum power_state power_status; - char generic_phy_oui[50]; - char generic_phy_variant[50]; + uint8_t power_status; + uint8_t generic_phy_oui[3]; + uint8_t generic_phy_variant; char generic_phy_url[1024]; uint8_t media_specific_data_size; uint8_t network_membership[6]; @@ -249,6 +243,8 @@ void topologyd_process_autoconfiguration_response(struct cmdu_cstruct *cstruct, void topologyd_process_higherlayer_response(struct cmdu_cstruct *cstruct, struct topologyd_private *priv); void topologyd_process_linkmetric_response(struct cmdu_cstruct *cstruct, struct topologyd_private *priv); void topology_add_txrx_data(uint8_t *metric, struct topologyd_private *priv); +void topologyd_process_generic_phy_response(struct cmdu_cstruct *cstruct, struct topologyd_private *priv); +void topology_add_generic_phy_data(uint8_t *phy, struct topologyd_private *priv); //Function to get string from enum const char *get_interface_type_string(uint16_t if_type);