4 #include <condition_variable>
11 #include "ocpayload.h"
12 #include "rd_client.h"
15 #include <OCPlatform.h>
17 #define maxSequenceNumber 0xFFFFFF
22 string g_host = "coap+tcp://";
23 condition_variable g_callbackLock;
28 /// Access this property from a TB client
30 std::string m_lightUri;
31 OCResourceHandle m_resourceHandle;
32 OCRepresentation m_lightRep;
36 m_power(""), m_lightUri("/a/light")
38 // Initialize representation
39 m_lightRep.setUri(m_lightUri);
40 m_lightRep.setValue("power", m_power);
43 /// This function internally calls registerResource API.
46 std::string resourceURI = m_lightUri; //URI of the resource
47 std::string resourceTypeName = "core.light"; //resource type name. In this case, it is light
48 std::string resourceInterface = DEFAULT_INTERFACE; // resource interface.
50 EntityHandler cb = std::bind(&LightResource::entityHandler, this, std::placeholders::_1);
52 // This will internally create and register the resource.
53 OCStackResult result = OCPlatform::registerResource(m_resourceHandle, resourceURI,
54 resourceTypeName, resourceInterface, cb, OC_DISCOVERABLE | OC_OBSERVABLE);
56 if (OC_STACK_OK != result)
58 cout << "Resource creation was unsuccessful\n";
62 OCRepresentation post(OCRepresentation &rep)
64 m_power = rep.getValueToString("power");
68 // gets the updated representation.
69 // Updates the representation with latest internal state before
71 OCRepresentation get()
73 m_lightRep.setValue("power", m_power);
79 // This is just a sample implementation of entity handler.
80 // Entity handler can be implemented in several ways by the manufacturer
81 OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request)
83 cout << "\tIn Server CPP entity handler:\n";
84 OCEntityHandlerResult ehResult = OC_EH_ERROR;
87 // Get the request type and request flag
88 std::string requestType = request->getRequestType();
89 int requestFlag = request->getRequestHandlerFlag();
91 if (requestFlag & RequestHandlerFlag::RequestFlag)
93 cout << "\t\trequestFlag : Request\n";
94 auto pResponse = std::make_shared< OC::OCResourceResponse >();
95 pResponse->setRequestHandle(request->getRequestHandle());
96 pResponse->setResourceHandle(request->getResourceHandle());
98 // If the request type is GET
99 if (requestType == "GET")
101 cout << "\t\t\trequestType : GET\n";
102 pResponse->setErrorCode(200);
103 pResponse->setResponseResult(OC_EH_OK);
104 pResponse->setResourceRepresentation(get());
105 if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
110 else if (requestType == "POST")
112 cout << "\t\t\trequestType : POST\n";
114 OCRepresentation rep = request->getResourceRepresentation();
116 // Do related operations related to POST request
117 OCRepresentation rep_post = post(rep);
118 pResponse->setResourceRepresentation(rep_post);
119 pResponse->setErrorCode(200);
121 if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
128 std::cout << "Unhandled request type" << std::endl;
134 std::cout << "Request invalid" << std::endl;
141 void printRepresentation(OCRepresentation rep)
143 for (auto itr = rep.begin(); itr != rep.end(); ++itr)
145 cout << "\t" << itr->attrname() << ":\t" << itr->getValueToString() << endl;
146 if (itr->type() == AttributeType::Vector)
148 switch (itr->base_type())
150 case AttributeType::OCRepresentation:
151 for (auto itr2 : (*itr).getValue< vector< OCRepresentation > >())
153 printRepresentation(itr2);
157 case AttributeType::Integer:
158 for (auto itr2 : (*itr).getValue< vector< int > >())
160 cout << "\t\t" << itr2 << endl;
164 case AttributeType::String:
165 for (auto itr2 : (*itr).getValue< vector< string > >())
167 cout << "\t\t" << itr2 << endl;
172 cout << "Unhandled base type " << itr->base_type() << endl;
176 else if (itr->type() == AttributeType::OCRepresentation)
178 printRepresentation((*itr).getValue< OCRepresentation >());
183 void getResource(const HeaderOptions &, const OCRepresentation &rep, const int ecode)
185 cout << "Resource get: " << ecode << endl;
187 printRepresentation(rep);
190 void foundMyDevice(shared_ptr< OC::OCResource > resource)
192 cout << "Device found: " << resource->uri() << endl;
193 cout << "DI: " << resource->sid() << endl;
195 g_callbackLock.notify_all();
198 void foundDevice(shared_ptr< OC::OCResource > resource)
200 vector < string > rt = resource->getResourceTypes();
202 cout << "Device found: " << resource->uri() << endl;
203 cout << "DI: " << resource->sid() << endl;
205 QueryParamsMap query;
206 resource->get(query, &getResource);
209 void onObserveGroup(const HeaderOptions /*headerOptions*/, const OCRepresentation &rep,
210 const int &eCode, const int /*&sequenceNumber*/)
212 cout << "onObserveGroup response received code: " << eCode << endl;
214 if (eCode == OC_STACK_OK)
216 printRepresentation(rep);
218 vector < string > dilist = rep.getValue < vector< string > > ("dilist");
220 for (auto itr = dilist.begin(); itr != dilist.end(); ++itr)
222 cout << (*itr) << " discovered" << endl;
223 if ((*itr) != OCGetServerInstanceIDString())
225 cout << "New device joined" << endl;
226 string query = "/oic/res?di=";
228 OCStackResult result = OC_STACK_ERROR;
230 cout << "find my resource : " << *itr << endl;
231 result = OCPlatform::findResource(g_host, query,
232 static_cast< OCConnectivityType >(CT_ADAPTER_TCP | CT_IP_USE_V4),
234 cout << " result: " << result << endl;
239 g_callbackLock.notify_all();
242 string g_invitedGroup;
243 void onInvite(const HeaderOptions /*headerOptions*/, const OCRepresentation &rep, const int &eCode,
244 const int &sequenceNumber)
246 cout << "onInvite response received code: " << eCode << endl;
248 if (eCode == OC_STACK_OK)
250 printRepresentation(rep);
252 if (sequenceNumber != OC_OBSERVE_REGISTER)
254 vector < OCRepresentation > invited = rep.getValue < vector< OCRepresentation >
257 g_invitedGroup = invited[0].getValueToString("gid");
261 g_callbackLock.notify_all();
265 void onCreateGroup(const HeaderOptions &, const OCRepresentation &rep, const int ecode)
267 cout << "onCreateGroup response received code: " << ecode << endl;
271 printRepresentation(rep);
272 g_gid = rep.getValueToString("gid");
275 g_callbackLock.notify_all();
278 void onPublish(const OCRepresentation &, const int &eCode)
280 cout << "Publish resource response received, code: " << eCode << endl;
281 g_callbackLock.notify_all();
284 void onPost(const HeaderOptions & /*headerOptions*/, const OCRepresentation &rep, const int eCode)
286 if (eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CHANGED)
288 cout << "\tRequest was successful: " << eCode << endl;
290 printRepresentation(rep);
294 cout << "\tResponse error: " << eCode << endl;
297 g_callbackLock.notify_all();
301 string g_accesstoken;
303 void handleLoginoutCB(const HeaderOptions &, const OCRepresentation &rep, const int ecode)
305 cout << "Auth response received code: " << ecode << endl;
307 if (rep.getPayload() != NULL)
309 printRepresentation(rep);
314 g_accesstoken = rep.getValueToString("accesstoken");
316 g_uid = rep.getValueToString("uid");
319 g_callbackLock.notify_all();
324 static FILE *client_open(const char * /*path*/, const char *mode)
326 string option = "./";
329 return fopen(option.c_str(), mode);
332 int main(int argc, char **argv)
337 << "Put \"[host-ipaddress:port] [authprovider] [authcode] [\'owner\'|\'member\']\" for sign-up and sign-in"
339 cout << "Put \"[host-ipaddress:port] [uid] [accessToken] 1\" for sign-in" << endl;
345 OCPersistentStorage ps
346 { client_open, fread, fwrite, fclose, unlink };
349 { ServiceType::InProc, ModeType::Both, "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
350 0, // Uses randomly available port
351 QualityOfService::LowQos, &ps };
353 OCPlatform::Configure(cfg);
355 OCStackResult result = OC_STACK_ERROR;
359 OCAccountManager::Ptr accountMgr = OCPlatform::constructAccountManagerObject(g_host,
363 unique_lock < mutex > lock(blocker);
367 accountMgr->signIn(argv[2], argv[3], &handleLoginoutCB);
368 g_callbackLock.wait(lock);
372 accountMgr->signUp(argv[2], argv[3], &handleLoginoutCB);
373 g_callbackLock.wait(lock);
374 accountMgr->signIn(g_uid, g_accesstoken, &handleLoginoutCB);
375 g_callbackLock.wait(lock);
380 LightResource lightResource;
381 lightResource.createResource();
383 ResourceHandles resourceHandles;
384 resourceHandles.push_back(lightResource.m_resourceHandle);
386 OCPlatform::publishResourceToRD(g_host, OCConnectivityType::CT_ADAPTER_TCP, resourceHandles,
388 g_callbackLock.wait(lock);
389 /* TODO: need to modify the below according to the OCAccountManager API changed.
390 if (g_option == "owner")
392 cout << "Creating group" << endl;
393 accountMgr->createGroup(AclGroupType::PUBLIC, &onCreateGroup);
394 g_callbackLock.wait(lock);
395 cout << "Adding device " << OCGetServerInstanceIDString() << " to group " << g_gid << endl;
396 accountMgr->addDeviceToGroup(g_gid,
397 { OCGetServerInstanceIDString() }, &onPost);
398 g_callbackLock.wait(lock);
400 accountMgr->observeGroup(g_gid, &onObserveGroup);
401 g_callbackLock.wait(lock);
402 cout << "Put userUUID to send invitation" << endl;
404 cout << "Group id : " << g_gid << " send invitation to " << cmd << endl;
405 accountMgr->sendInvitation(g_gid, cmd, &onPost);
406 g_callbackLock.wait(lock);
410 else if (g_option == "member")
412 cout << "Observing invitation" << endl;
413 accountMgr->observeInvitation(&onInvite);
414 g_callbackLock.wait(lock);
415 cout << "Waiting invitation" << endl;
416 g_callbackLock.wait(lock);
417 cout << "Joining group " << g_invitedGroup << endl;
418 accountMgr->joinGroup(g_invitedGroup, &onPost);
419 g_callbackLock.wait(lock);
421 cout << "find my resource " << cmd << endl;
422 result = OCPlatform::findResource(g_host, "/oic/res",
423 static_cast< OCConnectivityType >(CT_ADAPTER_TCP | CT_IP_USE_V4), &foundMyDevice);
424 g_callbackLock.wait(lock);
426 accountMgr->observeGroup(g_invitedGroup, &onObserveGroup);
427 g_callbackLock.wait(lock);