13605c802486424c2fe22b3474c941f224cd56419Zach Johnson/******************************************************************************
23605c802486424c2fe22b3474c941f224cd56419Zach Johnson *
33605c802486424c2fe22b3474c941f224cd56419Zach Johnson *  Copyright (C) 2014 Google, Inc.
43605c802486424c2fe22b3474c941f224cd56419Zach Johnson *
53605c802486424c2fe22b3474c941f224cd56419Zach Johnson *  Licensed under the Apache License, Version 2.0 (the "License");
63605c802486424c2fe22b3474c941f224cd56419Zach Johnson *  you may not use this file except in compliance with the License.
73605c802486424c2fe22b3474c941f224cd56419Zach Johnson *  You may obtain a copy of the License at:
83605c802486424c2fe22b3474c941f224cd56419Zach Johnson *
93605c802486424c2fe22b3474c941f224cd56419Zach Johnson *  http://www.apache.org/licenses/LICENSE-2.0
103605c802486424c2fe22b3474c941f224cd56419Zach Johnson *
113605c802486424c2fe22b3474c941f224cd56419Zach Johnson *  Unless required by applicable law or agreed to in writing, software
123605c802486424c2fe22b3474c941f224cd56419Zach Johnson *  distributed under the License is distributed on an "AS IS" BASIS,
133605c802486424c2fe22b3474c941f224cd56419Zach Johnson *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143605c802486424c2fe22b3474c941f224cd56419Zach Johnson *  See the License for the specific language governing permissions and
153605c802486424c2fe22b3474c941f224cd56419Zach Johnson *  limitations under the License.
163605c802486424c2fe22b3474c941f224cd56419Zach Johnson *
173605c802486424c2fe22b3474c941f224cd56419Zach Johnson ******************************************************************************/
183605c802486424c2fe22b3474c941f224cd56419Zach Johnson
193605c802486424c2fe22b3474c941f224cd56419Zach Johnson#define LOG_TAG "bt_osi_data_dispatcher"
203605c802486424c2fe22b3474c941f224cd56419Zach Johnson
2149a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen#include "osi/include/data_dispatcher.h"
2249a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen
23f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He#include <base/logging.h>
242b56e01a2d0ccf9eff58b24fb66c18280f95a680Jakub Pawlowski#include <unordered_map>
253605c802486424c2fe22b3474c941f224cd56419Zach Johnson
260f9b91e150e153229235c163861198e23600e636Sharvil Nanavati#include "osi/include/allocator.h"
2744802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati#include "osi/include/log.h"
28b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson#include "osi/include/osi.h"
293605c802486424c2fe22b3474c941f224cd56419Zach Johnson
303605c802486424c2fe22b3474c941f224cd56419Zach Johnson#define DEFAULT_TABLE_BUCKETS 10
313605c802486424c2fe22b3474c941f224cd56419Zach Johnson
32b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watsontypedef std::unordered_map<data_dispatcher_type_t, fixed_queue_t*>
33b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson    DispatchTableMap;
342b56e01a2d0ccf9eff58b24fb66c18280f95a680Jakub Pawlowski
353605c802486424c2fe22b3474c941f224cd56419Zach Johnsonstruct data_dispatcher_t {
36b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson  char* name;
37b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson  DispatchTableMap* dispatch_table;
38b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson  fixed_queue_t* default_queue;  // We don't own this queue
393605c802486424c2fe22b3474c941f224cd56419Zach Johnson};
403605c802486424c2fe22b3474c941f224cd56419Zach Johnson
41b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watsondata_dispatcher_t* data_dispatcher_new(const char* name) {
42f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He  CHECK(name != NULL);
433605c802486424c2fe22b3474c941f224cd56419Zach Johnson
44b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson  data_dispatcher_t* ret =
45b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson      (data_dispatcher_t*)osi_calloc(sizeof(data_dispatcher_t));
463605c802486424c2fe22b3474c941f224cd56419Zach Johnson
472b56e01a2d0ccf9eff58b24fb66c18280f95a680Jakub Pawlowski  ret->dispatch_table = new DispatchTableMap();
483605c802486424c2fe22b3474c941f224cd56419Zach Johnson
49ee2aa45def216a3c4d6a23481fa96f1b02a5de8cZach Johnson  ret->name = osi_strdup(name);
503605c802486424c2fe22b3474c941f224cd56419Zach Johnson  if (!ret->name) {
51db554581079863974af8e1289646f5deea6fc044Marie Janssen    LOG_ERROR(LOG_TAG, "%s unable to duplicate provided name.", __func__);
523605c802486424c2fe22b3474c941f224cd56419Zach Johnson    goto error;
533605c802486424c2fe22b3474c941f224cd56419Zach Johnson  }
543605c802486424c2fe22b3474c941f224cd56419Zach Johnson
553605c802486424c2fe22b3474c941f224cd56419Zach Johnson  return ret;
563605c802486424c2fe22b3474c941f224cd56419Zach Johnson
573605c802486424c2fe22b3474c941f224cd56419Zach Johnsonerror:;
583605c802486424c2fe22b3474c941f224cd56419Zach Johnson  data_dispatcher_free(ret);
593605c802486424c2fe22b3474c941f224cd56419Zach Johnson  return NULL;
603605c802486424c2fe22b3474c941f224cd56419Zach Johnson}
613605c802486424c2fe22b3474c941f224cd56419Zach Johnson
62b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watsonvoid data_dispatcher_free(data_dispatcher_t* dispatcher) {
63b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson  if (!dispatcher) return;
643605c802486424c2fe22b3474c941f224cd56419Zach Johnson
652b56e01a2d0ccf9eff58b24fb66c18280f95a680Jakub Pawlowski  delete dispatcher->dispatch_table;
6620524d393e8b3bea4c573f7980cd843500b0e6a4Pavlin Radoslavov  osi_free(dispatcher->name);
67ee2aa45def216a3c4d6a23481fa96f1b02a5de8cZach Johnson  osi_free(dispatcher);
683605c802486424c2fe22b3474c941f224cd56419Zach Johnson}
693605c802486424c2fe22b3474c941f224cd56419Zach Johnson
70b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watsonvoid data_dispatcher_register(data_dispatcher_t* dispatcher,
71b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson                              data_dispatcher_type_t type,
72b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson                              fixed_queue_t* queue) {
73f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He  CHECK(dispatcher != NULL);
743605c802486424c2fe22b3474c941f224cd56419Zach Johnson
7511f58e22343cb77155ebd9c27382e222fbd9a0ceZach Johnson  if (queue)
762b56e01a2d0ccf9eff58b24fb66c18280f95a680Jakub Pawlowski    (*dispatcher->dispatch_table)[type] = queue;
772b56e01a2d0ccf9eff58b24fb66c18280f95a680Jakub Pawlowski  else
782b56e01a2d0ccf9eff58b24fb66c18280f95a680Jakub Pawlowski    dispatcher->dispatch_table->erase(type);
793605c802486424c2fe22b3474c941f224cd56419Zach Johnson}
803605c802486424c2fe22b3474c941f224cd56419Zach Johnson
81b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watsonvoid data_dispatcher_register_default(data_dispatcher_t* dispatcher,
82b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson                                      fixed_queue_t* queue) {
83f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He  CHECK(dispatcher != NULL);
843605c802486424c2fe22b3474c941f224cd56419Zach Johnson
853605c802486424c2fe22b3474c941f224cd56419Zach Johnson  dispatcher->default_queue = queue;
863605c802486424c2fe22b3474c941f224cd56419Zach Johnson}
873605c802486424c2fe22b3474c941f224cd56419Zach Johnson
88b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watsonbool data_dispatcher_dispatch(data_dispatcher_t* dispatcher,
89b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson                              data_dispatcher_type_t type, void* data) {
90f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He  CHECK(dispatcher != NULL);
91f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He  CHECK(data != NULL);
923605c802486424c2fe22b3474c941f224cd56419Zach Johnson
93b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson  fixed_queue_t* queue;
942b56e01a2d0ccf9eff58b24fb66c18280f95a680Jakub Pawlowski  auto iter = dispatcher->dispatch_table->find(type);
952b56e01a2d0ccf9eff58b24fb66c18280f95a680Jakub Pawlowski  if (iter == dispatcher->dispatch_table->end())
963605c802486424c2fe22b3474c941f224cd56419Zach Johnson    queue = dispatcher->default_queue;
972b56e01a2d0ccf9eff58b24fb66c18280f95a680Jakub Pawlowski  else
982b56e01a2d0ccf9eff58b24fb66c18280f95a680Jakub Pawlowski    queue = iter->second;
993605c802486424c2fe22b3474c941f224cd56419Zach Johnson
1003605c802486424c2fe22b3474c941f224cd56419Zach Johnson  if (queue)
1013605c802486424c2fe22b3474c941f224cd56419Zach Johnson    fixed_queue_enqueue(queue, data);
1023605c802486424c2fe22b3474c941f224cd56419Zach Johnson  else
103b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson    LOG_WARN(LOG_TAG,
104b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson             "%s has no handler for type (%zd) in data dispatcher named: %s",
105b55040cc6448a8847490da807d2b6362aa8cb8d9Myles Watson             __func__, type, dispatcher->name);
1063605c802486424c2fe22b3474c941f224cd56419Zach Johnson
1073605c802486424c2fe22b3474c941f224cd56419Zach Johnson  return queue != NULL;
1083605c802486424c2fe22b3474c941f224cd56419Zach Johnson}
109