[ENROLLEE] Tizen enrollee sample application build using scons command
[platform/upstream/iotivity.git] / service / easy-setup / enrollee / src / resourcehandler.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics 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 "resourcehandler.h"
22 #include "ocpayload.h"
23
24
25 /**
26  * @var ES_RH_TAG
27  * @brief Logging tag for module name.
28  */
29 #define ES_RH_TAG "ES_RH"
30
31 //-----------------------------------------------------------------------------
32 // Private variables
33 //-----------------------------------------------------------------------------
34
35 /**
36  * @var gProvResource
37  * @brief Structure for holding the Provisioning status and target information required to connect to the target network
38  */
39 static ProvResource gProvResource;
40
41 /**
42  * @var gNetResource
43  * @brief Structure forr holding the Provisioning status of network information
44  */
45 static NetResource gNetResource;
46
47 //-----------------------------------------------------------------------------
48 // Private internal function prototypes
49 //-----------------------------------------------------------------------------
50 OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
51                                                 OCEntityHandlerRequest *ehRequest, void *callback);
52 const char *getResult(OCStackResult result);
53 OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest,
54                                                OCRepPayload** payload);
55 OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest *ehRequest,
56                                                OCRepPayload** payload);
57 OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest,
58                                                 OCRepPayload** payload);
59 OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest);
60
61 static int g_flag = 0;
62
63 ResourceEventCallback gNetworkInfoProvEventCb = NULL;
64
65 void RegisterResourceEventCallBack(ResourceEventCallback cb)
66 {
67     gNetworkInfoProvEventCb = cb;
68 }
69
70 void UnRegisterResourceEventCallBack()
71 {
72     if (gNetworkInfoProvEventCb)
73     {
74         gNetworkInfoProvEventCb = NULL;
75     }
76 }
77
78 void GetTargetNetworkInfoFromProvResource(char *name, char *pass)
79 {
80     if (name != NULL && pass != NULL)
81     {
82         sprintf(name, "%s", gProvResource.tnn);
83         sprintf(pass, "%s", gProvResource.cd);
84     }
85 }
86
87 OCStackResult CreateProvisioningResource()
88 {
89     gProvResource.ps = 1; // need to do provisioning
90     gProvResource.tnt = CT_ADAPTER_IP;
91     sprintf(gProvResource.tnn, "Unknown");
92     sprintf(gProvResource.cd, "Unknown");
93
94     OCStackResult res = OCCreateResource(&gProvResource.handle, "oic.r.prov", OC_RSRVD_INTERFACE_DEFAULT,
95                                                 OC_RSRVD_ES_URI_PROV, OCEntityHandlerCb, NULL,
96                                                 OC_DISCOVERABLE | OC_OBSERVABLE);
97     OC_LOG_V(INFO, ES_RH_TAG, "Created Prov resource with result: %s", getResult(res));
98     return res;
99 }
100
101 OCStackResult DeleteProvisioningResource()
102 {
103     OCStackResult res = OCDeleteResource(gProvResource.handle);
104     if (res != OC_STACK_OK)
105     {
106         OC_LOG_V(INFO, ES_RH_TAG, "Deleting Prov resource error with result: %s", getResult(res));
107     }
108
109     return res;
110 }
111
112 #ifdef ESWIFI
113 OCStackResult CreateNetworkResource()
114 {
115     NetworkInfo netInfo;
116
117     if (getCurrentNetworkInfo(CT_ADAPTER_IP, &netInfo) != ES_OK)
118     {
119         return OC_STACK_ERROR;
120     }
121
122     if (netInfo.type != CT_ADAPTER_IP)
123     {
124         return OC_STACK_ERROR;
125     }
126
127     gNetResource.cnt = (int) netInfo.type;
128     gNetResource.ant[0] = (int) CT_ADAPTER_IP;
129
130     if(netInfo.ipaddr != NULL)
131     {
132         sprintf(gNetResource.ipaddr, "%d.%d.%d.%d", netInfo.ipaddr[0], netInfo.ipaddr[1],
133                                             netInfo.ipaddr[2], netInfo.ipaddr[3]);
134     }
135     sprintf(gNetResource.cnn, "%s", netInfo.ssid);
136
137     OC_LOG_V(INFO, ES_RH_TAG, "SSID: %s", gNetResource.cnn);
138     OC_LOG_V(INFO, ES_RH_TAG, "IP Address: %s", gNetResource.ipaddr);
139
140     OCStackResult res = OCCreateResource(&gNetResource.handle, "oic.r.net", OC_RSRVD_INTERFACE_DEFAULT,
141             OC_RSRVD_ES_URI_NET, OCEntityHandlerCb,NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
142
143     OC_LOG_V(INFO, ES_RH_TAG, "Created Net resource with result: %s", getResult(res));
144
145     return res;
146 }
147
148 OCStackResult DeleteNetworkResource()
149 {
150     OCStackResult res = OCDeleteResource(gNetResource.handle);
151     if (res != OC_STACK_OK)
152     {
153         OC_LOG_V(INFO, ES_RH_TAG, "Deleting Network resource error with result: %s",
154                                                                             getResult(res));
155     }
156
157     return res;
158 }
159 #endif
160
161 OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest,
162                                                 OCRepPayload **payload)
163 {
164     OCEntityHandlerResult ehResult = OC_EH_ERROR;
165     if (!ehRequest)
166     {
167         OC_LOG(ERROR, ES_RH_TAG, "Request is Null");
168         return ehResult;
169     }
170     if (ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
171     {
172         OC_LOG(ERROR, ES_RH_TAG, "Incoming payload not a representation");
173         return ehResult;
174     }
175
176     OCRepPayload *getResp = constructResponse(ehRequest);
177     if (!getResp)
178     {
179         OC_LOG(ERROR, ES_RH_TAG, "constructResponse failed");
180         return OC_EH_ERROR;
181     }
182
183     *payload = getResp;
184     ehResult = OC_EH_OK;
185
186     return ehResult;
187 }
188
189 OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest *ehRequest,
190                                                OCRepPayload** payload)
191 {
192     OC_LOG(INFO, ES_RH_TAG, "ProcessPutRequest enter");
193     OCEntityHandlerResult ehResult = OC_EH_ERROR;
194     if (ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
195     {
196         OC_LOG(ERROR, ES_RH_TAG, "Incoming payload not a representation");
197         return ehResult;
198     }
199
200     OCRepPayload* input = (OCRepPayload*) (ehRequest->payload);
201     if (!input)
202     {
203         OC_LOG(ERROR, ES_RH_TAG, "Failed to parse");
204         return ehResult;
205     }
206
207     //TODO : ES_PS_PROVISIONING_COMPLETED state indicates that already provisioning is completed.
208     // A new request for provisioning means overriding existing network provisioning information.
209     // Metadata to indicate that it is override is needed. The metadata can be a new attribute
210     // should be added to the /oic/prov resource indicating to override the existing network
211     // information.
212     if (gProvResource.ps == ES_PS_PROVISIONING_COMPLETED)
213     {
214         OC_LOG(DEBUG, ES_RH_TAG, "Provisioning already completed. "
215                 "This a request to override the existing the network provisioning information");
216     }
217
218     // PUT request is appropriate for provisioning information to the enrollee.
219     // When an enrollee receives the put request, the entire resource information should
220     // be overwritten.
221     sprintf(gProvResource.tnn, "%s", "");
222     sprintf(gProvResource.tnn, "%s", "");
223
224     char* tnn;
225     if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_TNN, &tnn))
226     {
227         sprintf(gProvResource.tnn, "%s", tnn);
228         OC_LOG(INFO, ES_RH_TAG, "got ssid");
229     }
230
231         OC_LOG_V(INFO, ES_RH_TAG, "gProvResource.tnn %s", gProvResource.tnn);
232     char* cd;
233     if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_CD, &cd))
234     {
235         sprintf(gProvResource.cd, "%s", cd);
236         OC_LOG(INFO, ES_RH_TAG, "got password");
237     }
238         OC_LOG_V(INFO, ES_RH_TAG, "gProvResource.cd %s", gProvResource.cd);
239     gProvResource.ps = 2;
240     OC_LOG_V(INFO, ES_RH_TAG, "gProvResource.ps %d", gProvResource.ps);
241     g_flag = 1;
242
243     OCRepPayload *getResp = constructResponse(ehRequest);
244     if (!getResp)
245     {
246         OC_LOG(ERROR, ES_RH_TAG, "constructResponse failed");
247         return OC_EH_ERROR;
248     }
249
250     *payload = getResp;
251     ehResult = OC_EH_OK;
252
253     return ehResult;
254 }
255
256 OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest,
257                                                 OCRepPayload** payload)
258 {
259     OCEntityHandlerResult ehResult = OC_EH_ERROR;
260     if (!ehRequest)
261     {
262         OC_LOG(ERROR, ES_RH_TAG, "Request is Null");
263         return ehResult;
264     }
265     if (ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
266     {
267         OC_LOG(ERROR, ES_RH_TAG, "Incoming payload not a representation");
268         return ehResult;
269     }
270
271     OCRepPayload* input = (OCRepPayload*) (ehRequest->payload);
272     if (!input)
273     {
274         OC_LOG(ERROR, ES_RH_TAG, "Failed to parse");
275         return ehResult;
276     }
277     char* tr;
278     if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_TR, &tr))
279     {
280         // Triggering
281         ehResult = OC_EH_OK;
282     }
283     g_flag = 1;
284
285     return ehResult;
286 }
287
288 OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
289 {
290     OCRepPayload* payload = OCRepPayloadCreate();
291     if (!payload)
292     {
293         OC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
294         return NULL;
295     }
296
297     if (ehRequest->resource == gProvResource.handle)
298     {
299         OC_LOG(INFO, ES_RH_TAG, "constructResponse prov res");
300         OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_PROV);
301         OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_PS, gProvResource.ps);
302         OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_TNT, gProvResource.tnt);
303         OCRepPayloadSetPropString(payload, OC_RSRVD_ES_TNN, gProvResource.tnn);
304         OCRepPayloadSetPropString(payload, OC_RSRVD_ES_CD, gProvResource.cd);
305     }
306     else if (ehRequest->requestHandle == gNetResource.handle)
307     {
308
309         OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_NET);
310         OCRepPayloadSetPropInt(payload, "ant", gNetResource.ant[0]);
311     }
312     return payload;
313 }
314
315 /**
316  * This is the entity handler for the registered resource.
317  * This is invoked by OCStack whenever it recevies a request for this resource.
318  */
319 OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
320         OCEntityHandlerRequest* entityHandlerRequest, void *callback)
321 {
322     (void) callback;
323     OCEntityHandlerResult ehRet = OC_EH_OK;
324     OCEntityHandlerResponse response = { 0 };
325     OCRepPayload* payload = NULL;
326     if (entityHandlerRequest && (flag & OC_REQUEST_FLAG))
327     {
328         if (OC_REST_GET == entityHandlerRequest->method)
329         {
330             OC_LOG(INFO, ES_RH_TAG, "Received GET request");
331             ehRet = ProcessGetRequest(entityHandlerRequest, &payload);
332         }
333         else if (OC_REST_PUT == entityHandlerRequest->method)
334         {
335             OC_LOG(INFO, ES_RH_TAG, "Received PUT request");
336
337             if (gProvResource.handle != NULL && entityHandlerRequest->resource == gProvResource.handle)
338             {
339                 ehRet = ProcessPutRequest(entityHandlerRequest, &payload);
340             }
341             else
342             {
343                 OC_LOG(ERROR, ES_RH_TAG, "Cannot process put");
344                 ehRet = OC_EH_ERROR;
345             }
346         }
347         else if (OC_REST_POST == entityHandlerRequest->method)
348         {
349             // TODO: As of now, POST request will be not received.
350             OC_LOG(INFO, ES_RH_TAG, "Received OC_REST_POST from client");
351             //ehRet = ProcessPostRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
352         }
353
354         if (ehRet == OC_EH_OK)
355         {
356             // Format the response.  Note this requires some info about the request
357             response.requestHandle = entityHandlerRequest->requestHandle;
358             response.resourceHandle = entityHandlerRequest->resource;
359             response.ehResult = ehRet;
360             //response uses OCPaylod while all get,put methodes use OCRepPayload
361             response.payload = (OCPayload*) (payload);
362             response.numSendVendorSpecificHeaderOptions = 0;
363             memset(response.sendVendorSpecificHeaderOptions, 0,
364                     sizeof response.sendVendorSpecificHeaderOptions);
365             memset(response.resourceUri, 0, sizeof response.resourceUri);
366             // Indicate that response is NOT in a persistent buffer
367             response.persistentBufferFlag = 0;
368
369             // Send the response
370             if (OCDoResponse(&response) != OC_STACK_OK)
371             {
372                 OC_LOG(ERROR, ES_RH_TAG, "Error sending response");
373                 ehRet = OC_EH_ERROR;
374             }
375         }
376     }
377
378     if (g_flag == 1)
379     {
380         gNetworkInfoProvEventCb(ES_RECVTRIGGEROFPROVRES);
381         g_flag = 0;
382     }
383
384     return ehRet;
385 }
386
387 const char *getResult(OCStackResult result)
388 {
389     switch (result)
390     {
391         case OC_STACK_OK:
392             return "OC_STACK_OK";
393         case OC_STACK_INVALID_URI:
394             return "OC_STACK_INVALID_URI";
395         case OC_STACK_INVALID_QUERY:
396             return "OC_STACK_INVALID_QUERY";
397         case OC_STACK_INVALID_IP:
398             return "OC_STACK_INVALID_IP";
399         case OC_STACK_INVALID_PORT:
400             return "OC_STACK_INVALID_PORT";
401         case OC_STACK_INVALID_CALLBACK:
402             return "OC_STACK_INVALID_CALLBACK";
403         case OC_STACK_INVALID_METHOD:
404             return "OC_STACK_INVALID_METHOD";
405         case OC_STACK_NO_MEMORY:
406             return "OC_STACK_NO_MEMORY";
407         case OC_STACK_COMM_ERROR:
408             return "OC_STACK_COMM_ERROR";
409         case OC_STACK_INVALID_PARAM:
410             return "OC_STACK_INVALID_PARAM";
411         case OC_STACK_NOTIMPL:
412             return "OC_STACK_NOTIMPL";
413         case OC_STACK_NO_RESOURCE:
414             return "OC_STACK_NO_RESOURCE";
415         case OC_STACK_RESOURCE_ERROR:
416             return "OC_STACK_RESOURCE_ERROR";
417         case OC_STACK_SLOW_RESOURCE:
418             return "OC_STACK_SLOW_RESOURCE";
419         case OC_STACK_NO_OBSERVERS:
420             return "OC_STACK_NO_OBSERVERS";
421         case OC_STACK_ERROR:
422             return "OC_STACK_ERROR";
423         default:
424             return "UNKNOWN";
425     }
426 }
427