blob: 2a80f4c366c49e168fb6c156e9ea12c11081953e [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 <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;
}