int object_init() { int i, objects, j, x, y, l, dir; const char *sprite; for (i = objects = 0; i < rpg.map.map->objects; i++) if (!strcmp(d_map_prop(rpg.map.map->object[i].ref, "TYPE"), "npc")) objects++; if (!(rpg.object.entry = malloc(sizeof(OBJECT_ENTRY) * objects)) && objects) return -1; rpg.object.bbox = d_bbox_new(objects); for (i = j = 0; i < rpg.map.map->objects; i++) { if (!strcmp(d_map_prop(rpg.map.map->object[i].ref, "TYPE"), "teleporter")) { /* TODO: Implement teleporters */ continue; } if (!strcmp(d_map_prop(rpg.map.map->object[i].ref, "TYPE"), "npc")) { x = rpg.map.map->object[i].x; y = rpg.map.map->object[i].y; l = rpg.map.map->object[i].l; MAP_COORD_DECODE(x, y, l, &x, &y); rpg.object.entry[j].x = x; rpg.object.entry[j].y = y; rpg.object.entry[j].layer = l; rpg.object.entry[j].data.pointer = NULL; rpg.object.entry[j].data.num = 0; sprite = MAP_OBJ_PROP("sprite", i); dir = atoi(MAP_OBJ_PROP("sprite_dir", i)); if (!strcmp(sprite, "NO SUCH KEY")) rpg.object.entry[j].sprite = d_sprite_load(sprite, dir, DARNIT_PFORMAT_RGB5A1); else rpg.object.entry[j].sprite = NULL; rpg.object.entry[j].handler = object_resolve(i); if (rpg.object.entry[j].handler) rpg.object.entry[j].handler(OBJECT_MSG_INIT, &rpg.object.entry[j]); j++; } } rpg.object.entries = objects; return 1; }
static uint32_t internal_request_handle(coap_message_t * p_request, uint16_t * p_path, uint8_t path_len) { uint32_t err_code; uint8_t operation = LWM2M_OPERATION_CODE_NONE; uint32_t content_type = 0; err_code = coap_message_ct_mask_get(p_request, &content_type); if (err_code != NRF_SUCCESS) { return err_code; } /** * TODO: the methods should check if we have read / write / execute rights * through ACL and resource operations */ switch (p_request->header.code) { case COAP_CODE_GET: { LWM2M_TRC("[LWM2M][CoAP ]: CoAP GET request\r\n"); if (content_type == COAP_CT_APP_LINK_FORMAT) // Discover { operation = LWM2M_OPERATION_CODE_DISCOVER; } else // Read { operation = LWM2M_OPERATION_CODE_READ; } break; } case COAP_CODE_PUT: { operation = LWM2M_OPERATION_CODE_WRITE; break; } case COAP_CODE_POST: { operation = LWM2M_OPERATION_CODE_WRITE; break; } case COAP_CODE_DELETE: { operation = LWM2M_OPERATION_CODE_DELETE; break; } default: break; // Maybe send response with unsupported method not allowed? } err_code = NRF_ERROR_NOT_FOUND; switch (path_len) { case 0: { if (operation == LWM2M_OPERATION_CODE_DELETE) { LWM2M_TRC("[LWM2M][CoAP ]: >> %s root /\r\n", m_operation_desc[op_desc_idx_lookup(operation)]); LWM2M_MUTEX_UNLOCK(); err_code = lwm2m_coap_handler_root(LWM2M_OPERATION_CODE_DELETE, p_request); LWM2M_MUTEX_LOCK(); LWM2M_TRC("[LWM2M][CoAP ]: << %s root /\r\n", m_operation_desc[op_desc_idx_lookup(operation)]); } break; } case 1: { LWM2M_TRC("[LWM2M][CoAP ]: >> %s object /%u/\r\n", m_operation_desc[op_desc_idx_lookup(operation)], p_path[0]); lwm2m_object_prototype_t * p_object; err_code = object_resolve(&p_object, p_path[0]); if (err_code != NRF_SUCCESS) { break; } LWM2M_MUTEX_UNLOCK(); err_code = p_object->callback(p_object, LWM2M_INVALID_INSTANCE, operation, p_request); LWM2M_MUTEX_LOCK(); LWM2M_TRC("[LWM2M][CoAP ]: << %s object /%u/, result: %s\r\n", m_operation_desc[op_desc_idx_lookup(operation)], p_path[0], (err_code == NRF_SUCCESS) ? "SUCCESS" : "NOT_FOUND"); break; } case 2: { LWM2M_TRC("[LWM2M][CoAP ]: >> %s instance /%u/%u/\r\n", m_operation_desc[op_desc_idx_lookup(operation)], p_path[0], p_path[1]); lwm2m_instance_prototype_t * p_instance; err_code = instance_resolve(&p_instance, p_path[0], p_path[1]); if (err_code == NRF_SUCCESS) { LWM2M_MUTEX_UNLOCK(); err_code = p_instance->callback(p_instance, LWM2M_INVALID_RESOURCE, operation, p_request); LWM2M_MUTEX_LOCK(); LWM2M_TRC("[LWM2M][CoAP ]: << %s instance /%u/%u/, result: %s\r\n", m_operation_desc[op_desc_idx_lookup(operation)], p_path[0], p_path[1], (err_code == NRF_SUCCESS) ? "SUCCESS" : "NOT_FOUND"); break; } // Bootstrap can write to non-existing instances if (err_code == NRF_ERROR_NOT_FOUND && operation == LWM2M_OPERATION_CODE_WRITE && p_request->header.code == COAP_CODE_PUT) { LWM2M_TRC("[LWM2M][CoAP ]: >> %s object /%u/%u/\r\n", m_operation_desc[op_desc_idx_lookup(operation)], p_path[0], p_path[1]); lwm2m_object_prototype_t * p_object; err_code = object_resolve(&p_object, p_path[0]); if (err_code != NRF_SUCCESS) { break; } LWM2M_MUTEX_UNLOCK(); err_code = p_object->callback(p_object, p_path[1], operation, p_request); LWM2M_MUTEX_LOCK(); LWM2M_TRC("[LWM2M][CoAP ]: << %s object /%u/%u/, result: %s\r\n", m_operation_desc[op_desc_idx_lookup(operation)], p_path[0], p_path[1], (err_code == NRF_SUCCESS) ? "SUCCESS" : "NOT_FOUND"); } if (err_code == NRF_ERROR_NOT_FOUND && operation == LWM2M_OPERATION_CODE_WRITE && p_request->header.code == COAP_CODE_POST) { LWM2M_TRC("[LWM2M][CoAP ]: >> CREATE object /%u/%u/\r\n", p_path[0], p_path[1]); lwm2m_object_prototype_t * p_object; err_code = object_resolve(&p_object, p_path[0]); if (err_code != NRF_SUCCESS) { break; } LWM2M_MUTEX_UNLOCK(); err_code = p_object->callback(p_object, p_path[1], LWM2M_OPERATION_CODE_CREATE, p_request); LWM2M_MUTEX_LOCK(); LWM2M_TRC("[LWM2M][CoAP ]: << CREATE object /%u/%u/, result: %s\r\n", p_path[0], p_path[1], (err_code == NRF_SUCCESS) ? "SUCCESS" : "NOT_FOUND"); break; } break; } case 3: { if (operation == LWM2M_OPERATION_CODE_DELETE) { // Deleting resources within an instance not allowed. break; } if (p_request->header.code == COAP_CODE_POST) { for (int i = 0; i < m_num_instances; ++i) { if ((m_instances[i]->object_id == p_path[0]) && (m_instances[i]->instance_id == p_path[1])) { if (m_instances[i]->callback == NULL) { err_code = NRF_ERROR_NULL; break; } uint8_t resource_operation = 0; err_code = op_code_resolve(m_instances[i], p_path[2], &resource_operation); if (err_code != NRF_SUCCESS) break; if ((resource_operation & LWM2M_OPERATION_CODE_EXECUTE) > 0) { operation = LWM2M_OPERATION_CODE_EXECUTE; } if ((resource_operation & LWM2M_OPERATION_CODE_WRITE) > 0) { operation = LWM2M_OPERATION_CODE_WRITE; } LWM2M_TRC("[LWM2M][CoAP ]: >> %s instance /%u/%u/%u/\r\n", m_operation_desc[op_desc_idx_lookup(operation)], m_instances[i]->object_id, m_instances[i]->instance_id, p_path[2]); LWM2M_MUTEX_UNLOCK(); (void)m_instances[i]->callback(m_instances[i], p_path[2], operation, p_request); LWM2M_MUTEX_LOCK(); err_code = NRF_SUCCESS; LWM2M_TRC("[LWM2M][CoAP ]: << %s instance /%u/%u/%u/\r\n", m_operation_desc[op_desc_idx_lookup(operation)], m_instances[i]->object_id, m_instances[i]->instance_id, p_path[2]); break; } } } else { LWM2M_TRC("[LWM2M][CoAP ]: >> %s instance /%u/%u/%u/\r\n", m_operation_desc[op_desc_idx_lookup(operation)], p_path[0], p_path[1], p_path[2]); lwm2m_instance_prototype_t * p_instance; err_code = instance_resolve(&p_instance, p_path[0], p_path[1]); if (err_code != NRF_SUCCESS) { break; } LWM2M_MUTEX_UNLOCK(); err_code = p_instance->callback(p_instance, p_path[2], operation, p_request); LWM2M_MUTEX_LOCK(); LWM2M_TRC("[LWM2M][CoAP ]: << %s instance /%u/%u/%u/, result: %s\r\n", m_operation_desc[op_desc_idx_lookup(operation)], p_path[0], p_path[1], p_path[2], (err_code == NRF_SUCCESS) ? "SUCCESS" : "NOT_FOUND"); } break; } default: break; } return err_code; }