Difference between revisions of "User:Pixel Gausman/Interop Viewer"

From Second Life Wiki
Jump to: navigation, search
(Assets and Inventory)
(Open Grid Protocol implementation in Snowglobe)
 
(37 intermediate revisions by 2 users not shown)
Line 1: Line 1:
== Open Grid Protocol implementation in SnowGlobe ==
+
== Open Grid Protocol implementation in Snowglobe ==
 +
 
 +
This page is only for describing the OGP implementation of the viewer, not general OGP protocol description.
  
 
Open Grid Protocol (OGP) currently includes a style of login and teleport that separates control  
 
Open Grid Protocol (OGP) currently includes a style of login and teleport that separates control  
of the agent into a separate domain named agent domain (sometimes shortened to agentd or even AD).  
+
of the agent into a separate domain named agent domain (also called agentd or agent service). This separate service
It is a protocol under development, and that's why we need it in SnowGlobe. I've developed a patch for SnowGlobe to  
+
handles moving an avatar from region to region, including between regions that are run by different entities. This
 +
is helpful to end users because they can maintain a consistent appearance and inventory as they move from region to
 +
region. They can also trust the agent service to maintain their
 +
inventory without having to "hand over the keys" to their inventory to every region they visit.
 +
 
 +
 +
It is a protocol under development, and that's why we need it in Snowglobe. I've developed a patch for Snowglobe to  
 
enable OGP. Protocols are best standardized with the experience of implementation, and I believe  
 
enable OGP. Protocols are best standardized with the experience of implementation, and I believe  
 
OGP needs a publicly available implementation to experiment with. An open implementation
 
OGP needs a publicly available implementation to experiment with. An open implementation
 
will help ground the design of protocols in the reality of working code that the community can work with.  
 
will help ground the design of protocols in the reality of working code that the community can work with.  
 +
 +
