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