Fix build warnings
[platform/upstream/iotivity.git] / resource / csdk / stack / src / occlientcb.c
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH 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
22 #include "occlientcb.h"
23 #include "occoap.h"
24 #include "utlist.h"
25 #include "logger.h"
26 #include "ocmalloc.h"
27 #include <string.h>
28
29 #ifdef CA_INT
30 #include "cacommon.h"
31 #include "cainterface.h"
32 #endif
33
34 /// Module Name
35 #define TAG PCF("occlientcb")
36
37 #define VERIFY_NON_NULL(arg) { if (!arg) {OC_LOG(FATAL, TAG, #arg " is NULL"); goto exit;} }
38
39 struct ClientCB *cbList = NULL;
40 OCMulticastNode * mcPresenceNodes = NULL;
41
42 OCStackResult
43 #ifdef CA_INT
44 AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
45              CAToken_t * token, OCDoHandle *handle, OCMethod method,
46              unsigned char * requestUri, unsigned char * resourceTypeName)
47 #else // CA_INT
48 AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
49              OCCoAPToken * token, OCDoHandle *handle, OCMethod method,
50              unsigned char * requestUri, unsigned char * resourceTypeName)
51 #endif // CA_INT
52 {
53
54     ClientCB *cbNode = NULL;
55
56     #ifdef WITH_PRESENCE
57     if(method == OC_REST_PRESENCE)
58     {   // Retrieve the presence callback structure for this specific requestUri.
59         cbNode = GetClientCB(NULL, NULL, requestUri);
60     }
61     #endif // WITH_PRESENCE
62
63     if(!cbNode)// If it does not already exist, create new node.
64     {
65         cbNode = (ClientCB*) OCMalloc(sizeof(ClientCB));
66         if(!cbNode)
67         {
68             *clientCB = NULL;
69             goto exit;
70         }
71         else
72         {
73             cbNode->callBack = cbData->cb;
74             cbNode->context = cbData->context;
75             cbNode->deleteCallback = cbData->cd;
76 #ifdef CA_INT
77             //Note: token memory is allocated in the caller OCDoResource
78             //but freed in DeleteClientCB
79             cbNode->token = *token;
80 #else // CA_INT
81             memcpy(&(cbNode->token), token, sizeof(OCCoAPToken));
82 #endif // CA_INT
83             cbNode->handle = *handle;
84             cbNode->method = method;
85             cbNode->sequenceNumber = 0;
86             #ifdef WITH_PRESENCE
87             cbNode->presence = NULL;
88             cbNode->filterResourceType = NULL;
89             #endif // WITH_PRESENCE
90             cbNode->requestUri = requestUri;
91             LL_APPEND(cbList, cbNode);
92             *clientCB = cbNode;
93         }
94     }
95     else
96     {
97         // Ensure that the handle the SDK hands back up to the application layer for the
98         // OCDoResource call matches the found ClientCB Node.
99         *clientCB = cbNode;
100         OCFree(requestUri);
101         OCFree(*handle);
102         *handle = cbNode->handle;
103     }
104
105     #ifdef WITH_PRESENCE
106     if(method == OC_REST_PRESENCE && resourceTypeName)
107     {   // Amend the found or created node by adding a new resourceType to it.
108         return InsertResourceTypeFilter(cbNode, (const char *)resourceTypeName);
109     }
110     #endif
111
112     return OC_STACK_OK;
113
114     exit:
115         return OC_STACK_NO_MEMORY;
116 }
117
118 void DeleteClientCB(ClientCB * cbNode) {
119     if(cbNode) {
120         LL_DELETE(cbList, cbNode);
121         OC_LOG(INFO, TAG, PCF("deleting tokens"));
122 #ifdef CA_INT
123         CADestroyToken (cbNode->token);
124         OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)cbNode->token, CA_MAX_TOKEN_LEN);
125 #else
126         OC_LOG_BUFFER(INFO, TAG, cbNode->token.token, cbNode->token.tokenLength);
127 #endif // CA_INT
128         OCFree(cbNode->handle);
129         OCFree(cbNode->requestUri);
130         if(cbNode->deleteCallback)
131         {
132             cbNode->deleteCallback(cbNode->context);
133         }
134
135         #ifdef WITH_PRESENCE
136         if(cbNode->presence) {
137             OCFree(cbNode->presence->timeOut);
138             OCFree(cbNode->presence);
139         }
140         if(cbNode->method == OC_REST_PRESENCE)
141         {
142             OCResourceType * pointer = cbNode->filterResourceType;
143             OCResourceType * next = NULL;
144             while(pointer)
145             {
146                 next = pointer->next;
147                 OCFree(pointer->resourcetypename);
148                 OCFree(pointer);
149                 pointer = next;
150             }
151         }
152         #endif // WITH_PRESENCE
153         OCFree(cbNode);
154         cbNode = NULL;
155     }
156 }
157
158 #ifdef CA_INT
159 ClientCB* GetClientCB(const CAToken_t * token, OCDoHandle handle, const unsigned char * requestUri)
160 #else // CA_INT
161 ClientCB* GetClientCB(OCCoAPToken * token, OCDoHandle handle, const unsigned char * requestUri)
162 #endif // CA_INT
163 {
164     ClientCB* out = NULL;
165     if(token) {
166         LL_FOREACH(cbList, out) {
167             OC_LOG(INFO, TAG, PCF("comparing tokens"));
168 #ifdef CA_INT
169             OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)*token, CA_MAX_TOKEN_LEN);
170             OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->token, CA_MAX_TOKEN_LEN);
171             if(memcmp(out->token, *token, CA_MAX_TOKEN_LEN) == 0)
172             {
173                 return out;
174             }
175 #else // CA_INT
176             OC_LOG_BUFFER(INFO, TAG, token->token, token->tokenLength);
177             OC_LOG_BUFFER(INFO, TAG, out->token.token, out->token.tokenLength);
178             if((out->token.tokenLength == token->tokenLength) &&
179                 (memcmp(out->token.token, token->token, token->tokenLength) == 0) ) {
180                 return out;
181             }
182 #endif // CA_INT
183         }
184     }
185     else if(handle) {
186         LL_FOREACH(cbList, out) {
187             if(out->handle == handle) {
188                 return out;
189             }
190         }
191     }
192     else if(requestUri) {
193         LL_FOREACH(cbList, out) {
194             if(out->requestUri && strcmp((char *)out->requestUri, (char *)requestUri) == 0) {
195                 return out;
196             }
197         }
198     }
199     OC_LOG(INFO, TAG, PCF("Callback Not found !!"));
200     return NULL;
201 }
202
203 #ifdef WITH_PRESENCE
204 OCStackResult InsertResourceTypeFilter(ClientCB * cbNode, const char * resourceTypeName)
205 {
206     OCResourceType * newResourceType = NULL;
207     if(cbNode && resourceTypeName)
208     {
209         // Form a new resourceType member.
210         newResourceType = (OCResourceType *) OCMalloc(sizeof(OCResourceType));
211         if(!newResourceType)
212         {
213             return OC_STACK_NO_MEMORY;
214         }
215
216         newResourceType->next = NULL;
217         newResourceType->resourcetypename = (char *) resourceTypeName;
218
219         LL_APPEND(cbNode->filterResourceType, newResourceType);
220         return OC_STACK_OK;
221     }
222     return OC_STACK_ERROR;
223 }
224 #endif // WITH_PRESENCE
225
226 void DeleteClientCBList() {
227     ClientCB* out;
228     ClientCB* tmp;
229     LL_FOREACH_SAFE(cbList, out, tmp) {
230         DeleteClientCB(out);
231     }
232     cbList = NULL;
233 }
234
235 void FindAndDeleteClientCB(ClientCB * cbNode) {
236     ClientCB* tmp;
237     if(cbNode)
238     {
239         LL_FOREACH(cbList, tmp)
240         {
241             if (cbNode == tmp)
242             {
243                 DeleteClientCB(tmp);
244                 break;
245             }
246         }
247     }
248 }
249
250 OCStackResult AddMCPresenceNode(OCMulticastNode** outnode, unsigned char* uri, uint32_t nonce)
251 {
252     OCMulticastNode *node;
253
254     node = (OCMulticastNode*) OCMalloc(sizeof(OCMulticastNode));
255
256     if (node) {
257         node->nonce = nonce;
258         node->uri = uri;
259         LL_APPEND(mcPresenceNodes, node);
260         *outnode = node;
261         return OC_STACK_OK;
262     }
263     *outnode = NULL;
264     return OC_STACK_NO_MEMORY;
265 }
266
267 OCMulticastNode* GetMCPresenceNode(const unsigned char * uri) {
268     OCMulticastNode* out = NULL;
269
270     if(uri) {
271         LL_FOREACH(mcPresenceNodes, out) {
272             if(out->uri && strcmp((char *)out->uri, (char *)uri) == 0) {
273                 return out;
274             }
275         }
276     }
277     OC_LOG(INFO, TAG, PCF("MulticastNode Not found !!"));
278     return NULL;
279 }