viernes, 1 de febrero de 2013

Código incompleto IAX2 en PIC

Tras  algunos años de dedicarme a otros proyectos y por falta de tiempo no he podido terminar el código del IAX2 en el PIC. Es por eso que he decidido hacerlo público por si alguien esta interesado en terminarlo o bien le sirva como base para algo.

El código es sucio, debo admitir, pero es a mi parecer bastante claro, trate de mantener los comentarios para que se supiera que se estaba haciendo.

Todo el código esta basado en la RFC 5456 que pueden encontrar aqui: http://www.rfc-editor.org/rfc/rfc5456.txt

En el PIC solo hay una parte de el. No esta completo. El hardware esta basado en los esquematicos anteriores. Y su funcionamiento se reduce a responder ACKs, LAGRP, Registro, LLamada, RING y Asnwer.

El programa principal "met2h" responde a las peticiones IAX2(udp) que recibe el modulo "enc_m2eth", el modulo "iax2" contiene las definiciones necesarias, así como el sonido que dice: '¿Clave?'.

La siguiente imagen muestra de manera rápida como funciona la transacción IAX2 entre 2 dispositivos:


Imagen de VOIPFORO.COM



De modo que el PIC se comporta a base de "Respuestas", lo que nos pregunte el Asterisk es lo que nuestro PIC va a contestar, siempre tomando en cuenta las limitaciones del código mismo.

El PIC es capaz de guardar la configuración en la Memoria para no perderla, puede reconfigurar los valores a fábrica, es decir borrar todo y es administrado desde la pagina web.

Teóricamente el ADC del PIC debería bastar para adquirir la voz y codificarla en formato ulaw para enviarla, esta parte no esta implementada. La sección de administración esta basada en el ejemplo que incluye Mikrobasic.

Sin más aquí dejo el código:

Programa Principal:
'Historial:
' 8/Sep/2010
'  Se intento Registrar Trama IAX2 con server
'  Trama enviada corectamente server responde de manera correcta
'   TODO: Habilitar MD5 para autenticacion, Habilitar resolucion de dominio e introduccion de IP
'
' 11/Sep/2010
'  Se Cambio a modo DHCP para obtener la IP
'   comportamineto inestable

'  18/Sep/2010
'   Se Uso la V2 del HTTPDEMO para hacer una pagina un poco mas decente
'   Se pudo usar el DNS resolv para cambiar el host
'   El DCHP se bloquea por el router
'   El IAx ya manda al host establecido
'   Autentifica la Pagina
'
'     TODO:
'     IMplementar MD5
'     Toogle PORTD Via web

'  19/Sep/2010
'    Se añadio usuario y password
    
'     TODO:
'     IMplementar MD5
'     Toogle PORTD Via web


'   16/OCT/2010
'    Migracion de P18F4525 a P18F4620
'    PORTE SELECCIONA IP FIJA O DHCP
'    0 = DHCP
'    1 = IP FIJA
'    Se agregaron 3 botones en la seccion de administrador Se activan por 1.2segundos.(toogle PORTD)
'    Se Puede cambiar configuracion de red  desde Pagina WEB
'    Guarda en EEPROM
'    Factory Defaults con PIN escribiendo OO en Posicion de Memoria 0

'    TODO:
'     Implementar MD5


'  30/Oct/2010
'  Se implemento las respuesta al Qualify IAX(Poke y LAGRQ)
'  Se Registra sin Password
'  Acepta la LLamada de algun peer
'     TODO:
'     Implementar MD5
'     Enviar VOZ para clave


'   03/Nov/2010
'   Se establece la llamada con un ring y contesta, fallo el enviar mensaje
'     TODO:
'      IMplementar MD5
'      Buscar Optmizacion muy poca memoria
'      Enviar el mensaje o algun tono

'   20/Nov/2010
'   Se establece la llamada con un ring y contesta
'   Implementacion de tramas IAX DTMF para activar PORTD6 y PORTD0 con 852 como clave
'   Se logro enviar la palabra "Clave" desde la memoria del PIC
'     TODO:
'      IMplementar MD5
'
   

      
program M2ETH

include "enc_m2eth"        ' modulo donde se implementa el codigo
include "eth_enc28j60"     ' modulo usado por el compilador
include "iax2"             ' modulo iax2

 sub procedure dns()
 dim i as byte
         if(isalpha(server[0]) <> 0) then   ' Verificar si el servidor inicia con una Letra
                ' Resolver Host
                remoteIpAddr = Spi_Ethernet_dnsResolve(server, 5)
        	      if(remoteIpAddr <> 0) then
                    memcpy(@IPD, remoteIpAddr, 4) ' Guardar IP del Servidor
                else
                    exit
                end if
            else
                ' Si el host comienza con un numero lo guardamos directamente
                i = 0
                k = 0
                while (server[i] <> ".")
                    temp[k] = server[i]
                    i = i + 1
                    k = k + 1
                wend
                temp[k] = 0  ' Finalizamos la cadena con 0
                i = i + 1    ' saltamos el punto  '.'
                IPD[0] = StrToWord(temp)
                k = 0
                while (server[i] <> ".")
                    temp[k] = server[i]
                    i = i + 1
                    k = k + 1
                wend
                temp[k] = 0  ' Finalizamos la cadena con 0
                i = i + 1    ' saltamos el punto '.'
                IPD[1] = StrToWord(temp)
                k = 0
                while (server[i] <> ".")
                    temp[k] = server[i]
                    i = i + 1
                    k = k + 1
                wend
                temp[k] = 0  ' Finalizamos la cadena con 0
                i = i + 1    ' saltamos el punto '.'
                IPD[2] = StrToWord(temp)
                k = 0
                while (server[i] <> ".")
                    temp[k] = server[i]
                    i = i + 1
                    k = k + 1
                wend
                temp[k] = 0  ' Finalizamos la cadena con 0
                IPD[3] = StrToWord(temp)
            end if
  flag=0
  end sub

 sub procedure pausa()   ' Pausa para  recepcion de Paquetes
   dim i as byte
  for i=0 to 100
  spi_ethernet_dopacket()
  delay_ms(10)
  spi_ethernet_dopacket()
  next i
 end sub

 sub procedure regIAX()
  '/ Construccion Trama IAX de registro /
 IAX2_p1[0]=128    ' Trama F y 7bits SCN
 IAX2_p1[1]=30     ' 8bits SCN = 30 numero arbitrario
 IAX2_p1[2]=0      ' Retransmision Falso y 7bits DCN, el envio no lleva destino solo las respuestas
 IAX2_p1[3]=0      ' 8bits DCN
 IAX2_p1[4]=0      ' Timestamp
 IAX2_p1[5]=0      ' Timestamp
 IAX2_p1[6]=0      ' Timestamp
 IAX2_p1[7]=3      ' Timestamp arbitrario
 IAX2_p1[8]=0      ' OseqNo
 IAX2_p1[9]=0      ' IseqNo
 IAX2_p1[10]=IaxCTRL  ' Frame type (IAX CTRL)
 IAX2_p1[11]=Regreq  ' C=0 y Sublcass REGREQ
 IAX2_p1[12]=Usuario  ' IE Username
 IAX2_p1[13]=0x04  ' IE Lenght
 IAX2_p1[14]=0x35  ' Data 5
 IAX2_p1[15]=0x30  ' Data 0
 IAX2_p1[16]=0x30  ' Data 0
 IAX2_p1[17]=0x31  ' Data 1
 IAX2_p1[18]=0x13  ' IE Refresh
 IAX2_p1[19]=0x02  ' IE Lenght
 IAX2_p1[20]=0x0E  ' Data 0
 IAX2_p1[21]=0x10  ' Data 60
 '/
  spi_ethernet_sendUdp(IPD, 4569, 4569, @IAX2_p1 ,22)
 end sub
 
 sub procedure IAX_Full_Frame(dim DestC1 as byte, dim DestC2 as byte, dim Timest1 as byte, dim Timest2 as byte, dim Timest3 as byte, dim Timest4 as byte, dim Oseq as byte, dim Iseq as byte, dim frame as byte, dim subclass as byte)
  '/ Construccion Trama IAX  /
 IAX2_p1[0]=128     ' Trama F y 7bits SCN
 IAX2_p1[1]=30      ' 8bits SCN
 IAX2_p1[2]=DestC1  ' Retransmision Falso y 7bits DCN
 IAX2_p1[3]=DestC2  ' 8bits DCN
 IAX2_p1[4]=Timest1 ' Timestamp
 IAX2_p1[5]=Timest2 ' Timestamp
 IAX2_p1[6]=Timest3 ' Timestamp
 IAX2_p1[7]=Timest4 ' Timestamp
 IAX2_p1[8]=Oseq    ' OseqNo
 IAX2_p1[9]=Iseq    ' IseqNo
 IAX2_p1[10]=frame  ' Tipo de trama
 IAX2_p1[11]=subclass ' C=0 y Sublclase
 '/
  spi_ethernet_sendUdp(IPD, 4569, 4569, @IAX2_p1 ,12)
 end sub
 
 sub procedure IAX_Full_Accept(dim DestC1 as byte, dim DestC2 as byte, dim Timest1 as byte, dim Timest2 as byte, dim Timest3 as byte, dim Timest4 as byte, dim Oseq as byte, dim Iseq as byte, dim frame as byte, dim subclass as byte)
  '/ Construccion Trama IAX de Accept /
 IAX2_p1[0]=128     ' Trama F y 7bits SCN
 IAX2_p1[1]=30      ' 8bits SCN
 IAX2_p1[2]=DestC1  ' Retransmision Falso y 7bits DCN
 IAX2_p1[3]=DestC2  ' 8bits DCN
 IAX2_p1[4]=Timest1 ' Timestamp
 IAX2_p1[5]=Timest2 ' Timestamp
 IAX2_p1[6]=Timest3 ' Timestamp
 IAX2_p1[7]=Timest4 ' Timestamp
 IAX2_p1[8]=Oseq    ' OseqNo
 IAX2_p1[9]=Iseq    ' IseqNo
 IAX2_p1[10]=frame  ' Tipo de trama
 IAX2_p1[11]=subclass ' C=0 y Sublclase
 IAX2_p1[12]=Format1  ' Formato
 IAX2_p1[13]=0x04     ' Longitud
 IAX2_p1[14]=0x00        ' 0
 IAX2_p1[15]=0x00        ' 0
 IAX2_p1[16]=0x00        ' 0
 IAX2_p1[17]=G711u         ' 0x00000004 --> g711u
 '/
  spi_ethernet_sendUdp(IPD, 4569, 4569, @IAX2_p1 ,18)
 end sub
 
 sub procedure IAX_Full_Voice(dim DestC1 as byte, dim DestC2 as byte, dim Timest1 as byte, dim Timest2 as byte, dim Timest3 as byte, dim Timest4 as byte, dim Oseq as byte, dim Iseq as byte, dim frame as byte, dim subclass as byte)
  dim n as byte
  '/ Construccion Trama IAX de Voz/
 IAX2_p1[0]=128     ' Trama F y 7bits SCN
 IAX2_p1[1]=30      ' 8bits SCN
 IAX2_p1[2]=DestC1  ' Retransmision Falso y 7bits DCN
 IAX2_p1[3]=DestC2  ' 8bits DCN
 IAX2_p1[4]=Timest1 ' Timestamp
 IAX2_p1[5]=Timest2 ' Timestamp
 IAX2_p1[6]=Timest3 ' Timestamp
 IAX2_p1[7]=Timest4 ' Timestamp
 IAX2_p1[8]=Oseq    ' OseqNo
 IAX2_p1[9]=Iseq    ' IseqNo
 IAX2_p1[10]=frame  ' Tipo de trama
 IAX2_p1[11]=subclass ' C=0 y Sublclase
  '/
  for n=0 to 160       ' Anexamos una parte del mensaje
   IAX2_p1[n+12]=gdata[n]
  next n
  
  spi_ethernet_sendUdp(IPD, 4569, 4569, @IAX2_p1 ,183)
 end sub


