Imported Upstream version 1.1.0
[platform/upstream/iotivity.git] / service / resource-directory / src / internal / rd_storage.c
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 #include "rd_storage.h"
21
22 #include <pthread.h>
23 #include <string.h>
24
25 #include "payload_logging.h"
26 #include "oic_malloc.h"
27 #include "octypes.h"
28
29 #include "rdpayload.h"
30
31 #define TAG  PCF("RDStorage")
32
33 pthread_mutex_t storageMutex = PTHREAD_MUTEX_INITIALIZER;
34 // This variable holds the published resources on the RD.
35 static OCRDStorePublishResources *g_rdStorage = NULL;
36
37 static void printStoragedResources(OCRDStorePublishResources *payload)
38 {
39     OIC_LOG(DEBUG, TAG, "Print Storage Resources ... ");
40     for (OCRDStorePublishResources *temp = payload; temp; temp = temp->next)
41     {
42         if (temp->publishedResource)
43         {
44             OCTagsLog(DEBUG, temp->publishedResource->tags);
45             OCLinksLog(DEBUG, temp->publishedResource->setLinks);
46         }
47     }
48 }
49
50 OCStackResult OCRDStorePublishedResources(const OCResourceCollectionPayload *payload, const OCDevAddr *address)
51 {
52     OCResourceCollectionPayload *storeResource = (OCResourceCollectionPayload *)OICCalloc(1, sizeof(OCResourceCollectionPayload));
53     if (!storeResource)
54     {
55         OIC_LOG(ERROR, TAG, "Failed allocating memory for OCRDStorePublishResources.");
56         return OC_STACK_NO_MEMORY;
57     }
58
59     OIC_LOG_V(DEBUG, TAG, "Storing Resources for %s:%u", address->addr, address->port);
60
61     OCTagsPayload *tags = payload->tags;
62     storeResource->tags = OCCopyTagsResources(tags->n.deviceName, tags->di.id, tags->baseURI,
63         tags->bitmap, address->port, tags->ins, tags->rts, tags->drel, tags->ttl);
64     if (!storeResource->tags)
65     {
66         OIC_LOG(ERROR, TAG, "Failed allocating memory for tags.");
67         OCFreeCollectionResource(storeResource);
68         return OC_STACK_NO_MEMORY;
69     }
70
71     for (OCLinksPayload *links = payload->setLinks; links; links = links->next)
72     {
73         if (!storeResource->setLinks)
74         {
75             storeResource->setLinks = OCCopyLinksResources(links->href, links->rt, links->itf,
76                 links->rel, links->obs, links->title, links->uri, links->ins, links->mt);
77             if (!storeResource->setLinks)
78             {
79                 OIC_LOG(ERROR, TAG, "Failed allocating memory for links.");
80                 OCFreeCollectionResource(storeResource);
81                 return OC_STACK_NO_MEMORY;
82             }
83         }
84         else
85         {
86             OCLinksPayload *temp = storeResource->setLinks;
87             while (temp->next)
88             {
89                 temp = temp->next;
90             }
91             temp->next = OCCopyLinksResources(links->href, links->rt, links->itf, links->rel,
92                 links->obs, links->title, links->uri, links->ins, links->mt);
93             if (!temp->next)
94             {
95                 OIC_LOG(ERROR, TAG, "Failed allocating memory for links.");
96                 OCFreeCollectionResource(storeResource);
97                 return OC_STACK_NO_MEMORY;
98             }
99         }
100
101     }
102     storeResource->next = NULL;
103     OCRDStorePublishResources *resources = (OCRDStorePublishResources *)OICCalloc(1, sizeof(OCRDStorePublishResources));
104     if (!resources)
105     {
106         OCFreeCollectionResource(storeResource);
107         return OC_STACK_NO_MEMORY;
108     }
109     resources->publishedResource = storeResource;
110     resources->devAddr = *address;
111
112     pthread_mutex_lock(&storageMutex);
113     if (g_rdStorage)
114     {
115         OCRDStorePublishResources *temp = g_rdStorage;
116         while (temp->next)
117         {
118             temp = temp->next;
119         }
120         temp->next = resources;
121     }
122     else
123     {
124         g_rdStorage = resources;
125     }
126     pthread_mutex_unlock(&storageMutex);
127
128     printStoragedResources(g_rdStorage);
129     return OC_STACK_OK;
130 }
131
132 OCStackResult OCRDCheckPublishedResource(const char *interfaceType, const char *resourceType,
133         OCResourceCollectionPayload **payload, OCDevAddr *devAddr)
134 {
135     // ResourceType and InterfaceType if both are NULL it will return. If either is
136     // not null it will continue execution.
137     if (!resourceType && !interfaceType)
138     {
139         OIC_LOG(DEBUG, TAG, "Missing resource type or interace type.");
140         return OC_STACK_INVALID_PARAM;
141     }
142
143     OIC_LOG(DEBUG, TAG, "Check Resource in RD");
144     if (g_rdStorage && g_rdStorage->publishedResource)
145     {
146         for (OCRDStorePublishResources *pResource = g_rdStorage;
147                 pResource; pResource = pResource->next)
148         {
149             if (pResource->publishedResource->setLinks)
150             {
151                 for (OCLinksPayload *tLinks = pResource->publishedResource->setLinks; tLinks; tLinks = tLinks->next)
152                 {
153                     // If either rt or itf are NULL, it should skip remaining code execution.
154                     if (!tLinks->rt || !tLinks->itf)
155                     {
156                         OIC_LOG(DEBUG, TAG, "Either resource type or interface type is missing.");
157                         continue;
158                     }
159                     if (resourceType)
160                     {
161                         OCStringLL *temp = tLinks->rt;
162                         while(temp)
163                         {
164                             OIC_LOG_V(DEBUG, TAG, "Resource Type: %s %s", resourceType, temp->value);
165                             if (strcmp(resourceType, temp->value) == 0)
166                             {
167                                 OCTagsPayload *tag = pResource->publishedResource->tags;
168                                 OCTagsPayload *tags = OCCopyTagsResources(tag->n.deviceName, tag->di.id, tag->baseURI,
169                                     tag->bitmap, tag->port, tag->ins, tag->rts, tag->drel, tag->ttl);
170                                 if (!tags)
171                                 {
172                                     return OC_STACK_NO_MEMORY;
173                                 }
174                                 OCLinksPayload *links = OCCopyLinksResources(tLinks->href, tLinks->rt, tLinks->itf,
175                                     tLinks->rel, tLinks->obs, tLinks->title, tLinks->uri, tLinks->ins, tLinks->mt);
176                                 if (!links)
177                                 {
178                                     OCFreeTagsResource(tags);
179                                     return OC_STACK_NO_MEMORY;
180                                 }
181                                 *payload = OCCopyCollectionResource(tags, links);
182                                 if (!*payload)
183                                 {
184                                     OCFreeTagsResource(tags);
185                                     OCFreeLinksResource(links);
186                                     return OC_STACK_NO_MEMORY;
187                                 }
188                                 memcpy(devAddr, &pResource->devAddr, sizeof(*devAddr));
189                                 return OC_STACK_OK;
190                             }
191                             temp = temp->next;
192                         }
193                     }
194                     if (interfaceType)
195                     {
196                         OCStringLL *temp = tLinks->itf;
197                         while (temp)
198                         {
199                             OIC_LOG_V(DEBUG, TAG, "Interface Type: %s %s", interfaceType, temp->value);
200                             if (strcmp(interfaceType, temp->value) == 0)
201                             {
202                                 OCTagsPayload *tag = pResource->publishedResource->tags;
203                                 OCTagsPayload *tags = OCCopyTagsResources(tag->n.deviceName, tag->di.id, tag->baseURI,
204                                     tag->bitmap, tag->port, tag->ins, tag->rts, tag->drel, tag->ttl);
205                                 if (!tags)
206                                 {
207                                     return OC_STACK_NO_MEMORY;
208                                 }
209                                 OCLinksPayload *links = OCCopyLinksResources(tLinks->uri, tLinks->rt, tLinks->itf,
210                                     tLinks->rel, tLinks->obs, tLinks->title, tLinks->uri, tLinks->ins, tLinks->mt);
211                                 if (!links)
212                                 {
213                                     OCFreeTagsResource(tags);
214                                     return OC_STACK_NO_MEMORY;
215                                 }
216                                 *payload = OCCopyCollectionResource(tags, links);
217                                 if (!*payload)
218                                 {
219                                     OCFreeTagsResource(tags);
220                                     OCFreeLinksResource(links);
221                                     return OC_STACK_NO_MEMORY;
222                                 }
223                                 devAddr = &pResource->devAddr;
224                                 return OC_STACK_OK;
225                             }
226                             temp = temp->next;
227                         }
228                     }
229                 }
230             }
231         }
232     }
233     return OC_STACK_ERROR;
234 }