1 /*********************************************************************
3 * Filename: irias_object.c
5 * Description: IAS object database and functions
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Thu Oct 1 22:50:04 1998
9 * Modified at: Wed Dec 15 11:23:16 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
12 * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
19 * Neither Dag Brattli nor University of Tromsø admit liability nor
20 * provide warranty for any of this software. This material is
21 * provided "AS-IS" and at no charge.
23 ********************************************************************/
25 #include <linux/string.h>
26 #include <linux/socket.h>
28 #include <net/irda/irda.h>
29 #include <net/irda/irmod.h>
30 #include <net/irda/irias_object.h>
32 hashbin_t
*objects
= NULL
;
35 * Used when a missing value needs to be returned
37 struct ias_value missing
= { IAS_MISSING
, 0, 0, {0}};
40 * Function strdup (str)
42 * My own kernel version of strdup!
45 char *strdup(char *str
)
52 ASSERT(strlen( str
) < 64, return NULL
;);
54 new_str
= kmalloc(strlen(str
)+1, GFP_ATOMIC
);
64 * Function ias_new_object (name, id)
66 * Create a new IAS object
69 struct ias_object
*irias_new_object( char *name
, int id
)
71 struct ias_object
*obj
;
73 IRDA_DEBUG( 4, __FUNCTION__
"()\n");
75 obj
= (struct ias_object
*) kmalloc(sizeof(struct ias_object
),
78 IRDA_DEBUG(0, __FUNCTION__
"(), Unable to allocate object!\n");
81 memset(obj
, 0, sizeof( struct ias_object
));
83 obj
->magic
= IAS_OBJECT_MAGIC
;
84 obj
->name
= strdup( name
);
87 obj
->attribs
= hashbin_new(HB_LOCAL
);
93 * Function irias_delete_attrib (attrib)
95 * Delete given attribute and deallocate all its memory
98 void __irias_delete_attrib(struct ias_attrib
*attrib
)
100 ASSERT(attrib
!= NULL
, return;);
101 ASSERT(attrib
->magic
== IAS_ATTRIB_MAGIC
, return;);
106 irias_delete_value(attrib
->value
);
107 attrib
->magic
= ~IAS_ATTRIB_MAGIC
;
112 void __irias_delete_object(struct ias_object
*obj
)
114 ASSERT(obj
!= NULL
, return;);
115 ASSERT(obj
->magic
== IAS_OBJECT_MAGIC
, return;);
120 hashbin_delete(obj
->attribs
, (FREE_FUNC
) __irias_delete_attrib
);
122 obj
->magic
= ~IAS_OBJECT_MAGIC
;
128 * Function irias_delete_object (obj)
130 * Remove object from hashbin and deallocate all attributes assosiated with
131 * with this object and the object itself
134 int irias_delete_object(struct ias_object
*obj
)
136 struct ias_object
*node
;
138 ASSERT(obj
!= NULL
, return -1;);
139 ASSERT(obj
->magic
== IAS_OBJECT_MAGIC
, return -1;);
141 node
= hashbin_remove(objects
, 0, obj
->name
);
143 return 0; /* Already removed */
145 __irias_delete_object(node
);
151 * Function irias_delete_attrib (obj)
153 * Remove attribute from hashbin and, if it was the last attribute of
154 * the object, remove the object as well.
157 int irias_delete_attrib(struct ias_object
*obj
, struct ias_attrib
*attrib
)
159 struct ias_attrib
*node
;
161 ASSERT(obj
!= NULL
, return -1;);
162 ASSERT(obj
->magic
== IAS_OBJECT_MAGIC
, return -1;);
163 ASSERT(attrib
!= NULL
, return -1;);
165 /* Remove atribute from object */
166 node
= hashbin_remove(obj
->attribs
, 0, attrib
->name
);
168 return 0; /* Already removed or non-existent */
170 /* Deallocate attribute */
171 __irias_delete_attrib(node
);
173 /* Check if object has still some attributes */
174 node
= (struct ias_attrib
*) hashbin_get_first(obj
->attribs
);
176 irias_delete_object(obj
);
182 * Function irias_insert_object (obj)
184 * Insert an object into the LM-IAS database
187 void irias_insert_object(struct ias_object
*obj
)
189 ASSERT(obj
!= NULL
, return;);
190 ASSERT(obj
->magic
== IAS_OBJECT_MAGIC
, return;);
192 hashbin_insert(objects
, (irda_queue_t
*) obj
, 0, obj
->name
);
196 * Function irias_find_object (name)
198 * Find object with given name
201 struct ias_object
*irias_find_object(char *name
)
203 ASSERT(name
!= NULL
, return NULL
;);
205 return hashbin_find(objects
, 0, name
);
209 * Function irias_find_attrib (obj, name)
211 * Find named attribute in object
214 struct ias_attrib
*irias_find_attrib(struct ias_object
*obj
, char *name
)
216 struct ias_attrib
*attrib
;
218 ASSERT(obj
!= NULL
, return NULL
;);
219 ASSERT(obj
->magic
== IAS_OBJECT_MAGIC
, return NULL
;);
220 ASSERT(name
!= NULL
, return NULL
;);
222 attrib
= hashbin_find(obj
->attribs
, 0, name
);
230 * Function irias_add_attribute (obj, attrib)
232 * Add attribute to object
235 void irias_add_attrib( struct ias_object
*obj
, struct ias_attrib
*attrib
,
238 ASSERT(obj
!= NULL
, return;);
239 ASSERT(obj
->magic
== IAS_OBJECT_MAGIC
, return;);
241 ASSERT(attrib
!= NULL
, return;);
242 ASSERT(attrib
->magic
== IAS_ATTRIB_MAGIC
, return;);
244 /* Set if attrib is owned by kernel or user space */
245 attrib
->value
->owner
= owner
;
247 hashbin_insert(obj
->attribs
, (irda_queue_t
*) attrib
, 0, attrib
->name
);
251 * Function irias_object_change_attribute (obj_name, attrib_name, new_value)
253 * Change the value of an objects attribute.
256 int irias_object_change_attribute(char *obj_name
, char *attrib_name
,
257 struct ias_value
*new_value
)
259 struct ias_object
*obj
;
260 struct ias_attrib
*attrib
;
263 obj
= hashbin_find(objects
, 0, obj_name
);
265 WARNING(__FUNCTION__
"(), Unable to find object: %s\n",
271 attrib
= hashbin_find(obj
->attribs
, 0, attrib_name
);
272 if (attrib
== NULL
) {
273 WARNING(__FUNCTION__
"(), Unable to find attribute: %s\n",
278 if ( attrib
->value
->type
!= new_value
->type
) {
279 IRDA_DEBUG( 0, __FUNCTION__
280 "(), changing value type not allowed!\n");
284 /* Delete old value */
285 irias_delete_value(attrib
->value
);
287 /* Insert new value */
288 attrib
->value
= new_value
;
295 * Function irias_object_add_integer_attrib (obj, name, value)
297 * Add an integer attribute to an LM-IAS object
300 void irias_add_integer_attrib(struct ias_object
*obj
, char *name
, int value
,
303 struct ias_attrib
*attrib
;
305 ASSERT(obj
!= NULL
, return;);
306 ASSERT(obj
->magic
== IAS_OBJECT_MAGIC
, return;);
307 ASSERT(name
!= NULL
, return;);
309 attrib
= (struct ias_attrib
*) kmalloc(sizeof(struct ias_attrib
),
311 if (attrib
== NULL
) {
312 WARNING(__FUNCTION__
"(), Unable to allocate attribute!\n");
315 memset(attrib
, 0, sizeof( struct ias_attrib
));
317 attrib
->magic
= IAS_ATTRIB_MAGIC
;
318 attrib
->name
= strdup(name
);
321 attrib
->value
= irias_new_integer_value(value
);
323 irias_add_attrib(obj
, attrib
, owner
);
327 * Function irias_add_octseq_attrib (obj, name, octet_seq, len)
329 * Add a octet sequence attribute to an LM-IAS object
333 void irias_add_octseq_attrib(struct ias_object
*obj
, char *name
, __u8
*octets
,
336 struct ias_attrib
*attrib
;
338 ASSERT(obj
!= NULL
, return;);
339 ASSERT(obj
->magic
== IAS_OBJECT_MAGIC
, return;);
341 ASSERT(name
!= NULL
, return;);
342 ASSERT(octets
!= NULL
, return;);
344 attrib
= (struct ias_attrib
*) kmalloc(sizeof(struct ias_attrib
),
346 if (attrib
== NULL
) {
348 "(), Unable to allocate attribute!\n");
351 memset(attrib
, 0, sizeof( struct ias_attrib
));
353 attrib
->magic
= IAS_ATTRIB_MAGIC
;
354 attrib
->name
= strdup( name
);
356 attrib
->value
= irias_new_octseq_value( octets
, len
);
358 irias_add_attrib(obj
, attrib
, owner
);
362 * Function irias_object_add_string_attrib (obj, string)
364 * Add a string attribute to an LM-IAS object
367 void irias_add_string_attrib(struct ias_object
*obj
, char *name
, char *value
,
370 struct ias_attrib
*attrib
;
372 ASSERT(obj
!= NULL
, return;);
373 ASSERT(obj
->magic
== IAS_OBJECT_MAGIC
, return;);
375 ASSERT(name
!= NULL
, return;);
376 ASSERT(value
!= NULL
, return;);
378 attrib
= (struct ias_attrib
*) kmalloc(sizeof( struct ias_attrib
),
380 if (attrib
== NULL
) {
381 WARNING(__FUNCTION__
"(), Unable to allocate attribute!\n");
384 memset(attrib
, 0, sizeof( struct ias_attrib
));
386 attrib
->magic
= IAS_ATTRIB_MAGIC
;
387 attrib
->name
= strdup(name
);
389 attrib
->value
= irias_new_string_value(value
);
391 irias_add_attrib(obj
, attrib
, owner
);
395 * Function irias_new_integer_value (integer)
397 * Create new IAS integer value
400 struct ias_value
*irias_new_integer_value(int integer
)
402 struct ias_value
*value
;
404 value
= kmalloc(sizeof(struct ias_value
), GFP_ATOMIC
);
406 WARNING(__FUNCTION__
"(), Unable to kmalloc!\n");
409 memset(value
, 0, sizeof(struct ias_value
));
411 value
->type
= IAS_INTEGER
;
413 value
->t
.integer
= integer
;
419 * Function irias_new_string_value (string)
421 * Create new IAS string value
424 struct ias_value
*irias_new_string_value(char *string
)
426 struct ias_value
*value
;
428 value
= kmalloc(sizeof(struct ias_value
), GFP_ATOMIC
);
430 WARNING(__FUNCTION__
"(), Unable to kmalloc!\n");
433 memset( value
, 0, sizeof( struct ias_value
));
435 value
->type
= IAS_STRING
;
436 value
->charset
= CS_ASCII
;
437 value
->len
= strlen(string
);
438 value
->t
.string
= strdup(string
);
445 * Function irias_new_octseq_value (octets, len)
447 * Create new IAS octet-sequence value
450 struct ias_value
*irias_new_octseq_value(__u8
*octseq
, int len
)
452 struct ias_value
*value
;
454 value
= kmalloc(sizeof(struct ias_value
), GFP_ATOMIC
);
456 WARNING(__FUNCTION__
"(), Unable to kmalloc!\n");
459 memset(value
, 0, sizeof(struct ias_value
));
461 value
->type
= IAS_OCT_SEQ
;
464 value
->t
.oct_seq
= kmalloc(len
, GFP_ATOMIC
);
465 if (value
->t
.oct_seq
== NULL
){
466 WARNING(__FUNCTION__
"(), Unable to kmalloc!\n");
469 memcpy(value
->t
.oct_seq
, octseq
, len
);
473 struct ias_value
*irias_new_missing_value(void)
475 struct ias_value
*value
;
477 value
= kmalloc(sizeof(struct ias_value
), GFP_ATOMIC
);
479 WARNING(__FUNCTION__
"(), Unable to kmalloc!\n");
482 memset(value
, 0, sizeof(struct ias_value
));
484 value
->type
= IAS_MISSING
;
491 * Function irias_delete_value (value)
496 void irias_delete_value(struct ias_value
*value
)
498 IRDA_DEBUG(4, __FUNCTION__
"()\n");
500 ASSERT(value
!= NULL
, return;);
502 switch (value
->type
) {
503 case IAS_INTEGER
: /* Fallthrough */
505 /* No need to deallocate */
508 /* If string, deallocate string */
509 if (value
->t
.string
!= NULL
)
510 kfree(value
->t
.string
);
513 /* If byte stream, deallocate byte stream */
514 if (value
->t
.oct_seq
!= NULL
)
515 kfree(value
->t
.oct_seq
);
518 IRDA_DEBUG(0, __FUNCTION__
"(), Unknown value type!\n");