Адресная книга для Cisco 7940/7960 из Active Directory

29 Авг
2011

Достаточно долго у нас в компании внутренние номера сотрудников распространялись в виде листочков с таблицей:
• Иванов-101
• Петров-102
Но компания продолжала расти, со временем мы перешли на Asterisk-PBX, и листочков стало не хватать. Я озадачился заменой этим листочкам чем-то более значимым, благо в компании есть Active Directory, и в качестве конечных точек использовались CISCO 7940. Это меня натолкнуло на мысль о том, что можно использовать встроенный в эти телефоны XML сервис External Directory для выгрузки адресной книги из AD в телефон. Для начала изучили всевозможные XML сервисы которые вообще могут предоставляться Cisco 7940. Например здесь.
Что еще раз натолкнуло меня на мысль о том что все возможно в этом мире. Проблема в том что worldwide в компании работает порядка 1000 человек, что помноженное на 32 объекта которые может высвечивать меню телефона дает нам необходимость листать страницы и иметь какой-либо поиск.
Тот факт что AD у меня стойко ассоциируется с Windows, а web программирование в Windows c ASP.Net у меня не было проблем с выбором платформы для скрипта который будет генерировать XML для телефона.
<%@ Language=VBScript %>
<%
Response.ContentType = "text/xml"
	Function ToLower(strng)
		Dim  c,i,s
		s=""
		for i = 1 to len(strng)
		c=Asc(mid(strng,i,1))
		if (c>=65)And(c<=90) then c=c+32
		s=s & Chr©
		next
		ToLower=s 
	End Function
 
	Function Tele(strng)
		Dim  c,i,s
		s=""
		for i = 1 to len(strng)
		c=mid(strng,i,1)
		if c="+" then 
			s=s & "810"
		elseif c="(" Or c=")" Or c="-" Or c=" " then
 
		else
		   s= s & c
		End If
		next
		Tele=s 
	End Function
 
	Function Compare(strng, ptrn)
		dim i
 
		compare=false
		for i = 1 to len(strng)-len(ptrn)+1
				if (ToLower(mid(strng,1,len(ptrn)))=ToLower(ptrn))or(ToLower(mid(strng,i,len(" " & ptrn)))=ToLower(" " & ptrn)) then compare=true
		next
	End Function
 
scriptaddress="http://192.168.101.12/CiscoIPServices/PhoneDirectory.asp"
strDomain = "mydomain.net"
    Const ADS_SCOPE_SUBTREE = 5
	Dim Name(2000)
	Dim voip(2000)
	Dim mobile(2000)
 
    page=0
  	UserName=Request.QueryString("Username")
	Page=Request.QueryString("Page")
	sstring=Request.QueryString("sstring")
 
    Set objConnection = CreateObject("ADODB.Connection")
    Set objCommand =   CreateObject("ADODB.Command")
    objConnection.Provider = "ADsDSOObject"
    objConnection.Open "Active Directory Provider"
 
    Set objCOmmand.ActiveConnection = objConnection
If (Username <>"") Then
    objCommand.CommandText = "Select Name, IPPhone, Mobile from 'LDAP://" & strDomain & "'" & "Where objectCategory='person' and name='"&UserName&"'"
    objCommand.Properties("Page Size") = 1000
    objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
    Set objRecordSet = objCommand.Execute
	Response.Write("<CiscoIPPhoneDirectory>")
	Response.Write("	<Title>" & objRecordSet.Fields("Name").Value& "</Title>")
	Response.Write("	<Prompt>Company Staff</Prompt>")
    objRecordSet.MoveFirst
    Do Until objRecordSet.EOF
    if (objRecordSet.Fields("IPPhone").Value<>"") then
	Response.Write("	<DirectoryEntry>")
	Response.Write("		<Name> VoIP </Name>")
	Response.Write("		<Telephone>" & objRecordSet.Fields("IPPhone").Value & "</Telephone>")
	Response.Write("	</DirectoryEntry>")
    end if
    if (objRecordSet.Fields("Mobile").Value<>"") then
	Response.Write("	<DirectoryEntry>")
	Response.Write("		<Name> Mobile </Name>")
	Response.Write("		<Telephone>" & Tele(objRecordSet.Fields("Mobile").Value) & "</Telephone>")
	Response.Write("	</DirectoryEntry>")
    end if
    objRecordSet.MoveNext
    Loop
	Response.Write("</CiscoIPPhoneDirectory>")
