| /* |
| * 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 <string.h> |
| #include <os/mynewt.h> |
| #include <log/log.h> |
| |
| #include "oic/oc_log.h" |
| #include "oic/port/oc_connectivity.h" |
| #include "oic/port/mynewt/adaptor.h" |
| |
| #define OC_CONN_EV_CB MYNEWT_VAL(OC_CONN_EV_CB_CNT) |
| |
| static SLIST_HEAD(, oc_conn_cb) oc_conn_cbs = |
| SLIST_HEAD_INITIALIZER(oc_conn_cbs); |
| static STAILQ_HEAD(, oc_conn_ev) oc_conn_evs = |
| STAILQ_HEAD_INITIALIZER(oc_conn_evs); |
| |
| static void oc_conn_ev_deliver(struct os_event *); |
| static struct os_event oc_conn_cb_ev = { |
| .ev_cb = oc_conn_ev_deliver, |
| }; |
| static struct os_mempool oc_conn_ev_pool; |
| static uint8_t oc_conn_ev_area[OS_MEMPOOL_BYTES(OC_CONN_EV_CB, |
| sizeof(struct oc_conn_ev))]; |
| |
| void |
| oc_conn_cb_register(struct oc_conn_cb *cb) |
| { |
| SLIST_INSERT_HEAD(&oc_conn_cbs, cb, occ_next); |
| } |
| |
| void |
| oc_conn_init(void) |
| { |
| os_mempool_init(&oc_conn_ev_pool, OC_CONN_EV_CB, sizeof(struct oc_conn_ev), |
| oc_conn_ev_area, "oc_conn_ev"); |
| } |
| |
| struct oc_conn_ev * |
| oc_conn_ev_alloc(void) |
| { |
| return os_memblock_get(&oc_conn_ev_pool); |
| } |
| |
| static void |
| oc_conn_ev_queue(struct oc_conn_ev *oce) |
| { |
| int sr; |
| |
| OS_ENTER_CRITICAL(sr); |
| STAILQ_INSERT_TAIL(&oc_conn_evs, oce, oce_next); |
| OS_EXIT_CRITICAL(sr); |
| os_eventq_put(oc_evq_get(), &oc_conn_cb_ev); |
| } |
| |
| void |
| oc_conn_created(struct oc_conn_ev *oce) |
| { |
| OC_LOG_DEBUG("oc_conn_created: "); |
| OC_LOG_ENDPOINT(LOG_LEVEL_DEBUG, &oce->oce_oe); |
| oce->oce_type = OC_ENDPOINT_CONN_EV_OPEN; |
| oc_conn_ev_queue(oce); |
| } |
| |
| void |
| oc_conn_removed(struct oc_conn_ev *oce) |
| { |
| OC_LOG_DEBUG("oc_conn_removed: "); |
| OC_LOG_ENDPOINT(LOG_LEVEL_DEBUG, &oce->oce_oe); |
| oce->oce_type = OC_ENDPOINT_CONN_EV_CLOSE; |
| oc_conn_ev_queue(oce); |
| } |
| |
| static void |
| oc_conn_ev_deliver(struct os_event *ev) |
| { |
| struct oc_conn_ev *oce; |
| struct oc_conn_cb *occ; |
| int sr; |
| |
| OS_ENTER_CRITICAL(sr); |
| while ((oce = STAILQ_FIRST(&oc_conn_evs))) { |
| STAILQ_REMOVE_HEAD(&oc_conn_evs, oce_next); |
| OS_EXIT_CRITICAL(sr); |
| SLIST_FOREACH(occ, &oc_conn_cbs, occ_next) { |
| occ->occ_func(&oce->oce_oe, oce->oce_type); |
| } |
| os_memblock_put(&oc_conn_ev_pool, oce); |
| OS_ENTER_CRITICAL(sr); |
| } |
| OS_EXIT_CRITICAL(sr); |
| } |