File: /usr/src/linux/net/irda/irias_object.c

1     /*********************************************************************
2      *                
3      * Filename:      irias_object.c
4      * Version:       0.3
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>
11      * 
12      *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
13      *      
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.
18      *  
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.
22      *     
23      ********************************************************************/
24     
25     #include <linux/string.h>
26     #include <linux/socket.h>
27     
28     #include <net/irda/irda.h>
29     #include <net/irda/irmod.h>
30     #include <net/irda/irias_object.h>
31     
32     hashbin_t *objects = NULL;
33     
34     /*
35      *  Used when a missing value needs to be returned
36      */
37     struct ias_value missing = { IAS_MISSING, 0, 0, 0, {0}};
38     
39     /*
40      * Function strndup (str, max)
41      *
42      *    My own kernel version of strndup!
43      *
44      * Faster, check boundary... Jean II
45      */
46     char *strndup(char *str, int max)
47     {
48     	char *new_str;
49     	int len;
50     	
51     	/* Check string */
52     	if (str == NULL)
53     		return NULL;
54     	/* Check length, truncate */
55     	len = strlen(str);
56     	if(len > max)
57     		len = max;
58     
59     	/* Allocate new string */
60             new_str = kmalloc(len + 1, GFP_ATOMIC);
61             if (new_str == NULL) {
62     		WARNING(__FUNCTION__"(), Unable to kmalloc!\n");
63     		return NULL;
64     	}
65     
66     	/* Copy and truncate */
67     	memcpy(new_str, str, len);
68     	new_str[len] = '\0';
69     	
70     	return new_str;
71     }
72     
73     /*
74      * Function ias_new_object (name, id)
75      *
76      *    Create a new IAS object
77      *
78      */
79     struct ias_object *irias_new_object( char *name, int id)
80     {
81             struct ias_object *obj;
82     	
83     	IRDA_DEBUG( 4, __FUNCTION__ "()\n");
84     
85     	obj = (struct ias_object *) kmalloc(sizeof(struct ias_object), 
86     					    GFP_ATOMIC);
87     	if (obj == NULL) {
88     		IRDA_DEBUG(0, __FUNCTION__ "(), Unable to allocate object!\n");
89     		return NULL;
90     	}
91     	memset(obj, 0, sizeof( struct ias_object));
92     
93     	obj->magic = IAS_OBJECT_MAGIC;
94     	obj->name = strndup(name, IAS_MAX_CLASSNAME);
95     	obj->id = id;
96     
97     	obj->attribs = hashbin_new(HB_LOCAL);
98     	
99     	return obj;
100     }
101     
102     /*
103      * Function irias_delete_attrib (attrib)
104      *
105      *    Delete given attribute and deallocate all its memory
106      *
107      */
108     void __irias_delete_attrib(struct ias_attrib *attrib)
109     {
110     	ASSERT(attrib != NULL, return;);
111     	ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
112     
113     	if (attrib->name)
114     		kfree(attrib->name);
115     
116     	irias_delete_value(attrib->value);
117     	attrib->magic = ~IAS_ATTRIB_MAGIC;
118     	
119     	kfree(attrib);
120     }
121     
122     void __irias_delete_object(struct ias_object *obj)
123     {
124     	ASSERT(obj != NULL, return;);
125     	ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
126     
127     	if (obj->name)
128     		kfree(obj->name);
129     	
130     	hashbin_delete(obj->attribs, (FREE_FUNC) __irias_delete_attrib);
131     	
132     	obj->magic = ~IAS_OBJECT_MAGIC;
133     	
134     	kfree(obj);
135     }
136     
137     /*
138      * Function irias_delete_object (obj)
139      *
140      *    Remove object from hashbin and deallocate all attributes assosiated with
141      *    with this object and the object itself
142      *
143      */
144     int irias_delete_object(struct ias_object *obj) 
145     {
146     	struct ias_object *node;
147     
148     	ASSERT(obj != NULL, return -1;);
149     	ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;);
150     
151     	node = hashbin_remove(objects, 0, obj->name);
152     	if (!node)
153     		return 0; /* Already removed */
154     
155     	__irias_delete_object(node);
156     
157     	return 0;
158     }
159     
160     /*
161      * Function irias_delete_attrib (obj)
162      *
163      *    Remove attribute from hashbin and, if it was the last attribute of
164      *    the object, remove the object as well.
165      *
166      */
167     int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib) 
168     {
169     	struct ias_attrib *node;
170     
171     	ASSERT(obj != NULL, return -1;);
172     	ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;);
173     	ASSERT(attrib != NULL, return -1;);
174     
175     	/* Remove attribute from object */
176     	node = hashbin_remove(obj->attribs, 0, attrib->name);
177     	if (!node)
178     		return 0; /* Already removed or non-existent */
179     
180     	/* Deallocate attribute */
181     	__irias_delete_attrib(node);
182     
183     	/* Check if object has still some attributes */
184     	node = (struct ias_attrib *) hashbin_get_first(obj->attribs);
185     	if (!node)
186     		irias_delete_object(obj);
187     
188     	return 0;
189     }
190     
191     /*
192      * Function irias_insert_object (obj)
193      *
194      *    Insert an object into the LM-IAS database
195      *
196      */
197     void irias_insert_object(struct ias_object *obj)
198     {
199     	ASSERT(obj != NULL, return;);
200     	ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
201     	
202     	hashbin_insert(objects, (irda_queue_t *) obj, 0, obj->name);
203     }
204     
205     /*
206      * Function irias_find_object (name)
207      *
208      *    Find object with given name
209      *
210      */
211     struct ias_object *irias_find_object(char *name)
212     {
213     	ASSERT(name != NULL, return NULL;);
214     
215     	return hashbin_find(objects, 0, name);
216     }
217     
218     /*
219      * Function irias_find_attrib (obj, name)
220      *
221      *    Find named attribute in object
222      *
223      */
224     struct ias_attrib *irias_find_attrib(struct ias_object *obj, char *name)
225     {
226     	struct ias_attrib *attrib;
227     
228     	ASSERT(obj != NULL, return NULL;);
229     	ASSERT(obj->magic == IAS_OBJECT_MAGIC, return NULL;);
230     	ASSERT(name != NULL, return NULL;);
231     
232     	attrib = hashbin_find(obj->attribs, 0, name);
233     	if (attrib == NULL)
234     		return NULL;
235     
236     	return attrib;
237     }
238     
239     /*
240      * Function irias_add_attribute (obj, attrib)
241      *
242      *    Add attribute to object
243      *
244      */
245     void irias_add_attrib( struct ias_object *obj, struct ias_attrib *attrib,
246     		       int owner)
247     {
248     	ASSERT(obj != NULL, return;);
249     	ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
250     	
251     	ASSERT(attrib != NULL, return;);
252     	ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
253     
254     	/* Set if attrib is owned by kernel or user space */
255     	attrib->value->owner = owner;
256     
257     	hashbin_insert(obj->attribs, (irda_queue_t *) attrib, 0, attrib->name);
258     }
259     
260     /*
261      * Function irias_object_change_attribute (obj_name, attrib_name, new_value)
262      *
263      *    Change the value of an objects attribute.
264      *
265      */
266     int irias_object_change_attribute(char *obj_name, char *attrib_name, 
267     				  struct ias_value *new_value) 
268     {
269     	struct ias_object *obj;
270     	struct ias_attrib *attrib;
271     
272     	/* Find object */
273     	obj = hashbin_find(objects, 0, obj_name);
274     	if (obj == NULL) {
275     		WARNING(__FUNCTION__ "(), Unable to find object: %s\n",
276     			obj_name);
277     		return -1;
278     	}
279     
280     	/* Find attribute */
281     	attrib = hashbin_find(obj->attribs, 0, attrib_name);
282     	if (attrib == NULL) {
283     		WARNING(__FUNCTION__ "(), Unable to find attribute: %s\n",
284     			attrib_name);
285     		return -1;
286     	}
287     	
288     	if ( attrib->value->type != new_value->type) {
289     		IRDA_DEBUG( 0, __FUNCTION__ 
290     		       "(), changing value type not allowed!\n");
291     		return -1;
292     	}
293     
294     	/* Delete old value */
295     	irias_delete_value(attrib->value);
296     	
297     	/* Insert new value */
298     	attrib->value = new_value;
299     
300     	/* Success */
301     	return 0;
302     }
303     
304     /*
305      * Function irias_object_add_integer_attrib (obj, name, value)
306      *
307      *    Add an integer attribute to an LM-IAS object
308      *
309      */
310     void irias_add_integer_attrib(struct ias_object *obj, char *name, int value,
311     			      int owner)
312     {
313     	struct ias_attrib *attrib;
314     
315     	ASSERT(obj != NULL, return;);
316     	ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
317     	ASSERT(name != NULL, return;);
318     	
319     	attrib = (struct ias_attrib *) kmalloc(sizeof(struct ias_attrib), 
320     					       GFP_ATOMIC);
321     	if (attrib == NULL) {
322     		WARNING(__FUNCTION__ "(), Unable to allocate attribute!\n");
323     		return;
324     	}
325     	memset(attrib, 0, sizeof( struct ias_attrib));
326     
327     	attrib->magic = IAS_ATTRIB_MAGIC;
328     	attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
329     
330     	/* Insert value */
331     	attrib->value = irias_new_integer_value(value);
332     	
333     	irias_add_attrib(obj, attrib, owner);
334     }
335     
336      /*
337      * Function irias_add_octseq_attrib (obj, name, octet_seq, len)
338      *
339      *    Add a octet sequence attribute to an LM-IAS object
340      *
341      */
342     
343     void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets,
344     			     int len, int owner)
345     {
346     	struct ias_attrib *attrib;
347     	
348     	ASSERT(obj != NULL, return;);
349     	ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
350     	
351     	ASSERT(name != NULL, return;);
352     	ASSERT(octets != NULL, return;);
353     	
354     	attrib = (struct ias_attrib *) kmalloc(sizeof(struct ias_attrib), 
355     					       GFP_ATOMIC);
356     	if (attrib == NULL) {
357     		WARNING(__FUNCTION__ 
358     			"(), Unable to allocate attribute!\n");
359     		return;
360     	}
361     	memset(attrib, 0, sizeof( struct ias_attrib));
362     	
363     	attrib->magic = IAS_ATTRIB_MAGIC;
364     	attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
365     	
366     	attrib->value = irias_new_octseq_value( octets, len);
367     	
368     	irias_add_attrib(obj, attrib, owner);
369     }
370     
371     /*
372      * Function irias_object_add_string_attrib (obj, string)
373      *
374      *    Add a string attribute to an LM-IAS object
375      *
376      */
377     void irias_add_string_attrib(struct ias_object *obj, char *name, char *value,
378     			     int owner)
379     {
380     	struct ias_attrib *attrib;
381     
382     	ASSERT(obj != NULL, return;);
383     	ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
384     
385     	ASSERT(name != NULL, return;);
386     	ASSERT(value != NULL, return;);
387     	
388     	attrib = (struct ias_attrib *) kmalloc(sizeof( struct ias_attrib), 
389     					       GFP_ATOMIC);
390     	if (attrib == NULL) {
391     		WARNING(__FUNCTION__ "(), Unable to allocate attribute!\n");
392     		return;
393     	}
394     	memset(attrib, 0, sizeof( struct ias_attrib));
395     
396     	attrib->magic = IAS_ATTRIB_MAGIC;
397     	attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
398     
399     	attrib->value = irias_new_string_value(value);
400     
401     	irias_add_attrib(obj, attrib, owner);
402     }
403     
404     /*
405      * Function irias_new_integer_value (integer)
406      *
407      *    Create new IAS integer value
408      *
409      */
410     struct ias_value *irias_new_integer_value(int integer)
411     {
412     	struct ias_value *value;
413     
414     	value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
415     	if (value == NULL) {
416     		WARNING(__FUNCTION__ "(), Unable to kmalloc!\n");
417     		return NULL;
418     	}
419     	memset(value, 0, sizeof(struct ias_value));
420     
421     	value->type = IAS_INTEGER;
422     	value->len = 4;
423     	value->t.integer = integer;
424     
425     	return value;
426     }
427     
428     /*
429      * Function irias_new_string_value (string)
430      *
431      *    Create new IAS string value
432      *
433      * Per IrLMP 1.1, 4.3.3.2, strings are up to 256 chars - Jean II
434      */
435     struct ias_value *irias_new_string_value(char *string)
436     {
437     	struct ias_value *value;
438     	int len;
439     	char *new_str;
440     
441     	value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
442     	if (value == NULL) {
443     		WARNING(__FUNCTION__ "(), Unable to kmalloc!\n");
444     		return NULL;
445     	}
446     	memset( value, 0, sizeof( struct ias_value));
447     
448     	value->type = IAS_STRING;
449     	value->charset = CS_ASCII;
450     	value->t.string = strndup(string, IAS_MAX_STRING);
451     	value->len = strlen(value->t.string);
452     
453     	return value;
454     }
455     
456     
457     /*
458      * Function irias_new_octseq_value (octets, len)
459      *
460      *    Create new IAS octet-sequence value
461      *
462      * Per IrLMP 1.1, 4.3.3.2, octet-sequence are up to 1024 bytes - Jean II
463      */
464     struct ias_value *irias_new_octseq_value(__u8 *octseq , int len)
465     {
466     	struct ias_value *value;
467     
468     	value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
469     	if (value == NULL) {
470     		WARNING(__FUNCTION__ "(), Unable to kmalloc!\n");
471     		return NULL;
472     	}
473     	memset(value, 0, sizeof(struct ias_value));
474     
475     	value->type = IAS_OCT_SEQ;
476     	/* Check length */
477     	if(len > IAS_MAX_OCTET_STRING)
478     		len = IAS_MAX_OCTET_STRING;
479     	value->len = len;
480     
481     	value->t.oct_seq = kmalloc(len, GFP_ATOMIC);
482     	if (value->t.oct_seq == NULL){
483     		WARNING(__FUNCTION__"(), Unable to kmalloc!\n");
484     		kfree(value);
485     		return NULL;
486     	}
487     	memcpy(value->t.oct_seq, octseq , len);
488     	return value;
489     }
490     
491     struct ias_value *irias_new_missing_value(void)
492     {
493     	struct ias_value *value;
494     
495     	value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
496     	if (value == NULL) {
497     		WARNING(__FUNCTION__ "(), Unable to kmalloc!\n");
498     		return NULL;
499     	}
500     	memset(value, 0, sizeof(struct ias_value));
501     
502     	value->type = IAS_MISSING;
503     	value->len = 0;
504     
505     	return value;
506     }
507     
508     /*
509      * Function irias_delete_value (value)
510      *
511      *    Delete IAS value
512      *
513      */
514     void irias_delete_value(struct ias_value *value)
515     {
516     	IRDA_DEBUG(4, __FUNCTION__ "()\n");
517     
518     	ASSERT(value != NULL, return;);
519     
520     	switch (value->type) {
521     	case IAS_INTEGER: /* Fallthrough */
522     	case IAS_MISSING:
523     		/* No need to deallocate */
524     		break;
525     	case IAS_STRING:
526     		/* If string, deallocate string */
527     		if (value->t.string != NULL)
528     			kfree(value->t.string);
529     		break;
530     	case IAS_OCT_SEQ:
531     		/* If byte stream, deallocate byte stream */
532     		 if (value->t.oct_seq != NULL)
533     			 kfree(value->t.oct_seq);
534     		 break;
535     	default:
536     		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown value type!\n");
537     		break;
538     	}
539     	kfree(value);
540     }
541     
542     
543     
544