void javax_wukong_wkpf_WKPF_boolean_isLocalComponent_short() { uint16_t component_id = (int16_t)dj_exec_stackPopShort(); wkcomm_address_t node_id; uint8_t port_number; wkpf_error_code = wkpf_get_node_and_port_for_component(component_id, &node_id, &port_number); dj_exec_stackPushShort(wkpf_error_code == WKPF_OK && node_id == wkcomm_get_node_id()); }
uint8_t wkpf_propagate_property(wuobject_t *wuobject, uint8_t property_number, void *value) { uint8_t port_number = wuobject->port_number; uint16_t component_id; if (!wkpf_get_component_id(port_number, &component_id)) return WKPF_OK; // WuObject isn't used in the application. wuobject_t *src_wuobject; uint8_t wkpf_error_code; DEBUG_LOG(DBG_WKPF, "WKPF: propagate property number %x of component %x on port %x (value %x)\n", property_number, component_id, port_number, *((uint16_t *)value)); // TODONR: values other than 16 bit values wkpf_get_wuobject_by_port(port_number, &src_wuobject); for(int i=0; i<wkpf_number_of_links; i++) { wkpf_link_t *link = wkpf_get_link(i); if(link->src_component_id == component_id && link->src_property_number == property_number) { uint16_t dest_component_id = link->dest_component_id; uint8_t dest_property_number = link->dest_property_number; uint8_t dest_port_number = wkpf_leader_for_component(dest_component_id).port_number; address_t dest_node_id = wkpf_leader_for_component(dest_component_id).node_id; if (dest_node_id == wkcomm_get_node_id()) { // Local wuobject_t *dest_wuobject; wkpf_error_code = wkpf_get_wuobject_by_port(dest_port_number, &dest_wuobject); if (wkpf_error_code == WKPF_OK) { DEBUG_LOG(DBG_WKPF, "WKPF: propagate_property (local). (%x, %x)->(%x, %x), value %x\n", port_number, property_number, dest_port_number, dest_property_number, *((uint16_t *)value)); // TODONR: values other than 16 bit values if (WKPF_GET_PROPERTY_DATATYPE(src_wuobject->wuclass->properties[property_number]) == WKPF_PROPERTY_TYPE_BOOLEAN) wkpf_error_code = wkpf_external_write_property_boolean(dest_wuobject, dest_property_number, *((bool *)value)); else if (WKPF_GET_PROPERTY_DATATYPE(src_wuobject->wuclass->properties[property_number]) == WKPF_PROPERTY_TYPE_SHORT) wkpf_error_code = wkpf_external_write_property_int16(dest_wuobject, dest_property_number, *((uint16_t *)value)); else wkpf_error_code = wkpf_external_write_property_refresh_rate(dest_wuobject, dest_property_number, *((uint16_t *)value)); } } else { // Remote DEBUG_LOG(DBG_WKPF, "WKPF: propagate_property (remote). (%x, %x)->(%x, %x, %x), value %x\n", port_number, property_number, dest_node_id, dest_port_number, dest_property_number, *((uint16_t *)value)); // TODONR: values other than 16 bit values if (WKPF_GET_PROPERTY_DATATYPE(src_wuobject->wuclass->properties[property_number]) == WKPF_PROPERTY_TYPE_BOOLEAN) wkpf_error_code = wkpf_send_set_property_boolean(dest_node_id, dest_port_number, dest_property_number, link->dest_wuclass_id, *((bool *)value)); else if (WKPF_GET_PROPERTY_DATATYPE(src_wuobject->wuclass->properties[property_number]) == WKPF_PROPERTY_TYPE_SHORT) wkpf_error_code = wkpf_send_set_property_int16(dest_node_id, dest_port_number, dest_property_number, link->dest_wuclass_id, *((uint16_t *)value)); else wkpf_error_code = wkpf_send_set_property_refresh_rate(dest_node_id, dest_port_number, dest_property_number, link->dest_wuclass_id, *((uint16_t *)value)); } if (wkpf_error_code != WKPF_OK) return wkpf_error_code; } } return WKPF_OK; }
bool wkpf_get_component_id(uint8_t port_number, uint16_t *component_id) { for(int i=0; i<wkpf_number_of_components; i++) { wkpf_component_t *component = wkpf_get_component(i); uint16_t number_of_endpoints = wkpf_number_of_endpoints(component); for(int j=0; j<number_of_endpoints; j++) { wkpf_endpoint_t *endpoint = wkpf_get_endpoint_for_component(component, j); if(endpoint->node_id == wkcomm_get_node_id() && endpoint->port_number == port_number) { *component_id = i; return true; // Found } } } return false; // Not found. Could happen for wuobjects that aren't used in the application (unused sensors, actuators, etc). }
uint8_t wkpf_pull_property(uint8_t port_number, uint8_t property_number) { uint16_t component_id; wkpf_get_component_id(port_number, &component_id); for(int i=0; i<wkpf_number_of_links; i++) { wkpf_link_t *link = wkpf_get_link(i); if(link->dest_component_id == component_id && link->dest_property_number == property_number) { uint16_t src_component_id = link->src_component_id; wkpf_endpoint_t src_endpoint = wkpf_leader_for_component(src_component_id); uint8_t src_property_number = link->src_property_number; if (src_endpoint.node_id != wkcomm_get_node_id()) { // Properties with local sources will be initialised eventually, so we only need to send a message // to ask for initial values coming from remote nodes return wkpf_send_request_property_init(src_endpoint.node_id, src_endpoint.port_number, src_property_number); } } } return WKPF_ERR_SHOULDNT_HAPPEN; }
void javax_wukong_wkpf_WKPF_void_setPropertyRefreshRate_short_byte_short() { int16_t value = (int16_t)dj_exec_stackPopShort(); uint8_t property_number = (uint8_t)dj_exec_stackPopShort(); uint16_t component_id = (uint16_t)dj_exec_stackPopShort(); address_t node_id; uint8_t port_number; wkpf_error_code = wkpf_get_node_and_port_for_component(component_id, &node_id, &port_number); if (wkpf_error_code == WKPF_OK) { if (node_id != wkcomm_get_node_id()) wkpf_error_code = WKPF_ERR_REMOTE_PROPERTY_FROM_JAVASET_NOT_SUPPORTED; else { wuobject_t *wuobject; wkpf_error_code = wkpf_get_wuobject_by_port(port_number, &wuobject); if (wkpf_error_code == WKPF_OK) { DEBUG_LOG(DBG_WKPF, "WKPF: setPropertyRefreshRate (local). Port %x, property %x, value %x\n", port_number, property_number, value); wkpf_error_code = wkpf_external_write_property_refresh_rate(wuobject, property_number, value); } } } }
bool wkpf_does_property_need_initialisation_pull(uint8_t port_number, uint8_t property_number) { uint16_t component_id; wkpf_get_component_id(port_number, &component_id); for(int i=0; i<wkpf_number_of_links; i++) { wkpf_link_t *link = wkpf_get_link(i); if (link->dest_component_id == component_id && link->dest_property_number == property_number) { // The property is the destination of this link. If the source is remote, we need to ask for an initial value if (wkpf_node_is_leader(link->src_component_id, wkcomm_get_node_id())) { DEBUG_LOG(DBG_WKPF, "%x, %x doesn't need pull: source is a local property\n", port_number, property_number); return false; // Source link is local, so no need to pull initial value as it will come automatically. } else { DEBUG_LOG(DBG_WKPF, "%x, %x needs initialisation pull\n", port_number, property_number); return true; // There is a link to this property, coming from another node. We need to ask it for the initial value. } } } DEBUG_LOG(DBG_WKPF, "%x, %x doesn't need pull: not a destination property\n", port_number, property_number); return false; // This wuobject isn't used in the application. }
uint8_t wkpf_load_component_to_wuobject_map(dj_ref_array *map) { wkpf_component_map_store = map; // After storing the reference, only use the constants defined above to access it so that we may change the storage implementation later DEBUG_LOG(DBG_WKPF, "WKPF: Registering %x components\n", wkpf_number_of_components); #ifdef DARJEELING_DEBUG for (int i=0; i<wkpf_number_of_components; i++) { DEBUG_LOG(DBG_WKPF, "WKPF: Component %d -> ", i); wkpf_component_t *component = wkpf_get_component(i); for (int j=0; j<wkpf_number_of_endpoints(component); j++) { wkpf_endpoint_t *endpoint = wkpf_get_endpoint_for_component(component, j); DEBUG_LOG(DBG_WKPF, " (node %d, port %d)", endpoint->node_id, endpoint->port_number); } DEBUG_LOG(DBG_WKPF, "\n"); } #endif // DARJEELING_DEBUG // TODONR: nieuwe constante bedenken en implementatie van group_add_node_to_watch en wkcomm_get_node_id #ifdef NVM_USE_GROUP for (int i=0; i<wkpf_number_of_components; i++) { wkpf_component_t *component = wkpf_get_component(i); for (int j=0; j<wkpf_number_of_endpoints(component); j++) { wkpf_endpoint_t *endpoint = wkpf_get_endpoint_for_component(component, j); if (endpoint->node_id == wkcomm_get_node_id()) { if (j == 0) { // I'm the leader, so watch everyone for (int k=1; k<wkpf_number_of_endpoints(component); k++) group_add_node_to_watch(wkpf_get_endpoint_for_component(component, k)->node_id); } else { // Just watch the leader group_add_node_to_watch(wkpf_get_endpoint_for_component(component, 0)->node_id); } } } } #endif // NVM_USE_GROUP return WKPF_OK; }
void javax_wukong_wkpf_WKPF_short_getMyNodeId() { dj_exec_stackPushShort(wkcomm_get_node_id()); }