replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / unittest / sampleserver2.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 //NOTE :  This sample server is generated based on ocserverbasicops.cpp
22 ///////////////////////////////////////////////////////////////////////
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <signal.h>
28 #include <pthread.h>
29 #include "ocstack.h"
30 #include "logger.h"
31 #include "ocpayload.h"
32 #include "oic_string.h"
33
34 #define TAG "UNITTEST_SERVER_2"
35
36 int gQuitFlag = 0;
37
38 /* Structure to represent a LED resource */
39 typedef struct LEDRESOURCE{
40     OCResourceHandle handle;
41     bool state;
42     int power;
43 } LEDResource;
44
45 static LEDResource LED;
46 // This variable determines instance number of the LED resource.
47 // Used by POST method to create a new instance of LED resource.
48 static int gCurrLedInstance = 0;
49 #define SAMPLE_MAX_NUM_POST_INSTANCE  2
50 static LEDResource gLedInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
51
52 char *gResourceUri= (char *)"/a/led";
53
54 //Secure Virtual Resource database for Iotivity Server
55 //It contains Server's Identity and the PSK credentials
56 //of other devices which the server trusts
57 static char CRED_FILE[] = "oic_svr_db_server2.dat";
58
59 static uint8_t DEFAULT_SVR_DB[] = {
60     0xBF, 0x63, 0x61, 0x63, 0x6C, 0x59, 0x03, 0x4F, 0xA4, 0x66, 0x61, 0x63, 0x6C, 0x69, 0x73, 0x74,
61     0xA1, 0x64, 0x61, 0x63, 0x65, 0x73, 0x84, 0xA3, 0x6B, 0x73, 0x75, 0x62, 0x6A, 0x65, 0x63, 0x74,
62     0x75, 0x75, 0x69, 0x64, 0x61, 0x2A, 0x69, 0x72, 0x65, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x73,
63     0x83, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x68, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x72, 0x65, 0x73,
64     0x62, 0x72, 0x74, 0x81, 0x6A, 0x6F, 0x69, 0x63, 0x2E, 0x77, 0x6B, 0x2E, 0x72, 0x65, 0x73, 0x62,
65     0x69, 0x66, 0x81, 0x69, 0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x6C, 0x6C, 0x63, 0x72, 0x65,
66     0x6C, 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x66, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x64, 0x62,
67     0x72, 0x74, 0x81, 0x68, 0x6F, 0x69, 0x63, 0x2E, 0x77, 0x6B, 0x2E, 0x64, 0x62, 0x69, 0x66, 0x82,
68     0x6F, 0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65,
69     0x68, 0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x72, 0x63, 0x72, 0x65, 0x6C, 0x60, 0xA4, 0x64,
70     0x68, 0x72, 0x65, 0x66, 0x66, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x70, 0x62, 0x72, 0x74, 0x81, 0x68,
71     0x6F, 0x69, 0x63, 0x2E, 0x77, 0x6B, 0x2E, 0x70, 0x62, 0x69, 0x66, 0x82, 0x6F, 0x6F, 0x69, 0x63,
72     0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0x68, 0x6F, 0x69, 0x63,
73     0x2E, 0x69, 0x66, 0x2E, 0x72, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x6A, 0x70, 0x65, 0x72, 0x6D, 0x69,
74     0x73, 0x73, 0x69, 0x6F, 0x6E, 0x02, 0xA3, 0x6B, 0x73, 0x75, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x75,
75     0x75, 0x69, 0x64, 0x61, 0x2A, 0x69, 0x72, 0x65, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x73, 0x84,
76     0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x6D, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F,
77     0x64, 0x6F, 0x78, 0x6D, 0x62, 0x72, 0x74, 0x81, 0x6A, 0x6F, 0x69, 0x63, 0x2E, 0x72, 0x2E, 0x64,
78     0x6F, 0x78, 0x6D, 0x62, 0x69, 0x66, 0x81, 0x6F, 0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x62,
79     0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0x63, 0x72, 0x65, 0x6C, 0x60, 0xA4, 0x64, 0x68, 0x72,
80     0x65, 0x66, 0x6E, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, 0x70, 0x73, 0x74, 0x61,
81     0x74, 0x62, 0x72, 0x74, 0x81, 0x6B, 0x6F, 0x69, 0x63, 0x2E, 0x72, 0x2E, 0x70, 0x73, 0x74, 0x61,
82     0x74, 0x62, 0x69, 0x66, 0x81, 0x6F, 0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73,
83     0x65, 0x6C, 0x69, 0x6E, 0x65, 0x63, 0x72, 0x65, 0x6C, 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66,
84     0x6C, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, 0x61, 0x63, 0x6C, 0x62, 0x72, 0x74,
85     0x81, 0x69, 0x6F, 0x69, 0x63, 0x2E, 0x72, 0x2E, 0x61, 0x63, 0x6C, 0x62, 0x69, 0x66, 0x81, 0x6F,
86     0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0x63,
87     0x72, 0x65, 0x6C, 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x6D, 0x2F, 0x6F, 0x69, 0x63, 0x2F,
88     0x73, 0x65, 0x63, 0x2F, 0x63, 0x72, 0x65, 0x64, 0x62, 0x72, 0x74, 0x81, 0x6A, 0x6F, 0x69, 0x63,
89     0x2E, 0x72, 0x2E, 0x63, 0x72, 0x65, 0x64, 0x62, 0x69, 0x66, 0x81, 0x6F, 0x6F, 0x69, 0x63, 0x2E,
90     0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0x63, 0x72, 0x65, 0x6C, 0x60,
91     0x6A, 0x70, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x06, 0xA3, 0x6B, 0x73, 0x75,
92     0x62, 0x6A, 0x65, 0x63, 0x74, 0x75, 0x75, 0x69, 0x64, 0x61, 0x2A, 0x69, 0x72, 0x65, 0x73, 0x6F,
93     0x75, 0x72, 0x63, 0x65, 0x73, 0x82, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x6E, 0x2F, 0x6F, 0x69,
94     0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, 0x70, 0x63, 0x6F, 0x6E, 0x66, 0x62, 0x72, 0x74, 0x81, 0x6B,
95     0x6F, 0x69, 0x63, 0x2E, 0x72, 0x2E, 0x70, 0x63, 0x6F, 0x6E, 0x66, 0x62, 0x69, 0x66, 0x81, 0x6F,
96     0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0x63,
97     0x72, 0x65, 0x6C, 0x60, 0xA4, 0x64, 0x68, 0x72, 0x65, 0x66, 0x71, 0x2F, 0x6F, 0x69, 0x63, 0x2F,
98     0x73, 0x65, 0x63, 0x2F, 0x64, 0x70, 0x61, 0x69, 0x72, 0x69, 0x6E, 0x67, 0x62, 0x72, 0x74, 0x81,
99     0x6E, 0x6F, 0x69, 0x63, 0x2E, 0x72, 0x2E, 0x64, 0x70, 0x61, 0x69, 0x72, 0x69, 0x6E, 0x67, 0x62,
100     0x69, 0x66, 0x81, 0x6F, 0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C,
101     0x69, 0x6E, 0x65, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x6A, 0x70, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73,
102     0x69, 0x6F, 0x6E, 0x06, 0xA3, 0x6B, 0x73, 0x75, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x75, 0x75, 0x69,
103     0x64, 0x61, 0x2A, 0x69, 0x72, 0x65, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x73, 0x81, 0xA4, 0x64,
104     0x68, 0x72, 0x65, 0x66, 0x6C, 0x2F, 0x6F, 0x69, 0x63, 0x2F, 0x73, 0x65, 0x63, 0x2F, 0x76, 0x65,
105     0x72, 0x62, 0x72, 0x74, 0x81, 0x69, 0x6F, 0x69, 0x63, 0x2E, 0x72, 0x2E, 0x76, 0x65, 0x72, 0x62,
106     0x69, 0x66, 0x81, 0x6F, 0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C,
107     0x69, 0x6E, 0x65, 0x63, 0x72, 0x65, 0x6C, 0x60, 0x6A, 0x70, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73,
108     0x69, 0x6F, 0x6E, 0x02, 0x6A, 0x72, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64, 0x78,
109     0x24, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32,
110     0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
111     0x32, 0x32, 0x32, 0x32, 0x32, 0x62, 0x72, 0x74, 0x81, 0x69, 0x6F, 0x69, 0x63, 0x2E, 0x72, 0x2E,
112     0x61, 0x63, 0x6C, 0x62, 0x69, 0x66, 0x81, 0x6F, 0x6F, 0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x62,
113     0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0x65, 0x70, 0x73, 0x74, 0x61, 0x74, 0x58, 0x9D, 0xA9,
114     0x64, 0x69, 0x73, 0x6F, 0x70, 0xF4, 0x62, 0x63, 0x6D, 0x02, 0x62, 0x74, 0x6D, 0x00, 0x62, 0x6F,
115     0x6D, 0x04, 0x62, 0x73, 0x6D, 0x04, 0x6A, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x75, 0x75, 0x69,
116     0x64, 0x78, 0x24, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32,
117     0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x32,
118     0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x6A, 0x72, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75,
119     0x69, 0x64, 0x78, 0x24, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32,
120     0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32,
121     0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x62, 0x72, 0x74, 0x81, 0x6B, 0x6F, 0x69, 0x63,
122     0x2E, 0x72, 0x2E, 0x70, 0x73, 0x74, 0x61, 0x74, 0x62, 0x69, 0x66, 0x81, 0x6F, 0x6F, 0x69, 0x63,
123     0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0x64, 0x64, 0x6F, 0x78,
124     0x6D, 0x58, 0xEB, 0xAA, 0x64, 0x6F, 0x78, 0x6D, 0x73, 0x82, 0x00, 0x19, 0xFF, 0x00, 0x66, 0x6F,
125     0x78, 0x6D, 0x73, 0x65, 0x6C, 0x00, 0x63, 0x73, 0x63, 0x74, 0x01, 0x65, 0x6F, 0x77, 0x6E, 0x65,
126     0x64, 0xF4, 0x6A, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x32,
127     0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32,
128     0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
129     0x32, 0x32, 0x32, 0x6C, 0x64, 0x65, 0x76, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64,
130     0x78, 0x24, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D,
131     0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
132     0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6A, 0x72, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69,
133     0x64, 0x78, 0x24, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32,
134     0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x32,
135     0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x72, 0x78, 0x2E, 0x6F, 0x72, 0x67, 0x2E, 0x69, 0x6F,
136     0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2E, 0x64, 0x70, 0x63, 0xF5, 0x62, 0x72, 0x74, 0x81, 0x6A,
137     0x6F, 0x69, 0x63, 0x2E, 0x72, 0x2E, 0x64, 0x6F, 0x78, 0x6D, 0x62, 0x69, 0x66, 0x81, 0x6F, 0x6F,
138     0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0xFF
139 };
140
141 /* Function that creates a new LED resource by calling the
142  * OCCreateResource() method.
143  */
144 int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower);
145
146 /* This method converts the payload to JSON format */
147 OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest);
148
149 /* Following methods process the PUT, GET, POST
150  * requests
151  */
152 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
153                                          OCRepPayload **payload);
154 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
155                                          OCRepPayload **payload);
156 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
157                                         OCEntityHandlerResponse *response,
158                                         OCRepPayload **payload);
159
160 /* Entity Handler callback functions */
161 OCEntityHandlerResult
162 OCEntityHandlerCb (OCEntityHandlerFlag flag,
163         OCEntityHandlerRequest *entityHandlerRequest,
164         void* callbackParam);
165
166 const char *getResult(OCStackResult result) {
167     switch (result) {
168     case OC_STACK_OK:
169         return "OC_STACK_OK";
170     case OC_STACK_RESOURCE_CREATED:
171         return "OC_STACK_RESOURCE_CREATED";
172     case OC_STACK_RESOURCE_DELETED:
173         return "OC_STACK_RESOURCE_DELETED";
174     case OC_STACK_INVALID_URI:
175         return "OC_STACK_INVALID_URI";
176     case OC_STACK_INVALID_QUERY:
177         return "OC_STACK_INVALID_QUERY";
178     case OC_STACK_INVALID_IP:
179         return "OC_STACK_INVALID_IP";
180     case OC_STACK_INVALID_PORT:
181         return "OC_STACK_INVALID_PORT";
182     case OC_STACK_INVALID_CALLBACK:
183         return "OC_STACK_INVALID_CALLBACK";
184     case OC_STACK_INVALID_METHOD:
185         return "OC_STACK_INVALID_METHOD";
186     case OC_STACK_NO_MEMORY:
187         return "OC_STACK_NO_MEMORY";
188     case OC_STACK_COMM_ERROR:
189         return "OC_STACK_COMM_ERROR";
190     case OC_STACK_INVALID_PARAM:
191         return "OC_STACK_INVALID_PARAM";
192     case OC_STACK_NOTIMPL:
193         return "OC_STACK_NOTIMPL";
194     case OC_STACK_NO_RESOURCE:
195         return "OC_STACK_NO_RESOURCE";
196     case OC_STACK_RESOURCE_ERROR:
197         return "OC_STACK_RESOURCE_ERROR";
198     case OC_STACK_SLOW_RESOURCE:
199         return "OC_STACK_SLOW_RESOURCE";
200     case OC_STACK_NO_OBSERVERS:
201         return "OC_STACK_NO_OBSERVERS";
202     #ifdef WITH_PRESENCE
203     case OC_STACK_PRESENCE_STOPPED:
204         return "OC_STACK_PRESENCE_STOPPED";
205     #endif
206     case OC_STACK_ERROR:
207         return "OC_STACK_ERROR";
208     default:
209         return "UNKNOWN";
210     }
211 }
212
213 OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
214 {
215     OCRepPayload* payload = OCRepPayloadCreate();
216     if(!payload)
217     {
218         OIC_LOG(ERROR, TAG, "Failed to allocate Payload");
219         return NULL;
220     }
221
222     OCRepPayloadSetUri(payload, uri);
223     OCRepPayloadSetPropBool(payload, "state", state);
224     OCRepPayloadSetPropInt(payload, "power", power);
225
226     return payload;
227 }
228
229 //This function takes the request as an input and returns the response
230 OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest)
231 {
232     if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
233     {
234         OIC_LOG(ERROR, TAG, "Incoming payload not a representation");
235         return NULL;
236     }
237
238     OCRepPayload* input = (OCRepPayload*)(ehRequest->payload);
239
240     LEDResource *currLEDResource = &LED;
241
242     if (ehRequest->resource == gLedInstance[0].handle)
243     {
244         currLEDResource = &gLedInstance[0];
245         gResourceUri = (char *) "/a/led/0";
246     }
247     else if (ehRequest->resource == gLedInstance[1].handle)
248     {
249         currLEDResource = &gLedInstance[1];
250         gResourceUri = (char *) "/a/led/1";
251     }
252
253     if(OC_REST_PUT == ehRequest->method)
254     {
255         // Get pointer to query
256         int64_t pow;
257         if(OCRepPayloadGetPropInt(input, "power", &pow))
258         {
259             currLEDResource->power =pow;
260         }
261
262         bool state;
263         if(OCRepPayloadGetPropBool(input, "state", &state))
264         {
265             currLEDResource->state = state;
266         }
267     }
268
269     return getPayload(gResourceUri, currLEDResource->power, currLEDResource->state);
270 }
271
272 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
273         OCRepPayload **payload)
274 {
275     OCEntityHandlerResult ehResult;
276
277     OCRepPayload *getResp = constructResponse(ehRequest);
278
279     if(getResp)
280     {
281         *payload = getResp;
282         ehResult = OC_EH_OK;
283     }
284     else
285     {
286         ehResult = OC_EH_ERROR;
287     }
288
289     return ehResult;
290 }
291
292 OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
293         OCRepPayload **payload)
294 {
295     OCEntityHandlerResult ehResult;
296
297     OCRepPayload *putResp = constructResponse(ehRequest);
298
299     if(putResp)
300     {
301         *payload = putResp;
302         ehResult = OC_EH_OK;
303     }
304     else
305     {
306         ehResult = OC_EH_ERROR;
307     }
308
309     return ehResult;
310 }
311
312 OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
313         OCEntityHandlerResponse *response, OCRepPayload **payload)
314 {
315     OCRepPayload *respPLPost_led = NULL;
316     OCEntityHandlerResult ehResult = OC_EH_OK;
317
318     /*
319      * The entity handler determines how to process a POST request.
320      * Per the REST paradigm, POST can also be used to update representation of existing
321      * resource or create a new resource.
322      * In the sample below, if the POST is for /a/led then a new instance of the LED
323      * resource is created with default representation (if representation is included in
324      * POST payload it can be used as initial values) as long as the instance is
325      * lesser than max new instance count. Once max instance count is reached, POST on
326      * /a/led updated the representation of /a/led (just like PUT)
327      */
328
329     if (ehRequest->resource == LED.handle)
330     {
331         if (gCurrLedInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
332         {
333             // Create new LED instance
334             char newLedUri[15] = "/a/led/";
335             int newLedUriLength = strlen(newLedUri);
336             snprintf (newLedUri + newLedUriLength, sizeof(newLedUri)-newLedUriLength, "%d", gCurrLedInstance);
337
338             respPLPost_led = OCRepPayloadCreate();
339             OCRepPayloadSetUri(respPLPost_led, gResourceUri);
340             OCRepPayloadSetPropString(respPLPost_led, "createduri", newLedUri);
341
342             if (0 == createLEDResource (newLedUri, &gLedInstance[gCurrLedInstance], false, 0))
343             {
344                 OIC_LOG (INFO, TAG, "Created new LED instance");
345                 gLedInstance[gCurrLedInstance].state = 0;
346                 gLedInstance[gCurrLedInstance].power = 0;
347                 gCurrLedInstance++;
348                 strncpy ((char *)response->resourceUri, newLedUri, sizeof(response->resourceUri));
349                 ehResult = OC_EH_RESOURCE_CREATED;
350             }
351         }
352         else
353         {
354             respPLPost_led = constructResponse(ehRequest);
355         }
356     }
357     else
358     {
359         for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
360         {
361             if (ehRequest->resource == gLedInstance[i].handle)
362             {
363                 if (i == 0)
364                 {
365                     respPLPost_led = constructResponse(ehRequest);
366                     break;
367                 }
368                 else if (i == 1)
369                 {
370                     respPLPost_led = constructResponse(ehRequest);
371                 }
372             }
373         }
374     }
375
376     if (respPLPost_led != NULL)
377     {
378         *payload = respPLPost_led;
379         ehResult = OC_EH_OK;
380     }
381     else
382     {
383         OIC_LOG_V (INFO, TAG, "Payload was NULL");
384         ehResult = OC_EH_ERROR;
385     }
386
387     return ehResult;
388 }
389
390 OCEntityHandlerResult
391 OCEntityHandlerCb (OCEntityHandlerFlag flag,
392         OCEntityHandlerRequest *entityHandlerRequest,
393         void* callbackParam)
394 {
395     OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
396     (void)callbackParam;
397     OCEntityHandlerResult ehResult = OC_EH_ERROR;
398
399     OCEntityHandlerResponse response;
400     memset(&response, 0, sizeof(response));
401
402     // Validate pointer
403     if (!entityHandlerRequest)
404     {
405         OIC_LOG (ERROR, TAG, "Invalid request pointer");
406         return OC_EH_ERROR;
407     }
408
409     OCRepPayload* payload = NULL;
410
411     if (flag & OC_REQUEST_FLAG)
412     {
413         OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
414         if (entityHandlerRequest)
415         {
416             if (OC_REST_GET == entityHandlerRequest->method)
417             {
418                 OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
419                 ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
420             }
421             else if (OC_REST_PUT == entityHandlerRequest->method)
422             {
423                 OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
424                 ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
425             }
426             else if (OC_REST_POST == entityHandlerRequest->method)
427             {
428                 OIC_LOG (INFO, TAG, "Received OC_REST_POST from client");
429                 ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
430             }
431             else
432             {
433                 OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
434                         entityHandlerRequest->method);
435                 ehResult = OC_EH_ERROR;
436             }
437
438             if (ehResult == OC_EH_OK && ehResult != OC_EH_FORBIDDEN)
439             {
440                 // Format the response.  Note this requires some info about the request
441                 response.requestHandle = entityHandlerRequest->requestHandle;
442                 response.resourceHandle = entityHandlerRequest->resource;
443                 response.ehResult = ehResult;
444                 response.payload = (OCPayload*)(payload);
445                 response.numSendVendorSpecificHeaderOptions = 0;
446                 memset(response.sendVendorSpecificHeaderOptions, 0,
447                        sizeof(response.sendVendorSpecificHeaderOptions));
448                 memset(response.resourceUri, 0, sizeof(response.resourceUri));
449                 // Indicate that response is NOT in a persistent buffer
450                 response.persistentBufferFlag = 0;
451
452                 // Send the response
453                 if (OCDoResponse(&response) != OC_STACK_OK)
454                 {
455                     OIC_LOG(ERROR, TAG, "Error sending response");
456                     ehResult = OC_EH_ERROR;
457                 }
458             }
459         }
460     }
461
462     OCPayloadDestroy(response.payload);
463     return ehResult;
464 }
465
466 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
467 void handleSigInt(int signum)
468 {
469     if (signum == SIGINT)
470     {
471         gQuitFlag = 1;
472     }
473 }
474
475 static void GetCurrentWorkingDirectory(char* buf, size_t bufsize)
476 {
477     char cwd[1024] = {0};
478     const char* unittest_path = "resource/csdk/security/provisioning/unittest";
479     if(getcwd(cwd, sizeof(cwd)) != NULL)
480     {
481         if(strstr(cwd, unittest_path) == NULL)
482         {
483 #if defined __linux__
484 #if __x86_64__
485         snprintf(buf, bufsize, "%s/out/linux/x86_64/release/%s/", cwd, unittest_path);
486         snprintf(buf, bufsize, "%s/out/linux/x86_64/release/%s/", cwd, unittest_path);
487 #else
488         snprintf(buf, bufsize, "%s/out/linux/x86/release/%s/", cwd, unittest_path);
489         snprintf(buf, bufsize, "%s/out/linux/x86/release/%s/", cwd, unittest_path);
490 #endif //__x86_64__
491 #endif //defined __linux__
492         }
493         else
494         {
495             snprintf(buf, bufsize, "%s/", cwd);
496         }
497     }
498 }
499
500 FILE* server_fopen(const char *path, const char *mode)
501 {
502     (void)path;
503     char cwd[1024] = {0};
504     char cred_path[1024] = {0};
505     GetCurrentWorkingDirectory(cwd, sizeof(cwd));
506     snprintf(cred_path, sizeof(cred_path), "%s%s", cwd, CRED_FILE);
507     return fopen(cred_path, mode);
508 }
509
510 int main()
511 {
512     struct timespec timeout;
513
514     //Delete previous SVR DB, if exist.
515     char cwd[1024] = {0};
516     char cred_path[1024] = {0};
517     char del_cmd[1024] = {0};
518     FILE* fp = NULL;
519     GetCurrentWorkingDirectory(cwd, sizeof(cwd));
520     snprintf(del_cmd, sizeof(del_cmd), "rm -rf %s%s", cwd, CRED_FILE);
521     system(del_cmd);
522
523     //Generate default SVR DB.
524     snprintf(cred_path, sizeof(cred_path), "%s%s", cwd, CRED_FILE);
525     fp = fopen(cred_path, "w");
526     if(NULL != fp)
527     {
528         size_t numberItems = fwrite(DEFAULT_SVR_DB, 1, sizeof(DEFAULT_SVR_DB), fp);
529         if(sizeof(DEFAULT_SVR_DB) != numberItems)
530         {
531             OIC_LOG_V(ERROR, TAG, "Failed to initialize SVR DB (%s)", cred_path);
532             fclose(fp);
533             return -1;
534         }
535         fclose(fp);
536     }
537
538     OIC_LOG(DEBUG, TAG, "OCServer is starting...");
539
540     // Initialize Persistent Storage for SVR database
541     OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
542
543     OCRegisterPersistentStorageHandler(&ps);
544
545     if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
546     {
547         OIC_LOG(ERROR, TAG, "OCStack init error");
548         return 0;
549     }
550
551     /*
552      * Declare and create the example resource: LED
553      */
554     createLEDResource(gResourceUri, &LED, false, 0);
555
556     timeout.tv_sec  = 0;
557     timeout.tv_nsec = 100000000L;
558
559     // Break from loop with Ctrl-C
560     OIC_LOG(INFO, TAG, "Entering ocserver main loop...");
561     signal(SIGINT, handleSigInt);
562     while (!gQuitFlag)
563     {
564         if (OCProcess() != OC_STACK_OK)
565         {
566             OIC_LOG(ERROR, TAG, "OCStack process error");
567             return 0;
568         }
569         nanosleep(&timeout, NULL);
570     }
571
572     OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");
573
574     if (OCStop() != OC_STACK_OK)
575     {
576         OIC_LOG(ERROR, TAG, "OCStack process error");
577     }
578
579     return 0;
580 }
581
582 int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower)
583 {
584     if (!uri)
585     {
586         OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
587         return -1;
588     }
589
590     ledResource->state = resourceState;
591     ledResource->power= resourcePower;
592     OCStackResult res = OCCreateResource(&(ledResource->handle),
593             "core.led",
594             OC_RSRVD_INTERFACE_DEFAULT,
595             uri,
596             OCEntityHandlerCb,
597             NULL,
598             OC_DISCOVERABLE|OC_OBSERVABLE | OC_SECURE);
599     OIC_LOG_V(INFO, TAG, "Created LED resource with result: %s", getResult(res));
600
601     return 0;
602 }