sub procedure IAX_Mini_FrameClave(dim index as byte, dim Timest3 as byte, dim Timest4 as byte)
  '/ Construccion Trama IAX de voz/
 dim l as word
 IAX2_p1[0]=0       ' Trama M y 7bits SCN
 IAX2_p1[1]=30      ' 8bits SCN
 IAX2_p1[2]=Timest3 ' Timestamp

  '/enviamos el mensaje guardado en la memoria que dice: 'Clave?'
 if index = 1 then
  IAX2_p1[3]=Timest4+20
  for l=0 to 160
   IAX2_p1[l+4]=vmsg[l]
  next l
 end if

 if index = 2 then
  IAX2_p1[3]=Timest4+40
  for l=0 to 160
   IAX2_p1[l+4]=vmsg2[l]
  next l
 end if

 if index = 3 then
  IAX2_p1[3]=Timest4+60
  for l=0 to 160
   IAX2_p1[l+4]=vmsg3[l]
  next l
 end if

 if index = 4 then
  IAX2_p1[3]=Timest4+80
  for l=0 to 160
   IAX2_p1[l+4]=vmsg4[l]
  next l
 end if
 
 if index = 5 then
  IAX2_p1[3]=Timest4+100
  for l=0 to 160
   IAX2_p1[l+4]=vmsg5[l]
  next l
 end if
 
 if index = 6 then
  IAX2_p1[3]=Timest4+120
  for l=0 to 160
   IAX2_p1[l+4]=vmsg6[l]
  next l
 end if
 
 if index = 7 then
  IAX2_p1[3]=Timest4+140
  for l=0 to 160
   IAX2_p1[l+4]=vmsg7[l]
  next l
 end if
 
 if index = 8 then
  IAX2_p1[3]=Timest4+160
  for l=0 to 160
   IAX2_p1[l+4]=vmsg8[l]
  next l
 end if
 
 if index = 9 then
  IAX2_p1[3]=Timest4+180
  for l=0 to 160
   IAX2_p1[l+4]=vmsg9[l]
  next l
 end if

 if index = 10 then
  IAX2_p1[3]=Timest4+200
  for l=0 to 160
   IAX2_p1[l+4]=vmsg10[l]
  next l
 end if

 if index = 11 then
  IAX2_p1[3]=Timest4+220
  for l=0 to 160
   IAX2_p1[l+4]=vmsg11[l]
  next l
 end if

 if index = 12 then
  IAX2_p1[3]=Timest4+240
  for l=0 to 160
   IAX2_p1[l+4]=vmsg12[l]
  next l
 end if

 if index = 13 then
  IAX2_p1[3]=Timest4+260
  for l=0 to 160
   IAX2_p1[l+4]=vmsg13[l]
  next l
 end if

 if index = 14 then
  IAX2_p1[3]=Timest4+280
  for l=0 to 160
   IAX2_p1[l+4]=vmsg14[l]
  next l
 end if

 if index = 15 then
  IAX2_p1[3]=Timest4+300
  for l=0 to 160
   IAX2_p1[l+4]=vmsg15[l]
  next l
 end if

 if index = 16 then
  IAX2_p1[3]=Timest4+320
  for l=0 to 160
   IAX2_p1[l+4]=vmsg16[l]
  next l
 end if

 if index = 17 then
  IAX2_p1[3]=Timest4+340
  for l=0 to 160
   IAX2_p1[l+4]=vmsg17[l]
  next l
 end if

 if index = 18 then
  IAX2_p1[3]=Timest4+360
  for l=0 to 160
   IAX2_p1[l+4]=vmsg18[l]
  next l
 end if

 if index = 19 then
  IAX2_p1[3]=Timest4+380
  for l=0 to 160
   IAX2_p1[l+4]=vmsg19[l]
  next l
 end if

 if index = 20 then
  IAX2_p1[3]=Timest4+400
  for l=0 to 160
   IAX2_p1[l+4]=vmsg20[l]
  next l
 end if

 if index = 21 then
  IAX2_p1[3]=Timest4+420
  for l=0 to 160
   IAX2_p1[l+4]=vmsg21[l]
  next l
 end if

 if index = 22 then
  IAX2_p1[3]=Timest4+440
  for l=0 to 160
   IAX2_p1[l+4]=vmsg22[l]
  next l
 end if


 spi_ethernet_sendUdp(IPD, 4569, 4569, @IAX2_p1 ,164)
 l=0
end sub
 

 main:

  adcon2.7 = 1    ' JUSTIFICADO A LA DERECHA
  adcon1   = 13   ' RA0 y RA1 ADC
  cmcon    = 7     ' SIN COMPARADORES

  trisa = 7      ' RA0, RA1 Y RA2 ENTRADA DEMAS SALIDAS
  trise =%110
  PORTE.0=0
  trisd = 0     ' PORTD de Salida =0
  portd = 0
  TRISB=0
  
  httpCounter  = 0
  path_private = "/admin"
  PRIVATE_LOGINPASSWD  =  "admin:admin"  ' user + password

  'EEprom_Write(0,0) ' Factory Default

  mymacaddr[0]= 0x00  ' MAC del PIC
  mymacaddr[1]= 0x0A
  mymacaddr[2]= 0x10
  mymacaddr[3]= 0xBA
  mymacaddr[4]= 0x4B
  mymacaddr[5]= 0x65


  if PORTE.2 = 0 then    ' Definimos si usa DHCP o IP FIJA
    myipaddr[0]= 0    ' IP del PIC
    myipaddr[1]= 0
    myipaddr[2]= 0
    myipaddr[3]= 0
    
   else
     conf = Eeprom_Read(0)
      if Conf = 0 then
        myipAddr[0]  = 10
        myipAddr[1]  = 0
        myipAddr[2]  = 1
        myipAddr[3]  = 10

        gwIpAddr[0]  = 0
        gwIpAddr[1]  = 0
        gwIpAddr[2]  = 0
        gwIpAddr[3]  = 0

        dnsIpAddr[0] = 0
        dnsIpAddr[1] = 0
        dnsIpAddr[2] = 0
        dnsIpAddr[3] = 0

        myipMask[0]  = 0
        myipMask[1]  = 0
        myipMask[2]  = 0
        myipMask[3]  = 0
       Else
       
        myipAddr[0]  = Eeprom_Read(5)
        Epausa()
        myipAddr[1]  = Eeprom_Read(6)
        Epausa()
        myipAddr[2]  = Eeprom_Read(7)
        Epausa()
        myipAddr[3]  = Eeprom_Read(8)
        Epausa()
        
        myipMask[0]  = Eeprom_Read(10)
        Epausa()
        myipMask[1]  = Eeprom_Read(11)
        Epausa()
        myipMask[2]  = Eeprom_Read(12)
        Epausa()
        myipMask[3]  = Eeprom_Read(13)
        Epausa()

        gwIpAddr[0]  = Eeprom_Read(15)
        Epausa()
        gwIpAddr[1]  = Eeprom_Read(16)
        Epausa()
        gwIpAddr[2]  = Eeprom_Read(17)
        Epausa()
        gwIpAddr[3]  = Eeprom_Read(18)
        Epausa()

        dnsIpAddr[0] = Eeprom_Read(20)
        Epausa()
        dnsIpAddr[1] = Eeprom_Read(21)
        Epausa()
        dnsIpAddr[2] = Eeprom_Read(22)
        Epausa()
        dnsIpAddr[3] = Eeprom_Read(23)
        Epausa()
      end if
  end if


  PORTD.4=1         ' Pic encendido
  LCD_CONFIG(PORTB,3,2,1,0,PORTB,7,6,5)   'Configuramos el PORTB para el LCD
  LCD_OUT(1,1,"INICIALIZANDO")
  DELAY_MS(1500)
  CLS

  spi_init()  'iniciamos SPI en el PIC
  spi_ethernet_init(portc,0,portc,1,mymacaddr,myipaddr,Spi_Ethernet_FULLDUPLEX) 'Configuramos e Iniciamos el Ethernet del PIC

 if PORTE.2 = 0 then
   PORTD.2=1   'DHCP No obtenido
   PORTD.3=0
   LCD_OUT(1,1,"Obteniendo DHCP")
   LCD_OUT(2,1,"..........")

   DELAY_MS(350)

   'Obtener DHCP y guardar en las variables correspondientes
   while (Spi_Ethernet_initDHCP(5)=0)
   wend
   memcpy(@myipAddr,  Spi_Ethernet_getIpAddress(),    4)
   memcpy(@myipMask,  Spi_Ethernet_getIpMask(),       4)
   memcpy(@gwIpAddr,  Spi_Ethernet_getGwIpAddress(),  4)
   memcpy(@dnsIpAddr, Spi_Ethernet_getDnsIpAddress(), 4)

   PORTD.2=0    ' DHCP Obtenido
   PORTD.3=1

 else
   spi_ethernet_confnetwork(myipmask,gwipaddr,dnsipaddr)
   PORTD.2=0    ' IP Configurada
   PORTD.3=1
 end if
 
 server="your.server.com"
 username="yourusername"
 password="yourpassword"
 registered="no"
 flag=0
 OseqNo=0
 IseqNo=0
 session=0
 
 showIP:
  BytetoStr(myipaddr[0],myip1)    'convertimos la IP a texto
  BytetoStr(myipaddr[1],myip2)
  BytetoStr(myipaddr[2],myip3)
  BytetoStr(myipaddr[3],myip4)
  
  CLS          ' Limpiamos y mostramos la IP de la placa
  delay_ms(1000)
  LCD_OUT(1,1,"M2ETH IP:")
  LCD_OUT(2,1,myip1)
  LCD_OUT(2,4,".")
  LCD_OUT(2,5,myip2)
  LCD_OUT(2,8,".")
  LCD_OUT(2,9,myip3)
  LCD_OUT(2,12,".")
  LCD_OUT(2,13,myip4)

 flag=0

 
loop1:
 spi_ethernet_dopacket()
 
 if iaxc = Ack then  '///// enviamos un Ack
  IAX_Full_Frame(DCN1,DCN2,TS1,TS2,TS3,TS4,Oseqno,Iseqno,IaxCTRL,Ack)
  spi_ethernet_dopacket()
  iaxc =0
  spi_ethernet_dopacket()
 end if
 spi_ethernet_dopacket()

 if iaxc = Pong then  '///// enviamos un Pong
  IAX_Full_Frame(DCN1,DCN2,TS1,TS2,TS3,TS4,Oseqno,Iseqno,IaxCTRL,Pong)
   spi_ethernet_dopacket()
  Iseqno=0  ' Reseteamos los contadores
  Oseqno=0
  iaxc=0
  spi_ethernet_dopacket()
 end if
 spi_ethernet_dopacket()

 if iaxc = Lagrp then  '///// enviamos un LAGRP
  IAX_Full_Frame(DCN1,DCN2,TS1,TS2,TS3,TS4,Oseqno,Iseqno,IaxCTRL,LAGRP)
  spi_ethernet_dopacket()
  Iseqno=0  ' Reseteamos los contadores
  Oseqno=0
  iaxc=0
  spi_ethernet_dopacket()
 end if
 spi_ethernet_dopacket()

 if session=1 then ' recibimos una peticion de llamada correctamente y enviamos un ack y un accept
  if iaxc=Accept then
   IAX_Full_Frame(DCN1,DCN2,TS1,TS2,TS3,TS4,Oseqno,Iseqno,IaxCTRL,Ack) ' enviamos un Ack
   spi_ethernet_dopacket()
   IAX_Full_Accept(DCN1,DCN2,TS1,TS2,TS3,TS4+30,Oseqno,Iseqno,IaxCTRL,Accept)' enviamos un accept
   spi_ethernet_dopacket()
   iaxc=0
  end if
  spi_ethernet_dopacket()
  spi_ethernet_dopacket()
  if iaxf=ringing then
   Iseqno=1
   Oseqno=1
   spi_ethernet_dopacket()
   IAX_Full_Frame(DCN1,DCN2,TS1,TS2,TS3,TS4+40,Oseqno,Iseqno,Control,Ringing)
   spi_ethernet_dopacket()
   pausa()
   pausa()
   pausa()
   pausa()
   spi_ethernet_dopacket()
   iaxf=Answer
   spi_ethernet_dopacket()
  end if
  spi_ethernet_dopacket()
  spi_ethernet_dopacket()
  if iaxf=Answer then
   Oseqno=2
   Iseqno=1
   spi_ethernet_dopacket()
   IAX_Full_Frame(DCN1,DCN2,TS1,TS2,TS3,TS4+50,Oseqno,Iseqno,Control,Answer)
   spi_ethernet_dopacket()
   iaxf=0
  end if
  spi_ethernet_dopacket()
  spi_ethernet_dopacket()
  if iaxc=Ack then
   Oseqno=3
   Iseqno=2
   spi_ethernet_dopacket()
   IAX_Full_Frame(DCN1,DCN2,TS1,TS2,TS3,TS4,Oseqno,Iseqno,IaxCTRL,Ack) ' enviamos un Ack
   spi_ethernet_dopacket()
   iaxc=0
  end if
  spi_ethernet_dopacket()
  spi_ethernet_dopacket()
  if iaxc="B" then
  spi_ethernet_dopacket()
  Iseqno=3  ' reseteamos contadores
  Oseqno=3
  spi_ethernet_dopacket()
  IAX_Full_Frame(DCN1,DCN2,TS1,TS2,TS3,TS4,Oseqno,Iseqno,IaxCTRL,Ack) ' enviamos un Ack
  spi_ethernet_dopacket()
  IAX_Full_Voice(DCN1,DCN2,TS1,TS2,TS3,TS4+20,Oseqno,Iseqno,Voice,G711u) ' enviamos la palabra clave
  spi_ethernet_dopacket()                                                ' en g711u
  spi_ethernet_dopacket()
  IAX_Mini_FrameClave(1,TS3,TS4)
  IAX_Mini_FrameClave(2,TS3,TS4)
  IAX_Mini_FrameClave(3,TS3,TS4)
  IAX_Mini_FrameClave(4,TS3,TS4)
  IAX_Mini_FrameClave(5,TS3,TS4)
  IAX_Mini_FrameClave(6,TS3,TS4)
  IAX_Mini_FrameClave(7,TS3,TS4)
  IAX_Mini_FrameClave(8,TS3,TS4)
  IAX_Mini_FrameClave(9,TS3,TS4)
  IAX_Mini_FrameClave(10,TS3,TS4)
  IAX_Mini_FrameClave(11,TS3,TS4)
  IAX_Mini_FrameClave(12,TS3,TS4)
  IAX_Mini_FrameClave(13,TS3,TS4)
  IAX_Mini_FrameClave(14,TS3,TS4)
  IAX_Mini_FrameClave(15,TS3,TS4)
  IAX_Mini_FrameClave(16,TS3,TS4)
  IAX_Mini_FrameClave(17,TS3,TS4)
  IAX_Mini_FrameClave(18,TS3,TS4)
  IAX_Mini_FrameClave(19,TS3,TS4)
  IAX_Mini_FrameClave(20,TS3,TS4)
  IAX_Mini_FrameClave(21,TS3,TS4)
  IAX_Mini_FrameClave(22,TS3,TS4)
  spi_ethernet_dopacket()
  spi_ethernet_dopacket()
  Iseqno=0  ' reseteamos contadores
  Oseqno=0
  iaxc=0
  end if
 spi_ethernet_dopacket()
  if iaxf=DTMF then
    IAX_Full_Frame(DCN1,DCN2,TS1,TS2,TS3,TS4,Oseqno,Iseqno,IaxCTRL,Ack)
    iaxf=0
  end if
 end if
 spi_ethernet_dopacket()
  spi_ethernet_dopacket()

 if PORTE.1=1 then ' Factory Defaults
  LCD_OUT(1,1,"Configuracion")
  LCD_OUT(2,1,"De Fabrica...")
  for k=0 to 40
    Eeprom_write(k,0)
    Epausa()
  next k
 goto MAIN
 end if
 spi_ethernet_dopacket()

 ' /// Flag del Puerto D para encender I/O desde Web
 if pflag = 1 then
  PORTD.0=1
  delay_ms(1200)          ' Encendemos 1.2s Led1
  PORTD.0=0
  pflag =0
 end if