Note:  IBM has open sourced an OGP implementation for the community to experiment with ( http://forge.opensimulator.org/gf/project/ogp/ ). If you are running an AD or OGP regions, lease let Pixel know! .
  
 
OGP protocols are not supported on the main Linden grid or the Linden test grid, which for now is a good thing.  
 
OGP protocols are not supported on the main Linden grid or the Linden test grid, which for now is a good thing.  
Line 16: Line 26:
 
inventory, and resolving remote assets do not exist on the Linden Lab main grid or test grid, so  
 
inventory, and resolving remote assets do not exist on the Linden Lab main grid or test grid, so  
 
no assets/inventory will cross the boundary between Second Life and OpenSim by using this  
 
no assets/inventory will cross the boundary between Second Life and OpenSim by using this  
viewer unless Linden enables it in their deployment.OpenSim grids that choose to expose the interfaces can  
+
viewer unless Linden enables it in their server side deployment.OpenSim grids that choose to expose the interfaces can  
experiment with distributed assets and with an inventory that is maintained by the agent domain.  
+
experiment with distributed assets and with an inventory and library that are maintained by the agent domain.  
  
'''Note:''' If appropriate, at some point OGP references in the code and this wiki page will need to be changed to match the IETF working group name.
+
'''Note:''' If appropriate, I intend to replace OGP references in the code and this wiki page to match the IETF working group name of VWRAP.
 +
 
 +
General information about OGP is at https://wiki.secondlife.com/wiki/User:Infinity_Linden/IETF_Drafts_and_Meetings
 +
until the IETF working group is officially formed. General information about IBM's open source OGP implementation is at TBD.
  
 
== OGP History ==
 
== OGP History ==
  
OGP was developed by LL with input from the Architecture Working Group (AWG). OGP's initial proof of concept implementation was a joint project between
+
The original OGP specs ware developed by Linden Lab with input from the Architecture Working Group (AWG). OGP's initial proof of concept implementation was a joint project between
LL and IBM.  IBM did a portion of that OGP viewer code with some help from Linden developers. The viewer code for that initial  
+
Linden Lab and IBM.  IBM did a portion of that OGP viewer code with some help from Linden developers. The viewer code for that initial  
 
Proof of Concept is currently located in the OGP9 public svn branch. I ported the OGP9
 
Proof of Concept is currently located in the OGP9 public svn branch. I ported the OGP9
branch to SnowGlobe, gave the code some cleanup, and added some of the additional inventory caps we have been experimenting with.  
+
branch to Snowglobe, gave the code some cleanup, and added some of the additional inventory caps we have been experimenting with.  
 
The additional caps are not supported in Linden's agent domain implementation, so no assets/inventory
 
The additional caps are not supported in Linden's agent domain implementation, so no assets/inventory
will cross the boundary between Second Life and OpenSim by using this viewer unless Linden enables it.
+
will cross the boundary between Second Life and OpenSim by using this viewer unless Linden adds additional interfaces to their agent domain.
  
When looking at the patch, gentle readers, please remember that it was originally proof of concept level code.
+
When looking at the patch, gentle readers, please remember that it was originally proof of concept level code, and that the OGP drafts are a moving target.
  
 
== Implementation ==
 
== Implementation ==
  
OGP viewer code affects small portions of the UI, added some command line parameters, modified the login and teleport sequences, and
+
OGP viewer code affects small portions of the UI, adds some command line parameters, modifies the login and teleport sequences, and
 
implements some additional agent domain caps involving inventory and assets.  
 
implements some additional agent domain caps involving inventory and assets.  
  
Line 40: Line 53:
 
=== UI ===
 
=== UI ===
  
If -ogp is passed on the command line, the panel_login layout is modified. Last/Home/Region has no meaning in OGP, so that space
+
If --ogp is passed on the command line, the panel_login layout is modified. Last/Home/Region has no meaning in OGP, so that space in the panel is instead used for the regionuri_edit combo box. The user enters the region uri in this combo box.   
in the panel is instead used for the regionuri_edit combo box. The user enters the region uri in this combo box.   
+
"Start Location:" is used in both instances, because from an end user point of view, a region uri is a starting location.   
"Start Location:" is used in both instances,because from an end user point of view, a region uri is a starting location.   
+
 
The combo box is populated using URIs that are saved in a LLURLHistory named "region_uri", but only if the  
 
The combo box is populated using URIs that are saved in a LLURLHistory named "region_uri", but only if the  
user's First/Last name is saved. This is because if I don't have a First/Last when building the login panel, it's impossible
+
user's First/Last name is saved. This is because if I don't have a First/Last when building the login panel, it's impossible to pull/save *user* specific data (like the specific LLURLHistory for the user Pixel Gausman). The selected entry for the combo box is set to the command line parameter --regionuri ( gSavedSettings.getString("CmdLineRegionURI")), which is an additional way to specify the desired initial region.
to pull/save *user* specific data (like the specific LLURLHistory for the user Pixel Gausman). The selected entry for the combo box  
+
is set to the command line parameter --regionuri ( gSavedSettings.getString("CmdLineRegionURI")),  
+
which is an additional way to specify the desired initial region.
+
  
Also enabled/disabled by the -ogp command line switch is the "Teleport Region..." selection in the World menu.  
+
Also enabled/disabled by the --ogp command line switch is the "Teleport Region..." selection in the new "Interop" submenu under the "Advanced" menu.  
 
This menu selection pops a floater that allows teleport via OGP, it also uses the LLURLHistory to store region uris.   
 
This menu selection pops a floater that allows teleport via OGP, it also uses the LLURLHistory to store region uris.   
The floater can also be popped via Ctrl-Alt-Shift-L.
+
The floater can also be popped via Ctrl-Alt-Shift-R.
 
+
 
+
 
+
  
 
=== Command line parameters ===
 
=== Command line parameters ===
  
;-ogp
+
;--ogp
 
:  enables OGP mode. Viewer is either OGP or non OGP for the life of the session
 
:  enables OGP mode. Viewer is either OGP or non OGP for the life of the session
 
;--regionuri  <uri>
 
;--regionuri  <uri>
Line 73: Line 79:
 
If you are part of the OGP beta from Summer 08 (yay Gridnauts!), this would be the command line parameter to authenticate against vaak, where <regionuri> comes from http://wiki.secondlife.com/wiki/Open_Grid_Public_Beta/Public_Regions#Linden_Lab_OGP_Regions :
 
If you are part of the OGP beta from Summer 08 (yay Gridnauts!), this would be the command line parameter to authenticate against vaak, where <regionuri> comes from http://wiki.secondlife.com/wiki/Open_Grid_Public_Beta/Public_Regions#Linden_Lab_OGP_Regions :
  
  -ogp --set PurgeCacheOnNextStartup TRUE  --regionuri  <regionuri>  --loginuri https://login1.aditi.lindenlab.com/cgi-bin/auth.cgi
+
  --ogp --set PurgeCacheOnNextStartup TRUE  --regionuri  <regionuri>  --loginuri https://login1.aditi.lindenlab.com/cgi-bin/auth.cgi
  
 
=== Login sequence ===
 
=== Login sequence ===
  
The login sequence for SnowGlobe is messier than what exists in OGP9 SVN. This is because OGP9 did not
+
The login sequence for Snowglobe is messier than what exists in OGP9 SVN. This is because OGP9 did not
 
support XML-RPC style logins, and the removal of the XML-RPC path in OGP9 made the code simpler. We will need to maintain
 
support XML-RPC style logins, and the removal of the XML-RPC path in OGP9 made the code simpler. We will need to maintain
the XML-RPC path in SnowGlobe, so the patch attempts to do that with minimal disturbance (and therefore risk) to the XML-RPC code path.  
+
the XML-RPC path in Snowglobe, so the patch attempts to do that with minimal disturbance (and therefore risk) to the XML-RPC code path.  
  
  
Line 91: Line 97:
  
 
After the overly complex STATE_LOGIN_PROCESS_RESPONSE section of the code, OGP and XMLRPC processing are essentially the  
 
After the overly complex STATE_LOGIN_PROCESS_RESPONSE section of the code, OGP and XMLRPC processing are essentially the  
same in STATE_WORLD_INIT and onward. The viewer still does it's handshake with the region, and goes through  
+
same in STATE_WORLD_INIT and onward. The viewer still does its handshake with the region, and goes through  
it's AgentMovementComplete processing. In our initial POC coding last year, we had experimented with
+
its AgentMovementComplete processing. In our initial POC coding last year, we had experimented with
 
getting rid of AgentMovementComplete messages, but were unsuccessful.   
 
getting rid of AgentMovementComplete messages, but were unsuccessful.   
  
 
The login sequence is intended to work for agent domains that do not expose inventory and asset HTTP caps (like the one on
 
The login sequence is intended to work for agent domains that do not expose inventory and asset HTTP caps (like the one on
vaak). It has been tested with vaak for login and teleport, despite vaak being slightly tempermental. Members if Gridnauts group
+
vaak). It has been tested with vaak for login and teleport, despite vaak being slightly temperamental. Members of the Gridnauts group
on Aditi should be able to test with vaak, but vaak has intermittent issues with login.
+
on Aditi should be able to test with vaak, but be warned that vaak has intermittent issues with login.  
 
+
One difference between this viewer and the OGP9 branch is that this viewer does not include LLSD "legacy" login, only XMLRPC legacy and OGP.  
+
  
 +
On logout, instead of sending a UDP message to the region, in OGP a rez_avatar/place request is sent with a null URI. The null URI signals to the agent domain that it should derez the agent from its current region.
  
 +
One difference between this viewer and the OGP9 SVN branch is that this viewer does not include LLSD "legacy" login, only XMLRPC legacy and OGP.
  
 
=== Teleport sequence ===
 
=== Teleport sequence ===
  
The user invokes OGP teleport via Ctrl-Alt-Shift-L or 'Teleport Region...' in the World menu. This pops up  
+
The user invokes OGP teleport via Ctrl-Alt-Shift-R or 'Teleport Region...' in the World menu. This pops up  
 
an instance of LLFoaterTeleport, which has a combo box of the same region_uri LLURLHistory.  
 
an instance of LLFoaterTeleport, which has a combo box of the same region_uri LLURLHistory.  
 
LLFloaterTeleport's function in life is to make a rez_avatar/place request on the agent domain using the URI
 
LLFloaterTeleport's function in life is to make a rez_avatar/place request on the agent domain using the URI
Line 113: Line 119:
  
 
After the response to rez_avatar/place is received from the agentd, the code for Teleport is very similar to XML-RPC Teleport.
 
After the response to rez_avatar/place is received from the agentd, the code for Teleport is very similar to XML-RPC Teleport.
 
  
 
=== Assets and Inventory ===
 
=== Assets and Inventory ===
  
 
Inventory can now be managed by the agent domain, and fetched via HTTP using agent/inventory cap.  
 
Inventory can now be managed by the agent domain, and fetched via HTTP using agent/inventory cap.  
Temporarily Inventory manipulation still goes through UDP.  The UDP calls in OpenSim are  
+
Temporarily Inventory manipulation (CreateInventoryItem, etc.) still goes through UDP.  The UDP calls in OpenSim are  
reflected to the agent domain for handling.  This was done as a temporary measure until proper  
+
reflected to the agent domain via an HTTP interface for handling.  This was done as a temporary measure until proper  
 
HTTP Inventory manipulation calls could be designed properly and done from the viewer.  
 
HTTP Inventory manipulation calls could be designed properly and done from the viewer.  
  
Line 125: Line 130:
 
code in the viewer, with the cap renamed to be '''agent/inventory''' for the agentd case. For the time being, the  
 
code in the viewer, with the cap renamed to be '''agent/inventory''' for the agentd case. For the time being, the  
 
format of agent/inventory is the same as WebFetchInventoryDescendents.  
 
format of agent/inventory is the same as WebFetchInventoryDescendents.  
In cases where there is both a agent/inventory cap on the agent domain and a WebFetchInventoryDescendents cap on
+
In cases where there is both an agent/inventory cap on the agent domain and a WebFetchInventoryDescendents cap on
 
the region, the cap on the agent domain is used.   
 
the region, the cap on the agent domain is used.   
  
There is a new cap in agentd called '''agent/inventory-skeleton'''. It's responder, LLInventorySkeletonResponder,  
+
There is a new cap in agentd called '''agent/inventory-skeleton'''. Its responder, LLInventorySkeletonResponder,  
 
grabs the skeleton, and also makes a new (dangerous?) assumption.  
 
grabs the skeleton, and also makes a new (dangerous?) assumption.  
 
It assumes that content["Skeleton"][0]["folder_id"] is the inventory-root UUID. It makes sense,  
 
It assumes that content["Skeleton"][0]["folder_id"] is the inventory-root UUID. It makes sense,  
but is a change to how things worked in legacy mode. In legacy XML-RPC authentication, the inventory-root  
+
but it is a change compared to how things worked in legacy mode. In legacy XML-RPC authentication, the inventory-root  
 
UUID is passed back from authenticate, separate from the skeleton.  Just like agent/inventory, the values  
 
UUID is passed back from authenticate, separate from the skeleton.  Just like agent/inventory, the values  
 
passed back for agent/inventory-skeleton mimic the values received in an XML-RPC login.  
 
passed back for agent/inventory-skeleton mimic the values received in an XML-RPC login.  
  
The interfaces of agent/inventory and agent/inventory-skeleton will change as the design of agent domain moves forward.
+
 
 +
The interfaces of agent/inventory and agent/inventory-skeleton will change as the design of agent domain moves forward.
 +
Also, assets will eventually be distributed, meaning that a region on a grid might contain an asset that is not stored
 +
on that grid. An agent's inventory might be made up of items scattered across the web.
 +
This means some interesting protocol changes, while keeping an eye on performance.
  
 
== Shortcomings, future needs, and dirty laundry ==
 
== Shortcomings, future needs, and dirty laundry ==
Line 141: Line 150:
 
;Refactor Teleport
 
;Refactor Teleport
 
:  The teleport code needs to be refactored into a new class when OGP support is added for:
 
:  The teleport code needs to be refactored into a new class when OGP support is added for:
#LLAgent::telportViaLure - This function is invoked when one agent offers one or more other agents to teleport to her location LLAgent::teleportViaLure() is called when current agent has accepted a lure and desires to TP to a friend.  Currently all the protocol gives me is a lure_id. I'd really like to get a region_uri, so a protocol change would be needed.
+
#LLAgent::teleportViaLure - This function is invoked when one agent offers one or more other agents to teleport to her location. LLAgent::teleportViaLure() is called when the current agent has accepted a lure and desires to TP to a friend.  Currently all the protocol gives me is a lure_id. I'd really like to get a region_uri, so a protocol change would be needed.
 
#LLAgent::teleportViaLandmark - Similar to teleportViaLure issue. I have a landmark_asset_id, and need a URI.  
 
#LLAgent::teleportViaLandmark - Similar to teleportViaLure issue. I have a landmark_asset_id, and need a URI.  
#LLAgent::teleportVialocation - This is invoked from about a dozen different places in the viewer. A global position is passed in, which is then used to compute the regionhandle. With the regionhandle, the legacy teleportRequest() is called. The assumptions around the use of regionhandle need to be reworked in the viewer (and in the OGP protocol).  
+
#LLAgent::teleportViaLocation - This is invoked from about a dozen different places in the viewer (for instance, when the user clicks on the map). A global position is passed in, which is then used to compute the regionhandle. With the regionhandle, the legacy teleportRequest() is called. The assumptions around the use of regionhandle need to be reworked in the viewer (and in the OGP protocol).  
  
 
;regionhandles
 
;regionhandles
:The viewer assumes that all regions it can get to are arranged in one contiguous XY grid. It's not its fault, when the viewer was written, there *was* only one grid. A region's regionhandle denotes its XY location in the one known grid, i.e. where it shows up on the map. When teleporting between two distinct grids, it is very possible that two regions report the same regionhandle. This makes the viewer very unhappy. The viewer uses the regionhandle to check that an XY location is a valid region that the viewer has a connection to, and to do location based things like determine neighboring regions. It's even checked when determining if you are flying. When doing In the OGP beta, we worked around this issue by having all the OGP region owners register their regionhandles on a website. That allowed us to avoid the issue. Longer term, the issue needs to be resolved differently.  
+
:The viewer assumes that all regions it can get to are arranged in one contiguous XY grid. It's not its fault, when the viewer was written, there ''was'' only one grid. A region's regionhandle denotes its XY location in the one known grid, i.e. where it shows up on the map. When teleporting between two distinct grids, it is very possible that two regions report the same regionhandle. This makes the viewer very unhappy. The viewer uses the regionhandle to check that an XY location is a valid region that the viewer has a connection to, and to do location based things like determine neighboring regions. It's even checked when determining if you are flying.  In the OGP beta, we worked around this issue by having all the OGP region owners register their regionhandles on a website. That allowed us to avoid the issue. Longer term, the issue needs to be resolved differently.  
 +
 
 
;STATE_LOGIN_PROCESS_RESPONSE
 
;STATE_LOGIN_PROCESS_RESPONSE
:This section of idle_startup() is rather brittle, and will be easy to break. Consider rewriting it, or separating XML-RPC and OGP into two different states instead of both of them using STATE_LOGIN_PROCESS_RESPONSE. I think the original OGP9 code usedSTATE_LOGIN_PROCESS_RESPONSE as a common state between legacy and OGP because OGP9 only dealt with LLSD login (and had chopped all the XML-RPC code.
+
:This section of idle_startup() is rather brittle, and will be easy to break. Consider rewriting it, or separating XML-RPC and OGP into two different states instead of both of them using STATE_LOGIN_PROCESS_RESPONSE. I think the original OGP9 code used STATE_LOGIN_PROCESS_RESPONSE as a common state between legacy and OGP because OGP9 only dealt with LLSD login (and had chopped all the XML-RPC code.)
  
 
;makeNewOutfit() crashes when in OGP mode.  
 
;makeNewOutfit() crashes when in OGP mode.  
 
:In the original Proof of Concept, we chose to disable the UI button for Make New Outfit.  It has been re-enabled, and needs to be fixed for both agent domains that support inventory, and ones that do not.  
 
:In the original Proof of Concept, we chose to disable the UI button for Make New Outfit.  It has been re-enabled, and needs to be fixed for both agent domains that support inventory, and ones that do not.  
  
;PurgeCacheOnNextStartup   
+
;PurgeCacheOnNextStartup flag  
:This flag is only needed in OGP mode, test the viewer without this flag and make sure viewer's internal caching mechanisms work with OGP. Careful definition of the testing scenarios need to be defined, and it needs to work with agent domains that do not support Inventory.  
+
:This flag is only needed in OGP mode, we need to test the viewer without this flag and make sure viewer's internal caching mechanisms work with OGP. Careful definition of the testing scenarios need to be done, and it also needs to work with agent domains that do not support Inventory.  
  
 
;LLPlaceAvatarTeleportResponder
 
;LLPlaceAvatarTeleportResponder
:Rework how values are caught from the rez_avatar/place responder, and put into mResult. Currently I think we might wipe out some mResult values on teleport.  
+
:Rework how values are caught from the rez_avatar/place responder, and put into mResult. Currently I think we might wipe out some mResult values on teleport.
 +
 
 +
== Snowglobe Mysterious Future -Pixel's wishlist ==
 +
# enhance event queue code - OGP requires a more complex handling of events on the event queue
 +
# regionhandle rework - see above in dirty laundry section. this might also fix SVC-2941 .
 +
# inventory UDP->caps
 +
# remove secondlife.com and lindenlab.com assumptions in the viewer
 +
# change map tiles to be a cap instead of hardcoded to amazon.com
 +
# cleanup run thru logging output for OGP, especially event queue spamming
 +
# implement Mana Janus' gridinfo type functionality for managing URIs on different grids
 +
# implement a SNOW-129 type feature to allow multiple user names/password to be stored
 +
# pluggable authentication model - allow things like OpenID and LDAP to be used
 +
 
 +
== Test Plan ==
 +
 
 +
=== Objectives ===
 +
Exercise agent related capability in the areas of login, teleport in the viewer for both OGP and non-OGP logins, with a focus on non-OGP mode testing.
 +
 
 +
=== Procedures for non-OGP testing ===
 +
==== Login ====
 +
* Validate login failure in non-OGP mode
 +
# Launch the viewer with no additional command line parameters
 +
# Enter bogus First/Last/password, and in the Start Location, type 'Ahern'
 +
# After attempted login, verify that the viewer displays one error dialog (and one only...) and comes back to the same login screen
 +
* Validate login panel UI and Agni login
 +
# Launch the viewer with no additional command line parameters
 +
# Validate that the combobox next to Start Location has : home, last, and region as the choices, and it can be toggled on/off in Preferences floater on General tab
 +
# Enter First/Last/password, and in the Start Location, type 'Ahern'
 +
# Login to Agni
 +
# Ensure that My Inventory in your Inventory folder is populated.
 +
# Search for an item in your inventory (thus kicking off large inventory fetch)
 +
# Move an Inventory item from Landmarks to Clothes
 +
* Login to Aditi using Grids combobox
 +
# Launch viewer to login panel. Ctrl-Shift-G toggle Grid Box if not already displayed.
 +
# Select Aditi and click login
 +
# Validate that agent rezzes with expected appearance and wearables, and Inventory Folder has contents you'd expect
 +
# Validate that the AVs friends list is correct by clicking Contacts in the Communicate window
 +
# After logout, validate that with default logcontrol.xml, there isn't extra OGP related messages going into the SecondLife.log
 +
* Login to OpenSim using --loginuri. (Note: you can register for an osgrid AV at http://www.osgrid.org/ login instructions at http://www.osgrid.org/docs/instructions.htm)
 +
# Create a Windoze shortcut with the additional command line options, or otherwise launch the viewer with the command line: -loginuri http://osgrid.org:8002 -loginpage http://osgrid.org/loginscreen.php  -helperuri http://osgrid.org/ 
 +
*Login to Agni by launching the viewer with a SLURL in firefox : http://slurl.com/secondlife/Ahern/128/10/50
 +
# Validate that the landmark you moved into Clothes folder in Test 1 above is still in Clothes folder
 +
 
 +
With a new AV on OSgrid, you might (as of Sept 2) need to create Skin and create Hair and wear it to get your texture bakes to happen properly. To create Skin/Hair, open Inventory, then Create->BodyParts->Hair in the Inventory floater menu, then right click on the created hair item, and select Wear. Do the same for Skin.
 +
 
 +
==== Teleport ====
 +
For each type of test, validate these things after the completion of a Teleport:
 +
# The progress bar during teleport slowly fills up as a teleport progresses
 +
# Your AV arrives and can navigate in the region ( try to walk in a circle)
 +
# The objects in the surrounding region look appropriate (you shouldn't see a mixture of objects from the source and destination regions jumbled together),
 +
# Your AV rezzes properly. Avatar appearance should be validated from both your viewer session, and with a second viewer session that has your AV in its camera view. This is because the viewer's caching can play tricks on you. So validate wearables, texture bakes, and attachments by observing your AV from a second viewer
 +
# After TP is complete, a message in Local chat appears: "Teleport completed from http://slurl.com/secondlife/Morris/11/195/59" (change Morris to whatever your source region for the TP was)
 +
 
 +
* Teleport via Landmark
 +
# Open Landmarks folder in My Inventory, double click on a landmark to open it, and click teleport.
 +
*Teleport via Location
 +
# Open the Map, double click in the region next to you, this should invoke a TP
 +
# Open the Map, double click a region that is 3 regions away
 +
*Teleport Via Lure
 +
# Login as AV1 in Ahern on Agni
 +
# Login as AV2 in IBM
 +
# AV2 double clicks on AV1 in her friends list to bring up AV1's profile
 +
# AV2 clicks "offer teleport" to AV1
 +
# AV1 accepts the TP offer
 +
# AV1 is teleported to IBM
 +
 
 +
* Teleport Home
 +
# Ctrl-Alt-Shift-H should TP you to wherever your Home location is set
 +
 
 +
*Validate that Ctrl-Alt-Shift-L does *not* bring up the OGP Teleport floater,  and that "Teleport Region..." in the World menu is disabled
 +
 
 +
==== Region Crossing ====
 +
* Validate agent crossing between two touching regions
 +
# Go to the edge of Ahern, http://slurl.com/secondlife/Ahern/10/10/50 and walk between the adjoining regions.
 +
# Watch the Region name and XYZ location in the menu bar to validate that you crossed the region successfully.
 +
# Make sure you can walk around the region, and make sure you don't lose Voice connection.
 +
# Validate that your Inventory looks correct in the Clothing folder of My Inventory
 +
 
 +
 
 +
==== Browser history ==== 
 +
 
 +
* OGP makes use of the LLURLHistory class, so test out that url history is properly saved for non-OGP usage
 +
# Press PF1 to bring up in world browser
 +
# enter www.ibm.com in the address bar and hit enter
 +
# enter www.opensimulator.org in the address bar and hit enter
 +
# Log out and back in, and Press PF1 again.
 +
# Validate that ibm.com and opensimulator.org are in the history by using the arrow button in the combo box
 +
 
 +
=== Procedures for OGP testing ===
 +
 
 +
==== Login ====
 +
If you are in gridnauts group, and vaak is in a good mood, these command line parameters should get you to vaak regions:
 +
 
 +
<pre>--ogp --set PurgeCacheOnNextStartup TRUE  --regionuri <regionuri>  --loginuri https://login1.aditi.lindenlab.com/cgi-bin/auth.cgi</pre>
 +
 
 +
where regionuri is one of the vaak regions at http://wiki.secondlife.com/wiki/Open_Grid_Public_Beta/Public_Regions#Linden_Lab_OGP_Regions
 +
 
 +
 
 +
On the login panel, validate that --ogp  *slightly* enlarges the combo box at the right of Start Location (vs the size of that box when running in non-OGP mode), and that the regionuri is in the box.
 +
* Click Login
 +
* With vaak you might need to try several times, or try different regions in the list, or request restart of the regions and the agentd.
 +
* This should log you in, but you will not have an appearance or inventory maintained.
 +
 
 +
==== Teleport ====
 +
* Only one OGP teleport mechanism is provided in the viewer, it is accessed via Ctrl-Alt-Shift-R or "Teleport Region..." in the World menu
 +
# Authenticate with vaak following Login instructions
 +
# Place one of the region seeds from http://wiki.secondlife.com/wiki/Open_Grid_Public_Beta/Public_Regions#Linden_Lab_OGP_Regions
 +
# Click Teleport.
 +
Note: The progress bar gives a less pleasing "fill up" in OGP mode, this is expected.
 +
 
 +
 
 +
On vaak, verify that the Inventory floater has no items in My Inventory
 +
 
 +
==== Avatar Rezzing ====
 +
The OGP testing assumes vaak use. Additional tests for Avatar appearance and Inventory will be added at a later date.
 +
 
 +
If it is a new Avatar on an agent domain that supports inventory, then you will be a gassy cloud until you create and wear Skin and Hair. To create Skin/Hair, open Inventory, then Create->BodyParts->Hair in the Inventory floater menu, then right click on the created hair item, and select Wear. Do the same for Skin. 
 +
 
 +
On vaak, currently you have no inventory, so you will probably be gassy ruthie.
 +
 
 +
 
  
 +
=== Future testing ===
 +
# Region Crossing with OGP - currently not supported (or at least not in all agent domains)
 +
# OGP and non-OGP regions intermingled on the same grid - try a mix of teleporting (Lure, Landmark, location) and region crossings between OGP and non-OGP regions.
 +
# On an agent domain and OpenSim region that supports Inventory managed at the agent domain, Test these Scenarios:
 +
# Validate that several levels of hierarchy in My Inventory can be created
 +
# Validate Create/Wear body part and clothing item
 +
# Validate uploading a texture and applying it to a prim that you rez in multiple regions
 +
# Validate modifying a clothing item color and texture.
 +
# Validate that icons and C-M-T for items in My Inventory survive relogin
 +
# Validate PurgeCacheOnRestart FALSE works
 +
# Validate that meaningful error messages are displayed in all rez_avatar/place failure cases. agentd is also guilty here
 +
# Test Voice on Vaak - didnt this used to work???
  
 
== Disclaimer ==
 
== Disclaimer ==

Latest revision as of 15:50, 25 January 2010

Open Grid Protocol implementation in Snowglobe

This page is only for describing the OGP implementation of the viewer, not general OGP protocol description.

Open Grid Protocol (OGP) currently includes a style of login and teleport that separates control of the agent into a separate domain named agent domain (also called agentd or agent service). This separate service handles moving an avatar from region to region, including between regions that are run by different entities. This is helpful to end users because they can maintain a consistent appearance and inventory as they move from region to region. They can also trust the agent service to maintain their inventory without having to "hand over the keys" to their inventory to every region they visit.


It is a protocol under development, and that's why we need it in Snowglobe. I've developed a patch for Snowglobe to enable OGP. Protocols are best standardized with the experience of implementation, and I believe OGP needs a publicly available implementation to experiment with. An open implementation will help ground the design of protocols in the reality of working code that the community can work with.

Note: IBM has open sourced an OGP implementation for the community to experiment with ( http://forge.opensimulator.org/gf/project/ogp/ ). If you are running an AD or OGP regions, lease let Pixel know! .

OGP protocols are not supported on the main Linden grid or the Linden test grid, which for now is a good thing. The protocol needs further development before Linden or anyone else should use it on a production level grid. OGP is new and distinct protocol from the current SL UDP and HTTP protocols, so it is the choice of the deployer to expose these interfaces or not. The specific HTTP caps for keeping inventory at the agent domain, manipulating the agent domain inventory, and resolving remote assets do not exist on the Linden Lab main grid or test grid, so no assets/inventory will cross the boundary between Second Life and OpenSim by using this viewer unless Linden enables it in their server side deployment.OpenSim grids that choose to expose the interfaces can experiment with distributed assets and with an inventory and library that are maintained by the agent domain.

Note: If appropriate, I intend to replace OGP references in the code and this wiki page to match the IETF working group name of VWRAP.

General information about OGP is at https://wiki.secondlife.com/wiki/User:Infinity_Linden/IETF_Drafts_and_Meetings until the IETF working group is officially formed. General information about IBM's open source OGP implementation is at TBD.

OGP History

The original OGP specs ware developed by Linden Lab with input from the Architecture Working Group (AWG). OGP's initial proof of concept implementation was a joint project between Linden Lab and IBM. IBM did a portion of that OGP viewer code with some help from Linden developers. The viewer code for that initial Proof of Concept is currently located in the OGP9 public svn branch. I ported the OGP9 branch to Snowglobe, gave the code some cleanup, and added some of the additional inventory caps we have been experimenting with. The additional caps are not supported in Linden's agent domain implementation, so no assets/inventory will cross the boundary between Second Life and OpenSim by using this viewer unless Linden adds additional interfaces to their agent domain.

When looking at the patch, gentle readers, please remember that it was originally proof of concept level code, and that the OGP drafts are a moving target.

Implementation

OGP viewer code affects small portions of the UI, adds some command line parameters, modifies the login and teleport sequences, and implements some additional agent domain caps involving inventory and assets.


UI

If --ogp is passed on the command line, the panel_login layout is modified. Last/Home/Region has no meaning in OGP, so that space in the panel is instead used for the regionuri_edit combo box. The user enters the region uri in this combo box. "Start Location:" is used in both instances, because from an end user point of view, a region uri is a starting location. The combo box is populated using URIs that are saved in a LLURLHistory named "region_uri", but only if the user's First/Last name is saved. This is because if I don't have a First/Last when building the login panel, it's impossible to pull/save *user* specific data (like the specific LLURLHistory for the user Pixel Gausman). The selected entry for the combo box is set to the command line parameter --regionuri ( gSavedSettings.getString("CmdLineRegionURI")), which is an additional way to specify the desired initial region.

Also enabled/disabled by the --ogp command line switch is the "Teleport Region..." selection in the new "Interop" submenu under the "Advanced" menu. This menu selection pops a floater that allows teleport via OGP, it also uses the LLURLHistory to store region uris. The floater can also be popped via Ctrl-Alt-Shift-R.

Command line parameters

--ogp
enables OGP mode. Viewer is either OGP or non OGP for the life of the session
--regionuri <uri>
allows you to pass in the name of the region you wish to login to.
--agenturi <uri>
allows you to specify the name of the agent domain you wish to use. This is passed to the authenticate call. If you do not specify one, it is still possible to request and get a seed cap on an agent domain from authenticate.
--loginuri <uri>
While not a new flag, it is needed when authenticating against any agent domain. Use it to point to whatever authentication authority your agent domain accepts.
--set PurgeCacheOnNextStartup TRUE
Also not a new flag, but simplified testing in the OGP viewer. Not needed in XLM-RPC Legacy mode. On the TODO list is to test with the viewer's caching in OGP mode.


Example: If you are part of the OGP beta from Summer 08 (yay Gridnauts!), this would be the command line parameter to authenticate against vaak, where <regionuri> comes from http://wiki.secondlife.com/wiki/Open_Grid_Public_Beta/Public_Regions#Linden_Lab_OGP_Regions :

--ogp --set PurgeCacheOnNextStartup TRUE  --regionuri  <regionuri>  --loginuri https://login1.aditi.lindenlab.com/cgi-bin/auth.cgi

Login sequence

The login sequence for Snowglobe is messier than what exists in OGP9 SVN. This is because OGP9 did not support XML-RPC style logins, and the removal of the XML-RPC path in OGP9 made the code simpler. We will need to maintain the XML-RPC path in Snowglobe, so the patch attempts to do that with minimal disturbance (and therefore risk) to the XML-RPC code path.


The login sequence is kicked off in idle_startup() in llstartup.cpp. The code loops continuously in idle_startup() as it moves through the different stages of the login sequence. OGP and XML-RPC diverge states for AUTHENTICATE and XMLRPC_LEGACY, and then share the code for STATE_LOGIN_PROCESS_RESPONSE. STATE_LOGIN_PROCESS_RESPONSE is exceptionally long, there are now separate XLMRPC and OGP blocks in that state that cope with all the responses gathered through the stages of the login process. Note that the login for OGP daisy chains together several HTTP POSTs, kicking off the next one in the responder of the previous one. Some of the HTTP POSTs must be successful (for instance, rez_avatar/place must succeed to move to STATE_LOGIN_PROCESS_RESPONSE), but some need to be optional, and still proceed with the login process if they fail (for instance, fetching agent/inventory needs to be optional)

After the overly complex STATE_LOGIN_PROCESS_RESPONSE section of the code, OGP and XMLRPC processing are essentially the same in STATE_WORLD_INIT and onward. The viewer still does its handshake with the region, and goes through its AgentMovementComplete processing. In our initial POC coding last year, we had experimented with getting rid of AgentMovementComplete messages, but were unsuccessful.

The login sequence is intended to work for agent domains that do not expose inventory and asset HTTP caps (like the one on vaak). It has been tested with vaak for login and teleport, despite vaak being slightly temperamental. Members of the Gridnauts group on Aditi should be able to test with vaak, but be warned that vaak has intermittent issues with login.

On logout, instead of sending a UDP message to the region, in OGP a rez_avatar/place request is sent with a null URI. The null URI signals to the agent domain that it should derez the agent from its current region.

One difference between this viewer and the OGP9 SVN branch is that this viewer does not include LLSD "legacy" login, only XMLRPC legacy and OGP.

Teleport sequence

The user invokes OGP teleport via Ctrl-Alt-Shift-R or 'Teleport Region...' in the World menu. This pops up an instance of LLFoaterTeleport, which has a combo box of the same region_uri LLURLHistory. LLFloaterTeleport's function in life is to make a rez_avatar/place request on the agent domain using the URI from the floater. The reponse is caught by LLPlaceAvatarTeleportResponder, and relevant values are plucked from its contents. Note that some of the values in the response to rez_avatar/place are *only* passed on login, and not passed in teleport.

After the response to rez_avatar/place is received from the agentd, the code for Teleport is very similar to XML-RPC Teleport.

Assets and Inventory

Inventory can now be managed by the agent domain, and fetched via HTTP using agent/inventory cap. Temporarily Inventory manipulation (CreateInventoryItem, etc.) still goes through UDP. The UDP calls in OpenSim are reflected to the agent domain via an HTTP interface for handling. This was done as a temporary measure until proper HTTP Inventory manipulation calls could be designed properly and done from the viewer.

Fetching of the inventory is done via the existing WebFetchInventoryDescendents HTTP cap code in the viewer, with the cap renamed to be agent/inventory for the agentd case. For the time being, the format of agent/inventory is the same as WebFetchInventoryDescendents. In cases where there is both an agent/inventory cap on the agent domain and a WebFetchInventoryDescendents cap on the region, the cap on the agent domain is used.

There is a new cap in agentd called agent/inventory-skeleton. Its responder, LLInventorySkeletonResponder, grabs the skeleton, and also makes a new (dangerous?) assumption. It assumes that content["Skeleton"][0]["folder_id"] is the inventory-root UUID. It makes sense, but it is a change compared to how things worked in legacy mode. In legacy XML-RPC authentication, the inventory-root UUID is passed back from authenticate, separate from the skeleton. Just like agent/inventory, the values passed back for agent/inventory-skeleton mimic the values received in an XML-RPC login.


The interfaces of agent/inventory and agent/inventory-skeleton will change as the design of agent domain moves forward. Also, assets will eventually be distributed, meaning that a region on a grid might contain an asset that is not stored on that grid. An agent's inventory might be made up of items scattered across the web. This means some interesting protocol changes, while keeping an eye on performance.

Shortcomings, future needs, and dirty laundry

Refactor Teleport
The teleport code needs to be refactored into a new class when OGP support is added for:
  1. LLAgent::teleportViaLure - This function is invoked when one agent offers one or more other agents to teleport to her location. LLAgent::teleportViaLure() is called when the current agent has accepted a lure and desires to TP to a friend. Currently all the protocol gives me is a lure_id. I'd really like to get a region_uri, so a protocol change would be needed.
  2. LLAgent::teleportViaLandmark - Similar to teleportViaLure issue. I have a landmark_asset_id, and need a URI.
  3. LLAgent::teleportViaLocation - This is invoked from about a dozen different places in the viewer (for instance, when the user clicks on the map). A global position is passed in, which is then used to compute the regionhandle. With the regionhandle, the legacy teleportRequest() is called. The assumptions around the use of regionhandle need to be reworked in the viewer (and in the OGP protocol).
regionhandles
The viewer assumes that all regions it can get to are arranged in one contiguous XY grid. It's not its fault, when the viewer was written, there was only one grid. A region's regionhandle denotes its XY location in the one known grid, i.e. where it shows up on the map. When teleporting between two distinct grids, it is very possible that two regions report the same regionhandle. This makes the viewer very unhappy. The viewer uses the regionhandle to check that an XY location is a valid region that the viewer has a connection to, and to do location based things like determine neighboring regions. It's even checked when determining if you are flying. In the OGP beta, we worked around this issue by having all the OGP region owners register their regionhandles on a website. That allowed us to avoid the issue. Longer term, the issue needs to be resolved differently.
STATE_LOGIN_PROCESS_RESPONSE
This section of idle_startup() is rather brittle, and will be easy to break. Consider rewriting it, or separating XML-RPC and OGP into two different states instead of both of them using STATE_LOGIN_PROCESS_RESPONSE. I think the original OGP9 code used STATE_LOGIN_PROCESS_RESPONSE as a common state between legacy and OGP because OGP9 only dealt with LLSD login (and had chopped all the XML-RPC code.)
makeNewOutfit() crashes when in OGP mode.
In the original Proof of Concept, we chose to disable the UI button for Make New Outfit. It has been re-enabled, and needs to be fixed for both agent domains that support inventory, and ones that do not.
PurgeCacheOnNextStartup flag
This flag is only needed in OGP mode, we need to test the viewer without this flag and make sure viewer's internal caching mechanisms work with OGP. Careful definition of the testing scenarios need to be done, and it also needs to work with agent domains that do not support Inventory.
LLPlaceAvatarTeleportResponder
Rework how values are caught from the rez_avatar/place responder, and put into mResult. Currently I think we might wipe out some mResult values on teleport.

Snowglobe Mysterious Future -Pixel's wishlist

  1. enhance event queue code - OGP requires a more complex handling of events on the event queue
  2. regionhandle rework - see above in dirty laundry section. this might also fix SVC-2941 .
  3. inventory UDP->caps
  4. remove secondlife.com and lindenlab.com assumptions in the viewer
  5. change map tiles to be a cap instead of hardcoded to amazon.com
  6. cleanup run thru logging output for OGP, especially event queue spamming
  7. implement Mana Janus' gridinfo type functionality for managing URIs on different grids
  8. implement a SNOW-129 type feature to allow multiple user names/password to be stored
  9. pluggable authentication model - allow things like OpenID and LDAP to be used

Test Plan

Objectives

Exercise agent related capability in the areas of login, teleport in the viewer for both OGP and non-OGP logins, with a focus on non-OGP mode testing.

Procedures for non-OGP testing

Login

  • Validate login failure in non-OGP mode
  1. Launch the viewer with no additional command line parameters
  2. Enter bogus First/Last/password, and in the Start Location, type 'Ahern'
  3. After attempted login, verify that the viewer displays one error dialog (and one only...) and comes back to the same login screen
  • Validate login panel UI and Agni login
  1. Launch the viewer with no additional command line parameters
  2. Validate that the combobox next to Start Location has : home, last, and region as the choices, and it can be toggled on/off in Preferences floater on General tab
  3. Enter First/Last/password, and in the Start Location, type 'Ahern'
  4. Login to Agni
  5. Ensure that My Inventory in your Inventory folder is populated.
  6. Search for an item in your inventory (thus kicking off large inventory fetch)
  7. Move an Inventory item from Landmarks to Clothes
  • Login to Aditi using Grids combobox
  1. Launch viewer to login panel. Ctrl-Shift-G toggle Grid Box if not already displayed.
  2. Select Aditi and click login
  3. Validate that agent rezzes with expected appearance and wearables, and Inventory Folder has contents you'd expect
  4. Validate that the AVs friends list is correct by clicking Contacts in the Communicate window
  5. After logout, validate that with default logcontrol.xml, there isn't extra OGP related messages going into the SecondLife.log
  1. Create a Windoze shortcut with the additional command line options, or otherwise launch the viewer with the command line: -loginuri http://osgrid.org:8002 -loginpage http://osgrid.org/loginscreen.php -helperuri http://osgrid.org/
  1. Validate that the landmark you moved into Clothes folder in Test 1 above is still in Clothes folder

With a new AV on OSgrid, you might (as of Sept 2) need to create Skin and create Hair and wear it to get your texture bakes to happen properly. To create Skin/Hair, open Inventory, then Create->BodyParts->Hair in the Inventory floater menu, then right click on the created hair item, and select Wear. Do the same for Skin.

Teleport

For each type of test, validate these things after the completion of a Teleport:

  1. The progress bar during teleport slowly fills up as a teleport progresses
  2. Your AV arrives and can navigate in the region ( try to walk in a circle)
  3. The objects in the surrounding region look appropriate (you shouldn't see a mixture of objects from the source and destination regions jumbled together),
  4. Your AV rezzes properly. Avatar appearance should be validated from both your viewer session, and with a second viewer session that has your AV in its camera view. This is because the viewer's caching can play tricks on you. So validate wearables, texture bakes, and attachments by observing your AV from a second viewer
  5. After TP is complete, a message in Local chat appears: "Teleport completed from http://slurl.com/secondlife/Morris/11/195/59" (change Morris to whatever your source region for the TP was)
  • Teleport via Landmark
  1. Open Landmarks folder in My Inventory, double click on a landmark to open it, and click teleport.
  • Teleport via Location
  1. Open the Map, double click in the region next to you, this should invoke a TP
  2. Open the Map, double click a region that is 3 regions away
  • Teleport Via Lure
  1. Login as AV1 in Ahern on Agni
  2. Login as AV2 in IBM
  3. AV2 double clicks on AV1 in her friends list to bring up AV1's profile
  4. AV2 clicks "offer teleport" to AV1
  5. AV1 accepts the TP offer
  6. AV1 is teleported to IBM
  • Teleport Home
  1. Ctrl-Alt-Shift-H should TP you to wherever your Home location is set
  • Validate that Ctrl-Alt-Shift-L does *not* bring up the OGP Teleport floater, and that "Teleport Region..." in the World menu is disabled

Region Crossing

  • Validate agent crossing between two touching regions
  1. Go to the edge of Ahern, http://slurl.com/secondlife/Ahern/10/10/50 and walk between the adjoining regions.
  2. Watch the Region name and XYZ location in the menu bar to validate that you crossed the region successfully.
  3. Make sure you can walk around the region, and make sure you don't lose Voice connection.
  4. Validate that your Inventory looks correct in the Clothing folder of My Inventory


Browser history

  • OGP makes use of the LLURLHistory class, so test out that url history is properly saved for non-OGP usage
  1. Press PF1 to bring up in world browser
  2. enter www.ibm.com in the address bar and hit enter
  3. enter www.opensimulator.org in the address bar and hit enter
  4. Log out and back in, and Press PF1 again.
  5. Validate that ibm.com and opensimulator.org are in the history by using the arrow button in the combo box

Procedures for OGP testing

Login

If you are in gridnauts group, and vaak is in a good mood, these command line parameters should get you to vaak regions:

--ogp --set PurgeCacheOnNextStartup TRUE  --regionuri <regionuri>   --loginuri https://login1.aditi.lindenlab.com/cgi-bin/auth.cgi

where regionuri is one of the vaak regions at http://wiki.secondlife.com/wiki/Open_Grid_Public_Beta/Public_Regions#Linden_Lab_OGP_Regions


On the login panel, validate that --ogp *slightly* enlarges the combo box at the right of Start Location (vs the size of that box when running in non-OGP mode), and that the regionuri is in the box.

  • Click Login
  • With vaak you might need to try several times, or try different regions in the list, or request restart of the regions and the agentd.
  • This should log you in, but you will not have an appearance or inventory maintained.

Teleport

  • Only one OGP teleport mechanism is provided in the viewer, it is accessed via Ctrl-Alt-Shift-R or "Teleport Region..." in the World menu
  1. Authenticate with vaak following Login instructions
  2. Place one of the region seeds from http://wiki.secondlife.com/wiki/Open_Grid_Public_Beta/Public_Regions#Linden_Lab_OGP_Regions
  3. Click Teleport.

Note: The progress bar gives a less pleasing "fill up" in OGP mode, this is expected.


On vaak, verify that the Inventory floater has no items in My Inventory

Avatar Rezzing

The OGP testing assumes vaak use. Additional tests for Avatar appearance and Inventory will be added at a later date.

If it is a new Avatar on an agent domain that supports inventory, then you will be a gassy cloud until you create and wear Skin and Hair. To create Skin/Hair, open Inventory, then Create->BodyParts->Hair in the Inventory floater menu, then right click on the created hair item, and select Wear. Do the same for Skin.

On vaak, currently you have no inventory, so you will probably be gassy ruthie.


Future testing

  1. Region Crossing with OGP - currently not supported (or at least not in all agent domains)
  2. OGP and non-OGP regions intermingled on the same grid - try a mix of teleporting (Lure, Landmark, location) and region crossings between OGP and non-OGP regions.
  3. On an agent domain and OpenSim region that supports Inventory managed at the agent domain, Test these Scenarios:
  4. Validate that several levels of hierarchy in My Inventory can be created
  5. Validate Create/Wear body part and clothing item
  6. Validate uploading a texture and applying it to a prim that you rez in multiple regions
  7. Validate modifying a clothing item color and texture.
  8. Validate that icons and C-M-T for items in My Inventory survive relogin
  9. Validate PurgeCacheOnRestart FALSE works
  10. Validate that meaningful error messages are displayed in all rez_avatar/place failure cases. agentd is also guilty here
  11. Test Voice on Vaak - didnt this used to work???

Disclaimer

Anything resembling an opinion is my own, and not that of my employer, IBM. This is experimental code, meant to give the community a relevant viewer to use in interoperability work.