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