spi_ethernet_dopacket()

 if pflag = 2 then
  PORTD.5=1
  delay_ms(1200)        ' Encendemos 1.2s Led2
  PORTD.5=0
  pflag =0
 end if
spi_ethernet_dopacket()

 if pflag = 3 then
  PORTD.6=1
  delay_ms(1200)       ' Encendemos 1.2s Led3
  PORTD.6=0
  pflag =0
 end if
spi_ethernet_dopacket()
' ///  Fin Flag del Puerto D para encender I/O desde Web

 if flag = 30 then  ' Si cambio la IP mostrar la nueva
  goto showIP
 end if
spi_ethernet_dopacket()

 if flag = 20 then  ' resolver DNS y enviar registro IAX
  dns()
  pausa()
  regIAX()
  flag=0
  spi_ethernet_dopacket()
 end if
spi_ethernet_dopacket()

 if PORTE.2=0 then        ' Buscar si caduco el DHCP
  spi_ethernet_dopacket()
  if(Spi_Ethernet_doDHCPLeaseTime()<> 0) then
  spi_ethernet_dopacket()
   CLS
   Lcd_Out(2, 1, "Renovando DHCP..")
   spi_ethernet_dopacket()
    while (Spi_Ethernet_renewDHCP(5) = 0)
    wend
    spi_ethernet_dopacket()
    CLS
    spi_ethernet_dopacket()
  end if
 end if
spi_ethernet_dopacket()

goto loop1
end.


Módulo 1(Aqui se configura la pagina web y escuchamos eventos IAX2):
module enc_m2eth

include "eth_enc28j60_api"  ' Modulo del compilador
include "httpUtils"
include "iax2"


dim mymacaddr   as byte[6]  ' variables para MAC, IP, DNS,GW,MASCARA
    myIpAddr    as byte[4]
    gwIpAddr    as byte[4]
    myipMask    as byte[4]
    dnsIpAddr   as byte[4]
    servAddr    as byte[4]
    userAddr    as byte[4]
    passAddr    as byte[4]
    pass        as byte[3]
    myip1       as string[5]
    myip2       as string[5]
    myip3       as string[5]
    myip4       as string[5]
    server      as string[128]
    username    as string[128]
    password    as string[128]
    myIP        as string[128]
    myGW        as string[128]
    myDNS       as string[128]
    myMASK      as string[128]
    registered  as string[5]
    IPD         as byte [4]
    k           as byte
    temp        as byte[4]
    remoteIpAddr as ^byte

    
dim   PRIVATE_LOGINPASSWD as string[20]
    
    

dim    getRequest  as byte[80]    ' variables de uso general
       dyna        as byte[30]
       flag        as byte
       Conf        as byte
       pflag       as byte
       path_private as string[6]
       
dim    httpCounter as longword


'-------------- Devuelve 1 si el caracter esta en minusculas
sub function islower(dim character as byte) as byte
	  if (character <= "z") and (character >= "a") then
      result = 1
    else
      result = 0
    end if
end sub

'-------------- Devuelve 1 si el caracter esta en mayusculas
sub function isupper(dim character as byte) as byte
	  if (character <= "Z") and (character >= "A") then
      result = 1
    else
      result = 0
    end if
end sub


'-------------- Devuelve 1 si es una letra el primer caracter
sub function isalpha(dim character as byte) as byte
	  if islower(character) or isupper(character) then
      result = 1
    else
      result = 0
    end if
end sub

sub procedure    int2str(dim l as longint, dim byref s as byte[13])
  dim
        i, j, n  as byte

        if(l = 0) then
            s[0] = "0"
            s[1] = 0
        else
            if(l < 0) then
                l = l * (-1)
                n = 1
            else
                n = 0
            end if
            s[0] = 0
            i    = 0
            while(l > 0)
                j = i + 1
                while j > 0
                    s[j] = s[j - 1]
                    j = j - 1
                wend
                s[0] = l mod 10
                s[0] = s[0] + "0"
                i = i + 1
                l = l div 10
            wend
            if (n <> 0) then
                j = i + 1
                while j > 0
                    s[j] = s[j - 1]
                    j = j - 1
                wend
                s[0] = "-"
            end if
        end if
end sub

sub procedure    ip2str(dim s as ^byte, dim byref ip as byte[4])
  dim
        i as byte
        buf as byte[4]

        s^ = 0
        for i=0 to 3
            int2str(ip[i], buf)
            strcat(s, buf)
            if(i <> 3) then
              strcat(s, ".")
            end if
        next i
end sub

sub function nibble2hex(dim n as byte) as byte
    n = n and 0x0f
    if(n >= 0x0a) then
        result = n + "7"
        exit
    end if
    result = n + "0"
end sub

sub procedure byte2hex(dim s as ^byte, dim v as byte)
    s^ = nibble2hex(v >> 4)
    s  = s + 1
    s^ = nibble2hex(v)
    s  = s + 1
    s^ = "."
end sub

sub procedure Epausa()
 delay_ms(20)
end sub


const HTTP_REQUEST_SIZE   =   128

const httpHeader as string[30] = "HTTP/1.1 200 OK" + Chr(10) + "Content-type: "  ' HTTP header
const httpMimeTypeHTML as string[12] = "text/html:" + Chr(10) + Chr(10)               ' HTML MIME type
const httpMimeTypeScript as string[12] = "text/plain" + Chr(10) + Chr(10)            ' TEXT MIME type

' *
' * stylesheets
' *
' *
const CSS as string[33] =
'"HTTP/1.1 200 OK" + Chr(10) + "Content-type: text/css" + Chr(10) + Chr(10) +
"body {background-color: #f2f5f7;}"

' *
' * HTTP + HTML header
' *
const HTMLheader as string[95] =
'"HTTP/1.1 200 OK" + Chr(10) + "Content-type: text/html" + Chr(10) + Chr(10) +
"<HTML><HEAD>" +
"<TITLE>VoiPIC V 0.1</TITLE>" +
"</HEAD><BODY alink=black vlink=black link=black><center>"
'"<link rel=" + Chr(10) + "stylesheet" + Chr(10) + " type="  + Chr(10) + "text/css" + Chr(10) + " href=" + Chr(10) + "/s.css" + Chr(10) + chr(62) +
'"<center>"

' * Network info
' *
const HTMLnetwork as string[834]=
"<table width=1024 style='background-color:#3baae3'><tr><td align=center><h3 style=color:white>Info</h3></td><td align=center><h3><a href=/admin>ADMIN</a></h3></td><tr></table>" +
"<script src=/c></script>" +
"<table style=" + Chr(10) + " width=500>" +
"<tr><td>IP</td><td align=right><script>document.write(IP)</script></td></tr>" +
"<tr><td>Mask</td><td align=right><script>document.write(MASK)</script></td></tr>" +
"<tr><td>Gateway</td><td align=right><script>document.write(GW)</script></td></tr>" +
"<tr><td>DNS</td><td align=right><script>document.write(DNS)</script></td></tr>" +
"<tr><td><strong>IAX2 Status</td></tr>"+
"<tr><td>Server:</td><td align=right><script>document.write(SERVER)</script></td></tr>" +
"<tr><td>UserName</td><td align=right><script>document.write(UserName)</script></td></tr>" +
"<tr><td>Registered</td><td align=right><script>document.write(reg)</script></td></tr>"

' *
' * Seccion ADMIN
' *
const HTMLadmin as string[1025] =
"<table width=1024 style='background-color:#3baae3'><tr><td align=center><h3><a href=/3>Info</a></h3></td><td align=center><h3 style=color:white>ADMIN</h3></td><tr></table>" +
"<script src=/admin/s></script>" +
"<form name=s method=GET>"+
"<table border=1 style=" + Chr(10) + " width=500>" +
"<tr><td>Server Registrar</td><td align=right><script>document.write(SERVER)</script></td></tr>" +
"<tr><td>Username</td><td align=right><script>document.write(UserName)</script></td></tr>" +
"<tr><td>Password</td><td align=right><script>document.write(Password)</script></td></tr>"+
"<tr><td>IP</td><td align=right><script>document.write(myIP)</script></td></tr>"+
"<tr><td>Netmask</td><td align=right><script>document.write(myMASK)</script></td></tr>"+
"<tr><td>GW</td><td align=right><script>document.write(myGW)</script></td></tr>"+
"<tr><td>DNS</td><td align=right><script>document.write(myDNS)</script></td></tr>"+
"</form></table>"+
"<a href=/admin/1/><input type=button value='E1'></a>"+
"<a href=/admin/2/><input type=button value='E2'></a>"+
"<a href=/admin/3/><input type=button value='E3'></a>"

' *
' * footer
' *
const   HTMLfooter as string[287] =
"<HTML><HEAD>" +
"</center><table  width=1024 style='background-color:#3baae3' align=center><tr><td align=center><a href=http://digital-merge.com target=_blank>www.digital-merge.com</a></td></tr><tr><td align=center><strong><a href='mailto:navaismo@yahoo.com.mx'>Contacto</a></td></tr></table>"

