| /* |
| * 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/mynewt.h" |
| #include <bsp/bsp.h> |
| #include <log/log.h> |
| #include <oic/oc_api.h> |
| #include <cborattr/cborattr.h> |
| #if (MYNEWT_VAL(OC_TRANSPORT_SERIAL) == 1) |
| #include <console/console.h> |
| #include <console/prompt.h> |
| #include <shell/shell.h> |
| #endif |
| |
| #if (MYNEWT_VAL(OC_TRANSPORT_GATT) == 1) |
| #include "host/ble_hs.h" |
| #include "ocf_sample.h" |
| #endif |
| |
| #if (MYNEWT_VAL(OC_CLIENT) == 1) |
| static void issue_requests(void); |
| #endif |
| |
| #if (MYNEWT_VAL(OC_SERVER) == 1) |
| static bool light_state = false; |
| |
| static void |
| get_light(oc_request_t *request, oc_interface_mask_t interface) |
| { |
| printf("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); |
| printf("Light state %d\n", light_state); |
| } |
| |
| static void |
| put_light(oc_request_t *request, oc_interface_mask_t interface) |
| { |
| bool state; |
| int len; |
| uint16_t data_off; |
| struct os_mbuf *m; |
| struct cbor_attr_t attrs[] = { |
| [0] = { |
| .attribute = "state", |
| .type = CborAttrBooleanType, |
| .addr.boolean = &state, |
| .dflt.boolean = false |
| }, |
| [1] = { |
| } |
| }; |
| |
| printf("PUT_light:\n"); |
| |
| len = coap_get_payload(request->packet, &m, &data_off); |
| if (cbor_read_mbuf_attrs(m, data_off, len, attrs)) { |
| oc_send_response(request, OC_STATUS_BAD_REQUEST); |
| } else { |
| printf("value: %d\n", state); |
| light_state = state; |
| oc_send_response(request, OC_STATUS_CHANGED); |
| } |
| } |
| |
| 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 |
| |
| #if (MYNEWT_VAL(OC_CLIENT) == 1) |
| #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 struct os_callout callout; |
| |
| static void |
| set_device_custom_property(void *data) |
| { |
| oc_set_custom_device_property(purpose, "operate mynewt-light"); |
| } |
| |
| static void |
| stop_observe(struct os_event *ev) |
| { |
| printf("Stopping OBSERVE\n"); |
| oc_stop_observe(light_1, &light_server); |
| } |
| |
| static void |
| put_light(oc_client_response_t *data) |
| { |
| printf("PUT_light:\n"); |
| if (data->code == OC_STATUS_CHANGED) |
| printf("PUT response OK\n"); |
| else |
| printf("PUT response code %d\n", data->code); |
| } |
| |
| static void |
| observe_light(oc_client_response_t *rsp) |
| { |
| bool state; |
| int len; |
| uint16_t data_off; |
| struct os_mbuf *m; |
| struct cbor_attr_t attrs[] = { |
| [0] = { |
| .attribute = "state", |
| .type = CborAttrBooleanType, |
| .addr.boolean = &state, |
| .dflt.boolean = false |
| }, |
| [1] = { |
| } |
| }; |
| |
| len = coap_get_payload(rsp->packet, &m, &data_off); |
| if (!cbor_read_mbuf_attrs(m, data_off, len, attrs)) { |
| printf("OBSERVE_light: %d\n", state); |
| light_state = state; |
| } |
| |
| 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() == true) { |
| printf("Sent PUT request\n"); |
| } else { |
| printf("Could not send PUT\n"); |
| } |
| } else { |
| printf("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); |
| os_callout_reset(&callout, 30 * OS_TICKS_PER_SEC); |
| 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); |
| #if (MYNEWT_VAL(OC_CLIENT) == 1) |
| oc_add_device("/oic/d", "oic.d.light", "MynewtClient", "1.0", "1.0", |
| set_device_custom_property, NULL); |
| #endif |
| |
| #if (MYNEWT_VAL(OC_SERVER) == 1) |
| oc_add_device("/oic/d", "oic.d.light", "MynewtServer", "1.0", "1.0", NULL, |
| NULL); |
| #endif |
| } |
| |
| oc_handler_t ocf_handler = { |
| .init = app_init, |
| #if (MYNEWT_VAL(OC_SERVER) == 1) |
| .register_resources = register_resources, |
| #endif |
| #if (MYNEWT_VAL(OC_CLIENT) == 1) |
| .requests_entry = issue_requests, |
| #endif |
| }; |
| |
| static void |
| ocf_init_tasks(void) |
| { |
| #if (MYNEWT_VAL(OC_CLIENT) == 1) |
| os_callout_init(&callout, os_eventq_dflt_get(), stop_observe, NULL); |
| #endif |
| oc_main_init(&ocf_handler); |
| } |
| |
| int |
| main(int argc, char **argv) |
| { |
| #ifdef ARCH_sim |
| mcu_sim_parse_args(argc, argv); |
| #endif |
| |
| /* Initialize OS */ |
| sysinit(); |
| |
| #if (MYNEWT_VAL(OC_TRANSPORT_GATT) == 1) |
| ocf_ble_init(); |
| #endif |
| |
| ocf_init_tasks(); |
| |
| while (1) { |
| os_eventq_run(os_eventq_dflt_get()); |
| } |
| /* Never returns */ |
| |
| /* os start should never return. If it does, this should be an error */ |
| assert(0); |
| } |