Esempio n. 1
0
/* Gets the escaped stringified version of an attribute list. 
 *
 * The string returned must be free()'d by the caller.
 *
 * If find_delta is set to true, only the attributes that have changed since 
 * the last serialize are updated.
 */
SLPError SLPAttrSerialize(SLPAttributes attr_h, size_t *count, char **str, SLPBoolean find_delta) {
	struct xx_SLPAttributes *slp_attr = (struct xx_SLPAttributes *)attr_h;
	var_t *var; /* For iterating. */
	unsigned int size; /* Size of the string to allocate. */
	unsigned int var_count; /* To count the number of variables. */
	char *build_str; /* The string that is being built. */
	char *cur; /* Current location within the already allocated str. */
	
	size = 0;
	var_count = 0;
	
	/***** Find the size of string needed for the attribute string. *****/
	for (var = slp_attr->attrs; var != NULL; var = var->next) {
		/*** Skip old attributes. ***/
		if (find_delta == SLP_TRUE && var->modified == SLP_FALSE) {
			continue;
		}
		
		/*** Get size of tag ***/
		size += var->tag_len;
		
		/*** Count the size needed for the value list ***/
		if (var->type != SLP_KEYWORD) {
			value_t *value;
		
			/** Get size of data **/
			value = var->list;
			while (value) {
				size += value->escaped_len;
				value = value->next;
			}
		
			/** Count number of commas needed for multivalued attributes. **/
			assert(var->list_size >= 0);
			size += (var->list_size - 1) * VAR_SEPARATOR_LEN;

			/** Count the semantics needed to store a multivalue list **/
			size += VAR_NON_KEYWORD_SEMANTIC_LEN;
		} else {
			assert(var->list == NULL);
		}
		
		/*** Count number of variables ***/
		var_count++;
	}

	/*** Count the number of characters between attributes. ***/
	if (var_count > 0) {
		size += (var_count - 1) * VAR_SEPARATOR_LEN;
	}
	
	/***** Create the string. *****/
	build_str = (char *)malloc( size + 1);
	if (build_str == NULL) {
		return SLP_MEMORY_ALLOC_FAILED;
	}
	build_str[0] = '\0';
	
	/***** Add values *****/
	cur = build_str;
	for (var = slp_attr->attrs; var != NULL; var = var->next) { 
		/*** Skip old attributes. ***/
		if (find_delta == SLP_TRUE && var->modified == SLP_FALSE) {
			continue;
		}

		if (var->type == SLP_KEYWORD) {
			/**** Handle keywords. ****/
			strcpy(cur, var->tag);
			cur += var->tag_len;
		} else {
			/**** Handle everything else. ****/
			char *to_add;
			size_t to_add_len;
			value_t *value;
		
			/*** Add the prefix. ***/
			strcpy(cur, VAR_PREFIX);
			cur += VAR_PREFIX_LEN;
		
			/*** Add the tag. ***/
			strcpy(cur, var->tag);
			cur += var->tag_len;
		
			/*** Add the infix. ***/
			strcpy(cur, VAR_INFIX);
			cur += VAR_INFIX_LEN;
			
			/*** Insert value (list) ***/
			value = var->list;
			assert(value);
			while (value) { /* foreach member value of an attribute. */
				assert(var->type != SLP_KEYWORD);
				switch(var->type) {
					case(SLP_BOOLEAN):
						assert(value->next == NULL); /* Can't be a multivalued list. */
						assert(value->data.va_bool == SLP_TRUE 
								|| value->data.va_bool == SLP_FALSE);

						if (value->data.va_bool == SLP_TRUE) {
							to_add = BOOL_TRUE_STR;
							to_add_len = BOOL_TRUE_STR_LEN;
						} else {
							to_add = BOOL_FALSE_STR;
							to_add_len = BOOL_FALSE_STR_LEN;
						}
						strcpy(cur, to_add);
						cur += to_add_len;

						break;
					case(SLP_STRING):
						cur = escape_into(cur, value->data.va_str, -1);
						break;
					case(SLP_INTEGER):
						sprintf(cur, "%ld", value->data.va_int);
						cur += value->escaped_len;
						break;
					case(SLP_OPAQUE):
						strcpy(cur, OPAQUE_PREFIX);
						cur += OPAQUE_PREFIX_LEN;
						cur = escape_opaque_into(cur, value->data.va_str, value->unescaped_len);
						break;
					default:
						printf("Unknown type (%s:%d).\n", __FILE__, __LINE__);
						return SLP_INTERNAL_SYSTEM_ERROR;
				}
				
				value = value->next;
				/*** Add separator (if necessary) ***/
				if (value != NULL) {
					strcpy(cur, VAR_SEPARATOR);
					cur += VAR_SEPARATOR_LEN;
				}	
			}

			/*** Add the suffix. ***/
			strcpy(cur, VAR_SUFFIX);
			cur += VAR_SUFFIX_LEN;
		}

		/*** Add separator (if necessary) ***/
		if (var->next != NULL) {
			strcpy(cur, VAR_SEPARATOR);
			cur += VAR_SEPARATOR_LEN;
		}
			
		/*** Reset the modified flag. ***/
		var->modified = SLP_FALSE;
	}

	assert((cur - build_str) == size && size == strlen(build_str));

	/***** Append a null (This is actually done by strcpy, but its better to
	 * be safe than sorry =) *****/
	*cur = '\0';
	
	*str = build_str;
	return SLP_OK;
}	
Esempio n. 2
0
static netdev_tx_t ieee802154_xbee_xmit(struct sk_buff *skb,
					      struct net_device *dev)
{
	struct ieee802154_mac_cb* cb;

