<% 
' Copyright 2000 Phone.com, Inc.  All rights reserved.
'
'   Subject to the terms and conditions of the SDK License Agreement,
'   Phone.com, Inc. hereby grants you the right to use the UP.SDK
'   software and its related documentation.
'
'   The Phone.com name and logo and the family of terms carrying the "UP."
'   prefix are trademarks of Phone.com, Inc. All other brands and product
'   names may be trademarks of the respective companies with which they
'   are associated.
'
' whoami.asp
'
'   The application reports all UP.Link related information
'   available to an application through HTTP headers
'
'   Key concepts illustrated include:
'       - Parsing HTTP header variables to read UP.Link information
'
'   Note: The "Prefs" selection is accessible only in UPLink mode.
'
'
' Declarations
'
' Global Constants
'
' A newline (linefeed) is appended to each line of WML to
' aid legibility of source dumped to the Sim Info Window.
'
nl  = Chr(10)

Dim cardW, cardU, cardD
Dim deckW, deckF, deckP, deckH
Dim tz, alert, deckTable

' Create a dictionary for use in parsing Request Server Variables 
'
set rsvDict = CreateObject("Scripting.Dictionary")

'
' Routines
'

' Create a dictionary of "?NEXT=" query string arguments,
' to determine the next deck to be constructed dynamically.
' 
Sub CreateStateDictionary()
    set deckTable   = CreateObject("Scripting.Dictionary")
    deckTable.Add   "HOME",     "WhoAmI"
    deckTable.Add   "FAX",      "faxInfo"
    deckTable.Add   "HTTP",     "httpInfo"
    deckTable.Add   "PREFS",    "prefsInfo"
End Sub

Sub ParseAllHTTP()
  ' Parse the set of "ALL_HTTP" Request Server Variables
  '
  Dim allVars, allArray, item, thisArray, thisKey, thisItem, oldItem
  '
  allVars     = Request.ServerVariables("ALL_HTTP")
  
  ' Create an array by splitting on each "HTTP_" string.
  '
  allArray    = Split(allVars, "HTTP_")
  
  ' For each item indexed by the array 
  '
  For i = 0 to UBound(allArray)
      item    = allArray(i)

      If item <> "" Then
      ' Populate a temporary array with this item; then,
      ' split this array into substrings at the colon separator, 
      ' append the "HTTP_" prefix to the first substring,
      ' and introduce an item into the request dictionary 
      ' with the second substring.
      '
          thisArray   = Split(item, ":")
          thisKey     = "HTTP_" & thisArray(0)
          thisItem    = thisArray(1)
          If rsvDict.Exists(thisKey) Then
              oldItem = rsvDict.Item(thisKey)
              If oldItem  <> thisItem Then
                  rsvDict.Remove(thisKey)
                  rsvDict.Add thisKey, thisItem
              End If
          Else
              rsvDict.Add thisKey, thisItem
          End If
      End If
  Next
End Sub

Sub SelectAndSendAdeck()
    ' Check whether a query string was appended to the Request
    '
    If Request.QueryString.Count = 0 Then
        ' No query; so, write out the WhoAmI deck.
        '
        Call CreateWhoAmIDeck()
    Else
        Call GetDeck()
    End If
End Sub

Sub GetDeck()
    nextState   = Request.QueryString.Item("NEXT") 
    Select Case deckTable.Item(nextState)
        Case "WhoAmI"
            Call CreateWhoAmIcard()
            Call WriteDeck(cardW)

        Case "faxInfo"
            Call OutputFaxDeck()

        Case "prefsInfo"
            tz    = Request.QueryString.Item("TZ") 
            alert = Request.QueryString.Item("ALERT")
            Call OutputPrefsDeck()

        Case "httpInfo"
            Call OutputHTTPdeck()

        Case Else
            Call ErrorDeck()
    End Select
End Sub

Sub OutputPrefsDeck()
  deckP =         "<wml>" & nl
  deckP = deckP & "  <card title=""Prefs Info"">" & nl
  deckP = deckP & "    <p mode=""wrap"">"
  deckP = deckP &        "Prefs: "
  deckP = deckP & "    </p>" & nl
  deckP = deckP & "    <p mode=""nowrap"">"
  deckP = deckP &        "TZ: " & tz & nl
  deckP = deckP & "    </p>" & nl
  deckP = deckP & "    <p mode=""nowrap"">"
  deckP = deckP &        "ALERT: " & alert & nl
  deckP = deckP & "    </p>" & nl
  deckP = deckP & "  </card>" & nl
  deckP = deckP & "</wml>" & nl
  Call WriteDeck(deckP)
