Imported Upstream version 1.0.1
[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     OC_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         OC_LOG(ERROR, TAG, "Failed allocating memory for OCRDStorePublishResources.");
56         return OC_STACK_NO_MEMORY;
57     }
58
59     OC_LOG_V(DEBUG, TAG, "Storing Resources for %s:%u", address->addr, address->port);
60
61     char rdPubAddr[MAX_ADDR_STR_SIZE];
62     snprintf(rdPubAddr, MAX_ADDR_STR_SIZE, "%s:%d", address->addr, address->port);
63
64     OCTagsPayload *tags = payload->tags;
65     storeResource->tags = OCCopyTagsResources(tags->n.deviceName, tags->di.id, rdPubAddr,
66         tags->bitmap, address->port, tags->ins, tags->rts, tags->drel, tags->ttl);
67     if (!storeResource->tags)
68     {
69         OC_LOG(ERROR, TAG, "Failed allocating memory for tags.");
70         OCFreeCollectionResource(storeResource);
71         return OC_STACK_NO_MEMORY;
72     }
73
74     for (OCLinksPayload *links = payload->setLinks; links; links = links->next)
75     {
76         if (!storeResource->setLinks)
77         {
78             storeResource->setLinks = OCCopyLinksResources(links->href, links->rt, links->itf,
79                 links->rel, links->obs, links->title, links->uri, links->ins, links->mt);
80             if (!storeResource->setLinks)
81             {
82                 OC_LOG(ERROR, TAG, "Failed allocating memory for links.");
83                 OCFreeCollectionResource(storeResource);
84                 return OC_STACK_NO_MEMORY;
85             }
86         }
87         else
88         {
89             OCLinksPayload *temp = storeResource->setLinks;
90             while (temp->next)
91             {
92                 temp = temp->next;
93             }
94             temp->next = OCCopyLinksResources(links->href, links->rt, links->itf, links->rel,
95                 links->obs, links->title, links->uri, links->ins, links->mt);
96             if (!temp->next)
97             {
98                 OC_LOG(ERROR, TAG, "Failed allocating memory for links.");
99                 OCFreeCollectionResource(storeResource);
100                 return OC_STACK_NO_MEMORY;
101             }
102         }
103
104     }
105     storeResource->next = NULL;
106     OCRDStorePublishResources *resources = (OCRDStorePublishResources *)OICCalloc(1, sizeof(OCRDStorePublishResources));
107     if (!resources)
108     {
109         OCFreeCollectionResource(storeResource);
110         return OC_STACK_NO_MEMORY;
111     }
112     resources->publishedResource = storeResource;
113
114     pthread_mutex_lock(&storageMutex);
115     if (g_rdStorage)
116     {
117         OCRDStorePublishResources *temp = g_rdStorage;
118         while (temp->next)
119         {
120             temp = temp->next;
121         }
122         temp->next = resources;
123     }
124     else
125     {
126         g_rdStorage = resources;
127     }
128     pthread_mutex_unlock(&storageMutex);
129
130     printStoragedResources(g_rdStorage);
131     return OC_STACK_OK;
132 }
133
134 OCStackResult OCRDCheckPublishedResource(const char *interfaceType, const char *resourceType,
135         OCResourceCollectionPayload **payload)
136 {
137     // ResourceType and InterfaceType if both are NULL it will return. If either is
138     // not null it will continue execution.
139     if (!resourceType && !interfaceType)
140     {
141         OC_LOG(DEBUG, TAG, "Missing resource type and interace type.");
142         return OC_STACK_INVALID_PARAM;
143     }
144
145     OC_LOG(DEBUG, TAG, "Check Resource in RD");
146     if (g_rdStorage && g_rdStorage->publishedResource)
147     {
148         for (OCRDStorePublishResources *pResource = g_rdStorage;
149                 pResource; pResource = pResource->next)
150         {
151             if (pResource->publishedResource->setLinks)
152             {
153                 for (OCLinksPayload *tLinks = pResource->publishedResource->setLinks; tLinks; tLinks = tLinks->next)
154                 {
155                     // If either rt or itf are NULL, it should skip remaining code execution.
156                     if (!tLinks->rt || !tLinks->itf)
157                     {
158                         OC_LOG(DEBUG, TAG, "Either resource type and interface type are missing.");
159                         continue;
160                     }
161                     if (resourceType)
162                     {
163                         OCStringLL *temp = tLinks->rt;
164                         while(temp)
165                         {
166                             OC_LOG_V(DEBUG, TAG, "Resource Type: %s %s", resourceType, temp->value);
167                             if (strcmp(resourceType, temp->value) == 0)
168                             {
169                                 OCTagsPayload *tag = pResource->publishedResource->tags;
170                                 OCTagsPayload *tags = OCCopyTagsResources(tag->n.deviceName, tag->di.id, tag->baseURI,
171                                     tag->bitmap, tag->port, tag->ins, tag->rts, tag->drel, tag->ttl);
172                                 if (!tags)
173                                 {
174                                     return OC_STACK_NO_MEMORY;
175                                 }
176                                 OCLinksPayload *links = OCCopyLinksResources(tLinks->href, tLinks->rt, tLinks->itf,
177                                     tLinks->rel, tLinks->obs, tLinks->title, tLinks->uri, tLinks->ins, tLinks->mt);
178                                 if (!links)
179                                 {
180                                     OCFreeTagsResource(tags);
181                                     return OC_STACK_NO_MEMORY;
182                                 }
183                                 *payload = OCCopyCollectionResource(tags, links);
184                                 if (!*payload)
185                                 {
186                                     OCFreeTagsResource(tags);
187                                     OCFreeLinksResource(links);
188                                     return OC_STACK_NO_MEMORY;
189                                 }
190                                 return OC_STACK_OK;
191                             }
192                             temp = temp->next;
193                         }
194                     }
195                     if (interfaceType)
196                     {
197                         OCStringLL *temp = tLinks->itf;
198                         while (temp)
199                         {
200                             OC_LOG_V(DEBUG, TAG, "Interface Type: %s %s", interfaceType, temp->value);
201                             if (strcmp(interfaceType, temp->value) == 0)
202                             {
203                                 OCTagsPayload *tag = pResource->publishedResource->tags;
204                                 OCTagsPayload *tags = OCCopyTagsResources(tag->n.deviceName, tag->di.id, tag->baseURI,
205                                     tag->bitmap, tag->port, tag->ins, tag->rts, tag->drel, tag->ttl);
206                                 if (!tags)
207                                 {
208                                     return OC_STACK_NO_MEMORY;
209                                 }
210                                 OCLinksPayload *links = OCCopyLinksResources(tLinks->uri, tLinks->rt, tLinks->itf,
211                                     tLinks->rel, tLinks->obs, tLinks->title, tLinks->uri, tLinks->ins, tLinks->mt);
212                                 if (!links)
213                                 {
214                                     OCFreeTagsResource(tags);
215                                     return OC_STACK_NO_MEMORY;
216                                 }
217                                 *payload = OCCopyCollectionResource(tags, links);
218                                 if (!*payload)
219                                 {
220                                     OCFreeTagsResource(tags);
221                                     OCFreeLinksResource(links);
222                                     return OC_STACK_NO_MEMORY;
223                                 }
224                                 return OC_STACK_OK;
225                             }
226                             temp = temp->next;
227                         }
228                     }
229                 }
230             }
231         }
232     }
233     return OC_STACK_ERROR;
234 }