static struct sol_oic_server_resource * register_light_resource_type( sol_coap_responsecode_t (*handle_get)(const struct sol_network_link_addr *cliaddr, const void *data, const struct sol_vector *input, struct sol_vector *output), sol_coap_responsecode_t (*handle_put)(const struct sol_network_link_addr *cliaddr, const void *data, const struct sol_vector *input, struct sol_vector *output)) { /* This function will be auto-generated from the RAML definitions. */ struct sol_oic_resource_type rt = { .api_version = SOL_OIC_RESOURCE_TYPE_API_VERSION, .resource_type = SOL_STR_SLICE_LITERAL("core.light"), .interface = SOL_STR_SLICE_LITERAL("oc.mi.def"), .get = { .handle = handle_get /* User-provided. */ }, .put = { .handle = handle_put /* User-provided. */ } };
// 37 = 2 * 16 (chars) + 4 (hyphens) + 1 (\0) SOL_API int sol_util_uuid_gen(bool upcase, bool with_hyphens, char id[SOL_STATIC_ARRAY_SIZE(37)]) { static struct sol_str_slice hyphen = SOL_STR_SLICE_LITERAL("-"); /* hyphens on positions 8, 13, 18, 23 (from 0) */ static const int hyphens_pos[] = { 8, 13, 18, 23 }; struct sol_uuid uuid = { { 0 } }; unsigned i; int r; struct sol_buffer buf = { 0 }; sol_buffer_init_flags(&buf, id, 37, SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED); r = uuid_gen(&uuid); SOL_INT_CHECK(r, < 0, r); for (i = 0; i < SOL_UTIL_ARRAY_SIZE(uuid.bytes); i++) { r = sol_buffer_append_printf(&buf, upcase ? "%02hhX" : "%02hhx", uuid.bytes[i]); SOL_INT_CHECK_GOTO(r, < 0, err); } if (with_hyphens) { for (i = 0; i < SOL_UTIL_ARRAY_SIZE(hyphens_pos); i++) { r = sol_buffer_insert_slice(&buf, hyphens_pos[i], hyphen); SOL_INT_CHECK_GOTO(r, < 0, err); } } err: sol_buffer_fini(&buf); return r; }
return -1; } sol_coap_header_set_type(resp, SOL_COAP_TYPE_ACK); sol_coap_header_set_code(resp, SOL_COAP_RSPCODE_CONTENT); sol_coap_packet_get_payload(resp, &payload, &len); len = light_resource_to_rep(resource, get_scrolllock_led(), (char *)payload, len); sol_coap_packet_set_payload_used(resp, len); return sol_coap_send_packet(server, resp, cliaddr); } static struct sol_coap_resource light = { .get = light_method_get, .put = light_method_put, .iface = SOL_STR_SLICE_LITERAL("oc.mi.def"), .resource_type = SOL_STR_SLICE_LITERAL("core.light"), .flags = SOL_COAP_FLAGS_WELL_KNOWN | SOL_COAP_FLAGS_OC_CORE, .path = { SOL_STR_SLICE_LITERAL("a"), SOL_STR_SLICE_LITERAL("light"), SOL_STR_SLICE_EMPTY, } }; int main(int argc, char *argv[]) { struct light_context context = { .resource = &light }; struct sol_coap_server *server; char old_led_state;
sol_buffer_fini(&buf); if (size != (ssize_t)sizeof(*ret)) return -EIO; *ret = assert_uuid_v4(*ret); return 0; } // 37 = 2 * 16 (chars) + 4 (hyphens) + 1 (\0) int sol_util_uuid_gen(bool upcase, bool with_hyphens, char id[static 37]) { static struct sol_str_slice hyphen = SOL_STR_SLICE_LITERAL("-"); /* hyphens on positions 8, 13, 18, 23 (from 0) */ static const int hyphens_pos[] = { 8, 13, 18, 23 }; struct sol_uuid uuid = { { 0 } }; unsigned i; int r; struct sol_buffer buf = { 0 }; sol_buffer_init_flags(&buf, id, 37, SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED); r = uuid_gen(&uuid); SOL_INT_CHECK(r, < 0, r); for (i = 0; i < ARRAY_SIZE(uuid.bytes); i++) {
err_exit_del_client_list: sol_ptr_vector_remove(&server->clients, bs_cinfo); err_exit_del_client: bootstrap_client_info_del(bs_cinfo); err_exit: sol_coap_header_set_code(response, SOL_COAP_RESPONSE_CODE_BAD_REQUEST); sol_coap_send_packet(coap, response, cliaddr); return r; } static const struct sol_coap_resource bootstrap_request_interface = { SOL_SET_API_VERSION(.api_version = SOL_COAP_RESOURCE_API_VERSION, ) .post = bootstrap_request, .flags = SOL_COAP_FLAGS_NONE, .path = { SOL_STR_SLICE_LITERAL("bs"), SOL_STR_SLICE_EMPTY } }; SOL_API struct sol_lwm2m_bootstrap_server * sol_lwm2m_bootstrap_server_new(uint16_t port, const char **known_clients, uint16_t num_sec_modes, ...) { struct sol_lwm2m_bootstrap_server *server; struct sol_network_link_addr servaddr = { .family = SOL_NETWORK_FAMILY_INET6, .port = port }; int r; struct sol_lwm2m_security_psk **known_psks = NULL, *cli_psk; struct sol_lwm2m_security_rpk *my_rpk = NULL; struct sol_blob **known_pub_keys = NULL, *cli_pub_key;
SOL_INT_CHECK_GOTO(r, < 0, err); return sol_coap_send_packet(server, resp, cliaddr); err: sol_coap_packet_unref(resp); return r; } static struct sol_coap_resource light = { SOL_SET_API_VERSION(.api_version = SOL_COAP_RESOURCE_API_VERSION, ) .get = light_method_get, .put = light_method_put, .flags = SOL_COAP_FLAGS_WELL_KNOWN, .path = { SOL_STR_SLICE_LITERAL("a"), SOL_STR_SLICE_LITERAL("light"), SOL_STR_SLICE_EMPTY, } }; int main(int argc, char *argv[]) { struct light_context context = { .resource = &light }; struct sol_coap_server *server; char old_led_state; struct sol_network_link_addr servaddr = { .family = SOL_NETWORK_FAMILY_INET6, .port = DEFAULT_UDP_PORT }; sol_init();
} \ } while (0) struct sol_flow_packet { const struct sol_flow_packet_type *type; void *data; }; struct sol_flow_packet_composed_type { struct sol_flow_packet_type self; const struct sol_flow_packet_type **members; uint16_t members_len; }; static struct sol_ptr_vector composed_types_cache = SOL_PTR_VECTOR_INIT; static const struct sol_str_slice composed_prefix = SOL_STR_SLICE_LITERAL("composed:"); static inline void * sol_flow_packet_get_memory(const struct sol_flow_packet *packet) { if (!packet || !packet->type || !packet->type->data_size) return NULL; if (packet->type->data_size <= sizeof(packet->data)) return (void *)&packet->data; return (void *)packet->data; } static int packet_default_get(const struct sol_flow_packet_type *type, const void *mem, void *output) { memcpy(output, mem, type->data_size);
static void test_uuid_functions(void) { SOL_BUFFER_DECLARE_STATIC(buf, 37); struct sol_str_slice uuid_uh = SOL_STR_SLICE_LITERAL("9FD636DD-FF84-4075-8AE7-D55F2F7BA190"), uuid_lh = SOL_STR_SLICE_LITERAL("9fd636dd-ff84-4075-8ae7-d55f2f7ba190"), uuid_u = SOL_STR_SLICE_LITERAL("9FD636DDFF8440758AE7D55F2F7BA190"), uuid_l = SOL_STR_SLICE_LITERAL("9fd636ddff8440758ae7d55f2f7ba190"), uuid_invalid = SOL_STR_SLICE_LITERAL("9fd6-6dd1ff841407518ae71d5-f2f7ba190"), uuid_invalid2 = SOL_STR_SLICE_LITERAL("9fd636ddff8440758ae7d55-2f7ba190"), uuid_invalid3 = SOL_STR_SLICE_LITERAL("9fd636ddff8440758ae7d552f7ba190"); const uint8_t uuid_bytes[16] = { 0x9F, 0xD6, 0x36, 0xDD, 0xFF, 0x84, 0x40, 0x75, 0x8A, 0xE7, 0xD5, 0x5F, 0x2F, 0x7B, 0xA1, 0x90 }; //UUID string to bytes ASSERT_INT_EQ(sol_util_uuid_bytes_from_string(uuid_uh, &buf), 0); ASSERT_INT_EQ(buf.used, sizeof(uuid_bytes)); ASSERT_INT_EQ(memcmp(buf.data, uuid_bytes, sizeof(uuid_bytes)), 0); buf.used = 0; ASSERT_INT_EQ(sol_util_uuid_bytes_from_string(uuid_lh, &buf), 0); ASSERT_INT_EQ(buf.used, sizeof(uuid_bytes)); ASSERT_INT_EQ(memcmp(buf.data, uuid_bytes, sizeof(uuid_bytes)), 0); buf.used = 0; ASSERT_INT_EQ(sol_util_uuid_bytes_from_string(uuid_u, &buf), 0); ASSERT_INT_EQ(buf.used, sizeof(uuid_bytes)); ASSERT_INT_EQ(memcmp(buf.data, uuid_bytes, sizeof(uuid_bytes)), 0); buf.used = 0; ASSERT_INT_EQ(sol_util_uuid_bytes_from_string(uuid_l, &buf), 0); ASSERT_INT_EQ(buf.used, sizeof(uuid_bytes)); ASSERT_INT_EQ(memcmp(buf.data, uuid_bytes, sizeof(uuid_bytes)), 0); //UUID bytes to string buf.used = 0; ASSERT_INT_EQ(sol_util_uuid_string_from_bytes(true, true, uuid_bytes, &buf), 0); ASSERT(sol_str_slice_str_eq(uuid_uh, buf.data)); buf.used = 0; ASSERT_INT_EQ(sol_util_uuid_string_from_bytes(true, false, uuid_bytes, &buf), 0); ASSERT(sol_str_slice_str_eq(uuid_u, buf.data)); buf.used = 0; ASSERT_INT_EQ(sol_util_uuid_string_from_bytes(false, true, uuid_bytes, &buf), 0); ASSERT(sol_str_slice_str_eq(uuid_lh, buf.data)); buf.used = 0; ASSERT_INT_EQ(sol_util_uuid_string_from_bytes(false, false, uuid_bytes, &buf), 0); ASSERT(sol_str_slice_str_eq(uuid_l, buf.data)); //UUID validation ASSERT(sol_util_uuid_str_is_valid(uuid_uh)); ASSERT(sol_util_uuid_str_is_valid(uuid_lh)); ASSERT(sol_util_uuid_str_is_valid(uuid_u)); ASSERT(sol_util_uuid_str_is_valid(uuid_l)); ASSERT(!sol_util_uuid_str_is_valid(uuid_invalid)); ASSERT(!sol_util_uuid_str_is_valid(uuid_invalid2)); ASSERT(!sol_util_uuid_str_is_valid(uuid_invalid3)); }
static void test_escape_quotes(void) { static const struct { const struct sol_str_slice input; const struct sol_str_slice output; ssize_t int_result; enum sol_buffer_flags flags; } escape_tests[] = { //Cases where that copy is not necessary. { SOL_STR_SLICE_LITERAL("x"), SOL_STR_SLICE_LITERAL("x"), 0, SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED }, { SOL_STR_SLICE_LITERAL(" x"), SOL_STR_SLICE_LITERAL("x"), 0, SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED }, { SOL_STR_SLICE_LITERAL("x "), SOL_STR_SLICE_LITERAL("x"), 0, SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED }, { SOL_STR_SLICE_LITERAL("'x'"), SOL_STR_SLICE_LITERAL("x"), 0, SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED }, { SOL_STR_SLICE_LITERAL("\"x\""), SOL_STR_SLICE_LITERAL("x"), 0, SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED }, { SOL_STR_SLICE_LITERAL(" \"x\""), SOL_STR_SLICE_LITERAL("x"), 0, SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED }, { SOL_STR_SLICE_LITERAL("\"x\" "), SOL_STR_SLICE_LITERAL("x"), 0, SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED }, { SOL_STR_SLICE_LITERAL(" \"x\" "), SOL_STR_SLICE_LITERAL("x"), 0, SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED }, { SOL_STR_SLICE_LITERAL("'Locale'"), SOL_STR_SLICE_LITERAL("Locale"), 0, SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED }, { SOL_STR_SLICE_LITERAL("\"My String\""), SOL_STR_SLICE_LITERAL("My String"), 0, SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED }, { SOL_STR_SLICE_LITERAL(" \"My Stri ng\" "), SOL_STR_SLICE_LITERAL("My Stri ng"), 0, SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED }, { SOL_STR_SLICE_LITERAL(" "), SOL_STR_SLICE_LITERAL(""), 0, SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED }, { SOL_STR_SLICE_LITERAL("I'm good"), SOL_STR_SLICE_LITERAL("I'm good"), 0, SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED }, { SOL_STR_SLICE_LITERAL("Hello"), SOL_STR_SLICE_LITERAL("Hello"), 0, SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED }, { SOL_STR_SLICE_LITERAL("I 'like' you"), SOL_STR_SLICE_LITERAL("I like you"), 0, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("x'y'"), SOL_STR_SLICE_LITERAL("xy"), 0, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("x\\\"y"), SOL_STR_SLICE_LITERAL("x\"y"), 0, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("\\\'x"), SOL_STR_SLICE_LITERAL("'x"), 0, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("\\\"x"), SOL_STR_SLICE_LITERAL("\"x"), 0, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL(" \\\"x"), SOL_STR_SLICE_LITERAL("\"x"), 0, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("x\\\'y\\\"zd"), SOL_STR_SLICE_LITERAL("x'y\"zd"), 0, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("x\"y\""), SOL_STR_SLICE_LITERAL("xy"), 0, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("x\"y\"z\\\"f"), SOL_STR_SLICE_LITERAL("xyz\"f"), 0, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("\\'Locale\\'"), SOL_STR_SLICE_LITERAL("'Locale'"), 0, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("MyQuo\\\"tes"), SOL_STR_SLICE_LITERAL("MyQuo\"tes"), 0, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("MyQuo\\'tes2"), SOL_STR_SLICE_LITERAL("MyQuo'tes2"), 0, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("\\\"Hi, I'm good\\\" "), SOL_STR_SLICE_LITERAL("\"Hi, I'm good\""), 0, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL(" \\\"Hi, I'm good\\\" "), SOL_STR_SLICE_LITERAL("\"Hi, I'm good\""), 0, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL(" \\\"Hi, I'm good\\\" "), SOL_STR_SLICE_LITERAL("\"Hi, I'm good\""), 0, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("\\\"Hi, I'm good\\\""), SOL_STR_SLICE_LITERAL("\"Hi, I'm good\""), 0, SOL_BUFFER_FLAGS_DEFAULT }, //Cases that should fail { SOL_STR_SLICE_LITERAL("Wrong\\a"), SOL_STR_SLICE_LITERAL(""), -EINVAL, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("Wrong\\ba"), SOL_STR_SLICE_LITERAL(""), -EINVAL, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("'x\""), SOL_STR_SLICE_LITERAL(""), -EINVAL, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("\"x'"), SOL_STR_SLICE_LITERAL(""), -EINVAL, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("\"x'"), SOL_STR_SLICE_LITERAL(""), -EINVAL, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("'x\""), SOL_STR_SLICE_LITERAL(""), -EINVAL, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("'x"), SOL_STR_SLICE_LITERAL(""), -EINVAL, SOL_BUFFER_FLAGS_DEFAULT }, { SOL_STR_SLICE_LITERAL("\"x"), SOL_STR_SLICE_LITERAL(""), -EINVAL, SOL_BUFFER_FLAGS_DEFAULT }, }; size_t i; for (i = 0; i < sol_util_array_size(escape_tests); i++) { struct sol_buffer buf; int r; r = sol_util_unescape_quotes(escape_tests[i].input, &buf); ASSERT_INT_EQ(r, escape_tests[i].int_result); if (r < 0) continue; ASSERT(sol_str_slice_eq(escape_tests[i].output, sol_buffer_get_slice(&buf))); ASSERT(buf.flags == escape_tests[i].flags); sol_buffer_fini(&buf); } }