	int framelen, datalen;
	char *frame;
	
	struct xbee_priv *priv = netdev_priv(dev);
	
	struct xbee_tx_header header = {
		.length = 0x00,
		.api_id = 0x00,
		.frame_id = 0x02,
		.options = 0x04
	};

        dev->stats.tx_packets++;
        dev->stats.tx_bytes += skb->len;

		
	if(main_tty == NULL) {
		printk(KERN_ALERT "No tty attached!\nMake sure ldisc_daemon is running\n");
		return 0;
	}
		
	printk(KERN_ALERT "[NET tx called, %d bytes in sk_buff, pkt type %hu, protocol %hu]\n", skb->len, skb->pkt_type, skb->protocol);
   
	cb = mac_cb(skb);	
 
	//header.address = cpu_to_be64(0x000000000000FFFF); // So far broadcast

	header.address = cpu_to_be64p( (__be64*) &(cb->dest.extended_addr) );
	
	printk(KERN_ALERT "MAC DST addr %llx\n", cb->dest.extended_addr);

	header.length = cpu_to_be16(skb->len + 1 + 10);
    	datalen = skb->len + 1;

	// Allocate buffer to hold entire serial frame, including start byte and checksum
	frame = kmalloc(sizeof(struct xbee_tx_header) + (2*datalen) + 2, GFP_KERNEL);

	/* Assemble the frame */
    
	/* Escaping the XBee header */
    	printk(KERN_ALERT "Adding XBEE header- length is %lu\n", sizeof(header) + 1);
	framelen = escape_into((frame + 1), &header, sizeof(header));
    
    	printk(KERN_ALERT "Adding data - length is %u\n", datalen);
	framelen += escape_into((frame + framelen + 1 ), (skb->data), datalen );

	framelen++; // Checksum char at the beginning
	
	/* save the timestamp */
	dev->trans_start = jiffies; 
	
	//Stop the interface from sending more data, get the spinlock, and send it!
	netif_stop_queue(dev);
	
	spin_lock(&priv->lock);
	
	xbee_hw_tx(frame, framelen, dev);
	
	//Free the skbuff, we've copied all the data out
	dev_kfree_skb(skb);

	spin_unlock(&priv->lock);	

	return NETDEV_TX_OK;
}



/*
 * Copies bytes from one array into another, escaping them if necessary.
 * Returns the size of the new array, including character escapes.
 * The destination array MUST be at least twice the size of the source
 */
static int escape_into(char *dest, const void *srcarray, int len) {
	int i, j=0;
	
	const char *src = srcarray;
	
	for(i=0; i<len; i++) {
		char unesc = *(src + i);
		// We support API mode 1 (escape characters is for API 2, if we want to enable mode 2 we need to implement escape management at RX)
		if( unesc == 0x7D || unesc == 0x7E || unesc == 0x11 || unesc == 0x13) {
			dest[j] = 0x7D;
			dest[j+1] = unesc ^ 0x20;
			j+=2;
		} else {
			dest[j] = unesc;
			j++;
		}	
	}
	return j;
}