const ZONE_NAME            =  "VoiPIC V 0.1 Admin Section"     ' Mensaje de autenticacion
const MSG_DENIED           =  "Authorization Required"         ' Mensaje para denegar


  sub procedure cls    'Procedimiento para limpiar LCD
   lcd_cmd(lcd_clear)
  end sub
  
  sub function isdigit(dim character as byte) as byte 'funcion para convertir la cadena en numero
   result = (character <= "9") and (character >= "0")
  end sub
  


 '/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 '/////////////// Se implementa el TCP para mostrar la Pagina web
  sub function Spi_Ethernet_UserTCP(dim byref remoteHost as byte[4], dim remotePort, localPort, reqLength as word) as word
  dim
        dyna as byte[64]
        temp as byte[100]
        getRequest as byte[HTTP_REQUEST_SIZE + 1]
        ptr as ^byte

        i as integer
        admin as byte

        src, dst as ^byte
        k as byte

  result=0
  
        if(HTTP_getRequest(@getRequest, reqLength, HTTP_REQUEST_SIZE) = 0) then
            result = 0
            exit
        end if

        admin = HTTP_basicRealm(reqLength, @PRIVATE_LOGINPASSWD)

        if(memcmp(@getRequest, @path_private, strlen(path_private)) = 0) then  ' Seccion Privada
            ' apuntamos al subpath
            ptr = @getRequest + strlen(path_private)

            ' Verificar que este logeado
            if(admin = 0) then
                ' Si no mensaje de Negacion
                result = HTTP_accessDenied(ZONE_NAME, MSG_DENIED)
            else
                ' Si  verificamos request
                if(getRequest[strlen(path_private)+1] = "s") then

                    result = Spi_Ethernet_putConstString(httpHeader)
                    result = result + Spi_Ethernet_putConstString(httpMimeTypeScript)
                     ' Server Registrar
                    temp = "var SERVER=" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    temp = "<input onChange=\" + Chr(34) + "document.location.href = '/admin/n/' + this.value\" + Chr(34) + " value=\" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    result = result + Spi_Ethernet_putString(@server)
                    temp = "\" + Chr(34) + ">" + Chr(34) + " ;"
                    result = result + Spi_Ethernet_putString(@temp)
                    
                      ' Username
                    temp = "var UserName=" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    temp = "<input onChange=\" + Chr(34) + "document.location.href = '/admin/p/' + this.value\" + Chr(34) + " value=\" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    result = result + Spi_Ethernet_putString(@username)
                    temp = "\" + Chr(34) + ">" + Chr(34) + " ;"
                    result = result + Spi_Ethernet_putString(@temp)
                    
                      ' Password
                    temp = "var Password=" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    temp = "<input type=password onChange=\" + Chr(34) + "document.location.href = '/admin/q/' + this.value\" + Chr(34) + " value=\" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    result = result + Spi_Ethernet_putString(@password)
                    temp = "\" + Chr(34) + ">" + Chr(34) + " ;"
                    result = result + Spi_Ethernet_putString(@temp)


                If PORTE.2 = 0 then

                      ' myIP Desactivar Edicion
                    ip2str(@myIP, myIpAddr)
                    temp = "var myIP=" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    temp = "<input disabled onChange=\" + Chr(34) + "document.location.href = '/admin/z/' + this.value\" + Chr(34) + " value=\" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    result = result + Spi_Ethernet_putString(@myIP)
                    temp = "\" + Chr(34) + ">" + Chr(34) + " ;"
                    result = result + Spi_Ethernet_putString(@temp)

                  ELSE
                      ' myIP
                    ip2str(@myIP, myIpAddr)
                    temp = "var myIP=" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    temp = "<input onChange=\" + Chr(34) + "document.location.href = '/admin/z/' + this.value\" + Chr(34) + " value=\" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    result = result + Spi_Ethernet_putString(@myIP)
                    temp = "\" + Chr(34) + ">" + Chr(34) + " ;"
                    result = result + Spi_Ethernet_putString(@temp)
                end if


                if PORTE.2=0 then
                      ' myMASK  Desactivar Edicion
                    ip2str(@myMASK, myIpMask)
                    temp = "var myMASK=" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    temp = "<input disabled onChange=\" + Chr(34) + "document.location.href = '/admin/x/' + this.value\" + Chr(34) + " value=\" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    result = result + Spi_Ethernet_putString(@myMASK)
                    temp = "\" + Chr(34) + ">" + Chr(34) + " ;"
                    result = result + Spi_Ethernet_putString(@temp)
                
                  ELSE
                     ' myMASK
                    ip2str(@myMASK, myIpMask)
                    temp = "var myMASK=" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    temp = "<input onChange=\" + Chr(34) + "document.location.href = '/admin/x/' + this.value\" + Chr(34) + " value=\" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    result = result + Spi_Ethernet_putString(@myMASK)
                    temp = "\" + Chr(34) + ">" + Chr(34) + " ;"
                    result = result + Spi_Ethernet_putString(@temp)
                end if
                
                 if PORTE.2=0 then
                     ' myGW  Desactivar Edicion
                    ip2str(@myGW, gwIpAddr)
                    temp = "var myGW=" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    temp = "<input disabled onChange=\" + Chr(34) + "document.location.href = '/admin/y/' + this.value\" + Chr(34) + " value=\" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    result = result + Spi_Ethernet_putString(@myGW)
                    temp = "\" + Chr(34) + ">" + Chr(34) + " ;"
                    result = result + Spi_Ethernet_putString(@temp)
                   Else
                     ' myGW
                    ip2str(@myGW, gwIpAddr)
                    temp = "var myGW=" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    temp = "<input onChange=\" + Chr(34) + "document.location.href = '/admin/y/' + this.value\" + Chr(34) + " value=\" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    result = result + Spi_Ethernet_putString(@myGW)
                    temp = "\" + Chr(34) + ">" + Chr(34) + " ;"
                    result = result + Spi_Ethernet_putString(@temp)
                 end if
                 
                 if PORTE.2=0 then
                       ' myDNS  Desactivar edicion
                    ip2str(@myDNS, dnsIpAddr)
                    temp = "var myDNS=" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    temp = "<input disabled onChange=\" + Chr(34) + "document.location.href = '/admin/o/' + this.value\" + Chr(34) + " value=\" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    result = result + Spi_Ethernet_putString(@myDNS)
                    temp = "\" + Chr(34) + ">" + Chr(34) + " ;"
                    result = result + Spi_Ethernet_putString(@temp)
                 
                   ELSE
                      ' myDNS
                    ip2str(@myDNS, dnsIpAddr)
                    temp = "var myDNS=" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    temp = "<input onChange=\" + Chr(34) + "document.location.href = '/admin/o/' + this.value\" + Chr(34) + " value=\" + Chr(34)
                    result = result + Spi_Ethernet_putString(@temp)
                    result = result + Spi_Ethernet_putString(@myDNS)
                    temp = "\" + Chr(34) + ">" + Chr(34) + " ;"
                    result = result + Spi_Ethernet_putString(@temp)
                 end if

                else
                    select case getRequest[strlen(path_private)+1]
                           case "n"
                              ' Guardamos el Server de registro
                              src = @getRequest[strlen(path_private) + 3]
                              dst = @server
                              for k=0 to 127
                                  dst^ = src^
                                  src  = src + 1
                                  if(dst^ = " ") then
                                      dst^ = 0
                                      break
                                  end if
                                  dst = dst + 1
                              next k
                               'Convertimos el string a Byte y guardamos en la IP
                              i = 0
                              k = 0
                              while (server[i] <> ".")
                               temp[k] = server[i]
                                i = i + 1
                                k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              i = i + 1    ' saltamos el punto '.'
                              servAddr[0] = StrToWord(temp)
                              Eeprom_write(25,servAddr[0])
                              Epausa()
                              k = 0
                              while (server[i] <> ".")
                              temp[k] = server[i]
                              i = i + 1
                              k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              i = i + 1    ' saltamos el punto '.'
                              servAddr[1] = StrToWord(temp)
                              Eeprom_write(26,servAddr[1])
                              Epausa()
                              k = 0
                              while (server[i] <> ".")
                              temp[k] = server[i]
                              i = i + 1
                              k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              i = i + 1    ' saltamos el punto '.'
                              servAddr[2] = StrToWord(temp)
                              Eeprom_write(27,servAddr[2])
                              Epausa()
                              k = 0
                              while (server[i] <> ".")
                              temp[k] = server[i]
                              i  = i + 1
                              k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              servAddr[3] = StrToWord(temp)
                              Eeprom_write(28,servAddr[3])
                              Epausa()


                              
                          case "p"
                              ' Guardamos el username
                              src = @getRequest[strlen(path_private) + 3]
                              dst = @username
                              for k=0 to 127
                                  dst^ = src^
                                  src  = src + 1
                                  if(dst^ = " ") then
                                      dst^ = 0
                                      break
                                  end if
                                  dst = dst + 1
                              next k


                         case "q"
                              ' Guardamos el Password
                              src = @getRequest[strlen(path_private) + 3]
                              dst = @password
                              for k=0 to 127
                                  dst^ = src^
                                  src  = src + 1
                                  if(dst^ = " ") then
                                      dst^ = 0
                                      break
                                  end if
                                  dst = dst + 1
                              next k
                              flag = 20  ' Resolvemos el DNS del server registrar
                              
                         case "z"
                              ' Actualizamos la nueva IP
                              src = @getRequest[strlen(path_private) + 3]
                              dst = @myIP
                              for k=0 to 127
                                  dst^ = src^
                                  src  = src + 1
                                  if(dst^ = " ") then
                                      dst^ = 0
                                      break
                                  end if
                                  dst = dst + 1
                              next k
                              'Convertimos el string a Byte y guardamos en la IP
                              i = 0
                              k = 0
                              while (myIP[i] <> ".")
                               temp[k] = myIP[i]
                                i = i + 1
                                k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              i = i + 1    ' saltamos el punto '.'
                              myIpAddr[0] = StrToWord(temp)
                              Eeprom_write(0,1)
                              Eeprom_write(5,myIpAddr[0])
                              Epausa()
                              k = 0
                              while (myIP[i] <> ".")
                              temp[k] = myIP[i]
                              i = i + 1
                              k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              i = i + 1    ' saltamos el punto '.'
                              myIpAddr[1] = StrToWord(temp)
                              Eeprom_write(6,myIpAddr[1])
                              Epausa()
                              k = 0
                              while (myIP[i] <> ".")
                              temp[k] = myIP[i]
                              i = i + 1
                              k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              i = i + 1    ' saltamos el punto '.'
                              myIpAddr[2] = StrToWord(temp)
                              Eeprom_write(7,myIpAddr[2])
                              Epausa()
                              k = 0
                              while (myIP[i] <> ".")
                              temp[k] = myIP[i]
                              i  = i + 1
                              k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              myIpAddr[3] = StrToWord(temp)
                              Eeprom_write(8,myIpAddr[3])
                              Epausa()

                       case "x"
                              ' Actualizamos la nueva Mascara
                              src = @getRequest[strlen(path_private) + 3]
                              dst = @myMASK
                              for k=0 to 127
                                  dst^ = src^
                                  src  = src + 1
                                  if(dst^ = " ") then
                                      dst^ = 0
                                      break
                                  end if
                                  dst = dst + 1
                              next k
                              ' Convertimos String a Byte y guardamos en la Netmask
                              i = 0
                              k = 0
                              while (myMASK[i] <> ".")
                               temp[k] = myMASK[i]
                                i = i + 1
                                k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              i = i + 1    ' saltamos el punto '.'
                              myIpMask[0] = StrToWord(temp)
                              Eeprom_write(10,myIpMask[0])
                              Epausa()
                              k = 0
                              while (myMASK[i] <> ".")
                              temp[k] = myMASK[i]
                              i = i + 1
                              k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              i = i + 1    ' saltamos el punto '.'
                              myIpMask[1] = StrToWord(temp)
                              Eeprom_write(11,myIpMask[1])
                              Epausa()
                              k = 0
                              while (myMASK[i] <> ".")
                              temp[k] = myMASK[i]
                              i = i + 1
                              k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              i = i + 1    ' saltamos el punto '.'
                              myIpMASK[2] = StrToWord(temp)
                              Eeprom_write(12,myIpMask[2])
                              Epausa()
                              k = 0
                              while (myMASK[i] <> ".")
                              temp[k] = myMASK[i]
                              i  = i + 1
                              k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              myIpMASK[3] = StrToWord(temp)
                              Eeprom_write(13,myIpMask[3])
                              Epausa()

                       case "y"
                              ' Actualizamos el GW
                              src = @getRequest[strlen(path_private) + 3]
                              dst = @myGW
                              for k=0 to 127
                                  dst^ = src^
                                  src  = src + 1
                                  if(dst^ = " ") then
                                      dst^ = 0
                                      break
                                  end if
                                  dst = dst + 1
                              next k
                              ' Convertimos String a Byte y guardamos en GW
                              i = 0
                              k = 0
                              while (myGW[i] <> ".")
                               temp[k] = myGW[i]
                                i = i + 1
                                k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              i = i + 1    ' saltamos el punto '.'
                              gwIpAddr[0] = StrToWord(temp)
                              Eeprom_write(15,gwIpAddr[0])
                              Epausa()
                              k = 0
                              while (myGW[i] <> ".")
                              temp[k] = myGW[i]
                              i = i + 1
                              k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              i = i + 1    ' saltamos el punto '.'
                              gwIpAddr[1] = StrToWord(temp)
                              Eeprom_write(16,gwIpAddr[1])
                              Epausa()
                              k = 0
                              while (myGW[i] <> ".")
                              temp[k] = myGW[i]
                              i = i + 1
                              k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              i = i + 1    ' saltamos el punto '.'
                              gwIpAddr[2] = StrToWord(temp)
                              Eeprom_write(17,gwIpAddr[2])
                              Epausa()
                              k = 0
                              while (myGW[i] <> ".")
                              temp[k] = myGW[i]
                              i  = i + 1
                              k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              gwIpAddr[3] = StrToWord(temp)
                              Eeprom_write(18,gwIpAddr[3])
                              Epausa()

                        case "o"
                              ' Actualizamos DNS
                              src = @getRequest[strlen(path_private) + 3]
                              dst = @myDNS
                              for k=0 to 127
                                  dst^ = src^
                                  src  = src + 1
                                  if(dst^ = " ") then
                                      dst^ = 0
                                      break
                                  end if
                                  dst = dst + 1
                              next k
                              ' Convertimos String a Byte y guardamos en DNS
                              i = 0
                              k = 0
                              while (myDNS[i] <> ".")
                               temp[k] = myDNS[i]
                                i = i + 1
                                k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              i = i + 1    ' saltamos el punto '.'
                              dnsIpAddr[0] = StrToWord(temp)
                              Eeprom_write(20,dnsIpAddr[0])
                              Epausa()
                              k = 0
                              while (myDNS[i] <> ".")
                              temp[k] = myDNS[i]
                              i = i + 1
                              k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              i = i + 1    ' saltamos el punto '.'
                              dnsIpAddr[1] = StrToWord(temp)
                              Eeprom_write(21,dnsIpAddr[1])
                              Epausa()
                              k = 0
                              while (myDNS[i] <> ".")
                              temp[k] = myDNS[i]
                              i = i + 1
                              k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              i = i + 1    ' saltamos el punto '.'
                              dnsIpAddr[2] = StrToWord(temp)
                              Eeprom_write(22,dnsIpAddr[2])
                              Epausa()
                              k = 0
                              while (myDNS[i] <> ".")
                              temp[k] = myDNS[i]
                              i  = i + 1
                              k = k + 1
                              wend
                              temp[k] = 0  ' Finalizamos la cadena con 0
                              dnsIpAddr[3] = StrToWord(temp)
                              Eeprom_write(23,dnsIpAddr[3])
                              Epausa()

                              cls   ' Mensaje a LCD
                              LCD_OUT(1,1,"Reconfigurando....")
                              LCD_OUT(2,1,"..................")

                              spi_init()  'reiniciamos SPI en el PIC y configuracion de red con los nuevos datos
                              spi_ethernet_init(portc,0,portc,1,mymacaddr,myipaddr,Spi_Ethernet_FULLDUPLEX) 'Configuramos e Iniciamos el Ethernet del PIC

                              flag = 30

                       case "1"  ' Encendemos salida 1
                        pflag=1

                       case "2"  ' Encendemos salida 2
                        pflag=2

                       case "3"  ' Encendemos salida 3
                        pflag=3


                    end select
                    ' Enviamos Pagina Seccion ADMIN
                    result = result + Spi_Ethernet_putConstString(HTMLheader)
                    result = result + Spi_Ethernet_putConstString(HTMLadmin)
                    result = result + Spi_Ethernet_putConstString(HTMLfooter)
                end if
            end if
        else
            select case getRequest[1]
                  ' Si no estamos en la seecion de admin
                  case "s"
                          ' Enviamos stilo
                          result = Spi_Ethernet_putConstString(CSS)
                  case "c"
                          result = result + Spi_Ethernet_putConstString(httpHeader)
                          result = result + Spi_Ethernet_putConstString(httpMimeTypeScript)

                          ' Escribimos IP a html
                          ip2str(@dyna, myIpAddr)
                          temp = "var IP=" + Chr(34)
                          result = result + Spi_Ethernet_putString(@temp)
                          result = result + Spi_Ethernet_putString(@dyna)
                          temp = Chr(34) + ";"
                          result = result + Spi_Ethernet_putString(@temp)

                          ' Escribimos GW a html
                          ip2str(@dyna, gwIpAddr)
                          temp = "var GW=" + Chr(34)
                          result = result + Spi_Ethernet_putString(@temp)
                          result = result + Spi_Ethernet_putString(@dyna)
                          temp = Chr(34) + ";"
                          result = result + Spi_Ethernet_putString(@temp)

                          ' Escribimos Mascara a html
                          ip2str(@dyna, myipMask)
                          temp = "var MASK=" + Chr(34)
                          result = result + Spi_Ethernet_putString(@temp)
                          result = result + Spi_Ethernet_putString(@dyna)
                          temp = Chr(34) + ";"
                          result = result + Spi_Ethernet_putString(@temp)

                          ' Escribimos DNS a HTML
                          ip2str(@dyna, dnsIpAddr)
                          temp = "var DNS=" + Chr(34)
                          result = result + Spi_Ethernet_putString(@temp)
                          result = result + Spi_Ethernet_putString(@dyna)
                          temp = Chr(34) + ";"
                          result = result + Spi_Ethernet_putString(@temp)

                           ' Escribimos Server Regitro a HTML
                          temp = "var SERVER=" + Chr(34)
                          result = result + Spi_Ethernet_putString(@temp)
                          result = result + Spi_Ethernet_putString(@server)
                          temp = Chr(34) + ";"
                          result = result + Spi_Ethernet_putString(@temp)

                            ' Escribimos Username a HTML
                          temp = "var UserName=" + Chr(34)
                          result = result + Spi_Ethernet_putString(@temp)
                          result = result + Spi_Ethernet_putString(@username)
                          temp = Chr(34) + ";"
                          result = result + Spi_Ethernet_putString(@temp)

                            ' Escribimos Registro a HTML
                          temp = "var reg=" + Chr(34)
                          result = result + Spi_Ethernet_putString(@temp)
                          result = result + Spi_Ethernet_putString(@registered)
                          temp = Chr(34) + ";"
                          result = result + Spi_Ethernet_putString(@temp)


                  case "d"

                          result = result + Spi_Ethernet_putConstString(httpHeader)
                          result = result + Spi_Ethernet_putConstString(httpMimeTypeScript)


                  case "3"
                          ' Enviamos la Pagina de RED
                          result = result + Spi_Ethernet_putConstString(HTMLheader)
                          result = result + Spi_Ethernet_putConstString(HTMLnetwork)
                          result = result + Spi_Ethernet_putConstString(HTMLfooter)
                  case else
                          ' Cualquier cosa enviamos Pagina de RED
                          result = result + Spi_Ethernet_putConstString(HTMLheader)
                          result = result + Spi_Ethernet_putConstString(HTMLnetwork)
                          result = result + Spi_Ethernet_putConstString(HTMLfooter)
              end select
          end if
        httpCounter = httpCounter + 1  ' Contador de peticiones

