void dj_panic(int32_t panictype) { switch(panictype) { case DJ_PANIC_OUT_OF_MEMORY: DEBUG_LOG(true, "PANIC: out of memory!\n"); break; case DJ_PANIC_ILLEGAL_INTERNAL_STATE: DEBUG_LOG(true, "PANIC: illegal internal state!\n"); break; case DJ_PANIC_UNIMPLEMENTED_FEATURE: DEBUG_LOG(true, "PANIC: unimplemented feature!\n"); break; case DJ_PANIC_UNCAUGHT_EXCEPTION: DEBUG_LOG(true, "PANIC: uncaught exception!\n"); break; case DJ_PANIC_UNSATISFIED_LINK: DEBUG_LOG(true, "PANIC: unsatisfied link!\n"); break; case DJ_PANIC_MALFORMED_INFUSION: DEBUG_LOG(true, "PANIC: malformed infusion!\n"); break; case DJ_PANIC_ASSERTION_FAILURE: DEBUG_LOG(true, "PANIC: assertion failed!\n"); break; case DJ_PANIC_SAFE_POINTER_OVERFLOW: DEBUG_LOG(true, "PANIC: safe pointer overflow!\n"); break; default: DEBUG_LOG(true, "PANIC: unknown panic type %d!\n", panictype); break; } if (dj_exec_getRunlevel() < RUNLEVEL_PANIC) { dj_exec_setRunlevel(panictype); while (true) // Still allow remote access through wkcomm when in panic state. dj_hook_call(dj_core_pollingHook, NULL); } else { exit(panictype); // To avoid getting into a recursive panic. } }
void javax_wukong_wkpf_WKPF_javax_wukong_wkpf_VirtualWuObject_select() { wuobject_t *wuobject; while(true) { // Process any incoming messages dj_hook_call(dj_vm_pollingHook, NULL); // // TODONR: implement group stuff // #ifdef NVM_USE_GROUP // // Send out a heartbeat message if it's due, and check for failed nodes. // group_heartbeat(); // #endif // NVM_USE_GROUP if (dj_exec_getRunlevel() == RUNLEVEL_RUNNING) { // Propagate any dirty properties wkpf_propagate_dirty_properties(); // Check if any wuobjects need updates if(wkpf_get_next_wuobject_to_update(&wuobject)) { // Will call update() for native profiles directly, and return true for virtual profiles requiring an update. dj_exec_stackPushRef(VOIDP_TO_REF(wuobject->java_instance_reference)); DEBUG_LOG(DBG_WKPF, "WKPF: WKPF.select returning wuclass at port %x.\n", wuobject->port_number); return; } } } }
//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