1 //******************************************************************
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
22 #include "occlientcb.h"
25 #include "oic_malloc.h"
33 #include "coap_time.h"
36 #include "cainterface.h"
39 #define TAG PCF("occlientcb")
41 struct ClientCB *cbList = NULL;
42 static OCMulticastNode * mcPresenceNodes = NULL;
45 AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
46 CAToken_t token, uint8_t tokenLength,
47 OCDoHandle *handle, OCMethod method,
48 OCDevAddr *devAddr, char * requestUri,
49 char * resourceTypeName, uint32_t ttl)
51 if(!clientCB || !cbData || !handle || !requestUri || tokenLength > CA_MAX_TOKEN_LEN)
53 return OC_STACK_INVALID_PARAM;
56 ClientCB *cbNode = NULL;
59 if(method == OC_REST_PRESENCE)
60 { // Retrieve the presence callback structure for this specific requestUri.
61 cbNode = GetClientCB(NULL, 0, NULL, requestUri);
63 #endif // WITH_PRESENCE
65 if(!cbNode)// If it does not already exist, create new node.
67 cbNode = (ClientCB*) OICMalloc(sizeof(ClientCB));
75 cbNode->callBack = cbData->cb;
76 cbNode->context = cbData->context;
77 cbNode->deleteCallback = cbData->cd;
78 //Note: token memory is allocated in the caller OCDoResource
79 //but freed in DeleteClientCB
80 cbNode->token = token;
81 cbNode->tokenLength = tokenLength;
82 cbNode->handle = *handle;
83 cbNode->method = method;
84 cbNode->sequenceNumber = 0;
86 cbNode->presence = NULL;
87 cbNode->filterResourceType = NULL;
88 #endif // WITH_PRESENCE
90 if (method == OC_REST_PRESENCE ||
91 method == OC_REST_OBSERVE ||
92 method == OC_REST_OBSERVE_ALL)
100 cbNode->requestUri = requestUri; // I own it now
101 cbNode->devAddr = devAddr; // I own it now
102 LL_APPEND(cbList, cbNode);
108 // Ensure that the handle the SDK hands back up to the application layer for the
109 // OCDoResource call matches the found ClientCB Node.
114 cbData->cd(cbData->context);
121 *handle = cbNode->handle;
125 if(method == OC_REST_PRESENCE && resourceTypeName)
127 // Amend the found or created node by adding a new resourceType to it.
128 return InsertResourceTypeFilter(cbNode,(char *)resourceTypeName);
129 // I own resourceTypName now.
133 OICFree(resourceTypeName);
136 OICFree(resourceTypeName);
142 return OC_STACK_NO_MEMORY;
145 void DeleteClientCB(ClientCB * cbNode)
149 LL_DELETE(cbList, cbNode);
150 OC_LOG(INFO, TAG, PCF("deleting tokens"));
151 OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)cbNode->token, cbNode->tokenLength);
152 CADestroyToken (cbNode->token);
153 OICFree(cbNode->devAddr);
154 OICFree(cbNode->handle);
155 OICFree(cbNode->requestUri);
156 if(cbNode->deleteCallback)
158 cbNode->deleteCallback(cbNode->context);
164 OICFree(cbNode->presence->timeOut);
165 OICFree(cbNode->presence);
167 if(cbNode->method == OC_REST_PRESENCE)
169 OCResourceType * pointer = cbNode->filterResourceType;
170 OCResourceType * next = NULL;
173 next = pointer->next;
174 OICFree(pointer->resourcetypename);
179 #endif // WITH_PRESENCE
186 * This function checks if the node is past its time to live and
187 * deletes it if timed-out. Calling this function with a presence or observe
188 * callback with ttl set to 0 will not delete anything as presence nodes have
189 * their own mechanisms for timeouts. A null argument will cause the function to
192 static void CheckAndDeleteTimedOutCB(ClientCB* cbNode)
198 if (cbNode->TTL == 0)
205 if (cbNode->TTL < now)
207 OC_LOG(INFO, TAG, PCF("Deleting timed-out callback"));
208 DeleteClientCB(cbNode);
212 ClientCB* GetClientCB(const CAToken_t token, uint8_t tokenLength,
213 OCDoHandle handle, const char * requestUri)
216 ClientCB* out = NULL;
218 if(token && *token && tokenLength <= CA_MAX_TOKEN_LEN && tokenLength > 0)
220 LL_FOREACH(cbList, out)
222 OC_LOG(INFO, TAG, PCF("comparing tokens"));
223 OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
224 OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->token, tokenLength);
226 if(memcmp(out->token, token, tokenLength) == 0)
230 CheckAndDeleteTimedOutCB(out);
235 LL_FOREACH(cbList, out)
237 if(out->handle == handle)
241 CheckAndDeleteTimedOutCB(out);
246 LL_FOREACH(cbList, out)
248 if(out->requestUri && strcmp(out->requestUri, requestUri ) == 0)
252 CheckAndDeleteTimedOutCB(out);
255 OC_LOG(INFO, TAG, PCF("Callback Not found !!"));
260 OCStackResult InsertResourceTypeFilter(ClientCB * cbNode, char * resourceTypeName)
262 OCResourceType * newResourceType = NULL;
263 if(cbNode && resourceTypeName)
265 // Form a new resourceType member.
266 newResourceType = (OCResourceType *) OICMalloc(sizeof(OCResourceType));
269 return OC_STACK_NO_MEMORY;
272 newResourceType->next = NULL;
273 newResourceType->resourcetypename = resourceTypeName;
275 LL_APPEND(cbNode->filterResourceType, newResourceType);
278 return OC_STACK_ERROR;
280 #endif // WITH_PRESENCE
282 void DeleteClientCBList()
286 LL_FOREACH_SAFE(cbList, out, tmp)
293 void FindAndDeleteClientCB(ClientCB * cbNode)
298 LL_FOREACH(cbList, tmp)
309 OCStackResult AddMCPresenceNode(OCMulticastNode** outnode, char* uri, uint32_t nonce)
313 return OC_STACK_INVALID_PARAM;
316 OCMulticastNode *node;
318 node = (OCMulticastNode*) OICMalloc(sizeof(OCMulticastNode));
324 LL_APPEND(mcPresenceNodes, node);
329 return OC_STACK_NO_MEMORY;
332 OCMulticastNode* GetMCPresenceNode(const char * uri)
334 OCMulticastNode* out = NULL;
338 LL_FOREACH(mcPresenceNodes, out)
340 if(out->uri && strcmp(out->uri, uri) == 0)
346 OC_LOG(INFO, TAG, PCF("MulticastNode Not found !!"));