3aebc4a36b485779f473f92f9fd07bc86bfd0e11
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_srpcserver.h"
48 #include "interface_devicelist.h"
50 /*********************************************************************
51 * DEFINES
52 */
55 /*********************************************************************
56 * TYPEDEFS
57 */
59 typedef struct
60 {
61 void *next;
62 epInfo_t epInfo;
63 }deviceRecord_t;
65 deviceRecord_t *deviceRecordHead = NULL;
67 /*********************************************************************
68 * LOCAL FUNCTION PROTOTYPES
69 */
70 static deviceRecord_t* createDeviceRec( epInfo_t epInfo );
71 static deviceRecord_t* findDeviceRec( uint16_t nwkAddr, uint8_t endpoint);
72 static char* findDeviceInFileString( uint16_t nwkAddr, uint8_t endpoint, char* fileBuf, uint32_t bufLen );
73 static void reomveDeviceFromFile( uint16_t nwkAddr, uint8_t endpoint );
74 static void writeDeviceToFile( deviceRecord_t *device );
75 static void readDeviceListFromFile( void );
77 /*********************************************************************
78 * FUNCTIONS
79 *********************************************************************/
81 /*********************************************************************
82 * @fn createDeviceRec
83 *
84 * @brief create a device and add a rec fto the list.
85 *
86 * @param table
87 * @param rmTimer
88 *
89 * @return none
90 */
91 static deviceRecord_t* createDeviceRec( epInfo_t epInfo )
92 {
93 deviceRecord_t *srchRec;
95 //printf("createDeviceRec++\n");
97 //does it already exist
98 if( findDeviceRec( epInfo.nwkAddr, epInfo.endpoint ) )
99 {
100 //printf("createDeviceRec: Device already exists\n");
101 return NULL;
102 }
104 deviceRecord_t *newDevice = malloc( sizeof( deviceRecord_t ) );
106 //Store the epInfo
107 memcpy( &(newDevice->epInfo), &epInfo, sizeof(epInfo_t));
109 newDevice->epInfo.deviceName = NULL;
110 newDevice->epInfo.status = DEVLIST_STATE_ACTIVE;
112 //printf("New Device added (%x) - ADDR:%x, DEVICE:%x, PROFILE:%x, EP:%x\n", newDevice, newDevice->epInfo.nwkAddr, newDevice->epInfo.deviceID, newDevice->epInfo.profileID, newDevice->epInfo.endpoint);
114 newDevice->next = NULL;
116 if(deviceRecordHead)
117 {
118 //find the end of the list and add the record
119 srchRec = deviceRecordHead;
120 // Stop at the last record
121 while ( srchRec->next )
122 srchRec = srchRec->next;
124 // Add to the list
125 srchRec->next = newDevice;
127 //printf("New Device added to end of list (%x)\n", srchRec->next);
128 }
129 else
130 {
131 //printf("createDeviceRec: adding new device to head of the list\n");
132 deviceRecordHead = newDevice;
133 }
135 return newDevice;
136 //printf("createDeviceRec--\n");
137 }
139 /*********************************************************************
140 * @fn findDeviceRec
141 *
142 * @brief find a device and in the list.
143 *
144 * @param nwkAddr
145 * @param endpoint
146 *
147 * @return deviceRecord_t for the device foundm null if not found
148 */
149 static deviceRecord_t* findDeviceRec( uint16_t nwkAddr, uint8_t endpoint)
150 {
151 deviceRecord_t *srchRec = deviceRecordHead;
153 //printf("findDeviceRec++: nwkAddr:%x, ep:%x\n", nwkAddr, endpoint);
155 // find record
156 while ( (srchRec) && !((srchRec->epInfo.nwkAddr == nwkAddr) && (srchRec->epInfo.endpoint == endpoint)) )
157 {
158 //printf("findDeviceRec++: searching nwkAddr:%x, ep:%x\n", srchRec->epInfo.nwkAddr, srchRec->epInfo.endpoint);
159 srchRec = srchRec->next;
160 }
162 //printf("findDeviceRec[%x]--\n", srchRec);
164 return srchRec;
165 }
167 /***************************************************************************************************
168 * @fn findDeviceInFileString - remove device from file.
169 *
170 * @brief
171 * @param
172 *
173 * @return
174 ***************************************************************************************************/
175 static char* findDeviceInFileString( uint16_t nwkAddr, uint8_t endpoint, char* fileBuf, uint32_t bufLen )
176 {
177 char *deviceIdx = NULL, *deviceStartIdx, *deviceEndIdx;
178 uint32_t remainingBytes;
180 //printf("findDeviceInFile++\n");
182 deviceStartIdx = fileBuf;
183 remainingBytes = bufLen;
184 //set to a non NULL value
185 deviceEndIdx = fileBuf;
187 while( ((fileBuf - deviceStartIdx) < bufLen) && (deviceEndIdx != 0) )
188 {
189 //is this device the correct device
190 if( *((uint16_t*)deviceStartIdx) == nwkAddr )
191 {
192 //device found
193 deviceIdx = deviceStartIdx;
194 break;
195 }
197 //find end of current device by finding the delimiter
198 deviceEndIdx = strchr(deviceStartIdx, ';');
199 if( deviceEndIdx > (fileBuf + bufLen) )
200 {
201 //past end of file string
202 //printf("findDeviceInFile++\n");
203 deviceEndIdx = NULL;
204 }
206 if( deviceEndIdx )
207 {
208 remainingBytes = bufLen - (fileBuf - deviceEndIdx);
209 deviceStartIdx = &(deviceEndIdx[1]);
210 }
211 }
213 //printf("findDeviceInFile-- [%x]\n", (uint32_t) deviceIdx);
215 return deviceIdx;
216 }
218 /***************************************************************************************************
219 * @fn reomveDeviceFromFile - remove device from file.
220 *
221 * @brief
222 * @param
223 *
224 * @return
225 ***************************************************************************************************/
226 static void reomveDeviceFromFile( uint16_t nwkAddr, uint8_t endpoint )
227 {
228 FILE *fpDevFile;
229 uint32_t fileSize;
230 char *fileBuf, *deviceStr, *devStrEnd;
232 //printf("reomveDeviceFromFile++\n");
234 fpDevFile = fopen("devicelistfile.dat", "w+b");
236 if(fpDevFile)
237 {
238 //read the file into a buffer
239 fseek(fpDevFile, 0, SEEK_END);
240 fileSize = ftell(fpDevFile);
241 rewind(fpDevFile);
242 fileBuf = (char*) calloc(sizeof(char), fileSize);
243 fread(fileBuf, 1, fileSize, fpDevFile);
245 //printf("reomveDeviceFromFile: number of bytes in file = %d\n", fileSize);
246 //printf("reomveDeviceFromFile: Searching for device string\n");
247 //find the device
248 deviceStr = findDeviceInFileString( nwkAddr, endpoint, fileBuf, fileSize );
250 if( deviceStr )
251 {
252 //printf("reomveDeviceFromFile: device string:%x\n", (uint32_t) deviceStr);
253 //find device delimiter
254 devStrEnd = strchr(deviceStr, ';');
256 if( devStrEnd )
257 {
258 //copy start of file to bigenning of device
259 fwrite((const void *) fileBuf, fileBuf-deviceStr, 1, fpDevFile);
260 //copy end of device to end of file
261 fwrite((const void *) devStrEnd, fileSize - (fileBuf - devStrEnd), 1, fpDevFile);
262 }
263 else
264 {
265 //printf("reomveDeviceFromFile: device delimiter not found\n");
266 }
267 }
268 else
269 {
270 //printf("reomveDeviceFromFile: device not found in file\n");
271 }
272 }
274 fflush(fpDevFile);
275 fclose(fpDevFile);
276 free(fileBuf);
277 }
279 /***************************************************************************************************
280 * @fn writeDeviceToFile - store device list.
281 *
282 * @brief
283 * @param
284 *
285 * @return
286 ***************************************************************************************************/
287 static void writeDeviceToFile( deviceRecord_t *device )
288 {
289 FILE *fpDevFile;
291 //printf("writeDeviceToFile++\n");
293 fpDevFile = fopen("devicelistfile.dat", "a+b");
295 if(fpDevFile)
296 {
297 //printf("writeDeviceToFile: opened file\n");
299 //printf("writeDeviceToFile: Store epInfo[%d - %d - %d - %d]\n", sizeof(epInfo_t), sizeof (char*), sizeof (uint8_t), ((sizeof(epInfo_t)) - (sizeof (char*) + sizeof (uint8_t))));
300 //Store epInfo - device name pointer and status
301 fwrite((const void *) &(device->epInfo), (sizeof(epInfo_t) - (sizeof (char*) + sizeof (uint8_t))), 1, fpDevFile);
303 //Store deviceName len
304 if(device->epInfo.deviceName)
305 {
306 uint8_t i;
307 //printf("writeDeviceToFile: Store deviceName\n");
309 //first char of dev name is str length
310 for(i = 0; i < (device->epInfo.deviceName[0] + 1) ; i++)
311 {
312 fwrite((const void *) (&(device->epInfo.deviceName[i])), 1, 1, fpDevFile);
313 }
314 }
315 else
316 {
317 //just store the len of 0
318 uint8_t tmp = 0;
319 fwrite(&tmp, 1, 1, fpDevFile);
320 }
322 //printf("writeDeviceToFile: Store status\n");
323 //Store status
324 fwrite((const void *) &(device->epInfo.status), 1, 1, fpDevFile);
325 //write delimter
326 fwrite(";", 1, 1, fpDevFile);
328 fflush(fpDevFile);
329 fclose(fpDevFile);
330 }
331 }
333 /***************************************************************************************************
334 * @fn readDeviceListFromFile - restore the device list.
335 *
336 * @brief
337 *
338 * @return
339 ***************************************************************************************************/
340 static void readDeviceListFromFile( void )
341 {
342 FILE *fpDevFile;
343 deviceRecord_t *device;
344 epInfo_t epInfo;
345 char chTmp;
347 //printf("readDeviceListFromFile++\n");
348 fpDevFile = fopen("devicelistfile.dat", "a+b");
350 if(fpDevFile)
351 {
352 //printf("readDeviceListFromFile: file opened\n");
353 //read epInfo_t - device name pointer and status
354 while(fread(&(epInfo), (sizeof(epInfo_t) - (sizeof (char*) + sizeof (uint8_t))), 1, fpDevFile))
355 {
356 //printf("readDeviceListFromFile: epInfo[%d] read for device %x\n", (sizeof(epInfo_t) - (sizeof (char*) + sizeof (uint8_t))), epInfo.nwkAddr);
358 device = createDeviceRec(epInfo);
360 if(device)
361 {
362 uint8_t strLen;
363 char *strName;
364 fread(&(strLen), 1, 1, fpDevFile);
365 //printf("readDeviceListFromFile: strLen %d\n", strLen);
367 if(strLen > 0)
368 {
369 strName = malloc(strLen + 1);
370 if(strName)
371 {
372 strName[0] = strLen;
373 fread(&(strName[1]), 1, strLen, fpDevFile);
374 }
375 device->epInfo.deviceName = strName;
376 }
378 fread(&(device->epInfo.status), 1, 1, fpDevFile);
379 //printf("readDeviceListFromFile: device->epInfo.status %x\n", device->epInfo.status);
381 //read ';' delimeter
382 fread(&chTmp, 1, 1, fpDevFile);
384 if(chTmp != ';')
385 {
386 //printf("readDeviceListFromFile: Error, device delimter not found\n");
387 return;
388 }
389 }
390 }
392 fflush(fpDevFile);
393 fclose(fpDevFile);
394 }
396 //printf("readDeviceListFromFile--\n");
397 }
399 /*********************************************************************
400 * @fn devListAddDevice
401 *
402 * @brief create a device and add a rec to the list.
403 *
404 * @param epInfo
405 *
406 * @return none
407 */
408 void devListAddDevice( epInfo_t *epInfo)
409 {
410 //printf("devListAddDevice++(%x:%x)\n", epInfo->nwkAddr, epInfo->endpoint);
412 deviceRecord_t *device = createDeviceRec(*epInfo);
413 if(device)
414 {
415 writeDeviceToFile(device);
416 }
418 //printf("\n\n\ndevListAddDevice: list=\n");
419 //find the end of the list and add the record
420 deviceRecord_t *srchRec = deviceRecordHead;
421 //printf("%x", srchRec);
423 while ( srchRec->next )
424 {
425 srchRec = srchRec->next;
426 //printf("%x\n", srchRec);
427 }
428 //printf("\n\n\n");
430 //printf("devListAddDevice--\n");
431 }
433 /*********************************************************************
434 * @fn devListRemoveDevice
435 *
436 * @brief remove a device rec from the list.
437 *
438 * @param nwkAddr - nwkAddr of device to be removed
439 * @param endpoint - endpoint of device to be removed
440 *
441 * @return none
442 */
443 void devListRemoveDevice( uint16_t nwkAddr, uint8_t endpoint )
444 {
445 deviceRecord_t *srchRec, *prevRec=NULL;
447 // find record and prev device record
448 srchRec = deviceRecordHead;
450 // find record
451 while ( (srchRec) && !((srchRec->epInfo.nwkAddr == nwkAddr) && (srchRec->epInfo.endpoint == endpoint)) )
452 {
453 prevRec = srchRec;
454 srchRec = srchRec->next;
455 }
457 if (srchRec == NULL)
458 {
459 //printf("deleteDeviceRec: record not found\n");
460 return;
461 }
462 else
463 {
464 // delete the rec from the list
465 if ( prevRec == NULL )
466 {
467 //at head of the list
468 //remove record from list
469 deviceRecordHead = srchRec->next;
470 }
471 else
472 {
473 //remove record from list
474 prevRec->next = srchRec->next;
475 }
477 free(srchRec);
478 }
479 }
481 /*********************************************************************
482 * @fn devListRestorDevices
483 *
484 * @brief create a device list from file.
485 *
486 * @param none
487 *
488 * @return none
489 */
490 void devListRestorDevices( void )
491 {
492 //printf("devListRestorDevices++\n");
493 if( deviceRecordHead == NULL)
494 {
495 readDeviceListFromFile();
496 }
497 //else do what, should we delete the list and recreate from the file?
498 }
500 /*********************************************************************
501 * @fn devListChangeDeviceName
502 *
503 * @brief change the name of a device.
504 *
505 * @return
506 */
507 void devListChangeDeviceName( uint16_t devNwkAddr, uint8_t devEndpoint, char *deviceNameStr)
508 {
509 //printf("devListChangeDeviceName++\n");
511 deviceRecord_t *device = findDeviceRec( devNwkAddr, devEndpoint );
513 if(device)
514 {
515 if(device->epInfo.deviceName)
516 {
517 free(device->epInfo.deviceName);
518 }
520 //printf("devListChangeDeviceName: removing device from file\n");
521 reomveDeviceFromFile(devNwkAddr, devEndpoint);
523 //printf("devListChangeDeviceName: Changing device name\n");
524 //fisrt byte of deviceNameStr is the size of the string
525 device->epInfo.deviceName = malloc(deviceNameStr[0]);
526 strncpy(device->epInfo.deviceName, &(deviceNameStr[0]), (deviceNameStr[0] + 1) );
528 //printf("devListChangeDeviceName: writing device to file\n");
529 writeDeviceToFile(device);
530 }
531 else
532 {
533 //printf("devListChangeDeviceName: Device not found");
534 }
536 //printf("devListChangeDeviceName--\n");
538 return;
539 }
541 /*********************************************************************
542 * @fn devListNumDevices
543 *
544 * @brief get the number of devices in the list.
545 *
546 * @param none
547 *
548 * @return none
549 */
550 uint32_t devListNumDevices( void )
551 {
552 uint32_t recordCnt=0;
553 deviceRecord_t *srchRec;
555 //printf("devListNumDevices++\n");
557 // Head of the list
558 srchRec = deviceRecordHead;
560 if(srchRec==NULL)
561 {
562 //printf("devListNumDevices: deviceRecordHead NULL\n");
563 return -1;
564 }
566 // Stop when rec found or at the end
567 while ( srchRec )
568 {
569 //printf("devListNumDevices: recordCnt=%d\n", recordCnt);
570 srchRec = srchRec->next;
571 recordCnt++;
572 }
574 //printf("devListNumDevices %d\n", recordCnt);
575 return (recordCnt);
576 }
578 /*********************************************************************
579 * @fn devListGetNextDev
580 *
581 * @brief Return the next device in the list.
582 *
583 * @param nwkAddr - if 0xFFFF it will return head of the list
584 *
585 * @return epInfo, return next epInfo from nwkAddr and ep supplied or
586 * NULL if at end of the list
587 */
588 epInfo_t* devListGetNextDev( uint16_t nwkAddr, uint8_t endpoint )
589 {
590 epInfo_t* epInfo = NULL;
591 deviceRecord_t *srchRec;
593 //printf("devListGetNextDev++: nwkAddr=%x, endpoint=%x\n", nwkAddr, endpoint);
595 // Head of the list
596 srchRec = deviceRecordHead;
598 if(nwkAddr != 0xFFFF)
599 {
600 //Find the record for nwkAddr
601 srchRec = findDeviceRec(nwkAddr, endpoint);
602 //get the next record (may be NULL if at end of list)
603 srchRec = srchRec->next;
605 //printf("devListGetNextDev: found device %x\n", srchRec);
607 //Store the epInfo
608 if(srchRec)
609 {
610 //printf("devListGetNextDev: returning next device %x\n", srchRec);
611 epInfo = &(srchRec->epInfo);
612 }
613 }
614 else
615 {
616 //printf("\n\n\ndevListGetNextDev: list= [%x]\n", deviceRecordHead);
617 //find the end of the list and add the record
618 deviceRecord_t *srchRec1 = deviceRecordHead;
619 //printf("%x", srchRec1);
620 if(srchRec1)
621 {
622 while ( srchRec1->next )
623 {
624 srchRec1 = srchRec1->next;
625 //printf("%x\n", srchRec1);
626 }
627 }
628 //printf("\n\n\n");
630 //printf("devListGetNextDev: returning head of list\n");
631 //return fisrt record
632 if(deviceRecordHead)
633 {
634 epInfo = &(deviceRecordHead->epInfo);
635 }
636 }
638 //printf("devListGetNextDev[%x]--\n", epInfo);
640 return (epInfo);
641 }