end sub

'////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
'///// Implementamos la recepcion de paquetes UDP reseteando siempre el resultado a 0
sub function Spi_Ethernet_UserUDP(dim byref remoteHost as byte[4], dim remotePort, destPort, reqLength as word) as word
dim i as byte
result = 0   ' reseteo de la funcion
'////////////Seleccionamos el puerto para las rutinas
select case destport

'/////////////////////////////// Puerto IAX2
case 4569
  for i=0 to 80    ' tomamos algunos bytes de la trama IAX2
    getRequest[i]=spi_ethernet_getbyte()
  next i
          '////// Obtenemos el Destination call number del peer o server
   DCN1 = (getRequest[0] and 0x7F)   '/ Eliminamos el Bit 8 que siempre es 1 y obtenemos los 7 bits
   DCN2 = (getRequest[1] and 0xFF)   '/ obtenemos los 8 bits restantes

    ' /////Implementamos la parte del registro
  if getRequest[2] = 0 then  ' Si corresponde a nuestro call number de registro (30)
   if getRequest[3] = 30 then
    if getRequest[10] = IaxCTRL then  ' si nos llega un peticion de trama tipo control
     if getRequest[11] = Regack  then ' Si es nuestro regack
        TS1 = getRequest[4] ' Copiamos el timestamp
        TS2 = getRequest[5]
        TS3 = getRequest[6]
        TS4 = getRequest[7]
        Oseqno = getRequest[8]
        Iseqno = getRequest[9]
        iaxc = Ack          ' Enviamos un Ack
        registered="yes"
     end if
    end if
   end if
  end if
    ' ///// Fin implementamos la parte del registro

  
   ' /////Implementamos el PONG para PING
 if getRequest[2] = 0 then  ' Si corresponde a call number 30
  if getRequest[3] = 30 then
   if getRequest[10] = IaxCTRL then ' si es una trama tipo control
    if getrequest[11] = Ping then   ' si es un Ping
     TS1 = getRequest[4] ' Copiamos el timestamp
     TS2 = getRequest[5]
     TS3 = getRequest[6]
     TS4 = getRequest[7]
     Oseqno = getRequest[8]' enviamos el mismo Iseqno
     Iseqno = getRequest[9]' enviamos el mismo Iseqno
     iaxc = Pong           ' Enviamos un Ack
     inc(Iseqno)           ' Incrementamos el Oseqno
     end if
    end if
   end if
  end if
  '///////// Fin de la implementacion de Pong
  
    ' /////Implementamos el PONG para POKE
 if getRequest[2] = 0 then  ' Si corresponde a call number 00 osea primera peticion
  if getRequest[3] = 0 then
   if getRequest[10] = IaxCTRL then ' si es una trama tipo control
    if getrequest[11] = Poke then   ' si es un Poke
     TS1 = getRequest[4] ' Copiamos el timestamp
     TS2 = getRequest[5]
     TS3 = getRequest[6]
     TS4 = getRequest[7]
     Oseqno = getRequest[8]' enviamos el mismo Iseqno
     Iseqno = getRequest[9]' enviamos el mismo Iseqno
     iaxc = Pong           ' Enviamos un Ack
     inc(Iseqno)           ' Incrementamos el Oseqno
     end if
    end if
   end if
  end if
  '///////// Fin de la implementacion de Pong

    ' /////Implementamos el LAGRP
 if getRequest[2] = 0 then  ' Si corresponde a nuestro call number
  if getRequest[3] = 30 then
   if getRequest[10] = IaxCTRL then ' si es una trama tipo control
    if getrequest[11] = Lagrq then   ' si es un LAGRQ
     TS1 = getRequest[4] ' Copiamos el timestamp
     TS2 = getRequest[5]
     TS3 = getRequest[6]
     TS4 = getRequest[7]
     Oseqno = getRequest[8]' enviamos el mismo Iseqno
     Iseqno = getRequest[9]' enviamos el mismo Iseqno
     iaxc = Lagrp          ' Enviamos un LAGRP
     inc(Oseqno)           ' Incrementamos el Oseqno
     end if
    end if
   end if
  end if
    '/////// Fin de la implementacion del LAGRP
    
   '*******************************************************************************************
   '//////// **************** Implementamos la llamada ******************** //////////////////////
 if getRequest[2] = 0 then  ' Si corresponde a destination callnumber 00
  if getRequest[3] = 0 then
   if getRequest[10] = IaxCTRL then ' si es una trama tipo control
    if getrequest[11] = New1 then   ' si es un New
     TS1 = getRequest[4] ' Copiamos el timestamp y aumentamos 30ms
     TS2 = getRequest[5]
     TS3 = getRequest[6]
     TS4 = getRequest[7] + 30
     Oseqno = getRequest[8]' enviamos el mismo Iseqno
     Iseqno = getRequest[9]' enviamos el mismo Iseqno
     inc(Iseqno)           ' Incrementamos el Oseqno
     iaxc=Accept
     session=1             ' Abrimos session de llamada y enviamos ack y accept
     end if
    end if
   end if
  end if

if session =1 then

 if getRequest[2] = 0 then  ' Si corresponde a nuestro call number
  if getRequest[3] = 30 then
   if getRequest[10] = IaxCTRL then ' si es una trama tipo DTMF
    if getrequest[11] = Ack then   ' si es el ACk del accept
     if getRequest[8] = 1 then ' enviamos el mismo Iseqno
     if getRequest[9] = 1 then' enviamos el mismo Iseqno
       iaxf=Ringing
      end if
     end if
    end if
   end if
  end if
 end if

 if getRequest[2] = 0 then  ' Si corresponde a nuestro call number
  if getRequest[3] = 30 then
   if getRequest[10] = Control then ' si es una trama tipo DTMF
    if getrequest[11] = 0x14 then   ' si es el ACk del accept
     TS1 = getRequest[4] ' Copiamos el timestamp
     TS2 = getRequest[5]
     TS3 = getRequest[6]
     TS4 = getRequest[7]
       iaxc=Ack
    end if
   end if
  end if
 end if

 if getRequest[2] = 0 then  ' Si corresponde a nuestro call number
  if getRequest[3] = 30 then
   if getRequest[10] = Voice then ' si es una trama tipo Voz
    if getrequest[11] = G711u then   ' si g711u
     TS1 = getRequest[4] ' Copiamos el timestamp
     TS2 = getRequest[5]
     TS3 = getRequest[6]
     TS4 = getRequest[7]
       iaxc="B"
    end if
   end if
  end if
 end if


 if getRequest[2] = 0 then  ' Si corresponde a nuestro call number
  if getRequest[3] = 30 then
   if getRequest[10] = DTMF then ' si es una trama tipo DTMF
    if getrequest[11] = 0x38 then   ' si es 8
     Oseqno = getRequest[8]' enviamos el mismo Iseqno
     Iseqno = getRequest[9]' enviamos el mismo Iseqno
     TS1 = getRequest[4] ' Copiamos el timestamp
     TS2 = getRequest[5]
     TS3 = getRequest[6]
     TS4 = getRequest[7]
     iaxf=DTMF
     pass[0]=8
     dts=1
    end if
   end if
  end if
 end if

 if dts=1 then
 if getRequest[2] = 0 then  ' Si corresponde a nuestro call number
  if getRequest[3] = 30 then
   if getRequest[10] = DTMF then ' si es una trama tipo DTMF
    if getrequest[11] = 0x35 then   ' si es 5
     Oseqno = getRequest[8]' enviamos el mismo Iseqno
     Iseqno = getRequest[9]' enviamos el mismo Iseqno
     TS1 = getRequest[4] ' Copiamos el timestamp
     TS2 = getRequest[5]
     TS3 = getRequest[6]
     TS4 = getRequest[7]
     iaxf=DTMF
     pass[1]=5
    end if
   end if
  end if
 end if

  if getRequest[2] = 0 then  ' Si corresponde a nuestro call number
  if getRequest[3] = 30 then
   if getRequest[10] = DTMF then ' si es una trama tipo DTMF
    if getrequest[11] = 0x32 then   ' si es 2
     Oseqno = getRequest[8]' enviamos el mismo Iseqno
     Iseqno = getRequest[9]' enviamos el mismo Iseqno
     TS1 = getRequest[4] ' Copiamos el timestamp
     TS2 = getRequest[5]
     TS3 = getRequest[6]
     TS4 = getRequest[7]
     iaxf=DTMF
     pass[2]=2
    end if
   end if
  end if
 end if
end if

   if pass[0]=8 then
    if pass[1]=5 then
     if pass[2]=2 then
       PORTD.0=1
       PORTD.6=1
       delay_ms(2000)       ' Encendemos 2s Led3
       PORTD.0=0
       PORTD.6=0
       pass[0]=0
       pass[1]=0
       pass[2]=0
       dts=0
      end if
     end if
    end if

 if getRequest[2] = 0 then  ' Si corresponde a nuestro call number
  if getRequest[3] = 30 then
   if getRequest[10] = IaxCTRL then ' si es una trama tipo control
    if getrequest[11] = Hangup2 then   ' si es un Hangup
     session = 0
     Iseqno  = 0
     Oseqno  = 0
     iaxf=0
     iaxc=0
     end if
    end if
   end if
  end if
end if
   '/////////// *********** Fin de la Llamada ******** ///////////
'****************************************************************************************
 end select
 end sub

end.


Módulo 2(parte de las librerias de MKB) :
' *
' * file         : httpUtils.pbas
' * project      : HTTP utils
' * author       : Bruno Gavand
' * compiler     : mikroBasic
' * date         : april 2008
' *
' * description  :
'                Some useful functions for mikroBasic ethernet library
' *
' *
module httpUtils

implements

' *
' * maximum length of username:password (arbitrary)
' *
const LOGINPASSWD_MAXLENGTH = 30

const AUTH_STR_MAXLENGTH  as word  = 128                             ' maximum length of base64 encoded username:password (arbitrary limit)

' *
' * some HTTP headers
' *
const HTTP_NotFound    as string[25]  = "HTTP/1.1 404 Not Found" + Chr(10) + Chr(10)                                ' HTTP reply with error 404
'const HTTP_HeaderGif   as string[41]  = "HTTP/1.1 200 OK" + Chr(10) + "Content-type: image/gif" + Chr(10) + Chr(10) ' HTTP reply with GIF image mime type
const HTTP_HeaderHtml  as string[41]  = "HTTP/1.1 200 OK" + Chr(10) + "Content-type: text/html" + Chr(10) + Chr(10) ' HTTP reply with HTML mime type
const HTTP_Denied      as string[67]  = "HTTP/1.1 401 Authorization Required" + Chr(10) + "WWW-Authenticate: Basic realm=" + chr(34) ' HTTP reply with basic realm authorization needed
const HTTP_Redir       as string[41]  = "HTTP/1.1 301 Moved Permanently" + Chr(10) + "Location: "                   ' HTTP reply with redirection

' *
' * This is a base64 coding section taken from http:'base64.sourceforge.net/
' *
' * This little utility implements the Base64
' * Content-Transfer-Encoding standard described in
' * RFC1113 (http:'www.faqs.org/rfcs/rfc1113.html).
' *
' * This is the coding scheme used by MIME to allow
' * binary data to be transferred by SMTP mail.
' *
' * The following licence agreement is related only to base64 coding section.
'
'   LICENCE :
'      Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc.
'
'      Permission is hereby granted, free of charge, to any person
'      obtaining a copy of this software and associated
'      documentation files (the "Software"), to deal in the
'      Software without restriction, including without limitation
'      the rights to use, copy, modify, merge, publish, distribute,
'      sublicense, and/or sell copies of the Software, and to
'      permit persons to whom the Software is furnished to do so,
'      subject to the following conditions:
'
'      The above copyright notice and this permission notice shall
'      be included in all copies or substantial portions of the
'      Software.
'
'      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
'      KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
'      WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
'      PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
'      OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
'      OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
'      OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
'      SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
' *
 