elseif (Page > 0)or(sstring<>"") Then
 	objCommand.CommandText = "Select Name, IPPhone, Mobile from 'LDAP://" & strDomain & "'" & "Where objectCategory='person' AND NOT msExchHideFromAddressLists=TRUE" 
    objCommand.Properties("Page Size") = 1000
    objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
    Set objRecordSet = objCommand.Execute
 
    objRecordSet.MoveFirst
    counter=1
    Do Until objRecordSet.EOF
    if ((objRecordSet.Fields("IPPhone").Value<>"")or(objRecordSet.Fields("Mobile").Value<>"")) then
	name(counter)= objRecordSet.Fields("Name").Value
	voip(counter)=objRecordSet.Fields("IPPhone").Value
	mobile(counter)=objRecordSet.Fields("mobile").Value
	if Compare(name(counter),sstring) then 
		counter=counter+1
	else
		name(counter)=""
		voip(counter)=""
		mobile(counter)=""
	end if
    end if
    objRecordSet.MoveNext
    Loop
counter=counter-1
 
do
	sorted=true
	for i= 1 to counter-1
		if name(i)>name(i+1) then
			temp=name(i)
			name(i)=name(i+1)
			name(i+1)=temp
			temp=voip(i)
			voip(i)=voip(i+1)
			voip(i+1)=temp
			temp=mobile(i)
			mobile(i)=mobile(i+1)
			mobile(i+1)=temp
			sorted= false
		end if
	next
loop until sorted
 
if page=0 then page = 1
if counter >0 then
	Response.Write("<CiscoIPPhoneMenu>")
	Response.Write("	<Title>Company Staff</Title>")
	Response.Write("	<Prompt>Page "&Page&"</Prompt>")
	if page>1 then
		Response.Write("    <MenuItem>")
		Response.Write("          <Name>Previous Page</Name>")
		Response.Write("         <URL>" & scriptaddress & "?page=" & page-1  &  "&sstring=" & sstring & "</URL>")
		Response.Write("    </MenuItem>  ")
	end if
	nonext=false
	for counter = (page-1)*30+1 to page*30
  		if name(counter)<>"" then
			Response.Write("    <MenuItem>")
			Response.Write("          <Name>" &name(counter)& "</Name>")
			Response.Write("         <URL>" & scriptaddress & "?Username=" & name(counter)& "</URL>")
			Response.Write("    </MenuItem>  ")	
		else
			nonext=true
		end if 
	next 
	if not nonext then
		Response.Write("    <MenuItem>")
		Response.Write("          <Name>Next Page</Name>")
		Response.Write("         <URL>" & scriptaddress & "?page=" & page+1 &  "&sstring=" & sstring & "</URL>")
		Response.Write("    </MenuItem>  ")
	end if	
	Response.Write("</CiscoIPPhoneMenu>")
else 
	Response.Write("<CiscoIPPhoneText>")
	Response.Write("<Title>Phone book search</Title>")
	Response.Write("    <Text>There is no users in phone book satisfying entered pattern: " & sstring & "</Text>")
	Response.Write("    <Prompt>Nothing found</Prompt>")
	Response.Write("</CiscoIPPhoneText> ")
end if
else
 
Response.Write("    <CiscoIPPhoneInput>")
Response.Write("        <Title>Phone book search</Title>")
Response.Write("        <Prompt>Enter the name</Prompt>")
Response.Write("        <URL>" & scriptaddress & "</URL>")
Response.Write("        <InputItem>")
Response.Write("              <DisplayName>Name</DisplayName>")
Response.Write("              <QueryStringParam>sstring</QueryStringParam>")
Response.Write("              <InputFlags></InputFlags>")
Response.Write("              <DefaultValue></DefaultValue>")
Response.Write("        </InputItem> ")
Response.Write("    </CiscoIPPhoneInput>")
 
end if
%>

При отсутствии какого либо ввода передается CiscoIPPhoneInput, позволяющий внести маску поиска.
После нажатия на клавишу Submit скрипту передается маска, и он по 30 записей на странице демонстрирует все записи отвечающие маске поиска.
Для того чтобы это заработало у Вас, вам нужно выложить скрипт в IIS, и добиться того чтобы он запускался с соответствующими правами(он обязан уметь читать из AD), а также заполнить переменные scriptadress и strDomain.
Удачи.
По материалам Хабрахабр.



загрузка...

Комментарии:

Наверх