def search(self, baseDn, filter="(objectClass=*)", attrs = []):
		"""
		LDAP search query
		
		@param baseDn: baseDN for search
		@type baseDn: string
		
		@param filter: default (objectClass=*) 
		@type filter: string
		
		@param attrs: attributes 
		@type attrs: list
		"""
		if not self.__connected: return
		
		# log disconnect event
		tpl = templates.ldap( ip=self.cfg['ip'], port=self.cfg['port'], more=templates.ldap_search(bdn=baseDn, filter=filter) )
		self.logSentEvent( shortEvt = "search", tplEvt = self.encapsule(ldap_event=tpl) )
		
		try:
			res = self.con.search_s(baseDn, ldap.SCOPE_SUBTREE, filter,attrs)
		except ldap.NO_SUCH_OBJECT:
			tpl = templates.ldap( ip=self.cfg['ip'], port=self.cfg['port'],  more=templates.ldap_error(details="%s" % e) )
			self.logRecvEvent( shortEvt = "ldap search - no such object", tplEvt = self.encapsule(ldap_event=tpl) )
		except Exception as e:
			# log error event
			tpl = templates.ldap( ip=self.cfg['ip'], port=self.cfg['port'],  more=templates.ldap_error(details="%s" % e) )
			self.logRecvEvent( shortEvt = "ldap search - generic error", tplEvt = self.encapsule(ldap_event=tpl) )
		else:
			# log connected event
			r_tpl= TestTemplates.Template(parent=None)
			r_layer= r_tpl.prepareLayer(name="", data=res)
			
			tpl = templates.ldap( ip=self.cfg['ip'], port=self.cfg['port'],  more=templates.ldap_response(results=r_layer) )
			self.logRecvEvent( shortEvt = "results (%s)" % len(res), tplEvt = self.encapsule(ldap_event=tpl) )
	def deleteAttribute(self, baseDn, attrName, value):
		"""
		Delete attribute
		
		@param baseDn: baseDn
		@type baseDn: string
		
		@param attrName: attrName 
		@type attrName: string
		
		@param value: value to manipulate
		@type value: string
		"""
		if not self.__connected: return
		
		# log disconnect event
		tpl = templates.ldap( ip=self.cfg['ip'], port=self.cfg['port'], more=templates.ldap_delete_attribute(bdn=baseDn, 
																																																																				attr=attrName,
																																																																				value=value) )
		self.logSentEvent( shortEvt = "delete attribute", tplEvt = self.encapsule(ldap_event=tpl) )
		
		try:
			mod_attrs = [(ldap.MOD_DELETE, attrName, value)]
			result = self.con.modify_s(baseDn, mod_attrs)

		except Exception as e:
			# log error event
			tpl = templates.ldap( ip=self.cfg['ip'], port=self.cfg['port'],  more=templates.ldap_error(details="%s" % e) )
			self.logRecvEvent( shortEvt = "ldap delete attribute - generic error", tplEvt = self.encapsule(ldap_event=tpl) )
		else:
			tpl = templates.ldap( ip=self.cfg['ip'], port=self.cfg['port'],  more=templates.ldap_response() )
			self.logRecvEvent( shortEvt = "delete attribute success", tplEvt = self.encapsule(ldap_event=tpl) )
	def add(self, baseDn, record=[]):
		"""
		LDAP add query
		
		@param baseDn: baseDN for search
		@type baseDn: string
		
		@param record: record to add 
		@type record: list
		"""
		if not self.__connected: return
		
		r_tpl= TestTemplates.Template(parent=None)
		r_layer= r_tpl.prepareLayer(name="", data=record)
			
		# log disconnect event
		tpl = templates.ldap( ip=self.cfg['ip'], port=self.cfg['port'], more=templates.ldap_add(bdn=baseDn, record=r_layer) )
		self.logSentEvent( shortEvt = "add", tplEvt = self.encapsule(ldap_event=tpl) )
		
		try:
			
			self.con.add_s(baseDn,record)
			
		except ldap.ALREADY_EXISTS as e:
			tpl = templates.ldap( ip=self.cfg['ip'], port=self.cfg['port'],  more=templates.ldap_error(details="%s" % str(e) ) )
			self.logRecvEvent( shortEvt = "ldap add - entry already exits", tplEvt = self.encapsule(ldap_event=tpl) )
		except Exception as e:
			tpl = templates.ldap( ip=self.cfg['ip'], port=self.cfg['port'],  more=templates.ldap_error(details="%s" % str(e) ) )
			self.logRecvEvent( shortEvt = "ldap add - generic error", tplEvt = self.encapsule(ldap_event=tpl) )
		else:
			tpl = templates.ldap( ip=self.cfg['ip'], port=self.cfg['port'],  more=templates.ldap_response() )
			self.logRecvEvent( shortEvt = "add success", tplEvt = self.encapsule(ldap_event=tpl) )
	def delete(self, baseDn):
		"""
		Delete entry
		
		@param baseDn: baseDn
		@type baseDn: string
		"""
		if not self.__connected: return
		
		# log disconnect event
		tpl = templates.ldap( ip=self.cfg['ip'], port=self.cfg['port'], more=templates.ldap_delete() )
		self.logSentEvent( shortEvt = "delete", tplEvt = self.encapsule(ldap_event=tpl) )
	
		try:
			result = self.con.delete(baseDn)
		except Exception as e:
			# log error event
			tpl = templates.ldap( ip=self.cfg['ip'], port=self.cfg['port'],  more=templates.ldap_error(details="%s" % e) )
			self.logRecvEvent( shortEvt = "ldap delete - generic error", tplEvt = self.encapsule(ldap_event=tpl) )
		else:
			tpl = templates.ldap( ip=self.cfg['ip'], port=self.cfg['port'], more=templates.ldap_response() )
			self.logRecvEvent( shortEvt = "deleted", tplEvt = self.encapsule(ldap_event=tpl) )
	def hasReceivedResponse(self, timeout=1.0):
		"""
		Wait ldap response event until the end of the timeout
		
		@param timeout: time max to wait to receive event in second (default=1s)
		@type timeout: float	

		@return: an event matching with the template or None otherwise
		@rtype: templatemessage/none
		"""
		TestAdapterLib.check_timeout(caller=TestAdapterLib.caller(), timeout=timeout)
		
		# construct the expected template

		layer_ldap = templates.ldap()
		layer_ldap.addMore(more=templates.ldap_response())
		
		expected = TestTemplates.TemplateMessage()
		expected.addLayer(layer=layer_ldap)

		# try to match the template 
		evt = self.received( expected=expected, timeout=timeout )
		return evt