' *
' * base64 array for reverse coding
' *
const HTTP_b64_reverse as string[80] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\]^_`abcdefghijklmnopq"

' ************************************************
' * PRIVATE FUNCTIONS
' ************************************************

' *
' * decodes a 4 bytes array into a 3 bytes array
' *
sub procedure HTTP_b64_decode4(dim byref inputT as byte[4], dim byref  outputT as byte[3])
    outputT[0] = (inputT[0] << 2) or (inputT[1] >> 4)
    outputT[1] = (inputT[1] << 4) or (inputT[2] >> 2)
    outputT[2] = ((inputT[2] << 6) and 0xC0) or inputT[3]
end sub

' *
' * base 64 unencode string src to string dst
' *
sub procedure HTTP_b64_unencode(dim src, dst as ^byte)
  dim inputT  as byte[4]
      outputT as byte[3]
      v as byte
      i, lenN as integer

  while(src^ <> 0)
    lenN = 0
    i = 0
    while (i < 4) and (src^ <> 0)
      v = 0
      while(src^ <> 0) and (v = 0)
        v = src^
        Inc(src)
        if (v < 43) or (v > 122) then
          v = 0
        else
          v = HTTP_b64_reverse[v - 43]
        end if
        if(v <> 0) then
          if (v = "$") then
            v = 0
          else
            v = v - 61
          end if
        end if
      wend
      if(src^ <> 0) then
        Inc(lenN)
        if(v <> 0) then
          inputT[i] = (v - 1)
        end if
      else
        inputT[i] = 0
      end if
      inc(i)
    wend

    if(lenN <> 0) then
      HTTP_b64_decode4(inputT, outputT)
      i = 0
      while i < (lenN - 1)
        dst^ = outputT[i]
        inc(dst)
        inc(i)
      wend
    end if
  wend

  dst^ = 0
end sub
  
' *
' * end of base64 coding section
' *
 
' *******************************************
' * PUBLIC FUNCTIONS
' *******************************************

' *
' * try to find base64 encoded passwd in next l HTTP request characters
' * passwd is username:password
' * returns 1 if found, 0 if failed
' *
sub function HTTP_BasicRealm(dim l as word, dim passwd as ^byte) as byte
  dim
        i  as word         ' general purpose integers
       auth  as byte[AUTH_STR_MAXLENGTH]
       login as byte[LOGINPASSWD_MAXLENGTH + 1]
       AUTH_STRING as string[21]  ' basic realm signature


  i   = 0
  result = 0
  AUTH_STRING = "Authorization: Basic "
  while(l <> 0)
    auth[i] = Spi_Ethernet_getByte()
    if((auth[i] < 32) or (i = AUTH_STR_MAXLENGTH - 1)) then
      if(memcmp(@auth, @AUTH_STRING, strlen(AUTH_STRING)) = 0) then
        auth[i] = 0
        HTTP_b64_unencode(@auth + strlen(AUTH_STRING), @login)
        if(strcmp(login, passwd) = 0) then
          result = 1
        end if
        break
      end if
      i = 0
    else
      inc(i)
    end if
    Dec(l)
  wend

end sub

' *
' * simplified routine to extract document name of a GET request from HTTP header
' * document name is copied to buffer buf
' * len points to the remaining length of the request to parse
' * max is buf size
' * returns 1 if GET request if found, 0 otherwise
' *
sub function HTTP_GetRequest(dim buf as ^byte, dim byref lenN as word, dim max as word) as word
  dim
        i   as word
  ' *
  ' * check if GET method is invoked
  ' *
  if(    (Spi_Ethernet_getByte() <> "G")
      or (Spi_Ethernet_getByte() <> "E")
      or (Spi_Ethernet_getByte() <> "T")
      or (Spi_Ethernet_getByte() <> " ")
    ) then
      result = 0
      exit
  end if

  ' *
  ' * yes, copy the following string to buf, until a separator is found or buffer size limit
  ' *
  i = 0
  while (i < max) and (lenN <> 0)
    buf^ = Spi_Ethernet_getByte()
    lenN = lenN - 1
    if(buf^ < 32) then
      break
    end if
    Inc(i)
    Inc(buf)
  wend
  buf^ = 0

  result = 1
end sub

' *
' * reply with http code 401 (private)
' * the browser will pop up the authorization window to ask user for username + password
' * zone name zn is usually shown in the browser authorization window
' * if the user cancels the request, or after some attempts (usually 3),
' * the browser will show the message pointed to by m
' * if the user enters a username + password, the browser will encode it in base64
' * and add it to the header of a new HTTP request to the same document
' * if the server respond with anything but a new code 401, the browser will
' * add it also to the future requests
' * return : number of bytes added to the transmit buffer
' *
sub function HTTP_AccessDenied(dim const zn as ^byte, dim const m as ^byte) as word
  dim
    temp as string[3]

  temp = Chr(34) + Chr(10) + Chr(10)
  result = Spi_Ethernet_putConstString(HTTP_Denied)
  result = result + Spi_Ethernet_putConstString(zn)
  result = result + Spi_Ethernet_putString(@temp)
  result = result + Spi_Ethernet_putConstString(m)

end sub

' *
' * ask browser to redirect to new location url
' * return : number of bytes added added to the transmit buffer
' *
'sub function HTTP_Redirect(dim url as ^byte) as word
'  dim
'      temp as string[2]
'
'  temp = Chr(10) + Chr(10)
'  result = Spi_Ethernet_putConstString(HTTP_Redir)
'  result = result + Spi_Ethernet_putString(url)
'  result = result + Spi_Ethernet_putString(@temp)
'end sub

' *
' * send an HTML web page to the browser
' * return : number of bytes added added to the transmit buffer
' *
sub function HTTP_Html(dim const html as ^byte) as word

  result = Spi_Ethernet_putConstString(HTTP_HeaderHtml)
  result = result + Spi_Ethernet_putConstString(html)
end sub

' *
' * send a GIF image to the browser
' * return : number of bytes added added to the transmit buffer
' *
'sub function HTTP_ImageGIF(dim const img as ^byte, dim l as word) as word
'  dim i as byte
'
'  result = Spi_Ethernet_putConstString(@HTTP_HeaderGif)
'  ' put image string in 255 bytes chunks
'  while (l>255)
'    Spi_Ethernet_putConstBytes(img, 255)
'    l = l - 255
'    img = img + 255
'    result = result + 255
'  wend
'  Spi_Ethernet_putConstBytes(img, l)
'  result = result + l
'
'end sub

' *
' * send an error 404 (not found) to the browser
' * return : number of bytes added added to the transmit buffer
' *
sub function HTTP_Error() as word
  result = Spi_Ethernet_putConstString(HTTP_NotFound)
end sub
end.


Modulo 3(Definiciones IAX2):
module IAX2

'///////////////////////// Variables IAX2      //////////////////////
Dim    iaxf,iaxc       as byte  ' iax flags
       OseqNo,IseqNo   as byte  ' Secuencia de Entrada y de Salida
       DCN1,DCN2       as byte  ' Destination call number
       session,dts     as byte  ' Session
       IAX2_p1         as byte [250] ' Paquete para contruccion
       TS1,TS2,TS3,TS4 as byte  ' variables para timestamp

'//// Definicion de algunas constantes IAX2
'///////////////////////// Tipo de Trama a Usar /////////////////////
const DTMF    = 0x01  ' Trama DTMF Sublcase 0-9,A-D,*,#
const Voice   = 0x02  ' Trama de Voz audio comprimido
const Control = 0x04  ' Trama de control
const IaxCTRL = 0x06  ' Trama de control IAX2

'/////////////////////// Sublcase de las Tramas /////////////////////
'/// Subclase para trama Voice ///
const ADPCM = 0x20
const G711u  = 0x04

'/// Subclase para trama Control ///
const Hangup  = 0x01  ' La llamada ha sido terminada
const Ringing = 0x03  ' Ring Back a la peticion de llamada
const Answer  = 0x04  ' La llamada ha sido contestada

'///Subclase para trama IaxCTRL ///
const New1   = 0x01    ' Se inicia una Llamada
const Ping   = 0x02    ' Ping
const Pong   = 0x03    ' Contestamos un PING o un POKE
const Ack    = 0x04    ' Ack
const Hangup2 = 0x05   ' Iniciar la finalizacion de llamada
const Reject = 0x06    ' Rechazar llamada
const Accept = 0x07    ' Aceptar una llamada
const Lagrq  = 0x0B    ' Peticion de LAG
const Lagrp  = 0x0C    ' Responder peticion de LAG
const Regreq = 0x0D    ' Solicitud de registro
const Regack = 0x0F    ' Ack de registro
const Regrel = 0x11    ' Solicitud de liberacion.
const Dial   = 0x15    ' Marcar
const Poke   = 0x1E    ' POKE

'///////////////////// Elementos de Informacion (IE) /////////////////
const Usuario  = 0x06  ' Nombre de usuario para autenticacion
const Clave    = 0x07  ' Password de autenticacion
const Format1  = 0x09  ' CODEC


'//////////////////// Sonido de "Clave" ////////////////////////////////////////////
const gdata as byte[160]=($ff,$ff,$ff,$ff,$ff,$ff,$7f,$fe,$7e,$7b,$7a,$7a,$7a,$7a,$7a,$7a,$79,$7a,$7a,$7a,$7b,$7a,$7b,$7b,$7b,$7b,$7b,$7c,$7b,$7b,$7b,$7b,$7b,$7b,$7a,$7a,$7b,$7a,$7a,$7a,$7a,$7b,$7b,$7b,$7c,$7c,$7d,$7d,$7e,$7d,$7f,$7f,$ff,$fe,$fe,$fd,$fc,$fc,$fb,$fb,$fb,$fa,$fa,$fa,$f9,$fa,$f9,$fa,$fa,$f9,$fa,$f9,$fa,$fa,$fa,$fa,$f9,$fa,$f9,$f9,$fa,$f8,$f7,$f7,$f7,$f8,$f6,$f7,$f8,$f9,$f9,$f9,$f9,$fa,$fa,$f9,$fa,$f9,$fb,$fb,$fe,$7c,$7b,$7c,$7c,$7e,$fe,$fd,$fd,$fa,$f9,$f7,$f9,$f7,$f4,$f4,$f5,$f2,$ef,$ef,$ed,$ee,$ec,$ec,$eb,$e9,$e9,$e7,$e7,$e6,$e6,$e5,$e4,$e4,$e3,$e2,$e2,$e0,$df,$de,$dd,$de,$dd,$dd,$dd,$dc,$dc,$dc,$dd,$dd,$dc,$dc,$dc,$de,$dd,$dd,$dd,$df,$e2,$e3)
const vmsg as byte[160]=($fd,$62,$62,$5e,$5a,$6f,$43,$32,$48,$cc,$c9,$4c,$2f,$32,$42,$6c,$5c,$49,$58,$5b,$db,$c9,$de,$72,$42,$35,$41,$5f,$54,$47,$44,$5c,$d3,$78,$4b,$5b,$d7,$64,$46,$4e,$69,$e2,$66,$4d,$5c,$e1,$db,$7f,$6d,$dd,$ce,$d9,$78,$fa,$df,$e0,$7d,$72,$db,$cc,$cf,$e0,$da,$cb,$ca,$da,$ea,$d4,$c9,$cf,$e3,$d9,$cb,$cd,$dd,$e9,$d6,$cc,$d6,$e3,$d7,$ce,$ce,$d5,$d6,$d4,$d8,$df,$df,$d5,$d3,$db,$dc,$d5,$da,$e7,$f1,$f5,$f4,$75,$6e,$6e,$6e,$67,$60,$62,$5e,$5b,$5d,$5e,$5c,$5e,$5a,$56,$65,$62,$5a,$5c,$58,$65,$69,$59,$5e,$66,$69,$5d,$55,$5d,$6c,$5d,$58,$5f,$79,$f8,$5f,$60,$f0,$e8,$fb,$6d,$fb,$de,$ee,$7a,$f4,$f1,$f3,$70,$72,$73,$69,$5f,$5e,$5f,$54,$54,$55,$53,$4f,$47)
const vmsg2 as byte[160]=($45,$47,$46,$40,$3a,$38,$38,$39,$36,$33,$32,$32,$35,$33,$31,$31,$35,$39,$37,$39,$3e,$4b,$5b,$65,$da,$cd,$ca,$bb,$b5,$b3,$b4,$ae,$a9,$a8,$a5,$a2,$9d,$9e,$9e,$9a,$94,$97,$a8,$a8,$9f,$9f,$d9,$2c,$5b,$c5,$6c,$20,$25,$dd,$bf,$3f,$2a,$c9,$a6,$ab,$df,$6e,$a8,$a5,$bf,$39,$4d,$dc,$32,$1f,$19,$1b,$1b,$19,$14,$16,$1e,$20,$1f,$1f,$27,$30,$31,$2c,$26,$2e,$32,$2e,$2a,$2c,$3c,$3b,$3b,$43,$6e,$c8,$c0,$b3,$ac,$a6,$a2,$9f,$9b,$9b,$98,$93,$90,$9a,$c5,$b7,$a8,$aa,$30,$1a,$2d,$d9,$dd,$29,$32,$b8,$a6,$a7,$b2,$a6,$9f,$9d,$a3,$a7,$a7,$af,$bc,$e1,$ee,$49,$34,$2d,$2e,$37,$31,$30,$2e,$38,$49,$48,$3e,$38,$3e,$41,$40,$36,$2e,$2e,$2e,$2e,$29,$29,$27,$27,$26,$23)
const vmsg3 as byte[160]=($26,$24,$28,$2b,$28,$2c,$2f,$3a,$44,$44,$4d,$7d,$d5,$c6,$c0,$bf,$b0,$af,$ab,$a8,$a3,$9c,$99,$99,$a2,$9b,$9b,$a4,$a0,$a8,$ab,$b8,$c6,$6a,$e4,$c9,$32,$36,$47,$43,$3c,$4d,$d8,$e6,$ce,$e0,$be,$b3,$b3,$b8,$b9,$b7,$bd,$ba,$bf,$c2,$e9,$40,$3e,$3a,$34,$29,$25,$26,$1f,$1e,$1f,$21,$20,$20,$22,$26,$2b,$2d,$2e,$2e,$31,$34,$36,$38,$37,$32,$31,$38,$38,$3b,$45,$48,$66,$e2,$c5,$af,$a9,$a6,$a2,$9a,$98,$92,$97,$a1,$94,$9e,$a1,$9f,$ab,$ab,$d7,$5b,$48,$c0,$3c,$2d,$4a,$3a,$3b,$44,$c9,$c9,$be,$c9,$b8,$a8,$ac,$ad,$b0,$af,$bd,$bd,$b9,$d2,$6b,$39,$34,$34,$31,$2a,$26,$28,$1f,$1f,$25,$21,$22,$22,$24,$27,$2a,$2a,$2d,$2e,$28,$2c,$2e,$2c,$2b,$2b,$2c,$2d,$2e,$31)
const vmsg4 as byte[160]=($38,$3d,$3f,$38,$ea,$bb,$b7,$ab,$a1,$9f,$9b,$93,$94,$8f,$9b,$9a,$95,$a7,$a2,$b0,$b3,$5f,$2e,$2f,$39,$4d,$2b,$40,$4c,$55,$ca,$b1,$a6,$a7,$a5,$a7,$9e,$9e,$a5,$a6,$af,$b9,$c7,$dd,$4d,$35,$2b,$26,$26,$25,$25,$26,$26,$25,$28,$2d,$2f,$33,$2e,$2f,$33,$2f,$30,$2d,$2b,$28,$26,$27,$2a,$29,$2b,$2d,$2d,$35,$3b,$46,$44,$52,$c7,$d9,$bf,$ab,$a9,$a5,$9f,$9d,$9b,$99,$94,$92,$9e,$9f,$9d,$ac,$b4,$b4,$b6,$38,$24,$3a,$30,$28,$3a,$49,$37,$31,$c5,$ad,$b9,$ad,$aa,$ad,$b0,$a9,$a2,$b4,$c8,$c0,$65,$41,$4f,$4c,$30,$2a,$2e,$31,$2d,$32,$3c,$2e,$2e,$37,$33,$2f,$2b,$2b,$2a,$28,$2b,$28,$22,$22,$24,$24,$25,$27,$28,$29,$2f,$36,$3b,$47,$54,$e3,$ca,$b9,$af,$ac,$a5,$a0)
const vmsg5 as byte[160]=($9d,$9b,$99,$96,$93,$90,$94,$9d,$a3,$aa,$b0,$b9,$bb,$47,$28,$2d,$2f,$2d,$38,$49,$3e,$36,$cd,$ae,$ae,$a9,$a5,$a8,$ae,$a7,$a4,$b1,$c7,$eb,$48,$35,$38,$38,$29,$24,$26,$29,$29,$2e,$32,$2d,$2c,$2e,$31,$2c,$29,$2a,$26,$23,$23,$24,$1f,$1e,$20,$20,$20,$23,$25,$27,$2c,$36,$3e,$4d,$de,$bd,$b5,$ae,$a8,$a4,$9e,$9c,$99,$98,$97,$92,$8f,$8e,$94,$9b,$9f,$b9,$bf,$c0,$4c,$22,$19,$1f,$30,$59,$c5,$bd,$b5,$a5,$99,$94,$9b,$a9,$aa,$af,$bd,$f0,$2e,$1c,$1a,$24,$2b,$2a,$2c,$2f,$3b,$e4,$b7,$c6,$3a,$2a,$1f,$19,$17,$17,$14,$14,$1a,$1f,$23,$28,$2a,$27,$29,$2d,$2c,$27,$29,$2b,$2b,$3a,$51,$67,$c2,$b0,$aa,$a0,$98,$92,$90,$93,$91,$92,$91,$8d,$90,$b8,$1e,$1e,$27,$2a)
const vmsg6 as byte[160]=($28,$25,$2a,$cd,$97,$90,$99,$9e,$9d,$9c,$9f,$ad,$39,$1e,$23,$39,$43,$3b,$43,$d8,$b3,$a2,$a2,$bc,$45,$43,$3b,$29,$1f,$19,$15,$18,$1b,$1c,$1c,$21,$2d,$32,$2e,$28,$23,$20,$1e,$1c,$19,$19,$1e,$26,$2c,$33,$44,$c5,$b2,$ac,$ab,$a7,$9f,$9b,$98,$99,$9a,$98,$97,$96,$90,$8e,$a1,$28,$22,$35,$3d,$36,$2f,$2e,$dd,$99,$91,$9c,$a7,$a5,$a7,$ad,$bd,$39,$21,$26,$58,$c4,$da,$cd,$b9,$af,$aa,$ab,$ed,$2b,$27,$26,$20,$1c,$1a,$19,$19,$1e,$24,$23,$28,$31,$2e,$26,$20,$1d,$1c,$1b,$1c,$1c,$1e,$2b,$3c,$43,$4a,$db,$bd,$af,$a8,$a5,$a3,$9c,$97,$97,$97,$95,$94,$92,$8e,$8e,$a9,$1f,$1d,$2f,$48,$46,$3c,$3e,$af,$95,$92,$9f,$b7,$ba,$b8,$c3,$4d,$2b,$26,$3c,$b0,$a7,$ac,$b0)
const vmsg7 as byte[160]=($b2,$b1,$b7,$5c,$28,$1e,$1f,$25,$23,$1f,$1e,$1f,$20,$20,$1f,$1e,$1f,$24,$22,$1e,$1d,$1d,$1d,$1d,$1e,$1f,$27,$37,$4c,$47,$53,$cd,$bb,$b2,$af,$aa,$9f,$99,$95,$93,$92,$92,$90,$8f,$8f,$9e,$2d,$1d,$2d,$e8,$c8,$bc,$bc,$b4,$9e,$99,$a8,$52,$35,$32,$3e,$60,$4f,$3f,$c7,$a4,$9e,$9f,$a9,$bc,$ed,$5c,$3f,$2c,$26,$29,$2d,$2e,$2c,$25,$1f,$1b,$19,$19,$1b,$1d,$1f,$1f,$1e,$1d,$1d,$1d,$1e,$21,$29,$32,$3e,$50,$4e,$48,$5e,$d1,$bd,$b5,$ab,$9f,$9a,$96,$95,$96,$98,$97,$8f,$8d,$98,$39,$19,$22,$d3,$ab,$ad,$bc,$bb,$a3,$99,$9f,$e4,$2b,$27,$34,$6f,$dc,$56,$7b,$ae,$a1,$9f,$a8,$bf,$53,$48,$49,$39,$2d,$29,$2c,$2e,$2f,$2a,$22,$1c,$19,$1a,$1c,$1e,$1f,$1e,$1d,$1c,$1c)
const vmsg8 as byte[160]=($1c,$1e,$22,$28,$2d,$3a,$49,$53,$4c,$4a,$5c,$c8,$b6,$af,$a4,$9c,$95,$91,$92,$94,$93,$8f,$8e,$93,$b8,$1b,$1d,$5e,$aa,$a9,$ae,$b6,$ae,$9e,$9e,$bd,$2d,$27,$2a,$45,$c6,$cf,$f3,$ba,$a3,$9d,$a1,$b4,$47,$38,$49,$43,$36,$2c,$2b,$2f,$35,$36,$28,$1f,$1b,$19,$19,$1b,$1e,$1e,$1f,$1e,$1d,$1d,$1e,$1f,$23,$27,$2b,$35,$42,$44,$3b,$3e,$49,$db,$bd,$b2,$aa,$a3,$99,$94,$93,$96,$98,$95,$90,$8e,$97,$d3,$1f,$26,$5b,$ab,$a8,$af,$b2,$a9,$9d,$9f,$b7,$36,$28,$2d,$45,$d8,$d6,$d7,$b8,$a6,$9e,$9f,$b0,$5d,$3b,$41,$49,$3d,$30,$2e,$35,$3f,$3f,$2e,$23,$1f,$1c,$1a,$1a,$1b,$1d,$1f,$20,$1f,$1f,$1f,$20,$22,$23,$26,$2a,$2f,$36,$35,$34,$39,$42,$5f,$c7,$bb,$b0,$a9,$a0,$9a)
const vmsg9 as byte[160]=($95,$94,$98,$9b,$97,$90,$8e,$94,$ad,$2c,$28,$59,$ac,$a9,$b3,$ba,$ad,$9f,$9d,$ac,$42,$29,$2b,$3b,$6f,$df,$e2,$c6,$ab,$9f,$9e,$a8,$c9,$45,$3e,$45,$3e,$31,$2c,$2e,$3a,$51,$3d,$27,$1f,$1d,$1c,$1a,$19,$19,$1b,$20,$24,$24,$22,$20,$1f,$20,$20,$22,$26,$2a,$2e,$2e,$2f,$2f,$39,$4d,$5c,$eb,$ca,$af,$a3,$a0,$9e,$9c,$99,$97,$97,$96,$92,$8e,$8f,$9d,$55,$2b,$34,$d9,$b2,$b2,$b5,$b1,$a4,$9d,$9f,$b1,$46,$32,$33,$4b,$f9,$78,$df,$ba,$a5,$9e,$9f,$a9,$c3,$5e,$4e,$47,$37,$2d,$2b,$30,$43,$5e,$4d,$36,$2d,$2a,$29,$24,$1d,$19,$18,$1a,$1e,$23,$25,$26,$26,$27,$28,$24,$20,$1f,$1f,$22,$27,$29,$2a,$2d,$33,$3a,$47,$59,$e2,$bd,$b2,$aa,$a6,$a3,$a1,$9e,$9b,$9b,$99,$98)
const vmsg10 as byte[160]=($93,$8e,$8d,$95,$ae,$41,$3e,$70,$c6,$c4,$df,$6c,$ba,$a4,$9e,$a2,$b2,$cd,$5f,$66,$e0,$50,$3f,$44,$d2,$b0,$a7,$a4,$ab,$b4,$bb,$be,$cd,$4b,$33,$2c,$2c,$30,$39,$3b,$37,$35,$34,$38,$37,$2e,$24,$1e,$1d,$1e,$21,$23,$25,$26,$27,$2a,$2b,$29,$23,$21,$23,$25,$26,$24,$26,$27,$29,$2d,$31,$36,$37,$41,$57,$ce,$b9,$b9,$b4,$ae,$a9,$a8,$ad,$ad,$ad,$a3,$9c,$96,$92,$91,$94,$9b,$9f,$a8,$bc,$d6,$55,$49,$40,$53,$c6,$b9,$af,$ac,$ab,$af,$b2,$b5,$bf,$c8,$e2,$ea,$70,$fb,$ce,$c6,$be,$be,$ba,$bd,$c7,$c9,$d3,$ee,$4d,$43,$3d,$39,$39,$3b,$3d,$3a,$3a,$3a,$39,$3a,$38,$36,$33,$2f,$2e,$2d,$2c,$2c,$2c,$2a,$29,$29,$28,$28,$27,$27,$27,$26,$27,$28,$2a,$2b,$2c,$2e,$2e,$2f)
const vmsg11 as byte[160]=($37,$3b,$3d,$3f,$43,$4a,$55,$6f,$f1,$dd,$cb,$c4,$c0,$bd,$bc,$b7,$b2,$b3,$b2,$b0,$af,$ac,$aa,$a7,$a4,$9f,$9c,$9a,$9c,$9e,$a2,$a7,$ac,$ae,$af,$b7,$c7,$d9,$cd,$ca,$c1,$be,$c6,$d3,$dc,$cd,$c9,$cb,$cc,$cd,$d2,$de,$ce,$c8,$ca,$ca,$cd,$cc,$d2,$ce,$cc,$cf,$d4,$e0,$e2,$74,$5f,$5c,$4e,$48,$41,$3e,$3e,$3c,$3b,$3a,$38,$36,$36,$35,$33,$33,$32,$2f,$2f,$2d,$2c,$2c,$2c,$2b,$2a,$29,$29,$29,$29,$2a,$2c,$2b,$2a,$2c,$2f,$2e,$2f,$32,$32,$37,$36,$39,$3c,$3f,$48,$4f,$57,$5a,$72,$f8,$e0,$de,$cc,$c5,$cf,$c5,$c3,$c2,$c1,$bd,$b6,$b7,$b5,$b2,$b0,$b2,$b0,$ac,$aa,$a8,$a4,$a0,$9d,$9c,$9b,$9e,$a3,$a6,$a8,$a9,$aa,$ae,$b9,$c9,$cd,$c2,$bc,$bf,$c8,$cf,$d8,$d0,$c6,$c2)
const vmsg12 as byte[160]=($cd,$dc,$dd,$de,$dc,$d5,$d6,$f3,$6d,$ff,$fc,$e9,$f3,$71,$64,$58,$5b,$5a,$53,$4b,$47,$44,$41,$40,$3e,$3c,$38,$37,$38,$37,$36,$35,$34,$35,$33,$33,$33,$31,$2f,$2f,$2f,$2f,$2e,$2e,$2d,$2e,$2e,$2e,$2e,$2d,$2d,$2d,$2e,$2e,$2f,$2f,$2e,$31,$32,$34,$35,$37,$3b,$3c,$3f,$43,$49,$48,$4b,$59,$67,$e5,$d3,$ce,$d9,$cd,$c0,$be,$bf,$c4,$be,$bf,$bf,$ba,$bb,$be,$bb,$b9,$b7,$b3,$af,$af,$b0,$ad,$a8,$a4,$a2,$a2,$9e,$99,$95,$94,$9a,$a5,$ae,$aa,$a7,$b0,$c9,$45,$33,$3b,$65,$bf,$52,$3c,$58,$ca,$ba,$ba,$be,$cb,$ee,$c7,$bc,$cb,$4b,$3c,$3f,$46,$49,$41,$3b,$36,$37,$45,$4b,$45,$3d,$3d,$46,$4d,$4d,$45,$3e,$3a,$3e,$45,$43,$3d,$39,$3b,$3e,$3e,$3c,$39,$37,$36,$38,$39)
const vmsg13 as byte[160]=($38,$34,$34,$37,$38,$37,$34,$32,$31,$30,$30,$2f,$2d,$2c,$2c,$2c,$2c,$2e,$2e,$2d,$2e,$2e,$2e,$2f,$33,$37,$3b,$46,$55,$6a,$e0,$dd,$cf,$ca,$cc,$ca,$c7,$c5,$cb,$d7,$cf,$c8,$c7,$c7,$c9,$be,$bd,$c2,$c7,$c4,$bf,$be,$b6,$b3,$af,$af,$ac,$a3,$a2,$a4,$a4,$a5,$a5,$9e,$9d,$9c,$9a,$94,$8e,$9e,$cb,$b2,$9e,$ad,$25,$28,$37,$2d,$2b,$2f,$39,$2c,$5d,$ad,$b2,$cd,$b7,$9e,$a9,$c0,$bb,$b8,$ce,$35,$39,$37,$27,$25,$26,$28,$24,$29,$38,$3a,$3c,$4d,$c4,$c8,$df,$c4,$c5,$de,$49,$4f,$4b,$2f,$2e,$32,$2f,$29,$2c,$3c,$41,$3a,$3f,$75,$d3,$f9,$f2,$76,$5a,$47,$3f,$38,$2c,$2e,$2e,$2a,$25,$26,$2c,$2c,$2d,$2f,$32,$38,$3b,$3d,$3c,$42,$46,$48,$42,$42,$54,$59,$59,$6b,$f4,$d2)
const vmsg14 as byte[160]=($c0,$bc,$bd,$bd,$bb,$bd,$c5,$c7,$c3,$c3,$c7,$c0,$ba,$ba,$bf,$bc,$af,$b4,$c1,$bb,$b2,$b9,$c5,$b5,$af,$bd,$c3,$b4,$b4,$ca,$bd,$b5,$ba,$c1,$b8,$ad,$cd,$af,$9c,$9b,$9a,$ad,$a8,$9d,$a3,$ba,$2d,$73,$cc,$29,$1f,$24,$3f,$31,$29,$36,$52,$ba,$c8,$c9,$b7,$b2,$a9,$bb,$e9,$ce,$d2,$50,$2b,$2c,$2f,$27,$25,$24,$2d,$2f,$30,$40,$47,$df,$c6,$c9,$c1,$c3,$ba,$c7,$ef,$ed,$50,$4a,$36,$31,$38,$34,$32,$30,$3c,$49,$46,$59,$70,$c9,$c8,$ce,$c3,$cb,$e7,$4d,$3e,$31,$2b,$2a,$24,$21,$23,$25,$26,$27,$2e,$35,$38,$46,$fc,$ca,$c8,$c6,$bb,$bb,$bd,$c0,$c6,$cf,$dc,$d0,$d7,$dd,$cf,$cd,$dd,$ce,$be,$bf,$be,$b9,$b6,$bc,$bc,$b7,$bf,$c3,$b9,$cc,$63,$bf,$c2,$4a,$46,$c5,$c1,$44)
const vmsg15 as byte[160]=($51,$c6,$be,$d7,$dd,$bb,$bc,$b5,$b8,$cf,$b9,$ab,$b1,$bd,$ab,$a0,$a2,$a2,$9e,$a6,$af,$a8,$ad,$5e,$3a,$58,$3b,$24,$28,$34,$2d,$2a,$36,$47,$4a,$dc,$bd,$c2,$bd,$af,$b2,$c8,$cb,$c1,$5e,$3a,$3a,$38,$2c,$28,$2b,$2d,$2b,$2f,$37,$3b,$4b,$ed,$d7,$c8,$bb,$b7,$be,$bf,$bb,$c9,$fe,$5e,$5c,$45,$3b,$3d,$3a,$3b,$3e,$40,$46,$58,$e0,$e0,$ce,$c4,$bf,$c1,$c4,$c2,$c9,$cd,$3f,$31,$3f,$30,$21,$1f,$29,$28,$1e,$26,$33,$33,$33,$40,$ce,$c5,$be,$b8,$b7,$ac,$ad,$b3,$b9,$b1,$b0,$cf,$de,$cd,$cf,$4c,$3b,$5f,$5d,$46,$41,$51,$d9,$62,$59,$6c,$ce,$ca,$5f,$f5,$cf,$c7,$e6,$5f,$de,$e5,$5f,$4e,$ce,$cf,$5e,$5e,$d8,$c6,$57,$61,$be,$bf,$77,$c5,$b3,$cc,$bc,$ab,$ad,$a9,$9f,$a1)
const vmsg16 as byte[160]=($a9,$a5,$a5,$af,$c3,$cc,$f9,$38,$30,$2e,$2b,$2c,$2d,$2f,$32,$45,$63,$72,$c9,$b9,$b6,$b9,$b5,$b4,$be,$d1,$e8,$5b,$3f,$36,$30,$2d,$2d,$2d,$2d,$2e,$38,$41,$43,$64,$cb,$c5,$bf,$bb,$b6,$b8,$bc,$be,$c8,$d6,$6e,$4d,$43,$3d,$3c,$39,$37,$3b,$40,$43,$4a,$66,$e3,$d8,$ce,$c3,$be,$bf,$c0,$c2,$c9,$c8,$46,$34,$3e,$2e,$25,$25,$2b,$29,$24,$2e,$36,$3a,$48,$e3,$bd,$bd,$af,$ac,$ad,$aa,$ac,$ae,$af,$b9,$c9,$6d,$5c,$4c,$3b,$32,$33,$38,$35,$33,$3d,$4a,$4e,$51,$fa,$ca,$ce,$da,$d4,$d4,$e6,$6c,$f7,$53,$44,$4b,$47,$4d,$4f,$47,$4f,$57,$6a,$6e,$f1,$c8,$ce,$d4,$c0,$ba,$c0,$ca,$b5,$af,$bb,$b2,$a4,$a0,$a2,$9e,$9f,$a8,$a5,$a5,$ba,$62,$dd,$5d,$2e,$2a,$2f,$2e,$29,$2e)
const vmsg17 as byte[160]=($35,$3b,$51,$72,$d4,$bf,$b2,$b3,$ba,$b2,$b4,$c4,$d8,$e6,$51,$3a,$34,$32,$2f,$2e,$2f,$31,$38,$3f,$4a,$58,$ce,$c3,$bf,$ba,$b7,$b6,$bc,$bd,$c1,$da,$f9,$54,$48,$3c,$39,$3a,$35,$36,$3b,$3d,$3f,$4b,$69,$73,$d5,$c4,$c3,$bf,$bc,$bd,$c2,$c6,$bf,$d6,$38,$3a,$42,$2a,$22,$29,$2d,$26,$27,$37,$3b,$3f,$61,$c7,$b7,$b1,$ae,$ae,$ac,$ab,$b7,$bf,$be,$ce,$4d,$37,$3a,$39,$2d,$2b,$30,$39,$36,$3a,$4a,$63,$e1,$e6,$de,$d5,$c8,$cd,$64,$6c,$dc,$5a,$40,$4b,$5a,$3d,$3a,$59,$53,$37,$45,$c2,$eb,$4a,$c6,$b5,$c4,$cf,$bd,$c3,$c5,$cd,$7c,$c1,$b6,$bf,$c2,$ac,$a5,$a5,$9f,$a2,$a4,$a0,$a1,$ac,$c3,$bc,$ea,$32,$2f,$2e,$2b,$25,$28,$2e,$2e,$3d,$4e,$76,$c2,$ba,$b2,$b1,$ae,$af)
const vmsg18 as byte[160]=($b9,$ba,$c8,$e8,$4e,$3d,$39,$31,$30,$2e,$2e,$33,$36,$3d,$45,$69,$d0,$cd,$be,$bb,$b8,$b8,$bc,$bc,$c5,$d0,$72,$4e,$4a,$3c,$36,$36,$35,$35,$35,$37,$3c,$46,$4e,$54,$dd,$cd,$c7,$c4,$c2,$bb,$c0,$c3,$c5,$cc,$d8,$f2,$62,$37,$38,$3a,$2b,$29,$2d,$30,$2c,$2d,$3e,$40,$50,$e6,$c7,$ba,$b6,$af,$b2,$af,$ae,$b9,$bd,$c0,$cb,$59,$47,$45,$37,$34,$33,$34,$36,$35,$3e,$45,$51,$6f,$e0,$c9,$c9,$c3,$c4,$c4,$c0,$d0,$6b,$4f,$fc,$4d,$3a,$52,$53,$42,$41,$56,$76,$47,$67,$e0,$dc,$d6,$ed,$bf,$c4,$d5,$c6,$c8,$cf,$f3,$cf,$d2,$fd,$c5,$c1,$be,$b6,$ad,$a7,$a8,$a3,$a4,$a6,$a7,$ac,$ad,$be,$d9,$6f,$42,$3b,$2f,$31,$2f,$2e,$34,$34,$3f,$46,$57,$db,$cf,$be,$c0,$bc,$bc,$bf,$bf)
const vmsg19 as byte[160]=($d8,$dc,$67,$49,$42,$3a,$3b,$36,$35,$37,$38,$43,$3d,$47,$63,$ef,$d8,$de,$c3,$c0,$c8,$c9,$cd,$ca,$ee,$7b,$65,$4c,$4f,$47,$44,$44,$47,$4d,$47,$58,$60,$65,$dc,$d5,$cb,$ca,$c0,$c2,$c5,$bc,$bf,$c6,$ca,$ca,$dd,$de,$5b,$38,$3c,$37,$2b,$2a,$2d,$2d,$27,$2e,$39,$35,$40,$59,$d9,$c8,$bd,$ba,$ba,$b2,$ba,$c5,$c0,$cc,$5a,$46,$4e,$3e,$33,$38,$37,$36,$3a,$3f,$4b,$5b,$d7,$c8,$bc,$b4,$b2,$b3,$b9,$bc,$bb,$c8,$6f,$63,$e7,$4f,$44,$4d,$49,$4e,$53,$4f,$65,$e5,$dc,$de,$dc,$ce,$c2,$c6,$ce,$c6,$c9,$de,$df,$d1,$de,$d9,$c6,$cc,$d3,$c9,$c7,$ca,$cb,$bf,$ba,$b7,$b6,$b1,$ad,$ae,$b0,$b0,$b1,$ba,$ca,$d5,$ee,$4e,$3f,$3c,$3d,$3b,$38,$38,$3c,$3f,$3f,$40,$4d,$5c,$5f,$63)
const vmsg20 as byte[160]=($e6,$d3,$da,$e8,$e3,$de,$6d,$57,$5d,$5c,$50,$4c,$4f,$55,$55,$51,$59,$69,$5d,$5d,$5b,$62,$fa,$5d,$5d,$6b,$71,$5d,$50,$78,$73,$58,$6c,$e3,$da,$f6,$d6,$cb,$d6,$cd,$cc,$d3,$db,$dd,$db,$6c,$69,$70,$60,$59,$4d,$4b,$49,$47,$3f,$3d,$3f,$3e,$3d,$3e,$43,$45,$42,$4a,$4f,$55,$5a,$67,$f5,$6e,$fa,$e6,$e6,$e0,$df,$d0,$db,$6b,$69,$6c,$56,$4b,$4f,$50,$4c,$48,$50,$5c,$4f,$53,$5d,$6d,$5d,$52,$5c,$5e,$66,$5f,$74,$d9,$df,$e4,$dd,$d0,$d2,$e4,$dd,$dd,$d7,$ed,$6f,$d8,$e3,$5b,$55,$e3,$e2,$5b,$e7,$cb,$c6,$cb,$c8,$bc,$bc,$be,$be,$b8,$b7,$b6,$b2,$b3,$b0,$af,$b5,$b6,$b2,$b7,$bf,$bd,$be,$cf,$d0,$cb,$e8,$72,$dc,$df,$ec,$db,$d8,$e1,$d7,$d3,$f2,$f0,$dd,$72,$69,$f9)
const vmsg21 as byte[160]=($fa,$f8,$61,$5a,$7d,$6a,$55,$5f,$74,$5f,$55,$5e,$5d,$4b,$49,$46,$40,$3f,$3e,$3f,$3f,$42,$40,$3f,$43,$3e,$3b,$3a,$39,$37,$35,$39,$38,$37,$3a,$3c,$3d,$3e,$41,$40,$3f,$43,$43,$46,$49,$4d,$4f,$4e,$56,$59,$55,$55,$59,$59,$57,$60,$6c,$78,$f8,$f0,$e3,$e4,$ee,$ec,$ea,$e1,$e1,$e4,$d3,$d1,$d5,$d0,$ce,$d2,$d4,$d3,$d3,$d0,$cf,$cf,$d1,$d1,$ce,$d3,$ce,$ce,$d6,$d1,$cf,$d0,$da,$d2,$cd,$cf,$cc,$ca,$c4,$c6,$c4,$be,$be,$be,$be,$bf,$c0,$c0,$bf,$c1,$bf,$bd,$bd,$bb,$b8,$b5,$b8,$bc,$b6,$b6,$bd,$c5,$c1,$c0,$ce,$dc,$df,$e2,$6e,$59,$73,$57,$4d,$5b,$53,$54,$4f,$54,$4f,$49,$4d,$45,$43,$45,$44,$44,$42,$49,$46,$46,$49,$47,$4a,$44,$45,$48,$43,$43,$43,$48,$42,$41)
const vmsg22 as byte[153]=($48,$45,$44,$44,$4b,$4c,$48,$4f,$52,$59,$57,$52,$59,$5c,$5d,$54,$57,$5d,$55,$57,$5a,$59,$58,$5d,$63,$5e,$5f,$63,$61,$60,$65,$5f,$5d,$65,$66,$67,$77,$ee,$e9,$eb,$e2,$dc,$de,$de,$de,$da,$d5,$d5,$cf,$cd,$ce,$ce,$ce,$ce,$d5,$d7,$d8,$d8,$d4,$d5,$d0,$cf,$d2,$d4,$d5,$d5,$d6,$d9,$dd,$d8,$d9,$dd,$d9,$d9,$d8,$de,$d9,$d8,$e0,$db,$dc,$db,$db,$da,$d8,$de,$dd,$e6,$e6,$e2,$f2,$eb,$e9,$e3,$e6,$e6,$df,$e9,$ee,$ec,$ed,$f9,$7c,$fa,$7c,$79,$77,$6d,$6e,$6c,$66,$65,$6f,$6c,$5f,$64,$6a,$65,$5e,$60,$64,$5e,$5f,$62,$61,$5f,$5d,$5c,$5c,$5d,$5c,$5c,$5d,$5d,$5d,$60,$69,$62,$62,$6a,$68,$66,$66,$69,$67,$68,$69,$6b,$71,$73,$6f,$70,$7b)
end.


El resultado final en video:

Configurando la página web:



Llamando al PIC:

No hay comentarios:

Publicar un comentario