working client and server after refactoring the adaptor to allow for serial and gatt interfaces
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/12ef82c6 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/12ef82c6 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/12ef82c6 Branch: refs/heads/sterly_refactor Commit: 12ef82c64f072d79bcffd417ad803b503dac6431 Parents: 29a11be Author: Paul Dietrich <paulfdietr...@yahoo.com> Authored: Wed Sep 21 10:47:56 2016 -0700 Committer: Paul Dietrich <paulfdietr...@yahoo.com> Committed: Wed Sep 21 10:48:28 2016 -0700 ---------------------------------------------------------------------- apps/ocf_sample/pkg.yml | 8 +- apps/ocf_sample/src/main.c | 141 ++++++++++-- libs/iotivity/pkg.yml | 2 +- libs/iotivity/src/api/oc_ri.c | 2 +- libs/iotivity/src/port/mynewt/adaptor.c | 223 +++++++++++++++++++ libs/iotivity/src/port/mynewt/adaptor.h | 61 +++++ libs/iotivity/src/port/mynewt/ble_adaptor.c | 18 ++ libs/iotivity/src/port/mynewt/config.h | 2 + libs/iotivity/src/port/mynewt/ip_adaptor.c | 234 ++++++++------------ libs/iotivity/src/port/mynewt/serial_adaptor.c | 153 +++++++++++++ libs/iotivity/src/port/oc_connectivity.h | 3 +- libs/os/include/os/os_eventq.h | 2 +- 12 files changed, 685 insertions(+), 164 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/12ef82c6/apps/ocf_sample/pkg.yml ---------------------------------------------------------------------- diff --git a/apps/ocf_sample/pkg.yml b/apps/ocf_sample/pkg.yml index 32c96f2..52858b5 100644 --- a/apps/ocf_sample/pkg.yml +++ b/apps/ocf_sample/pkg.yml @@ -33,4 +33,10 @@ pkg.deps: - libs/iotivity # this tells the library that you intend to suppor the server functionality -pkg.cflags: -DOC_SERVER \ No newline at end of file +pkg.cflags: + +#-DOC_SERVER -- build the server examples +#-DOC_CLIENT -- build the client examples +#-DOC_TRANSPORT_GATT -- to send COAP over GATT +#-DOC_TRANSPORT_SERIAL -- to send COAP over serial +#-DOC_TRANSPORT_IP -- to send COAP over IP ÃÃ \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/12ef82c6/apps/ocf_sample/src/main.c ---------------------------------------------------------------------- diff --git a/apps/ocf_sample/src/main.c b/apps/ocf_sample/src/main.c index 4d90495..78846d2 100644 --- a/apps/ocf_sample/src/main.c +++ b/apps/ocf_sample/src/main.c @@ -28,7 +28,7 @@ #include "mn_socket/arch/sim/native_sock.h" /* Shell */ -#define SHELL_TASK_PRIO (8) +#define SHELL_TASK_PRIO (8) #define SHELL_MAX_INPUT_LEN (256) #define SHELL_TASK_STACK_SIZE (OS_STACK_ALIGN(2048)) static os_stack_t shell_stack[SHELL_TASK_STACK_SIZE]; @@ -38,8 +38,6 @@ static os_stack_t shell_stack[SHELL_TASK_STACK_SIZE]; static os_stack_t ocf_stack[OCF_TASK_STACK_SIZE]; struct os_task ocf_task; -static bool light_state = false; - #define DEFAULT_MBUF_MPOOL_BUF_LEN (256) #define DEFAULT_MBUF_MPOOL_NBUFS (10) @@ -49,6 +47,13 @@ static uint8_t default_mbuf_mpool_data[DEFAULT_MBUF_MPOOL_BUF_LEN * static struct os_mbuf_pool default_mbuf_pool; static struct os_mempool default_mbuf_mpool; +#ifdef OC_CLIENT +static void issue_requests(void); +#endif + +#ifdef OC_SERVER +static bool light_state = false; + static void get_light(oc_request_t *request, oc_interface_mask_t interface) { @@ -93,13 +98,6 @@ put_light(oc_request_t *request, oc_interface_mask_t interface) } static void -app_init(void) -{ - oc_init_platform("Mynewt", NULL, NULL); - oc_add_device("/oic/d", "oic.d.light", "MynewtLED", "1.0", "1.0", NULL, NULL); -} - -static void register_resources(void) { oc_resource_t *res = oc_new_resource("/light/1", 1, 0); @@ -107,22 +105,131 @@ register_resources(void) oc_resource_bind_resource_interface(res, OC_IF_RW); oc_resource_set_default_interface(res, OC_IF_RW); -#ifdef OC_SECURITY - oc_resource_make_secure(res); -#endif - oc_resource_set_discoverable(res); oc_resource_set_periodic_observable(res, 1); oc_resource_set_request_handler(res, OC_GET, get_light); oc_resource_set_request_handler(res, OC_PUT, put_light); oc_add_resource(res); } +#endif -struct os_sem ocf_main_loop_sem; +#ifdef OC_CLIENT +#define MAX_URI_LENGTH (30) +static char light_1[MAX_URI_LENGTH]; +static oc_server_handle_t light_server; +static bool light_state = false; + +static void +set_device_custom_property(void *data) +{ + oc_set_custom_device_property(purpose, "operate mynewt-light"); +} + +static oc_event_callback_retval_t +stop_observe(void *data) +{ + PRINT("Stopping OBSERVE\n"); + oc_stop_observe(light_1, &light_server); + return DONE; +} + +static void +put_light(oc_client_response_t *data) +{ + PRINT("PUT_light:\n"); + if (data->code == OC_STATUS_CHANGED) + PRINT("PUT response OK\n"); + else + PRINT("PUT response code %d\n", data->code); +} + +static void +observe_light(oc_client_response_t *data) +{ + PRINT("OBSERVE_light:\n"); + oc_rep_t *rep = data->payload; + while (rep != NULL) { + PRINT("key %s, value ", oc_string(rep->name)); + switch (rep->type) { + case BOOL: + PRINT("%d\n", rep->value_boolean); + light_state = rep->value_boolean; + break; + default: + break; + } + rep = rep->next; + } + + if (oc_init_put(light_1, &light_server, NULL, &put_light, LOW_QOS)) { + oc_rep_start_root_object(); + oc_rep_set_boolean(root, state, !light_state); + oc_rep_end_root_object(); + if (oc_do_put()) + PRINT("Sent PUT request\n"); + else + PRINT("Could not send PUT\n"); + } else + PRINT("Could not init PUT\n"); +} + +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); + oc_set_delayed_callback(NULL, &stop_observe, 30); + return OC_STOP_DISCOVERY; + } + } + return OC_CONTINUE_DISCOVERY; +} + +static void +issue_requests(void) +{ + oc_do_ip_discovery("oic.r.light", &discovery); +} + +#endif + +static void +app_init(void) +{ + oc_init_platform("Mynewt", NULL, NULL); +#ifdef OC_CLIENT + oc_add_device("/oic/d", "oic.d.phone", "MynewtClient", "1.0", "1.0", + set_device_custom_property, NULL); +#endif + +#ifdef OC_SERVER + oc_add_device("/oic/d", "oic.d.light", "MynewtServer", "1.0", "1.0", NULL, NULL); +#endif +} oc_handler_t ocf_handler = {.init = app_init, - .register_resources = register_resources }; +#ifdef OC_SERVER + .register_resources = register_resources, +#endif +#ifdef OC_CLIENT + .requests_entry = issue_requests, +#endif + }; + +struct os_sem ocf_main_loop_sem; void oc_signal_main_loop(void) { @@ -184,8 +291,10 @@ main(int argc, char **argv) SHELL_MAX_INPUT_LEN); assert(rc == 0); +#ifdef OC_TRANSPORT_IP rc = native_sock_init(); assert(rc == 0); +#endif ocf_task_init(); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/12ef82c6/libs/iotivity/pkg.yml ---------------------------------------------------------------------- diff --git a/libs/iotivity/pkg.yml b/libs/iotivity/pkg.yml index 87b4b45..f837bf4 100644 --- a/libs/iotivity/pkg.yml +++ b/libs/iotivity/pkg.yml @@ -29,7 +29,7 @@ pkg.deps: - "@apache-mynewt-core/sys/mn_socket" - "@apache-mynewt-core/sys/log" -# remove debug option to save logging +# remove debug option to save logging pkg.cflags: -std=c99 -DDEBUG=1 -DSECURE=0 http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/12ef82c6/libs/iotivity/src/api/oc_ri.c ---------------------------------------------------------------------- diff --git a/libs/iotivity/src/api/oc_ri.c b/libs/iotivity/src/api/oc_ri.c index 76d7ed2..7a6df95 100644 --- a/libs/iotivity/src/api/oc_ri.c +++ b/libs/iotivity/src/api/oc_ri.c @@ -895,7 +895,7 @@ oc_ri_invoke_client_cb(void *response, oc_endpoint_t *endpoint) break; } } - coap_get_header_observe(pkt, &client_response.observe_option); + coap_get_header_observe(pkt, (uint32_t*)&client_response.observe_option); bool separate = false; /* http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/12ef82c6/libs/iotivity/src/port/mynewt/adaptor.c ---------------------------------------------------------------------- diff --git a/libs/iotivity/src/port/mynewt/adaptor.c b/libs/iotivity/src/port/mynewt/adaptor.c new file mode 100644 index 0000000..2a80f4c --- /dev/null +++ b/libs/iotivity/src/port/mynewt/adaptor.c @@ -0,0 +1,223 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#include <assert.h> +#include <os/os.h> +#include <os/endian.h> +#include <string.h> +#include <log/log.h> +#include "../oc_network_events_mutex.h" +#include "../oc_connectivity.h" +#include "oc_buffer.h" +#include "../oc_log.h" +#include "adaptor.h" + +struct os_eventq oc_event_q; + +/* not sure if these semaphores are necessary yet. If we are running + * all of this from one task, we may not need these */ +static struct os_mutex oc_net_mutex; + +void +oc_network_event_handler_mutex_init(void) +{ + os_error_t rc; + rc = os_mutex_init(&oc_net_mutex); + assert(rc == 0); +} + +void +oc_network_event_handler_mutex_lock(void) +{ + os_mutex_pend(&oc_net_mutex, OS_TIMEOUT_NEVER); +} + +void +oc_network_event_handler_mutex_unlock(void) +{ + os_mutex_release(&oc_net_mutex); +} + +/* need a task to process OCF messages */ +#define OC_NET_TASK_STACK_SIZE OS_STACK_ALIGN(300) +#define OC_NET_TASK_PRIORITY (4) +struct os_task oc_task; +os_stack_t *oc_stack; + +void +oc_send_buffer(oc_message_t *message) { + + switch (message->endpoint.flags) + { +#ifdef OC_TRANSPORT_IP + case IP: + oc_send_buffer_ip(message); + break; +#endif +#ifdef OC_TRANSPORT_GATT + case GATT: + oc_send_buffer_gatt(message); + break; +#endif +#ifdef OC_TRANSPORT_SERIAL + case SERIAL: + oc_send_buffer_serial(message); + break; +#endif + default: + ERROR("Unknown transport option %u\n", message->endpoint.flags); + oc_message_unref(message); + } +} + +void oc_send_multicast_message(oc_message_t *message) +{ + + /* send on all the transports. Don't forget to reference the message + * so it doesn't get deleted */ + +#ifdef OC_TRANSPORT_IP + oc_send_buffer_ip_mcast(message); +#endif + +#ifdef OC_TRANSPORT_GATT + /* no multicast for GATT, just send unicast */ + oc_message_add_ref(message); + oc_send_buffer_gatt(message); +#endif + +#ifdef OC_TRANSPORT_SERIAL + /* no multi-cast for serial. just send unicast */ + oc_message_add_ref(message); + oc_send_buffer_serial(message); +#endif +} + +/* send all the entries to the OCF stack through the same task */ +void +oc_task_handler(void *arg) { + while (1) { + oc_message_t *pmsg; + (void) pmsg; /* to avoid unused */ + struct os_event *evt = os_eventq_get(&oc_event_q); + + switch(evt->ev_type) { + +#ifdef OC_TRANSPORT_IP + case OC_ADATOR_EVENT_IP: + while ((pmsg = oc_attempt_rx_ip()) != NULL) { + oc_network_event(pmsg); + } + break; +#endif + +#ifdef OC_TRANSPORT_SERIAL + case OC_ADATOR_EVENT_SERIAL: + while ((pmsg = oc_attempt_rx_serial()) != NULL) { + oc_network_event(pmsg); + } + break; +#endif + +#ifdef OC_TRANSPORT_GATT + case OC_ADATOR_EVENT_GATT: + while ((pmsg = oc_attempt_rx_gatt()) != NULL) { + oc_network_event(pmsg); + } + break; +#endif + default: + ERROR("oc_task_handler: Unidentified event %d\n", evt->ev_type); + + } + } +} + +static int +oc_init_task(void) { + int rc; + + os_eventq_init(&oc_event_q); + + oc_stack = (os_stack_t*) malloc(sizeof(os_stack_t)*OC_NET_TASK_STACK_SIZE); + if (NULL == oc_stack) { + ERROR("Could not malloc oc stack\n"); + return -1; + } + + rc = os_task_init(&oc_task, "oc", oc_task_handler, NULL, + OC_NET_TASK_PRIORITY, OS_WAIT_FOREVER, + oc_stack, OC_NET_TASK_STACK_SIZE); + + if (rc != 0) { + ERROR("Could not start oc task\n"); + free(oc_stack); + } + + return rc; +} + +void +oc_connectivity_shutdown(void) +{ +#ifdef OC_TRANSPORT_IP + oc_connectivity_shutdown_ip(); +#endif +#ifdef OC_TRANSPORT_SERIAL + oc_connectivity_shutdown_serial(); +#endif +#ifdef OC_TRANSPORT_GATT + oc_connectivity_shutdown_gatt(); +#endif +} + +int +oc_connectivity_init(void) +{ + int rc; + +#ifdef OC_TRANSPORT_IP + rc = oc_connectivity_init_ip(); + if (rc != 0) { + goto oc_connectivity_init_err; + } +#endif +#ifdef OC_TRANSPORT_SERIAL + rc = oc_connectivity_init_serial(); + if (rc != 0) { + goto oc_connectivity_init_err; + } +#endif +#ifdef OC_TRANSPORT_GATT + rc = oc_connectivity_init_gatt(); + if (rc != 0) { + goto oc_connectivity_init_err; + } +#endif + + rc = oc_init_task(); + if (rc != 0) { + goto oc_connectivity_init_err; + } + + return 0; + +oc_connectivity_init_err: + oc_connectivity_shutdown(); + return rc; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/12ef82c6/libs/iotivity/src/port/mynewt/adaptor.h ---------------------------------------------------------------------- diff --git a/libs/iotivity/src/port/mynewt/adaptor.h b/libs/iotivity/src/port/mynewt/adaptor.h new file mode 100644 index 0000000..431c7e9 --- /dev/null +++ b/libs/iotivity/src/port/mynewt/adaptor.h @@ -0,0 +1,61 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef ADAPTOR_H +#define ADAPTOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define OC_ADATOR_EVENT_IP (OS_EVENT_T_PERUSER + 0) +#define OC_ADATOR_EVENT_SERIAL (OS_EVENT_T_PERUSER + 1) +#define OC_ADATOR_EVENT_GATT (OS_EVENT_T_PERUSER + 2) + +extern struct os_eventq oc_event_q; + + +#ifdef OC_TRANSPORT_IP +int oc_connectivity_init_ip(void); +void oc_connectivity_shutdown_ip(void); +void oc_send_buffer_ip(oc_message_t *message); +void oc_send_buffer_ip_mcast(oc_message_t *message); +oc_message_t *oc_attempt_rx_ip(void); +#endif + +#ifdef OC_TRANSPORT_GATT +int oc_connectivity_init_gatt(void); +void oc_connectivity_shutdown_gatt(void); +void oc_send_buffer_gatt(oc_message_t *message); +oc_message_t *oc_attempt_rx_gatt(void); +#endif + +#ifdef OC_TRANSPORT_SERIAL +int oc_connectivity_init_serial(void); +void oc_connectivity_shutdown_serial(void); +void oc_send_buffer_serial(oc_message_t *message); +oc_message_t *oc_attempt_rx_serial(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ADAPTOR_H */ + http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/12ef82c6/libs/iotivity/src/port/mynewt/ble_adaptor.c ---------------------------------------------------------------------- diff --git a/libs/iotivity/src/port/mynewt/ble_adaptor.c b/libs/iotivity/src/port/mynewt/ble_adaptor.c new file mode 100644 index 0000000..f736fe1 --- /dev/null +++ b/libs/iotivity/src/port/mynewt/ble_adaptor.c @@ -0,0 +1,18 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/12ef82c6/libs/iotivity/src/port/mynewt/config.h ---------------------------------------------------------------------- diff --git a/libs/iotivity/src/port/mynewt/config.h b/libs/iotivity/src/port/mynewt/config.h index 10b4f95..83e19de 100644 --- a/libs/iotivity/src/port/mynewt/config.h +++ b/libs/iotivity/src/port/mynewt/config.h @@ -54,4 +54,6 @@ typedef os_time_t oc_clock_time_t; /* Max inactivity timeout before tearing down DTLS connection */ //#define DTLS_INACTIVITY_TIMEOUT (10) +#define MYNEWT_OCF_SERIAL_PORT (1) + #endif /* CONFIG_H */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/12ef82c6/libs/iotivity/src/port/mynewt/ip_adaptor.c ---------------------------------------------------------------------- diff --git a/libs/iotivity/src/port/mynewt/ip_adaptor.c b/libs/iotivity/src/port/mynewt/ip_adaptor.c index 9b8bbff..8ae67e4 100644 --- a/libs/iotivity/src/port/mynewt/ip_adaptor.c +++ b/libs/iotivity/src/port/mynewt/ip_adaptor.c @@ -24,15 +24,22 @@ #include <log/log.h> #include <mn_socket/mn_socket.h> -#include "../oc_network_events_mutex.h" #include "../oc_connectivity.h" #include "oc_buffer.h" #include "../oc_log.h" +#include "adaptor.h" + +#ifdef OC_TRANSPORT_IP + +struct os_event oc_sock_read_event = { + .ev_type = OC_ADATOR_EVENT_IP, +}; #ifdef OC_SECURITY #error This implementation does not yet support security #endif + #define COAP_PORT_UNSECURED (5683) /* TODO use inet_pton when its available */ const struct mn_in6_addr coap_all_nodes_v6 = { @@ -40,89 +47,86 @@ const struct mn_in6_addr coap_all_nodes_v6 = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFD} }; -/* need a task to process OCF messages */ -#define OC_NET_TASK_STACK_SIZE OS_STACK_ALIGN(300) -#define OC_NET_TASK_PRIORITY (4) -struct os_task oc_task; -os_stack_t *oc_stack; /* sockets to use for coap unicast and multicast */ -struct mn_socket *mcast; struct mn_socket *ucast; -/* to wake our task when stuff is ready */ -struct os_sem oc_read_sem; -struct os_sem oc_write_sem; - -/* not sure if these semaphores are necessary yet. If we are running - * all of this from one task, we may not need these */ -static struct os_mutex oc_net_mutex; - -void -oc_network_event_handler_mutex_init(void) -{ - os_error_t rc; - rc = os_mutex_init(&oc_net_mutex); - assert(rc == 0); -} - -void -oc_network_event_handler_mutex_lock(void) -{ - os_mutex_pend(&oc_net_mutex, OS_TIMEOUT_NEVER); -} - -void -oc_network_event_handler_mutex_unlock(void) -{ - os_mutex_release(&oc_net_mutex); -} +#ifdef OC_SERVER +struct mn_socket *mcast; +#endif -void -oc_send_buffer(oc_message_t *message) +static void +oc_send_buffer_ip_int(oc_message_t *message, int mcast) { struct mn_sockaddr_in6 to; - struct mn_socket * send_sock; struct os_mbuf m; int rc; - while (1) { - LOG("attempt send buffer %lu\n", message->length); - - to.msin6_len = sizeof(to); - to.msin6_family = MN_AF_INET6; - to.msin6_scope_id = message->endpoint.ipv6_addr.scope; - to.msin6_port = htons(message->endpoint.ipv6_addr.port); - memcpy(&to.msin6_addr, message->endpoint.ipv6_addr.address, - sizeof(to.msin6_addr)); - send_sock = ucast; - - /* put on an mbuf header to make the socket happy */ - memset(&m,0, sizeof(m)); - m.om_data = message->data; - m.om_len = message->length; - - rc = mn_sendto(send_sock, &m, (struct mn_sockaddr *) &to); - /* TODO what to do if this fails, we can't keep the buffer */ + LOG("oc_transport_ip attempt send buffer %lu\n", message->length); + + to.msin6_len = sizeof(to); + to.msin6_family = MN_AF_INET6; + + to.msin6_port = htons(message->endpoint.ipv6_addr.port); + memcpy(&to.msin6_addr, message->endpoint.ipv6_addr.address, + sizeof(to.msin6_addr)); + + /* put on an mbuf header to make the socket happy */ + memset(&m,0, sizeof(m)); + m.om_data = message->data; + m.om_len = message->length; + to.msin6_scope_id = message->endpoint.ipv6_addr.scope; + + if (mcast) { + struct mn_itf itf; + memset(&itf, 0, sizeof(itf)); + + while (1) { + rc = mn_itf_getnext(&itf); + if (rc) { + break; + } + + if (0 == (itf.mif_flags & MN_ITF_F_UP)) { + continue; + } + + to.msin6_scope_id = itf.mif_idx; + + rc = mn_sendto(ucast, &m, (struct mn_sockaddr *) &to); + if (rc != 0) { + ERROR("Failed sending buffer %lu on itf %d\n", + message->length, to.msin6_scope_id); + } + } + } else { + rc = mn_sendto(ucast, &m, (struct mn_sockaddr *) &to); if (rc != 0) { - ERROR("Failed sending buffer %lu\n", message->length); - } else { - break; + ERROR("Failed sending buffer %lu on itf %d\n", + message->length, to.msin6_scope_id); } - /* if we failed to write, wait around until we can */ - os_sem_pend(&oc_write_sem, OS_TIMEOUT_NEVER); } + oc_message_unref(message); +} + +void +oc_send_buffer_ip(oc_message_t *message) { + oc_send_buffer_ip_int(message, 0); +} +void +oc_send_buffer_ip_mcast(oc_message_t *message) { + oc_send_buffer_ip_int(message, 1); } oc_message_t * -oc_attempt_rx(struct mn_socket * rxsock) { +oc_attempt_rx_ip_sock(struct mn_socket * rxsock) { int rc; struct os_mbuf *m = NULL; struct os_mbuf_pkthdr *pkt; oc_message_t *message = NULL; struct mn_sockaddr_in6 from; - LOG("attempt rx from %p\n", rxsock); + LOG("oc_transport_ip attempt rx from %p\n", rxsock); rc= mn_recvfrom(rxsock, &m, (struct mn_sockaddr *) &from); @@ -181,108 +185,55 @@ rx_attempt_err: } oc_message_t * -oc_attempt_rx_mcast(void) { - return oc_attempt_rx(mcast); -} - -oc_message_t * -oc_attempt_rx_ucast(void) { - return oc_attempt_rx(ucast); +oc_attempt_rx_ip(void) { + oc_message_t *pmsg; + pmsg = oc_attempt_rx_ip_sock(ucast); +#ifdef OC_SERVER + if (pmsg == NULL ) { + pmsg = oc_attempt_rx_ip_sock(mcast); + } +#endif + return pmsg; } static void oc_socks_readable(void *cb_arg, int err); -static void oc_socks_writable(void *cb_arg, int err); union mn_socket_cb oc_sock_cbs = { .socket.readable = oc_socks_readable, - .socket.writable = oc_socks_writable + .socket.writable = NULL }; void oc_socks_readable(void *cb_arg, int err) { - os_sem_release(&oc_read_sem); -} - -void -oc_socks_writable(void *cb_arg, int err) -{ - os_sem_release(&oc_write_sem); -} - -void -oc_task_handler(void *arg) { - while (1) { - oc_message_t *pmsg; - os_sem_pend(&oc_read_sem, OS_TIMEOUT_NEVER); - pmsg = oc_attempt_rx_ucast(); - if (pmsg) { - oc_network_event(pmsg); - } - - pmsg = oc_attempt_rx_mcast(); - if (pmsg) { - oc_network_event(pmsg); - } - } -} - -static int -oc_init_net_task(void) { - int rc; - - /* start this thing running to check right away */ - rc = os_sem_init(&oc_read_sem, 1); - if (0 != rc) { - ERROR("Could not initialize oc read sem\n"); - return rc; - } - - rc = os_sem_init(&oc_write_sem, 1); - if (0 != rc) { - ERROR("Could not initialize oc write sem\n"); - return rc; - } - - oc_stack = (os_stack_t*) malloc(sizeof(os_stack_t)*OC_NET_TASK_STACK_SIZE); - if (NULL == oc_stack) { - ERROR("Could not malloc oc stack\n"); - return -1; - } - - rc = os_task_init(&oc_task, "oc", oc_task_handler, NULL, - OC_NET_TASK_PRIORITY, OS_WAIT_FOREVER, - oc_stack, OC_NET_TASK_STACK_SIZE); - - if (rc != 0) { - ERROR("Could not start oc task\n"); - free(oc_stack); - } - - return rc; + os_eventq_put(&oc_event_q, &oc_sock_read_event); } void -oc_connectivity_shutdown(void) +oc_connectivity_shutdown_ip(void) { - LOG("OC shutdown"); + LOG("OC shutdown IP\n"); if (ucast) { mn_close(ucast); } +#ifdef OC_SERVER if (mcast) { mn_close(mcast); } +#endif + } int -oc_connectivity_init(void) +oc_connectivity_init_ip(void) { int rc; struct mn_sockaddr_in6 sin; struct mn_itf itf; + LOG("OC transport init IP\n"); memset(&itf, 0, sizeof(itf)); rc = oc_log_init(); @@ -295,14 +246,17 @@ oc_connectivity_init(void) ERROR("Could not create oc unicast socket\n"); return rc; } + mn_socket_set_cbs(ucast, ucast, &oc_sock_cbs); + +#ifdef OC_SERVER rc = mn_socket(&mcast, MN_PF_INET6, MN_SOCK_DGRAM, 0); if ( rc != 0 || !mcast ) { mn_close(ucast); ERROR("Could not create oc multicast socket\n"); return rc; } - mn_socket_set_cbs(ucast, ucast, &oc_sock_cbs); mn_socket_set_cbs(mcast, mcast, &oc_sock_cbs); +#endif sin.msin6_len = sizeof(sin); sin.msin6_family = MN_AF_INET6; @@ -316,6 +270,7 @@ oc_connectivity_init(void) goto oc_connectivity_init_err; } +#ifdef OC_SERVER /* Set socket option to join multicast group on all valid interfaces */ while (1) { struct mn_mreq join; @@ -348,11 +303,7 @@ oc_connectivity_init(void) ERROR("Could not bind oc multicast socket\n"); goto oc_connectivity_init_err; } - - rc = oc_init_net_task(); - if (rc != 0) { - goto oc_connectivity_init_err; - } +#endif return 0; @@ -361,7 +312,4 @@ oc_connectivity_init_err: return rc; } -void oc_send_multicast_message(oc_message_t *message) -{ - oc_send_buffer(message); -} \ No newline at end of file +#endif \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/12ef82c6/libs/iotivity/src/port/mynewt/serial_adaptor.c ---------------------------------------------------------------------- diff --git a/libs/iotivity/src/port/mynewt/serial_adaptor.c b/libs/iotivity/src/port/mynewt/serial_adaptor.c new file mode 100644 index 0000000..ddca3bb --- /dev/null +++ b/libs/iotivity/src/port/mynewt/serial_adaptor.c @@ -0,0 +1,153 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <assert.h> +#include <os/os.h> +#include <shell/shell.h> +#include "oc_buffer.h" +#include "../oc_log.h" +#include "adaptor.h" + +#ifdef OC_TRANSPORT_SERIAL + +struct os_mqueue oc_serial_mqueue; + +static int +oc_serial_in(struct os_mbuf *m, void *arg) +{ + return os_mqueue_put(&oc_serial_mqueue, &oc_event_q, m); +} + +void +oc_connectivity_shutdown_serial(void) { + shell_nlip_input_register(NULL, NULL); +} + +int +oc_connectivity_init_serial(void) { + int rc; + + rc = shell_nlip_input_register(oc_serial_in, NULL); + if (rc != 0) { + goto err; + } + + rc = os_mqueue_init(&oc_serial_mqueue, NULL); + if (rc != 0) { + goto err; + } + /* override the eventq type */ + oc_serial_mqueue.mq_ev.ev_type = OC_ADATOR_EVENT_SERIAL; + +err: + oc_connectivity_shutdown_serial(); + return rc; +} + + +void oc_send_buffer_serial(oc_message_t *message) { + int rc; + struct os_mbuf *m; + + /* get a packet header */ + m = os_msys_get_pkthdr(0, 0); + if (m == NULL) { + goto err; + } + + /* add this data to the mbuf */ + rc = os_mbuf_append(m, message->data, message->length); + if (rc != 0) { + goto err; + } + + /* send over the shell output */ + rc = shell_nlip_output(m); + if (rc != 0) { + goto err; + } + + return; + + err: + ERROR("Unable to send message via oc_serial %d\n", rc); + oc_message_unref(message); + return; + +} + +oc_message_t * +oc_attempt_rx_serial(void) { + int rc; + struct os_mbuf *m = NULL; + struct os_mbuf_pkthdr *pkt; + oc_message_t *message = NULL; + + LOG("oc_transport_serial attempt rx\n"); + + /* get an mbuf from the queue */ + m = os_mqueue_get(&oc_serial_mqueue); + + if (!OS_MBUF_IS_PKTHDR(m)) { + goto rx_attempt_err; + } + + pkt = OS_MBUF_PKTHDR(m); + + LOG("oc_transport_serial rx %p-%u\n", pkt, pkt->omp_len); + + message = oc_allocate_message(); + if (NULL == message) { + ERROR("Could not allocate OC message buffer\n"); + goto rx_attempt_err; + } + + if (pkt->omp_len > MAX_PAYLOAD_SIZE) { + ERROR("Message to large for OC message buffer\n"); + goto rx_attempt_err; + } + /* copy to message from mbuf chain */ + rc = os_mbuf_copydata(m, 0, pkt->omp_len, message->data); + if (rc != 0) { + ERROR("Failed to copy message from mbuf to OC message buffer \n"); + goto rx_attempt_err; + } + + os_mbuf_free_chain(m); + + message->endpoint.flags = SERIAL; + message->length = pkt->omp_len; + + LOG("Successfully rx length %lu\n", message->length); + return message; + + /* add the addr info to the message */ +rx_attempt_err: + if (m) { + os_mbuf_free_chain(m); + } + + if (message) { + oc_message_unref(message); + } + + return NULL; +} + +#endif \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/12ef82c6/libs/iotivity/src/port/oc_connectivity.h ---------------------------------------------------------------------- diff --git a/libs/iotivity/src/port/oc_connectivity.h b/libs/iotivity/src/port/oc_connectivity.h index b004cea..4e4cdec 100644 --- a/libs/iotivity/src/port/oc_connectivity.h +++ b/libs/iotivity/src/port/oc_connectivity.h @@ -44,7 +44,8 @@ typedef struct GATT = 1 << 1, IPSP = 1 << 2, MULTICAST = 1 << 3, - SECURED = 1 << 4 + SECURED = 1 << 4, + SERIAL = 1 <<5, } flags; union http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/12ef82c6/libs/os/include/os/os_eventq.h ---------------------------------------------------------------------- diff --git a/libs/os/include/os/os_eventq.h b/libs/os/include/os/os_eventq.h index 9e2b1be..b298f92 100644 --- a/libs/os/include/os/os_eventq.h +++ b/libs/os/include/os/os_eventq.h @@ -33,7 +33,7 @@ struct os_event { #define OS_EVENT_QUEUED(__ev) ((__ev)->ev_queued) #define OS_EVENT_T_TIMER (1) -#define OS_EVENT_T_MQUEUE_DATA (2) +#define OS_EVENT_T_MQUEUE_DATA (2) #define OS_EVENT_T_PERUSER (16) struct os_eventq {