コード例 #1
0
bool wkpf_get_next_wuobject_to_update(wuobject_t **virtual_wuobject) {
	if (wuobjects_list == NULL)
		return false;
	wuobject_t *wuobject;
	if (wkpf_get_wuobject_by_index(last_updated_wuobject_index, &wuobject) == WKPF_ERR_WUOBJECT_NOT_FOUND) { // Could happen if objects were deleted
		wuobject = wuobjects_list;
		last_updated_wuobject_index = 0;
	}
	uint16_t current_index = last_updated_wuobject_index;

	// wuobject is now pointing to the last updated object
	do {
		// Find the first next object that needs to be updated, or the same if there's no other.
		// Find next object
		wuobject = wuobject->next;
		current_index++;
		if (wuobject == NULL) {
			wuobject = wuobjects_list; // Wrap around to the first object.
			current_index = 0;
		}

		// Does it need to be updated?
		if ((wuobject->next_scheduled_update > 0 && wuobject->next_scheduled_update < dj_timer_getTimeMillis())
				|| wuobject->need_to_call_update) {
			// Update this object
			// Clear the flag if it was set
			wuobject->need_to_call_update = false;
			// If update has to be called because it's scheduled, schedule the next call
			if (wuobject->next_scheduled_update > 0 && wuobject->next_scheduled_update < dj_timer_getTimeMillis())
				wkpf_schedule_next_update_for_wuobject(wuobject);
			if (WKPF_IS_NATIVE_WUOBJECT(wuobject)) { // For native wuobjects: call update() directly
				// Mark wuobject as safe just in case the wuclass does something to trigger GC
				dj_mem_addSafePointer((void**)&wuobject);
				DEBUG_LOG(DBG_WKPFUPDATE, "WKPFUPDATE: Update native wuobject at port %x\n", wuobject->port_number);
				wuobject->wuclass->update(wuobject);
				dj_mem_removeSafePointer((void**)&wuobject);
			} else { // For virtual wuobject: return it so WKPF.select() can return it to Java
				*virtual_wuobject = wuobject;
				last_updated_wuobject_index = current_index;
				DEBUG_LOG(DBG_WKPFUPDATE, "WKPFUPDATE: Update virtual wuobject at port %x\n", wuobject->port_number);
				return true;
			}
		}
	} while(current_index != last_updated_wuobject_index);
	return false; // No Java wuobjects need to be updated
}
コード例 #2
0
// This is here instead of in wkpf_properties so we can directly access the wuobjects list.
bool wkpf_get_next_dirty_property(wuobject_t **dirty_wuobject, uint8_t *dirty_property_number) {
	if (wuobjects_list == NULL)
		return false;
	wuobject_t *wuobject;
	if (wkpf_get_wuobject_by_index(last_propagated_property_wuobject_index, &wuobject) == WKPF_ERR_WUOBJECT_NOT_FOUND) { // Could happen if objects were deleted
		wuobject = wuobjects_list;
		last_propagated_property_wuobject_index = 0;
	}
	uint16_t current_index = last_propagated_property_wuobject_index;

	// wuobject is now pointing to the last checked object
	do {
		// Find the first next object that needs to be checked for dirty properties, or the same if there's no other.
		// Find next object
		wuobject = wuobject->next;
		current_index++;
		if (wuobject == NULL) {
			wuobject = wuobjects_list; // Wrap around to the first object.
			current_index = 0;
		}

		// Check if any property is dirty for this wuobject
		wuclass_t *wuclass = wuobject->wuclass;
		uint8_t offset = 0;
		for (int i=0; i<wuclass->number_of_properties; i++) {
			wuobject_property_t *property = (wuobject_property_t *)&(wuobject->properties_store[offset]);
			if (wkpf_property_status_is_dirty(property->status)) {
				// Found a dirty property. Return it.
				DEBUG_LOG(DBG_WKPF, "WKPF: wkpf_get_next_dirty_property DIRTY: port %x property %x status %x\n", wuobject->port_number, i, property->status);
				last_propagated_property_wuobject_index = current_index; // Next time continue from the next wuobject
				*dirty_wuobject = wuobject;
				*dirty_property_number = i;
				return true;
			}
			offset += WKPF_GET_PROPERTY_DATASIZE(wuclass->properties[i]);
		}
	} while(current_index != last_propagated_property_wuobject_index);
	return false; // No dirty properties found
}
コード例 #3
0
ファイル: wkpf_comm.c プロジェクト: fakewen/Monitoring-branch
//void wkpf_comm_handle_message(wkcomm_address_t src, uint8_t nvmcomm_command, uint8_t *payload, uint8_t response_size, uint8_t response_cmd) {
void wkpf_comm_handle_message(void *data) {
	wkcomm_received_msg *msg = (wkcomm_received_msg *)data;
	uint8_t *payload = msg->payload;
	uint8_t response_size = 0, response_cmd = 0;
	uint8_t retval;

	if (dj_exec_getRunlevel() == RUNLEVEL_REPROGRAMMING)
		return;

	switch (msg->command) {
		case WKPF_COMM_CMD_GET_LOCATION: {
			// Format of get_location request messages: payload[0] offset of the first byte requested
			// Format of get_location return messages: payload[0..] the part of the location string

			// The length of the location is stored by the master as the first byte of the string.

			// Get the offset of the requested data within the location string
			uint8_t requested_offset = payload[0];

			// Read the EEPROM
			uint8_t length = wkpf_config_get_part_of_location_string((char *)payload, requested_offset, WKCOMM_MESSAGE_PAYLOAD_SIZE);

			DEBUG_LOG(DBG_WKPF, "WKPF_COMM_CMD_GET_LOCATION: Reading %d bytes at offset %d\n", length, requested_offset);

			response_cmd = WKPF_COMM_CMD_GET_LOCATION_R;
			response_size = length;
		}
		break;
		case WKPF_COMM_CMD_SET_LOCATION: {
			// Format of set_location request messages: payload[0] offset of part of the location string being sent
			// Format of set_location request messages: payload[1] the length of part of the location string being sent
			// Format of set_location request messages: payload[2..] the part of the location string
			// Format of set_location return messages: payload[0] the wkpf return code

			uint8_t written_offset = payload[0];
			uint8_t length = payload[1];

			DEBUG_LOG(DBG_WKPF, "WKPF_COMM_CMD_SET_LOCATION: Writing %d bytes at offset %d\n", length, written_offset);

			// Read the EEPROM
			retval = wkpf_config_set_part_of_location_string((char*) payload+2, written_offset, length);

			// Send response
			if (retval == WKPF_OK) {
				response_cmd = WKPF_COMM_CMD_SET_LOCATION_R;
			} else {
				response_cmd = WKPF_COMM_CMD_ERROR_R;
			}
			payload[0] = retval;       
			response_size = 1;
		}
		break;
		case WKPF_COMM_CMD_GET_FEATURES: {
			int count = 0;
			for (int i=0; i<WKPF_NUMBER_OF_FEATURES; i++) { // Needs to be changed if we have more features than fits in a single message, but for now it will work fine.
				if (wkpf_config_get_feature_enabled(i)) {
					payload[1+count++] = i;
				}
			}
			payload[0] = count;
			response_cmd = WKPF_COMM_CMD_GET_FEATURES_R;
			response_size = 1+count;
		}
		break;
		case WKPF_COMM_CMD_SET_FEATURE: {
			retval = wkpf_config_set_feature_enabled(payload[2], payload[3]);
			if (retval == WKPF_OK) {
				response_cmd = WKPF_COMM_CMD_SET_FEATURE_R;
				response_size = 0;
			} else {
				payload[2] = retval;       
				response_cmd = WKPF_COMM_CMD_ERROR_R;
				response_size = 1;
			}
		}
		break;
		case WKPF_COMM_CMD_GET_WUCLASS_LIST: {
			// Request format: payload[0] request message number
			// Response format: payload[0] response message number
			// Response format: payload[1] total number of messages
			// Response format: payload[2] number of wuclasses

			uint8_t number_of_wuclasses = wkpf_get_number_of_wuclasses();
			uint8_t number_of_messages = (number_of_wuclasses / NUMBER_OF_WUCLASSES_PER_MESSAGE);
			if ((number_of_wuclasses % NUMBER_OF_WUCLASSES_PER_MESSAGE) != 0)
				number_of_messages++;
			uint8_t start_at_wuclass_index = payload[0]*NUMBER_OF_WUCLASSES_PER_MESSAGE;
			payload[1] = number_of_messages;
			payload[2] = number_of_wuclasses;

			uint8_t number_of_wuclasses_in_message = number_of_wuclasses - start_at_wuclass_index;
			if (number_of_wuclasses_in_message > NUMBER_OF_WUCLASSES_PER_MESSAGE)
				number_of_wuclasses_in_message = NUMBER_OF_WUCLASSES_PER_MESSAGE;

			for (uint8_t i=0; i<number_of_wuclasses_in_message; i++) {
				wuclass_t *wuclass;
				wkpf_get_wuclass_by_index(i+start_at_wuclass_index, &wuclass);

        payload[3*i + 3] = (uint8_t)(wuclass->wuclass_id >> 8);
        payload[3*i + 4] = (uint8_t)(wuclass->wuclass_id);
				if (wuclass->flags & WKPF_WUCLASS_FLAG_APP_CAN_CREATE_INSTANCE) {
					payload[3*i + 5] = WKPF_IS_VIRTUAL_WUCLASS(wuclass) ? 3 : 2;
				} else {
					payload[3*i + 5] = WKPF_IS_VIRTUAL_WUCLASS(wuclass) ? 1 : 0;
        }
			}
			response_size = 3*number_of_wuclasses_in_message + 3; // 3*wuclasses + 3 bytes for message nr, number of messages, number of wuclasses
			response_cmd = WKPF_COMM_CMD_GET_WUCLASS_LIST_R;
		}
		break;
		case WKPF_COMM_CMD_GET_WUOBJECT_LIST: {
			// Request format: payload[0] request message number
			// Response format: payload[0] response message number
			// Response format: payload[1] total number of messages
			// Response format: payload[2] number of wuobjects


			uint8_t number_of_wuobjects = wkpf_get_number_of_wuobjects();
			uint8_t number_of_wuobject_messages = (number_of_wuobjects / NUMBER_OF_WUOBJECTS_PER_MESSAGE);
			if ((number_of_wuobjects % NUMBER_OF_WUOBJECTS_PER_MESSAGE) != 0)
				number_of_wuobject_messages++;
			uint8_t start_at_wuobject_index = payload[0]*NUMBER_OF_WUOBJECTS_PER_MESSAGE;
			payload[1] = number_of_wuobject_messages;
			payload[2] = number_of_wuobjects;

			uint8_t number_of_wuobjects_in_message = number_of_wuobjects - start_at_wuobject_index;
			if (number_of_wuobjects_in_message > NUMBER_OF_WUOBJECTS_PER_MESSAGE)
				number_of_wuobjects_in_message = NUMBER_OF_WUOBJECTS_PER_MESSAGE;

			for (uint8_t i=0; i<number_of_wuobjects_in_message; i++) {
				wuobject_t *wuobject;
				wkpf_get_wuobject_by_index(start_at_wuobject_index+i, &wuobject);
				payload[4*i + 3] = (uint8_t)(wuobject->port_number);
				payload[4*i + 4] = (uint8_t)(wuobject->wuclass->wuclass_id >> 8);
				payload[4*i + 5] = (uint8_t)(wuobject->wuclass->wuclass_id);
				payload[4*i + 6] = WKPF_IS_VIRTUAL_WUCLASS(wuobject->wuclass);
			}
			response_size = 4*number_of_wuobjects_in_message + 3; // 4*wuobjects + 3 bytes for message nr, number of messages, number of wuobjects (max 39 bytes, barely over 40 bytes)
			response_cmd = WKPF_COMM_CMD_GET_WUOBJECT_LIST_R;
		}
		break;
		case WKPF_COMM_CMD_READ_PROPERTY: { // TODONR: check wuclassid
			uint8_t port_number = payload[0];
			// TODONR: uint16_t wuclass_id = (uint16_t)(payload[1]<<8)+(uint16_t)(payload[2]);
			uint8_t property_number = payload[3];
			wuobject_t *wuobject;
			retval = wkpf_get_wuobject_by_port(port_number, &wuobject);
			if (retval != WKPF_OK) {
				payload [2] = retval;
				response_cmd = WKPF_COMM_CMD_ERROR_R;
				response_size = 1;
				break;
			}
			uint8_t property_status;
			wkpf_get_property_status(wuobject, property_number, &property_status);
			if (WKPF_GET_PROPERTY_DATATYPE(wuobject->wuclass->properties[property_number]) == WKPF_PROPERTY_TYPE_SHORT) {
				int16_t value;
				retval = wkpf_external_read_property_int16(wuobject, property_number, &value);
				payload[4] = WKPF_GET_PROPERTY_DATATYPE(wuobject->wuclass->properties[property_number]);
				payload[5] = property_status;
				payload[6] = (uint8_t)(value>>8);
				payload[7] = (uint8_t)(value);
				response_size = 8;
				response_cmd = WKPF_COMM_CMD_READ_PROPERTY_R;        
			} else if (WKPF_GET_PROPERTY_DATATYPE(wuobject->wuclass->properties[property_number]) == WKPF_PROPERTY_TYPE_BOOLEAN) {
				bool value;
				retval = wkpf_external_read_property_boolean(wuobject, property_number, &value);
				payload[4] = WKPF_GET_PROPERTY_DATATYPE(wuobject->wuclass->properties[property_number]);
				payload[5] = property_status;
				payload[6] = (uint8_t)(value);
				response_size = 7;
				response_cmd = WKPF_COMM_CMD_READ_PROPERTY_R;                
			} else if (WKPF_GET_PROPERTY_DATATYPE(wuobject->wuclass->properties[property_number]) == WKPF_PROPERTY_TYPE_REFRESH_RATE) {
				wkpf_refresh_rate_t value;
				retval = wkpf_external_read_property_refresh_rate(wuobject, property_number, &value);
				payload[4] = WKPF_GET_PROPERTY_DATATYPE(wuobject->wuclass->properties[property_number]);
				payload[5] = property_status;
				payload[6] = (uint8_t)(value>>8);
				payload[7] = (uint8_t)(value);
				response_size = 8;
				response_cmd = WKPF_COMM_CMD_READ_PROPERTY_R;        
			} else
コード例 #4
0
ファイル: wkpf_comm.c プロジェクト: HuangZhenQiu/NanoKong
void wkpf_comm_handle_message(u08_t nvmcomm_command, u08_t *payload, u08_t *response_size, u08_t *response_cmd) {
  uint8_t number_of_wuclasses;
  uint8_t number_of_wuobjects;
  // TODONR: uint16_t wuclass_id;
  uint8_t port_number;
  uint8_t property_number;
  uint8_t retval;
  wkpf_local_wuobject *wuobject;
  
  if (nvm_runlevel != NVM_RUNLVL_VM)
    return;

  switch (nvmcomm_command) {
    case NVMCOMM_WKPF_GET_LOCATION:
      payload[2] = strlen(location);
      strcpy((char*)payload+3, location);
      *response_size = sizeof(location) + 3;//payload size location + 2 byte overhead + 1 byte location size
      *response_cmd = NVMCOMM_WKPF_GET_LOCATION_R;
    break;
    case NVMCOMM_WKPF_SET_LOCATION:
      strncpy(location, (char*)payload+3, payload[2]);
      *response_size = 6;
      *response_cmd = NVMCOMM_WKPF_SET_LOCATION_R;
      retval = WKPF_OK;
      if (retval != WKPF_OK) {
        payload[2] = retval;
        *response_size = 3;//payload size
        *response_cmd = NVMCOMM_WKPF_ERROR_R;
      }
    break;
    case NVMCOMM_WKPF_GET_WUCLASS_LIST:
      number_of_wuclasses = wkpf_get_number_of_wuclasses();
      payload[2] = number_of_wuclasses;
      for (int i=0; i<number_of_wuclasses && i<9; i++) { // TODONR: i<9 is temporary to keep the length within MESSAGE_SIZE, but we should have a protocol that sends multiple messages
        wkpf_wuclass_definition *wuclass;
        wkpf_get_wuclass_by_index(i, &wuclass);
        payload[3*i + 3] = (uint8_t)(wuclass->wuclass_id >> 8);
        payload[3*i + 4] = (uint8_t)(wuclass->wuclass_id);
        payload[3*i + 5] = WKPF_IS_VIRTUAL_WUCLASS(wuclass) ? 1 : 0;
      }
      *response_size = 3*number_of_wuclasses + 3;//payload size 2*wuclasses + 2 bytes seqnr + 1 byte number of wuclasses
      *response_cmd = NVMCOMM_WKPF_GET_WUCLASS_LIST_R;
    break;
    case NVMCOMM_WKPF_GET_WUOBJECT_LIST:
      number_of_wuobjects = wkpf_get_number_of_wuobjects();
      payload[2] = number_of_wuobjects;
      for (int i=0; i<number_of_wuobjects && i<9; i++) { // TODONR: i<9 is temporary to keep the length within MESSAGE_SIZE, but we should have a protocol that sends multiple messages
        wkpf_local_wuobject *wuobject;
        wkpf_get_wuobject_by_index(i, &wuobject);
        payload[3*i + 3] = (uint8_t)(wuobject->port_number);
        payload[3*i + 4] = (uint8_t)(wuobject->wuclass->wuclass_id >> 8);
        payload[3*i + 5] = (uint8_t)(wuobject->wuclass->wuclass_id);
      }
      *response_size = 3*number_of_wuobjects + 3;//payload size 3*wuobjects + 2 bytes seqnr + 1 byte number of wuclasses
      *response_cmd = NVMCOMM_WKPF_GET_WUOBJECT_LIST_R;
    break;
    case NVMCOMM_WKPF_READ_PROPERTY: // TODONR: check wuclassid
      port_number = payload[2];
      // TODONR: wuclass_id = (uint16_t)(payload[3]<<8)+(uint16_t)(payload[4]);
      property_number = payload[5];
      retval = wkpf_get_wuobject_by_port(port_number, &wuobject);
      if (retval != WKPF_OK) {
        payload [2] = retval;
        *response_cmd = NVMCOMM_WKPF_ERROR_R;
        *response_size = 3;//payload size
        break;
      }
      uint8_t property_status;
      wkpf_get_property_status(wuobject, property_number, &property_status);
      if (WKPF_GET_PROPERTY_DATATYPE(wuobject->wuclass->properties[property_number]) == WKPF_PROPERTY_TYPE_SHORT) {
        int16_t value;
        retval = wkpf_external_read_property_int16(wuobject, property_number, &value);
        payload[6] = WKPF_GET_PROPERTY_DATATYPE(wuobject->wuclass->properties[property_number]);
        payload[7] = property_status;
        payload[8] = (uint8_t)(value>>8);
        payload[9] = (uint8_t)(value);
        *response_size = 10;//payload size
        *response_cmd = NVMCOMM_WKPF_READ_PROPERTY_R;        
      } else if (WKPF_GET_PROPERTY_DATATYPE(wuobject->wuclass->properties[property_number]) == WKPF_PROPERTY_TYPE_BOOLEAN) {