PageRenderTime 29ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/start/TupleSpace.h

https://github.com/okoye/teenylime
C Header | 568 lines | 412 code | 101 blank | 55 comment | 91 complexity | d76c420d5bfa907feb89947594713496 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0
  1. /***
  2. * * PROJECT
  3. * * TeenyLIME
  4. * * VERSION
  5. * * $LastChangedRevision: 4 $
  6. * * DATE
  7. * * $LastChangedDate: 2007-04-27 10:22:42 -0500 (Fri, 27 Apr 2007) $
  8. * * LAST_CHANGE_BY
  9. * * $LastChangedBy: paolinux78 $
  10. * *
  11. * * $Id: TupleSpace.h 4 2007-04-27 15:22:42Z paolinux78 $
  12. * *
  13. * * TeenyLIME - Transiently Shared Tuple Space Middleware for
  14. * * Wireless Sensor Networks
  15. * *
  16. * * This program is free software; you can redistribute it and/or
  17. * * modify it under the terms of the GNU Lesser General Public License
  18. * * as published by the Free Software Foundation; either version 2
  19. * * of the License, or (at your option) any later version.
  20. * *
  21. * * This program is distributed in the hope that it will be useful,
  22. * * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. * * GNU General Public License for more details.
  25. * *
  26. * * You should have received a copy of the GNU General Public License
  27. * * along with this program; if not, you may find a copy at the FSF web
  28. * * site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
  29. * * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  30. * * Boston, MA 02111-1307, USA
  31. ***/
  32. /**
  33. * Definition of data structures.
  34. *
  35. * @author Paolo Costa
  36. * <a href="mailto:paolo.costa@polimi.it">paolo.costa@polimi.it</a>
  37. *
  38. */
  39. #include <stdarg.h>
  40. #include <stdio.h>
  41. #include <float.h>
  42. #include "TLConf.h"
  43. // Definition of possible targets for operations
  44. #define TL_LOCAL TOS_LOCAL_ADDRESS
  45. #define TL_NEIGHBORHOOD TOS_BCAST_ADDR
  46. /* TODO: #define TL_ANY TOS_BCAST_ADDR-1 */
  47. // To distinguish between actual and formal fields
  48. #define TYPE_ACTUAL 0
  49. #define TYPE_FORMAL 128
  50. // To tag tuples with no epoch requirement
  51. #define TIME_UNDEFINED 0
  52. // TeenyLIME internal constants
  53. #define STR_SIZE 4
  54. #define TEENYLIME_SYSTEM_OPERATION 0
  55. #define TEENYLIME_SYSTEM_COMPONENT 0
  56. #define UINT16_MIN 0
  57. #ifdef mica2
  58. #define UINT16_MAX 0xFFFF
  59. #define UINT32_MAX 0xFFFFFFFF
  60. #endif
  61. typedef uint16_t TLTarget_t;
  62. typedef uint8_t fieldType;
  63. typedef struct {
  64. uint8_t componentId;
  65. uint8_t commandId;
  66. uint16_t msgOrigin;
  67. bool reliable;
  68. } TLOpId_t;
  69. //__attribute__((__packed__)) TLOpId_t;
  70. enum {
  71. TYPE_EMPTY, TYPE_UINT8_T,
  72. TYPE_UINT16_T, TYPE_UINT32_T,
  73. TYPE_FLOAT, TYPE_CHAR, TYPE_STR,
  74. TYPE_RANGE_IN, TYPE_RANGE_OUT, TYPE_DONT_CARE
  75. };
  76. typedef union fieldValue {
  77. uint8_t int8;
  78. uint16_t int16;
  79. uint32_t int32;
  80. float flt;
  81. char c;
  82. char str[STR_SIZE];
  83. uint16_t range_int16[2];
  84. } fieldValue;
  85. typedef struct field {
  86. fieldType type;
  87. fieldValue value;
  88. } field;
  89. //__attribute__((__packed__)) field;
  90. typedef struct tuple {
  91. // In the case of a real tuple, the following is the timestamp when
  92. // the tuple was output, in case of a template, it specifies a
  93. // freshness requirement wrt to the local time
  94. uint16_t logicalTime;
  95. // The number of epochs this tuple should survive
  96. uint16_t expireIn;
  97. bool capabilityT;
  98. field fields[MAX_FIELDS];
  99. } tuple;
  100. //__attribute__((__packed__)) tuple;
  101. // To return a code error to the application, this must use isFailed() to check
  102. #define TL_OP_FAIL 0
  103. bool isFailed(TLOpId_t* opId) {
  104. if (opId->commandId == 0) return TRUE;
  105. else return FALSE;
  106. }
  107. field formalField(fieldType type) {
  108. field f;
  109. f.type = (TYPE_FORMAL | type);
  110. return f;
  111. }
  112. field lowerField(uint16_t bound) {
  113. field f;
  114. f.type = (TYPE_FORMAL | TYPE_RANGE_IN);
  115. f.value.range_int16[0] = UINT16_MIN;
  116. f.value.range_int16[1] = bound;
  117. return f;
  118. }
  119. field greaterField(uint16_t bound) {
  120. field f;
  121. f.type = (TYPE_FORMAL | TYPE_RANGE_IN);
  122. f.value.range_int16[0] = bound;
  123. f.value.range_int16[1] = UINT16_MAX;
  124. return f;
  125. }
  126. field rangeField(uint16_t lower_bound, uint16_t upper_bound) {
  127. field f;
  128. f.type = (TYPE_FORMAL | TYPE_RANGE_IN);
  129. f.value.range_int16[0] = lower_bound;
  130. f.value.range_int16[1] = upper_bound;
  131. return f;
  132. }
  133. field rangeOutField(uint16_t lower_bound, uint16_t upper_bound) {
  134. field f;
  135. f.type = (TYPE_FORMAL | TYPE_RANGE_OUT);
  136. f.value.range_int16[0] = lower_bound;
  137. f.value.range_int16[1] = upper_bound;
  138. return f;
  139. }
  140. field actualField_uint8(uint8_t value) {
  141. field f;
  142. f.type = (TYPE_ACTUAL | TYPE_UINT8_T);
  143. f.value.int8 = value;
  144. return f;
  145. }
  146. field actualField_uint16(uint16_t value) {
  147. field f;
  148. f.type = (TYPE_ACTUAL | TYPE_UINT16_T);
  149. f.value.int16 = value;
  150. return f;
  151. }
  152. field actualField_uint32(uint32_t value) {
  153. field f;
  154. f.type = (TYPE_ACTUAL | TYPE_UINT32_T);
  155. f.value.int32 = value;
  156. return f;
  157. }
  158. field actualField_float(float value) {
  159. field f;
  160. f.type = (TYPE_ACTUAL | TYPE_FLOAT);
  161. f.value.flt = value;
  162. return f;
  163. }
  164. field actualField_char(char value) {
  165. field f;
  166. f.type = (TYPE_ACTUAL | TYPE_CHAR);
  167. f.value.c = value;
  168. return f;
  169. }
  170. field actualField_str(char value[]) {
  171. field f;
  172. f.type = (TYPE_ACTUAL | TYPE_STR);
  173. strncpy(f.value.str, value, STR_SIZE-1);
  174. f.value.str[STR_SIZE-1] = '\0';
  175. return f;
  176. }
  177. field emptyField() {
  178. field f;
  179. f.type = TYPE_EMPTY | TYPE_FORMAL;
  180. return f;
  181. }
  182. field dontCareField() {
  183. field f;
  184. f.type = (TYPE_FORMAL | TYPE_DONT_CARE);
  185. return f;
  186. }
  187. tuple newTuple(uint8_t numFields, ...) {
  188. tuple t;
  189. int i = 0;
  190. va_list ap;
  191. va_start(ap, numFields);
  192. while(i < numFields && i < MAX_FIELDS) {
  193. t.fields[i] = va_arg(ap, field);
  194. i++;
  195. }
  196. while(i < MAX_FIELDS) {
  197. t.fields[i] = emptyField();
  198. i++;
  199. }
  200. t.logicalTime = TIME_UNDEFINED;
  201. t.expireIn = TIME_UNDEFINED;
  202. t. capabilityT = FALSE;
  203. return t;
  204. }
  205. tuple newCapabilityTuple(uint8_t numFields, ...) {
  206. tuple t;
  207. int i = 0;
  208. va_list ap;
  209. va_start(ap, numFields);
  210. while(i < numFields && i < MAX_FIELDS) {
  211. t.fields[i] = va_arg(ap, field);
  212. i++;
  213. }
  214. while(i < MAX_FIELDS) {
  215. t.fields[i] = emptyField();
  216. i++;
  217. }
  218. t.logicalTime = TIME_UNDEFINED;
  219. t.expireIn = TIME_UNDEFINED;
  220. t.capabilityT = TRUE;
  221. return t;
  222. }
  223. // TODO: Shall we check if templ is indeed a template?
  224. void setFreshness(tuple* templ, uint16_t freshness) {
  225. templ->logicalTime = freshness;
  226. }
  227. void setExpireIn(tuple* t, uint16_t expireIn) {
  228. t->expireIn = expireIn;
  229. }
  230. uint16_t getFreshness(tuple* t) {
  231. return t->logicalTime;
  232. }
  233. tuple emptyTuple() {
  234. return newTuple(0);
  235. }
  236. tuple dontCareTuple() {
  237. tuple t;
  238. uint8_t i;
  239. for(i = 0; i < MAX_FIELDS; i++) {
  240. t.fields[i] = dontCareField();
  241. }
  242. t.logicalTime = TIME_UNDEFINED;
  243. t.expireIn = TIME_UNDEFINED;
  244. t. capabilityT = FALSE;
  245. return t;
  246. }
  247. bool isEmptyField(field *f) {
  248. return f->type % TYPE_FORMAL == TYPE_EMPTY;
  249. }
  250. bool isCapabilityTuple(tuple *t) {
  251. return t->capabilityT;
  252. }
  253. bool isEmptyTuple(tuple *t) {
  254. uint8_t i;
  255. for(i = 0; i < MAX_FIELDS; i++) {
  256. if(isEmptyField(&(t->fields[i])) == FALSE) {
  257. return FALSE;
  258. }
  259. }
  260. return TRUE;
  261. }
  262. uint8_t getTupleSize(tuple *t) {
  263. uint8_t i = 0;
  264. while(i < MAX_FIELDS && !isEmptyField(&(t->fields[i]))) {
  265. i++;
  266. }
  267. return i;
  268. }
  269. bool isFormalField(field *f) {
  270. return ((f->type & TYPE_FORMAL) == TYPE_FORMAL);
  271. }
  272. fieldType getFieldType(field *f) {
  273. return (f->type % TYPE_FORMAL);
  274. }
  275. field* getField(tuple* t, uint8_t loc) {
  276. if(loc >= MAX_FIELDS || isEmptyField(&(t->fields[loc]))) {
  277. return NULL;
  278. }
  279. else {
  280. return &(t->fields[loc]);
  281. }
  282. }
  283. void printTuple(tuple *t, char tupleString[]) {
  284. #ifndef mica2
  285. uint8_t i;
  286. sprintf(tupleString, "[");
  287. for(i = 0; i < MAX_FIELDS; i++) {
  288. if((t->fields[i].type % TYPE_FORMAL) == TYPE_EMPTY) {
  289. sprintf(tupleString, "%s ", tupleString);
  290. break;
  291. }
  292. else if((t->fields[i].type % TYPE_FORMAL) == TYPE_DONT_CARE) {
  293. sprintf(tupleString, "%s (don't care),", tupleString);
  294. continue;
  295. }
  296. switch(t->fields[i].type % TYPE_FORMAL) {
  297. case TYPE_UINT8_T:
  298. sprintf(tupleString, "%s (uint8_t,", tupleString);
  299. if(isFormalField(&(t->fields[i])) == FALSE)
  300. sprintf(tupleString, "%s %d),", tupleString, t->fields[i].value.int8);
  301. break;
  302. case TYPE_UINT16_T:
  303. sprintf(tupleString, "%s (uint16_t,", tupleString);
  304. if(isFormalField(&(t->fields[i])) == FALSE)
  305. sprintf(tupleString, "%s %d),", tupleString, t->fields[i].value.int16);
  306. break;
  307. case TYPE_UINT32_T:
  308. sprintf(tupleString, "%s (uint32_t,", tupleString);
  309. if(isFormalField(&(t->fields[i])) == FALSE)
  310. sprintf(tupleString, "%s %d),", tupleString, t->fields[i].value.int32);
  311. break;
  312. case TYPE_FLOAT:
  313. sprintf(tupleString, "%s (float,", tupleString);
  314. if(isFormalField(&(t->fields[i])) == FALSE)
  315. sprintf(tupleString, "%s %.2f),", tupleString, t->fields[i].value.flt);
  316. break;
  317. case TYPE_CHAR:
  318. sprintf(tupleString, "%s (char,", tupleString);
  319. if(isFormalField(&(t->fields[i])) == FALSE)
  320. sprintf(tupleString, "%s \'%c\'),", tupleString, t->fields[i].value.c);
  321. break;
  322. case TYPE_STR:
  323. sprintf(tupleString, "%s (string,", tupleString);
  324. if(isFormalField(&(t->fields[i])) == FALSE)
  325. sprintf(tupleString, "%s \"%s\"),",
  326. tupleString, t->fields[i].value.str);
  327. break;
  328. case TYPE_RANGE_IN:
  329. sprintf(tupleString, "%s (range,", tupleString);
  330. sprintf(tupleString, "%s [%d:%d]),",
  331. tupleString, t->fields[i].value.range_int16[0],
  332. t->fields[i].value.range_int16[1]);
  333. break;
  334. case TYPE_RANGE_OUT:
  335. sprintf(tupleString, "%s (range out,", tupleString);
  336. sprintf(tupleString, "%s [%d:%d]),", tupleString,
  337. t->fields[i].value.range_int16[0],
  338. t->fields[i].value.range_int16[1]);
  339. break;
  340. default:
  341. sprintf(tupleString, "%s (unknown type,", tupleString);
  342. break;
  343. }
  344. if(isFormalField(&(t->fields[i])) == TRUE && getFieldType(&(t->fields[i])) != TYPE_RANGE_IN && getFieldType(&(t->fields[i])) != TYPE_RANGE_OUT) {
  345. sprintf(tupleString, "%s formal),", tupleString);
  346. }
  347. }
  348. tupleString[strlen(tupleString)-1] = ' ';
  349. sprintf(tupleString, "%s]", tupleString);
  350. #endif
  351. }
  352. bool compareRangeFields(field* range, field* actual) {
  353. if(isFormalField(actual))
  354. return FALSE;
  355. switch(getFieldType(actual)) {
  356. case TYPE_UINT8_T:
  357. return (range->value.range_int16[0] <= actual->value.int8
  358. && range->value.range_int16[1] >= actual->value.int8);
  359. case TYPE_UINT16_T:
  360. return (range->value.range_int16[0] <= actual->value.int16
  361. && range->value.range_int16[1] >= actual->value.int16);
  362. case TYPE_FLOAT:
  363. return (range->value.range_int16[0] <= actual->value.flt
  364. && range->value.range_int16[1] >= actual->value.flt);
  365. default:
  366. return FALSE;
  367. }
  368. }
  369. bool compareRangeOutFields(field* range, field* actual) {
  370. if(isFormalField(actual))
  371. return FALSE;
  372. switch(getFieldType(actual)) {
  373. case TYPE_UINT8_T:
  374. return (range->value.range_int16[0] >= actual->value.int8
  375. || range->value.range_int16[1] <= actual->value.int8);
  376. case TYPE_UINT16_T:
  377. return (range->value.range_int16[0] >= actual->value.int16
  378. || range->value.range_int16[1] <= actual->value.int16);
  379. case TYPE_FLOAT:
  380. return (range->value.range_int16[0] >= actual->value.flt
  381. || range->value.range_int16[1] <= actual->value.flt);
  382. default:
  383. return FALSE;
  384. }
  385. }
  386. bool compareFields(field *f1, field *f2) {
  387. fieldType fieldType1 = getFieldType(f1);
  388. fieldType fieldType2 = getFieldType(f2);
  389. if(fieldType1 == TYPE_DONT_CARE || fieldType2 == TYPE_DONT_CARE) {
  390. return TRUE;
  391. }
  392. // Range matching
  393. if(fieldType1 == TYPE_RANGE_IN) {
  394. return compareRangeFields(f1, f2);
  395. } else if(fieldType2 == TYPE_RANGE_IN) {
  396. return compareRangeFields(f2, f1);
  397. }
  398. // Range out matching
  399. if(fieldType1 == TYPE_RANGE_OUT) {
  400. return compareRangeOutFields(f1, f2);
  401. } else if(fieldType2 == TYPE_RANGE_OUT) {
  402. return compareRangeOutFields(f2, f1);
  403. }
  404. if(fieldType1 != fieldType2) {
  405. return FALSE;
  406. } else {
  407. if(isFormalField(f1) || isFormalField(f2)) {
  408. return TRUE;
  409. } else {
  410. switch(fieldType1) {
  411. case TYPE_UINT8_T:
  412. return (f1->value.int8 == f2->value.int8);
  413. case TYPE_UINT16_T:
  414. return (f1->value.int16 == f2->value.int16);
  415. case TYPE_UINT32_T:
  416. return (f1->value.int32 == f2->value.int32);
  417. case TYPE_FLOAT:
  418. return (f1->value.flt == f2->value.flt);
  419. case TYPE_CHAR:
  420. return (f1->value.c == f2->value.c);
  421. case TYPE_STR:
  422. return (strncmp(f1->value.str, f2->value.str, STR_SIZE) == 0);
  423. default:
  424. return FALSE;
  425. }
  426. }
  427. }
  428. }
  429. bool compareFreshness (tuple* templ, tuple* t, uint16_t localTime) {
  430. if (isEmptyTuple(t)) {
  431. return FALSE;
  432. } else if (templ->logicalTime == TIME_UNDEFINED) {
  433. return TRUE;
  434. } else if (localTime - t->logicalTime < templ->logicalTime) {
  435. return TRUE;
  436. } else {
  437. return FALSE;
  438. }
  439. }
  440. bool isTemplate(tuple* t) {
  441. uint8_t i;
  442. for(i=0; i < MAX_FIELDS; i++) {
  443. if (isFormalField(&(t->fields[i])) && !isEmptyField(&(t->fields[i]))) {
  444. return TRUE;
  445. }
  446. }
  447. return FALSE;
  448. }
  449. bool compareTuples(tuple *t1, tuple *t2, uint16_t localTime) {
  450. uint8_t i;
  451. // Comparing freshness
  452. if (!isCapabilityTuple(t1)
  453. &&isTemplate(t1)
  454. &&!compareFreshness(t1,t2,localTime)) {
  455. return FALSE;
  456. } else if (!isCapabilityTuple(t2)
  457. && isTemplate(t2)
  458. && !compareFreshness(t2,t1,localTime)) {
  459. return FALSE;
  460. }
  461. for(i=0; i < MAX_FIELDS; i++) {
  462. if(compareFields(&(t1->fields[i]), &(t2->fields[i])) == FALSE) {
  463. return FALSE;
  464. }
  465. }
  466. return TRUE;
  467. }