End Sub

Sub CreateWhoAmIDeck()
'
' Only two of the five cards which a user may choose are included
' in the first deck. If the user selects one of the three remaining
' choices, a card will constructed from a query request to this URL.
'
  Call CreateUPLinkCard()
  Call CreateDeviceCard()
  Call CreateWhoAmIcard()

  deckW =         "<wml>" & nl
  deckW = deckW & cardW & cardU & cardD
  deckW = deckW & "</wml>" & nl
  Call WriteDeck(deckW)
End Sub

Sub CreateWhoAmIcard()
' This card divides the list of user selections into 4 separate digests
' to avoid constructing a digest larger the maximum size of the device.
'
' The "Prefs" option "href="device:home/pref..."" is relevant only in UPLink
' mode; in HTTP-Direct mode "Prefs" should return a "HTTP Error: 404" error,
' unless there happens to be an URI named "pref" at the location specified 
' as the "Home URL" in Device Settings. 
'
  cardW =         "<card>" & nl
  cardW = cardW & "  <p>" & nl
  cardW = cardW & "    <select title=""Who am I"">" & nl
  cardW = cardW & "      <option onpick=""#u"">UP.Link</option>" & nl
  cardW = cardW & "      <option onpick=""#d"">Device</option>" & nl
  cardW = cardW & "      <option onpick=""?NEXT=FAX"">UP.Fax</option>" & nl
  cardW = cardW & "      <option>" & nl
  cardW = cardW & "        <onevent type=""onpick"">" & nl
  cardW = cardW & "          <spawn href=""device:home/pref?get=TZ;Alert"" "
  cardW = cardW &              "onexit="
  cardW = cardW &            " ""?NEXT=PREFS&amp;TZ=$(tz)&amp;ALERT=$(alert)"">"
  cardW = cardW &              nl
  cardW = cardW & "            <receive/>" & nl
  cardW = cardW & "            <receive name=""tz""/>" & nl
  cardW = cardW & "            <receive name=""alert""/>" & nl
  cardW = cardW & "          </spawn>" & nl
  cardW = cardW & "        </onevent>" & nl
  cardW = cardW & "        Prefs" & nl
  cardW = cardW & "      </option>" & nl
  cardW = cardW & "      <option onpick=""?NEXT=HTTP"">HTTP</option>" & nl
  cardW = cardW & "    </select>" & nl
  cardW = cardW & "  </p>" & nl
  cardW = cardW & "</card>" & nl
End Sub

Sub CreateUPLinkCard()
  cardU =         "<card id=""u"" title=""UP.Link Info"">" & nl
  cardU = cardU & "  <p mode=""nowrap"">"
  cardU = cardU &      "SubNo: " & rsvDict.Item("HTTP_X_UP_SUBNO") & nl
  cardU = cardU & "  </p>" & nl
  cardU = cardU & "  <p mode=""nowrap"">"
  cardU = cardU &      "UP.Link: " & rsvDict.Item("HTTP_X_UP_UPLINK") & nl
  cardU = cardU & "  </p>" & nl
  cardU = cardU & "</card>" & nl
End Sub

