]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - iot-gateway/lighting-gateway.git/blob - server/Source/interface_grouplist.c
add support for control bridge FW
[iot-gateway/lighting-gateway.git] / server / Source / interface_grouplist.c
1 /**************************************************************************************************
2  * Filename:       interface_devicelist.c
3  * Description:    Socket Remote Procedure Call Interface - sample device application.
4  *
5  *
6  * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ 
7  * 
8  * 
9  *  Redistribution and use in source and binary forms, with or without 
10  *  modification, are permitted provided that the following conditions 
11  *  are met:
12  *
13  *    Redistributions of source code must retain the above copyright 
14  *    notice, this list of conditions and the following disclaimer.
15  *
16  *    Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the 
18  *    documentation and/or other materials provided with the   
19  *    distribution.
20  *
21  *    Neither the name of Texas Instruments Incorporated nor the names of
22  *    its contributors may be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
26  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
27  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
29  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
30  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
31  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
34  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
35  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *
37  */
39 /*********************************************************************
40  * INCLUDES
41  */
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <unistd.h>
47 #include "interface_grouplist.h"
48 #include "hal_types.h"
49 #include "SimpleDBTxt.h"
51 static db_descriptor * db;
53 /*********************************************************************
54  * TYPEDEFS
55  */
57 void groupListInitDatabase(char * dbFilename)
58 {
59         db = sdb_init_db(dbFilename, sdbtGetRecordSize, sdbtCheckDeleted,
60                         sdbtCheckIgnored, sdbtMarkDeleted,
61                         (consolidation_processing_f) sdbtErrorComment, SDB_TYPE_TEXT, 0);
62         sdb_consolidate_db(&db);
63 }
65 static char * groupListComposeRecord(groupRecord_t *group, char * record)
66 {
67         groupMembersRecord_t *groupMembers;
69         sprintf(record, "        0x%04X , \"%s\"", //leave a space at the beginning to mark this record as deleted if needed later, or as bad format (can happen if edited manually). Another space to write the reason of bad format. 
70                         group->id, group->name ? group->name : "");
72         groupMembers = group->members;
74         while (groupMembers != NULL)
75         {
76                 sprintf(record + strlen(record), " , 0x%04X , 0x%02X",
77                                 groupMembers->nwkAddr, groupMembers->endpoint);
78                 groupMembers = groupMembers->next;
79         }
81         sprintf(record + strlen(record), "\n");
83         return record;
84 }
86 #define MAX_SUPPORTED_GROUP_NAME_LENGTH 32
87 #define MAX_SUPPORTED_GROUP_MEMBERS 20
89 static groupRecord_t * groupListParseRecord(char * record)
90 {
91         char * pBuf = record + 1; //+1 is to ignore the 'for deletion' mark that may just be added to this record.
92         static groupRecord_t group;
93         static char groupName[MAX_SUPPORTED_GROUP_NAME_LENGTH + 1];
94         static groupMembersRecord_t member[MAX_SUPPORTED_GROUP_MEMBERS];
95         groupMembersRecord_t ** nextMemberPtr;
96         parsingResult_t parsingResult =
97         { SDB_TXT_PARSER_RESULT_OK, 0 };
98         int i;
100         if (record == NULL)
101         {
102                 return NULL;
103         }
105         sdb_txt_parser_get_numeric_field(&pBuf, (uint8_t *) &group.id, 2, FALSE,
106                         &parsingResult);
107         sdb_txt_parser_get_quoted_string(&pBuf, groupName,
108                         MAX_SUPPORTED_GROUP_NAME_LENGTH, &parsingResult);
109         nextMemberPtr = &group.members;
110         for (i = 0;
111                         (parsingResult.code == SDB_TXT_PARSER_RESULT_OK)
112                                         && (i < MAX_SUPPORTED_GROUP_MEMBERS); i++)
113         {
114                 *nextMemberPtr = &(member[i]);
115                 sdb_txt_parser_get_numeric_field(&pBuf, (uint8_t *) &(member[i].nwkAddr), 2,
116                                 FALSE, &parsingResult);
117                 sdb_txt_parser_get_numeric_field(&pBuf, (uint8_t *) &(member[i].endpoint),
118                                 1, FALSE, &parsingResult);
119                 nextMemberPtr = &(member[i].next);
120         }
121         *nextMemberPtr = NULL;
123         if ((parsingResult.code != SDB_TXT_PARSER_RESULT_OK)
124                         && (parsingResult.code != SDB_TXT_PARSER_RESULT_REACHED_END_OF_RECORD))
125         {
126                 sdbtMarkError(db, record, &parsingResult);
127                 return NULL;
128         }
130         if (strlen(groupName) > 0)
131         {
132                 group.name = groupName;
133         }
134         else
135         {
136                 group.name = NULL;
137         }
139         return &group;
142 static int groupListCheckKeyName(char * record, char * key)
144         groupRecord_t * group;
145         int result = SDB_CHECK_KEY_NOT_EQUAL;
147         group = groupListParseRecord(record);
148         if (group == NULL)
149         {
150                 return SDB_CHECK_KEY_ERROR;
151         }
153         if (strcmp(group->name, key) == 0)
154         {
155                 result = SDB_CHECK_KEY_EQUAL;
156         }
158         return result;
161 static int groupListCheckKeyId(char * record, uint16_t * key)
163         groupRecord_t * group;
164         int result = SDB_CHECK_KEY_NOT_EQUAL;
166         group = groupListParseRecord(record);
167         if (group == NULL)
168         {
169                 return SDB_CHECK_KEY_ERROR;
170         }
172         if (group->id == *key)
173         {
174                 result = SDB_CHECK_KEY_EQUAL;
175         }
177         return result;
180 groupRecord_t * groupListGetGroupByName(char * groupName)
182         char * rec;
184         rec = SDB_GET_UNIQUE_RECORD(db, groupName, (check_key_f)groupListCheckKeyName);
185         if (rec == NULL)
186         {
187                 return NULL;
188         }
190         return groupListParseRecord(rec);
193 uint16_t groupListGetUnusedGroupId(void)
195         static uint16_t lastUsedGroupId = 0;
197         lastUsedGroupId++;
199         while (SDB_GET_UNIQUE_RECORD(db, &lastUsedGroupId, (check_key_f)groupListCheckKeyId)
200                         != NULL)
201         {
202                 lastUsedGroupId++;
203         }
205         return lastUsedGroupId;
208 uint16_t groupListAddGroup(char *groupNameStr)
210         groupRecord_t *exsistingGroup;
211         groupRecord_t newGroup;
212         char rec[MAX_SUPPORTED_RECORD_SIZE];
214         //printf("groupListAddGroup++\n");
216         exsistingGroup = groupListGetGroupByName(groupNameStr);
218         if (exsistingGroup != NULL)
219         {
220                 return exsistingGroup->id;
221         }
223         newGroup.id = groupListGetUnusedGroupId();
224         newGroup.name = groupNameStr;
225         newGroup.members = NULL;
227         groupListComposeRecord(&newGroup, rec);
229         sdb_add_record(db, rec);
231         //printf("groupListAddGroup--\n");
233         return newGroup.id;
236 groupRecord_t * groupListRemoveGroupByName(char * groupName)
238         return groupListParseRecord(
239                         sdb_delete_record(db, groupName, (check_key_f) groupListCheckKeyName));
242 uint16_t groupListAddDeviceToGroup(char *groupNameStr, uint16_t nwkAddr,
243                 uint8_t endpoint)
245         groupRecord_t *group;
246         groupRecord_t newGroup;
247         char rec[MAX_SUPPORTED_RECORD_SIZE];
248         groupMembersRecord_t ** nextMemberPtr;
249         groupMembersRecord_t newMember;
250         bool memberExists = FALSE;
251         uint16_t groupId;
253         //printf("groupListAddGroup++\n");
255         group = groupListGetGroupByName(groupNameStr);
257         if (group == NULL)
258         {
259                 group = &newGroup;
260                 group->id = groupListGetUnusedGroupId();
261                 group->name = groupNameStr;
262                 group->members = NULL;
263         }
265         groupId = group->id;
267         nextMemberPtr = &(group->members);
268         while ((*nextMemberPtr != NULL) && (!memberExists))
269         {
270                 if (((*nextMemberPtr)->nwkAddr == nwkAddr)
271                                 && ((*nextMemberPtr)->endpoint == endpoint))
272                 {
273                         memberExists = TRUE;
274                 }
275                 else
276                 {
277                         nextMemberPtr = &((*nextMemberPtr)->next);
278                 }
279         }
281         if (!memberExists)
282         {
283                 *nextMemberPtr = &newMember;
284                 newMember.nwkAddr = nwkAddr;
285                 newMember.endpoint = endpoint;
286                 newMember.next = NULL;
287                 groupListComposeRecord(group, rec);
288                 groupListRemoveGroupByName(groupNameStr);
289                 sdb_add_record(db, rec);
290         }
292         //printf("groupListAddGroup--\n");
294         return groupId;
297 groupRecord_t * groupListGetNextGroup(uint32_t *context)
299         char * rec;
300         groupRecord_t *group;
302         do
303         {
304                 rec = SDB_GET_NEXT_RECORD(db,context);
306                 if (rec == NULL)
307                 {
308                         return NULL;
309                 }
311                 group = groupListParseRecord(rec);
312         }
313         while (group == NULL); //in case of a bad-format record - skip it and read the next one
315         return group;