blob: 78846d2adaae4793b8214741291b4007162c3065 [file] [log] [blame]
/**
* 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 <bsp/bsp.h>
#include <console/console.h>
#include <shell/shell.h>
#include <log/log.h>
#include <iotivity/oc_api.h>
#include "mn_socket/mn_socket.h"
#include "mn_socket/arch/sim/native_sock.h"
/* Shell */
#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];
#define OCF_TASK_PRIO (8)
#define OCF_TASK_STACK_SIZE (OS_STACK_ALIGN(2048))
static os_stack_t ocf_stack[OCF_TASK_STACK_SIZE];
struct os_task ocf_task;
#define DEFAULT_MBUF_MPOOL_BUF_LEN (256)
#define DEFAULT_MBUF_MPOOL_NBUFS (10)
static uint8_t default_mbuf_mpool_data[DEFAULT_MBUF_MPOOL_BUF_LEN *
DEFAULT_MBUF_MPOOL_NBUFS];
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)
{
PRINT("GET_light:\n");
oc_rep_start_root_object();
switch (interface) {
case OC_IF_BASELINE:
oc_process_baseline_interface(request->resource);
case OC_IF_RW:
oc_rep_set_boolean(root, state, light_state);
break;
default:
break;
}
oc_rep_end_root_object();
oc_send_response(request, OC_STATUS_OK);
PRINT("Light state %d\n", light_state);
}
static void
put_light(oc_request_t *request, oc_interface_mask_t interface)
{
PRINT("PUT_light:\n");
bool state = false;
oc_rep_t *rep = request->request_payload;
while (rep != NULL) {
PRINT("key: %s ", oc_string(rep->name));
switch (rep->type) {
case BOOL:
state = rep->value_boolean;
PRINT("value: %d\n", state);
break;
default:
oc_send_response(request, OC_STATUS_BAD_REQUEST);
return;
break;
}
rep = rep->next;
}
oc_send_response(request, OC_STATUS_CHANGED);
light_state = state;
}
static void
register_resources(void)
{
oc_resource_t *res = oc_new_resource("/light/1", 1, 0);
oc_resource_bind_resource_type(res, "oic.r.light");
oc_resource_bind_resource_interface(res, OC_IF_RW);
oc_resource_set_default_interface(res, OC_IF_RW);
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
#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,
#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) {
os_sem_release(&ocf_main_loop_sem);
}
void ocf_task_handler(void *arg) {
/* TODO */
oc_main_init(&ocf_handler);
os_sem_init(&ocf_main_loop_sem, 1);
while (1) {
uint32_t ticks;
oc_clock_time_t next_event;
next_event = oc_main_poll();
ticks = oc_clock_time();
if (next_event == 0) {
ticks = OS_TIMEOUT_NEVER;
} else {
ticks = next_event - ticks;
}
os_sem_pend(&ocf_main_loop_sem, ticks);
}
oc_main_shutdown();
}
void
ocf_task_init(void) {
int rc;
rc = os_task_init(&ocf_task, "ocf", ocf_task_handler, NULL,
OCF_TASK_PRIO, OS_WAIT_FOREVER, ocf_stack, OCF_TASK_STACK_SIZE);
assert(rc == 0);
}
int
main(int argc, char **argv)
{
int rc;
/* Initialize OS */
os_init();
rc = os_mempool_init(&default_mbuf_mpool, DEFAULT_MBUF_MPOOL_NBUFS,
DEFAULT_MBUF_MPOOL_BUF_LEN, default_mbuf_mpool_data,
"default_mbuf_data");
assert(rc == 0);
rc = os_mbuf_pool_init(&default_mbuf_pool, &default_mbuf_mpool,
DEFAULT_MBUF_MPOOL_BUF_LEN, DEFAULT_MBUF_MPOOL_NBUFS);
assert(rc == 0);
rc = os_msys_register(&default_mbuf_pool);
assert(rc == 0);
/* Init tasks */
rc = shell_task_init(SHELL_TASK_PRIO, shell_stack, SHELL_TASK_STACK_SIZE,
SHELL_MAX_INPUT_LEN);
assert(rc == 0);
#ifdef OC_TRANSPORT_IP
rc = native_sock_init();
assert(rc == 0);
#endif
ocf_task_init();
/* Start the OS */
os_start();
/* os start should never return. If it does, this should be an error */
assert(0);
}