static bool filter_resource(oc_resource_t *resource, const char *rt, int rt_len, CborEncoder *links) { int i; bool match = true; if (rt_len > 0) { match = false; for (i = 0; i < oc_string_array_get_allocated_size(resource->types); i++) { int size = oc_string_array_get_item_size(resource->types, i); const char *t = (const char *)oc_string_array_get_item(resource->types, i); if (rt_len == size && strncmp(rt, t, rt_len) == 0) { match = true; break; } } } if (!match) { return false; } oc_rep_start_object(*links, res); // uri oc_rep_set_text_string(res, href, oc_string(resource->uri)); // rt oc_rep_set_array(res, rt); for (i = 0; i < oc_string_array_get_allocated_size(resource->types); i++) { int size = oc_string_array_get_item_size(resource->types, i); const char *t = (const char *)oc_string_array_get_item(resource->types, i); if (size > 0) oc_rep_add_text_string(rt, t); } oc_rep_close_array(res, rt); // if oc_core_encode_interfaces_mask(oc_rep_object(res), resource->interfaces); // p oc_rep_set_object(res, p); oc_rep_set_uint(p, bm, resource->properties & ~OC_PERIODIC); #ifdef OC_SECURITY if (resource->properties & OC_SECURE) { oc_rep_set_boolean(p, sec, true); oc_rep_set_uint(p, port, oc_connectivity_get_dtls_port()); } #endif /* OC_SECURITY */ oc_rep_close_object(res, p); oc_rep_end_object(*links, res); return true; }
static oc_discovery_flags_t discovery(const char *di, const char *uri, oc_string_array_t types, oc_interface_mask_t interfaces, oc_server_handle_t *server) { int i; int uri_len = strlen(uri); uri_len = (uri_len >= MAX_URI_LENGTH) ? MAX_URI_LENGTH - 1 : uri_len; for (i = 0; i < oc_string_array_get_allocated_size(types); i++) { char *t = oc_string_array_get_item(types, i); if (strlen(t) == 11 && strncmp(t, "oic.r.light", 11) == 0) { memcpy(&light_server, server, sizeof(oc_server_handle_t)); strncpy(light_1, uri, uri_len); light_1[uri_len] = '\0'; oc_do_observe(light_1, &light_server, NULL, &observe_light, LOW_QOS); os_callout_reset(&callout, 30 * OS_TICKS_PER_SEC); return OC_STOP_DISCOVERY; } } return OC_CONTINUE_DISCOVERY; }
oc_discovery_flags_t oc_ri_process_discovery_payload(struct coap_packet_rx *rsp, oc_discovery_cb_t *handler, oc_endpoint_t *endpoint) { oc_discovery_flags_t ret = OC_CONTINUE_DISCOVERY; oc_string_t uri = { .os_sz = 0, .os_str = NULL }; oc_string_t di = { .os_sz = 0, .os_str = NULL }; bool secure = false; uint16_t dtls_port = 0, default_port = endpoint->oe_ip.v6.port; oc_string_array_t types = {}; oc_interface_mask_t interfaces = 0; oc_server_handle_t handle; uint16_t data_off; struct os_mbuf *m; int len; memcpy(&handle.endpoint, endpoint, sizeof(oc_endpoint_t)); oc_rep_t *array = 0, *rep; len = coap_get_payload(rsp, &m, &data_off); int s = oc_parse_rep(m, data_off, len, &rep); if (s == 0) array = rep; while (array != NULL) { oc_rep_t *device_map = array->value_object; while (device_map != NULL) { switch (device_map->type) { case STRING: if (oc_string_len(device_map->name) == 2 && strncmp(oc_string(device_map->name), "di", 2) == 0) di = device_map->value_string; break; default: break; } device_map = device_map->next; } device_map = array->value_object; while (device_map != NULL) { switch (device_map->type) { case OBJECT_ARRAY: { oc_rep_t *links = device_map->value_object_array; while (links != NULL) { switch (links->type) { case OBJECT: { oc_rep_t *resource_info = links->value_object; while (resource_info != NULL) { switch (resource_info->type) { case STRING: uri = resource_info->value_string; break; case STRING_ARRAY: if (oc_string_len(resource_info->name) == 2 && strncmp(oc_string(resource_info->name), "rt", 2) == 0) types = resource_info->value_array; else { interfaces = 0; int i; for (i = 0; i < oc_string_array_get_allocated_size( resource_info->value_array); i++) { interfaces |= oc_ri_get_interface_mask( oc_string_array_get_item(resource_info->value_array, i), oc_string_array_get_item_size(resource_info->value_array, i)); } } break; case OBJECT: { oc_rep_t *policy_info = resource_info->value_object; while (policy_info != NULL) { if (policy_info->type == INT && oc_string_len(policy_info->name) == 4 && strncmp(oc_string(policy_info->name), "port", 4) == 0) { dtls_port = policy_info->value_int; } if (policy_info->type == BOOL && oc_string_len(policy_info->name) == 3 && strncmp(oc_string(policy_info->name), "sec", 3) == 0 && policy_info->value_boolean == true) { secure = true; } policy_info = policy_info->next; } } break; default: break; } resource_info = resource_info->next; } if (secure) { handle.endpoint.oe_ip.v6.port = dtls_port; handle.endpoint.oe_ip.flags |= SECURED; } else { handle.endpoint.oe_ip.v6.port = default_port; handle.endpoint.oe_ip.flags &= ~SECURED; } if (handler(oc_string(di), oc_string(uri), types, interfaces, &handle) == OC_STOP_DISCOVERY) { ret = OC_STOP_DISCOVERY; goto done; } dtls_port = 0; secure = false; } break; default: break; } links = links->next; } } break; default: break; } device_map = device_map->next; } array = array->next; } done: oc_free_rep(rep); return ret; }
/* Parse single property */ static void oc_parse_rep_value(CborValue *value, oc_rep_t **rep, CborError *err) { size_t k, len; CborValue map, array; *rep = _alloc_rep(); oc_rep_t *cur = *rep, **prev = 0; cur->next = 0; cur->value_object_array = 0; /* key */ *err |= cbor_value_calculate_string_length(value, &len); len++; oc_alloc_string(&cur->name, len); *err |= cbor_value_copy_text_string(value, (char *)oc_string(cur->name), &len, NULL); *err |= cbor_value_advance(value); /* value */ switch (value->type) { case CborIntegerType: *err |= cbor_value_get_int64(value, &cur->value_int); cur->type = INT; break; case CborBooleanType: *err |= cbor_value_get_boolean(value, &cur->value_boolean); cur->type = BOOL; break; case CborDoubleType: *err |= cbor_value_get_double(value, &cur->value_double); cur->type = DOUBLE; break; case CborByteStringType: *err |= cbor_value_calculate_string_length(value, &len); len++; oc_alloc_string(&cur->value_string, len); *err |= cbor_value_copy_byte_string( value, oc_cast(cur->value_string, uint8_t), &len, NULL); cur->type = BYTE_STRING; break; case CborTextStringType: *err |= cbor_value_calculate_string_length(value, &len); len++; oc_alloc_string(&cur->value_string, len); *err |= cbor_value_copy_text_string(value, oc_string(cur->value_string), &len, NULL); cur->type = STRING; break; case CborMapType: /* when value is a map/object */ { oc_rep_t **obj = &cur->value_object; // object points to list of properties *err |= cbor_value_enter_container(value, &map); while (!cbor_value_at_end(&map)) { oc_parse_rep_value(&map, obj, err); (*obj)->next = 0; obj = &(*obj)->next; *err |= cbor_value_advance(&map); } cur->type = OBJECT; } break; case CborArrayType: *err |= cbor_value_enter_container(value, &array); len = 0; cbor_value_get_array_length(value, &len); if (len == 0) { CborValue t = array; while (!cbor_value_at_end(&t)) { len++; cbor_value_advance(&t); } } k = 0; while (!cbor_value_at_end(&array)) { switch (array.type) { case CborIntegerType: if (k == 0) { oc_new_int_array(&cur->value_array, len); cur->type = INT | ARRAY; } *err |= cbor_value_get_int64(&array, oc_int_array(cur->value_array) + k); break; case CborDoubleType: if (k == 0) { oc_new_double_array(&cur->value_array, len); cur->type = DOUBLE | ARRAY; } *err |= cbor_value_get_double(&array, oc_double_array(cur->value_array) + k); break; case CborBooleanType: if (k == 0) { oc_new_bool_array(&cur->value_array, len); cur->type = BOOL | ARRAY; } *err |= cbor_value_get_boolean(&array, oc_bool_array(cur->value_array) + k); break; case CborByteStringType: if (k == 0) { oc_new_string_array(&cur->value_array, len); cur->type = BYTE_STRING | ARRAY; } *err |= cbor_value_calculate_string_length(&array, &len); len++; *err |= cbor_value_copy_byte_string( &array, (uint8_t *)oc_string_array_get_item(cur->value_array, k), &len, NULL); break; case CborTextStringType: if (k == 0) { oc_new_string_array(&cur->value_array, len); cur->type = STRING | ARRAY; } *err |= cbor_value_calculate_string_length(&array, &len); len++; *err |= cbor_value_copy_text_string( &array, (char *)oc_string_array_get_item(cur->value_array, k), &len, NULL); break; case CborMapType: if (k == 0) { cur->type = OBJECT | ARRAY; cur->value_object_array = _alloc_rep(); prev = &cur->value_object_array; } else { (*prev)->next = _alloc_rep(); prev = &(*prev)->next; } (*prev)->type = OBJECT; (*prev)->next = 0; oc_rep_t **obj = &(*prev)->value_object; /* Process a series of properties that make up an object of the array */ *err |= cbor_value_enter_container(&array, &map); while (!cbor_value_at_end(&map)) { oc_parse_rep_value(&map, obj, err); obj = &(*obj)->next; *err |= cbor_value_advance(&map); } break; default: break; } k++; *err |= cbor_value_advance(&array); } break; default: break; } }