iotivity 0.9.0
[platform/upstream/iotivity.git] / resource / examples / ocicuc / monoprocess.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Corporation All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include <map>
22 #include <thread>
23 #include <atomic>
24 #include <string>
25 #include <memory>
26 #include <utility>
27 #include <ostream>
28 #include <sstream>
29 #include <iostream>
30
31 #include "OCApi.h"
32 #include "OCResource.h"
33 #include "OCPlatform.h"
34
35 #include "exec.hpp"
36 #include "utility.hpp"
37
38 #include "demo_client.hpp"
39 #include "light_resource.hpp"
40
41 namespace Intel { namespace OCDemo {
42
43 auto make_description()
44     -> boost::program_options::options_description
45 {
46  using std::string;
47
48  namespace po = boost::program_options;
49
50  po::options_description desc("Monoprocess Client/Server options");
51
52  desc.add_options()
53     ("nres",        po::value<unsigned long>()->default_value(1),  "number of resources to use for testing")
54     ("host_ip",     po::value<string>()->default_value("0.0.0.0"), "IP of host")
55     ("host_port",   po::value<uint16_t>()->default_value(0),       "port of host")
56     ("interface",   po::value<string>()->default_value("eth0"),    "network interface name")
57     ("uri",         po::value<vector<string>>(),                   "resource URI")
58     ;
59
60  return desc;
61 }
62
63 /* Unfortunately, our target compiler may not support std::async correctly, so this
64 leverages RAII to save us from having to use the double-join-check pattern: */
65 struct simple_join_guard
66 {
67  thread t;
68
69  template <class FnT>
70  simple_join_guard(FnT&& fn)
71   : t(fn)
72  {}
73
74  ~simple_join_guard()
75  {
76     if(t.joinable())
77      t.join();
78  }
79 };
80
81 struct client_t
82 {
83  const boost::program_options::variables_map        m_vm;
84
85  atomic<bool>&                                      quit_flag;
86
87  vector<string>                                     resource_URIs;
88
89  public:
90  client_t(const boost::program_options::variables_map vm,
91           atomic<bool>& quit_flag_)
92   : m_vm(vm),
93     quit_flag(quit_flag_)
94  {}
95
96  public:
97  void init()
98  {
99     if(0 != m_vm.count("uri"))
100      {
101         const vector<string>& input_URIs = m_vm["uri"].as< vector<string> >();
102         copy(begin(input_URIs), end(input_URIs), back_inserter(resource_URIs));
103      }
104     else
105      resource_URIs.push_back("coap://224.0.1.187/oc/core");
106   }
107
108  void operator()()
109  {
110     std::cout << "Requesting " << resource_URIs.size() << " URIs:\n";
111
112     for(const auto& resource_URI : resource_URIs)
113      cout << resource_URI << '\n';
114
115     Intel::OCDemo::client::resource_handler resources(resource_URIs);
116
117     // Register callbacks and wait for resources:
118     resources.find_resources();
119
120     // Allow the client to receive events from the server:
121     while(!quit_flag)
122      {
123         std::this_thread::sleep_for(std::chrono::seconds(1));
124      }
125  }
126 };
127
128 struct server_t
129 {
130  const boost::program_options::variables_map        m_vm;
131
132  atomic<bool>&                                      quit_flag;
133
134  unsigned long                                      m_nresources;
135
136  vector<string>                                     resource_URIs;
137
138  vector<shared_ptr<Intel::OCDemo::LightResource>>   lights;
139
140  public:
141  server_t(const boost::program_options::variables_map& vm,
142           atomic<bool>& quit_flag_)
143   : m_vm(vm),
144     quit_flag(quit_flag_)
145  {
146     m_nresources = vm["nres"].as<unsigned long>();
147  }
148
149  public:
150  void init();
151
152  void operator()()
153  {
154     while(!quit_flag)
155      {
156         std::this_thread::sleep_for(std::chrono::seconds(5));
157      }
158  }
159 };
160
161 void server_t::init()
162 {
163  lights.resize(m_nresources);
164
165  for(unsigned int resource_number = 1; m_nresources >= resource_number; resource_number++)
166   {
167     cout << "Registering resource " << resource_number << ": " << std::flush;
168
169     auto lr = make_shared<Intel::OCDemo::LightResource>();
170
171     lr->createResource(resource_number);
172     lr->addType("core.brightlight");
173     lr->addInterface("oc.mi.ll");
174
175     lights.push_back(lr);
176
177     cout << "Ok." << std::endl;
178   }
179 }
180
181 int exec(const boost::program_options::variables_map& vm)
182 {
183  using namespace std;
184
185  std::cout << "Starting platform: " << std::flush;
186
187  OC::OCPlatform::Configure(OC::PlatformConfig {
188                           OC::ServiceType::InProc,
189                           OC::ModeType::Both,                   // run in client/server mode
190                           vm["host_ip"].as<string>(),           // host
191                           vm["host_port"].as<uint16_t>(),       // port
192                           OC::QualityOfService::LowQos
193                         });
194  std::cout << "Ok." << std::endl;
195
196  std::atomic<bool> quit_flag;
197
198  server_t server(vm, quit_flag);
199  client_t client(vm, quit_flag);
200
201 std::cout << "JFW: TODO: don't need to separate these any more\n";
202  server.init();
203  client.init();
204
205  // Run the server and client:
206  {
207     simple_join_guard server_guard(server);
208     simple_join_guard client_guard(client);
209
210     // Note that at present nothing makes this true:
211     while(!quit_flag)
212      {
213         // Perform app tasks
214         std::this_thread::sleep_for(std::chrono::seconds(2));
215      }
216   }
217
218  return 1;
219 }
220
221 }} // namespace Intel::OCDemo
222