diff --git a/src/capwap/cw_in_wtp_descriptor.c b/src/capwap/cw_in_wtp_descriptor.c
new file mode 100644
index 00000000..04eae57f
--- /dev/null
+++ b/src/capwap/cw_in_wtp_descriptor.c
@@ -0,0 +1,111 @@
+/*
+ This file is part of libcapwap.
+
+ libcapwap is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ libcapwap is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Foobar. If not, see .
+
+*/
+
+
+#include "capwap.h"
+#include "capwap_items.h"
+
+#include "wtpinfo.h"
+
+#include "cw_util.h"
+#include "cw_log.h"
+
+
+
+
+static int readelem_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8_t *data, int len, int cq)
+{
+
+ if (len<6)
+ return -1;
+
+ cw_itemstore_t itemstore = conn->itemstore;
+
+ cw_itemstore_set_byte(itemstore,CW_ITEM_WTP_MAX_RADIOS,cw_get_byte(data));
+ cw_itemstore_set_byte(itemstore,CW_ITEM_WTP_RADIOS_IN_USE,cw_get_byte(data+1));
+
+ int ncrypt = cw_get_byte(data+2);
+ int i;
+ if (ncrypt == 0 ){
+ /* non-conform */
+ cw_dbg(DBG_CW_RFC,"Non-standard-conform WTP descriptor detected (See RFC 5415)");
+ if (!cq)
+ i=3;
+ else
+ i=4;
+ }
+ else{
+ i=ncrypt*3+3;
+ }
+
+ do {
+ if (i+8>len)
+ {
+ cw_dbg(DBG_ELEM_ERR,"WTP descriptor subelement to long, length=%d>%d",i+8,len);
+ return -1;
+ }
+
+ uint32_t vendor_id=cw_get_dword(data+i); //ntohl(*((uint32_t*)(msgelem+i)));
+
+ uint32_t val = cw_get_dword(data+i+4);
+ int subtype= (val>>16)&0xffff;
+ int sublen = val&0xffff;
+ i+=8;
+
+ if (sublen+i>len){
+ cw_dbg(DBG_ELEM_ERR,"WTP descriptor subelement too long, length = %d",sublen);
+ return -1;
+ }
+
+ cw_dbg(DBG_ELEM,"Reading WTP descriptor subelement, type=%d,len=%d",subtype,sublen);
+
+ switch(subtype){
+ case CW_SUBELEM_WTP_HARDWARE_VERSION:
+ cw_itemstore_set_dword(itemstore,CW_ITEM_WTP_HARDWARE_VENDOR,vendor_id);
+ cw_itemstore_set_bstrn(itemstore,CW_ITEM_WTP_HARDWARE_VERSION,data+i,sublen);
+ break;
+ case CW_SUBELEM_WTP_SOFTWARE_VERSION:
+ cw_itemstore_set_dword(itemstore,CW_ITEM_WTP_SOFTWARE_VENDOR,vendor_id);
+ cw_itemstore_set_bstrn(itemstore,CW_ITEM_WTP_SOFTWARE_VERSION,data+i,sublen);
+ break;
+ case CW_SUBELEM_WTP_BOOTLOADER_VERSION:
+ cw_itemstore_set_dword(itemstore,CW_ITEM_WTP_BOOTLOADER_VENDOR,vendor_id);
+ cw_itemstore_set_bstrn(itemstore,CW_ITEM_WTP_BOOTLOADER_VERSION,data+i,sublen);
+ break;
+ default:
+ cw_dbg(DBG_ELEM_ERR,"Unknown WTP descriptor subelement, type = %d",subtype);
+ break;
+ }
+ i+=sublen;
+
+ }while(iresp_buffer;
+ int hbytes = cw_get_hdr_msg_offset(req);
+ memcpy(buffer,req,hbytes);
+
+ uint8_t * msgptr = req+hbytes;
+ uint8_t * dmsgptr = buffer+hbytes;
+
+ cw_set_msg_type(dmsgptr,cw_get_msg_type(msgptr)+1);
+ cw_set_msg_seqnum(dmsgptr,cw_get_msg_seqnum(msgptr));
+ cw_set_msg_flags(dmsgptr,0);
+
+
+}
diff --git a/src/capwap/cw_out_ac_descriptor.c b/src/capwap/cw_out_ac_descriptor.c
new file mode 100644
index 00000000..0de0fcf0
--- /dev/null
+++ b/src/capwap/cw_out_ac_descriptor.c
@@ -0,0 +1,68 @@
+#include "cw_log.h"
+#include "conn.h"
+
+#include "itemstore.h"
+#include "capwap_items.h"
+#include "capwap.h"
+
+
+int cw_put_subelem_version(uint8_t *dst,uint16_t subelem_id, uint32_t vendor_id,bstr16_t data)
+{
+printf("Vendor putter %d\n",vendor_id);
+
+ uint8_t *d=dst;
+ d += cw_put_dword(d,vendor_id);
+ d += cw_put_dword(d, (subelem_id<<16) | bstr16_len(data));
+ d += cw_put_data(d,bstr16_data(data),bstr16_len(data));
+ return d-dst;
+}
+
+
+
+int cw_out_ac_descriptor(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct cw_item * item)
+{
+
+ uint8_t *d = dst+4;
+ struct cw_item * i;
+ i = cw_itemstore_get(conn->local,CW_ITEM_AC_STATUS);
+
+ if (!i) {
+ cw_log(LOG_ERR,"Can't send AC Descriptor, no AC Status Item found");
+ return 0;
+ }
+
+ struct cw_ac_status *s = (struct cw_ac_status*)(i->data);
+
+ d += cw_put_dword (d, (s->stations << 16) | (s->limit) );
+ d += cw_put_dword (d, (s->active_wtps <<16) | (s->max_wtps) );
+ d += cw_put_dword (d, (s->security<<24) | (s->rmac_field<<16) | (s->dtls_policy));
+
+
+
+ i = cw_itemstore_get(conn->local,CW_ITEM_AC_HARDWARE_VERSION);
+
+ if ( i ) {
+ d += cw_put_subelem_version(d,CW_SUBELEM_AC_HARDWARE_VERSION,*((uint32_t*)(i->data)),i->data+4);
+ }
+ else {
+ cw_dbg(DBG_ELEM_ERR, "Can't send hard version in AC descriptor, not set.");
+ }
+
+
+ i = cw_itemstore_get(conn->local,CW_ITEM_AC_SOFTWARE_VERSION);
+
+ if ( i ) {
+ d += cw_put_subelem_version(d,CW_SUBELEM_AC_SOFTWARE_VERSION,*((uint32_t*)(i->data)),i->data+4);
+ }
+ else {
+ cw_dbg(DBG_ELEM_ERR, "Can't send software version in AC descriptor, not set.");
+ }
+
+ int len = d-dst-4;
+
+ return len + cw_put_elem_hdr(dst,CW_ELEM_AC_DESCRIPTOR,len);
+
+}
+
+
+
diff --git a/src/capwap/cw_out_ac_name.c b/src/capwap/cw_out_ac_name.c
new file mode 100644
index 00000000..a13ed8f5
--- /dev/null
+++ b/src/capwap/cw_out_ac_name.c
@@ -0,0 +1,9 @@
+
+#include "capwap.h"
+
+int cw_out_ac_name(uint8_t * dst,cw_item *item)
+{
+ uint8_t *data = item->data;
+ int len = cw_put_data(dst+4,data,strlen(data));
+ return len + cw_put_elem_hdr(str,CW_ELEM_AC_NAME,len);
+}
diff --git a/src/capwap/cw_out_capwap_control_ip_addrs.c b/src/capwap/cw_out_capwap_control_ip_addrs.c
new file mode 100644
index 00000000..321bd27a
--- /dev/null
+++ b/src/capwap/cw_out_capwap_control_ip_addrs.c
@@ -0,0 +1,61 @@
+
+#include "cw_log.h"
+
+#include "capwap.h"
+#include "aciplist.h"
+#include "sock.h"
+
+
+static int put_ip(void *priv, void *data)
+{
+ uint8_t ** dptr = (uint8_t **)priv;
+ cw_acip_t *acip=(cw_acip_t*)data;
+
+ uint8_t * dst = *dptr;
+
+ uint8_t *d = dst+4;
+
+ d+=cw_put_sockaddr(d,&acip->ip);
+ d+=cw_put_word(d,acip->wtp_count);
+
+ int fam = sock_addrfamily(&acip->ip);
+ int elem_id=-1;
+ switch (fam) {
+ case AF_INET:
+ elem_id = CW_ELEM_CAPWAP_CONTROL_IPV4_ADDRESS;
+ break;
+ case AF_INET6:
+ elem_id = CW_ELEM_CAPWAP_CONTROL_IPV6_ADDRESS;
+ break;
+ default:
+ cw_log(LOG_ERR,"Unknown adress family %d",fam);
+ break;
+ }
+
+ if (elem_id != -1 ) {
+ d+=cw_put_elem_hdr(dst,elem_id,d-dst-4);
+ *dptr = d-4;
+ }
+
+ return 1;
+}
+
+
+int cw_out_capwap_control_ip_addrs(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct cw_item * item)
+{
+ if ( !item ) {
+ cw_log(LOG_ERR, "Can't send CAPWAP Local IPv4/IPv6 Address, not found");
+ return 0;
+ }
+
+
+ cw_aciplist_t aciplist = (cw_aciplist_t) cw_item_get_data_ptr(item);
+
+
+ uint8_t *d = dst;
+ cw_aciplist_foreach(aciplist, put_ip, &d);
+
+ cw_item_release_data_ptr(item,aciplist);
+ return d-dst;
+}
+
diff --git a/src/capwap/cw_out_generic.c b/src/capwap/cw_out_generic.c
new file mode 100644
index 00000000..cd2c27d8
--- /dev/null
+++ b/src/capwap/cw_out_generic.c
@@ -0,0 +1,35 @@
+
+
+
+#include "capwap.h"
+#include "capwap_items.h"
+
+
+int cw_put_item(uint8_t *dst,struct cw_item*item)
+{
+ switch (item->type){
+ case CW_ITEMTYPE_STR:
+ printf("Outing str %s\n",item->data);
+ return cw_put_data(dst,item->data,strlen( (char*)item->data));
+ case CW_ITEMTYPE_BYTE:
+ return cw_put_byte(dst,item->byte);
+ case CW_ITEMTYPE_WORD:
+ return cw_put_word(dst,item->word);
+ case CW_ITEMTYPE_DWORD:
+ return cw_put_word(dst,item->dword);
+ }
+
+ return 0;
+}
+
+int cw_out_generic(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct cw_item * item)
+{
+ int len;
+ if ( !item )
+ len=0;
+ else
+ len = cw_put_item(dst+4,item);
+ return len + cw_put_elem_hdr(dst,elem_id,len);
+}
+
+
diff --git a/src/capwap/cw_strnelem.c b/src/capwap/cw_strnelem.c
new file mode 100644
index 00000000..e69de29b
diff --git a/src/capwap/dbg.h b/src/capwap/dbg.h
new file mode 100644
index 00000000..6944bf58
--- /dev/null
+++ b/src/capwap/dbg.h
@@ -0,0 +1,18 @@
+#ifndef __DBG_H
+#define __DBG_H
+
+
+
+void cw_dbg_elem_(int msg, int msgelem, const uint8_t * msgbuf, int len);
+
+
+#ifdef WITH_CW_LOG_DEBUG
+
+ #define cw_dbg_elem(msgtype,msgelemtype,msgbuf,msglen) cw_dbg_elem_(msgtype,msgelemtype,msgbuf,msglen)
+
+#else
+
+ #define cw_dbg_elem(...)
+#endif
+
+#endif