Sub CreateDeviceCard()
  Dim upDevice, qArray

  If rsvDict.Exists("HTTP_USER_AGENT") Then
    qArray    = Split(rsvDict.Item("HTTP_USER_AGENT"), " ")
    upDevice  = qArray(0)
  End If
  
  cardD =         "<card id=""d"" title=""Device Info"">" & nl
  cardD = cardD & "  <p mode=""nowrap"">"
  cardD = cardD &      "SubNo: " & rsvDict.Item("HTTP_X_UP_SUBNO") & nl
  cardD = cardD & "  </p>" & nl
  cardD = cardD & "  <p mode=""nowrap"">"
  cardD = cardD &      "UP.Link: " & rsvDict.Item("HTTP_X_UP_UPLINK") & nl
  cardD = cardD & "  </p>" & nl
  cardD = cardD & "  <p mode=""nowrap"">"
  cardD = cardD &      "Device ID: " & upDevice & nl
  cardD = cardD & "  </p>" & nl
  cardD = cardD & "  <p mode=""wrap"">"
  cardD = cardD &      "User Agent: " & rsvDict.Item("HTTP_USER_AGENT") & nl
  cardD = cardD & "  </p>" & nl
  cardD = cardD & "  <p mode=""wrap"">"
  cardD = cardD &      "Screen Chars(x,y): " 
  cardD = cardD &      rsvDict.Item("HTTP_X_UP_DEVCAP_SCREENCHARS") & nl
  cardD = cardD & "  </p>" & nl
  cardD = cardD & "  <p mode=""wrap"">"
  cardD = cardD &      "Screen Pixels(x,y): " 
  cardD = cardD &      rsvDict.Item("HTTP_X_UP_DEVCAP_SCREENPIXELS") & nl
  cardD = cardD & "  </p>" & nl
  cardD = cardD & "  <p mode=""wrap"">"
  cardD = cardD &      "Screen Depth: " 
  cardD = cardD &      rsvDict.Item("HTTP_X_UP_DEVCAP_SCREENDEPTH") & nl
  cardD = cardD & "  </p>" & nl
  cardD = cardD & "  <p mode=""wrap"">"
  cardD = cardD &      "M-Size: " 
  cardD = cardD &      rsvDict.Item("HTTP_X_UP_DEVCAP_MSIZE") & nl
  cardD = cardD & "  </p>" & nl
  cardD = cardD & "  <p mode=""wrap"">"
  cardD = cardD &      "Has Color: " 
  cardD = cardD &      rsvDict.Item("HTTP_X_UP_DEVCAP_ISCOLOR") & nl
  cardD = cardD & "  </p>" & nl
  cardD = cardD & "  <p mode=""wrap"">"
  cardD = cardD &      "Soft keys: " 
  cardD = cardD &      rsvDict.Item("HTTP_X_UP_DEVCAP_NUMSOFTKEYS") & nl
  cardD = cardD & "  </p>" & nl
  cardD = cardD & "  <p mode=""wrap"">"
  cardD = cardD &      "Softkey label size: " 
  cardD = cardD &      rsvDict.Item("HTTP_X_UP_DEVCAP_SOFTKEYSIZE") & nl
  cardD = cardD & "  </p>" & nl
  cardD = cardD & "  <p mode=""wrap"">"
  cardD = cardD &      "Max Digest Size: " 
  cardD = cardD &      rsvDict.Item("HTTP_X_UP_DEVCAP_MAX_PDU") & nl
  cardD = cardD & "  </p>" & nl
  cardD = cardD & "  <p mode=""wrap"">"
  cardD = cardD &      "Immediate Alert Support: " 
  cardD = cardD &      rsvDict.Item("HTTP_X_UP_DEVCAP_IMMED_ALERT") & nl
  cardD = cardD & "  </p>" & nl
  cardD = cardD & "</card>" & nl
End Sub

Sub OutputFaxDeck()
  deckF =         "<wml>" & nl
  deckF = deckF & "  <card title=""Fax Info"">" & nl
  deckF = deckF & "    <p mode=""nowrap"">"
  deckF = deckF &        "Fax Limit: " 
  deckF = deckF &      rsvDict.Item("HTTP_X_UP_FAX_LIMIT") & nl
  deckF = deckF & "    </p>" & nl
  deckF = deckF & "    <p mode=""wrap"">"
  deckF = deckF &        "Fax accepts: " 
  deckF = deckF &      rsvDict.Item("HTTP_X_UP_FAX_ACCEPTS") & nl
  deckF = deckF & "    </p>" & nl
  deckF = deckF & "    <p mode=""wrap"">"
  deckF = deckF &        "Fax encodings: " 
  deckF = deckF &      rsvDict.Item("HTTP_X_UP_FAX_ENCODINGS") & nl
  deckF = deckF & "    </p>" & nl
  deckF = deckF & "  </card>" & nl
  deckF = deckF & "</wml>" & nl
  Call WriteDeck(deckF)
End Sub

Sub OutputHTTPdeck()
  deckH =         "<wml>" & nl
  deckH = deckH & "  <card title=""HTTP Info"">" & nl
  deckH = deckH & "    <do type=""accept""><prev/></do>"
  deckH = deckH & "    <p mode=""wrap"">"
  deckH = deckH &        "Accepts: " 
  deckH = deckH &        rsvDict.Item("HTTP_ACCEPT") & nl
  deckH = deckH & "    </p>" & nl
  deckH = deckH & "    <p mode=""wrap"">"
  deckH = deckH &        "Charset: " 
  deckH = deckH &        rsvDict.Item("HTTP_ACCEPT_CHARSET") & nl
  deckH = deckH & "    </p>" & nl
  deckH = deckH & "    <p mode=""wrap"">"
  deckH = deckH &        "Encoding: " 
  deckH = deckH &        rsvDict.Item("HTTP_ACCEPT_ENCODING") & nl
  deckH = deckH & "    </p>" & nl
  deckH = deckH & "    <p mode=""wrap"">"
  deckH = deckH &        "Language: " 
  deckH = deckH &        rsvDict.Item("HTTP_ACCEPT_LANGUAGE") & nl
  deckH = deckH & "    </p>" & nl
  deckH = deckH & "    <p mode=""wrap"">"
  deckH = deckH &        "Referer: " 
  deckH = deckH &        rsvDict.Item("HTTP_REFERER") & nl
  deckH = deckH & "    </p>" & nl
  deckH = deckH & "  </card>" & nl
  deckH = deckH & "</wml>" & nl
  Call WriteDeck(deckH)
End Sub

Sub ErrorDeck()
'
' An unexpected URL was provided; try to format and report it. 
'
' Reserved WML characters will need to be escaped in formatted text.
'
  Dim apostrophe, quote, less_than, greater_than, ampersand
  apostrophe    = Chr(39)
  quote         = Chr(34)
  less_than     = Chr(60)
  greater_than  = Chr(62)
  ampersand     = Chr(38)
  dollar_sign   = Chr(36)

' Reconstruct the string passed from the Browser.
'
  anURL = Request.ServerVariables("SERVER_NAME")
  anURL = anURL & Request.ServerVariables("URL")
  aqStr = Request.ServerVariables("QUERY_STRING")
  aqStr = Replace(aqStr, apostrophe, "&apos;")
  aqStr = Replace(aqStr, quote, "&quot;")
  aqStr = Replace(aqStr, less_than, "&lt;")
  aqStr = Replace(aqStr, greater_than, "&lt;")
  aqStr = Replace(aqStr, ampersand, "&amp;")
  aqStr = Replace(aqStr, dollar_sign, "$$")

  deckE =         "<wml>" & nl
  deckE = deckE & "  <card>" & nl
  deckE = deckE & "    <p>" & nl
  deckE = deckE & "      Invalid URL: " & anURL & "?" & aqStr & nl
  deckE = deckE & "    </p>" & nl
  deckE = deckE & "  </card>" & nl
  deckE = deckE & "</wml>" & nl
  Call WriteDeck(deckE)
End Sub

' Subroutine to dispatch a deck in a digest to the subscriber
'
Sub WriteDeck(aDeck)

    ' Create a new COM Digest object.
    '
    set myDigest            = Server.CreateObject("PDCDigestUtils.CPDCDigest")
    
    ' Add the deck to the digest object.
    '
    myDigest.DigestAddDeck "", aDeck
    
    ' Suppress content type output within the digest to prevent a 
    ' server from encapsulating WML content within a second boundary.
    '
    myDigest.DigestSuppressContentType 1
    
    ' Serialize the digest into a single output buffer, digestString.
    '
    digestString    = myDigest.DigestSerialize(0)
    
    ' Specify a deck of type WML to the digest object.
    '
    myDigest.DeckType         = 1
 
    ' Specify content type through the server response, 
    ' rather than within the digest.
    '
    Response.ContentType    = myDigest.DigestGetContentType
    
    ' Write the response buffer to the client.
    '
    Response.BinaryWrite(digestString)

End Sub

Sub Main()

  Call CreateStateDictionary()

  Call ParseAllHTTP()

  Call SelectAndSendAdeck()

End Sub

' Main begins here.
'
Call Main
%>

