import changes from `dev' branch of rmottola/Arctic-Fox:

- Bug 1244883 - Add Nightly-/Aurora-only crash for AsyncTransactionWaiter timeouts - r=nical (132b2ceff9)
- Bug 1148978 - Trigger paints when moving plugin windows around on the browser main thread. r=mattwoodrow (c75ce5ec09)
- Dedent some functions. (bug 1254899 part 1, r=jrmuizel) (c84fb419c7)
- Refactor acceleration pref initialization. (bug 1254899 part 2, r=jrmuizel) (29a164c70e)
- Remove NS_NATIVE_GRAPHIC on Windows. (bug 1266536, r=jimm) (84011349d1)
- Bug 1267253 - Delete gfxWindowsPlatform::RenderMode and replace it with a check against the default backend. r=bas (93cb6e503e)
- Introduce gfxConfig, a manager for graphics feature settings. (bug 1254899 part 3, r=milan) (97498ca46a)
- Bug 1262187: Allow D3D9 if D3D11 failed, behind the pref, but on by default. r=bas (8163e28b26)
- Bug 1178376 - Optionally fade in new progressively painted tiles r=nical (777bf1799d)
- Bug 1178376 - Allow progressive painting when low-precision tiles are disabled r=BenWa (3b8d84e19c)
- Bug 1178376 - Put progressive paint status in tile updates r=nical (935d3b46ed)
- Bug 1251778: Attempt to avoid presenting when the window is still resizing. r=jrmuizel (32b194a6f7)
- Hoist mWidget into the Compositor base class. (bug 1264545 part 1, r=nical) (aca26ec343)
- Lift compositor-accessed methods from nsIWidget into CompositorWidgetProxy. (bug 1264545 part 2, r=jimm) (609a23157a)
- Rename FeatureStatus::Crashed to CrashedInHandler. (bug 1254899 part 4, r=milan) (0eae23a3fd)
- Move DeviceInitData from gfxWindowsPlatform to gfxPlatforn. (bug 1254899 part 5, r=milan) (e31540ba18)
- Merge gfxWindowsPlatform::mAcceleration into gfxConfig. (bug 1254899 part 6, r=milan) (9d45cc8b87)
- Add another feature state for blacklisting and environment decisions. (bug 1254899 part 7, r=milan) (e7eee53cfb)
- Give FeatureState a public interface. (bug 1254899 part 8, r=milan) (52d8e7f355)
- Replace gfxWindowsPlatform::mD3D11Status with gfxConfig. (bug 1254899 part 9, r=jrmuizel) (90dc658b53)
- Replace gfxWindowsPlatform::mD2D1Status with gfxConfig. (bug 1254899 part 10, r=milan) (eb9474f309)
- Fix assertion failure in gfxConfig. (bug 1269565, r=milan) (0eb738ce66)
- Add gfxConfig to nsIGfxInfo, for about:support access. (bug 1254899 part 11, r=jrmuizel) (e770240152)
- Change Compositor::GetWidget to return a CompositorWidgetProxy. (bug 1264545 part 3, r=jimm) (fdf1d96255)
- Bug 1251778 - Followup: Remove unreferenced local variable. r=bustage (27579f5542)
- Use CompositorWidgetProxy in place of nsIWidget in the compositor. (bug 1264545 part 4, r=jimm) (80def1c2eb)
- Use CompositorWidgetProxy in place of nsIWidget in CompositorBridgeParent. (bug 1264545 part 5, r=jimm,kats) (67d0e1ef7d)
- Move CompositorWidgetProxy inheritance out of nsIWidget. (bug 1264545 part 6, r=jimm) (61075722c5)
- Bug 1251894 - In CompositorD3D11::CreateTexture, copy as much as the render target allows. r=bas (bf5fc6baa2)
- Bug 1266444: It is OK for us not to have texture sharing. r=jrmuizel (0b1885f89d)
- Bug 1266396 - Make TextureClient more robust against racy shutdown situations. r=Bas (b1d7f54643)
- Fix test bustage due to platform line-endings. Bug 1222624 (10b8cf3592)
- More test bustage from bug 1222624 (763c4c0bb9)
- Backed out 4 changesets (bug 1222624) to fix bug 1249572 (7ba3d433d0)
- Bug 1268230 - RunTime.cpp and ScriptLoader do not have to use MainThreadStopSyncLoopRunnable, r=khuey (88499a3982)
- Bug 1037725 - Add warning message in the console when worker spawn over limit. r=khuey (8af94dbc1d)
- Bug 1047663 - Disabling the cache in a tab should also disable it for all workers in that tab;r=khuey (5411d81682)
- Bug 1253793 Update ScriptLoader assertion to handle cancelation case. r=khuey (18c78d5651)
- Bug 1245768 - Implement a test for the correct error management when worker imports 3rd party scripts, r=bz (c1d3f290a9)
- Bug 1249673. Muted errors should be turned into NetworkError DOMExceptions when returning from importScripts on workers, instead of becoming NS_ERROR_FAILURE. r=baku (0358282cbe)
- Bug 1265405 - Add a dictionary to specify how PeriodicWave should be normalized (or not); r=smaug …normalized (or not); r=smaugu (201213146c)
- Bug 1251082. Restore comments in PageTransitionEvent.webidl that got lost when nsIDOMPageTransitionEvent.idl was migrated to webidl. r=bz The mentioned migration happened in http://hg.mozilla.org/mozilla-central/rev/e6377ca32f3d from bug 1031051. (2dfa309056)
- Bug 1266178 Make ServiceWorkerClient not assert if the document doesn't have an outer window. r=ehsan (eafb169c91)
- Bug 1259164 - Set ServiceWorkerMessageEvent.origin correctly when calling ServiceWorkerClient.postMessage(); r=bkelly (caeb65d10e)
- Bug 1246319 P1 Dedupe service worker registrar entries. r=baku (b76deef941)
- Bug 1246319 P2 Verify entries are deduped from the ServiceWorkerRegistrar. r=baku (8a4e348d6e)
- Bug 1246319 P3 Fix service worker registry value update. r=bz (14abf6b6ce)
- Bug 1247970 - Remove principal spec from service worker registrar file. r=baku (3c30130700)
- Bug 1249438 P1 Move guts of RegisterServiceWorker() into a protected method that can be tested in gtest. r=baku (488243196d)
- Bug 1249438 P2 Modify existing gtest to use RegisterServiceWorkerInternal. r=baku (e86c66891d)
- Bug 1249438 P3 Add a gtest that registers duplicate service worker registrations. r=baku (35e269f9af)
- Bug 1226443 P6 Ignore update() called during top level service worker script evaluation. r=ehsan (dcb9d02553)
- Bug 1241725 - about:serviceworkers "Active Cache Name" UUID should not contain null bytes, r=bkelly (4cddea6a67)
- Bug 1221852 - SharedWorker.port should be always not null, r=smaug (a9800274dc)
- Bug 1261428: Clean up a bit more. r=bz (4977e3d7a5)
- Bug 890284. Stop splitting textnodes in the XML content sink. r=peterv (a46dfca1cf)
- Bug 1211708 Allow themes to specify XBL bindings even in unprivileged documents r=sicking (82cf1a4023)
- Bug 915962 - Part 1: Allow pressing space to scroll the document if an editable element or form control is not focused; r=roc (cdb934af03)
- Bug 915962 - Part 2: Add a test case for pressing space when a tabindex=-1 and a button element is focused; r=roc (17dcf5cfd0)
- Bug 915962 - Part 3: Do not crash when pressing the space bar without having an element focused; r=roc (2161e62bc3)
- Bug 1180761, cancel the event earlier so that space doesn't trigger checkbox change and scroll, r=neil (2425cb76ad)
- Bug 1259182 - Shrink keyCodeData. r=bz. (737204af84)
- Bug 1193567 - Check result of ReadID in nsXBLPrototypeBinding::Read(). r=wchen (c9b1c35bf3)
- Bug 1173344 - Remove an intermediary root from nsXBLProtoImplField's FieldGetterImpl; r=jandem (5f42dd2e48)
- Bug 1207494 - Part 14: Remove use of expression closure from dom/xbl/. r=bz (21c7d3825f)
- align tests (fe34b613d3)
- Bug 1223702 - Fix some errors about wifi direct. r=hchang (568d86054a)
- Bug 1166274 - Part 1: Handle the callback and IPC message of setStaticIpMode correctly. r=vchang (8fb8d7f3b7)
- Bug 1133665 - [Flame][Wifi] The SSID that has set to be binded with MAC address is not hightlighted when user taps it. r=hchang (3165471d13)
- Bug 1207494 - Part 13: Remove use of expression closure from dom/wifi/. r=henry (dd9ad23a8a)
- Bug 1251856 - Disable U2F in all releases (fix for 1231681). r=baku (24ada10566)
- align tests (dae9ecd0ee)
- var-let (11a3cb0878)
- Bug 1184822 - Use classId to get provider. r=fabrice (1288eccd06)
- Bug 1247410 - "test for _nomap ids does not work correctly". r=dougt (f736a04f08)
- Bug 1035097 - Changed the type from 'radio' to 'radioType'. r=jdm (f9a0079152)
- Bug 1177871 - Add a timeout to XHR request of WifiGeoPositionProvider. r=jdm (2f6aa87c20)
- align code to 978593 with POST and location structure (d8ba75a759)
- Bug 1230685 - Replace function declarations with add_task statements in test_storage_value_array.js and test_unicode.js. r=mak (9822bf2215)
- Bug 1230683 - Replace try/catch with Assert.throws in test_storage_connection.js. r=mak (1c993fc37e)
- Bug 655722 - Rewrite _buildGUIDMap in the sync bookmark engine to use PlacesUtils.promiseBookmarksTree. r=mak (3795d26af0)
- Bug 1251057 - enable debug logging for rest.js requests and responses. r=adw (1062bcd113)
- Bug 503515 - Try and ensure exported certificates include an extension by default. r=keeler (505967ab7f)
- Bug 1017616 - Filter out some more unnecessary characters when exporting certs. r=keeler (e95838e362)
- Bug 1241614 - don't overflow:auto the container, use em to size the dialog to avoid hidpi visibility issues, r=dolske,ttaubert (8bd6c2b35b)
- Bug 1266851. Make <xmp> and <listing> use HTMLPreElement as their primary interface, per <whatwg/html#1015>.  r=peterv (6be7f9d6e9)
- Bug 1262184 - Block embed content loading when child of media element; r=bz (a297eeb378)
- Bug 1263696 - Block embed content loading when ancestor of object element with content; r=bz (89c143cbfe)
- Bug 1266077. Fix <base> href getter to follow the spec; it should be using the fallback base URI to resolve against, not the document URI. r=bkelly (e757b23a14)
- Bug 1168079 nsTextEditRules::CollapseSelectionToTrailingBRIfNeeded() should ensure that there is a selection before calling nsEditor::GetStartNodeAndOffset() r=ehsan (6c283bf3a7)
- Bug 898321 - Return success from nsTableEditor::GetCellAt if frame not found; r=ehsan (0d09143b95)
- Bug 387687 - wrap quotes in plain text replies to window. r=masayuki (ca51437018)
- Bug 1247483 - Only replace nodes in nsHTMLEditor::ReplaceOrphanedStructure if all nodes in node list are descendants of replacement node. r=ehsan (8416037da2)
- bug 1266496 - fire some selection events for proxied accessibles r=davidb (8806de7dd9)
- bug 1266518 - add a new event message for AccSelChangeEvents r=davidb (46af183cab)
- Bug 953265: Adjust Opus bitrate in WebRTC to pass >8KHz audio, and comment r=bwc (b0be6a326e)
- Bug 1221473: Do not treat answer as authoritative wrt payload types. r=drno (d27409209e)
- Bug 1241321 - No RTCP stats for audio streams. r=rjesup (ec0222694e)
- bug 1250492 - use tl::Max instead of std::max to get rid of a static constructor r=jesup (3cebbc8969)
- Bug 1254187: Fix maxBitrate to respect simulcast. r=jesup (e569e54b57)
- Bug 1158931 - Fix static assertion compilation error; r=snorp (eb27881746)
- No bug, fix WebrtcMediaCodecVP8VideoCodec.cpp warnings (a983544581)
- Bug 1252737 - use size_t instead of uint32_t for InitEncode(). r=jesup (57c3abc9fa)
- Bug 1208371 - Never send more than one disabled frame in a row to the WebRTC encoder. r=jesup (ec0c28822b)
- Bug 1208371 - Do image format conversion async in MediaPipeline. r=jesup (032efec783)
- Bug 1266685 - Don't pass too many frames to the MediaPipelineTransmit VideoFrameConverter. r=jesup (21774a8d25)
- Bug 1266644 - Rename StreamBuffer to StreamTracks. r=jesup r=pehrsons (21906fe1f7)
- Bug 1208371 - Don't treat audio chunks as mutable in MediaPipeline. r=padenot (3878ef4332)
- Bug 1246310 - Let MediaPipelineReceive tracks start at 0. r=jesup (b468ff8d48)
- Bug 1266644 - Rename DOMMediaStream:: CreateXXXStream to DOMMediaStream:: CreateXXXStreamAsInput. r=jesup r=pehrsons (fe4b6d70bc)
- Bug 1234578: Add an assertion. r=drno, a=abillings (f1a2c8d841)
- bug 1250492 - include sstream in SdpMediaSection.h instead of iostream r=jesup (110b5c2eca)
- Bug 1264470 - a=identity is a long attribute, r=bwc (5848194fe9)
- Bug 1256750: Remove unnecessary sscanf_s parameter on windows, and fix format string everywhere else. r=jesup (371c0db476)
- Bug 1204082 - try strtoull instead. r=mt (a0313aa87c)
- Bug 1113443 - reject each media type with approriate default. r=bwc (a72ff312d1)
- Bug 1095793 - use mid if provided to place candidate in msection. r=bwc (2c29b21fac)
- Bug 1252699 - Set WEBRTC_DETECT_ARM_NEON when optional neon is requested. r=jesup (722e2043a5)
- Bug 1229475 - webrtc: Call opus tonality_analysis_init. r=jesup (1cf8cc2cd7)
- Bug 1254876: assert windows recording is shut down r=pkerr (1f2cb69073)
- Bug 1227481 - added a memset on aec. r=jesup (532026ce20)
- Bug 1254507 - Fix leak in WebRTC DesktopApplication class. r=jesup (54da72aeb4)
- Bug 1196542 - share only windows with non-zero area. r=pkerr (94595ec463)
- Bug 1202087 - Filter out non-shareable application for win8 or greater. r=jesup (d989956802)
- Bug 1216529 - WebRTC: Request camera permission before accessing camera APIs. r=gcp (24b6699226)
- Bug 1237630 - Part 1: Video freeze from WebRTC sender. r=rjesup (02daa8b5b7)
- Bug 1237630 - Part 2: remove LOG statement generating a now defunct error condition. r=rjesup (c6002ef12f)
- Bug 1248335: avoid using SvcInternal structure entirely, as system-vpx may not have it r=pkerr (ef9b21f20c)
- Bug 1234571: unregister encoded-frame callback when releasing codec databases r=pkerr (321bd5166b)
- Bug 820972 - Comment out colorTable[] because we don't need it. r=jesup. (60b10803d5)
- cleanup and missing test stuff (e2be0331d9)
- Merge remote-tracking branch 'upstream/dev' into winbuild (3a3bb0b315)
- layout/media: fix export symbol list, fix build bustage (f9f5bfe14c)
This commit is contained in:
2024-09-10 22:30:49 +08:00
parent fb49d72bb0
commit 21c98793d3
314 changed files with 9285 additions and 2946 deletions
+11
View File
@@ -1495,6 +1495,10 @@ a11y::ProxyEvent(ProxyAccessible* aTarget, uint32_t aEventType)
case nsIAccessibleEvent::EVENT_VALUE_CHANGE:
g_object_notify((GObject*)wrapper, "accessible-value");
break;
case nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED:
case nsIAccessibleEvent::EVENT_SELECTION_WITHIN:
g_signal_emit_by_name(wrapper, "selection_changed");
break;
}
}
@@ -1610,6 +1614,13 @@ MaiAtkObject::FireAtkShowHideEvent(AtkObject* aParent, bool aIsAdded,
g_signal_emit_by_name(aParent, signal_name, indexInParent, this, nullptr);
}
void
a11y::ProxySelectionEvent(ProxyAccessible*, ProxyAccessible* aWidget, uint32_t)
{
MaiAtkObject* obj = MAI_ATK_OBJECT(GetWrapperFor(aWidget));
g_signal_emit_by_name(obj, "selection_changed");
}
// static
void
AccessibleWrap::GetKeyBinding(Accessible* aAccessible, nsAString& aResult)
+2
View File
@@ -77,6 +77,8 @@ void ProxyTextChangeEvent(ProxyAccessible* aTarget, const nsString& aStr,
bool aFromUser);
void ProxyShowHideEvent(ProxyAccessible* aTarget, ProxyAccessible* aParent,
bool aInsert, bool aFromUser);
void ProxySelectionEvent(ProxyAccessible* aTarget, ProxyAccessible* aWidget,
uint32_t aType);
} // namespace a11y
} // namespace mozilla
+9
View File
@@ -885,6 +885,15 @@ Accessible::HandleAccEvent(AccEvent* aEvent)
event->IsFromUserInput());
break;
}
case nsIAccessibleEvent::EVENT_SELECTION:
case nsIAccessibleEvent::EVENT_SELECTION_ADD:
case nsIAccessibleEvent::EVENT_SELECTION_REMOVE: {
AccSelChangeEvent* selEvent = downcast_accEvent(aEvent);
uint64_t widgetID = selEvent->Widget()->IsDoc() ? 0 :
reinterpret_cast<uintptr_t>(selEvent->Widget());
ipcDoc->SendSelectionEvent(id, widgetID, aEvent->GetEventType());
break;
}
default:
ipcDoc->SendEvent(id, aEvent->GetEventType());
}
+25
View File
@@ -259,6 +259,31 @@ DocAccessibleParent::RecvTextChangeEvent(const uint64_t& aID,
return true;
}
bool
DocAccessibleParent::RecvSelectionEvent(const uint64_t& aID,
const uint64_t& aWidgetID,
const uint32_t& aType)
{
ProxyAccessible* target = GetAccessible(aID);
ProxyAccessible* widget = GetAccessible(aWidgetID);
if (!target || !widget) {
NS_ERROR("invalid id in selection event");
return true;
}
ProxySelectionEvent(target, widget, aType);
if (!nsCoreUtils::AccEventObserversExist()) {
return true;
}
xpcAccessibleGeneric* xpcTarget = GetXPCAccessible(target);
xpcAccessibleDocument* xpcDoc = GetAccService()->GetXPCDocument(this);
RefPtr<xpcAccEvent> event = new xpcAccEvent(aType, xpcTarget, xpcDoc,
nullptr, false);
nsCoreUtils::DispatchAccEvent(Move(event));
return true;
}
bool
DocAccessibleParent::RecvBindChildDoc(PDocAccessibleParent* aChildDoc, const uint64_t& aID)
{
+4
View File
@@ -64,6 +64,10 @@ public:
const bool& aIsInsert,
const bool& aFromUser) override;
virtual bool RecvSelectionEvent(const uint64_t& aID,
const uint64_t& aWidgetID,
const uint32_t& aType) override;
virtual bool RecvBindChildDoc(PDocAccessibleParent* aChildDoc, const uint64_t& aID) override;
void Unbind()
{
+1
View File
@@ -61,6 +61,7 @@ parent:
async CaretMoveEvent(uint64_t aID, int32_t aOffset);
async TextChangeEvent(uint64_t aID, nsString aStr, int32_t aStart, uint32_t aLen,
bool aIsInsert, bool aFromUser);
async SelectionEvent(uint64_t aID, uint64_t aWidgetID, uint32_t aType);
/*
* Tell the parent document to bind the existing document as a new child
+5
View File
@@ -106,6 +106,11 @@ void
ProxyShowHideEvent(ProxyAccessible*, ProxyAccessible*, bool, bool)
{
}
void
ProxySelectionEvent(ProxyAccessible*, ProxyAccessible*, uint32_t)
{
}
} // namespace a11y
} // namespace mozilla
+5
View File
@@ -54,3 +54,8 @@ void
a11y::ProxyShowHideEvent(ProxyAccessible*, ProxyAccessible*, bool, bool)
{
}
void
a11y::ProxySelectionEvent(ProxyAccessible*, ProxyAccessible*, uint32_t)
{
}
+7
View File
@@ -127,3 +127,10 @@ a11y::ProxyShowHideEvent(ProxyAccessible* aTarget, ProxyAccessible*, bool aInser
AccessibleWrap* wrapper = WrapperFor(aTarget);
AccessibleWrap::FireWinEvent(wrapper, event);
}
void
a11y::ProxySelectionEvent(ProxyAccessible* aTarget, ProxyAccessible*, uint32_t aType)
{
AccessibleWrap* wrapper = WrapperFor(aTarget);
AccessibleWrap::FireWinEvent(wrapper, aType);
}
+18 -6
View File
@@ -86,6 +86,7 @@
#include "mozilla/EventStates.h"
#include "mozilla/Telemetry.h"
#include "mozilla/dom/HTMLObjectElementBinding.h"
#include "mozilla/dom/HTMLSharedObjectElement.h"
#ifdef XP_WIN
// Thanks so much, Microsoft! :(
@@ -2969,24 +2970,35 @@ nsObjectLoadingContent::LoadFallback(FallbackType aType, bool aNotify) {
aType = eFallbackAlternate;
}
// We'll set this to null no matter what now, doing it here means we'll load
// child embeds as we find them in the upcoming loop.
mType = eType_Null;
// Do a breadth-first traverse of node tree with the current element as root,
// looking for the first embed we can find.
nsTArray<nsINodeList*> childNodes;
if ((thisContent->IsHTMLElement(nsGkAtoms::object) ||
thisContent->IsHTMLElement(nsGkAtoms::applet)) &&
(aType == eFallbackUnsupported ||
aType == eFallbackDisabled ||
aType == eFallbackBlocklisted))
{
// Show alternate content instead, if it exists
for (nsIContent* child = thisContent->GetFirstChild();
child; child = child->GetNextSibling()) {
if (!child->IsHTMLElement(nsGkAtoms::param) &&
for (nsIContent* child = thisContent->GetFirstChild(); child;
child = child->GetNextNode(thisContent)) {
if (aType != eFallbackAlternate &&
!child->IsHTMLElement(nsGkAtoms::param) &&
nsStyleUtil::IsSignificantChild(child, true, false)) {
aType = eFallbackAlternate;
break;
}
if (child->IsHTMLElement(nsGkAtoms::embed)) {
HTMLSharedObjectElement* object = static_cast<HTMLSharedObjectElement*>(child);
if (object) {
object->StartObjectLoad(true, true);
}
}
}
}
mType = eType_Null;
mFallbackType = aType;
// Notify
@@ -0,0 +1,12 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/REC-html401-19991224/strict.dtd">
<html>
<head>
<title>Bug 1263696 - iframe that should not be loaded</title>
</head>
<body>
<script>
parent.SimpleTest.ok(false, "this iframe should not load");
</script>
</body>
</html>
@@ -0,0 +1,13 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/REC-html401-19991224/strict.dtd">
<html>
<head>
<title>Bug 1263696 - iframe that should be loaded</title>
</head>
<body>
<script>
parent.index = parent.index + 1;
parent.SimpleTest.ok(true, "this iframe should load");
</script>
</body>
</html>
+3
View File
@@ -154,6 +154,8 @@ support-files =
file_bug902350_frame.html
file_bug907892.html
file_bug945152.jar
file_bug1263696_frame_pass.html
file_bug1263696_frame_fail.html
file_general_document.html
file_html_in_xhr.html
file_html_in_xhr.sjs
@@ -854,3 +856,4 @@ skip-if = buildapp == 'b2g' #no ssl support
[test_document_register.html]
[test_bug962251.html]
[test_bug1259588.html]
[test_bug1263696.html]
+53
View File
@@ -0,0 +1,53 @@
<!DOCTYPE html>
<html>
<head>
<meta><charset="utf-8"/>
<title>Test Embed/Object Node Conflicts</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="plugin-utils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
var index = 0;
function startTest() {
is(index, 12, "Should have loaded all passing frames.");
SimpleTest.finish();
}
</script>
</head>
<body onload="startTest()">
<object data="file_bug1263696_frame_pass.html" style="width: 100px; height: 100px">
<embed type="text/html" src="file_bug1263696_frame_fail.html" />
</object>
<object style="width: 100px; height: 100px" data="data:application/x-does-not-exist,test">
<embed type="text/html" src="file_bug1263696_frame_pass.html" />
</object>
<object style="width: 100px; height: 100px" data="data:application/x-does-not-exist,test">
<div></div>
<embed type="text/html" src="file_bug1263696_frame_pass.html" />
</object>
<object style="width: 100px; height: 100px" data="data:application/x-does-not-exist,test">
<div>
<embed type="text/html" src="file_bug1263696_frame_pass.html" />
</div>
</object>
<object style="width: 100px; height: 100px" data="data:application/x-does-not-exist,test">
<embed type="text/html" src="file_bug1263696_frame_pass.html" />
<embed type="text/html" src="file_bug1263696_frame_pass.html" />
<object data="file_bug1263696_frame_pass.html">
<embed type="text/html" src="file_bug1263696_frame_fail.html" />
</object>
<object data="data:application/x-does-not-exist,test">
<embed type="text/html" src="file_bug1263696_frame_pass.html" />
</object>
</object>
<div>
<object data="file_bug1263696_frame_pass.html" style="width: 100px; height: 100px"></object>
<embed type="text/html" src="file_bug1263696_frame_pass.html" />
</div>
<div>
<embed type="text/html" src="file_bug1263696_frame_pass.html" />
<object data="file_bug1263696_frame_pass.html" style="width: 100px; height: 100px"></object>
</div>
</body>
</html>
+1 -1
View File
@@ -2008,7 +2008,7 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded,
OutputMediaStream* out = mOutputStreams.AppendElement();
MediaStreamTrackSourceGetter* getter = new CaptureStreamTrackSourceGetter(this);
out->mStream = DOMMediaStream::CreateTrackUnionStream(window, aGraph, getter);
out->mStream = DOMMediaStream::CreateTrackUnionStreamAsInput(window, aGraph, getter);
out->mFinishWhenEnded = aFinishWhenEnded;
mAudioCaptured = true;
+1
View File
@@ -28,6 +28,7 @@ public:
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLObjectElement, object)
virtual int32_t TabIndexDefault() override;
#ifdef XP_MACOSX
+8
View File
@@ -64,6 +64,10 @@ HTMLPreElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
NS_IMETHODIMP_(bool)
HTMLPreElement::IsAttributeMapped(const nsIAtom* aAttribute) const
{
if (!mNodeInfo->Equals(nsGkAtoms::pre)) {
return nsGenericHTMLElement::IsAttributeMapped(aAttribute);
}
static const MappedAttributeEntry attributes[] = {
{ &nsGkAtoms::wrap },
{ nullptr },
@@ -80,6 +84,10 @@ HTMLPreElement::IsAttributeMapped(const nsIAtom* aAttribute) const
nsMapRuleToAttributesFunc
HTMLPreElement::GetAttributeMappingFunction() const
{
if (!mNodeInfo->Equals(nsGkAtoms::pre)) {
return nsGenericHTMLElement::GetAttributeMappingFunction();
}
return &MapAttributesIntoRule;
}
+3 -1
View File
@@ -62,13 +62,15 @@ NS_IMPL_STRING_ATTR(HTMLSharedElement, Target, target)
NS_IMETHODIMP
HTMLSharedElement::GetHref(nsAString& aValue)
{
MOZ_ASSERT(mNodeInfo->Equals(nsGkAtoms::base),
"This should only get called for <base> elements");
nsAutoString href;
GetAttr(kNameSpaceID_None, nsGkAtoms::href, href);
nsCOMPtr<nsIURI> uri;
nsIDocument* doc = OwnerDoc();
nsContentUtils::NewURIWithDocumentCharset(
getter_AddRefs(uri), href, doc, doc->GetDocumentURI());
getter_AddRefs(uri), href, doc, doc->GetFallbackBaseURI());
if (!uri) {
aValue = href;
+35 -6
View File
@@ -20,8 +20,9 @@
#ifdef XP_MACOSX
#include "mozilla/EventDispatcher.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/HTMLObjectElement.h"
#endif
#include "mozilla/dom/HTMLObjectElement.h"
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(SharedObject)
@@ -84,7 +85,7 @@ HTMLSharedObjectElement::DoneAddingChildren(bool aHaveNotified)
// If we're already in a document, we need to trigger the load
// Otherwise, BindToTree takes care of that.
if (IsInComposedDoc()) {
StartObjectLoad(aHaveNotified);
StartObjectLoad(aHaveNotified, false);
}
}
}
@@ -192,7 +193,8 @@ HTMLSharedObjectElement::SetAttr(int32_t aNameSpaceID, nsIAtom *aName,
// a document, just in case that the caller wants to set additional
// attributes before inserting the node into the document.
if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren &&
aNameSpaceID == kNameSpaceID_None && aName == URIAttrName()) {
aNameSpaceID == kNameSpaceID_None && aName == URIAttrName()
&& !BlockEmbedContentLoading()) {
return LoadObject(aNotify, true);
}
@@ -320,15 +322,16 @@ HTMLSharedObjectElement::GetAttributeMappingFunction() const
}
void
HTMLSharedObjectElement::StartObjectLoad(bool aNotify)
HTMLSharedObjectElement::StartObjectLoad(bool aNotify, bool aForceLoad)
{
// BindToTree can call us asynchronously, and we may be removed from the tree
// in the interim
if (!IsInComposedDoc() || !OwnerDoc()->IsActive()) {
if (!IsInComposedDoc() || !OwnerDoc()->IsActive() ||
BlockEmbedContentLoading()) {
return;
}
LoadObject(aNotify);
LoadObject(aNotify, aForceLoad);
SetIsNetworkCreated(false);
}
@@ -400,5 +403,31 @@ HTMLSharedObjectElement::GetContentPolicyType() const
}
}
bool
HTMLSharedObjectElement::BlockEmbedContentLoading()
{
// Only check on embed elements
if (!IsHTMLElement(nsGkAtoms::embed)) {
return false;
}
// Traverse up the node tree to see if we have any ancestors that may block us
// from loading
for (nsIContent* parent = GetParent(); parent; parent = parent->GetParent()) {
if (parent->IsAnyOfHTMLElements(nsGkAtoms::video, nsGkAtoms::audio)) {
return true;
}
// If we have an ancestor that is an object with a source, it'll have an
// associated displayed type. If that type is not null, don't load content
// for the embed.
if (HTMLObjectElement* object = HTMLObjectElement::FromContent(parent)) {
uint32_t type = object->DisplayedType();
if (type != eType_Null) {
return true;
}
}
}
return false;
}
} // namespace dom
} // namespace mozilla
+21 -6
View File
@@ -80,7 +80,7 @@ public:
nsresult CopyInnerTo(Element* aDest);
void StartObjectLoad() { StartObjectLoad(true); }
void StartObjectLoad() { StartObjectLoad(true, false); }
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(HTMLSharedObjectElement,
nsGenericHTMLElement)
@@ -192,6 +192,11 @@ public:
return GetContentDocument();
}
/**
* Calls LoadObject with the correct arguments to start the plugin load.
*/
void StartObjectLoad(bool aNotify, bool aForceLoad);
protected:
// Override for nsImageLoadingContent.
nsIContent* AsContent() override { return this; }
@@ -199,11 +204,6 @@ protected:
private:
virtual ~HTMLSharedObjectElement();
/**
* Calls LoadObject with the correct arguments to start the plugin load.
*/
void StartObjectLoad(bool aNotify);
nsIAtom *URIAttrName() const
{
return mNodeInfo->Equals(nsGkAtoms::applet) ?
@@ -224,6 +224,21 @@ private:
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
nsRuleData* aData);
/**
* Decides whether we should load embed node content.
*
* If this is an embed node there are cases in which we should not try to load
* the content:
*
* - If the embed node is the child of a media element
* - If the embed node is the child of an object node that already has
* content being loaded.
*
* In these cases, this function will return false, which will cause
* us to skip calling LoadObject.
*/
bool BlockEmbedContentLoading();
};
} // namespace dom
+2 -2
View File
@@ -166,7 +166,7 @@ HTML_TAG("label", "Label");
HTML_TAG("legend", "Legend");
HTML_TAG("li", "LI");
HTML_TAG("link", "Link");
HTML_TAG("listing", "");
HTML_TAG("listing", "Pre");
HTML_TAG("main", "");
HTML_TAG("map", "Map");
HTML_TAG("mark", "");
@@ -223,7 +223,7 @@ HTML_TAG("u", "");
HTML_TAG("ul", "UList");
HTML_TAG("var", "");
HTML_TAG("wbr", "");
HTML_TAG("xmp", "");
HTML_TAG("xmp", "Pre");
function tagName(aTag) {
return "<" + aTag + ">";
+1 -1
View File
@@ -64,7 +64,7 @@ InputPort::Init(nsIInputPortData* aData, nsIInputPortListener* aListener, ErrorR
MediaStreamGraph* graph =
MediaStreamGraph::GetInstance(MediaStreamGraph::SYSTEM_THREAD_DRIVER,
AudioChannel::Normal);
mStream = DOMMediaStream::CreateSourceStream(GetOwner(), graph);
mStream = DOMMediaStream::CreateSourceStreamAsInput(GetOwner(), graph);
}
void
+2 -2
View File
@@ -173,8 +173,8 @@ XMLDocumentLoadPrincipalMismatch=Use of document.load forbidden on Documents tha
IndexedDBTransactionAbortNavigation=An IndexedDB transaction that was not yet complete has been aborted due to page navigation.
# LOCALIZATION NOTE: Do not translate Will-change, %1$S,%2$S are numbers.
IgnoringWillChangeOverBudgetWarning=Will-change memory consumption is too high. Budget limit is the document surface area multiplied by %1$S (%2$S px). Occurrences of will-change over the budget will be ignored.
# LOCALIZATION NOTE: Do not translate "ServiceWorker".
HittingMaxWorkersPerDomain=A ServiceWorker could not be started immediately because other documents in the same origin are already using the maximum number of workers. The ServiceWorker is now queued and will be started after some of the other workers have completed.
# LOCALIZATION NOTE: Do not translate "Worker".
HittingMaxWorkersPerDomain2=A Worker could not be started immediately because other documents in the same origin are already using the maximum number of workers. The Worker is now queued and will be started after some of the other workers have completed.
# LOCALIZATION NOTE: Do not translate "setVelocity", "PannerNode", "AudioListener", "speedOfSound" and "dopplerFactor"
PannerNodeDopplerWarning=Use of setVelocity on the PannerNode and AudioListener, and speedOfSound and dopplerFactor on the AudioListener are deprecated and those members will be removed. For more help https://developer.mozilla.org/en-US/docs/Web/API/AudioListener#Deprecated_features
# LOCALIZATION NOTE: Do not translate "Application Cache API", "AppCache" and "ServiceWorker".
+3 -3
View File
@@ -71,7 +71,7 @@ AudioCaptureStream::ProcessInput(GraphTime aFrom, GraphTime aTo,
}
uint32_t inputCount = mInputs.Length();
StreamBuffer::Track* track = EnsureTrack(mTrackId);
StreamTracks::Track* track = EnsureTrack(mTrackId);
// Notify the DOM everything is in order.
if (!mTrackCreated) {
for (uint32_t i = 0; i < mListeners.Length(); i++) {
@@ -101,7 +101,7 @@ AudioCaptureStream::ProcessInput(GraphTime aFrom, GraphTime aTo,
AudioSegment output;
for (uint32_t i = 0; i < inputCount; i++) {
MediaStream* s = mInputs[i]->GetSource();
StreamBuffer::TrackIter tracks(s->GetStreamBuffer(), MediaSegment::AUDIO);
StreamTracks::TrackIter tracks(s->GetStreamTracks(), MediaSegment::AUDIO);
while (!tracks.IsEnded()) {
AudioSegment* inputSegment = tracks->Get<AudioSegment>();
StreamTime inputStart = s->GraphTimeToStreamTimeWithBlocking(aFrom);
@@ -121,7 +121,7 @@ AudioCaptureStream::ProcessInput(GraphTime aFrom, GraphTime aTo,
}
// Regardless of the status of the input tracks, we go foward.
mBuffer.AdvanceKnownTracksTime(GraphTimeToStreamTimeWithBlocking((aTo)));
mTracks.AdvanceKnownTracksTime(GraphTimeToStreamTimeWithBlocking((aTo)));
}
void
+1 -1
View File
@@ -8,7 +8,7 @@
#include "MediaStreamGraph.h"
#include "AudioMixer.h"
#include "StreamBuffer.h"
#include "StreamTracks.h"
#include <algorithm>
namespace mozilla
+1 -1
View File
@@ -8,7 +8,7 @@
#include "DOMMediaStream.h"
#include "mozilla/dom/HTMLCanvasElement.h"
#include "StreamBuffer.h"
#include "StreamTracks.h"
class nsIPrincipal;
+20 -20
View File
@@ -853,9 +853,9 @@ DOMMediaStream::InitPlaybackStreamCommon(MediaStreamGraph* aGraph)
}
already_AddRefed<DOMMediaStream>
DOMMediaStream::CreateSourceStream(nsPIDOMWindow* aWindow,
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter)
DOMMediaStream::CreateSourceStreamAsInput(nsPIDOMWindow* aWindow,
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter)
{
RefPtr<DOMMediaStream> stream = new DOMMediaStream(aWindow, aTrackSourceGetter);
stream->InitSourceStream(aGraph);
@@ -863,9 +863,9 @@ DOMMediaStream::CreateSourceStream(nsPIDOMWindow* aWindow,
}
already_AddRefed<DOMMediaStream>
DOMMediaStream::CreateTrackUnionStream(nsPIDOMWindow* aWindow,
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter)
DOMMediaStream::CreateTrackUnionStreamAsInput(nsPIDOMWindow* aWindow,
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter)
{
RefPtr<DOMMediaStream> stream = new DOMMediaStream(aWindow, aTrackSourceGetter);
stream->InitTrackUnionStream(aGraph);
@@ -873,9 +873,9 @@ DOMMediaStream::CreateTrackUnionStream(nsPIDOMWindow* aWindow,
}
already_AddRefed<DOMMediaStream>
DOMMediaStream::CreateAudioCaptureStream(nsPIDOMWindow* aWindow,
nsIPrincipal* aPrincipal,
MediaStreamGraph* aGraph)
DOMMediaStream::CreateAudioCaptureStreamAsInput(nsPIDOMWindow* aWindow,
nsIPrincipal* aPrincipal,
MediaStreamGraph* aGraph)
{
// Audio capture doesn't create tracks dynamically
MediaStreamTrackSourceGetter* getter = nullptr;
@@ -1300,9 +1300,9 @@ DOMLocalMediaStream::StopImpl()
}
already_AddRefed<DOMLocalMediaStream>
DOMLocalMediaStream::CreateSourceStream(nsPIDOMWindow* aWindow,
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter)
DOMLocalMediaStream::CreateSourceStreamAsInput(nsPIDOMWindow* aWindow,
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter)
{
RefPtr<DOMLocalMediaStream> stream =
new DOMLocalMediaStream(aWindow, aTrackSourceGetter);
@@ -1311,9 +1311,9 @@ DOMLocalMediaStream::CreateSourceStream(nsPIDOMWindow* aWindow,
}
already_AddRefed<DOMLocalMediaStream>
DOMLocalMediaStream::CreateTrackUnionStream(nsPIDOMWindow* aWindow,
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter)
DOMLocalMediaStream::CreateTrackUnionStreamAsInput(nsPIDOMWindow* aWindow,
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter)
{
RefPtr<DOMLocalMediaStream> stream =
new DOMLocalMediaStream(aWindow, aTrackSourceGetter);
@@ -1332,9 +1332,9 @@ DOMAudioNodeMediaStream::~DOMAudioNodeMediaStream()
}
already_AddRefed<DOMAudioNodeMediaStream>
DOMAudioNodeMediaStream::CreateTrackUnionStream(nsPIDOMWindow* aWindow,
AudioNode* aNode,
MediaStreamGraph* aGraph)
DOMAudioNodeMediaStream::CreateTrackUnionStreamAsInput(nsPIDOMWindow* aWindow,
AudioNode* aNode,
MediaStreamGraph* aGraph)
{
RefPtr<DOMAudioNodeMediaStream> stream = new DOMAudioNodeMediaStream(aWindow, aNode);
stream->InitTrackUnionStream(aGraph);
@@ -1443,7 +1443,7 @@ DOMHwMediaStream::SetImageSize(uint32_t width, uint32_t height)
#endif
SourceMediaStream* srcStream = GetInputStream()->AsSourceStream();
StreamBuffer::Track* track = srcStream->FindTrack(TRACK_VIDEO_PRIMARY);
StreamTracks::Track* track = srcStream->FindTrack(TRACK_VIDEO_PRIMARY);
if (!track || !track->GetSegment()) {
return;
@@ -1479,7 +1479,7 @@ DOMHwMediaStream::SetOverlayImage(OverlayImage* aImage)
#endif
SourceMediaStream* srcStream = GetInputStream()->AsSourceStream();
StreamBuffer::Track* track = srcStream->FindTrack(TRACK_VIDEO_PRIMARY);
StreamTracks::Track* track = srcStream->FindTrack(TRACK_VIDEO_PRIMARY);
if (!track || !track->GetSegment()) {
return;
+19 -19
View File
@@ -10,7 +10,7 @@
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
#include "StreamBuffer.h"
#include "StreamTracks.h"
#include "nsIDOMWindow.h"
#include "nsIPrincipal.h"
#include "mozilla/DOMEventTargetHelper.h"
@@ -484,25 +484,25 @@ public:
/**
* Create a DOMMediaStream whose underlying input stream is a SourceMediaStream.
*/
static already_AddRefed<DOMMediaStream> CreateSourceStream(nsPIDOMWindow* aWindow,
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter = nullptr);
static already_AddRefed<DOMMediaStream> CreateSourceStreamAsInput(nsPIDOMWindow* aWindow,
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter = nullptr);
/**
* Create a DOMMediaStream whose underlying input stream is a TrackUnionStream.
*/
static already_AddRefed<DOMMediaStream> CreateTrackUnionStream(nsPIDOMWindow* aWindow,
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter = nullptr);
static already_AddRefed<DOMMediaStream> CreateTrackUnionStreamAsInput(nsPIDOMWindow* aWindow,
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter = nullptr);
/**
* Create an DOMMediaStream whose underlying input stream is an
* AudioCaptureStream.
*/
static already_AddRefed<DOMMediaStream>
CreateAudioCaptureStream(nsPIDOMWindow* aWindow,
nsIPrincipal* aPrincipal,
MediaStreamGraph* aGraph);
CreateAudioCaptureStreamAsInput(nsPIDOMWindow* aWindow,
nsIPrincipal* aPrincipal,
MediaStreamGraph* aGraph);
void SetLogicalStreamStartTime(StreamTime aTime)
{
@@ -719,17 +719,17 @@ public:
* Create an nsDOMLocalMediaStream whose underlying stream is a SourceMediaStream.
*/
static already_AddRefed<DOMLocalMediaStream>
CreateSourceStream(nsPIDOMWindow* aWindow,
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter = nullptr);
CreateSourceStreamAsInput(nsPIDOMWindow* aWindow,
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter = nullptr);
/**
* Create an nsDOMLocalMediaStream whose underlying stream is a TrackUnionStream.
*/
static already_AddRefed<DOMLocalMediaStream>
CreateTrackUnionStream(nsPIDOMWindow* aWindow,
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter = nullptr);
CreateTrackUnionStreamAsInput(nsPIDOMWindow* aWindow,
MediaStreamGraph* aGraph,
MediaStreamTrackSourceGetter* aTrackSourceGetter = nullptr);
protected:
virtual ~DOMLocalMediaStream();
@@ -753,9 +753,9 @@ public:
* Create a DOMAudioNodeMediaStream whose underlying stream is a TrackUnionStream.
*/
static already_AddRefed<DOMAudioNodeMediaStream>
CreateTrackUnionStream(nsPIDOMWindow* aWindow,
AudioNode* aNode,
MediaStreamGraph* aGraph);
CreateTrackUnionStreamAsInput(nsPIDOMWindow* aWindow,
AudioNode* aNode,
MediaStreamGraph* aGraph);
protected:
~DOMAudioNodeMediaStream();
+1 -1
View File
@@ -14,7 +14,7 @@
#include "nsTArray.h"
#include "ImageTypes.h"
#include "MediaData.h"
#include "StreamBuffer.h" // for TrackID
#include "StreamTracks.h" // for TrackID
#include "TimeUnits.h"
namespace mozilla {
+3 -3
View File
@@ -835,7 +835,7 @@ public:
// not a problem here, we got explicit user content.
nsCOMPtr<nsIPrincipal> principal = window->GetExtantDoc()->NodePrincipal();
domStream =
DOMMediaStream::CreateAudioCaptureStream(window, principal, msg);
DOMMediaStream::CreateAudioCaptureStreamAsInput(window, principal, msg);
stream = msg->CreateSourceStream(nullptr); // Placeholder
msg->RegisterCaptureStreamForWindow(
@@ -921,8 +921,8 @@ public:
// avoid us blocking. Pass a simple TrackSourceGetter for potential
// fake tracks. Apart from them gUM never adds tracks dynamically.
domStream =
DOMLocalMediaStream::CreateSourceStream(window, msg,
new FakeTrackSourceGetter(principal));
DOMLocalMediaStream::CreateSourceStreamAsInput(window, msg,
new FakeTrackSourceGetter(principal));
if (mAudioDevice) {
nsString audioDeviceName;
+1 -1
View File
@@ -45,7 +45,7 @@ typedef int64_t MediaTime;
const int64_t MEDIA_TIME_MAX = TRACK_TICKS_MAX;
/**
* Media time relative to the start of a StreamBuffer.
* Media time relative to the start of a StreamTracks.
*/
typedef MediaTime StreamTime;
const StreamTime STREAM_TIME_MAX = MEDIA_TIME_MAX;
+41 -41
View File
@@ -101,7 +101,7 @@ MediaStreamGraphImpl::FinishStream(MediaStream* aStream)
return;
STREAM_LOG(LogLevel::Debug, ("MediaStream %p will finish", aStream));
#ifdef DEBUG
for (StreamBuffer::TrackIter track(aStream->mBuffer);
for (StreamTracks::TrackIter track(aStream->mTracks);
!track.IsEnded(); track.Next()) {
if (!track->IsEnded()) {
STREAM_LOG(LogLevel::Error,
@@ -112,7 +112,7 @@ MediaStreamGraphImpl::FinishStream(MediaStream* aStream)
}
#endif
aStream->mFinished = true;
aStream->mBuffer.AdvanceKnownTracksTime(STREAM_TIME_MAX);
aStream->mTracks.AdvanceKnownTracksTime(STREAM_TIME_MAX);
SetStreamOrderDirty();
}
@@ -120,7 +120,7 @@ MediaStreamGraphImpl::FinishStream(MediaStream* aStream)
void
MediaStreamGraphImpl::AddStreamGraphThread(MediaStream* aStream)
{
aStream->mBufferStartTime = mProcessedTime;
aStream->mTracksStartTime = mProcessedTime;
if (aStream->IsSuspended()) {
mSuspendedStreams.AppendElement(aStream);
STREAM_LOG(LogLevel::Debug, ("Adding media stream %p to the graph, in the suspended stream array", aStream));
@@ -180,14 +180,14 @@ MediaStreamGraphImpl::ExtractPendingInput(SourceMediaStream* aStream,
StreamTime t = aStream->GraphTimeToStreamTime(aDesiredUpToTime);
STREAM_LOG(LogLevel::Verbose, ("Calling NotifyPull aStream=%p t=%f current end=%f", aStream,
MediaTimeToSeconds(t),
MediaTimeToSeconds(aStream->mBuffer.GetEnd())));
if (t > aStream->mBuffer.GetEnd()) {
MediaTimeToSeconds(aStream->mTracks.GetEnd())));
if (t > aStream->mTracks.GetEnd()) {
*aEnsureNextIteration = true;
#ifdef DEBUG
if (aStream->mListeners.Length() == 0) {
STREAM_LOG(LogLevel::Error, ("No listeners in NotifyPull aStream=%p desired=%f current end=%f",
aStream, MediaTimeToSeconds(t),
MediaTimeToSeconds(aStream->mBuffer.GetEnd())));
MediaTimeToSeconds(aStream->mTracks.GetEnd())));
aStream->DumpTrackInfo();
}
#endif
@@ -206,7 +206,7 @@ MediaStreamGraphImpl::ExtractPendingInput(SourceMediaStream* aStream,
SourceMediaStream::TrackData* data = &aStream->mUpdateTracks[i];
aStream->ApplyTrackDisabling(data->mID, data->mData);
StreamTime offset = (data->mCommands & SourceMediaStream::TRACK_CREATE)
? data->mStart : aStream->mBuffer.FindTrack(data->mID)->GetSegment()->GetDuration();
? data->mStart : aStream->mTracks.FindTrack(data->mID)->GetSegment()->GetDuration();
for (MediaStreamListener* l : aStream->mListeners) {
l->NotifyQueuedTrackChanges(this, data->mID,
offset, data->mCommands, *data->mData);
@@ -227,14 +227,14 @@ MediaStreamGraphImpl::ExtractPendingInput(SourceMediaStream* aStream,
int64_t(segment->GetDuration())));
data->mEndOfFlushedData += segment->GetDuration();
aStream->mBuffer.AddTrack(data->mID, data->mStart, segment);
aStream->mTracks.AddTrack(data->mID, data->mStart, segment);
// The track has taken ownership of data->mData, so let's replace
// data->mData with an empty clone.
data->mData = segment->CreateEmptyClone();
data->mCommands &= ~SourceMediaStream::TRACK_CREATE;
notifiedTrackCreated = true;
} else if (data->mData->GetDuration() > 0) {
MediaSegment* dest = aStream->mBuffer.FindTrack(data->mID)->GetSegment();
MediaSegment* dest = aStream->mTracks.FindTrack(data->mID)->GetSegment();
STREAM_LOG(LogLevel::Verbose, ("SourceMediaStream %p track %d, advancing end from %lld to %lld",
aStream, data->mID,
int64_t(dest->GetDuration()),
@@ -243,7 +243,7 @@ MediaStreamGraphImpl::ExtractPendingInput(SourceMediaStream* aStream,
dest->AppendFrom(data->mData);
}
if (data->mCommands & SourceMediaStream::TRACK_END) {
aStream->mBuffer.FindTrack(data->mID)->SetEnded();
aStream->mTracks.FindTrack(data->mID)->SetEnded();
aStream->mUpdateTracks.RemoveElementAt(i);
}
}
@@ -253,10 +253,10 @@ MediaStreamGraphImpl::ExtractPendingInput(SourceMediaStream* aStream,
}
}
if (!aStream->mFinished) {
aStream->mBuffer.AdvanceKnownTracksTime(aStream->mUpdateKnownTracksTime);
aStream->mTracks.AdvanceKnownTracksTime(aStream->mUpdateKnownTracksTime);
}
}
if (aStream->mBuffer.GetEnd() > 0) {
if (aStream->mTracks.GetEnd() > 0) {
aStream->mHasCurrentData = true;
}
if (finished) {
@@ -271,7 +271,7 @@ MediaStreamGraphImpl::GraphTimeToStreamTimeWithBlocking(MediaStream* aStream,
MOZ_ASSERT(aTime <= mStateComputedTime,
"Don't ask about times where we haven't made blocking decisions yet");
return std::max<StreamTime>(0,
std::min(aTime, aStream->mStartBlocking) - aStream->mBufferStartTime);
std::min(aTime, aStream->mStartBlocking) - aStream->mTracksStartTime);
}
GraphTime
@@ -294,7 +294,7 @@ MediaStreamGraphImpl::UpdateCurrentTimeForStreams(GraphTime aPrevCurrentTime)
blockedTime);
STREAM_LOG(LogLevel::Verbose,
("MediaStream %p bufferStartTime=%f blockedTime=%f", stream,
MediaTimeToSeconds(stream->mBufferStartTime),
MediaTimeToSeconds(stream->mTracksStartTime),
MediaTimeToSeconds(blockedTime)));
stream->mStartBlocking = mStateComputedTime;
@@ -326,7 +326,7 @@ MediaStreamGraphImpl::UpdateCurrentTimeForStreams(GraphTime aPrevCurrentTime)
// out.
if (stream->mFinished && !stream->mNotifiedFinished &&
mProcessedTime >=
stream->StreamTimeToGraphTime(stream->GetStreamBuffer().GetAllTracksEnd())) {
stream->StreamTimeToGraphTime(stream->GetStreamTracks().GetAllTracksEnd())) {
stream->mNotifiedFinished = true;
SetStreamOrderDirty();
for (uint32_t j = 0; j < stream->mListeners.Length(); ++j) {
@@ -382,7 +382,7 @@ MediaStreamGraphImpl::ProcessChunkMetadata(GraphTime aPrevCurrentTime)
for (MediaStream* stream : AllStreams()) {
StreamTime iterationStart = stream->GraphTimeToStreamTime(aPrevCurrentTime);
StreamTime iterationEnd = stream->GraphTimeToStreamTime(mProcessedTime);
for (StreamBuffer::TrackIter tracks(stream->mBuffer);
for (StreamTracks::TrackIter tracks(stream->mTracks);
!tracks.IsEnded(); tracks.Next()) {
MediaSegment* segment = tracks->GetSegment();
if (!segment) {
@@ -416,13 +416,13 @@ MediaStreamGraphImpl::WillUnderrun(MediaStream* aStream,
// This stream isn't finished or suspended. We don't need to call
// StreamTimeToGraphTime since an underrun is the only thing that can block
// it.
GraphTime bufferEnd = aStream->GetBufferEnd() + aStream->mBufferStartTime;
GraphTime bufferEnd = aStream->GetTracksEnd() + aStream->mTracksStartTime;
#ifdef DEBUG
if (bufferEnd < mProcessedTime) {
STREAM_LOG(LogLevel::Error, ("MediaStream %p underrun, "
"bufferEnd %f < mProcessedTime %f (%lld < %lld), Streamtime %lld",
aStream, MediaTimeToSeconds(bufferEnd), MediaTimeToSeconds(mProcessedTime),
bufferEnd, mProcessedTime, aStream->GetBufferEnd()));
bufferEnd, mProcessedTime, aStream->GetTracksEnd()));
aStream->DumpTrackInfo();
NS_ASSERTION(bufferEnd >= mProcessedTime, "Buffer underran");
}
@@ -455,7 +455,7 @@ MediaStreamGraphImpl::AudioTrackPresent(bool& aNeedsAEC)
if (stream->AsAudioNodeStream()) {
audioTrackPresent = true;
} else {
for (StreamBuffer::TrackIter tracks(stream->GetStreamBuffer(), MediaSegment::AUDIO);
for (StreamTracks::TrackIter tracks(stream->GetStreamTracks(), MediaSegment::AUDIO);
!tracks.IsEnded(); tracks.Next()) {
audioTrackPresent = true;
}
@@ -749,7 +749,7 @@ MediaStreamGraphImpl::CreateOrDestroyAudioStreams(MediaStream* aStream)
return;
}
if (!aStream->GetStreamBuffer().GetAndResetTracksDirty() &&
if (!aStream->GetStreamTracks().GetAndResetTracksDirty() &&
!aStream->mAudioOutputStreams.IsEmpty()) {
return;
}
@@ -761,7 +761,7 @@ MediaStreamGraphImpl::CreateOrDestroyAudioStreams(MediaStream* aStream)
audioOutputStreamsFound.AppendElement(false);
}
for (StreamBuffer::TrackIter tracks(aStream->GetStreamBuffer(), MediaSegment::AUDIO);
for (StreamTracks::TrackIter tracks(aStream->GetStreamTracks(), MediaSegment::AUDIO);
!tracks.IsEnded(); tracks.Next()) {
uint32_t i;
for (i = 0; i < audioOutputStreamsFound.Length(); ++i) {
@@ -820,13 +820,13 @@ MediaStreamGraphImpl::PlayAudio(MediaStream* aStream)
ticksWritten = 0;
MediaStream::AudioOutputStream& audioOutput = aStream->mAudioOutputStreams[i];
StreamBuffer::Track* track = aStream->mBuffer.FindTrack(audioOutput.mTrackID);
StreamTracks::Track* track = aStream->mTracks.FindTrack(audioOutput.mTrackID);
AudioSegment* audio = track->Get<AudioSegment>();
AudioSegment output;
StreamTime offset = aStream->GraphTimeToStreamTime(mProcessedTime);
// We don't update aStream->mBufferStartTime here to account for time spent
// We don't update aStream->mTracksStartTime here to account for time spent
// blocked. Instead, we'll update it in UpdateCurrentTimeForStreams after
// the blocked period has completed. But we do need to make sure we play
// from the right offsets in the stream buffer, even if we've already
@@ -945,7 +945,7 @@ MediaStreamGraphImpl::PlayVideo(MediaStream* aStream)
PrincipalHandle lastPrincipalHandle = PRINCIPAL_HANDLE_NONE;
RefPtr<Image> blackImage;
MOZ_ASSERT(mProcessedTime >= aStream->mBufferStartTime, "frame position before buffer?");
MOZ_ASSERT(mProcessedTime >= aStream->mTracksStartTime, "frame position before buffer?");
// We only look at the non-blocking interval
StreamTime frameBufferTime = aStream->GraphTimeToStreamTime(mProcessedTime);
StreamTime bufferEndTime = aStream->GraphTimeToStreamTime(aStream->mStartBlocking);
@@ -957,7 +957,7 @@ MediaStreamGraphImpl::PlayVideo(MediaStream* aStream)
// Pick the last track that has a video chunk for the time, and
// schedule its frame.
chunk = nullptr;
for (StreamBuffer::TrackIter tracks(aStream->GetStreamBuffer(),
for (StreamTracks::TrackIter tracks(aStream->GetStreamTracks(),
MediaSegment::VIDEO);
!tracks.IsEnded();
tracks.Next()) {
@@ -1388,14 +1388,14 @@ MediaStreamGraphImpl::UpdateGraph(GraphTime aEndBlockingDecisions)
// The stream's not suspended, and since it's finished, underruns won't
// stop it playing out. So there's no blocking other than what we impose
// here.
GraphTime endTime = stream->GetStreamBuffer().GetAllTracksEnd() +
stream->mBufferStartTime;
GraphTime endTime = stream->GetStreamTracks().GetAllTracksEnd() +
stream->mTracksStartTime;
if (endTime <= mStateComputedTime) {
STREAM_LOG(LogLevel::Verbose, ("MediaStream %p is blocked due to being finished", stream));
stream->mStartBlocking = mStateComputedTime;
} else {
STREAM_LOG(LogLevel::Verbose, ("MediaStream %p is finished, but not blocked yet (end at %f, with blocking at %f)",
stream, MediaTimeToSeconds(stream->GetBufferEnd()),
stream, MediaTimeToSeconds(stream->GetTracksEnd()),
MediaTimeToSeconds(endTime)));
// Data can't be added to a finished stream, so underruns are irrelevant.
stream->mStartBlocking = std::min(endTime, aEndBlockingDecisions);
@@ -1459,7 +1459,7 @@ MediaStreamGraphImpl::Process()
} else {
ps->ProcessInput(mProcessedTime, mStateComputedTime,
ProcessedMediaStream::ALLOW_FINISH);
NS_WARN_IF_FALSE(stream->mBuffer.GetEnd() >=
NS_WARN_IF_FALSE(stream->mTracks.GetEnd() >=
GraphTimeToStreamTimeWithBlocking(stream, mStateComputedTime),
"Stream did not produce enough data");
}
@@ -1948,7 +1948,7 @@ MediaStreamGraphImpl::AppendMessage(UniquePtr<ControlMessage> aMessage)
}
MediaStream::MediaStream(DOMMediaStream* aWrapper)
: mBufferStartTime(0)
: mTracksStartTime(0)
, mStartBlocking(GRAPH_TIME_MAX)
, mSuspendedCount(0)
, mFinished(false)
@@ -1988,7 +1988,7 @@ MediaStream::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
// - mListeners - elements
// - mAudioOutputStream - elements
amount += mBuffer.SizeOfExcludingThis(aMallocSizeOf);
amount += mTracks.SizeOfExcludingThis(aMallocSizeOf);
amount += mAudioOutputs.ShallowSizeOfExcludingThis(aMallocSizeOf);
amount += mVideoOutputs.ShallowSizeOfExcludingThis(aMallocSizeOf);
amount += mListeners.ShallowSizeOfExcludingThis(aMallocSizeOf);
@@ -2023,7 +2023,7 @@ MediaStream::SetGraphImpl(MediaStreamGraphImpl* aGraph)
MOZ_ASSERT(!mGraph, "Should only be called once");
mGraph = aGraph;
mAudioChannelType = aGraph->AudioChannel();
mBuffer.InitGraphRate(aGraph->GraphRate());
mTracks.InitGraphRate(aGraph->GraphRate());
}
void
@@ -2039,16 +2039,16 @@ MediaStream::GraphTimeToStreamTime(GraphTime aTime)
NS_ASSERTION(mStartBlocking == GraphImpl()->mStateComputedTime ||
aTime <= mStartBlocking,
"Incorrectly ignoring blocking!");
return aTime - mBufferStartTime;
return aTime - mTracksStartTime;
}
GraphTime
MediaStream::StreamTimeToGraphTime(StreamTime aTime)
{
NS_ASSERTION(mStartBlocking == GraphImpl()->mStateComputedTime ||
aTime + mBufferStartTime <= mStartBlocking,
aTime + mTracksStartTime <= mStartBlocking,
"Incorrectly ignoring blocking!");
return aTime + mBufferStartTime;
return aTime + mTracksStartTime;
}
StreamTime
@@ -2063,16 +2063,16 @@ MediaStream::FinishOnGraphThread()
GraphImpl()->FinishStream(this);
}
StreamBuffer::Track*
StreamTracks::Track*
MediaStream::FindTrack(TrackID aID)
{
return mBuffer.FindTrack(aID);
return mTracks.FindTrack(aID);
}
StreamBuffer::Track*
StreamTracks::Track*
MediaStream::EnsureTrack(TrackID aTrackId)
{
StreamBuffer::Track* track = mBuffer.FindTrack(aTrackId);
StreamTracks::Track* track = mTracks.FindTrack(aTrackId);
if (!track) {
nsAutoPtr<MediaSegment> segment(new AudioSegment());
for (uint32_t j = 0; j < mListeners.Length(); ++j) {
@@ -2084,7 +2084,7 @@ MediaStream::EnsureTrack(TrackID aTrackId)
// change this.
l->NotifyFinishedTrackCreation(Graph());
}
track = &mBuffer.AddTrack(aTrackId, 0, segment.forget());
track = &mTracks.AddTrack(aTrackId, 0, segment.forget());
}
return track;
}
@@ -2400,7 +2400,7 @@ MediaStream::AddTrackListenerImpl(already_AddRefed<MediaStreamTrackListener> aLi
l->mListener = aListener;
l->mTrackID = aTrackID;
StreamBuffer::Track* track = FindTrack(aTrackID);
StreamTracks::Track* track = FindTrack(aTrackID);
if (!track) {
return;
}
+21 -21
View File
@@ -16,7 +16,7 @@
#include "AudioStream.h"
#include "nsTArray.h"
#include "nsIRunnable.h"
#include "StreamBuffer.h"
#include "StreamTracks.h"
#include "VideoFrameContainer.h"
#include "VideoSegment.h"
#include "MainThreadUtils.h"
@@ -477,7 +477,7 @@ struct TrackBound
* time. To ensure video plays in sync with audio, make sure that the same
* stream is playing both the audio and video.
*
* The data in a stream is managed by StreamBuffer. It consists of a set of
* The data in a stream is managed by StreamTracks. It consists of a set of
* tracks of various types that can start and end over time.
*
* Streams are explicitly managed. The client creates them via
@@ -541,7 +541,7 @@ public:
/**
* Returns sample rate of the graph.
*/
TrackRate GraphRate() { return mBuffer.GraphRate(); }
TrackRate GraphRate() { return mTracks.GraphRate(); }
// Control API.
// Since a stream can be played multiple ways, we need to combine independent
@@ -674,9 +674,9 @@ public:
* This must be idempotent.
*/
virtual void DestroyImpl();
StreamTime GetBufferEnd() { return mBuffer.GetEnd(); }
StreamTime GetTracksEnd() { return mTracks.GetEnd(); }
#ifdef DEBUG
void DumpTrackInfo() { return mBuffer.DumpTrackInfo(); }
void DumpTrackInfo() { return mTracks.DumpTrackInfo(); }
#endif
void SetAudioOutputVolumeImpl(void* aKey, float aVolume);
void AddAudioOutputImpl(void* aKey);
@@ -713,36 +713,36 @@ public:
{
return mConsumers.Length();
}
StreamBuffer& GetStreamBuffer() { return mBuffer; }
GraphTime GetStreamBufferStartTime() { return mBufferStartTime; }
StreamTracks& GetStreamTracks() { return mTracks; }
GraphTime GetStreamTracksStartTime() { return mTracksStartTime; }
double StreamTimeToSeconds(StreamTime aTime)
{
NS_ASSERTION(0 <= aTime && aTime <= STREAM_TIME_MAX, "Bad time");
return static_cast<double>(aTime)/mBuffer.GraphRate();
return static_cast<double>(aTime)/mTracks.GraphRate();
}
int64_t StreamTimeToMicroseconds(StreamTime aTime)
{
NS_ASSERTION(0 <= aTime && aTime <= STREAM_TIME_MAX, "Bad time");
return (aTime*1000000)/mBuffer.GraphRate();
return (aTime*1000000)/mTracks.GraphRate();
}
StreamTime SecondsToNearestStreamTime(double aSeconds)
{
NS_ASSERTION(0 <= aSeconds && aSeconds <= TRACK_TICKS_MAX/TRACK_RATE_MAX,
"Bad seconds");
return mBuffer.GraphRate() * aSeconds + 0.5;
return mTracks.GraphRate() * aSeconds + 0.5;
}
StreamTime MicrosecondsToStreamTimeRoundDown(int64_t aMicroseconds) {
return (aMicroseconds*mBuffer.GraphRate())/1000000;
return (aMicroseconds*mTracks.GraphRate())/1000000;
}
TrackTicks TimeToTicksRoundUp(TrackRate aRate, StreamTime aTime)
{
return RateConvertTicksRoundUp(aRate, mBuffer.GraphRate(), aTime);
return RateConvertTicksRoundUp(aRate, mTracks.GraphRate(), aTime);
}
StreamTime TicksToTimeRoundDown(TrackRate aRate, TrackTicks aTicks)
{
return RateConvertTicksRoundDown(mBuffer.GraphRate(), aRate, aTicks);
return RateConvertTicksRoundDown(mTracks.GraphRate(), aRate, aTicks);
}
/**
* Convert graph time to stream time. aTime must be <= mStateComputedTime
@@ -773,9 +773,9 @@ public:
/**
* Find track by track id.
*/
StreamBuffer::Track* FindTrack(TrackID aID);
StreamTracks::Track* FindTrack(TrackID aID);
StreamBuffer::Track* EnsureTrack(TrackID aTrack);
StreamTracks::Track* EnsureTrack(TrackID aTrack);
virtual void ApplyTrackDisabling(TrackID aTrackID, MediaSegment* aSegment, MediaSegment* aRawSegment = nullptr);
@@ -808,8 +808,8 @@ public:
protected:
void AdvanceTimeVaryingValuesToCurrentTime(GraphTime aCurrentTime, GraphTime aBlockedTime)
{
mBufferStartTime += aBlockedTime;
mBuffer.ForgetUpTo(aCurrentTime - mBufferStartTime);
mTracksStartTime += aBlockedTime;
mTracks.ForgetUpTo(aCurrentTime - mTracksStartTime);
}
void NotifyMainThreadListeners()
@@ -836,14 +836,14 @@ protected:
// This state is all initialized on the main thread but
// otherwise modified only on the media graph thread.
// Buffered data. The start of the buffer corresponds to mBufferStartTime.
// Buffered data. The start of the buffer corresponds to mTracksStartTime.
// Conceptually the buffer contains everything this stream has ever played,
// but we forget some prefix of the buffered data to bound the space usage.
StreamBuffer mBuffer;
StreamTracks mTracks;
// The time when the buffered data could be considered to have started playing.
// This increases over time to account for time the stream was blocked before
// mCurrentTime.
GraphTime mBufferStartTime;
GraphTime mTracksStartTime;
// Client-set volume of this stream
struct AudioOutput {
@@ -863,7 +863,7 @@ protected:
// GraphTime at which this stream starts blocking.
// This is only valid up to mStateComputedTime. The stream is considered to
// have not been blocked before mCurrentTime (its mBufferStartTime is increased
// have not been blocked before mCurrentTime (its mTracksStartTime is increased
// as necessary to account for that time instead).
GraphTime mStartBlocking;
+1 -1
View File
@@ -403,7 +403,7 @@ public:
void PlayVideo(MediaStream* aStream);
/**
* No more data will be forthcoming for aStream. The stream will end
* at the current buffer end point. The StreamBuffer's tracks must be
* at the current buffer end point. The StreamTracks's tracks must be
* explicitly set to finished by the caller.
*/
void OpenAudioInputImpl(int aID,
+1 -1
View File
@@ -10,7 +10,7 @@
#include "nsError.h"
#include "nsID.h"
#include "nsIPrincipal.h"
#include "StreamBuffer.h"
#include "StreamTracks.h"
#include "MediaTrackConstraints.h"
#include "mozilla/CORSMode.h"
#include "PrincipalChangeObserver.h"
-1
View File
@@ -1172,7 +1172,6 @@ RTCPeerConnection.prototype = {
return null;
}
sdp = this._localIdp.addIdentityAttribute(sdp);
return new this._win.RTCSessionDescription({ type: this._localType,
sdp: sdp });
},
+117
View File
@@ -0,0 +1,117 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "StreamTracks.h"
#include "mozilla/Logging.h"
#include <algorithm>
namespace mozilla {
extern LazyLogModule gMediaStreamGraphLog;
#define STREAM_LOG(type, msg) MOZ_LOG(gMediaStreamGraphLog, type, msg)
#ifdef DEBUG
void
StreamTracks::DumpTrackInfo() const
{
STREAM_LOG(LogLevel::Info, ("DumpTracks: mTracksKnownTime %lld", mTracksKnownTime));
for (uint32_t i = 0; i < mTracks.Length(); ++i) {
Track* track = mTracks[i];
if (track->IsEnded()) {
STREAM_LOG(LogLevel::Info, ("Track[%d] %d: ended", i, track->GetID()));
} else {
STREAM_LOG(LogLevel::Info, ("Track[%d] %d: %lld", i, track->GetID(),
track->GetEnd()));
}
}
}
#endif
StreamTime
StreamTracks::GetEnd() const
{
StreamTime t = mTracksKnownTime;
for (uint32_t i = 0; i < mTracks.Length(); ++i) {
Track* track = mTracks[i];
if (!track->IsEnded()) {
t = std::min(t, track->GetEnd());
}
}
return t;
}
StreamTime
StreamTracks::GetAllTracksEnd() const
{
if (mTracksKnownTime < STREAM_TIME_MAX) {
// A track might be added.
return STREAM_TIME_MAX;
}
StreamTime t = 0;
for (uint32_t i = 0; i < mTracks.Length(); ++i) {
Track* track = mTracks[i];
if (!track->IsEnded()) {
return STREAM_TIME_MAX;
}
t = std::max(t, track->GetEnd());
}
return t;
}
StreamTracks::Track*
StreamTracks::FindTrack(TrackID aID)
{
if (aID == TRACK_NONE || mTracks.IsEmpty()) {
return nullptr;
}
// The tracks are sorted by ID. We can use a binary search.
uint32_t left = 0, right = mTracks.Length() - 1;
while (left <= right) {
uint32_t middle = (left + right) / 2;
if (mTracks[middle]->GetID() == aID) {
return mTracks[middle];
}
if (mTracks[middle]->GetID() > aID) {
if (middle == 0) {
break;
}
right = middle - 1;
} else {
left = middle + 1;
}
}
return nullptr;
}
void
StreamTracks::ForgetUpTo(StreamTime aTime)
{
// Only prune if there is a reasonable chunk (50ms @ 48kHz) to forget, so we
// don't spend too much time pruning segments.
const StreamTime minChunkSize = 2400;
if (aTime < mForgottenTime + minChunkSize) {
return;
}
mForgottenTime = aTime;
for (uint32_t i = 0; i < mTracks.Length(); ++i) {
Track* track = mTracks[i];
if (track->IsEnded() && track->GetEnd() <= aTime) {
mTracks.RemoveElementAt(i);
mTracksDirty = true;
--i;
continue;
}
StreamTime forgetTo = std::min(track->GetEnd() - 1, aTime);
track->ForgetUpTo(forgetTo);
}
}
} // namespace mozilla
+343
View File
@@ -0,0 +1,343 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_STREAMTRACKS_H_
#define MOZILLA_STREAMTRACKS_H_
#include "MediaSegment.h"
#include "nsAutoPtr.h"
namespace mozilla {
/**
* Unique ID for track within a StreamTracks. Tracks from different
* StreamTrackss may have the same ID; this matters when appending StreamTrackss,
* since tracks with the same ID are matched. Only IDs greater than 0 are allowed.
*/
typedef int32_t TrackID;
const TrackID TRACK_NONE = 0;
const TrackID TRACK_INVALID = -1;
const TrackID TRACK_ANY = -2;
inline bool IsTrackIDExplicit(const TrackID& aId) {
return aId > TRACK_NONE;
}
inline TrackTicks RateConvertTicksRoundDown(TrackRate aOutRate,
TrackRate aInRate,
TrackTicks aTicks)
{
NS_ASSERTION(0 < aOutRate && aOutRate <= TRACK_RATE_MAX, "Bad out rate");
NS_ASSERTION(0 < aInRate && aInRate <= TRACK_RATE_MAX, "Bad in rate");
NS_WARN_IF_FALSE(0 <= aTicks && aTicks <= TRACK_TICKS_MAX, "Bad ticks"); // bug 957691
return (aTicks * aOutRate) / aInRate;
}
inline TrackTicks RateConvertTicksRoundUp(TrackRate aOutRate,
TrackRate aInRate, TrackTicks aTicks)
{
NS_ASSERTION(0 < aOutRate && aOutRate <= TRACK_RATE_MAX, "Bad out rate");
NS_ASSERTION(0 < aInRate && aInRate <= TRACK_RATE_MAX, "Bad in rate");
NS_ASSERTION(0 <= aTicks && aTicks <= TRACK_TICKS_MAX, "Bad ticks");
return (aTicks * aOutRate + aInRate - 1) / aInRate;
}
/**
* This object contains the decoded data for a stream's tracks.
* A StreamTracks can be appended to. Logically a StreamTracks only gets longer,
* but we also have the ability to "forget" data before a certain time that
* we know won't be used again. (We prune a whole number of seconds internally.)
*
* StreamTrackss should only be used from one thread at a time.
*
* A StreamTracks has a set of tracks that can be of arbitrary types ---
* the data for each track is a MediaSegment. The set of tracks can vary
* over the timeline of the StreamTracks.
*/
class StreamTracks
{
public:
/**
* Every track has a start time --- when it started in the StreamTracks.
* It has an end flag; when false, no end point is known; when true,
* the track ends when the data we have for the track runs out.
* Tracks have a unique ID assigned at creation. This allows us to identify
* the same track across StreamTrackss. A StreamTracks should never have
* two tracks with the same ID (even if they don't overlap in time).
* TODO Tracks can also be enabled and disabled over time.
* Takes ownership of aSegment.
*/
class Track final
{
Track(TrackID aID, StreamTime aStart, MediaSegment* aSegment)
: mStart(aStart),
mSegment(aSegment),
mID(aID),
mEnded(false)
{
MOZ_COUNT_CTOR(Track);
NS_ASSERTION(aID > TRACK_NONE, "Bad track ID");
NS_ASSERTION(0 <= aStart && aStart <= aSegment->GetDuration(), "Bad start position");
}
public:
~Track()
{
MOZ_COUNT_DTOR(Track);
}
template <class T> T* Get() const
{
if (mSegment->GetType() == T::StaticType()) {
return static_cast<T*>(mSegment.get());
}
return nullptr;
}
MediaSegment* GetSegment() const { return mSegment; }
TrackID GetID() const { return mID; }
bool IsEnded() const { return mEnded; }
StreamTime GetStart() const { return mStart; }
StreamTime GetEnd() const { return mSegment->GetDuration(); }
MediaSegment::Type GetType() const { return mSegment->GetType(); }
void SetEnded() { mEnded = true; }
void AppendFrom(Track* aTrack)
{
NS_ASSERTION(!mEnded, "Can't append to ended track");
NS_ASSERTION(aTrack->mID == mID, "IDs must match");
NS_ASSERTION(aTrack->mStart == 0, "Source track must start at zero");
NS_ASSERTION(aTrack->mSegment->GetType() == GetType(), "Track types must match");
mSegment->AppendFrom(aTrack->mSegment);
mEnded = aTrack->mEnded;
}
MediaSegment* RemoveSegment()
{
return mSegment.forget();
}
void ForgetUpTo(StreamTime aTime)
{
mSegment->ForgetUpTo(aTime);
}
void FlushAfter(StreamTime aNewEnd)
{
// Forget everything after a given endpoint
// a specified amount
mSegment->FlushAfter(aNewEnd);
}
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t amount = aMallocSizeOf(this);
if (mSegment) {
amount += mSegment->SizeOfIncludingThis(aMallocSizeOf);
}
return amount;
}
private:
friend class StreamTracks;
// Start offset is in ticks at rate mRate
StreamTime mStart;
// The segment data starts at the start of the owning StreamTracks, i.e.,
// there's mStart silence/no video at the beginning.
nsAutoPtr<MediaSegment> mSegment;
// Unique ID
TrackID mID;
// True when the track ends with the data in mSegment
bool mEnded;
};
class MOZ_STACK_CLASS CompareTracksByID final
{
public:
bool Equals(Track* aA, Track* aB) const {
return aA->GetID() == aB->GetID();
}
bool LessThan(Track* aA, Track* aB) const {
return aA->GetID() < aB->GetID();
}
};
StreamTracks()
: mGraphRate(0)
, mTracksKnownTime(0)
, mForgottenTime(0)
, mTracksDirty(false)
#ifdef DEBUG
, mGraphRateIsSet(false)
#endif
{
MOZ_COUNT_CTOR(StreamTracks);
}
~StreamTracks()
{
MOZ_COUNT_DTOR(StreamTracks);
}
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t amount = 0;
amount += mTracks.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (size_t i = 0; i < mTracks.Length(); i++) {
amount += mTracks[i]->SizeOfIncludingThis(aMallocSizeOf);
}
return amount;
}
/**
* Initialize the graph rate for use in calculating StreamTimes from track
* ticks. Called when a MediaStream's graph pointer is initialized.
*/
void InitGraphRate(TrackRate aGraphRate)
{
mGraphRate = aGraphRate;
#if DEBUG
MOZ_ASSERT(!mGraphRateIsSet);
mGraphRateIsSet = true;
#endif
}
TrackRate GraphRate() const
{
MOZ_ASSERT(mGraphRateIsSet);
return mGraphRate;
}
/**
* Takes ownership of aSegment. Don't do this while iterating, or while
* holding a Track reference.
* aSegment must have aStart worth of null data.
*/
Track& AddTrack(TrackID aID, StreamTime aStart, MediaSegment* aSegment)
{
NS_ASSERTION(!FindTrack(aID), "Track with this ID already exists");
Track* track = new Track(aID, aStart, aSegment);
mTracks.InsertElementSorted(track, CompareTracksByID());
mTracksDirty = true;
if (mTracksKnownTime == STREAM_TIME_MAX) {
// There exists code like
// http://mxr.mozilla.org/mozilla-central/source/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp?rev=96b197deb91e&mark=1292-1297#1292
NS_WARNING("Adding track to StreamTracks that should have no more tracks");
} else {
NS_ASSERTION(mTracksKnownTime <= aStart, "Start time too early");
}
return *track;
}
void AdvanceKnownTracksTime(StreamTime aKnownTime)
{
NS_ASSERTION(aKnownTime >= mTracksKnownTime, "Can't move tracks-known time earlier");
mTracksKnownTime = aKnownTime;
}
/**
* The end time for the StreamTracks is the latest time for which we have
* data for all tracks that haven't ended by that time.
*/
StreamTime GetEnd() const;
/**
* Returns the earliest time >= 0 at which all tracks have ended
* and all their data has been played out and no new tracks can be added,
* or STREAM_TIME_MAX if there is no such time.
*/
StreamTime GetAllTracksEnd() const;
#ifdef DEBUG
void DumpTrackInfo() const;
#endif
Track* FindTrack(TrackID aID);
class MOZ_STACK_CLASS TrackIter final
{
public:
/**
* Iterate through the tracks of aBuffer in order of ID.
*/
explicit TrackIter(const StreamTracks& aBuffer) :
mBuffer(&aBuffer.mTracks), mIndex(0), mMatchType(false) {}
/**
* Iterate through the tracks of aBuffer with type aType, in order of ID.
*/
TrackIter(const StreamTracks& aBuffer, MediaSegment::Type aType) :
mBuffer(&aBuffer.mTracks), mIndex(0), mType(aType), mMatchType(true) { FindMatch(); }
bool IsEnded() { return mIndex >= mBuffer->Length(); }
void Next()
{
++mIndex;
FindMatch();
}
Track* get() { return mBuffer->ElementAt(mIndex); }
Track& operator*() { return *mBuffer->ElementAt(mIndex); }
Track* operator->() { return mBuffer->ElementAt(mIndex); }
private:
void FindMatch()
{
if (!mMatchType)
return;
while (mIndex < mBuffer->Length() &&
mBuffer->ElementAt(mIndex)->GetType() != mType) {
++mIndex;
}
}
const nsTArray<nsAutoPtr<Track> >* mBuffer;
uint32_t mIndex;
MediaSegment::Type mType;
bool mMatchType;
};
friend class TrackIter;
/**
* Forget stream data before aTime; they will no longer be needed.
* Also can forget entire tracks that have ended at or before aTime.
* Can't be used to forget beyond GetEnd().
*/
void ForgetUpTo(StreamTime aTime);
/**
* Returns the latest time passed to ForgetUpTo.
*/
StreamTime GetForgottenDuration()
{
return mForgottenTime;
}
bool GetAndResetTracksDirty()
{
if (!mTracksDirty) {
return false;
}
mTracksDirty = false;
return true;
}
protected:
TrackRate mGraphRate; // StreamTime per second
// Any new tracks added will start at or after this time. In other words, the track
// list is complete and correct for all times less than this time.
StreamTime mTracksKnownTime;
StreamTime mForgottenTime;
private:
// All known tracks for this StreamTracks
nsTArray<nsAutoPtr<Track>> mTracks;
bool mTracksDirty;
#ifdef DEBUG
bool mGraphRateIsSet;
#endif
};
} // namespace mozilla
#endif /* MOZILLA_STREAMTRACKS_H_ */
+10 -10
View File
@@ -87,14 +87,14 @@ TrackUnionStream::TrackUnionStream(DOMMediaStream* aWrapper) :
allHaveCurrentData = false;
}
bool trackAdded = false;
for (StreamBuffer::TrackIter tracks(stream->GetStreamBuffer());
for (StreamTracks::TrackIter tracks(stream->GetStreamTracks());
!tracks.IsEnded(); tracks.Next()) {
bool found = false;
for (uint32_t j = 0; j < mTrackMap.Length(); ++j) {
TrackMapEntry* map = &mTrackMap[j];
if (map->mInputPort == mInputs[i] && map->mInputTrackID == tracks->GetID()) {
bool trackFinished;
StreamBuffer::Track* outputTrack = mBuffer.FindTrack(map->mOutputTrackID);
bool trackFinished = false;
StreamTracks::Track* outputTrack = mTracks.FindTrack(map->mOutputTrackID);
found = true;
if (!outputTrack || outputTrack->IsEnded() ||
!mInputs[i]->PassTrackThrough(tracks->GetID())) {
@@ -138,7 +138,7 @@ TrackUnionStream::TrackUnionStream(DOMMediaStream* aWrapper) :
// so we're finished now.
FinishOnGraphThread();
} else {
mBuffer.AdvanceKnownTracksTime(GraphTimeToStreamTimeWithBlocking(aTo));
mTracks.AdvanceKnownTracksTime(GraphTimeToStreamTimeWithBlocking(aTo));
}
if (allHaveCurrentData) {
// We can make progress if we're not blocked
@@ -146,7 +146,7 @@ TrackUnionStream::TrackUnionStream(DOMMediaStream* aWrapper) :
}
}
uint32_t TrackUnionStream::AddTrack(MediaInputPort* aPort, StreamBuffer::Track* aTrack,
uint32_t TrackUnionStream::AddTrack(MediaInputPort* aPort, StreamTracks::Track* aTrack,
GraphTime aFrom)
{
STREAM_LOG(LogLevel::Verbose, ("TrackUnionStream %p adding track %d for "
@@ -205,8 +205,8 @@ TrackUnionStream::TrackUnionStream(DOMMediaStream* aWrapper) :
aPort->GetSource(), aTrack->GetID());
}
segment->AppendNullData(outputStart);
StreamBuffer::Track* track =
&mBuffer.AddTrack(id, outputStart, segment.forget());
StreamTracks::Track* track =
&mTracks.AddTrack(id, outputStart, segment.forget());
STREAM_LOG(LogLevel::Debug, ("TrackUnionStream %p added track %d for input stream %p track %d, start ticks %lld",
this, track->GetID(), aPort->GetSource(), aTrack->GetID(),
(long long)outputStart));
@@ -246,7 +246,7 @@ TrackUnionStream::TrackUnionStream(DOMMediaStream* aWrapper) :
void TrackUnionStream::EndTrack(uint32_t aIndex)
{
StreamBuffer::Track* outputTrack = mBuffer.FindTrack(mTrackMap[aIndex].mOutputTrackID);
StreamTracks::Track* outputTrack = mTracks.FindTrack(mTrackMap[aIndex].mOutputTrackID);
if (!outputTrack || outputTrack->IsEnded())
return;
STREAM_LOG(LogLevel::Debug, ("TrackUnionStream %p ending track %d", this, outputTrack->GetID()));
@@ -269,12 +269,12 @@ TrackUnionStream::TrackUnionStream(DOMMediaStream* aWrapper) :
outputTrack->SetEnded();
}
void TrackUnionStream::CopyTrackData(StreamBuffer::Track* aInputTrack,
void TrackUnionStream::CopyTrackData(StreamTracks::Track* aInputTrack,
uint32_t aMapIndex, GraphTime aFrom, GraphTime aTo,
bool* aOutputTrackFinished)
{
TrackMapEntry* map = &mTrackMap[aMapIndex];
StreamBuffer::Track* outputTrack = mBuffer.FindTrack(map->mOutputTrackID);
StreamTracks::Track* outputTrack = mTracks.FindTrack(map->mOutputTrackID);
MOZ_ASSERT(outputTrack && !outputTrack->IsEnded(), "Can't copy to ended track");
MediaSegment* segment = map->mSegment;
+3 -3
View File
@@ -41,7 +41,7 @@ protected:
// We keep track IDs instead of track pointers because
// tracks can be removed without us being notified (e.g.
// when a finished track is forgotten.) When we need a Track*,
// we call StreamBuffer::FindTrack, which will return null if
// we call StreamTracks::FindTrack, which will return null if
// the track has been deleted.
TrackID mInputTrackID;
TrackID mOutputTrackID;
@@ -54,10 +54,10 @@ protected:
// Add the track to this stream, retaining its TrackID if it has never
// been previously used in this stream, allocating a new TrackID otherwise.
uint32_t AddTrack(MediaInputPort* aPort, StreamBuffer::Track* aTrack,
uint32_t AddTrack(MediaInputPort* aPort, StreamTracks::Track* aTrack,
GraphTime aFrom);
void EndTrack(uint32_t aIndex);
void CopyTrackData(StreamBuffer::Track* aInputTrack,
void CopyTrackData(StreamTracks::Track* aInputTrack,
uint32_t aMapIndex, GraphTime aFrom, GraphTime aTo,
bool* aOutputTrackFinished);
+1 -1
View File
@@ -10,7 +10,7 @@
#include "AudioSegment.h"
#include "EncodedFrameContainer.h"
#include "StreamBuffer.h"
#include "StreamTracks.h"
#include "TrackMetadataBase.h"
#include "VideoSegment.h"
#include "MediaStreamGraph.h"
+2 -2
View File
@@ -136,7 +136,7 @@ EXPORTS += [
'SeekTask.h',
'SelfRef.h',
'SharedBuffer.h',
'StreamBuffer.h',
'StreamTracks.h',
'ThreadPoolCOMListener.h',
'TimeUnits.h',
'TrackUnionStream.h',
@@ -239,7 +239,7 @@ UNIFIED_SOURCES += [
'RtspMediaResource.cpp',
'SeekJob.cpp',
'SeekTask.cpp',
'StreamBuffer.cpp',
'StreamTracks.cpp',
'TextTrack.cpp',
'TextTrackCue.cpp',
'TextTrackCueList.cpp',
@@ -8,7 +8,7 @@
<script type="application/javascript">
createHTML({
bug: "1087551",
title: "addCandidate behavior in different states"
title: "addIceCandidate behavior (local and remote) including invalid data"
});
var test;
@@ -71,6 +71,28 @@
sdpMLineIndex: 0});
return test.pcRemote._pc.addIceCandidate(candidate)
.then(ok(true, "Successfully added valid ICE candidate"));
},
// bug 1095793
function PC_REMOTE_ADD_MISMATCHED_MID_AND_LEVEL_CANDIDATE(test) {
var bogus = new mozRTCIceCandidate(
{candidate:"candidate:1 1 UDP 2130706431 192.168.2.1 50005 typ host",
sdpMLineIndex: 0,
sdpMid: "sdparta_1"});
return test.pcRemote._pc.addIceCandidate(bogus)
.then(
generateErrorCallback("addIceCandidate should have failed."),
err => {
is(err.name, "InvalidCandidateError", "Error is InvalidCandidateError");
}
);
},
function PC_REMOTE_ADD_MATCHING_MID_AND_LEVEL_CANDIDATE(test) {
var candidate = new mozRTCIceCandidate(
{candidate:"candidate:1 1 UDP 2130706431 192.168.2.1 50005 typ host",
sdpMLineIndex: 0,
sdpMid: "sdparta_0"});
return test.pcRemote._pc.addIceCandidate(candidate)
.then(ok(true, "Successfully added valid ICE candidate with matching mid and level"));
}
]);
test.run();
+1
View File
@@ -514,6 +514,7 @@ AudioContext::CreateOscillator(ErrorResult& aRv)
already_AddRefed<PeriodicWave>
AudioContext::CreatePeriodicWave(const Float32Array& aRealData,
const Float32Array& aImagData,
const PeriodicWaveConstraints& aConstraints,
ErrorResult& aRv)
{
aRealData.ComputeLengthAndData();
+2
View File
@@ -68,6 +68,7 @@ class ScriptProcessorNode;
class StereoPannerNode;
class WaveShaperNode;
class PeriodicWave;
struct PeriodicWaveConstraints;
class Promise;
enum class OscillatorType : uint32_t;
@@ -255,6 +256,7 @@ public:
already_AddRefed<PeriodicWave>
CreatePeriodicWave(const Float32Array& aRealData, const Float32Array& aImagData,
const PeriodicWaveConstraints& aConstraints,
ErrorResult& aRv);
already_AddRefed<Promise>
@@ -135,9 +135,9 @@ AudioNodeExternalInputStream::ProcessInput(GraphTime aFrom, GraphTime aTo,
MediaStream* source = mInputs[0]->GetSource();
AutoTArray<AudioSegment,1> audioSegments;
uint32_t inputChannels = 0;
for (StreamBuffer::TrackIter tracks(source->mBuffer, MediaSegment::AUDIO);
for (StreamTracks::TrackIter tracks(source->mTracks, MediaSegment::AUDIO);
!tracks.IsEnded(); tracks.Next()) {
const StreamBuffer::Track& inputTrack = *tracks;
const StreamTracks::Track& inputTrack = *tracks;
if (!mInputs[0]->PassTrackThrough(tracks->GetID())) {
continue;
}
+5 -5
View File
@@ -385,9 +385,9 @@ public:
void Run() override
{
auto ns = static_cast<AudioNodeStream*>(mStream);
ns->mBufferStartTime -= mAdvance;
ns->mTracksStartTime -= mAdvance;
StreamBuffer::Track* track = ns->EnsureTrack(AUDIO_TRACK);
StreamTracks::Track* track = ns->EnsureTrack(AUDIO_TRACK);
track->Get<AudioSegment>()->AppendNullData(mAdvance);
ns->GraphImpl()->DecrementSuspendCount(mStream);
@@ -630,9 +630,9 @@ AudioNodeStream::ProduceOutputBeforeInput(GraphTime aFrom)
void
AudioNodeStream::AdvanceOutputSegment()
{
StreamBuffer::Track* track = EnsureTrack(AUDIO_TRACK);
StreamTracks::Track* track = EnsureTrack(AUDIO_TRACK);
// No more tracks will be coming
mBuffer.AdvanceKnownTracksTime(STREAM_TIME_MAX);
mTracks.AdvanceKnownTracksTime(STREAM_TIME_MAX);
AudioSegment* segment = track->Get<AudioSegment>();
@@ -655,7 +655,7 @@ AudioNodeStream::AdvanceOutputSegment()
void
AudioNodeStream::FinishOutput()
{
StreamBuffer::Track* track = EnsureTrack(AUDIO_TRACK);
StreamTracks::Track* track = EnsureTrack(AUDIO_TRACK);
track->SetEnded();
for (uint32_t j = 0; j < mListeners.Length(); ++j) {
@@ -30,9 +30,9 @@ MediaStreamAudioDestinationNode::MediaStreamAudioDestinationNode(AudioContext* a
ChannelCountMode::Explicit,
ChannelInterpretation::Speakers)
, mDOMStream(
DOMAudioNodeMediaStream::CreateTrackUnionStream(GetOwner(),
this,
aContext->Graph()))
DOMAudioNodeMediaStream::CreateTrackUnionStreamAsInput(GetOwner(),
this,
aContext->Graph()))
{
// Ensure an audio track with the correct ID is exposed to JS
nsIDocument* doc = aContext->GetParentObject()->GetExtantDoc();
+2 -2
View File
@@ -16,7 +16,7 @@
#include "MediaEngine.h"
#include "VideoSegment.h"
#include "AudioSegment.h"
#include "StreamBuffer.h"
#include "StreamTracks.h"
#include "MediaStreamGraph.h"
#include "MediaTrackConstraints.h"
@@ -134,7 +134,7 @@ public:
const PrincipalHandle& aPrincipalHandle) override
{
#ifdef DEBUG
StreamBuffer::Track* data = aSource->FindTrack(aId);
StreamTracks::Track* data = aSource->FindTrack(aId);
NS_WARN_IF_FALSE(!data || data->IsEnded() ||
aDesiredTime <= aSource->GetEndOfAppendedData(aId),
"MediaEngineDefaultAudioSource data underrun");
@@ -24,7 +24,7 @@
#include "MediaEngineCameraVideoSource.h"
#include "VideoSegment.h"
#include "AudioSegment.h"
#include "StreamBuffer.h"
#include "StreamTracks.h"
#include "MediaStreamGraph.h"
#include "MediaEngineWrapper.h"
+1 -1
View File
@@ -27,7 +27,7 @@
#include "MediaEngineCameraVideoSource.h"
#include "VideoSegment.h"
#include "AudioSegment.h"
#include "StreamBuffer.h"
#include "StreamTracks.h"
#include "MediaStreamGraph.h"
#include "cubeb/cubeb.h"
#include "CubebUtils.h"
+16 -31
View File
@@ -220,20 +220,9 @@ WifiGeoCoordsObject.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGeoPositionCoords])
};
function WifiGeoPositionObject(lat, lng, acc, cc, tz, zip, city, rc, region, country, isp, org, as) {
function WifiGeoPositionObject(lat, lng, acc) {
this.coords = new WifiGeoCoordsObject(lat, lng, acc, 0, 0);
this.address = null;
this.countrycode = cc;
this.timezone = tz;
this.zipcode = zip;
this.postalcode = zip;
this.city = city;
this.regioncode = rc;
this.region = region;
this.country = country;
this.isp = isp;
this.org = org;
this.as = as;
this.timestamp = Date.now();
}
@@ -394,8 +383,9 @@ WifiGeoPositionProvider.prototype = {
let result = ap.ssid.indexOf(mask, ap.ssid.length - mask.length);
if (result != -1) {
LOG("Filtering out " + ap.ssid + " " + result);
return false;
}
return result;
return true;
};
function sort(a, b) {
@@ -455,7 +445,7 @@ WifiGeoPositionProvider.prototype = {
break;
// CDMA cases to be handled in bug 1010282
};
result.push({ radio: radioTechFamily,
result.push({ radioType: radioTechFamily,
mobileCountryCode: voice.network.mcc,
mobileNetworkCode: voice.network.mnc,
locationAreaCode: cell.gsmLocationAreaCode,
@@ -506,43 +496,38 @@ WifiGeoPositionProvider.prototype = {
this.notifyListener("locationUpdatePending");
try {
xhr.open("GET", url, true);
xhr.open("POST", url, true);
} catch (e) {
this.notifyListener("notifyError",
[POSITION_UNAVAILABLE]);
return;
}
xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
xhr.responseType = "json";
xhr.mozBackgroundRequest = true;
xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS;
xhr.timeout = Services.prefs.getIntPref("geo.wifi.xhr.timeout");
xhr.ontimeout = (function() {
LOG("Location request XHR timed out.")
this.notifyListener("notifyError",
[POSITION_UNAVAILABLE]);
}).bind(this);
xhr.onerror = (function() {
this.notifyListener("notifyError",
[POSITION_UNAVAILABLE]);
}).bind(this);
xhr.onload = (function() {
LOG("server returned status: " + xhr.status + " --> " + JSON.stringify(xhr.response));
if ((xhr.channel instanceof Ci.nsIHttpChannel && xhr.status != 200) ||
!xhr.response || !xhr.response.status || xhr.response.status == 'fail') {
!xhr.response || !xhr.response.location) {
this.notifyListener("notifyError",
[POSITION_UNAVAILABLE]);
return;
}
let newLocation = new WifiGeoPositionObject(xhr.response.lat,
xhr.response.lon,
null, //accuracy not provided
xhr.response.countryCode,
xhr.response.timezone,
xhr.response.zip,
xhr.response.city,
xhr.response.region,
xhr.response.regionName,
xhr.response.country,
xhr.response.isp,
xhr.response.org,
xhr.response.as);
let newLocation = new WifiGeoPositionObject(xhr.response.location.lat,
xhr.response.location.lng,
xhr.response.accuracy);
this.notifyListener("update", [newLocation]);
gCachedRequest = new CachedRequest(newLocation, data.cellTowers, data.wifiAccessPoints);
+1 -1
View File
@@ -27,7 +27,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
function ActiveProvider(aProvider) {
this.id = aProvider.id;
this._instance = Cc[aProvider.contractId].getService(Ci.nsISystemUpdateProvider);
this._instance = Components.classesByID[aProvider.id].getService(Ci.nsISystemUpdateProvider);
this._instance.setListener(this);
}
+1 -1
View File
@@ -13,7 +13,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
const kPrefRilDebuggingEnabled = "ril.debugging.enabled";
let DEBUG;
var DEBUG;
function debug(s) {
dump("USSDReceivedWrapper: " + s + "\n");
}
@@ -4,7 +4,7 @@
const TEST_URI = "http://example.com/browser/dom/tests/browser/test-console-api.html";
const TEST_URI_NAV = "http://example.com/browser/dom/tests/browser/";
let ConsoleAPIStorage = Cc["@mozilla.org/consoleAPI-storage;1"]
var ConsoleAPIStorage = Cc["@mozilla.org/consoleAPI-storage;1"]
.getService(Ci.nsIConsoleAPIStorage);
var apiCallCount;
+1
View File
@@ -6,3 +6,4 @@ skip-if = buildapp == 'b2g'
[test_offsets.js]
[test_offsets.xul]
skip-if = buildapp == 'mulet'
[test_spacetopagedown.html]
@@ -94,8 +94,8 @@ function checkOrder(entries, name) {
<p id="display"></p>
<div id="content">
<img src="http://mochi.test:8888/tests/image/test/mochitest/over.png">
<object data="http://mochi.test:8888/tests/image/test/mochitest/clear.png" type="image/png"/>
<embed src="http://mochi.test:8888/tests/image/test/mochitest/green.png" type="image/png"/>
<object data="http://mochi.test:8888/tests/image/test/mochitest/clear.png" type="image/png"></object>
<embed src="http://mochi.test:8888/tests/image/test/mochitest/green.png" type="image/png"/>
</div>
</body>
</html>
@@ -276,9 +276,9 @@ function iframeTestsCompleted() {
<p id="display"></p>
<div id="content">
<img src="http://mochi.test:8888/tests/image/test/mochitest/blue.png">
<object data="http://mochi.test:8888/tests/image/test/mochitest/red.png" type="image/png"/>
<embed src="http://mochi.test:8888/tests/image/test/mochitest/big.png" type="image/png"/>
<iframe sandbox="allow-same-origin allow-scripts" id="if_2" src="resource_timing_iframe.html" height="10" width="10"></iframe>
<object data="http://mochi.test:8888/tests/image/test/mochitest/red.png" type="image/png"></object>
<embed src="http://mochi.test:8888/tests/image/test/mochitest/big.png" type="image/png"/>
<iframe sandbox="allow-same-origin allow-scripts" id="if_2" src="resource_timing_iframe.html" height="10" width="10"></iframe>
</div>
</body>
</html>
@@ -1367,7 +1367,7 @@ var interfaceNamesInGlobalScope =
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "TVTuner", b2g: true, permission: ["tv"]},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "U2F", release: false},
{name: "U2F", disabled: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "UDPMessageEvent", b2g: true, permission: ["udp-socket"]},
// IMPORTANT: Do not change this list without review from a DOM peer!
@@ -0,0 +1,76 @@
<html>
<head>
<meta charset="utf-8">
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
<script type="application/javascript;version=1.7">
SimpleTest.waitForExplicitFinish();
Components.utils.import("resource://gre/modules/Task.jsm");
var windowUtils = SpecialPowers.getDOMWindowUtils(window);
function pressKey(isShift)
{
return new Promise(resolve => {
synthesizeKey(" ", { shiftKey: isShift });
windowUtils.advanceTimeAndRefresh(100);
SimpleTest.executeSoon(resolve);
});
}
function initTest()
{
SpecialPowers.pushPrefEnv({"set":[["general.smoothScroll", false]]}, runTest);
}
function runTest()
{
Task.async(function () {
yield pressKey(false);
ok(window.scrollY > 0, "Space with no focus" + window.scrollY);
yield pressKey(true);
is(window.scrollY, 0, "Shift+Space with no focus");
let checkbox = document.getElementById("checkbox");
checkbox.focus();
yield pressKey(false);
is(window.scrollY, 0, "Space with checkbox focused");
ok(checkbox.checked, "Space with checkbox focused, checked");
yield pressKey(true);
is(window.scrollY, 0, "Shift+Space with checkbox focused");
ok(!checkbox.checked, "Space with checkbox focused, unchecked");
let input = document.getElementById("input");
input.focus();
yield pressKey(false);
is(window.scrollY, 0, "Space with input focused");
is(input.value, " ", "Space with input focused, value");
yield pressKey(true);
is(window.scrollY, 0, "Shift+Space with input focused");
is(input.value, " ", "Space with input focused, value");
windowUtils.restoreNormalRefresh();
SimpleTest.finish();
})();
}
</script>
</head>
<body onload="SimpleTest.waitForFocus(initTest)">
<input id="checkbox" type="checkbox">Checkbox
<input id="input">
<p style="height: 4000px">Text</p>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>
@@ -0,0 +1,49 @@
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://testing-common/httpd.js");
var httpserver = null;
var geolocation = null;
function geoHandler(metadata, response)
{
response.processAsync();
}
function successCallback() {
// The call shouldn't be sucessful.
do_check_true(false);
do_test_finished();
}
function errorCallback() {
do_check_true(true);
do_test_finished();
}
function run_test()
{
do_test_pending();
// XPCShell does not get a profile by default. The geolocation service
// depends on the settings service which uses IndexedDB and IndexedDB
// needs a place where it can store databases.
do_get_profile();
httpserver = new HttpServer();
httpserver.registerPathHandler("/geo", geoHandler);
httpserver.start(-1);
var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
prefs.setCharPref("geo.wifi.uri", "http://localhost:" +
httpserver.identity.primaryPort + "/geo");
prefs.setBoolPref("dom.testing.ignore_ipc_principal", true);
prefs.setBoolPref("geo.wifi.scan", false);
// Setting timeout to a very low value to ensure time out will happen.
prefs.setIntPref("geo.wifi.xhr.timeout", 5);
geolocation = Cc["@mozilla.org/geolocation;1"].getService(Ci.nsISupports);
geolocation.getCurrentPosition(successCallback, errorCallback);
}
+2
View File
@@ -24,3 +24,5 @@ skip-if = os == "android"
skip-if = os == "mac" || os == "android"
[test_PromiseDebugging.js]
[test_xhr_init.js]
[test_geolocation_provider_timeout.js]
skip-if = os == "android"
+1 -1
View File
@@ -82,7 +82,7 @@ TetheringManager.prototype = {
this.NSGetFactory =
XPCOMUtils.generateNSGetFactory([TetheringManager]);
let debug;
var debug;
if (DEBUG) {
debug = function (s) {
dump("-*- TetheringManager component: " + s + "\n");
+1 -1
View File
@@ -38,7 +38,7 @@ function Deferred() {
Object.freeze(this);
}
let gTestSuite = (function() {
var gTestSuite = (function() {
let suite = {};
let tetheringManager;
+1 -1
View File
@@ -31,7 +31,7 @@ const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
const kPrefRilDebuggingEnabled = "ril.debugging.enabled";
const kPrefDefaultServiceId = "dom.voicemail.defaultServiceId";
let DEBUG;
var DEBUG;
function debug(s) {
dump("VoicemailService: " + s);
}
+4 -4
View File
@@ -5,7 +5,7 @@
const {Cc: Cc, Ci: Ci, Cr: Cr, Cu: Cu} = SpecialPowers;
let RIL = SpecialPowers.wrap(SpecialPowers.createBlankObject());
var RIL = SpecialPowers.wrap(SpecialPowers.createBlankObject());
SpecialPowers.Cu.import("resource://gre/modules/ril_consts.js", RIL);
// Emulate Promise.jsm semantics.
@@ -27,7 +27,7 @@ const MWI_TIMESTAMP = "00000000000000";
// Only bring in what we need from ril_worker/RadioInterfaceLayer here. Reusing
// that code turns out to be a nightmare, so there is some code duplication.
let PDUBuilder = {
var PDUBuilder = {
toHexString: function(n, length) {
let str = n.toString(16);
if (str.length < length) {
@@ -200,7 +200,7 @@ let PDUBuilder = {
}
};
let pendingEmulatorCmdCount = 0;
var pendingEmulatorCmdCount = 0;
/**
* Send emulator command with safe guard.
@@ -258,7 +258,7 @@ function pushPermissions(aPermissions) {
return deferred.promise;
}
let voicemail;
var voicemail;
/**
* Add required permissions and test if |navigator.mozVoicemail| exists.
+4 -4
View File
@@ -6,16 +6,16 @@
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
let WSP = {};
var WSP = {};
Cu.import("resource://gre/modules/WspPduHelper.jsm", WSP);
let WBXML = {};
var WBXML = {};
Cu.import("resource://gre/modules/WbxmlPduHelper.jsm", WBXML);
Cu.import("resource://services-crypto/utils.js");
Cu.import("resource://services-common/utils.js");
// set to true to see debug messages
let DEBUG = WBXML.DEBUG_ALL | false;
var DEBUG = WBXML.DEBUG_ALL | false;
/**
* Public identifier for CP
@@ -468,7 +468,7 @@ const CP_VALUE_FIELDS = (function () {
return names;
})();
let debug;
var debug;
if (DEBUG) {
debug = function (s) {
dump("-$- CpPduHelper: " + s + "\n");
+3 -3
View File
@@ -6,13 +6,13 @@
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
let WSP = {};
var WSP = {};
Cu.import("resource://gre/modules/WspPduHelper.jsm", WSP);
let WBXML = {};
var WBXML = {};
Cu.import("resource://gre/modules/WbxmlPduHelper.jsm", WBXML);
// set to true to see debug messages
let DEBUG = WBXML.DEBUG_ALL | false;
var DEBUG = WBXML.DEBUG_ALL | false;
/**
* Public identifier for SI
+3 -3
View File
@@ -6,13 +6,13 @@
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
let WSP = {};
var WSP = {};
Cu.import("resource://gre/modules/WspPduHelper.jsm", WSP);
let WBXML = {};
var WBXML = {};
Cu.import("resource://gre/modules/WbxmlPduHelper.jsm", WBXML);
// set to true to see debug messages
let DEBUG = WBXML.DEBUG_ALL | false;
var DEBUG = WBXML.DEBUG_ALL | false;
/**
* Public identifier for SL
+2 -2
View File
@@ -4,7 +4,7 @@
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
@@ -161,7 +161,7 @@ this.WapPushManager = {
},
};
let debug;
var debug;
if (DEBUG) {
debug = function (s) {
dump("-*- WapPushManager: " + s + "\n");
+1 -1
View File
@@ -6,7 +6,7 @@
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
let WSP = {};
var WSP = {};
Cu.import("resource://gre/modules/WspPduHelper.jsm", WSP);
/**
+2 -2
View File
@@ -3,8 +3,8 @@
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
let subscriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
var subscriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader);
+7 -7
View File
@@ -1,7 +1,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
let CP = {};
var CP = {};
subscriptLoader.loadSubScript("resource://gre/modules/CpPduHelper.jsm", CP);
CP.debug = do_print;
@@ -30,7 +30,7 @@ function test_hmac(rawDataArray, mac, key, expectResult) {
/*
* Test data from OMA-TS-WAP_ProvCont-V1_1-2009 0421-C.pdf, clause 6.1
*/
let text_data_array = new Uint8Array([
var text_data_array = new Uint8Array([
0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65,
0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31,
0x2E, 0x30, 0x22, 0x3F, 0x3E, 0x3C, 0x21, 0x44,
@@ -288,7 +288,7 @@ let text_data_array = new Uint8Array([
/*
* Test data from OMA-TS-WAP_ProvCont-V1_1-20090421-C.pdf, Appendix C
*/
let wbxml_data_array = new Uint8Array([
var wbxml_data_array = new Uint8Array([
// WBXML version 1.3
0x03,
// The Public Identifier for "-//WAPFORUM//DTD PROV 1.0//EN"
@@ -444,7 +444,7 @@ let wbxml_data_array = new Uint8Array([
/*
* Test data from CHT CP, with code page change
*/
let wbxml_code_page_data_array = new Uint8Array([
var wbxml_code_page_data_array = new Uint8Array([
0x03, 0x0B, 0x6A, 0x00, 0x45, 0xC6, 0x56, 0x01,
0x87, 0x07, 0x06, 0x03, 0x43, 0x48, 0x54, 0x5F,
0x65, 0x6D, 0x6F, 0x6D, 0x65, 0x00, 0x01, 0x01,
@@ -513,11 +513,11 @@ let wbxml_code_page_data_array = new Uint8Array([
/*
* Test data from OMA-TS-WAP_ProvCont-V1_1-20090421-C.pdf, clause 6.1
*/
let xml_header =
var xml_header =
"<?xml version=\"1.0\"?>" +
"<!DOCTYPE wap-provisioningdoc PUBLIC \"-//WAPFORUM//DTD PROV 1.0//EN\" \"http://www.wapforum.org/DTD/prov.dtd\">";
let xml_body =
var xml_body =
"<wap-provisioningdoc version=\"1.0\">" +
"<characteristic type=\"PXLOGICAL\">" +
"<parm name=\"PROXY-ID\" value=\"170.187.51.4\"/>" +
@@ -572,7 +572,7 @@ let xml_body =
"</characteristic>" +
"</wap-provisioningdoc>";
let wbxml_code_page_content =
var wbxml_code_page_content =
"<wap-provisioningdoc>" +
"<characteristic type=\"BOOTSTRAP\">" +
"<parm name=\"NAME\" value=\"CHT_emome\"/>" +
+1 -1
View File
@@ -1,7 +1,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
let SI = {};
var SI = {};
subscriptLoader.loadSubScript("resource://gre/modules/SiPduHelper.jsm", SI);
SI.debug = do_print;
+1 -1
View File
@@ -1,7 +1,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
let SL = {};
var SL = {};
subscriptLoader.loadSubScript("resource://gre/modules/SlPduHelper.jsm", SL);
SL.debug = do_print;
+5 -1
View File
@@ -19,6 +19,10 @@ enum AudioContextState {
"closed"
};
dictionary PeriodicWaveConstraints {
boolean disableNormalization = false;
};
[Constructor,
Constructor(AudioChannel audioChannelType)]
interface AudioContext : EventTarget {
@@ -88,7 +92,7 @@ interface AudioContext : EventTarget {
[NewObject, Throws]
OscillatorNode createOscillator();
[NewObject, Throws]
PeriodicWave createPeriodicWave(Float32Array real, Float32Array imag);
PeriodicWave createPeriodicWave(Float32Array real, Float32Array imag, optional PeriodicWaveConstraints constraints);
};
+11
View File
@@ -4,9 +4,20 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/**
* The PageTransitionEvent interface is used for the pageshow and
* pagehide events, which are generic events that apply to both page
* load/unload and saving/restoring a document from session history.
*/
[Constructor(DOMString type, optional PageTransitionEventInit eventInitDict)]
interface PageTransitionEvent : Event
{
/**
* Set to true if the document has been or will be persisted across
* firing of the event. For example, if a document is being cached in
* session history, |persisted| is true for the PageHide event.
*/
readonly attribute boolean persisted;
};
+1
View File
@@ -68,6 +68,7 @@ dictionary SignResponse {
callback U2FRegisterCallback = void(RegisterResponse response);
callback U2FSignCallback = void(SignResponse response);
[Pref="security.webauth.u2f"]
interface U2F {
// These enumerations are defined in the FIDO U2F Javascript API under the
// interface "ErrorCode" as constant integers, and also in the U2F.cpp file.
+1 -1
View File
@@ -533,7 +533,7 @@ this.NSGetFactory = XPCOMUtils.generateNSGetFactory([
MozWifiConnectionInfo
]);
let debug;
var debug;
if (DEBUG) {
debug = function (s) {
dump("-*- DOMWifiManager component: " + s + "\n");
+3 -3
View File
@@ -106,7 +106,7 @@ const GO_DHCP_SERVER_IP_RANGE = {
endIp: "192.168.2.30"
};
let gDebug = false;
var gDebug = false;
// Device Capability bitmap
const DEVICE_CAPAB_SERVICE_DISCOVERY = 1;
@@ -1188,7 +1188,7 @@ function P2pStateMachine(aP2pCommand, aNetUtil) {
enter: function() {
this.groupOwner = {
macAddress: _groupInfo.goAddress,
ipAddress: _groupInfo.networkInterface.gateways[0],
ipAddress: _groupInfo.networkInterface.info.gateways[0],
passphrase: _groupInfo.passphrase,
ssid: _groupInfo.ssid,
freq: _groupInfo.freq,
@@ -1443,7 +1443,7 @@ function P2pStateMachine(aP2pCommand, aNetUtil) {
debug("Client. Request IP from DHCP server on interface: " + _groupInfo.ifname);
aNetUtil.runDhcp(aInfo.ifname, function(dhcpData) {
aNetUtil.runDhcp(aInfo.ifname, 0, function(dhcpData) {
if(!dhcpData || !dhcpData.info) {
debug('Failed to run DHCP client');
onFailure();
+28 -9
View File
@@ -416,7 +416,7 @@ var WifiManager = (function() {
let currentNetwork = Object.create(null);
currentNetwork.netId = manager.connectionInfo.id;
manager.getNetworkConfiguration(currentNetwork, function (){
manager.getNetworkConfiguration(currentNetwork, function () {
curNetworkKey = getNetworkKey(currentNetwork);
// Add additional information to static ip configuration
@@ -435,15 +435,19 @@ var WifiManager = (function() {
// If the ssid of current connection is the same as configured ssid
// It means we need update current connection to use static IP address.
if (setNetworkKey == curNetworkKey) {
// Use configureInterface directly doesn't work, the network iterface
// Use configureInterface directly doesn't work, the network interface
// and routing table is changed but still cannot connect to network
// so the workaround here is disable interface the enable again to
// trigger network reconnect with static ip.
gNetworkService.disableInterface(manager.ifname, function (ok) {
gNetworkService.enableInterface(manager.ifname, function (ok) {
callback(ok);
});
});
return;
}
callback(true);
});
}
@@ -865,6 +869,16 @@ var WifiManager = (function() {
if (eventData.indexOf("CTRL-EVENT-EAP") === 0) {
return handleWpaEapEvents(event);
}
if (eventData.indexOf("CTRL-EVENT-ASSOC-REJECT") === 0) {
debug("CTRL-EVENT-ASSOC-REJECT: network error");
notify("passwordmaybeincorrect");
if (manager.authenticationFailuresCount > MAX_RETRIES_ON_AUTHENTICATION_FAILURE) {
manager.authenticationFailuresCount = 0;
debug("CTRL-EVENT-ASSOC-REJECT: disconnect network");
notify("disconnected", {connectionInfo: manager.connectionInfo});
}
return true;
}
if (eventData.indexOf("WPS-TIMEOUT") === 0) {
notifyStateChange({ state: "WPS_TIMEOUT", BSSID: null, id: -1 });
return true;
@@ -1772,7 +1786,7 @@ function isWepHexKey(s) {
}
let WifiNetworkInterface = {
var WifiNetworkInterface = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface]),
@@ -1839,8 +1853,8 @@ function WifiScanResult() {}
// TODO Make the difference between a DOM-based network object and our
// networks objects much clearer.
let netToDOM;
let netFromDOM;
var netToDOM;
var netFromDOM;
function WifiWorker() {
var self = this;
@@ -2192,7 +2206,10 @@ function WifiWorker() {
ssid: quote(WifiManager.connectionInfo.ssid),
mode: MODE_ESS,
frequency: 0};
self._fireEvent("onconnecting", { network: netToDOM(self.currentNetwork) });
WifiManager.getNetworkConfiguration(self.currentNetwork, function (){
// Notify again because we get complete network information.
self._fireEvent("onconnecting", { network: netToDOM(self.currentNetwork) });
});
break;
case "ASSOCIATED":
// set to full power mode when ready to do 4 way handsharke.
@@ -2628,7 +2645,9 @@ WifiWorker.prototype = {
// Only fire the event if the link speed changed or the signal
// strength changed by more than 10%.
function tensPlace(percent) ((percent / 10) | 0)
function tensPlace(percent) {
return (percent / 10) | 0;
}
if (last && last.linkSpeed === info.linkSpeed &&
last.ipAddress === info.ipAddress &&
@@ -3507,7 +3526,7 @@ WifiWorker.prototype = {
},
setStaticIpMode: function(msg) {
const message = "WifiManager:setStaticMode:Return";
const message = "WifiManager:setStaticIpMode:Return";
let self = this;
let network = msg.data.network;
let info = msg.data.info;
@@ -3895,7 +3914,7 @@ WifiWorker.prototype = {
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([WifiWorker]);
let debug;
var debug;
function updateDebug() {
if (DEBUG) {
debug = function (s) {
+284 -90
View File
@@ -43,13 +43,14 @@ const HOSTAPD_CONFIG_LIST = [
},
];
let gTestSuite = (function() {
var gTestSuite = (function() {
let suite = {};
// Private member variables of the returned object |suite|.
let wifiManager;
let wifiOrigEnabled;
let pendingEmulatorShellCount = 0;
let sdkVersion;
/**
* A wrapper function of "is".
@@ -433,6 +434,23 @@ let gTestSuite = (function() {
.then(event => event.target.result);
}
/**
* Set the given network to static ip mode.
*
* Resolve when we set static ip mode successfully; reject when any error
* occurs.
*
* Fulfill params: (none)
* Reject params: (none)
*
* @return A deferred promise.
*/
function setStaticIpMode(aNetwork, aConfig) {
let request = wifiManager.setStaticIpMode(aNetwork, aConfig);
return wrapDomRequestAsPromise(request)
.then(event => event.target.result);
}
/**
* Issue a request to scan all wifi available networks.
*
@@ -450,6 +468,57 @@ let gTestSuite = (function() {
.then(event => event.target.result);
}
/**
* Import a certificate with nickname and password.
*
* Resolve when we import certificate successfully; reject when any error
* occurs.
*
* Fulfill params: An object of certificate information.
* Reject params: (none)
*
* @return A deferred promise.
*/
function importCert(certBlob, password, nickname) {
let request = wifiManager.importCert(certBlob, password, nickname);
return wrapDomRequestAsPromise(request)
.then(event => event.target.result);
}
/**
* Delete certificate of nickname.
*
* Resolve when we delete certificate successfully; reject when any error
* occurs.
*
* Fulfill params: (none)
* Reject params: (none)
*
* @return A deferred promise.
*/
function deleteCert(nickname) {
let request = wifiManager.deleteCert(nickname);
return wrapDomRequestAsPromise(request)
.then(event => event.target.result);
}
/**
* Get list of imported certificates.
*
* Resolve when we get certificate list successfully; reject when any error
* occurs.
*
* Fulfill params: Nickname of imported certificate arranged by usage.
* Reject params: (none)
*
* @return A deferred promise.
*/
function getImportedCerts() {
let request = wifiManager.getImportedCerts();
return wrapDomRequestAsPromise(request)
.then(event => event.target.result);
}
/**
* Request wifi scan and verify the scan result as well.
*
@@ -707,7 +776,12 @@ let gTestSuite = (function() {
.then(() => runEmulatorShellSafe(['hostapd', '-B', configFileName]))
.then(function (reply) {
// It may fail at the first time due to the previous ungracefully terminated one.
if (reply[0] === 'bind(PF_UNIX): Address already in use') {
if (reply.length === 0) {
// The hostapd starts successfully
return;
}
if (reply[0].indexOf('bind(PF_UNIX): Address already in use') !== -1) {
return startOneHostapd(aIndex);
}
});
@@ -784,10 +858,21 @@ let gTestSuite = (function() {
* @return A deferred promise.
*/
function writeFile(aFilePath, aContent) {
if (-1 === aContent.indexOf(' ')) {
aContent = '"' + aContent + '"';
const CONTENT_MAX_LENGTH = 900;
var commands = [];
for (var i = 0; i < aContent.length; i += CONTENT_MAX_LENGTH) {
var content = aContent.substr(i, CONTENT_MAX_LENGTH);
if (-1 === content.indexOf(' ')) {
content = '"' + content + '"';
}
commands.push(['echo', '-n', content, i === 0 ? '>' : '>>', aFilePath]);
}
return runEmulatorShellSafe(['echo', aContent, '>', aFilePath]);
let chain = Promise.resolve();
commands.forEach(function (command) {
chain = chain.then(() => runEmulatorShellSafe(command));
});
return chain;
}
/**
@@ -963,6 +1048,117 @@ let gTestSuite = (function() {
});
}
/**
* Execute 'netcfg' shell and parse the result.
*
* Resolve when the executing is successful and reject otherwise.
*
* Fulfill params: Command result object, each key of which is the interface
* name and value is { ip(string), prefix(string) }.
* Reject params: String that indicates the reason of rejection.
*
* @return A deferred promise.
*/
function exeAndParseNetcfg() {
return runEmulatorShellSafe(['netcfg'])
.then(function (aLines) {
// Sample output:
//
// lo UP 127.0.0.1/8 0x00000049 00:00:00:00:00:00
// eth0 UP 10.0.2.15/24 0x00001043 52:54:00:12:34:56
// rmnet1 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:58
// rmnet2 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:59
// rmnet3 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:5a
// wlan0 UP 192.168.1.1/24 0x00001043 52:54:00:12:34:5b
// sit0 DOWN 0.0.0.0/0 0x00000080 00:00:00:00:00:00
// rmnet0 UP 10.0.2.100/24 0x00001043 52:54:00:12:34:57
//
let netcfgResult = {};
aLines.forEach(function (aLine) {
let tokens = aLine.split(/\s+/);
if (tokens.length < 5) {
return;
}
let ifname = tokens[0];
let [ip, prefix] = tokens[2].split('/');
netcfgResult[ifname] = { ip: ip, prefix: prefix };
});
log("netcfg result:" + JSON.stringify(netcfgResult));
return netcfgResult;
});
}
/**
* Execute 'ip route' and parse the result.
*
* Resolve when the executing is successful and reject otherwise.
*
* Fulfill params: Command result object, each key of which is the interface
* name and value is { src(string), gateway(string),
* default(boolean) }.
* Reject params: String that indicates the reason of rejection.
*
* @return A deferred promise.
*/
function exeAndParseIpRoute() {
return runEmulatorShellSafe(['ip', 'route'])
.then(function (aLines) {
// Sample output:
//
// 10.0.2.4 via 10.0.2.2 dev rmnet0
// 10.0.2.3 via 10.0.2.2 dev rmnet0
// 192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.1
// 10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15
// 10.0.2.0/24 dev rmnet0 proto kernel scope link src 10.0.2.100
// default via 10.0.2.2 dev rmnet0
// default via 10.0.2.2 dev eth0 metric 2
//
let ipRouteResult = {};
// Parse source ip for each interface.
aLines.forEach(function (aLine) {
let tokens = aLine.trim().split(/\s+/);
let srcIndex = tokens.indexOf('src');
if (srcIndex < 0 || srcIndex + 1 >= tokens.length) {
return;
}
let ifname = tokens[2];
let src = tokens[srcIndex + 1];
ipRouteResult[ifname] = { src: src, default: false, gateway: null };
});
// Parse default interfaces.
aLines.forEach(function (aLine) {
let tokens = aLine.split(/\s+/);
if (tokens.length < 2) {
return;
}
if ('default' === tokens[0]) {
let ifnameIndex = tokens.indexOf('dev');
if (ifnameIndex < 0 || ifnameIndex + 1 >= tokens.length) {
return;
}
let ifname = tokens[ifnameIndex + 1];
if (!ipRouteResult[ifname]) {
return;
}
ipRouteResult[ifname].default = true;
let gwIndex = tokens.indexOf('via');
if (gwIndex < 0 || gwIndex + 1 >= tokens.length) {
return;
}
ipRouteResult[ifname].gateway = tokens[gwIndex + 1];
return;
}
});
log("ip route result:" + JSON.stringify(ipRouteResult));
return ipRouteResult;
});
}
/**
* Verify everything about routing when the wifi tethering is either on or off.
*
@@ -982,93 +1178,20 @@ let gTestSuite = (function() {
* @return A deferred promise.
*/
function verifyTetheringRouting(aEnabled) {
let netcfgResult = {};
let ipRouteResult = {};
// Execute 'netcfg' and parse to |netcfgResult|, each key of which is the
// interface name and value is { ip(string) }.
function exeAndParseNetcfg() {
return runEmulatorShellSafe(['netcfg'])
.then(function (aLines) {
// Sample output:
//
// lo UP 127.0.0.1/8 0x00000049 00:00:00:00:00:00
// eth0 UP 10.0.2.15/24 0x00001043 52:54:00:12:34:56
// rmnet1 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:58
// rmnet2 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:59
// rmnet3 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:5a
// wlan0 UP 192.168.1.1/24 0x00001043 52:54:00:12:34:5b
// sit0 DOWN 0.0.0.0/0 0x00000080 00:00:00:00:00:00
// rmnet0 UP 10.0.2.100/24 0x00001043 52:54:00:12:34:57
//
aLines.forEach(function (aLine) {
let tokens = aLine.split(/\s+/);
if (tokens.length < 5) {
return;
}
let ifname = tokens[0];
let ip = (tokens[2].split('/'))[0];
netcfgResult[ifname] = { ip: ip };
});
});
}
// Execute 'ip route' and parse to |ipRouteResult|, each key of which is the
// interface name and value is { src(string), default(boolean) }.
function exeAndParseIpRoute() {
return runEmulatorShellSafe(['ip', 'route'])
.then(function (aLines) {
// Sample output:
//
// 10.0.2.4 via 10.0.2.2 dev rmnet0
// 10.0.2.3 via 10.0.2.2 dev rmnet0
// 192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.1
// 10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15
// 10.0.2.0/24 dev rmnet0 proto kernel scope link src 10.0.2.100
// default via 10.0.2.2 dev rmnet0
// default via 10.0.2.2 dev eth0 metric 2
//
// Parse source ip for each interface.
aLines.forEach(function (aLine) {
let tokens = aLine.trim().split(/\s+/);
let srcIndex = tokens.indexOf('src');
if (srcIndex < 0 || srcIndex + 1 >= tokens.length) {
return;
}
let ifname = tokens[2];
let src = tokens[srcIndex + 1];
ipRouteResult[ifname] = { src: src, default: false };
});
// Parse default interfaces.
aLines.forEach(function (aLine) {
let tokens = aLine.split(/\s+/);
if (tokens.length < 2) {
return;
}
if ('default' === tokens[0]) {
let ifnameIndex = tokens.indexOf('dev');
if (ifnameIndex < 0 || ifnameIndex + 1 >= tokens.length) {
return;
}
let ifname = tokens[ifnameIndex + 1];
if (ipRouteResult[ifname]) {
ipRouteResult[ifname].default = true;
}
return;
}
});
});
}
let netcfgResult;
let ipRouteResult;
// Find MASQUERADE in POSTROUTING section. 'MASQUERADE' should be found
// when tethering is enabled. 'MASQUERADE' shouldn't be found when tethering
// is disabled.
function verifyIptables() {
return runEmulatorShellSafe(['iptables', '-t', 'nat', '-L', 'POSTROUTING'])
let MASQUERADE_checkSection = 'POSTROUTING';
if (sdkVersion > 15) {
// Check 'natctrl_nat_POSTROUTING' section after ICS.
MASQUERADE_checkSection = 'natctrl_nat_POSTROUTING';
}
return runEmulatorShellSafe(['iptables', '-t', 'nat', '-L', MASQUERADE_checkSection])
.then(function(aLines) {
// $ iptables -t nat -L POSTROUTING
//
@@ -1096,9 +1219,6 @@ let gTestSuite = (function() {
}
function verifyDefaultRouteAndIp(aExpectedWifiTetheringIp) {
log(JSON.stringify(ipRouteResult));
log(JSON.stringify(netcfgResult));
if (aEnabled) {
isOrThrow(ipRouteResult['rmnet0'].src, netcfgResult['rmnet0'].ip, 'rmnet0.ip');
isOrThrow(ipRouteResult['rmnet0'].default, true, 'rmnet0.default');
@@ -1111,7 +1231,9 @@ let gTestSuite = (function() {
return verifyIptables()
.then(exeAndParseNetcfg)
.then((aResult) => { netcfgResult = aResult; })
.then(exeAndParseIpRoute)
.then((aResult) => { ipRouteResult = aResult; })
.then(() => getSettings(SETTINGS_TETHERING_WIFI_IP))
.then(ip => verifyDefaultRouteAndIp(ip));
}
@@ -1163,6 +1285,10 @@ let gTestSuite = (function() {
throw 'window.navigator.mozWifiManager is NULL';
}
wifiOrigEnabled = wifiManager.enabled;
})
.then(() => runEmulatorShellSafe(['getprop', 'ro.build.version.sdk']))
.then(aLines => {
sdkVersion = parseInt(aLines[0]);
});
}
@@ -1182,12 +1308,19 @@ let gTestSuite = (function() {
suite.getFirstIndexBySsid = getFirstIndexBySsid;
suite.testAssociate = testAssociate;
suite.getKnownNetworks = getKnownNetworks;
suite.setStaticIpMode = setStaticIpMode;
suite.requestWifiScan = requestWifiScan;
suite.waitForConnected = waitForConnected;
suite.forgetNetwork = forgetNetwork;
suite.waitForTimeout = waitForTimeout;
suite.waitForRilDataConnected = waitForRilDataConnected;
suite.requestTetheringEnabled = requestTetheringEnabled;
suite.importCert = importCert;
suite.getImportedCerts = getImportedCerts;
suite.deleteCert = deleteCert;
suite.writeFile = writeFile;
suite.exeAndParseNetcfg = exeAndParseNetcfg;
suite.exeAndParseIpRoute = exeAndParseIpRoute;
/**
* Common test routine.
@@ -1280,7 +1413,12 @@ let gTestSuite = (function() {
return suite.doTest(function() {
return verifyInitialState()
.then(initTetheringTestEnvironment)
// Since stock hostapd is not reliable after ICS, we just
// turn off potential stock hostapd during testing to avoid
// interference.
.then(stopStockHostapd)
.then(aTestCaseChain)
.then(startStockHostapd)
.then(restoreToInitialState, function onreject(aReason) {
return restoreToInitialState()
.then(() => { throw aReason; }); // Re-throw the orignal reject reason.
@@ -1288,5 +1426,61 @@ let gTestSuite = (function() {
});
};
/**
* Run test with imported certificate.
*
* Certificate will be imported and confirmed before running test, and be
* deleted after running test.
*
* Fulfill params: (none)
*
* @param certBlob
* Certificate content as Blob.
* @param password
* Password for importing certificate, only used for importing PKCS#12.
* @param nickanem
* Nickname for imported certificate.
* @param usage
* Expected usage of imported certificate.
* @param aTestCaseChain
* The test case entry point, which can be a function or a promise.
*
* @return A deferred promise.
*/
suite.doTestWithCertificate = function(certBlob, password, nickname, usage, aTestCaseChain) {
return suite.doTestWithoutStockAp(function() {
return ensureWifiEnabled(true)
// Import test certificate.
.then(() => importCert(certBlob, password, nickname))
.then(function(info) {
// Check import result.
is(info.nickname, nickname, "Imported nickname");
for (let i = 0; i < usage.length; i++) {
isnot(info.usage.indexOf(usage[i]), -1, "Usage " + usage[i]);
}
})
// Get imported certificate list.
.then(getImportedCerts)
// Check if certificate exists in imported certificate list.
.then(function(list) {
for (let i = 0; i < usage.length; i++) {
isnot(list[usage[i]].indexOf(nickname), -1,
"Certificate \"" + nickname + "\" of usage " + usage[i] + " is imported");
}
})
// Run test case.
.then(aTestCaseChain)
// Delete imported certificates.
.then(() => deleteCert(nickname))
// Check if certificate doesn't exist in imported certificate list.
.then(getImportedCerts)
.then(function(list) {
for (let i = 0; i < usage.length; i++) {
is(list[usage[i]].indexOf(nickname), -1, "Certificate is deleted");
}
})
});
};
return suite;
})();
+10
View File
@@ -8,7 +8,17 @@ qemu = true
[test_wifi_associate.js]
[test_wifi_associate_wo_connect.js]
[test_wifi_auto_connect.js]
[test_wifi_static_ip.js]
[test_wifi_tethering_wifi_disabled.js]
[test_wifi_tethering_wifi_inactive.js]
[test_wifi_tethering_wifi_active.js]
[test_wifi_manage_server_certificate.js]
[test_wifi_manage_user_certificate.js]
[test_wifi_manage_pkcs12_certificate.js]
[test_wifi_associate_WPA_EAP_PEAP.js]
skip-if = android_version < '16' # EAP test not working before KK.
[test_wifi_associate_WPA_EAP_TTLS.js]
skip-if = android_version < '16'
[test_wifi_associate_WPA_EAP_TLS.js]
skip-if = android_version < '16'
[test_wifi_enable_api.js]
@@ -0,0 +1,623 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
const SCAN_RETRY_CNT = 5;
const EAP_USERNAME = 'username';
const EAP_PASSWORD = 'password';
const SERVER_EAP_USER_CONF = {
path: HOSTAPD_CONFIG_PATH + 'hostapd.eap_user',
content: '* PEAP,TTLS,TLS\n' +
'"' + EAP_USERNAME + '" MSCHAPV2,TTLS-MSCHAPV2 "' + EAP_PASSWORD + '" [2]\n'
};
const CA_CERT = {
path: HOSTAPD_CONFIG_PATH + 'ca.pem',
content: '-----BEGIN CERTIFICATE-----\n' +
'MIIDsTCCApmgAwIBAgIJAKxTf+8X8qngMA0GCSqGSIb3DQEBCwUAMG4xCzAJBgNV\n' +
'BAYTAlRXMRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhjaHVja2xlZTER\n' +
'MA8GA1UEAwwIY2h1Y2tsZWUxJDAiBgkqhkiG9w0BCQEWFWNodWNrbGkwNzA2QGdt\n' +
'YWlsLmNvbTAgFw0xNDEyMjQxMTI4NTBaGA8yMjg4MTAwNzExMjg1MFowbjELMAkG\n' +
'A1UEBhMCVFcxEzARBgNVBAgMClNvbWUtU3RhdGUxETAPBgNVBAoMCGNodWNrbGVl\n' +
'MREwDwYDVQQDDAhjaHVja2xlZTEkMCIGCSqGSIb3DQEJARYVY2h1Y2tsaTA3MDZA\n' +
'Z21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo3c2yFxY\n' +
'o6gGg0I83jy00ME+MAfzCd+4ShL45ZLqysQP93jRBfPzU9ZuZ29ysVwgWIdqkZao\n' +
'XTuV/NAW2GMGd8W1jQJ3J81fjb9wvhlny3rrACwvUn1N1S1BnM+BAAiDLGxEmvAQ\n' +
'onp2aaa6HsHsYS8ONX+d2Qh4LEA4vupeSGAqJychCZv/l+aq/ErFZhFYB3CPUQEt\n' +
'cClO24ucsIYP95lA0zhscnmAj06qplFD4Bv6IVrdDqujy1zNwCQwsJq/8OQdaTN/\n' +
'h3y9pWvNKMBMM2niOUAjtuNpqsSK/lTS1WAT3PdtVECX9fYBi0Bg+HM92xs/6gt6\n' +
'kh9jPV8keXHvSwIDAQABo1AwTjAdBgNVHQ4EFgQU7hBqhuG04xeCzrQ3ngx18ZJ3\n' +
'lUswHwYDVR0jBBgwFoAU7hBqhuG04xeCzrQ3ngx18ZJ3lUswDAYDVR0TBAUwAwEB\n' +
'/zANBgkqhkiG9w0BAQsFAAOCAQEAFYX2iy680GAnBTttk0gyX6gk+8pYr3D22k/G\n' +
'6rvcjefzS7ELQPRKr6mfmwXq3mMf/4jiS2zI5zmXsestPYzHYxf2viQ6t7vr9XiJ\n' +
'3WfFjNw4ERlRisAvg0aqqTNNQq5v2VME4sdFZagy217f73C7azwCHl0bqOLH05rl\n' +
'8RubOxiHEj7ZybJqnRciK/bht4D+rZkwf4bBBmoloqH7xT0+rFQclpYXDGGjNUQB\n' +
'LcHLF10xcr7g3ZVVu82fe6+d85gIGOIMR9+TKhdw6gO3CNcnDAj6gxksghgtcxmh\n' +
'OzOggCn7nlIwImtsg2sZkpWB4lEi9hdv4lkNuyFjOL3bnuc+NA==\n' +
'-----END CERTIFICATE-----\n'
};
const SERVER_CERT = {
path: HOSTAPD_CONFIG_PATH + 'server.pem',
content: '-----BEGIN CERTIFICATE-----\n' +
'MIID1DCCArygAwIBAgIBADANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJUVzET\n' +
'MBEGA1UECAwKU29tZS1TdGF0ZTERMA8GA1UECgwIY2h1Y2tsZWUxETAPBgNVBAMM\n' +
'CGNodWNrbGVlMSQwIgYJKoZIhvcNAQkBFhVjaHVja2xpMDcwNkBnbWFpbC5jb20w\n' +
'IBcNMTQxMjI0MTEyOTQ5WhgPMjI4ODEwMDcxMTI5NDlaMG4xCzAJBgNVBAYTAlRX\n' +
'MRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhjaHVja2xlZTERMA8GA1UE\n' +
'AwwIY2h1Y2tsZWUxJDAiBgkqhkiG9w0BCQEWFWNodWNrbGkwNzA2QGdtYWlsLmNv\n' +
'bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMdhQmKilTJbWZRxTiSV\n' +
'rqIU+LYW1RKghx5o+0JpNRJVLuz5kBMaNskbbfUSNuHbEq0QA9BDKAZWIc4LSotk\n' +
'lCo8TbcO9CJvJPQGGjGdHcohWX5vy6BE/OVE46CUteMFyZF6F8R2fNUww08iR/u1\n' +
'YZebL5pWO1j43sPpAzEy6Tij2ACPt6EZcFaZG3SF2mVJWkCQnBqrojP65WUvZQqp\n' +
'seUhW2YAS8Nu0Yrohgxz6VYk+cNDuDZVGs6qWRStZzJfYrfc76DtkHof5B14M+xp\n' +
'XJaBLxN+whvnYkDTfinaCxnW1O7eXUltr87fLc5zmeBkgwaiaQuIdcfZm7vDUiz8\n' +
'vnUCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH\n' +
'ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFKK4f9/YavTHOfEiAB83Deac\n' +
'6gT5MB8GA1UdIwQYMBaAFO4QaobhtOMXgs60N54MdfGSd5VLMA0GCSqGSIb3DQEB\n' +
'CwUAA4IBAQBWnO9o9KSJIqjoz5Nwll63ULOdcvgGdOeJIw1fcKQ817Rsp+TVcjcH\n' +
'IrIADsT/QZGXRO/l6p1750e2iFtJEo1hsRaxtA1wWn2I9HO3+av2spQhr3jpYGPf\n' +
'zpsMTp4RNYV7Q8+q1kZIz9PY4V1T0p6lveK8+fUj2hSLnxSj0QiGSJJtnEC3w4Rv\n' +
'C9T6oUwIeToULmi+8FXQFdEqwKRU98DPq3eLzN28ZxUgoPE1C8+42D2UW8uyp/Gm\n' +
'tGOa/k7nzkCdVqZI7lX7f0AjEvQgjtAMQ/k7Mhxx7TzW2HO+1YPMoKji6Z4WkNwt\n' +
'JEj9ZUBSNt8B26UksJMBDkcvSegF3a7o\n' +
'-----END CERTIFICATE-----\n'
};
const SERVER_KEY = {
path: HOSTAPD_CONFIG_PATH + 'server.key',
content: '-----BEGIN RSA PRIVATE KEY-----\n' +
'MIIEpAIBAAKCAQEAx2FCYqKVMltZlHFOJJWuohT4thbVEqCHHmj7Qmk1ElUu7PmQ\n' +
'Exo2yRtt9RI24dsSrRAD0EMoBlYhzgtKi2SUKjxNtw70Im8k9AYaMZ0dyiFZfm/L\n' +
'oET85UTjoJS14wXJkXoXxHZ81TDDTyJH+7Vhl5svmlY7WPjew+kDMTLpOKPYAI+3\n' +
'oRlwVpkbdIXaZUlaQJCcGquiM/rlZS9lCqmx5SFbZgBLw27RiuiGDHPpViT5w0O4\n' +
'NlUazqpZFK1nMl9it9zvoO2Qeh/kHXgz7GlcloEvE37CG+diQNN+KdoLGdbU7t5d\n' +
'SW2vzt8tznOZ4GSDBqJpC4h1x9mbu8NSLPy+dQIDAQABAoIBAASG4Mr8hgaurEoC\n' +
'iJOsElr7vunjetMBcg/uskW/vcS8ymP3Bp5oafYG+WgnEbfvEW18f5mq7K24JuxW\n' +
'tUqU7ghHdjxByqk9fMlNmiqmNpbwSufkAeuRpWxPNBvhRH/zEbCL5R5A0nTEtqqF\n' +
'TL0aUSzwCRSoAJD0lZo9ICVt0n3GsDyM9rqQg/uZmh1qsRdwPsRuYORND9g48rKq\n' +
'6WN9leskSxhhsYE2D9ocOFd9bNt8Zxejh9ppVSnG/KsIdt18iBzcabatgAQ046fb\n' +
'Z3vprcZJLg93Sg2gSuVqlSTs3M2W8VQnm22/EBMb1y0M48MSRCgnbPLG/CcCLLfF\n' +
'LwxCOgECgYEA/eYt67xyJ6JeAdxdwOZuT1WWGbFpLiG9+2OgiHumyRQ5969XMTWo\n' +
'fIhMKchDdjoy9RR236\/\/EFCs7UEyB7+a7ODRzNiK2zCD8Smjp+21fUPSthEeQesk\n' +
'eiMYICIu5Ay35x9sxIX+XOUVvRhPOGcD29GVeRnKh1inTHOz2dje8LkCgYEAyQeY\n' +
'STi9jjCEcHkM1E/UeDiLfHHepLXi8wS41JNRHl5Jacp7XB5djAjKu/jf367/VpFy\n' +
'GDDMetE7n8eWkrnAvovxOwZ000YDMtL1sUYSjL+XtBS5s6VY1p4qaSAY9nUUGrJh\n' +
'JvtvsuI7SKTtL+60vjBOH7zDnvOdBgAp0utLhZ0CgYEAuLzzqrPKB8afShFSchn4\n' +
'J2dpuLYahsNsXW7HDqeR2nsKFosRETAusLXnXPtnAq4kB6jlOarwFqnsuRCX24Vx\n' +
'r2uBm9/vYL7zMdUPTA+s30ErHuhjsKjsOKYyVqcooSwT32pBFNk+E89nutfmRG7I\n' +
'IvhjHuNCNqqtx/Xj5d1jkZkCgYBQicppC2Jl5OoqZVTOem0U/RJk+PnJ41TZJ7sk\n' +
'7yBAmmWvDH\/\/l+rCf4M5a6vFYcbKV9rt9h711X2dtciNX/3oWQh8LUoAmrwNUJc+\n' +
'PmSQHvIYI3WCk2vUD+nN1B4sHxu+1lg11eYaNKiroeeknG2tBI1ICcgVlmQCU25u\n' +
'IfZPwQKBgQCdO6QHhPLtcHUDNFA6FQ1jKL1iEd7G0JLVRz4Xkpkn1Vrr5MD6JFDa\n' +
'5ccabADyl0lpFqDIVJQIzLku2hOD2i9aBNCY0pL391HeOS7CkZX+TdOY1tquoBq5\n' +
'MnmixZjDCVd2VcrVyTA6ntOBoharKFW0rH1PqU+qu7dZF7CBPbAdEw==\n' +
'-----END RSA PRIVATE KEY-----\n'
};
const WPA_EAP_AP_LIST = [
{
ssid: 'WPA-EAP-PEAP',
ieee8021x: 1,
eapol_version: 1,
eap_server: 1,
eapol_key_index_workaround: 0,
eap_user_file: SERVER_EAP_USER_CONF.path,
ca_cert: CA_CERT.path,
server_cert: SERVER_CERT.path,
private_key: SERVER_KEY.path,
wpa: 3,
wpa_key_mgmt: 'WPA-EAP'
}
];
const CLIENT_PKCS12_CERT = {
nickname: 'client',
password: 'password',
usage: ['UserCert', 'ServerCert'],
content: [0x30, 0x82, 0x0E, 0x01, 0x02, 0x01, 0x03, 0x30,
0x82, 0x0D, 0xC7, 0x06, 0x09, 0x2A, 0x86, 0x48,
0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82,
0x0D, 0xB8, 0x04, 0x82, 0x0D, 0xB4, 0x30, 0x82,
0x0D, 0xB0, 0x30, 0x82, 0x08, 0x67, 0x06, 0x09,
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07,
0x06, 0xA0, 0x82, 0x08, 0x58, 0x30, 0x82, 0x08,
0x54, 0x02, 0x01, 0x00, 0x30, 0x82, 0x08, 0x4D,
0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
0x01, 0x07, 0x01, 0x30, 0x1C, 0x06, 0x0A, 0x2A,
0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01,
0x06, 0x30, 0x0E, 0x04, 0x08, 0x67, 0x7A, 0xF3,
0x61, 0xBE, 0xE0, 0x51, 0xC1, 0x02, 0x02, 0x08,
0x00, 0x80, 0x82, 0x08, 0x20, 0xFC, 0x6A, 0x79,
0xA1, 0x6C, 0xAF, 0xBE, 0xEE, 0x62, 0x45, 0x33,
0xB8, 0x48, 0xE1, 0x68, 0xA1, 0x15, 0x11, 0x4B,
0x95, 0xCB, 0x77, 0xC0, 0x5D, 0xA2, 0xCB, 0xDB,
0xD1, 0x83, 0x74, 0x60, 0xD7, 0xEC, 0x42, 0xA6,
0x3A, 0x23, 0xF7, 0x85, 0xEB, 0xC1, 0xFE, 0x6A,
0x57, 0x8E, 0xC1, 0x44, 0xF3, 0x1F, 0xFE, 0xB8,
0x2D, 0x8C, 0x4D, 0xC9, 0x5B, 0xAE, 0x21, 0x2E,
0x4C, 0x1A, 0xEB, 0x84, 0x09, 0xF3, 0x40, 0x92,
0x39, 0x7F, 0x56, 0x02, 0x46, 0x61, 0x16, 0xDE,
0x5C, 0x48, 0xB6, 0x0C, 0x1D, 0xD3, 0x5F, 0x10,
0x9A, 0x39, 0xB8, 0x66, 0x31, 0xFC, 0x39, 0x71,
0x87, 0x23, 0x46, 0x9D, 0xE8, 0x3C, 0x2B, 0xA1,
0x39, 0x8A, 0xD3, 0xFF, 0xD9, 0x43, 0xB6, 0x61,
0xC6, 0x67, 0x70, 0x40, 0xBD, 0xFE, 0xD3, 0xC1,
0x68, 0xF5, 0xF7, 0xC8, 0x89, 0xD8, 0x17, 0xC5,
0xE8, 0x3D, 0x29, 0xD5, 0x91, 0xDF, 0x1F, 0x56,
0x74, 0x5A, 0xC4, 0xA8, 0x14, 0xBA, 0xD4, 0xFA,
0x13, 0x49, 0x2A, 0x9F, 0x63, 0xF1, 0xB2, 0x45,
0xF1, 0xF0, 0x2A, 0xDD, 0x75, 0x66, 0x8A, 0xF7,
0xAB, 0x73, 0x86, 0x26, 0x9D, 0x1F, 0x07, 0xAD,
0xD3, 0xFE, 0xE0, 0xA3, 0xED, 0xA0, 0x96, 0x3E,
0x1E, 0x89, 0x86, 0x02, 0x4C, 0x28, 0xFD, 0x57,
0xA1, 0x67, 0x55, 0xF0, 0x82, 0x3B, 0x7F, 0xCC,
0x2A, 0x32, 0x01, 0x93, 0x1D, 0x8B, 0x66, 0x8A,
0x20, 0x52, 0x84, 0xDD, 0x2C, 0xFD, 0xEE, 0x72,
0xF3, 0x8C, 0x58, 0xB9, 0x99, 0xE5, 0xC1, 0x22,
0x63, 0x59, 0x00, 0xE2, 0x76, 0xC5, 0x3A, 0x17,
0x7F, 0x93, 0xE9, 0x67, 0x61, 0xAA, 0x10, 0xC3,
0xD9, 0xC8, 0x24, 0x46, 0x5B, 0xBE, 0x8C, 0x1F,
0x2D, 0x66, 0x48, 0xD2, 0x02, 0x11, 0xFB, 0x74,
0x14, 0x76, 0x76, 0x5A, 0x98, 0x54, 0x35, 0xA7,
0x85, 0x66, 0x20, 0x26, 0x8B, 0x13, 0x6F, 0x68,
0xE3, 0xC9, 0x58, 0x7D, 0x1C, 0x3E, 0x01, 0x8D,
0xF8, 0xD6, 0x7F, 0xCF, 0xA2, 0x07, 0xB7, 0x95,
0xFD, 0xF0, 0x02, 0x34, 0x32, 0x30, 0xE8, 0xD4,
0x57, 0x5E, 0x53, 0xFB, 0x54, 0xE2, 0x03, 0x32,
0xCC, 0x52, 0x2E, 0xD2, 0x35, 0xD9, 0x58, 0x85,
0x2D, 0xEC, 0x2D, 0x71, 0xD1, 0x8A, 0x29, 0xD0,
0xB0, 0x24, 0xBD, 0x24, 0xDC, 0x1A, 0x28, 0x3F,
0xA0, 0x12, 0x81, 0x15, 0x24, 0xC9, 0xB5, 0x4A,
0x23, 0xB6, 0xA3, 0x45, 0x50, 0x2D, 0x73, 0x99,
0x6B, 0x1C, 0xFB, 0xA4, 0x53, 0xD7, 0x5C, 0xF4,
0x6C, 0xB0, 0xE5, 0x74, 0xB3, 0x76, 0xF8, 0xB1,
0x0D, 0x59, 0x70, 0x9F, 0xCA, 0xDE, 0xF2, 0xAA,
0x4C, 0x7D, 0x11, 0x54, 0xC4, 0x19, 0x0F, 0x36,
0x4A, 0x62, 0xFF, 0x8B, 0x10, 0xCB, 0x93, 0x50,
0xDA, 0x79, 0x5E, 0x4E, 0x09, 0x1F, 0x22, 0xC8,
0x19, 0x85, 0xE9, 0xEE, 0xB7, 0x71, 0x65, 0xB9,
0x10, 0xD2, 0x0A, 0x73, 0x5B, 0xA6, 0xDA, 0x37,
0x46, 0x02, 0x00, 0x98, 0x9E, 0x20, 0x6C, 0x7D,
0xC7, 0x69, 0xBB, 0xC2, 0x00, 0x40, 0x9C, 0x57,
0x00, 0xC2, 0x36, 0x76, 0xE8, 0x2A, 0x8D, 0xAD,
0x62, 0x57, 0xC8, 0xD0, 0x9D, 0x66, 0x27, 0x5A,
0xD8, 0x0D, 0x35, 0x60, 0x28, 0x38, 0x62, 0x94,
0x78, 0x36, 0x25, 0x58, 0xFD, 0xF8, 0x66, 0x1F,
0x68, 0x04, 0x0F, 0xD8, 0x00, 0xDF, 0xA0, 0x6C,
0x25, 0x42, 0x9A, 0x4C, 0xEB, 0x80, 0x13, 0x51,
0x7D, 0x2D, 0xA8, 0x89, 0xD6, 0x1B, 0x67, 0x72,
0x01, 0xF3, 0x2D, 0x16, 0x77, 0xFE, 0x22, 0xBC,
0x8A, 0x45, 0x09, 0x1F, 0x9C, 0x2F, 0x2A, 0xA9,
0x61, 0x5B, 0x4A, 0xE6, 0x64, 0x2C, 0x62, 0x1A,
0x3A, 0x96, 0xE6, 0x0A, 0xAE, 0x05, 0x1A, 0xC8,
0xCB, 0xD6, 0x8F, 0x3A, 0x4B, 0xE0, 0x7F, 0x82,
0xB4, 0x98, 0xF1, 0x9D, 0xD7, 0x14, 0x76, 0x5E,
0x77, 0x85, 0x87, 0xEC, 0x13, 0xDA, 0xFD, 0xAF,
0xCB, 0xA3, 0x1C, 0x99, 0xC1, 0xFE, 0x17, 0x0C,
0x40, 0x4D, 0x3C, 0x8F, 0x70, 0x86, 0x63, 0x64,
0xB7, 0x75, 0xA8, 0x71, 0x36, 0xDC, 0x54, 0x10,
0x57, 0x0C, 0xA8, 0xF2, 0xA1, 0xBB, 0xED, 0x03,
0x41, 0x57, 0x34, 0x2C, 0x8F, 0x7C, 0xA0, 0x09,
0xF3, 0x9E, 0x41, 0xB7, 0xA8, 0xD4, 0x66, 0x0D,
0x0D, 0xC0, 0x6A, 0xFC, 0x6A, 0xA2, 0xAC, 0xE2,
0x60, 0x00, 0xE3, 0xF7, 0x75, 0x43, 0x23, 0xEB,
0xC8, 0x61, 0xFA, 0xB3, 0xB8, 0x28, 0xCE, 0xCA,
0xF4, 0x47, 0x7F, 0x30, 0x6D, 0x61, 0x89, 0x47,
0xA1, 0x4A, 0xFE, 0xD1, 0x21, 0x0B, 0x6D, 0xF4,
0x3F, 0x00, 0x86, 0x30, 0x8E, 0x33, 0x21, 0x6F,
0xDA, 0x15, 0xFD, 0x5F, 0xEC, 0x8E, 0xF1, 0x12,
0x3F, 0xC9, 0x83, 0x0C, 0xCA, 0x22, 0x01, 0xF1,
0x70, 0x5F, 0x1F, 0x66, 0xB5, 0xF8, 0x3E, 0x7A,
0x6F, 0xDE, 0xDB, 0xA7, 0x8D, 0x18, 0x9E, 0xBE,
0xDB, 0xAD, 0x3D, 0x66, 0x30, 0xC1, 0x6C, 0x0C,
0x87, 0xB4, 0x65, 0x75, 0xE0, 0x9D, 0xEA, 0x16,
0x0D, 0x07, 0x37, 0x33, 0xC5, 0xEC, 0x97, 0x93,
0x37, 0xEB, 0x8E, 0x65, 0x9C, 0x40, 0x63, 0x6C,
0x43, 0x60, 0xB0, 0x40, 0x4D, 0x85, 0xEF, 0xC2,
0x47, 0x5F, 0xE7, 0x6B, 0xCB, 0x40, 0xE8, 0xEA,
0xD8, 0xAB, 0xB1, 0x9A, 0x72, 0xDC, 0x4C, 0x14,
0xFA, 0x43, 0x61, 0x5F, 0xA6, 0x5C, 0x3A, 0x05,
0x17, 0x2E, 0x74, 0xF3, 0x5E, 0x45, 0xD9, 0x47,
0xAA, 0x59, 0xB6, 0x8F, 0x42, 0x66, 0x42, 0x29,
0x90, 0x95, 0x48, 0x46, 0x91, 0x88, 0x3C, 0x8C,
0xDE, 0xCC, 0xED, 0xB3, 0xAA, 0x62, 0xEA, 0xBC,
0xB4, 0x0C, 0x48, 0x4C, 0x53, 0x23, 0x5E, 0x24,
0x85, 0xBF, 0x92, 0xDA, 0x14, 0xDB, 0x1A, 0x3D,
0xEF, 0x30, 0xD9, 0x49, 0x64, 0x4D, 0xE5, 0x01,
0xFC, 0xA4, 0x4B, 0xD1, 0x9F, 0xDE, 0x96, 0x7F,
0x50, 0xBC, 0x4D, 0x38, 0x44, 0xE9, 0x23, 0x5F,
0x37, 0x57, 0x1A, 0xA6, 0x52, 0x5A, 0x0F, 0x4F,
0x87, 0x33, 0x4A, 0x7B, 0x66, 0xEE, 0x3D, 0x66,
0x0A, 0x63, 0x39, 0x1F, 0x23, 0x38, 0x35, 0x73,
0x60, 0x5E, 0x47, 0x20, 0x4F, 0xC0, 0xC8, 0x3C,
0x09, 0xF9, 0x29, 0x4F, 0x5E, 0x55, 0x69, 0xC4,
0x6B, 0xE8, 0xF8, 0x91, 0xC0, 0x22, 0x65, 0x15,
0x1E, 0xFB, 0xB9, 0x61, 0xCE, 0x45, 0xBE, 0x2B,
0xEE, 0xB9, 0x04, 0x2B, 0xFD, 0xAE, 0x61, 0x1C,
0x3D, 0x3D, 0x7C, 0xBF, 0xC1, 0xF7, 0x3C, 0x4E,
0x9E, 0x0E, 0x54, 0xC8, 0xAD, 0xA9, 0xDF, 0x43,
0x49, 0xB9, 0x41, 0x05, 0xE5, 0xF1, 0x49, 0xAA,
0x77, 0x6C, 0x34, 0x5B, 0x93, 0x24, 0x24, 0x23,
0x74, 0x68, 0x11, 0xCE, 0x15, 0x80, 0xA1, 0xA4,
0x1F, 0x8D, 0x81, 0xCD, 0xB2, 0x98, 0xCA, 0x14,
0x0B, 0x0C, 0x61, 0x50, 0x69, 0x72, 0xAE, 0xFA,
0x8B, 0xC0, 0x3F, 0x0D, 0xE7, 0xF2, 0x0F, 0xEB,
0xC1, 0x11, 0xB9, 0x10, 0x03, 0x6A, 0xF5, 0x97,
0x3C, 0x53, 0x2F, 0x67, 0x86, 0x09, 0x6A, 0xE3,
0x28, 0xC0, 0x78, 0xC8, 0xB4, 0x39, 0x8E, 0xD1,
0xCE, 0x25, 0xE8, 0x66, 0xF7, 0x09, 0x40, 0x7D,
0x81, 0xFB, 0xAF, 0xFA, 0x59, 0xC4, 0x9B, 0x2B,
0x83, 0x45, 0x5B, 0xA8, 0x66, 0x9E, 0x38, 0xC8,
0xFD, 0xAC, 0xF2, 0x2D, 0x21, 0xDE, 0x50, 0x4C,
0x03, 0xCB, 0x88, 0x42, 0xDD, 0x84, 0x09, 0x99,
0x8E, 0x8B, 0x40, 0x97, 0x1B, 0x14, 0x85, 0x37,
0x11, 0x01, 0xE0, 0x74, 0x6B, 0x33, 0x52, 0x8C,
0x68, 0x3A, 0x89, 0xB2, 0xAF, 0x35, 0xE6, 0x65,
0xC3, 0x58, 0x70, 0xD2, 0xE7, 0x1F, 0x1F, 0xF6,
0xE5, 0x0A, 0xB1, 0xFE, 0xD0, 0xC9, 0x51, 0x50,
0xE7, 0xFD, 0x58, 0xF5, 0xC4, 0x58, 0x65, 0x94,
0xD1, 0x57, 0x55, 0x5E, 0xD2, 0x27, 0x98, 0xAF,
0xE7, 0x55, 0x0B, 0x87, 0x50, 0x9B, 0xEF, 0xE8,
0x2B, 0xFC, 0xE7, 0x3B, 0x4E, 0xD7, 0xB7, 0x4D,
0xF4, 0xBC, 0xF4, 0x88, 0x63, 0xE4, 0x8A, 0x20,
0x4B, 0x22, 0xB0, 0xA0, 0x53, 0x7F, 0xA8, 0xC9,
0x0C, 0xF8, 0xD7, 0xBD, 0x46, 0x39, 0xA7, 0x7D,
0xDD, 0x10, 0x91, 0x50, 0x54, 0x06, 0x47, 0xF0,
0x3C, 0xAA, 0x43, 0x40, 0xF8, 0x54, 0xDD, 0x8A,
0xEA, 0x8A, 0x0B, 0xA5, 0x7F, 0xCD, 0x5E, 0xAA,
0x02, 0x2E, 0x1F, 0xC6, 0x50, 0x15, 0xF8, 0x0A,
0x0C, 0x1B, 0x3C, 0x55, 0x3A, 0xC3, 0x6F, 0x88,
0xD7, 0xBF, 0xB1, 0x02, 0xCC, 0xE0, 0x08, 0x29,
0x97, 0xD2, 0xAA, 0x23, 0xC4, 0x6D, 0xE3, 0xE3,
0x76, 0x39, 0x92, 0xC3, 0x2E, 0x7A, 0xE2, 0x98,
0xD1, 0xFC, 0xAE, 0xCC, 0x95, 0xD8, 0xB4, 0xDC,
0x92, 0xEA, 0x6A, 0x5F, 0xF2, 0x92, 0x17, 0x0B,
0x8D, 0xC3, 0xFA, 0x9C, 0x62, 0xCE, 0x44, 0x8D,
0xC3, 0x1E, 0xC3, 0xB2, 0xD5, 0x00, 0xCD, 0xB4,
0x9E, 0x2D, 0x7B, 0xF2, 0x98, 0xA3, 0x00, 0x8B,
0x81, 0x30, 0x77, 0x5B, 0x02, 0x99, 0xB1, 0xCD,
0xC3, 0x1D, 0x74, 0x74, 0xEF, 0x41, 0xCB, 0x69,
0x63, 0x8E, 0xA6, 0xD3, 0x2D, 0x3E, 0x1F, 0x1D,
0x12, 0x9E, 0xD9, 0x18, 0x67, 0x06, 0xAF, 0x37,
0x29, 0xAD, 0x65, 0xD8, 0xEB, 0x71, 0xC4, 0x7D,
0x94, 0x3D, 0xEA, 0xCC, 0xDF, 0x72, 0x41, 0x51,
0x3C, 0xA1, 0x66, 0x98, 0x32, 0x32, 0x40, 0x54,
0xB0, 0x2F, 0xEB, 0xCE, 0xDF, 0x4A, 0x64, 0xFB,
0x9A, 0x90, 0xDC, 0xF6, 0x6F, 0xA9, 0xD4, 0xCA,
0xCB, 0x91, 0xC4, 0xFE, 0xEE, 0x9C, 0x01, 0x50,
0x2E, 0xAC, 0xCC, 0x5F, 0x89, 0xD0, 0x91, 0xA3,
0xD9, 0xF9, 0x4B, 0x8D, 0xDE, 0x6C, 0x60, 0x21,
0x19, 0xB1, 0xD3, 0x4D, 0x75, 0x56, 0x6F, 0xB8,
0x25, 0xA4, 0x92, 0x4F, 0x12, 0xF5, 0x8F, 0xC1,
0x17, 0x4B, 0xB3, 0x34, 0x21, 0x22, 0xAC, 0x52,
0xD2, 0x64, 0xC9, 0x9A, 0x7D, 0xFC, 0xC0, 0x0A,
0x89, 0x34, 0xFF, 0x08, 0xD3, 0x04, 0xDC, 0xFE,
0x7C, 0xB3, 0xB8, 0xFD, 0x85, 0xDD, 0x79, 0x51,
0xA7, 0x89, 0xE8, 0xF1, 0x23, 0xB1, 0xDF, 0xD7,
0x1F, 0x7B, 0xB1, 0x5D, 0x42, 0xF9, 0x61, 0xF8,
0xDC, 0x81, 0x04, 0xF1, 0xCC, 0xFA, 0xD7, 0xED,
0xBF, 0x47, 0xAC, 0xBD, 0xE5, 0xFA, 0xAC, 0xB3,
0x1C, 0xD9, 0xA1, 0xB3, 0x60, 0xEE, 0x9C, 0x8A,
0x36, 0x57, 0xB4, 0x2F, 0xA1, 0xA2, 0xF3, 0xE2,
0x09, 0x9A, 0x6E, 0x43, 0x9B, 0xE5, 0x93, 0xB8,
0x3D, 0x9E, 0x9F, 0xC1, 0xC6, 0x0D, 0x02, 0xEB,
0x4D, 0x38, 0xE9, 0xB4, 0x9F, 0xEA, 0x33, 0x8C,
0x07, 0xD8, 0xB4, 0x71, 0xAD, 0xE5, 0x43, 0xB2,
0xCC, 0x55, 0x93, 0x6A, 0xDB, 0x1E, 0x80, 0xDB,
0xC2, 0xEA, 0x42, 0x8E, 0xFC, 0x86, 0x44, 0xC9,
0x8A, 0xC4, 0xF2, 0x46, 0xA7, 0x39, 0x50, 0x0D,
0x1A, 0xAA, 0x07, 0x04, 0xBE, 0xD4, 0xCE, 0x62,
0x4D, 0x0F, 0x91, 0x7D, 0x29, 0x88, 0x9C, 0x4C,
0xAF, 0xF7, 0xD8, 0x40, 0x93, 0x88, 0xC7, 0x20,
0xD2, 0x17, 0x2A, 0xC4, 0x92, 0x72, 0xD0, 0xC0,
0x4E, 0x56, 0x47, 0xB1, 0x27, 0x02, 0xE6, 0x61,
0x82, 0x5E, 0xC8, 0x2E, 0x90, 0xD2, 0x31, 0x22,
0xE2, 0xA9, 0x4A, 0x91, 0x45, 0x69, 0xB1, 0xA5,
0x0F, 0x66, 0x2C, 0x30, 0xAD, 0x7F, 0x1B, 0x0E,
0x22, 0x17, 0x60, 0x2E, 0x3D, 0x7F, 0x7F, 0x8C,
0x33, 0x51, 0xA0, 0x25, 0xDE, 0xFD, 0x75, 0xBC,
0xEF, 0xE6, 0xE7, 0x20, 0x04, 0x5A, 0xEC, 0x50,
0x21, 0x48, 0x56, 0x98, 0xE2, 0x33, 0x6D, 0x22,
0x5C, 0xC3, 0xFB, 0xFC, 0x6F, 0xB3, 0xA7, 0x8E,
0x6F, 0x67, 0x70, 0x9D, 0xDA, 0x02, 0x01, 0x59,
0x7B, 0x3D, 0x2B, 0x38, 0xCC, 0x0F, 0x44, 0x3D,
0xFB, 0x9A, 0xB3, 0x23, 0x15, 0x50, 0x6E, 0xBF,
0x8B, 0xA1, 0x94, 0x33, 0xE5, 0x7B, 0x88, 0x4E,
0xCB, 0x6D, 0x9F, 0xBF, 0xBC, 0x7A, 0xA8, 0x1E,
0x68, 0x25, 0xED, 0x8E, 0x53, 0x21, 0x72, 0xC5,
0x70, 0xB3, 0xE4, 0xA6, 0xA1, 0x5A, 0x2D, 0xC8,
0x43, 0x9D, 0x60, 0x77, 0x78, 0xE0, 0xC4, 0xAF,
0xC8, 0x29, 0xBA, 0xD0, 0x4D, 0x39, 0x83, 0x51,
0xA7, 0x10, 0x7F, 0x0C, 0x34, 0x0E, 0x6C, 0x75,
0x26, 0xD7, 0xD6, 0xC7, 0x32, 0x53, 0xAF, 0x4E,
0xBE, 0xF2, 0xC2, 0x0F, 0x99, 0x23, 0xB9, 0xE1,
0xC8, 0xB4, 0xBC, 0x5A, 0xC6, 0xCB, 0xEB, 0x4D,
0x28, 0x56, 0x72, 0xFE, 0x1B, 0x2C, 0x5D, 0xE3,
0xBC, 0xC7, 0xA3, 0xC0, 0x7D, 0x27, 0xF0, 0xD0,
0x4F, 0x3F, 0x1F, 0xF7, 0x87, 0x15, 0xF2, 0xEA,
0xD4, 0x03, 0x6D, 0x2F, 0xD4, 0x8E, 0x50, 0x4B,
0x05, 0xBF, 0xF7, 0x8C, 0x67, 0x5A, 0xDC, 0x4D,
0xCD, 0xCF, 0x9D, 0x02, 0xB6, 0xE7, 0xAE, 0x49,
0xD1, 0x7C, 0x00, 0xE7, 0x3B, 0xEA, 0xFB, 0x0D,
0x2A, 0x7B, 0x41, 0x33, 0x66, 0xD0, 0x29, 0x9F,
0xB3, 0x8A, 0x71, 0xB0, 0xE2, 0x76, 0xA9, 0xDB,
0xFD, 0x64, 0x04, 0x69, 0xDF, 0x89, 0x1F, 0x56,
0x86, 0x92, 0xD9, 0xD9, 0xB9, 0xF3, 0x4F, 0xAC,
0xAE, 0x61, 0x48, 0x20, 0xCE, 0x3C, 0x2B, 0x44,
0xAB, 0x42, 0xFA, 0xAB, 0x2E, 0x94, 0x82, 0xC8,
0xD9, 0x97, 0xCF, 0x27, 0xDF, 0xAC, 0xAC, 0xE7,
0xCA, 0xB2, 0x84, 0xAB, 0xF2, 0x5D, 0xDF, 0x56,
0x0C, 0x8C, 0x07, 0x3C, 0x3D, 0xA8, 0xDD, 0xBE,
0xFF, 0x4E, 0x28, 0x0D, 0xB2, 0x2D, 0xE6, 0x9D,
0x44, 0x21, 0xCB, 0xE7, 0x33, 0x63, 0x22, 0x8F,
0x4C, 0xFF, 0xB6, 0x1D, 0x9A, 0x71, 0x3F, 0xB1,
0x29, 0xAE, 0x3A, 0x35, 0xEE, 0x9C, 0x97, 0x68,
0xA7, 0x52, 0x66, 0x01, 0xD8, 0x9A, 0x5D, 0xF4,
0xB3, 0x2F, 0x5C, 0xD4, 0x0E, 0xF9, 0xCF, 0x07,
0xF6, 0x8C, 0xBA, 0xA6, 0x8D, 0x6B, 0xC6, 0x01,
0xC2, 0x69, 0xAE, 0x60, 0x08, 0x1A, 0x0E, 0x3F,
0xAE, 0x60, 0x29, 0xF3, 0x48, 0x0D, 0xE0, 0xD0,
0xAE, 0x52, 0x44, 0xE9, 0x7F, 0x1F, 0x92, 0x5F,
0x71, 0xAD, 0xEC, 0x6B, 0x47, 0x66, 0x92, 0x22,
0x27, 0xAE, 0x6E, 0x25, 0xCD, 0xF3, 0x5F, 0x55,
0x59, 0xBD, 0x73, 0xCE, 0x2B, 0x7E, 0x99, 0x44,
0x56, 0x70, 0xA3, 0xE7, 0x7A, 0x59, 0x75, 0xD8,
0x48, 0x0C, 0x39, 0x2B, 0xD7, 0x53, 0xC6, 0xAD,
0x4A, 0x6F, 0xB4, 0x14, 0x96, 0xDF, 0xF2, 0x4A,
0x0C, 0xA2, 0xD5, 0x29, 0x98, 0x7C, 0x42, 0x87,
0xD9, 0x1F, 0x97, 0x61, 0xD9, 0xBF, 0x99, 0x4F,
0x2C, 0x4C, 0x75, 0xAC, 0xB8, 0x06, 0x75, 0xD6,
0x87, 0x76, 0x7E, 0xE3, 0x23, 0x4B, 0xEA, 0x1A,
0x1A, 0xF4, 0xB7, 0x09, 0xAF, 0x53, 0xEB, 0xA6,
0x39, 0x10, 0xFE, 0xD4, 0xEB, 0x1B, 0xAE, 0x38,
0x31, 0x33, 0xBA, 0x68, 0xEE, 0xC7, 0x65, 0x76,
0xFB, 0x49, 0x77, 0xD4, 0x19, 0xC4, 0xE6, 0xA7,
0x05, 0xFE, 0x2A, 0xDA, 0x39, 0x99, 0x1A, 0x92,
0xD2, 0xF0, 0x61, 0x97, 0xF6, 0x06, 0x6C, 0x88,
0x7B, 0x6F, 0x60, 0xE6, 0x70, 0x08, 0xF0, 0xB4,
0x6B, 0x39, 0x6F, 0x05, 0x41, 0x81, 0xF9, 0xBE,
0x7A, 0x51, 0xC4, 0x75, 0xB0, 0x6A, 0x89, 0xA0,
0xA6, 0x9A, 0x5B, 0xEE, 0x7D, 0x78, 0x17, 0x5F,
0x9F, 0x3B, 0x7D, 0xDD, 0x8A, 0x9E, 0xAA, 0x1A,
0xDA, 0x49, 0x08, 0xE9, 0xFD, 0x91, 0xA6, 0xFA,
0xCE, 0xCF, 0x67, 0xDF, 0x0F, 0xC9, 0xD6, 0x38,
0xD9, 0xD5, 0xD1, 0xC0, 0x76, 0x59, 0x42, 0x53,
0xBF, 0x48, 0xE9, 0x11, 0x74, 0xC7, 0x11, 0xD8,
0xE7, 0x8E, 0xD3, 0xC8, 0x25, 0xA1, 0x26, 0x50,
0xBB, 0xB4, 0x35, 0xAF, 0xAF, 0x06, 0x23, 0x69,
0x3E, 0x30, 0xFD, 0x7B, 0x34, 0x83, 0x07, 0xD0,
0xF0, 0x0F, 0x6C, 0x9A, 0x13, 0x5D, 0xC2, 0x7B,
0xDF, 0x6F, 0xDD, 0x8E, 0xF4, 0x30, 0x82, 0x05,
0x41, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, 0x05, 0x32,
0x04, 0x82, 0x05, 0x2E, 0x30, 0x82, 0x05, 0x2A,
0x30, 0x82, 0x05, 0x26, 0x06, 0x0B, 0x2A, 0x86,
0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01,
0x02, 0xA0, 0x82, 0x04, 0xEE, 0x30, 0x82, 0x04,
0xEA, 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48,
0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30,
0x0E, 0x04, 0x08, 0x74, 0xC0, 0x84, 0x8F, 0xC7,
0x74, 0x5E, 0x21, 0x02, 0x02, 0x08, 0x00, 0x04,
0x82, 0x04, 0xC8, 0x1E, 0xF4, 0xE9, 0x07, 0x27,
0x9E, 0x5A, 0xC9, 0x39, 0x1D, 0x37, 0x2C, 0x06,
0x4B, 0x57, 0xEA, 0xC5, 0x42, 0x9A, 0x60, 0xD5,
0x42, 0xB2, 0x34, 0x2D, 0xD3, 0x88, 0x7C, 0x78,
0x87, 0xB6, 0xE9, 0x42, 0x44, 0x1F, 0x67, 0x32,
0x92, 0x54, 0x22, 0xDA, 0xB2, 0x43, 0xE7, 0x40,
0xBE, 0x1F, 0xAF, 0x3A, 0xCD, 0x2A, 0x9F, 0xD7,
0x44, 0x5B, 0x37, 0x69, 0x85, 0xDF, 0xEB, 0x2A,
0xB9, 0xE2, 0x92, 0x3B, 0xEA, 0xD5, 0x42, 0x53,
0x95, 0x4A, 0xB0, 0x1B, 0xA5, 0xEF, 0xA6, 0x0D,
0x29, 0xF4, 0x33, 0xFE, 0xD7, 0x49, 0x04, 0x1E,
0x8C, 0xAD, 0x63, 0x1E, 0x79, 0x63, 0x74, 0x0C,
0xE5, 0x5E, 0xA2, 0x2C, 0xBE, 0xB8, 0x90, 0xCE,
0x06, 0x25, 0xBF, 0xD1, 0x5A, 0x50, 0xCF, 0x3B,
0x52, 0xE2, 0xA7, 0xFF, 0x19, 0x02, 0xCF, 0xD0,
0x9B, 0xD9, 0xF7, 0x28, 0x07, 0x38, 0x1F, 0xF2,
0xAF, 0x44, 0x91, 0x3F, 0x0F, 0xB6, 0x6E, 0x8C,
0xC0, 0x32, 0x92, 0xC0, 0xCD, 0x25, 0x98, 0x67,
0xF1, 0x47, 0x52, 0x50, 0xF0, 0xA3, 0x7B, 0xE6,
0x74, 0xDC, 0x72, 0x28, 0xC8, 0xAB, 0xB3, 0x31,
0x7D, 0xA3, 0xF7, 0xC7, 0xD1, 0xE6, 0x99, 0xB4,
0xB6, 0x5A, 0x3A, 0x4D, 0x83, 0x4F, 0xB8, 0xB5,
0x86, 0xF8, 0x37, 0x7F, 0xA0, 0x16, 0x2F, 0x3C,
0x62, 0x7A, 0xD4, 0x3A, 0xEB, 0xC2, 0xE8, 0x03,
0x49, 0x17, 0x9E, 0xFB, 0xD7, 0xAF, 0x91, 0x32,
0xFD, 0xEA, 0x4F, 0x64, 0xC6, 0x6E, 0x02, 0xEA,
0xC4, 0xC8, 0x1F, 0x16, 0xC5, 0x4C, 0xFB, 0xC5,
0x42, 0xF5, 0x85, 0x05, 0x92, 0x59, 0x4B, 0x31,
0xE5, 0xE9, 0x69, 0xE7, 0x02, 0x98, 0x33, 0xBA,
0x4C, 0x17, 0x09, 0xEF, 0x89, 0x20, 0xFA, 0x83,
0x9F, 0xAE, 0x0E, 0x1B, 0x7D, 0x98, 0xB9, 0xF2,
0x3C, 0x0F, 0xB7, 0x1C, 0x72, 0xDF, 0x17, 0x84,
0x7F, 0x0A, 0xFD, 0x12, 0x3C, 0x6F, 0x68, 0x5D,
0x45, 0xEB, 0xB8, 0xD6, 0x24, 0x65, 0x42, 0x75,
0x5C, 0xC2, 0xF3, 0x3A, 0x6A, 0x4E, 0x51, 0x34,
0x1B, 0xB6, 0x81, 0xB2, 0x8A, 0xEF, 0x28, 0xA4,
0xC5, 0x88, 0x9A, 0x97, 0xE0, 0xEF, 0x31, 0x12,
0x01, 0x7E, 0x1B, 0x43, 0x0F, 0x27, 0x80, 0x87,
0x98, 0xC5, 0xD5, 0x83, 0xCB, 0x4B, 0xB7, 0x01,
0x79, 0x60, 0xA1, 0x1A, 0x03, 0x05, 0xC6, 0x36,
0x04, 0x31, 0x3C, 0x06, 0xDB, 0x08, 0xA8, 0xDA,
0x8E, 0x32, 0x19, 0x91, 0xF1, 0x0D, 0x61, 0x6F,
0xE4, 0xB2, 0x79, 0x8A, 0xDE, 0xF4, 0xF7, 0xFB,
0x2C, 0x23, 0x5B, 0xD9, 0x64, 0x2F, 0xB7, 0xB3,
0x8B, 0xCA, 0xB8, 0x8C, 0x1D, 0x3B, 0x49, 0x05,
0x38, 0xA1, 0xE5, 0x8C, 0x1A, 0xDC, 0xA5, 0x61,
0xFE, 0xF4, 0x2B, 0xDC, 0x77, 0x28, 0xF6, 0x19,
0xE7, 0xB7, 0x8F, 0x4D, 0x27, 0x2D, 0xED, 0x8A,
0x3F, 0x3D, 0xDC, 0x9F, 0xD1, 0x30, 0xFF, 0xD6,
0xC3, 0xBE, 0x41, 0x25, 0xE3, 0xA5, 0x9B, 0x73,
0xDF, 0x6A, 0xD9, 0xF9, 0x70, 0x84, 0x02, 0x4C,
0x35, 0xD4, 0x3E, 0x05, 0x76, 0x3A, 0xDC, 0x6D,
0x5A, 0x81, 0xB3, 0x94, 0xF7, 0x22, 0xF7, 0xDC,
0xC1, 0x43, 0x31, 0x57, 0x5B, 0x42, 0x9A, 0x0B,
0xF4, 0x95, 0x30, 0xA9, 0xBB, 0xD8, 0x06, 0xFB,
0x1D, 0x6F, 0x9B, 0xC3, 0xBB, 0xF3, 0xBF, 0xFB,
0xB4, 0x9F, 0x35, 0x64, 0x0A, 0x69, 0xB7, 0xD1,
0x3E, 0xCA, 0x78, 0x07, 0x04, 0x03, 0x79, 0xD4,
0xF3, 0xA8, 0xEC, 0x18, 0xDB, 0x03, 0x5E, 0x47,
0xD7, 0xD0, 0x56, 0x2C, 0x74, 0x94, 0x86, 0x04,
0x46, 0xB8, 0xD4, 0x35, 0x0A, 0x7B, 0xE6, 0x78,
0xC4, 0x43, 0x3C, 0x56, 0xCC, 0x37, 0x8B, 0xFD,
0xE8, 0xF4, 0x57, 0xEA, 0xAE, 0xCF, 0x36, 0x97,
0x12, 0xAC, 0x39, 0xCF, 0x7C, 0xEF, 0x22, 0x67,
0x01, 0xEC, 0xD8, 0x09, 0x49, 0x4E, 0xE3, 0x74,
0xDD, 0x39, 0xE1, 0x39, 0xD7, 0x0C, 0x5F, 0x1B,
0xCE, 0x69, 0xBC, 0x72, 0x44, 0x87, 0x64, 0x1C,
0x08, 0x05, 0x93, 0x69, 0x6D, 0x7F, 0x90, 0x0A,
0x2C, 0xCB, 0x8A, 0xBB, 0x7F, 0xE3, 0xE0, 0x80,
0x31, 0xD0, 0x0A, 0x3A, 0x95, 0xFF, 0xF7, 0xB4,
0x36, 0x38, 0x93, 0xE0, 0x0C, 0x11, 0x37, 0x12,
0x06, 0xF6, 0xAD, 0xE9, 0xB1, 0x7A, 0x00, 0xF5,
0xD2, 0x32, 0x6B, 0xD0, 0x27, 0xA5, 0x1B, 0x3D,
0xE8, 0xDB, 0xCC, 0xA9, 0x1F, 0x1F, 0xB1, 0x99,
0x3D, 0x7C, 0xB7, 0xCA, 0xDA, 0x27, 0x2C, 0x64,
0x1C, 0x49, 0xB6, 0x87, 0x44, 0x06, 0x94, 0x9D,
0xBC, 0x6B, 0x20, 0xA2, 0x68, 0x15, 0x1F, 0xE2,
0xF2, 0xAD, 0x6D, 0x23, 0x2E, 0x2B, 0x74, 0xE2,
0x5D, 0xE4, 0xB0, 0xC7, 0x84, 0xCB, 0x64, 0xBF,
0xE0, 0xA8, 0x18, 0x83, 0xB4, 0xC9, 0xD9, 0x73,
0xA8, 0xE6, 0xA9, 0x36, 0xD5, 0x63, 0x1E, 0x2C,
0x2A, 0x55, 0x09, 0x77, 0x5E, 0xB3, 0x4B, 0xEA,
0xB5, 0xD0, 0x14, 0x5F, 0xEB, 0x50, 0x7B, 0xAA,
0xEF, 0x94, 0xBA, 0x2B, 0xD7, 0x8A, 0x07, 0xF1,
0xF9, 0x5E, 0x12, 0x12, 0x21, 0x52, 0xE5, 0x0A,
0x3E, 0xC0, 0xBC, 0x5D, 0x4C, 0xE2, 0x12, 0x7C,
0x39, 0xF9, 0x16, 0x9D, 0xBD, 0x96, 0x83, 0x3B,
0x7F, 0x3D, 0x6A, 0xEC, 0xF1, 0x25, 0xD2, 0xB0,
0xB0, 0xEB, 0x20, 0x06, 0x07, 0xD6, 0xD9, 0x4C,
0x07, 0x9A, 0x82, 0xC1, 0xFC, 0xF7, 0x66, 0x15,
0xBD, 0x62, 0x65, 0xD8, 0x6C, 0xF6, 0x33, 0x7B,
0x5A, 0x28, 0xEC, 0x90, 0xA1, 0x26, 0x9F, 0xC3,
0x28, 0x4A, 0x64, 0x50, 0x5F, 0xCA, 0xE2, 0x6D,
0xB8, 0x0F, 0xE2, 0x94, 0xB5, 0x8E, 0x1F, 0x8A,
0x8F, 0x6B, 0xA6, 0x86, 0x1F, 0xEE, 0xDC, 0x24,
0xB4, 0xB8, 0x25, 0xEC, 0x28, 0x2D, 0xF9, 0xCB,
0x7D, 0x38, 0xFF, 0xC7, 0x74, 0x2E, 0xD3, 0x10,
0xEC, 0x03, 0x31, 0xEE, 0x83, 0xE7, 0xA4, 0xF7,
0xBA, 0x28, 0x21, 0xE0, 0x7F, 0xB4, 0xB7, 0xE1,
0x7A, 0xF9, 0x2B, 0xB0, 0x2C, 0x3B, 0x80, 0x5F,
0xE0, 0x5D, 0xB2, 0x7E, 0x59, 0xFF, 0x59, 0x07,
0x58, 0x42, 0x57, 0xEE, 0x44, 0xF1, 0xB1, 0xAD,
0xBA, 0xDE, 0xCB, 0x1D, 0x8A, 0x36, 0x67, 0xE8,
0x45, 0xFF, 0x07, 0x8D, 0xEE, 0xA4, 0x51, 0x9C,
0x4C, 0x83, 0x5D, 0x2E, 0x2F, 0xE1, 0x5B, 0x75,
0xE8, 0x29, 0xCD, 0x0B, 0x07, 0x62, 0xE0, 0xC3,
0x0D, 0x1D, 0xEA, 0xCF, 0xF0, 0x8A, 0x65, 0x27,
0x70, 0x42, 0x9F, 0x26, 0x00, 0x15, 0x70, 0xC5,
0x4A, 0xF6, 0x25, 0xD0, 0x40, 0x72, 0xE9, 0xC1,
0x73, 0xFD, 0x48, 0x94, 0xA3, 0x8D, 0x66, 0x63,
0x96, 0x4F, 0xF7, 0xEE, 0xFB, 0x4C, 0xC7, 0xB8,
0x6B, 0xE9, 0x90, 0xE1, 0x2A, 0x66, 0x80, 0x99,
0x3B, 0xB0, 0x1A, 0x6C, 0xF9, 0x0E, 0x72, 0xDA,
0x8E, 0x4F, 0x46, 0xC2, 0x6A, 0x4B, 0x7A, 0x16,
0xE5, 0x26, 0x0B, 0x5C, 0xD4, 0x47, 0x34, 0xE5,
0x37, 0xBE, 0x68, 0x6C, 0xDA, 0xD3, 0x9B, 0x6F,
0xAE, 0x51, 0x9C, 0x99, 0x0A, 0x5B, 0xF8, 0x37,
0xBC, 0xDE, 0xFC, 0x93, 0xC5, 0xE7, 0x0F, 0xEF,
0x0B, 0xA6, 0x07, 0xC2, 0xA6, 0xE6, 0xDA, 0x2D,
0x1B, 0x49, 0xC9, 0xDE, 0x6B, 0x27, 0xDC, 0x00,
0xEF, 0x23, 0x87, 0x0E, 0xEB, 0xD1, 0x48, 0x7D,
0xB4, 0xF2, 0x58, 0xC6, 0x3C, 0xE2, 0x89, 0xBA,
0xB0, 0x05, 0xAC, 0x94, 0x41, 0x9A, 0xA8, 0xFF,
0x3E, 0xBC, 0x3A, 0x52, 0x9C, 0xF9, 0x7F, 0x07,
0x8B, 0xB0, 0x2C, 0x71, 0x83, 0x7B, 0xCF, 0x2E,
0x7F, 0x7C, 0x96, 0x65, 0xD9, 0x08, 0x17, 0xEC,
0xFA, 0xDE, 0x4E, 0x40, 0x12, 0x26, 0x70, 0x71,
0x65, 0xA5, 0xDC, 0x98, 0x47, 0xA3, 0xFC, 0xE0,
0x9A, 0x16, 0xED, 0x45, 0x56, 0x72, 0x50, 0x05,
0x28, 0x2C, 0x99, 0xEC, 0x20, 0x2E, 0x40, 0xC0,
0x26, 0x69, 0xCD, 0x49, 0x45, 0x17, 0xA4, 0xA3,
0x42, 0x0D, 0x14, 0x65, 0x87, 0x33, 0x8C, 0x92,
0xC5, 0xC4, 0x61, 0xFD, 0xE8, 0x68, 0x56, 0x20,
0x57, 0xF5, 0x8E, 0x5F, 0xCF, 0x7E, 0x97, 0xF6,
0x49, 0x97, 0x0A, 0xFE, 0xD3, 0x60, 0x1A, 0x5B,
0x0C, 0x75, 0xDD, 0x8E, 0x31, 0x78, 0x29, 0xA6,
0xB1, 0x4D, 0xAA, 0xDF, 0x8A, 0xD1, 0xE6, 0x91,
0xE3, 0x32, 0x3F, 0xEC, 0x8A, 0x1F, 0x0E, 0x35,
0x07, 0x6E, 0x4B, 0x83, 0x3B, 0xE5, 0x67, 0x34,
0x1F, 0x0C, 0x81, 0xD8, 0xD5, 0x25, 0x68, 0xE5,
0x28, 0x1B, 0x5C, 0x81, 0x3E, 0xE3, 0x5C, 0xB4,
0xB6, 0xBD, 0x62, 0x6A, 0x70, 0x33, 0xC2, 0xC5,
0x75, 0x27, 0xF4, 0x30, 0xE1, 0x1D, 0xC1, 0x4C,
0xC5, 0x02, 0x12, 0x46, 0xAC, 0xEC, 0xF9, 0xE8,
0xE7, 0x58, 0x24, 0x11, 0xB1, 0xF3, 0xB7, 0x8C,
0x3C, 0xA4, 0x0A, 0x94, 0xA6, 0x7C, 0x68, 0x54,
0x5B, 0xB9, 0x4D, 0x57, 0x9C, 0xE7, 0x28, 0x09,
0x6B, 0x89, 0x26, 0x5D, 0xE7, 0x50, 0xA9, 0x95,
0x90, 0x91, 0x8E, 0x00, 0x59, 0xF8, 0x3A, 0x70,
0xAF, 0x48, 0x2E, 0xE8, 0xC4, 0x34, 0x8C, 0xF4,
0x5F, 0x7F, 0xCB, 0x07, 0xAA, 0xF0, 0xD9, 0xFB,
0x5C, 0x32, 0x90, 0x22, 0x1A, 0xD2, 0x1A, 0xCF,
0x92, 0x06, 0x02, 0xCF, 0x10, 0x18, 0x7B, 0x93,
0xCC, 0x07, 0x4A, 0x31, 0x25, 0x30, 0x23, 0x06,
0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xD1, 0xDE,
0x23, 0x16, 0x9F, 0x6E, 0xF4, 0x42, 0x21, 0x23,
0xE1, 0x11, 0xAA, 0xC8, 0x7C, 0x60, 0x4A, 0x78,
0x9D, 0x24, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09,
0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05,
0x00, 0x04, 0x14, 0xD6, 0x4A, 0xBB, 0x75, 0xB1,
0xF9, 0x9E, 0xD3, 0x58, 0x6D, 0xD1, 0x74, 0x9F,
0x00, 0x8A, 0xF2, 0xC8, 0xAA, 0x52, 0x4D, 0x04,
0x08, 0x77, 0x46, 0xE7, 0xBA, 0x25, 0x4B, 0xDA,
0x41, 0x02, 0x02, 0x08, 0x00]
};
const WPA_EAP_CLIENT_LIST = [
{
ssid: 'WPA-EAP-PEAP',
keyManagement: 'WPA-EAP',
eap: 'PEAP',
identity: EAP_USERNAME,
password: EAP_PASSWORD,
serverCertificate: CLIENT_PKCS12_CERT.nickname,
phase2: 'MSCHAPV2'
}
];
/**
* Convert the given MozWifiNetwork object array to testAssociate chain.
*
* @param aNetworks
* An array of MozWifiNetwork which we want to convert.
*
* @return A promise chain which "then"s testAssociate accordingly.
*/
function convertToTestAssociateChain(aNetworks) {
let chain = Promise.resolve();
aNetworks.forEach(function (aNetwork) {
network = new window.MozWifiNetwork(aNetwork);
chain = chain.then(() => gTestSuite.testAssociate(network));
});
return chain;
}
gTestSuite.doTestWithCertificate(
new Blob([new Uint8Array(CLIENT_PKCS12_CERT.content)]),
CLIENT_PKCS12_CERT.password,
CLIENT_PKCS12_CERT.nickname,
CLIENT_PKCS12_CERT.usage,
function() {
return gTestSuite.ensureWifiEnabled(true)
// Load required server files.
.then(() => gTestSuite.writeFile(SERVER_EAP_USER_CONF.path, SERVER_EAP_USER_CONF.content))
.then(() => gTestSuite.writeFile(CA_CERT.path, CA_CERT.content))
.then(() => gTestSuite.writeFile(SERVER_CERT.path, SERVER_CERT.content))
.then(() => gTestSuite.writeFile(SERVER_KEY.path, SERVER_KEY.content))
// Start AP.
.then(() => gTestSuite.startHostapds(WPA_EAP_AP_LIST))
// Scan test.
.then(() => gTestSuite.testWifiScanWithRetry(SCAN_RETRY_CNT, WPA_EAP_AP_LIST))
// Associate test.
.then(() => convertToTestAssociateChain(WPA_EAP_CLIENT_LIST))
// Tear down.
.then(gTestSuite.killAllHostapd)
});
@@ -0,0 +1,622 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
const SCAN_RETRY_CNT = 5;
const EAP_USERNAME = 'username';
const EAP_PASSWORD = 'password';
const SERVER_EAP_USER_CONF = {
path: HOSTAPD_CONFIG_PATH + 'hostapd.eap_user',
content: '* PEAP,TTLS,TLS\n' +
'"' + EAP_USERNAME + '" MSCHAPV2,TTLS-MSCHAPV2 "' + EAP_PASSWORD + '" [2]\n'
};
const CA_CERT = {
path: HOSTAPD_CONFIG_PATH + 'ca.pem',
content: '-----BEGIN CERTIFICATE-----\n' +
'MIIDsTCCApmgAwIBAgIJAKxTf+8X8qngMA0GCSqGSIb3DQEBCwUAMG4xCzAJBgNV\n' +
'BAYTAlRXMRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhjaHVja2xlZTER\n' +
'MA8GA1UEAwwIY2h1Y2tsZWUxJDAiBgkqhkiG9w0BCQEWFWNodWNrbGkwNzA2QGdt\n' +
'YWlsLmNvbTAgFw0xNDEyMjQxMTI4NTBaGA8yMjg4MTAwNzExMjg1MFowbjELMAkG\n' +
'A1UEBhMCVFcxEzARBgNVBAgMClNvbWUtU3RhdGUxETAPBgNVBAoMCGNodWNrbGVl\n' +
'MREwDwYDVQQDDAhjaHVja2xlZTEkMCIGCSqGSIb3DQEJARYVY2h1Y2tsaTA3MDZA\n' +
'Z21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo3c2yFxY\n' +
'o6gGg0I83jy00ME+MAfzCd+4ShL45ZLqysQP93jRBfPzU9ZuZ29ysVwgWIdqkZao\n' +
'XTuV/NAW2GMGd8W1jQJ3J81fjb9wvhlny3rrACwvUn1N1S1BnM+BAAiDLGxEmvAQ\n' +
'onp2aaa6HsHsYS8ONX+d2Qh4LEA4vupeSGAqJychCZv/l+aq/ErFZhFYB3CPUQEt\n' +
'cClO24ucsIYP95lA0zhscnmAj06qplFD4Bv6IVrdDqujy1zNwCQwsJq/8OQdaTN/\n' +
'h3y9pWvNKMBMM2niOUAjtuNpqsSK/lTS1WAT3PdtVECX9fYBi0Bg+HM92xs/6gt6\n' +
'kh9jPV8keXHvSwIDAQABo1AwTjAdBgNVHQ4EFgQU7hBqhuG04xeCzrQ3ngx18ZJ3\n' +
'lUswHwYDVR0jBBgwFoAU7hBqhuG04xeCzrQ3ngx18ZJ3lUswDAYDVR0TBAUwAwEB\n' +
'/zANBgkqhkiG9w0BAQsFAAOCAQEAFYX2iy680GAnBTttk0gyX6gk+8pYr3D22k/G\n' +
'6rvcjefzS7ELQPRKr6mfmwXq3mMf/4jiS2zI5zmXsestPYzHYxf2viQ6t7vr9XiJ\n' +
'3WfFjNw4ERlRisAvg0aqqTNNQq5v2VME4sdFZagy217f73C7azwCHl0bqOLH05rl\n' +
'8RubOxiHEj7ZybJqnRciK/bht4D+rZkwf4bBBmoloqH7xT0+rFQclpYXDGGjNUQB\n' +
'LcHLF10xcr7g3ZVVu82fe6+d85gIGOIMR9+TKhdw6gO3CNcnDAj6gxksghgtcxmh\n' +
'OzOggCn7nlIwImtsg2sZkpWB4lEi9hdv4lkNuyFjOL3bnuc+NA==\n' +
'-----END CERTIFICATE-----\n'
};
const SERVER_CERT = {
path: HOSTAPD_CONFIG_PATH + 'server.pem',
content: '-----BEGIN CERTIFICATE-----\n' +
'MIID1DCCArygAwIBAgIBADANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJUVzET\n' +
'MBEGA1UECAwKU29tZS1TdGF0ZTERMA8GA1UECgwIY2h1Y2tsZWUxETAPBgNVBAMM\n' +
'CGNodWNrbGVlMSQwIgYJKoZIhvcNAQkBFhVjaHVja2xpMDcwNkBnbWFpbC5jb20w\n' +
'IBcNMTQxMjI0MTEyOTQ5WhgPMjI4ODEwMDcxMTI5NDlaMG4xCzAJBgNVBAYTAlRX\n' +
'MRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhjaHVja2xlZTERMA8GA1UE\n' +
'AwwIY2h1Y2tsZWUxJDAiBgkqhkiG9w0BCQEWFWNodWNrbGkwNzA2QGdtYWlsLmNv\n' +
'bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMdhQmKilTJbWZRxTiSV\n' +
'rqIU+LYW1RKghx5o+0JpNRJVLuz5kBMaNskbbfUSNuHbEq0QA9BDKAZWIc4LSotk\n' +
'lCo8TbcO9CJvJPQGGjGdHcohWX5vy6BE/OVE46CUteMFyZF6F8R2fNUww08iR/u1\n' +
'YZebL5pWO1j43sPpAzEy6Tij2ACPt6EZcFaZG3SF2mVJWkCQnBqrojP65WUvZQqp\n' +
'seUhW2YAS8Nu0Yrohgxz6VYk+cNDuDZVGs6qWRStZzJfYrfc76DtkHof5B14M+xp\n' +
'XJaBLxN+whvnYkDTfinaCxnW1O7eXUltr87fLc5zmeBkgwaiaQuIdcfZm7vDUiz8\n' +
'vnUCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH\n' +
'ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFKK4f9/YavTHOfEiAB83Deac\n' +
'6gT5MB8GA1UdIwQYMBaAFO4QaobhtOMXgs60N54MdfGSd5VLMA0GCSqGSIb3DQEB\n' +
'CwUAA4IBAQBWnO9o9KSJIqjoz5Nwll63ULOdcvgGdOeJIw1fcKQ817Rsp+TVcjcH\n' +
'IrIADsT/QZGXRO/l6p1750e2iFtJEo1hsRaxtA1wWn2I9HO3+av2spQhr3jpYGPf\n' +
'zpsMTp4RNYV7Q8+q1kZIz9PY4V1T0p6lveK8+fUj2hSLnxSj0QiGSJJtnEC3w4Rv\n' +
'C9T6oUwIeToULmi+8FXQFdEqwKRU98DPq3eLzN28ZxUgoPE1C8+42D2UW8uyp/Gm\n' +
'tGOa/k7nzkCdVqZI7lX7f0AjEvQgjtAMQ/k7Mhxx7TzW2HO+1YPMoKji6Z4WkNwt\n' +
'JEj9ZUBSNt8B26UksJMBDkcvSegF3a7o\n' +
'-----END CERTIFICATE-----\n'
};
const SERVER_KEY = {
path: HOSTAPD_CONFIG_PATH + 'server.key',
content: '-----BEGIN RSA PRIVATE KEY-----\n' +
'MIIEpAIBAAKCAQEAx2FCYqKVMltZlHFOJJWuohT4thbVEqCHHmj7Qmk1ElUu7PmQ\n' +
'Exo2yRtt9RI24dsSrRAD0EMoBlYhzgtKi2SUKjxNtw70Im8k9AYaMZ0dyiFZfm/L\n' +
'oET85UTjoJS14wXJkXoXxHZ81TDDTyJH+7Vhl5svmlY7WPjew+kDMTLpOKPYAI+3\n' +
'oRlwVpkbdIXaZUlaQJCcGquiM/rlZS9lCqmx5SFbZgBLw27RiuiGDHPpViT5w0O4\n' +
'NlUazqpZFK1nMl9it9zvoO2Qeh/kHXgz7GlcloEvE37CG+diQNN+KdoLGdbU7t5d\n' +
'SW2vzt8tznOZ4GSDBqJpC4h1x9mbu8NSLPy+dQIDAQABAoIBAASG4Mr8hgaurEoC\n' +
'iJOsElr7vunjetMBcg/uskW/vcS8ymP3Bp5oafYG+WgnEbfvEW18f5mq7K24JuxW\n' +
'tUqU7ghHdjxByqk9fMlNmiqmNpbwSufkAeuRpWxPNBvhRH/zEbCL5R5A0nTEtqqF\n' +
'TL0aUSzwCRSoAJD0lZo9ICVt0n3GsDyM9rqQg/uZmh1qsRdwPsRuYORND9g48rKq\n' +
'6WN9leskSxhhsYE2D9ocOFd9bNt8Zxejh9ppVSnG/KsIdt18iBzcabatgAQ046fb\n' +
'Z3vprcZJLg93Sg2gSuVqlSTs3M2W8VQnm22/EBMb1y0M48MSRCgnbPLG/CcCLLfF\n' +
'LwxCOgECgYEA/eYt67xyJ6JeAdxdwOZuT1WWGbFpLiG9+2OgiHumyRQ5969XMTWo\n' +
'fIhMKchDdjoy9RR236\/\/EFCs7UEyB7+a7ODRzNiK2zCD8Smjp+21fUPSthEeQesk\n' +
'eiMYICIu5Ay35x9sxIX+XOUVvRhPOGcD29GVeRnKh1inTHOz2dje8LkCgYEAyQeY\n' +
'STi9jjCEcHkM1E/UeDiLfHHepLXi8wS41JNRHl5Jacp7XB5djAjKu/jf367/VpFy\n' +
'GDDMetE7n8eWkrnAvovxOwZ000YDMtL1sUYSjL+XtBS5s6VY1p4qaSAY9nUUGrJh\n' +
'JvtvsuI7SKTtL+60vjBOH7zDnvOdBgAp0utLhZ0CgYEAuLzzqrPKB8afShFSchn4\n' +
'J2dpuLYahsNsXW7HDqeR2nsKFosRETAusLXnXPtnAq4kB6jlOarwFqnsuRCX24Vx\n' +
'r2uBm9/vYL7zMdUPTA+s30ErHuhjsKjsOKYyVqcooSwT32pBFNk+E89nutfmRG7I\n' +
'IvhjHuNCNqqtx/Xj5d1jkZkCgYBQicppC2Jl5OoqZVTOem0U/RJk+PnJ41TZJ7sk\n' +
'7yBAmmWvDH\/\/l+rCf4M5a6vFYcbKV9rt9h711X2dtciNX/3oWQh8LUoAmrwNUJc+\n' +
'PmSQHvIYI3WCk2vUD+nN1B4sHxu+1lg11eYaNKiroeeknG2tBI1ICcgVlmQCU25u\n' +
'IfZPwQKBgQCdO6QHhPLtcHUDNFA6FQ1jKL1iEd7G0JLVRz4Xkpkn1Vrr5MD6JFDa\n' +
'5ccabADyl0lpFqDIVJQIzLku2hOD2i9aBNCY0pL391HeOS7CkZX+TdOY1tquoBq5\n' +
'MnmixZjDCVd2VcrVyTA6ntOBoharKFW0rH1PqU+qu7dZF7CBPbAdEw==\n' +
'-----END RSA PRIVATE KEY-----\n'
};
const WPA_EAP_AP_LIST = [
{
ssid: 'WPA-EAP-TLS',
ieee8021x: 1,
eapol_version: 1,
eap_server: 1,
eapol_key_index_workaround: 0,
eap_user_file: SERVER_EAP_USER_CONF.path,
ca_cert: CA_CERT.path,
server_cert: SERVER_CERT.path,
private_key: SERVER_KEY.path,
wpa: 2,
wpa_key_mgmt: 'WPA-EAP'
}
];
const CLIENT_PKCS12_CERT = {
nickname: 'client',
password: 'password',
usage: ['UserCert', 'ServerCert'],
content: [0x30, 0x82, 0x0E, 0x01, 0x02, 0x01, 0x03, 0x30,
0x82, 0x0D, 0xC7, 0x06, 0x09, 0x2A, 0x86, 0x48,
0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82,
0x0D, 0xB8, 0x04, 0x82, 0x0D, 0xB4, 0x30, 0x82,
0x0D, 0xB0, 0x30, 0x82, 0x08, 0x67, 0x06, 0x09,
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07,
0x06, 0xA0, 0x82, 0x08, 0x58, 0x30, 0x82, 0x08,
0x54, 0x02, 0x01, 0x00, 0x30, 0x82, 0x08, 0x4D,
0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
0x01, 0x07, 0x01, 0x30, 0x1C, 0x06, 0x0A, 0x2A,
0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01,
0x06, 0x30, 0x0E, 0x04, 0x08, 0x67, 0x7A, 0xF3,
0x61, 0xBE, 0xE0, 0x51, 0xC1, 0x02, 0x02, 0x08,
0x00, 0x80, 0x82, 0x08, 0x20, 0xFC, 0x6A, 0x79,
0xA1, 0x6C, 0xAF, 0xBE, 0xEE, 0x62, 0x45, 0x33,
0xB8, 0x48, 0xE1, 0x68, 0xA1, 0x15, 0x11, 0x4B,
0x95, 0xCB, 0x77, 0xC0, 0x5D, 0xA2, 0xCB, 0xDB,
0xD1, 0x83, 0x74, 0x60, 0xD7, 0xEC, 0x42, 0xA6,
0x3A, 0x23, 0xF7, 0x85, 0xEB, 0xC1, 0xFE, 0x6A,
0x57, 0x8E, 0xC1, 0x44, 0xF3, 0x1F, 0xFE, 0xB8,
0x2D, 0x8C, 0x4D, 0xC9, 0x5B, 0xAE, 0x21, 0x2E,
0x4C, 0x1A, 0xEB, 0x84, 0x09, 0xF3, 0x40, 0x92,
0x39, 0x7F, 0x56, 0x02, 0x46, 0x61, 0x16, 0xDE,
0x5C, 0x48, 0xB6, 0x0C, 0x1D, 0xD3, 0x5F, 0x10,
0x9A, 0x39, 0xB8, 0x66, 0x31, 0xFC, 0x39, 0x71,
0x87, 0x23, 0x46, 0x9D, 0xE8, 0x3C, 0x2B, 0xA1,
0x39, 0x8A, 0xD3, 0xFF, 0xD9, 0x43, 0xB6, 0x61,
0xC6, 0x67, 0x70, 0x40, 0xBD, 0xFE, 0xD3, 0xC1,
0x68, 0xF5, 0xF7, 0xC8, 0x89, 0xD8, 0x17, 0xC5,
0xE8, 0x3D, 0x29, 0xD5, 0x91, 0xDF, 0x1F, 0x56,
0x74, 0x5A, 0xC4, 0xA8, 0x14, 0xBA, 0xD4, 0xFA,
0x13, 0x49, 0x2A, 0x9F, 0x63, 0xF1, 0xB2, 0x45,
0xF1, 0xF0, 0x2A, 0xDD, 0x75, 0x66, 0x8A, 0xF7,
0xAB, 0x73, 0x86, 0x26, 0x9D, 0x1F, 0x07, 0xAD,
0xD3, 0xFE, 0xE0, 0xA3, 0xED, 0xA0, 0x96, 0x3E,
0x1E, 0x89, 0x86, 0x02, 0x4C, 0x28, 0xFD, 0x57,
0xA1, 0x67, 0x55, 0xF0, 0x82, 0x3B, 0x7F, 0xCC,
0x2A, 0x32, 0x01, 0x93, 0x1D, 0x8B, 0x66, 0x8A,
0x20, 0x52, 0x84, 0xDD, 0x2C, 0xFD, 0xEE, 0x72,
0xF3, 0x8C, 0x58, 0xB9, 0x99, 0xE5, 0xC1, 0x22,
0x63, 0x59, 0x00, 0xE2, 0x76, 0xC5, 0x3A, 0x17,
0x7F, 0x93, 0xE9, 0x67, 0x61, 0xAA, 0x10, 0xC3,
0xD9, 0xC8, 0x24, 0x46, 0x5B, 0xBE, 0x8C, 0x1F,
0x2D, 0x66, 0x48, 0xD2, 0x02, 0x11, 0xFB, 0x74,
0x14, 0x76, 0x76, 0x5A, 0x98, 0x54, 0x35, 0xA7,
0x85, 0x66, 0x20, 0x26, 0x8B, 0x13, 0x6F, 0x68,
0xE3, 0xC9, 0x58, 0x7D, 0x1C, 0x3E, 0x01, 0x8D,
0xF8, 0xD6, 0x7F, 0xCF, 0xA2, 0x07, 0xB7, 0x95,
0xFD, 0xF0, 0x02, 0x34, 0x32, 0x30, 0xE8, 0xD4,
0x57, 0x5E, 0x53, 0xFB, 0x54, 0xE2, 0x03, 0x32,
0xCC, 0x52, 0x2E, 0xD2, 0x35, 0xD9, 0x58, 0x85,
0x2D, 0xEC, 0x2D, 0x71, 0xD1, 0x8A, 0x29, 0xD0,
0xB0, 0x24, 0xBD, 0x24, 0xDC, 0x1A, 0x28, 0x3F,
0xA0, 0x12, 0x81, 0x15, 0x24, 0xC9, 0xB5, 0x4A,
0x23, 0xB6, 0xA3, 0x45, 0x50, 0x2D, 0x73, 0x99,
0x6B, 0x1C, 0xFB, 0xA4, 0x53, 0xD7, 0x5C, 0xF4,
0x6C, 0xB0, 0xE5, 0x74, 0xB3, 0x76, 0xF8, 0xB1,
0x0D, 0x59, 0x70, 0x9F, 0xCA, 0xDE, 0xF2, 0xAA,
0x4C, 0x7D, 0x11, 0x54, 0xC4, 0x19, 0x0F, 0x36,
0x4A, 0x62, 0xFF, 0x8B, 0x10, 0xCB, 0x93, 0x50,
0xDA, 0x79, 0x5E, 0x4E, 0x09, 0x1F, 0x22, 0xC8,
0x19, 0x85, 0xE9, 0xEE, 0xB7, 0x71, 0x65, 0xB9,
0x10, 0xD2, 0x0A, 0x73, 0x5B, 0xA6, 0xDA, 0x37,
0x46, 0x02, 0x00, 0x98, 0x9E, 0x20, 0x6C, 0x7D,
0xC7, 0x69, 0xBB, 0xC2, 0x00, 0x40, 0x9C, 0x57,
0x00, 0xC2, 0x36, 0x76, 0xE8, 0x2A, 0x8D, 0xAD,
0x62, 0x57, 0xC8, 0xD0, 0x9D, 0x66, 0x27, 0x5A,
0xD8, 0x0D, 0x35, 0x60, 0x28, 0x38, 0x62, 0x94,
0x78, 0x36, 0x25, 0x58, 0xFD, 0xF8, 0x66, 0x1F,
0x68, 0x04, 0x0F, 0xD8, 0x00, 0xDF, 0xA0, 0x6C,
0x25, 0x42, 0x9A, 0x4C, 0xEB, 0x80, 0x13, 0x51,
0x7D, 0x2D, 0xA8, 0x89, 0xD6, 0x1B, 0x67, 0x72,
0x01, 0xF3, 0x2D, 0x16, 0x77, 0xFE, 0x22, 0xBC,
0x8A, 0x45, 0x09, 0x1F, 0x9C, 0x2F, 0x2A, 0xA9,
0x61, 0x5B, 0x4A, 0xE6, 0x64, 0x2C, 0x62, 0x1A,
0x3A, 0x96, 0xE6, 0x0A, 0xAE, 0x05, 0x1A, 0xC8,
0xCB, 0xD6, 0x8F, 0x3A, 0x4B, 0xE0, 0x7F, 0x82,
0xB4, 0x98, 0xF1, 0x9D, 0xD7, 0x14, 0x76, 0x5E,
0x77, 0x85, 0x87, 0xEC, 0x13, 0xDA, 0xFD, 0xAF,
0xCB, 0xA3, 0x1C, 0x99, 0xC1, 0xFE, 0x17, 0x0C,
0x40, 0x4D, 0x3C, 0x8F, 0x70, 0x86, 0x63, 0x64,
0xB7, 0x75, 0xA8, 0x71, 0x36, 0xDC, 0x54, 0x10,
0x57, 0x0C, 0xA8, 0xF2, 0xA1, 0xBB, 0xED, 0x03,
0x41, 0x57, 0x34, 0x2C, 0x8F, 0x7C, 0xA0, 0x09,
0xF3, 0x9E, 0x41, 0xB7, 0xA8, 0xD4, 0x66, 0x0D,
0x0D, 0xC0, 0x6A, 0xFC, 0x6A, 0xA2, 0xAC, 0xE2,
0x60, 0x00, 0xE3, 0xF7, 0x75, 0x43, 0x23, 0xEB,
0xC8, 0x61, 0xFA, 0xB3, 0xB8, 0x28, 0xCE, 0xCA,
0xF4, 0x47, 0x7F, 0x30, 0x6D, 0x61, 0x89, 0x47,
0xA1, 0x4A, 0xFE, 0xD1, 0x21, 0x0B, 0x6D, 0xF4,
0x3F, 0x00, 0x86, 0x30, 0x8E, 0x33, 0x21, 0x6F,
0xDA, 0x15, 0xFD, 0x5F, 0xEC, 0x8E, 0xF1, 0x12,
0x3F, 0xC9, 0x83, 0x0C, 0xCA, 0x22, 0x01, 0xF1,
0x70, 0x5F, 0x1F, 0x66, 0xB5, 0xF8, 0x3E, 0x7A,
0x6F, 0xDE, 0xDB, 0xA7, 0x8D, 0x18, 0x9E, 0xBE,
0xDB, 0xAD, 0x3D, 0x66, 0x30, 0xC1, 0x6C, 0x0C,
0x87, 0xB4, 0x65, 0x75, 0xE0, 0x9D, 0xEA, 0x16,
0x0D, 0x07, 0x37, 0x33, 0xC5, 0xEC, 0x97, 0x93,
0x37, 0xEB, 0x8E, 0x65, 0x9C, 0x40, 0x63, 0x6C,
0x43, 0x60, 0xB0, 0x40, 0x4D, 0x85, 0xEF, 0xC2,
0x47, 0x5F, 0xE7, 0x6B, 0xCB, 0x40, 0xE8, 0xEA,
0xD8, 0xAB, 0xB1, 0x9A, 0x72, 0xDC, 0x4C, 0x14,
0xFA, 0x43, 0x61, 0x5F, 0xA6, 0x5C, 0x3A, 0x05,
0x17, 0x2E, 0x74, 0xF3, 0x5E, 0x45, 0xD9, 0x47,
0xAA, 0x59, 0xB6, 0x8F, 0x42, 0x66, 0x42, 0x29,
0x90, 0x95, 0x48, 0x46, 0x91, 0x88, 0x3C, 0x8C,
0xDE, 0xCC, 0xED, 0xB3, 0xAA, 0x62, 0xEA, 0xBC,
0xB4, 0x0C, 0x48, 0x4C, 0x53, 0x23, 0x5E, 0x24,
0x85, 0xBF, 0x92, 0xDA, 0x14, 0xDB, 0x1A, 0x3D,
0xEF, 0x30, 0xD9, 0x49, 0x64, 0x4D, 0xE5, 0x01,
0xFC, 0xA4, 0x4B, 0xD1, 0x9F, 0xDE, 0x96, 0x7F,
0x50, 0xBC, 0x4D, 0x38, 0x44, 0xE9, 0x23, 0x5F,
0x37, 0x57, 0x1A, 0xA6, 0x52, 0x5A, 0x0F, 0x4F,
0x87, 0x33, 0x4A, 0x7B, 0x66, 0xEE, 0x3D, 0x66,
0x0A, 0x63, 0x39, 0x1F, 0x23, 0x38, 0x35, 0x73,
0x60, 0x5E, 0x47, 0x20, 0x4F, 0xC0, 0xC8, 0x3C,
0x09, 0xF9, 0x29, 0x4F, 0x5E, 0x55, 0x69, 0xC4,
0x6B, 0xE8, 0xF8, 0x91, 0xC0, 0x22, 0x65, 0x15,
0x1E, 0xFB, 0xB9, 0x61, 0xCE, 0x45, 0xBE, 0x2B,
0xEE, 0xB9, 0x04, 0x2B, 0xFD, 0xAE, 0x61, 0x1C,
0x3D, 0x3D, 0x7C, 0xBF, 0xC1, 0xF7, 0x3C, 0x4E,
0x9E, 0x0E, 0x54, 0xC8, 0xAD, 0xA9, 0xDF, 0x43,
0x49, 0xB9, 0x41, 0x05, 0xE5, 0xF1, 0x49, 0xAA,
0x77, 0x6C, 0x34, 0x5B, 0x93, 0x24, 0x24, 0x23,
0x74, 0x68, 0x11, 0xCE, 0x15, 0x80, 0xA1, 0xA4,
0x1F, 0x8D, 0x81, 0xCD, 0xB2, 0x98, 0xCA, 0x14,
0x0B, 0x0C, 0x61, 0x50, 0x69, 0x72, 0xAE, 0xFA,
0x8B, 0xC0, 0x3F, 0x0D, 0xE7, 0xF2, 0x0F, 0xEB,
0xC1, 0x11, 0xB9, 0x10, 0x03, 0x6A, 0xF5, 0x97,
0x3C, 0x53, 0x2F, 0x67, 0x86, 0x09, 0x6A, 0xE3,
0x28, 0xC0, 0x78, 0xC8, 0xB4, 0x39, 0x8E, 0xD1,
0xCE, 0x25, 0xE8, 0x66, 0xF7, 0x09, 0x40, 0x7D,
0x81, 0xFB, 0xAF, 0xFA, 0x59, 0xC4, 0x9B, 0x2B,
0x83, 0x45, 0x5B, 0xA8, 0x66, 0x9E, 0x38, 0xC8,
0xFD, 0xAC, 0xF2, 0x2D, 0x21, 0xDE, 0x50, 0x4C,
0x03, 0xCB, 0x88, 0x42, 0xDD, 0x84, 0x09, 0x99,
0x8E, 0x8B, 0x40, 0x97, 0x1B, 0x14, 0x85, 0x37,
0x11, 0x01, 0xE0, 0x74, 0x6B, 0x33, 0x52, 0x8C,
0x68, 0x3A, 0x89, 0xB2, 0xAF, 0x35, 0xE6, 0x65,
0xC3, 0x58, 0x70, 0xD2, 0xE7, 0x1F, 0x1F, 0xF6,
0xE5, 0x0A, 0xB1, 0xFE, 0xD0, 0xC9, 0x51, 0x50,
0xE7, 0xFD, 0x58, 0xF5, 0xC4, 0x58, 0x65, 0x94,
0xD1, 0x57, 0x55, 0x5E, 0xD2, 0x27, 0x98, 0xAF,
0xE7, 0x55, 0x0B, 0x87, 0x50, 0x9B, 0xEF, 0xE8,
0x2B, 0xFC, 0xE7, 0x3B, 0x4E, 0xD7, 0xB7, 0x4D,
0xF4, 0xBC, 0xF4, 0x88, 0x63, 0xE4, 0x8A, 0x20,
0x4B, 0x22, 0xB0, 0xA0, 0x53, 0x7F, 0xA8, 0xC9,
0x0C, 0xF8, 0xD7, 0xBD, 0x46, 0x39, 0xA7, 0x7D,
0xDD, 0x10, 0x91, 0x50, 0x54, 0x06, 0x47, 0xF0,
0x3C, 0xAA, 0x43, 0x40, 0xF8, 0x54, 0xDD, 0x8A,
0xEA, 0x8A, 0x0B, 0xA5, 0x7F, 0xCD, 0x5E, 0xAA,
0x02, 0x2E, 0x1F, 0xC6, 0x50, 0x15, 0xF8, 0x0A,
0x0C, 0x1B, 0x3C, 0x55, 0x3A, 0xC3, 0x6F, 0x88,
0xD7, 0xBF, 0xB1, 0x02, 0xCC, 0xE0, 0x08, 0x29,
0x97, 0xD2, 0xAA, 0x23, 0xC4, 0x6D, 0xE3, 0xE3,
0x76, 0x39, 0x92, 0xC3, 0x2E, 0x7A, 0xE2, 0x98,
0xD1, 0xFC, 0xAE, 0xCC, 0x95, 0xD8, 0xB4, 0xDC,
0x92, 0xEA, 0x6A, 0x5F, 0xF2, 0x92, 0x17, 0x0B,
0x8D, 0xC3, 0xFA, 0x9C, 0x62, 0xCE, 0x44, 0x8D,
0xC3, 0x1E, 0xC3, 0xB2, 0xD5, 0x00, 0xCD, 0xB4,
0x9E, 0x2D, 0x7B, 0xF2, 0x98, 0xA3, 0x00, 0x8B,
0x81, 0x30, 0x77, 0x5B, 0x02, 0x99, 0xB1, 0xCD,
0xC3, 0x1D, 0x74, 0x74, 0xEF, 0x41, 0xCB, 0x69,
0x63, 0x8E, 0xA6, 0xD3, 0x2D, 0x3E, 0x1F, 0x1D,
0x12, 0x9E, 0xD9, 0x18, 0x67, 0x06, 0xAF, 0x37,
0x29, 0xAD, 0x65, 0xD8, 0xEB, 0x71, 0xC4, 0x7D,
0x94, 0x3D, 0xEA, 0xCC, 0xDF, 0x72, 0x41, 0x51,
0x3C, 0xA1, 0x66, 0x98, 0x32, 0x32, 0x40, 0x54,
0xB0, 0x2F, 0xEB, 0xCE, 0xDF, 0x4A, 0x64, 0xFB,
0x9A, 0x90, 0xDC, 0xF6, 0x6F, 0xA9, 0xD4, 0xCA,
0xCB, 0x91, 0xC4, 0xFE, 0xEE, 0x9C, 0x01, 0x50,
0x2E, 0xAC, 0xCC, 0x5F, 0x89, 0xD0, 0x91, 0xA3,
0xD9, 0xF9, 0x4B, 0x8D, 0xDE, 0x6C, 0x60, 0x21,
0x19, 0xB1, 0xD3, 0x4D, 0x75, 0x56, 0x6F, 0xB8,
0x25, 0xA4, 0x92, 0x4F, 0x12, 0xF5, 0x8F, 0xC1,
0x17, 0x4B, 0xB3, 0x34, 0x21, 0x22, 0xAC, 0x52,
0xD2, 0x64, 0xC9, 0x9A, 0x7D, 0xFC, 0xC0, 0x0A,
0x89, 0x34, 0xFF, 0x08, 0xD3, 0x04, 0xDC, 0xFE,
0x7C, 0xB3, 0xB8, 0xFD, 0x85, 0xDD, 0x79, 0x51,
0xA7, 0x89, 0xE8, 0xF1, 0x23, 0xB1, 0xDF, 0xD7,
0x1F, 0x7B, 0xB1, 0x5D, 0x42, 0xF9, 0x61, 0xF8,
0xDC, 0x81, 0x04, 0xF1, 0xCC, 0xFA, 0xD7, 0xED,
0xBF, 0x47, 0xAC, 0xBD, 0xE5, 0xFA, 0xAC, 0xB3,
0x1C, 0xD9, 0xA1, 0xB3, 0x60, 0xEE, 0x9C, 0x8A,
0x36, 0x57, 0xB4, 0x2F, 0xA1, 0xA2, 0xF3, 0xE2,
0x09, 0x9A, 0x6E, 0x43, 0x9B, 0xE5, 0x93, 0xB8,
0x3D, 0x9E, 0x9F, 0xC1, 0xC6, 0x0D, 0x02, 0xEB,
0x4D, 0x38, 0xE9, 0xB4, 0x9F, 0xEA, 0x33, 0x8C,
0x07, 0xD8, 0xB4, 0x71, 0xAD, 0xE5, 0x43, 0xB2,
0xCC, 0x55, 0x93, 0x6A, 0xDB, 0x1E, 0x80, 0xDB,
0xC2, 0xEA, 0x42, 0x8E, 0xFC, 0x86, 0x44, 0xC9,
0x8A, 0xC4, 0xF2, 0x46, 0xA7, 0x39, 0x50, 0x0D,
0x1A, 0xAA, 0x07, 0x04, 0xBE, 0xD4, 0xCE, 0x62,
0x4D, 0x0F, 0x91, 0x7D, 0x29, 0x88, 0x9C, 0x4C,
0xAF, 0xF7, 0xD8, 0x40, 0x93, 0x88, 0xC7, 0x20,
0xD2, 0x17, 0x2A, 0xC4, 0x92, 0x72, 0xD0, 0xC0,
0x4E, 0x56, 0x47, 0xB1, 0x27, 0x02, 0xE6, 0x61,
0x82, 0x5E, 0xC8, 0x2E, 0x90, 0xD2, 0x31, 0x22,
0xE2, 0xA9, 0x4A, 0x91, 0x45, 0x69, 0xB1, 0xA5,
0x0F, 0x66, 0x2C, 0x30, 0xAD, 0x7F, 0x1B, 0x0E,
0x22, 0x17, 0x60, 0x2E, 0x3D, 0x7F, 0x7F, 0x8C,
0x33, 0x51, 0xA0, 0x25, 0xDE, 0xFD, 0x75, 0xBC,
0xEF, 0xE6, 0xE7, 0x20, 0x04, 0x5A, 0xEC, 0x50,
0x21, 0x48, 0x56, 0x98, 0xE2, 0x33, 0x6D, 0x22,
0x5C, 0xC3, 0xFB, 0xFC, 0x6F, 0xB3, 0xA7, 0x8E,
0x6F, 0x67, 0x70, 0x9D, 0xDA, 0x02, 0x01, 0x59,
0x7B, 0x3D, 0x2B, 0x38, 0xCC, 0x0F, 0x44, 0x3D,
0xFB, 0x9A, 0xB3, 0x23, 0x15, 0x50, 0x6E, 0xBF,
0x8B, 0xA1, 0x94, 0x33, 0xE5, 0x7B, 0x88, 0x4E,
0xCB, 0x6D, 0x9F, 0xBF, 0xBC, 0x7A, 0xA8, 0x1E,
0x68, 0x25, 0xED, 0x8E, 0x53, 0x21, 0x72, 0xC5,
0x70, 0xB3, 0xE4, 0xA6, 0xA1, 0x5A, 0x2D, 0xC8,
0x43, 0x9D, 0x60, 0x77, 0x78, 0xE0, 0xC4, 0xAF,
0xC8, 0x29, 0xBA, 0xD0, 0x4D, 0x39, 0x83, 0x51,
0xA7, 0x10, 0x7F, 0x0C, 0x34, 0x0E, 0x6C, 0x75,
0x26, 0xD7, 0xD6, 0xC7, 0x32, 0x53, 0xAF, 0x4E,
0xBE, 0xF2, 0xC2, 0x0F, 0x99, 0x23, 0xB9, 0xE1,
0xC8, 0xB4, 0xBC, 0x5A, 0xC6, 0xCB, 0xEB, 0x4D,
0x28, 0x56, 0x72, 0xFE, 0x1B, 0x2C, 0x5D, 0xE3,
0xBC, 0xC7, 0xA3, 0xC0, 0x7D, 0x27, 0xF0, 0xD0,
0x4F, 0x3F, 0x1F, 0xF7, 0x87, 0x15, 0xF2, 0xEA,
0xD4, 0x03, 0x6D, 0x2F, 0xD4, 0x8E, 0x50, 0x4B,
0x05, 0xBF, 0xF7, 0x8C, 0x67, 0x5A, 0xDC, 0x4D,
0xCD, 0xCF, 0x9D, 0x02, 0xB6, 0xE7, 0xAE, 0x49,
0xD1, 0x7C, 0x00, 0xE7, 0x3B, 0xEA, 0xFB, 0x0D,
0x2A, 0x7B, 0x41, 0x33, 0x66, 0xD0, 0x29, 0x9F,
0xB3, 0x8A, 0x71, 0xB0, 0xE2, 0x76, 0xA9, 0xDB,
0xFD, 0x64, 0x04, 0x69, 0xDF, 0x89, 0x1F, 0x56,
0x86, 0x92, 0xD9, 0xD9, 0xB9, 0xF3, 0x4F, 0xAC,
0xAE, 0x61, 0x48, 0x20, 0xCE, 0x3C, 0x2B, 0x44,
0xAB, 0x42, 0xFA, 0xAB, 0x2E, 0x94, 0x82, 0xC8,
0xD9, 0x97, 0xCF, 0x27, 0xDF, 0xAC, 0xAC, 0xE7,
0xCA, 0xB2, 0x84, 0xAB, 0xF2, 0x5D, 0xDF, 0x56,
0x0C, 0x8C, 0x07, 0x3C, 0x3D, 0xA8, 0xDD, 0xBE,
0xFF, 0x4E, 0x28, 0x0D, 0xB2, 0x2D, 0xE6, 0x9D,
0x44, 0x21, 0xCB, 0xE7, 0x33, 0x63, 0x22, 0x8F,
0x4C, 0xFF, 0xB6, 0x1D, 0x9A, 0x71, 0x3F, 0xB1,
0x29, 0xAE, 0x3A, 0x35, 0xEE, 0x9C, 0x97, 0x68,
0xA7, 0x52, 0x66, 0x01, 0xD8, 0x9A, 0x5D, 0xF4,
0xB3, 0x2F, 0x5C, 0xD4, 0x0E, 0xF9, 0xCF, 0x07,
0xF6, 0x8C, 0xBA, 0xA6, 0x8D, 0x6B, 0xC6, 0x01,
0xC2, 0x69, 0xAE, 0x60, 0x08, 0x1A, 0x0E, 0x3F,
0xAE, 0x60, 0x29, 0xF3, 0x48, 0x0D, 0xE0, 0xD0,
0xAE, 0x52, 0x44, 0xE9, 0x7F, 0x1F, 0x92, 0x5F,
0x71, 0xAD, 0xEC, 0x6B, 0x47, 0x66, 0x92, 0x22,
0x27, 0xAE, 0x6E, 0x25, 0xCD, 0xF3, 0x5F, 0x55,
0x59, 0xBD, 0x73, 0xCE, 0x2B, 0x7E, 0x99, 0x44,
0x56, 0x70, 0xA3, 0xE7, 0x7A, 0x59, 0x75, 0xD8,
0x48, 0x0C, 0x39, 0x2B, 0xD7, 0x53, 0xC6, 0xAD,
0x4A, 0x6F, 0xB4, 0x14, 0x96, 0xDF, 0xF2, 0x4A,
0x0C, 0xA2, 0xD5, 0x29, 0x98, 0x7C, 0x42, 0x87,
0xD9, 0x1F, 0x97, 0x61, 0xD9, 0xBF, 0x99, 0x4F,
0x2C, 0x4C, 0x75, 0xAC, 0xB8, 0x06, 0x75, 0xD6,
0x87, 0x76, 0x7E, 0xE3, 0x23, 0x4B, 0xEA, 0x1A,
0x1A, 0xF4, 0xB7, 0x09, 0xAF, 0x53, 0xEB, 0xA6,
0x39, 0x10, 0xFE, 0xD4, 0xEB, 0x1B, 0xAE, 0x38,
0x31, 0x33, 0xBA, 0x68, 0xEE, 0xC7, 0x65, 0x76,
0xFB, 0x49, 0x77, 0xD4, 0x19, 0xC4, 0xE6, 0xA7,
0x05, 0xFE, 0x2A, 0xDA, 0x39, 0x99, 0x1A, 0x92,
0xD2, 0xF0, 0x61, 0x97, 0xF6, 0x06, 0x6C, 0x88,
0x7B, 0x6F, 0x60, 0xE6, 0x70, 0x08, 0xF0, 0xB4,
0x6B, 0x39, 0x6F, 0x05, 0x41, 0x81, 0xF9, 0xBE,
0x7A, 0x51, 0xC4, 0x75, 0xB0, 0x6A, 0x89, 0xA0,
0xA6, 0x9A, 0x5B, 0xEE, 0x7D, 0x78, 0x17, 0x5F,
0x9F, 0x3B, 0x7D, 0xDD, 0x8A, 0x9E, 0xAA, 0x1A,
0xDA, 0x49, 0x08, 0xE9, 0xFD, 0x91, 0xA6, 0xFA,
0xCE, 0xCF, 0x67, 0xDF, 0x0F, 0xC9, 0xD6, 0x38,
0xD9, 0xD5, 0xD1, 0xC0, 0x76, 0x59, 0x42, 0x53,
0xBF, 0x48, 0xE9, 0x11, 0x74, 0xC7, 0x11, 0xD8,
0xE7, 0x8E, 0xD3, 0xC8, 0x25, 0xA1, 0x26, 0x50,
0xBB, 0xB4, 0x35, 0xAF, 0xAF, 0x06, 0x23, 0x69,
0x3E, 0x30, 0xFD, 0x7B, 0x34, 0x83, 0x07, 0xD0,
0xF0, 0x0F, 0x6C, 0x9A, 0x13, 0x5D, 0xC2, 0x7B,
0xDF, 0x6F, 0xDD, 0x8E, 0xF4, 0x30, 0x82, 0x05,
0x41, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, 0x05, 0x32,
0x04, 0x82, 0x05, 0x2E, 0x30, 0x82, 0x05, 0x2A,
0x30, 0x82, 0x05, 0x26, 0x06, 0x0B, 0x2A, 0x86,
0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01,
0x02, 0xA0, 0x82, 0x04, 0xEE, 0x30, 0x82, 0x04,
0xEA, 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48,
0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30,
0x0E, 0x04, 0x08, 0x74, 0xC0, 0x84, 0x8F, 0xC7,
0x74, 0x5E, 0x21, 0x02, 0x02, 0x08, 0x00, 0x04,
0x82, 0x04, 0xC8, 0x1E, 0xF4, 0xE9, 0x07, 0x27,
0x9E, 0x5A, 0xC9, 0x39, 0x1D, 0x37, 0x2C, 0x06,
0x4B, 0x57, 0xEA, 0xC5, 0x42, 0x9A, 0x60, 0xD5,
0x42, 0xB2, 0x34, 0x2D, 0xD3, 0x88, 0x7C, 0x78,
0x87, 0xB6, 0xE9, 0x42, 0x44, 0x1F, 0x67, 0x32,
0x92, 0x54, 0x22, 0xDA, 0xB2, 0x43, 0xE7, 0x40,
0xBE, 0x1F, 0xAF, 0x3A, 0xCD, 0x2A, 0x9F, 0xD7,
0x44, 0x5B, 0x37, 0x69, 0x85, 0xDF, 0xEB, 0x2A,
0xB9, 0xE2, 0x92, 0x3B, 0xEA, 0xD5, 0x42, 0x53,
0x95, 0x4A, 0xB0, 0x1B, 0xA5, 0xEF, 0xA6, 0x0D,
0x29, 0xF4, 0x33, 0xFE, 0xD7, 0x49, 0x04, 0x1E,
0x8C, 0xAD, 0x63, 0x1E, 0x79, 0x63, 0x74, 0x0C,
0xE5, 0x5E, 0xA2, 0x2C, 0xBE, 0xB8, 0x90, 0xCE,
0x06, 0x25, 0xBF, 0xD1, 0x5A, 0x50, 0xCF, 0x3B,
0x52, 0xE2, 0xA7, 0xFF, 0x19, 0x02, 0xCF, 0xD0,
0x9B, 0xD9, 0xF7, 0x28, 0x07, 0x38, 0x1F, 0xF2,
0xAF, 0x44, 0x91, 0x3F, 0x0F, 0xB6, 0x6E, 0x8C,
0xC0, 0x32, 0x92, 0xC0, 0xCD, 0x25, 0x98, 0x67,
0xF1, 0x47, 0x52, 0x50, 0xF0, 0xA3, 0x7B, 0xE6,
0x74, 0xDC, 0x72, 0x28, 0xC8, 0xAB, 0xB3, 0x31,
0x7D, 0xA3, 0xF7, 0xC7, 0xD1, 0xE6, 0x99, 0xB4,
0xB6, 0x5A, 0x3A, 0x4D, 0x83, 0x4F, 0xB8, 0xB5,
0x86, 0xF8, 0x37, 0x7F, 0xA0, 0x16, 0x2F, 0x3C,
0x62, 0x7A, 0xD4, 0x3A, 0xEB, 0xC2, 0xE8, 0x03,
0x49, 0x17, 0x9E, 0xFB, 0xD7, 0xAF, 0x91, 0x32,
0xFD, 0xEA, 0x4F, 0x64, 0xC6, 0x6E, 0x02, 0xEA,
0xC4, 0xC8, 0x1F, 0x16, 0xC5, 0x4C, 0xFB, 0xC5,
0x42, 0xF5, 0x85, 0x05, 0x92, 0x59, 0x4B, 0x31,
0xE5, 0xE9, 0x69, 0xE7, 0x02, 0x98, 0x33, 0xBA,
0x4C, 0x17, 0x09, 0xEF, 0x89, 0x20, 0xFA, 0x83,
0x9F, 0xAE, 0x0E, 0x1B, 0x7D, 0x98, 0xB9, 0xF2,
0x3C, 0x0F, 0xB7, 0x1C, 0x72, 0xDF, 0x17, 0x84,
0x7F, 0x0A, 0xFD, 0x12, 0x3C, 0x6F, 0x68, 0x5D,
0x45, 0xEB, 0xB8, 0xD6, 0x24, 0x65, 0x42, 0x75,
0x5C, 0xC2, 0xF3, 0x3A, 0x6A, 0x4E, 0x51, 0x34,
0x1B, 0xB6, 0x81, 0xB2, 0x8A, 0xEF, 0x28, 0xA4,
0xC5, 0x88, 0x9A, 0x97, 0xE0, 0xEF, 0x31, 0x12,
0x01, 0x7E, 0x1B, 0x43, 0x0F, 0x27, 0x80, 0x87,
0x98, 0xC5, 0xD5, 0x83, 0xCB, 0x4B, 0xB7, 0x01,
0x79, 0x60, 0xA1, 0x1A, 0x03, 0x05, 0xC6, 0x36,
0x04, 0x31, 0x3C, 0x06, 0xDB, 0x08, 0xA8, 0xDA,
0x8E, 0x32, 0x19, 0x91, 0xF1, 0x0D, 0x61, 0x6F,
0xE4, 0xB2, 0x79, 0x8A, 0xDE, 0xF4, 0xF7, 0xFB,
0x2C, 0x23, 0x5B, 0xD9, 0x64, 0x2F, 0xB7, 0xB3,
0x8B, 0xCA, 0xB8, 0x8C, 0x1D, 0x3B, 0x49, 0x05,
0x38, 0xA1, 0xE5, 0x8C, 0x1A, 0xDC, 0xA5, 0x61,
0xFE, 0xF4, 0x2B, 0xDC, 0x77, 0x28, 0xF6, 0x19,
0xE7, 0xB7, 0x8F, 0x4D, 0x27, 0x2D, 0xED, 0x8A,
0x3F, 0x3D, 0xDC, 0x9F, 0xD1, 0x30, 0xFF, 0xD6,
0xC3, 0xBE, 0x41, 0x25, 0xE3, 0xA5, 0x9B, 0x73,
0xDF, 0x6A, 0xD9, 0xF9, 0x70, 0x84, 0x02, 0x4C,
0x35, 0xD4, 0x3E, 0x05, 0x76, 0x3A, 0xDC, 0x6D,
0x5A, 0x81, 0xB3, 0x94, 0xF7, 0x22, 0xF7, 0xDC,
0xC1, 0x43, 0x31, 0x57, 0x5B, 0x42, 0x9A, 0x0B,
0xF4, 0x95, 0x30, 0xA9, 0xBB, 0xD8, 0x06, 0xFB,
0x1D, 0x6F, 0x9B, 0xC3, 0xBB, 0xF3, 0xBF, 0xFB,
0xB4, 0x9F, 0x35, 0x64, 0x0A, 0x69, 0xB7, 0xD1,
0x3E, 0xCA, 0x78, 0x07, 0x04, 0x03, 0x79, 0xD4,
0xF3, 0xA8, 0xEC, 0x18, 0xDB, 0x03, 0x5E, 0x47,
0xD7, 0xD0, 0x56, 0x2C, 0x74, 0x94, 0x86, 0x04,
0x46, 0xB8, 0xD4, 0x35, 0x0A, 0x7B, 0xE6, 0x78,
0xC4, 0x43, 0x3C, 0x56, 0xCC, 0x37, 0x8B, 0xFD,
0xE8, 0xF4, 0x57, 0xEA, 0xAE, 0xCF, 0x36, 0x97,
0x12, 0xAC, 0x39, 0xCF, 0x7C, 0xEF, 0x22, 0x67,
0x01, 0xEC, 0xD8, 0x09, 0x49, 0x4E, 0xE3, 0x74,
0xDD, 0x39, 0xE1, 0x39, 0xD7, 0x0C, 0x5F, 0x1B,
0xCE, 0x69, 0xBC, 0x72, 0x44, 0x87, 0x64, 0x1C,
0x08, 0x05, 0x93, 0x69, 0x6D, 0x7F, 0x90, 0x0A,
0x2C, 0xCB, 0x8A, 0xBB, 0x7F, 0xE3, 0xE0, 0x80,
0x31, 0xD0, 0x0A, 0x3A, 0x95, 0xFF, 0xF7, 0xB4,
0x36, 0x38, 0x93, 0xE0, 0x0C, 0x11, 0x37, 0x12,
0x06, 0xF6, 0xAD, 0xE9, 0xB1, 0x7A, 0x00, 0xF5,
0xD2, 0x32, 0x6B, 0xD0, 0x27, 0xA5, 0x1B, 0x3D,
0xE8, 0xDB, 0xCC, 0xA9, 0x1F, 0x1F, 0xB1, 0x99,
0x3D, 0x7C, 0xB7, 0xCA, 0xDA, 0x27, 0x2C, 0x64,
0x1C, 0x49, 0xB6, 0x87, 0x44, 0x06, 0x94, 0x9D,
0xBC, 0x6B, 0x20, 0xA2, 0x68, 0x15, 0x1F, 0xE2,
0xF2, 0xAD, 0x6D, 0x23, 0x2E, 0x2B, 0x74, 0xE2,
0x5D, 0xE4, 0xB0, 0xC7, 0x84, 0xCB, 0x64, 0xBF,
0xE0, 0xA8, 0x18, 0x83, 0xB4, 0xC9, 0xD9, 0x73,
0xA8, 0xE6, 0xA9, 0x36, 0xD5, 0x63, 0x1E, 0x2C,
0x2A, 0x55, 0x09, 0x77, 0x5E, 0xB3, 0x4B, 0xEA,
0xB5, 0xD0, 0x14, 0x5F, 0xEB, 0x50, 0x7B, 0xAA,
0xEF, 0x94, 0xBA, 0x2B, 0xD7, 0x8A, 0x07, 0xF1,
0xF9, 0x5E, 0x12, 0x12, 0x21, 0x52, 0xE5, 0x0A,
0x3E, 0xC0, 0xBC, 0x5D, 0x4C, 0xE2, 0x12, 0x7C,
0x39, 0xF9, 0x16, 0x9D, 0xBD, 0x96, 0x83, 0x3B,
0x7F, 0x3D, 0x6A, 0xEC, 0xF1, 0x25, 0xD2, 0xB0,
0xB0, 0xEB, 0x20, 0x06, 0x07, 0xD6, 0xD9, 0x4C,
0x07, 0x9A, 0x82, 0xC1, 0xFC, 0xF7, 0x66, 0x15,
0xBD, 0x62, 0x65, 0xD8, 0x6C, 0xF6, 0x33, 0x7B,
0x5A, 0x28, 0xEC, 0x90, 0xA1, 0x26, 0x9F, 0xC3,
0x28, 0x4A, 0x64, 0x50, 0x5F, 0xCA, 0xE2, 0x6D,
0xB8, 0x0F, 0xE2, 0x94, 0xB5, 0x8E, 0x1F, 0x8A,
0x8F, 0x6B, 0xA6, 0x86, 0x1F, 0xEE, 0xDC, 0x24,
0xB4, 0xB8, 0x25, 0xEC, 0x28, 0x2D, 0xF9, 0xCB,
0x7D, 0x38, 0xFF, 0xC7, 0x74, 0x2E, 0xD3, 0x10,
0xEC, 0x03, 0x31, 0xEE, 0x83, 0xE7, 0xA4, 0xF7,
0xBA, 0x28, 0x21, 0xE0, 0x7F, 0xB4, 0xB7, 0xE1,
0x7A, 0xF9, 0x2B, 0xB0, 0x2C, 0x3B, 0x80, 0x5F,
0xE0, 0x5D, 0xB2, 0x7E, 0x59, 0xFF, 0x59, 0x07,
0x58, 0x42, 0x57, 0xEE, 0x44, 0xF1, 0xB1, 0xAD,
0xBA, 0xDE, 0xCB, 0x1D, 0x8A, 0x36, 0x67, 0xE8,
0x45, 0xFF, 0x07, 0x8D, 0xEE, 0xA4, 0x51, 0x9C,
0x4C, 0x83, 0x5D, 0x2E, 0x2F, 0xE1, 0x5B, 0x75,
0xE8, 0x29, 0xCD, 0x0B, 0x07, 0x62, 0xE0, 0xC3,
0x0D, 0x1D, 0xEA, 0xCF, 0xF0, 0x8A, 0x65, 0x27,
0x70, 0x42, 0x9F, 0x26, 0x00, 0x15, 0x70, 0xC5,
0x4A, 0xF6, 0x25, 0xD0, 0x40, 0x72, 0xE9, 0xC1,
0x73, 0xFD, 0x48, 0x94, 0xA3, 0x8D, 0x66, 0x63,
0x96, 0x4F, 0xF7, 0xEE, 0xFB, 0x4C, 0xC7, 0xB8,
0x6B, 0xE9, 0x90, 0xE1, 0x2A, 0x66, 0x80, 0x99,
0x3B, 0xB0, 0x1A, 0x6C, 0xF9, 0x0E, 0x72, 0xDA,
0x8E, 0x4F, 0x46, 0xC2, 0x6A, 0x4B, 0x7A, 0x16,
0xE5, 0x26, 0x0B, 0x5C, 0xD4, 0x47, 0x34, 0xE5,
0x37, 0xBE, 0x68, 0x6C, 0xDA, 0xD3, 0x9B, 0x6F,
0xAE, 0x51, 0x9C, 0x99, 0x0A, 0x5B, 0xF8, 0x37,
0xBC, 0xDE, 0xFC, 0x93, 0xC5, 0xE7, 0x0F, 0xEF,
0x0B, 0xA6, 0x07, 0xC2, 0xA6, 0xE6, 0xDA, 0x2D,
0x1B, 0x49, 0xC9, 0xDE, 0x6B, 0x27, 0xDC, 0x00,
0xEF, 0x23, 0x87, 0x0E, 0xEB, 0xD1, 0x48, 0x7D,
0xB4, 0xF2, 0x58, 0xC6, 0x3C, 0xE2, 0x89, 0xBA,
0xB0, 0x05, 0xAC, 0x94, 0x41, 0x9A, 0xA8, 0xFF,
0x3E, 0xBC, 0x3A, 0x52, 0x9C, 0xF9, 0x7F, 0x07,
0x8B, 0xB0, 0x2C, 0x71, 0x83, 0x7B, 0xCF, 0x2E,
0x7F, 0x7C, 0x96, 0x65, 0xD9, 0x08, 0x17, 0xEC,
0xFA, 0xDE, 0x4E, 0x40, 0x12, 0x26, 0x70, 0x71,
0x65, 0xA5, 0xDC, 0x98, 0x47, 0xA3, 0xFC, 0xE0,
0x9A, 0x16, 0xED, 0x45, 0x56, 0x72, 0x50, 0x05,
0x28, 0x2C, 0x99, 0xEC, 0x20, 0x2E, 0x40, 0xC0,
0x26, 0x69, 0xCD, 0x49, 0x45, 0x17, 0xA4, 0xA3,
0x42, 0x0D, 0x14, 0x65, 0x87, 0x33, 0x8C, 0x92,
0xC5, 0xC4, 0x61, 0xFD, 0xE8, 0x68, 0x56, 0x20,
0x57, 0xF5, 0x8E, 0x5F, 0xCF, 0x7E, 0x97, 0xF6,
0x49, 0x97, 0x0A, 0xFE, 0xD3, 0x60, 0x1A, 0x5B,
0x0C, 0x75, 0xDD, 0x8E, 0x31, 0x78, 0x29, 0xA6,
0xB1, 0x4D, 0xAA, 0xDF, 0x8A, 0xD1, 0xE6, 0x91,
0xE3, 0x32, 0x3F, 0xEC, 0x8A, 0x1F, 0x0E, 0x35,
0x07, 0x6E, 0x4B, 0x83, 0x3B, 0xE5, 0x67, 0x34,
0x1F, 0x0C, 0x81, 0xD8, 0xD5, 0x25, 0x68, 0xE5,
0x28, 0x1B, 0x5C, 0x81, 0x3E, 0xE3, 0x5C, 0xB4,
0xB6, 0xBD, 0x62, 0x6A, 0x70, 0x33, 0xC2, 0xC5,
0x75, 0x27, 0xF4, 0x30, 0xE1, 0x1D, 0xC1, 0x4C,
0xC5, 0x02, 0x12, 0x46, 0xAC, 0xEC, 0xF9, 0xE8,
0xE7, 0x58, 0x24, 0x11, 0xB1, 0xF3, 0xB7, 0x8C,
0x3C, 0xA4, 0x0A, 0x94, 0xA6, 0x7C, 0x68, 0x54,
0x5B, 0xB9, 0x4D, 0x57, 0x9C, 0xE7, 0x28, 0x09,
0x6B, 0x89, 0x26, 0x5D, 0xE7, 0x50, 0xA9, 0x95,
0x90, 0x91, 0x8E, 0x00, 0x59, 0xF8, 0x3A, 0x70,
0xAF, 0x48, 0x2E, 0xE8, 0xC4, 0x34, 0x8C, 0xF4,
0x5F, 0x7F, 0xCB, 0x07, 0xAA, 0xF0, 0xD9, 0xFB,
0x5C, 0x32, 0x90, 0x22, 0x1A, 0xD2, 0x1A, 0xCF,
0x92, 0x06, 0x02, 0xCF, 0x10, 0x18, 0x7B, 0x93,
0xCC, 0x07, 0x4A, 0x31, 0x25, 0x30, 0x23, 0x06,
0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xD1, 0xDE,
0x23, 0x16, 0x9F, 0x6E, 0xF4, 0x42, 0x21, 0x23,
0xE1, 0x11, 0xAA, 0xC8, 0x7C, 0x60, 0x4A, 0x78,
0x9D, 0x24, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09,
0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05,
0x00, 0x04, 0x14, 0xD6, 0x4A, 0xBB, 0x75, 0xB1,
0xF9, 0x9E, 0xD3, 0x58, 0x6D, 0xD1, 0x74, 0x9F,
0x00, 0x8A, 0xF2, 0xC8, 0xAA, 0x52, 0x4D, 0x04,
0x08, 0x77, 0x46, 0xE7, 0xBA, 0x25, 0x4B, 0xDA,
0x41, 0x02, 0x02, 0x08, 0x00]
};
const WPA_EAP_CLIENT_LIST = [
{
ssid: 'WPA-EAP-TLS',
keyManagement: 'WPA-EAP',
eap: 'TLS',
identity: EAP_USERNAME,
serverCertificate: CLIENT_PKCS12_CERT.nickname,
userCertificate: CLIENT_PKCS12_CERT.nickname
}
];
/**
* Convert the given MozWifiNetwork object array to testAssociate chain.
*
* @param aNetworks
* An array of MozWifiNetwork which we want to convert.
*
* @return A promise chain which "then"s testAssociate accordingly.
*/
function convertToTestAssociateChain(aNetworks) {
let chain = Promise.resolve();
aNetworks.forEach(function (aNetwork) {
network = new window.MozWifiNetwork(aNetwork);
chain = chain.then(() => gTestSuite.testAssociate(network));
});
return chain;
}
gTestSuite.doTestWithCertificate(
new Blob([new Uint8Array(CLIENT_PKCS12_CERT.content)]),
CLIENT_PKCS12_CERT.password,
CLIENT_PKCS12_CERT.nickname,
CLIENT_PKCS12_CERT.usage,
function() {
return gTestSuite.ensureWifiEnabled(true)
// Load required server files.
.then(() => gTestSuite.writeFile(SERVER_EAP_USER_CONF.path, SERVER_EAP_USER_CONF.content))
.then(() => gTestSuite.writeFile(CA_CERT.path, CA_CERT.content))
.then(() => gTestSuite.writeFile(SERVER_CERT.path, SERVER_CERT.content))
.then(() => gTestSuite.writeFile(SERVER_KEY.path, SERVER_KEY.content))
// Start AP.
.then(() => gTestSuite.startHostapds(WPA_EAP_AP_LIST))
// Scan test.
.then(() => gTestSuite.testWifiScanWithRetry(SCAN_RETRY_CNT, WPA_EAP_AP_LIST))
// Associate test.
.then(() => convertToTestAssociateChain(WPA_EAP_CLIENT_LIST))
// Tear down.
.then(gTestSuite.killAllHostapd)
});
@@ -0,0 +1,623 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
const SCAN_RETRY_CNT = 5;
const EAP_USERNAME = 'username';
const EAP_PASSWORD = 'password';
const SERVER_EAP_USER_CONF = {
path: HOSTAPD_CONFIG_PATH + 'hostapd.eap_user',
content: '* PEAP,TTLS,TLS\n' +
'"' + EAP_USERNAME + '" MSCHAPV2,TTLS-MSCHAPV2 "' + EAP_PASSWORD + '" [2]\n'
};
const CA_CERT = {
path: HOSTAPD_CONFIG_PATH + 'ca.pem',
content: '-----BEGIN CERTIFICATE-----\n' +
'MIIDsTCCApmgAwIBAgIJAKxTf+8X8qngMA0GCSqGSIb3DQEBCwUAMG4xCzAJBgNV\n' +
'BAYTAlRXMRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhjaHVja2xlZTER\n' +
'MA8GA1UEAwwIY2h1Y2tsZWUxJDAiBgkqhkiG9w0BCQEWFWNodWNrbGkwNzA2QGdt\n' +
'YWlsLmNvbTAgFw0xNDEyMjQxMTI4NTBaGA8yMjg4MTAwNzExMjg1MFowbjELMAkG\n' +
'A1UEBhMCVFcxEzARBgNVBAgMClNvbWUtU3RhdGUxETAPBgNVBAoMCGNodWNrbGVl\n' +
'MREwDwYDVQQDDAhjaHVja2xlZTEkMCIGCSqGSIb3DQEJARYVY2h1Y2tsaTA3MDZA\n' +
'Z21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo3c2yFxY\n' +
'o6gGg0I83jy00ME+MAfzCd+4ShL45ZLqysQP93jRBfPzU9ZuZ29ysVwgWIdqkZao\n' +
'XTuV/NAW2GMGd8W1jQJ3J81fjb9wvhlny3rrACwvUn1N1S1BnM+BAAiDLGxEmvAQ\n' +
'onp2aaa6HsHsYS8ONX+d2Qh4LEA4vupeSGAqJychCZv/l+aq/ErFZhFYB3CPUQEt\n' +
'cClO24ucsIYP95lA0zhscnmAj06qplFD4Bv6IVrdDqujy1zNwCQwsJq/8OQdaTN/\n' +
'h3y9pWvNKMBMM2niOUAjtuNpqsSK/lTS1WAT3PdtVECX9fYBi0Bg+HM92xs/6gt6\n' +
'kh9jPV8keXHvSwIDAQABo1AwTjAdBgNVHQ4EFgQU7hBqhuG04xeCzrQ3ngx18ZJ3\n' +
'lUswHwYDVR0jBBgwFoAU7hBqhuG04xeCzrQ3ngx18ZJ3lUswDAYDVR0TBAUwAwEB\n' +
'/zANBgkqhkiG9w0BAQsFAAOCAQEAFYX2iy680GAnBTttk0gyX6gk+8pYr3D22k/G\n' +
'6rvcjefzS7ELQPRKr6mfmwXq3mMf/4jiS2zI5zmXsestPYzHYxf2viQ6t7vr9XiJ\n' +
'3WfFjNw4ERlRisAvg0aqqTNNQq5v2VME4sdFZagy217f73C7azwCHl0bqOLH05rl\n' +
'8RubOxiHEj7ZybJqnRciK/bht4D+rZkwf4bBBmoloqH7xT0+rFQclpYXDGGjNUQB\n' +
'LcHLF10xcr7g3ZVVu82fe6+d85gIGOIMR9+TKhdw6gO3CNcnDAj6gxksghgtcxmh\n' +
'OzOggCn7nlIwImtsg2sZkpWB4lEi9hdv4lkNuyFjOL3bnuc+NA==\n' +
'-----END CERTIFICATE-----\n'
};
const SERVER_CERT = {
path: HOSTAPD_CONFIG_PATH + 'server.pem',
content: '-----BEGIN CERTIFICATE-----\n' +
'MIID1DCCArygAwIBAgIBADANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJUVzET\n' +
'MBEGA1UECAwKU29tZS1TdGF0ZTERMA8GA1UECgwIY2h1Y2tsZWUxETAPBgNVBAMM\n' +
'CGNodWNrbGVlMSQwIgYJKoZIhvcNAQkBFhVjaHVja2xpMDcwNkBnbWFpbC5jb20w\n' +
'IBcNMTQxMjI0MTEyOTQ5WhgPMjI4ODEwMDcxMTI5NDlaMG4xCzAJBgNVBAYTAlRX\n' +
'MRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQKDAhjaHVja2xlZTERMA8GA1UE\n' +
'AwwIY2h1Y2tsZWUxJDAiBgkqhkiG9w0BCQEWFWNodWNrbGkwNzA2QGdtYWlsLmNv\n' +
'bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMdhQmKilTJbWZRxTiSV\n' +
'rqIU+LYW1RKghx5o+0JpNRJVLuz5kBMaNskbbfUSNuHbEq0QA9BDKAZWIc4LSotk\n' +
'lCo8TbcO9CJvJPQGGjGdHcohWX5vy6BE/OVE46CUteMFyZF6F8R2fNUww08iR/u1\n' +
'YZebL5pWO1j43sPpAzEy6Tij2ACPt6EZcFaZG3SF2mVJWkCQnBqrojP65WUvZQqp\n' +
'seUhW2YAS8Nu0Yrohgxz6VYk+cNDuDZVGs6qWRStZzJfYrfc76DtkHof5B14M+xp\n' +
'XJaBLxN+whvnYkDTfinaCxnW1O7eXUltr87fLc5zmeBkgwaiaQuIdcfZm7vDUiz8\n' +
'vnUCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH\n' +
'ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFKK4f9/YavTHOfEiAB83Deac\n' +
'6gT5MB8GA1UdIwQYMBaAFO4QaobhtOMXgs60N54MdfGSd5VLMA0GCSqGSIb3DQEB\n' +
'CwUAA4IBAQBWnO9o9KSJIqjoz5Nwll63ULOdcvgGdOeJIw1fcKQ817Rsp+TVcjcH\n' +
'IrIADsT/QZGXRO/l6p1750e2iFtJEo1hsRaxtA1wWn2I9HO3+av2spQhr3jpYGPf\n' +
'zpsMTp4RNYV7Q8+q1kZIz9PY4V1T0p6lveK8+fUj2hSLnxSj0QiGSJJtnEC3w4Rv\n' +
'C9T6oUwIeToULmi+8FXQFdEqwKRU98DPq3eLzN28ZxUgoPE1C8+42D2UW8uyp/Gm\n' +
'tGOa/k7nzkCdVqZI7lX7f0AjEvQgjtAMQ/k7Mhxx7TzW2HO+1YPMoKji6Z4WkNwt\n' +
'JEj9ZUBSNt8B26UksJMBDkcvSegF3a7o\n' +
'-----END CERTIFICATE-----\n'
};
const SERVER_KEY = {
path: HOSTAPD_CONFIG_PATH + 'server.key',
content: '-----BEGIN RSA PRIVATE KEY-----\n' +
'MIIEpAIBAAKCAQEAx2FCYqKVMltZlHFOJJWuohT4thbVEqCHHmj7Qmk1ElUu7PmQ\n' +
'Exo2yRtt9RI24dsSrRAD0EMoBlYhzgtKi2SUKjxNtw70Im8k9AYaMZ0dyiFZfm/L\n' +
'oET85UTjoJS14wXJkXoXxHZ81TDDTyJH+7Vhl5svmlY7WPjew+kDMTLpOKPYAI+3\n' +
'oRlwVpkbdIXaZUlaQJCcGquiM/rlZS9lCqmx5SFbZgBLw27RiuiGDHPpViT5w0O4\n' +
'NlUazqpZFK1nMl9it9zvoO2Qeh/kHXgz7GlcloEvE37CG+diQNN+KdoLGdbU7t5d\n' +
'SW2vzt8tznOZ4GSDBqJpC4h1x9mbu8NSLPy+dQIDAQABAoIBAASG4Mr8hgaurEoC\n' +
'iJOsElr7vunjetMBcg/uskW/vcS8ymP3Bp5oafYG+WgnEbfvEW18f5mq7K24JuxW\n' +
'tUqU7ghHdjxByqk9fMlNmiqmNpbwSufkAeuRpWxPNBvhRH/zEbCL5R5A0nTEtqqF\n' +
'TL0aUSzwCRSoAJD0lZo9ICVt0n3GsDyM9rqQg/uZmh1qsRdwPsRuYORND9g48rKq\n' +
'6WN9leskSxhhsYE2D9ocOFd9bNt8Zxejh9ppVSnG/KsIdt18iBzcabatgAQ046fb\n' +
'Z3vprcZJLg93Sg2gSuVqlSTs3M2W8VQnm22/EBMb1y0M48MSRCgnbPLG/CcCLLfF\n' +
'LwxCOgECgYEA/eYt67xyJ6JeAdxdwOZuT1WWGbFpLiG9+2OgiHumyRQ5969XMTWo\n' +
'fIhMKchDdjoy9RR236\/\/EFCs7UEyB7+a7ODRzNiK2zCD8Smjp+21fUPSthEeQesk\n' +
'eiMYICIu5Ay35x9sxIX+XOUVvRhPOGcD29GVeRnKh1inTHOz2dje8LkCgYEAyQeY\n' +
'STi9jjCEcHkM1E/UeDiLfHHepLXi8wS41JNRHl5Jacp7XB5djAjKu/jf367/VpFy\n' +
'GDDMetE7n8eWkrnAvovxOwZ000YDMtL1sUYSjL+XtBS5s6VY1p4qaSAY9nUUGrJh\n' +
'JvtvsuI7SKTtL+60vjBOH7zDnvOdBgAp0utLhZ0CgYEAuLzzqrPKB8afShFSchn4\n' +
'J2dpuLYahsNsXW7HDqeR2nsKFosRETAusLXnXPtnAq4kB6jlOarwFqnsuRCX24Vx\n' +
'r2uBm9/vYL7zMdUPTA+s30ErHuhjsKjsOKYyVqcooSwT32pBFNk+E89nutfmRG7I\n' +
'IvhjHuNCNqqtx/Xj5d1jkZkCgYBQicppC2Jl5OoqZVTOem0U/RJk+PnJ41TZJ7sk\n' +
'7yBAmmWvDH\/\/l+rCf4M5a6vFYcbKV9rt9h711X2dtciNX/3oWQh8LUoAmrwNUJc+\n' +
'PmSQHvIYI3WCk2vUD+nN1B4sHxu+1lg11eYaNKiroeeknG2tBI1ICcgVlmQCU25u\n' +
'IfZPwQKBgQCdO6QHhPLtcHUDNFA6FQ1jKL1iEd7G0JLVRz4Xkpkn1Vrr5MD6JFDa\n' +
'5ccabADyl0lpFqDIVJQIzLku2hOD2i9aBNCY0pL391HeOS7CkZX+TdOY1tquoBq5\n' +
'MnmixZjDCVd2VcrVyTA6ntOBoharKFW0rH1PqU+qu7dZF7CBPbAdEw==\n' +
'-----END RSA PRIVATE KEY-----\n'
};
const WPA_EAP_AP_LIST = [
{
ssid: 'WPA-EAP-TTLS',
ieee8021x: 1,
eapol_version: 1,
eap_server: 1,
eapol_key_index_workaround: 0,
eap_user_file: SERVER_EAP_USER_CONF.path,
ca_cert: CA_CERT.path,
server_cert: SERVER_CERT.path,
private_key: SERVER_KEY.path,
wpa: 3,
wpa_key_mgmt: 'WPA-EAP'
}
];
const CLIENT_PKCS12_CERT = {
nickname: 'client',
password: 'password',
usage: ['UserCert', 'ServerCert'],
content: [0x30, 0x82, 0x0E, 0x01, 0x02, 0x01, 0x03, 0x30,
0x82, 0x0D, 0xC7, 0x06, 0x09, 0x2A, 0x86, 0x48,
0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82,
0x0D, 0xB8, 0x04, 0x82, 0x0D, 0xB4, 0x30, 0x82,
0x0D, 0xB0, 0x30, 0x82, 0x08, 0x67, 0x06, 0x09,
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07,
0x06, 0xA0, 0x82, 0x08, 0x58, 0x30, 0x82, 0x08,
0x54, 0x02, 0x01, 0x00, 0x30, 0x82, 0x08, 0x4D,
0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
0x01, 0x07, 0x01, 0x30, 0x1C, 0x06, 0x0A, 0x2A,
0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01,
0x06, 0x30, 0x0E, 0x04, 0x08, 0x67, 0x7A, 0xF3,
0x61, 0xBE, 0xE0, 0x51, 0xC1, 0x02, 0x02, 0x08,
0x00, 0x80, 0x82, 0x08, 0x20, 0xFC, 0x6A, 0x79,
0xA1, 0x6C, 0xAF, 0xBE, 0xEE, 0x62, 0x45, 0x33,
0xB8, 0x48, 0xE1, 0x68, 0xA1, 0x15, 0x11, 0x4B,
0x95, 0xCB, 0x77, 0xC0, 0x5D, 0xA2, 0xCB, 0xDB,
0xD1, 0x83, 0x74, 0x60, 0xD7, 0xEC, 0x42, 0xA6,
0x3A, 0x23, 0xF7, 0x85, 0xEB, 0xC1, 0xFE, 0x6A,
0x57, 0x8E, 0xC1, 0x44, 0xF3, 0x1F, 0xFE, 0xB8,
0x2D, 0x8C, 0x4D, 0xC9, 0x5B, 0xAE, 0x21, 0x2E,
0x4C, 0x1A, 0xEB, 0x84, 0x09, 0xF3, 0x40, 0x92,
0x39, 0x7F, 0x56, 0x02, 0x46, 0x61, 0x16, 0xDE,
0x5C, 0x48, 0xB6, 0x0C, 0x1D, 0xD3, 0x5F, 0x10,
0x9A, 0x39, 0xB8, 0x66, 0x31, 0xFC, 0x39, 0x71,
0x87, 0x23, 0x46, 0x9D, 0xE8, 0x3C, 0x2B, 0xA1,
0x39, 0x8A, 0xD3, 0xFF, 0xD9, 0x43, 0xB6, 0x61,
0xC6, 0x67, 0x70, 0x40, 0xBD, 0xFE, 0xD3, 0xC1,
0x68, 0xF5, 0xF7, 0xC8, 0x89, 0xD8, 0x17, 0xC5,
0xE8, 0x3D, 0x29, 0xD5, 0x91, 0xDF, 0x1F, 0x56,
0x74, 0x5A, 0xC4, 0xA8, 0x14, 0xBA, 0xD4, 0xFA,
0x13, 0x49, 0x2A, 0x9F, 0x63, 0xF1, 0xB2, 0x45,
0xF1, 0xF0, 0x2A, 0xDD, 0x75, 0x66, 0x8A, 0xF7,
0xAB, 0x73, 0x86, 0x26, 0x9D, 0x1F, 0x07, 0xAD,
0xD3, 0xFE, 0xE0, 0xA3, 0xED, 0xA0, 0x96, 0x3E,
0x1E, 0x89, 0x86, 0x02, 0x4C, 0x28, 0xFD, 0x57,
0xA1, 0x67, 0x55, 0xF0, 0x82, 0x3B, 0x7F, 0xCC,
0x2A, 0x32, 0x01, 0x93, 0x1D, 0x8B, 0x66, 0x8A,
0x20, 0x52, 0x84, 0xDD, 0x2C, 0xFD, 0xEE, 0x72,
0xF3, 0x8C, 0x58, 0xB9, 0x99, 0xE5, 0xC1, 0x22,
0x63, 0x59, 0x00, 0xE2, 0x76, 0xC5, 0x3A, 0x17,
0x7F, 0x93, 0xE9, 0x67, 0x61, 0xAA, 0x10, 0xC3,
0xD9, 0xC8, 0x24, 0x46, 0x5B, 0xBE, 0x8C, 0x1F,
0x2D, 0x66, 0x48, 0xD2, 0x02, 0x11, 0xFB, 0x74,
0x14, 0x76, 0x76, 0x5A, 0x98, 0x54, 0x35, 0xA7,
0x85, 0x66, 0x20, 0x26, 0x8B, 0x13, 0x6F, 0x68,
0xE3, 0xC9, 0x58, 0x7D, 0x1C, 0x3E, 0x01, 0x8D,
0xF8, 0xD6, 0x7F, 0xCF, 0xA2, 0x07, 0xB7, 0x95,
0xFD, 0xF0, 0x02, 0x34, 0x32, 0x30, 0xE8, 0xD4,
0x57, 0x5E, 0x53, 0xFB, 0x54, 0xE2, 0x03, 0x32,
0xCC, 0x52, 0x2E, 0xD2, 0x35, 0xD9, 0x58, 0x85,
0x2D, 0xEC, 0x2D, 0x71, 0xD1, 0x8A, 0x29, 0xD0,
0xB0, 0x24, 0xBD, 0x24, 0xDC, 0x1A, 0x28, 0x3F,
0xA0, 0x12, 0x81, 0x15, 0x24, 0xC9, 0xB5, 0x4A,
0x23, 0xB6, 0xA3, 0x45, 0x50, 0x2D, 0x73, 0x99,
0x6B, 0x1C, 0xFB, 0xA4, 0x53, 0xD7, 0x5C, 0xF4,
0x6C, 0xB0, 0xE5, 0x74, 0xB3, 0x76, 0xF8, 0xB1,
0x0D, 0x59, 0x70, 0x9F, 0xCA, 0xDE, 0xF2, 0xAA,
0x4C, 0x7D, 0x11, 0x54, 0xC4, 0x19, 0x0F, 0x36,
0x4A, 0x62, 0xFF, 0x8B, 0x10, 0xCB, 0x93, 0x50,
0xDA, 0x79, 0x5E, 0x4E, 0x09, 0x1F, 0x22, 0xC8,
0x19, 0x85, 0xE9, 0xEE, 0xB7, 0x71, 0x65, 0xB9,
0x10, 0xD2, 0x0A, 0x73, 0x5B, 0xA6, 0xDA, 0x37,
0x46, 0x02, 0x00, 0x98, 0x9E, 0x20, 0x6C, 0x7D,
0xC7, 0x69, 0xBB, 0xC2, 0x00, 0x40, 0x9C, 0x57,
0x00, 0xC2, 0x36, 0x76, 0xE8, 0x2A, 0x8D, 0xAD,
0x62, 0x57, 0xC8, 0xD0, 0x9D, 0x66, 0x27, 0x5A,
0xD8, 0x0D, 0x35, 0x60, 0x28, 0x38, 0x62, 0x94,
0x78, 0x36, 0x25, 0x58, 0xFD, 0xF8, 0x66, 0x1F,
0x68, 0x04, 0x0F, 0xD8, 0x00, 0xDF, 0xA0, 0x6C,
0x25, 0x42, 0x9A, 0x4C, 0xEB, 0x80, 0x13, 0x51,
0x7D, 0x2D, 0xA8, 0x89, 0xD6, 0x1B, 0x67, 0x72,
0x01, 0xF3, 0x2D, 0x16, 0x77, 0xFE, 0x22, 0xBC,
0x8A, 0x45, 0x09, 0x1F, 0x9C, 0x2F, 0x2A, 0xA9,
0x61, 0x5B, 0x4A, 0xE6, 0x64, 0x2C, 0x62, 0x1A,
0x3A, 0x96, 0xE6, 0x0A, 0xAE, 0x05, 0x1A, 0xC8,
0xCB, 0xD6, 0x8F, 0x3A, 0x4B, 0xE0, 0x7F, 0x82,
0xB4, 0x98, 0xF1, 0x9D, 0xD7, 0x14, 0x76, 0x5E,
0x77, 0x85, 0x87, 0xEC, 0x13, 0xDA, 0xFD, 0xAF,
0xCB, 0xA3, 0x1C, 0x99, 0xC1, 0xFE, 0x17, 0x0C,
0x40, 0x4D, 0x3C, 0x8F, 0x70, 0x86, 0x63, 0x64,
0xB7, 0x75, 0xA8, 0x71, 0x36, 0xDC, 0x54, 0x10,
0x57, 0x0C, 0xA8, 0xF2, 0xA1, 0xBB, 0xED, 0x03,
0x41, 0x57, 0x34, 0x2C, 0x8F, 0x7C, 0xA0, 0x09,
0xF3, 0x9E, 0x41, 0xB7, 0xA8, 0xD4, 0x66, 0x0D,
0x0D, 0xC0, 0x6A, 0xFC, 0x6A, 0xA2, 0xAC, 0xE2,
0x60, 0x00, 0xE3, 0xF7, 0x75, 0x43, 0x23, 0xEB,
0xC8, 0x61, 0xFA, 0xB3, 0xB8, 0x28, 0xCE, 0xCA,
0xF4, 0x47, 0x7F, 0x30, 0x6D, 0x61, 0x89, 0x47,
0xA1, 0x4A, 0xFE, 0xD1, 0x21, 0x0B, 0x6D, 0xF4,
0x3F, 0x00, 0x86, 0x30, 0x8E, 0x33, 0x21, 0x6F,
0xDA, 0x15, 0xFD, 0x5F, 0xEC, 0x8E, 0xF1, 0x12,
0x3F, 0xC9, 0x83, 0x0C, 0xCA, 0x22, 0x01, 0xF1,
0x70, 0x5F, 0x1F, 0x66, 0xB5, 0xF8, 0x3E, 0x7A,
0x6F, 0xDE, 0xDB, 0xA7, 0x8D, 0x18, 0x9E, 0xBE,
0xDB, 0xAD, 0x3D, 0x66, 0x30, 0xC1, 0x6C, 0x0C,
0x87, 0xB4, 0x65, 0x75, 0xE0, 0x9D, 0xEA, 0x16,
0x0D, 0x07, 0x37, 0x33, 0xC5, 0xEC, 0x97, 0x93,
0x37, 0xEB, 0x8E, 0x65, 0x9C, 0x40, 0x63, 0x6C,
0x43, 0x60, 0xB0, 0x40, 0x4D, 0x85, 0xEF, 0xC2,
0x47, 0x5F, 0xE7, 0x6B, 0xCB, 0x40, 0xE8, 0xEA,
0xD8, 0xAB, 0xB1, 0x9A, 0x72, 0xDC, 0x4C, 0x14,
0xFA, 0x43, 0x61, 0x5F, 0xA6, 0x5C, 0x3A, 0x05,
0x17, 0x2E, 0x74, 0xF3, 0x5E, 0x45, 0xD9, 0x47,
0xAA, 0x59, 0xB6, 0x8F, 0x42, 0x66, 0x42, 0x29,
0x90, 0x95, 0x48, 0x46, 0x91, 0x88, 0x3C, 0x8C,
0xDE, 0xCC, 0xED, 0xB3, 0xAA, 0x62, 0xEA, 0xBC,
0xB4, 0x0C, 0x48, 0x4C, 0x53, 0x23, 0x5E, 0x24,
0x85, 0xBF, 0x92, 0xDA, 0x14, 0xDB, 0x1A, 0x3D,
0xEF, 0x30, 0xD9, 0x49, 0x64, 0x4D, 0xE5, 0x01,
0xFC, 0xA4, 0x4B, 0xD1, 0x9F, 0xDE, 0x96, 0x7F,
0x50, 0xBC, 0x4D, 0x38, 0x44, 0xE9, 0x23, 0x5F,
0x37, 0x57, 0x1A, 0xA6, 0x52, 0x5A, 0x0F, 0x4F,
0x87, 0x33, 0x4A, 0x7B, 0x66, 0xEE, 0x3D, 0x66,
0x0A, 0x63, 0x39, 0x1F, 0x23, 0x38, 0x35, 0x73,
0x60, 0x5E, 0x47, 0x20, 0x4F, 0xC0, 0xC8, 0x3C,
0x09, 0xF9, 0x29, 0x4F, 0x5E, 0x55, 0x69, 0xC4,
0x6B, 0xE8, 0xF8, 0x91, 0xC0, 0x22, 0x65, 0x15,
0x1E, 0xFB, 0xB9, 0x61, 0xCE, 0x45, 0xBE, 0x2B,
0xEE, 0xB9, 0x04, 0x2B, 0xFD, 0xAE, 0x61, 0x1C,
0x3D, 0x3D, 0x7C, 0xBF, 0xC1, 0xF7, 0x3C, 0x4E,
0x9E, 0x0E, 0x54, 0xC8, 0xAD, 0xA9, 0xDF, 0x43,
0x49, 0xB9, 0x41, 0x05, 0xE5, 0xF1, 0x49, 0xAA,
0x77, 0x6C, 0x34, 0x5B, 0x93, 0x24, 0x24, 0x23,
0x74, 0x68, 0x11, 0xCE, 0x15, 0x80, 0xA1, 0xA4,
0x1F, 0x8D, 0x81, 0xCD, 0xB2, 0x98, 0xCA, 0x14,
0x0B, 0x0C, 0x61, 0x50, 0x69, 0x72, 0xAE, 0xFA,
0x8B, 0xC0, 0x3F, 0x0D, 0xE7, 0xF2, 0x0F, 0xEB,
0xC1, 0x11, 0xB9, 0x10, 0x03, 0x6A, 0xF5, 0x97,
0x3C, 0x53, 0x2F, 0x67, 0x86, 0x09, 0x6A, 0xE3,
0x28, 0xC0, 0x78, 0xC8, 0xB4, 0x39, 0x8E, 0xD1,
0xCE, 0x25, 0xE8, 0x66, 0xF7, 0x09, 0x40, 0x7D,
0x81, 0xFB, 0xAF, 0xFA, 0x59, 0xC4, 0x9B, 0x2B,
0x83, 0x45, 0x5B, 0xA8, 0x66, 0x9E, 0x38, 0xC8,
0xFD, 0xAC, 0xF2, 0x2D, 0x21, 0xDE, 0x50, 0x4C,
0x03, 0xCB, 0x88, 0x42, 0xDD, 0x84, 0x09, 0x99,
0x8E, 0x8B, 0x40, 0x97, 0x1B, 0x14, 0x85, 0x37,
0x11, 0x01, 0xE0, 0x74, 0x6B, 0x33, 0x52, 0x8C,
0x68, 0x3A, 0x89, 0xB2, 0xAF, 0x35, 0xE6, 0x65,
0xC3, 0x58, 0x70, 0xD2, 0xE7, 0x1F, 0x1F, 0xF6,
0xE5, 0x0A, 0xB1, 0xFE, 0xD0, 0xC9, 0x51, 0x50,
0xE7, 0xFD, 0x58, 0xF5, 0xC4, 0x58, 0x65, 0x94,
0xD1, 0x57, 0x55, 0x5E, 0xD2, 0x27, 0x98, 0xAF,
0xE7, 0x55, 0x0B, 0x87, 0x50, 0x9B, 0xEF, 0xE8,
0x2B, 0xFC, 0xE7, 0x3B, 0x4E, 0xD7, 0xB7, 0x4D,
0xF4, 0xBC, 0xF4, 0x88, 0x63, 0xE4, 0x8A, 0x20,
0x4B, 0x22, 0xB0, 0xA0, 0x53, 0x7F, 0xA8, 0xC9,
0x0C, 0xF8, 0xD7, 0xBD, 0x46, 0x39, 0xA7, 0x7D,
0xDD, 0x10, 0x91, 0x50, 0x54, 0x06, 0x47, 0xF0,
0x3C, 0xAA, 0x43, 0x40, 0xF8, 0x54, 0xDD, 0x8A,
0xEA, 0x8A, 0x0B, 0xA5, 0x7F, 0xCD, 0x5E, 0xAA,
0x02, 0x2E, 0x1F, 0xC6, 0x50, 0x15, 0xF8, 0x0A,
0x0C, 0x1B, 0x3C, 0x55, 0x3A, 0xC3, 0x6F, 0x88,
0xD7, 0xBF, 0xB1, 0x02, 0xCC, 0xE0, 0x08, 0x29,
0x97, 0xD2, 0xAA, 0x23, 0xC4, 0x6D, 0xE3, 0xE3,
0x76, 0x39, 0x92, 0xC3, 0x2E, 0x7A, 0xE2, 0x98,
0xD1, 0xFC, 0xAE, 0xCC, 0x95, 0xD8, 0xB4, 0xDC,
0x92, 0xEA, 0x6A, 0x5F, 0xF2, 0x92, 0x17, 0x0B,
0x8D, 0xC3, 0xFA, 0x9C, 0x62, 0xCE, 0x44, 0x8D,
0xC3, 0x1E, 0xC3, 0xB2, 0xD5, 0x00, 0xCD, 0xB4,
0x9E, 0x2D, 0x7B, 0xF2, 0x98, 0xA3, 0x00, 0x8B,
0x81, 0x30, 0x77, 0x5B, 0x02, 0x99, 0xB1, 0xCD,
0xC3, 0x1D, 0x74, 0x74, 0xEF, 0x41, 0xCB, 0x69,
0x63, 0x8E, 0xA6, 0xD3, 0x2D, 0x3E, 0x1F, 0x1D,
0x12, 0x9E, 0xD9, 0x18, 0x67, 0x06, 0xAF, 0x37,
0x29, 0xAD, 0x65, 0xD8, 0xEB, 0x71, 0xC4, 0x7D,
0x94, 0x3D, 0xEA, 0xCC, 0xDF, 0x72, 0x41, 0x51,
0x3C, 0xA1, 0x66, 0x98, 0x32, 0x32, 0x40, 0x54,
0xB0, 0x2F, 0xEB, 0xCE, 0xDF, 0x4A, 0x64, 0xFB,
0x9A, 0x90, 0xDC, 0xF6, 0x6F, 0xA9, 0xD4, 0xCA,
0xCB, 0x91, 0xC4, 0xFE, 0xEE, 0x9C, 0x01, 0x50,
0x2E, 0xAC, 0xCC, 0x5F, 0x89, 0xD0, 0x91, 0xA3,
0xD9, 0xF9, 0x4B, 0x8D, 0xDE, 0x6C, 0x60, 0x21,
0x19, 0xB1, 0xD3, 0x4D, 0x75, 0x56, 0x6F, 0xB8,
0x25, 0xA4, 0x92, 0x4F, 0x12, 0xF5, 0x8F, 0xC1,
0x17, 0x4B, 0xB3, 0x34, 0x21, 0x22, 0xAC, 0x52,
0xD2, 0x64, 0xC9, 0x9A, 0x7D, 0xFC, 0xC0, 0x0A,
0x89, 0x34, 0xFF, 0x08, 0xD3, 0x04, 0xDC, 0xFE,
0x7C, 0xB3, 0xB8, 0xFD, 0x85, 0xDD, 0x79, 0x51,
0xA7, 0x89, 0xE8, 0xF1, 0x23, 0xB1, 0xDF, 0xD7,
0x1F, 0x7B, 0xB1, 0x5D, 0x42, 0xF9, 0x61, 0xF8,
0xDC, 0x81, 0x04, 0xF1, 0xCC, 0xFA, 0xD7, 0xED,
0xBF, 0x47, 0xAC, 0xBD, 0xE5, 0xFA, 0xAC, 0xB3,
0x1C, 0xD9, 0xA1, 0xB3, 0x60, 0xEE, 0x9C, 0x8A,
0x36, 0x57, 0xB4, 0x2F, 0xA1, 0xA2, 0xF3, 0xE2,
0x09, 0x9A, 0x6E, 0x43, 0x9B, 0xE5, 0x93, 0xB8,
0x3D, 0x9E, 0x9F, 0xC1, 0xC6, 0x0D, 0x02, 0xEB,
0x4D, 0x38, 0xE9, 0xB4, 0x9F, 0xEA, 0x33, 0x8C,
0x07, 0xD8, 0xB4, 0x71, 0xAD, 0xE5, 0x43, 0xB2,
0xCC, 0x55, 0x93, 0x6A, 0xDB, 0x1E, 0x80, 0xDB,
0xC2, 0xEA, 0x42, 0x8E, 0xFC, 0x86, 0x44, 0xC9,
0x8A, 0xC4, 0xF2, 0x46, 0xA7, 0x39, 0x50, 0x0D,
0x1A, 0xAA, 0x07, 0x04, 0xBE, 0xD4, 0xCE, 0x62,
0x4D, 0x0F, 0x91, 0x7D, 0x29, 0x88, 0x9C, 0x4C,
0xAF, 0xF7, 0xD8, 0x40, 0x93, 0x88, 0xC7, 0x20,
0xD2, 0x17, 0x2A, 0xC4, 0x92, 0x72, 0xD0, 0xC0,
0x4E, 0x56, 0x47, 0xB1, 0x27, 0x02, 0xE6, 0x61,
0x82, 0x5E, 0xC8, 0x2E, 0x90, 0xD2, 0x31, 0x22,
0xE2, 0xA9, 0x4A, 0x91, 0x45, 0x69, 0xB1, 0xA5,
0x0F, 0x66, 0x2C, 0x30, 0xAD, 0x7F, 0x1B, 0x0E,
0x22, 0x17, 0x60, 0x2E, 0x3D, 0x7F, 0x7F, 0x8C,
0x33, 0x51, 0xA0, 0x25, 0xDE, 0xFD, 0x75, 0xBC,
0xEF, 0xE6, 0xE7, 0x20, 0x04, 0x5A, 0xEC, 0x50,
0x21, 0x48, 0x56, 0x98, 0xE2, 0x33, 0x6D, 0x22,
0x5C, 0xC3, 0xFB, 0xFC, 0x6F, 0xB3, 0xA7, 0x8E,
0x6F, 0x67, 0x70, 0x9D, 0xDA, 0x02, 0x01, 0x59,
0x7B, 0x3D, 0x2B, 0x38, 0xCC, 0x0F, 0x44, 0x3D,
0xFB, 0x9A, 0xB3, 0x23, 0x15, 0x50, 0x6E, 0xBF,
0x8B, 0xA1, 0x94, 0x33, 0xE5, 0x7B, 0x88, 0x4E,
0xCB, 0x6D, 0x9F, 0xBF, 0xBC, 0x7A, 0xA8, 0x1E,
0x68, 0x25, 0xED, 0x8E, 0x53, 0x21, 0x72, 0xC5,
0x70, 0xB3, 0xE4, 0xA6, 0xA1, 0x5A, 0x2D, 0xC8,
0x43, 0x9D, 0x60, 0x77, 0x78, 0xE0, 0xC4, 0xAF,
0xC8, 0x29, 0xBA, 0xD0, 0x4D, 0x39, 0x83, 0x51,
0xA7, 0x10, 0x7F, 0x0C, 0x34, 0x0E, 0x6C, 0x75,
0x26, 0xD7, 0xD6, 0xC7, 0x32, 0x53, 0xAF, 0x4E,
0xBE, 0xF2, 0xC2, 0x0F, 0x99, 0x23, 0xB9, 0xE1,
0xC8, 0xB4, 0xBC, 0x5A, 0xC6, 0xCB, 0xEB, 0x4D,
0x28, 0x56, 0x72, 0xFE, 0x1B, 0x2C, 0x5D, 0xE3,
0xBC, 0xC7, 0xA3, 0xC0, 0x7D, 0x27, 0xF0, 0xD0,
0x4F, 0x3F, 0x1F, 0xF7, 0x87, 0x15, 0xF2, 0xEA,
0xD4, 0x03, 0x6D, 0x2F, 0xD4, 0x8E, 0x50, 0x4B,
0x05, 0xBF, 0xF7, 0x8C, 0x67, 0x5A, 0xDC, 0x4D,
0xCD, 0xCF, 0x9D, 0x02, 0xB6, 0xE7, 0xAE, 0x49,
0xD1, 0x7C, 0x00, 0xE7, 0x3B, 0xEA, 0xFB, 0x0D,
0x2A, 0x7B, 0x41, 0x33, 0x66, 0xD0, 0x29, 0x9F,
0xB3, 0x8A, 0x71, 0xB0, 0xE2, 0x76, 0xA9, 0xDB,
0xFD, 0x64, 0x04, 0x69, 0xDF, 0x89, 0x1F, 0x56,
0x86, 0x92, 0xD9, 0xD9, 0xB9, 0xF3, 0x4F, 0xAC,
0xAE, 0x61, 0x48, 0x20, 0xCE, 0x3C, 0x2B, 0x44,
0xAB, 0x42, 0xFA, 0xAB, 0x2E, 0x94, 0x82, 0xC8,
0xD9, 0x97, 0xCF, 0x27, 0xDF, 0xAC, 0xAC, 0xE7,
0xCA, 0xB2, 0x84, 0xAB, 0xF2, 0x5D, 0xDF, 0x56,
0x0C, 0x8C, 0x07, 0x3C, 0x3D, 0xA8, 0xDD, 0xBE,
0xFF, 0x4E, 0x28, 0x0D, 0xB2, 0x2D, 0xE6, 0x9D,
0x44, 0x21, 0xCB, 0xE7, 0x33, 0x63, 0x22, 0x8F,
0x4C, 0xFF, 0xB6, 0x1D, 0x9A, 0x71, 0x3F, 0xB1,
0x29, 0xAE, 0x3A, 0x35, 0xEE, 0x9C, 0x97, 0x68,
0xA7, 0x52, 0x66, 0x01, 0xD8, 0x9A, 0x5D, 0xF4,
0xB3, 0x2F, 0x5C, 0xD4, 0x0E, 0xF9, 0xCF, 0x07,
0xF6, 0x8C, 0xBA, 0xA6, 0x8D, 0x6B, 0xC6, 0x01,
0xC2, 0x69, 0xAE, 0x60, 0x08, 0x1A, 0x0E, 0x3F,
0xAE, 0x60, 0x29, 0xF3, 0x48, 0x0D, 0xE0, 0xD0,
0xAE, 0x52, 0x44, 0xE9, 0x7F, 0x1F, 0x92, 0x5F,
0x71, 0xAD, 0xEC, 0x6B, 0x47, 0x66, 0x92, 0x22,
0x27, 0xAE, 0x6E, 0x25, 0xCD, 0xF3, 0x5F, 0x55,
0x59, 0xBD, 0x73, 0xCE, 0x2B, 0x7E, 0x99, 0x44,
0x56, 0x70, 0xA3, 0xE7, 0x7A, 0x59, 0x75, 0xD8,
0x48, 0x0C, 0x39, 0x2B, 0xD7, 0x53, 0xC6, 0xAD,
0x4A, 0x6F, 0xB4, 0x14, 0x96, 0xDF, 0xF2, 0x4A,
0x0C, 0xA2, 0xD5, 0x29, 0x98, 0x7C, 0x42, 0x87,
0xD9, 0x1F, 0x97, 0x61, 0xD9, 0xBF, 0x99, 0x4F,
0x2C, 0x4C, 0x75, 0xAC, 0xB8, 0x06, 0x75, 0xD6,
0x87, 0x76, 0x7E, 0xE3, 0x23, 0x4B, 0xEA, 0x1A,
0x1A, 0xF4, 0xB7, 0x09, 0xAF, 0x53, 0xEB, 0xA6,
0x39, 0x10, 0xFE, 0xD4, 0xEB, 0x1B, 0xAE, 0x38,
0x31, 0x33, 0xBA, 0x68, 0xEE, 0xC7, 0x65, 0x76,
0xFB, 0x49, 0x77, 0xD4, 0x19, 0xC4, 0xE6, 0xA7,
0x05, 0xFE, 0x2A, 0xDA, 0x39, 0x99, 0x1A, 0x92,
0xD2, 0xF0, 0x61, 0x97, 0xF6, 0x06, 0x6C, 0x88,
0x7B, 0x6F, 0x60, 0xE6, 0x70, 0x08, 0xF0, 0xB4,
0x6B, 0x39, 0x6F, 0x05, 0x41, 0x81, 0xF9, 0xBE,
0x7A, 0x51, 0xC4, 0x75, 0xB0, 0x6A, 0x89, 0xA0,
0xA6, 0x9A, 0x5B, 0xEE, 0x7D, 0x78, 0x17, 0x5F,
0x9F, 0x3B, 0x7D, 0xDD, 0x8A, 0x9E, 0xAA, 0x1A,
0xDA, 0x49, 0x08, 0xE9, 0xFD, 0x91, 0xA6, 0xFA,
0xCE, 0xCF, 0x67, 0xDF, 0x0F, 0xC9, 0xD6, 0x38,
0xD9, 0xD5, 0xD1, 0xC0, 0x76, 0x59, 0x42, 0x53,
0xBF, 0x48, 0xE9, 0x11, 0x74, 0xC7, 0x11, 0xD8,
0xE7, 0x8E, 0xD3, 0xC8, 0x25, 0xA1, 0x26, 0x50,
0xBB, 0xB4, 0x35, 0xAF, 0xAF, 0x06, 0x23, 0x69,
0x3E, 0x30, 0xFD, 0x7B, 0x34, 0x83, 0x07, 0xD0,
0xF0, 0x0F, 0x6C, 0x9A, 0x13, 0x5D, 0xC2, 0x7B,
0xDF, 0x6F, 0xDD, 0x8E, 0xF4, 0x30, 0x82, 0x05,
0x41, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, 0x05, 0x32,
0x04, 0x82, 0x05, 0x2E, 0x30, 0x82, 0x05, 0x2A,
0x30, 0x82, 0x05, 0x26, 0x06, 0x0B, 0x2A, 0x86,
0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01,
0x02, 0xA0, 0x82, 0x04, 0xEE, 0x30, 0x82, 0x04,
0xEA, 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48,
0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30,
0x0E, 0x04, 0x08, 0x74, 0xC0, 0x84, 0x8F, 0xC7,
0x74, 0x5E, 0x21, 0x02, 0x02, 0x08, 0x00, 0x04,
0x82, 0x04, 0xC8, 0x1E, 0xF4, 0xE9, 0x07, 0x27,
0x9E, 0x5A, 0xC9, 0x39, 0x1D, 0x37, 0x2C, 0x06,
0x4B, 0x57, 0xEA, 0xC5, 0x42, 0x9A, 0x60, 0xD5,
0x42, 0xB2, 0x34, 0x2D, 0xD3, 0x88, 0x7C, 0x78,
0x87, 0xB6, 0xE9, 0x42, 0x44, 0x1F, 0x67, 0x32,
0x92, 0x54, 0x22, 0xDA, 0xB2, 0x43, 0xE7, 0x40,
0xBE, 0x1F, 0xAF, 0x3A, 0xCD, 0x2A, 0x9F, 0xD7,
0x44, 0x5B, 0x37, 0x69, 0x85, 0xDF, 0xEB, 0x2A,
0xB9, 0xE2, 0x92, 0x3B, 0xEA, 0xD5, 0x42, 0x53,
0x95, 0x4A, 0xB0, 0x1B, 0xA5, 0xEF, 0xA6, 0x0D,
0x29, 0xF4, 0x33, 0xFE, 0xD7, 0x49, 0x04, 0x1E,
0x8C, 0xAD, 0x63, 0x1E, 0x79, 0x63, 0x74, 0x0C,
0xE5, 0x5E, 0xA2, 0x2C, 0xBE, 0xB8, 0x90, 0xCE,
0x06, 0x25, 0xBF, 0xD1, 0x5A, 0x50, 0xCF, 0x3B,
0x52, 0xE2, 0xA7, 0xFF, 0x19, 0x02, 0xCF, 0xD0,
0x9B, 0xD9, 0xF7, 0x28, 0x07, 0x38, 0x1F, 0xF2,
0xAF, 0x44, 0x91, 0x3F, 0x0F, 0xB6, 0x6E, 0x8C,
0xC0, 0x32, 0x92, 0xC0, 0xCD, 0x25, 0x98, 0x67,
0xF1, 0x47, 0x52, 0x50, 0xF0, 0xA3, 0x7B, 0xE6,
0x74, 0xDC, 0x72, 0x28, 0xC8, 0xAB, 0xB3, 0x31,
0x7D, 0xA3, 0xF7, 0xC7, 0xD1, 0xE6, 0x99, 0xB4,
0xB6, 0x5A, 0x3A, 0x4D, 0x83, 0x4F, 0xB8, 0xB5,
0x86, 0xF8, 0x37, 0x7F, 0xA0, 0x16, 0x2F, 0x3C,
0x62, 0x7A, 0xD4, 0x3A, 0xEB, 0xC2, 0xE8, 0x03,
0x49, 0x17, 0x9E, 0xFB, 0xD7, 0xAF, 0x91, 0x32,
0xFD, 0xEA, 0x4F, 0x64, 0xC6, 0x6E, 0x02, 0xEA,
0xC4, 0xC8, 0x1F, 0x16, 0xC5, 0x4C, 0xFB, 0xC5,
0x42, 0xF5, 0x85, 0x05, 0x92, 0x59, 0x4B, 0x31,
0xE5, 0xE9, 0x69, 0xE7, 0x02, 0x98, 0x33, 0xBA,
0x4C, 0x17, 0x09, 0xEF, 0x89, 0x20, 0xFA, 0x83,
0x9F, 0xAE, 0x0E, 0x1B, 0x7D, 0x98, 0xB9, 0xF2,
0x3C, 0x0F, 0xB7, 0x1C, 0x72, 0xDF, 0x17, 0x84,
0x7F, 0x0A, 0xFD, 0x12, 0x3C, 0x6F, 0x68, 0x5D,
0x45, 0xEB, 0xB8, 0xD6, 0x24, 0x65, 0x42, 0x75,
0x5C, 0xC2, 0xF3, 0x3A, 0x6A, 0x4E, 0x51, 0x34,
0x1B, 0xB6, 0x81, 0xB2, 0x8A, 0xEF, 0x28, 0xA4,
0xC5, 0x88, 0x9A, 0x97, 0xE0, 0xEF, 0x31, 0x12,
0x01, 0x7E, 0x1B, 0x43, 0x0F, 0x27, 0x80, 0x87,
0x98, 0xC5, 0xD5, 0x83, 0xCB, 0x4B, 0xB7, 0x01,
0x79, 0x60, 0xA1, 0x1A, 0x03, 0x05, 0xC6, 0x36,
0x04, 0x31, 0x3C, 0x06, 0xDB, 0x08, 0xA8, 0xDA,
0x8E, 0x32, 0x19, 0x91, 0xF1, 0x0D, 0x61, 0x6F,
0xE4, 0xB2, 0x79, 0x8A, 0xDE, 0xF4, 0xF7, 0xFB,
0x2C, 0x23, 0x5B, 0xD9, 0x64, 0x2F, 0xB7, 0xB3,
0x8B, 0xCA, 0xB8, 0x8C, 0x1D, 0x3B, 0x49, 0x05,
0x38, 0xA1, 0xE5, 0x8C, 0x1A, 0xDC, 0xA5, 0x61,
0xFE, 0xF4, 0x2B, 0xDC, 0x77, 0x28, 0xF6, 0x19,
0xE7, 0xB7, 0x8F, 0x4D, 0x27, 0x2D, 0xED, 0x8A,
0x3F, 0x3D, 0xDC, 0x9F, 0xD1, 0x30, 0xFF, 0xD6,
0xC3, 0xBE, 0x41, 0x25, 0xE3, 0xA5, 0x9B, 0x73,
0xDF, 0x6A, 0xD9, 0xF9, 0x70, 0x84, 0x02, 0x4C,
0x35, 0xD4, 0x3E, 0x05, 0x76, 0x3A, 0xDC, 0x6D,
0x5A, 0x81, 0xB3, 0x94, 0xF7, 0x22, 0xF7, 0xDC,
0xC1, 0x43, 0x31, 0x57, 0x5B, 0x42, 0x9A, 0x0B,
0xF4, 0x95, 0x30, 0xA9, 0xBB, 0xD8, 0x06, 0xFB,
0x1D, 0x6F, 0x9B, 0xC3, 0xBB, 0xF3, 0xBF, 0xFB,
0xB4, 0x9F, 0x35, 0x64, 0x0A, 0x69, 0xB7, 0xD1,
0x3E, 0xCA, 0x78, 0x07, 0x04, 0x03, 0x79, 0xD4,
0xF3, 0xA8, 0xEC, 0x18, 0xDB, 0x03, 0x5E, 0x47,
0xD7, 0xD0, 0x56, 0x2C, 0x74, 0x94, 0x86, 0x04,
0x46, 0xB8, 0xD4, 0x35, 0x0A, 0x7B, 0xE6, 0x78,
0xC4, 0x43, 0x3C, 0x56, 0xCC, 0x37, 0x8B, 0xFD,
0xE8, 0xF4, 0x57, 0xEA, 0xAE, 0xCF, 0x36, 0x97,
0x12, 0xAC, 0x39, 0xCF, 0x7C, 0xEF, 0x22, 0x67,
0x01, 0xEC, 0xD8, 0x09, 0x49, 0x4E, 0xE3, 0x74,
0xDD, 0x39, 0xE1, 0x39, 0xD7, 0x0C, 0x5F, 0x1B,
0xCE, 0x69, 0xBC, 0x72, 0x44, 0x87, 0x64, 0x1C,
0x08, 0x05, 0x93, 0x69, 0x6D, 0x7F, 0x90, 0x0A,
0x2C, 0xCB, 0x8A, 0xBB, 0x7F, 0xE3, 0xE0, 0x80,
0x31, 0xD0, 0x0A, 0x3A, 0x95, 0xFF, 0xF7, 0xB4,
0x36, 0x38, 0x93, 0xE0, 0x0C, 0x11, 0x37, 0x12,
0x06, 0xF6, 0xAD, 0xE9, 0xB1, 0x7A, 0x00, 0xF5,
0xD2, 0x32, 0x6B, 0xD0, 0x27, 0xA5, 0x1B, 0x3D,
0xE8, 0xDB, 0xCC, 0xA9, 0x1F, 0x1F, 0xB1, 0x99,
0x3D, 0x7C, 0xB7, 0xCA, 0xDA, 0x27, 0x2C, 0x64,
0x1C, 0x49, 0xB6, 0x87, 0x44, 0x06, 0x94, 0x9D,
0xBC, 0x6B, 0x20, 0xA2, 0x68, 0x15, 0x1F, 0xE2,
0xF2, 0xAD, 0x6D, 0x23, 0x2E, 0x2B, 0x74, 0xE2,
0x5D, 0xE4, 0xB0, 0xC7, 0x84, 0xCB, 0x64, 0xBF,
0xE0, 0xA8, 0x18, 0x83, 0xB4, 0xC9, 0xD9, 0x73,
0xA8, 0xE6, 0xA9, 0x36, 0xD5, 0x63, 0x1E, 0x2C,
0x2A, 0x55, 0x09, 0x77, 0x5E, 0xB3, 0x4B, 0xEA,
0xB5, 0xD0, 0x14, 0x5F, 0xEB, 0x50, 0x7B, 0xAA,
0xEF, 0x94, 0xBA, 0x2B, 0xD7, 0x8A, 0x07, 0xF1,
0xF9, 0x5E, 0x12, 0x12, 0x21, 0x52, 0xE5, 0x0A,
0x3E, 0xC0, 0xBC, 0x5D, 0x4C, 0xE2, 0x12, 0x7C,
0x39, 0xF9, 0x16, 0x9D, 0xBD, 0x96, 0x83, 0x3B,
0x7F, 0x3D, 0x6A, 0xEC, 0xF1, 0x25, 0xD2, 0xB0,
0xB0, 0xEB, 0x20, 0x06, 0x07, 0xD6, 0xD9, 0x4C,
0x07, 0x9A, 0x82, 0xC1, 0xFC, 0xF7, 0x66, 0x15,
0xBD, 0x62, 0x65, 0xD8, 0x6C, 0xF6, 0x33, 0x7B,
0x5A, 0x28, 0xEC, 0x90, 0xA1, 0x26, 0x9F, 0xC3,
0x28, 0x4A, 0x64, 0x50, 0x5F, 0xCA, 0xE2, 0x6D,
0xB8, 0x0F, 0xE2, 0x94, 0xB5, 0x8E, 0x1F, 0x8A,
0x8F, 0x6B, 0xA6, 0x86, 0x1F, 0xEE, 0xDC, 0x24,
0xB4, 0xB8, 0x25, 0xEC, 0x28, 0x2D, 0xF9, 0xCB,
0x7D, 0x38, 0xFF, 0xC7, 0x74, 0x2E, 0xD3, 0x10,
0xEC, 0x03, 0x31, 0xEE, 0x83, 0xE7, 0xA4, 0xF7,
0xBA, 0x28, 0x21, 0xE0, 0x7F, 0xB4, 0xB7, 0xE1,
0x7A, 0xF9, 0x2B, 0xB0, 0x2C, 0x3B, 0x80, 0x5F,
0xE0, 0x5D, 0xB2, 0x7E, 0x59, 0xFF, 0x59, 0x07,
0x58, 0x42, 0x57, 0xEE, 0x44, 0xF1, 0xB1, 0xAD,
0xBA, 0xDE, 0xCB, 0x1D, 0x8A, 0x36, 0x67, 0xE8,
0x45, 0xFF, 0x07, 0x8D, 0xEE, 0xA4, 0x51, 0x9C,
0x4C, 0x83, 0x5D, 0x2E, 0x2F, 0xE1, 0x5B, 0x75,
0xE8, 0x29, 0xCD, 0x0B, 0x07, 0x62, 0xE0, 0xC3,
0x0D, 0x1D, 0xEA, 0xCF, 0xF0, 0x8A, 0x65, 0x27,
0x70, 0x42, 0x9F, 0x26, 0x00, 0x15, 0x70, 0xC5,
0x4A, 0xF6, 0x25, 0xD0, 0x40, 0x72, 0xE9, 0xC1,
0x73, 0xFD, 0x48, 0x94, 0xA3, 0x8D, 0x66, 0x63,
0x96, 0x4F, 0xF7, 0xEE, 0xFB, 0x4C, 0xC7, 0xB8,
0x6B, 0xE9, 0x90, 0xE1, 0x2A, 0x66, 0x80, 0x99,
0x3B, 0xB0, 0x1A, 0x6C, 0xF9, 0x0E, 0x72, 0xDA,
0x8E, 0x4F, 0x46, 0xC2, 0x6A, 0x4B, 0x7A, 0x16,
0xE5, 0x26, 0x0B, 0x5C, 0xD4, 0x47, 0x34, 0xE5,
0x37, 0xBE, 0x68, 0x6C, 0xDA, 0xD3, 0x9B, 0x6F,
0xAE, 0x51, 0x9C, 0x99, 0x0A, 0x5B, 0xF8, 0x37,
0xBC, 0xDE, 0xFC, 0x93, 0xC5, 0xE7, 0x0F, 0xEF,
0x0B, 0xA6, 0x07, 0xC2, 0xA6, 0xE6, 0xDA, 0x2D,
0x1B, 0x49, 0xC9, 0xDE, 0x6B, 0x27, 0xDC, 0x00,
0xEF, 0x23, 0x87, 0x0E, 0xEB, 0xD1, 0x48, 0x7D,
0xB4, 0xF2, 0x58, 0xC6, 0x3C, 0xE2, 0x89, 0xBA,
0xB0, 0x05, 0xAC, 0x94, 0x41, 0x9A, 0xA8, 0xFF,
0x3E, 0xBC, 0x3A, 0x52, 0x9C, 0xF9, 0x7F, 0x07,
0x8B, 0xB0, 0x2C, 0x71, 0x83, 0x7B, 0xCF, 0x2E,
0x7F, 0x7C, 0x96, 0x65, 0xD9, 0x08, 0x17, 0xEC,
0xFA, 0xDE, 0x4E, 0x40, 0x12, 0x26, 0x70, 0x71,
0x65, 0xA5, 0xDC, 0x98, 0x47, 0xA3, 0xFC, 0xE0,
0x9A, 0x16, 0xED, 0x45, 0x56, 0x72, 0x50, 0x05,
0x28, 0x2C, 0x99, 0xEC, 0x20, 0x2E, 0x40, 0xC0,
0x26, 0x69, 0xCD, 0x49, 0x45, 0x17, 0xA4, 0xA3,
0x42, 0x0D, 0x14, 0x65, 0x87, 0x33, 0x8C, 0x92,
0xC5, 0xC4, 0x61, 0xFD, 0xE8, 0x68, 0x56, 0x20,
0x57, 0xF5, 0x8E, 0x5F, 0xCF, 0x7E, 0x97, 0xF6,
0x49, 0x97, 0x0A, 0xFE, 0xD3, 0x60, 0x1A, 0x5B,
0x0C, 0x75, 0xDD, 0x8E, 0x31, 0x78, 0x29, 0xA6,
0xB1, 0x4D, 0xAA, 0xDF, 0x8A, 0xD1, 0xE6, 0x91,
0xE3, 0x32, 0x3F, 0xEC, 0x8A, 0x1F, 0x0E, 0x35,
0x07, 0x6E, 0x4B, 0x83, 0x3B, 0xE5, 0x67, 0x34,
0x1F, 0x0C, 0x81, 0xD8, 0xD5, 0x25, 0x68, 0xE5,
0x28, 0x1B, 0x5C, 0x81, 0x3E, 0xE3, 0x5C, 0xB4,
0xB6, 0xBD, 0x62, 0x6A, 0x70, 0x33, 0xC2, 0xC5,
0x75, 0x27, 0xF4, 0x30, 0xE1, 0x1D, 0xC1, 0x4C,
0xC5, 0x02, 0x12, 0x46, 0xAC, 0xEC, 0xF9, 0xE8,
0xE7, 0x58, 0x24, 0x11, 0xB1, 0xF3, 0xB7, 0x8C,
0x3C, 0xA4, 0x0A, 0x94, 0xA6, 0x7C, 0x68, 0x54,
0x5B, 0xB9, 0x4D, 0x57, 0x9C, 0xE7, 0x28, 0x09,
0x6B, 0x89, 0x26, 0x5D, 0xE7, 0x50, 0xA9, 0x95,
0x90, 0x91, 0x8E, 0x00, 0x59, 0xF8, 0x3A, 0x70,
0xAF, 0x48, 0x2E, 0xE8, 0xC4, 0x34, 0x8C, 0xF4,
0x5F, 0x7F, 0xCB, 0x07, 0xAA, 0xF0, 0xD9, 0xFB,
0x5C, 0x32, 0x90, 0x22, 0x1A, 0xD2, 0x1A, 0xCF,
0x92, 0x06, 0x02, 0xCF, 0x10, 0x18, 0x7B, 0x93,
0xCC, 0x07, 0x4A, 0x31, 0x25, 0x30, 0x23, 0x06,
0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xD1, 0xDE,
0x23, 0x16, 0x9F, 0x6E, 0xF4, 0x42, 0x21, 0x23,
0xE1, 0x11, 0xAA, 0xC8, 0x7C, 0x60, 0x4A, 0x78,
0x9D, 0x24, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09,
0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05,
0x00, 0x04, 0x14, 0xD6, 0x4A, 0xBB, 0x75, 0xB1,
0xF9, 0x9E, 0xD3, 0x58, 0x6D, 0xD1, 0x74, 0x9F,
0x00, 0x8A, 0xF2, 0xC8, 0xAA, 0x52, 0x4D, 0x04,
0x08, 0x77, 0x46, 0xE7, 0xBA, 0x25, 0x4B, 0xDA,
0x41, 0x02, 0x02, 0x08, 0x00]
};
const WPA_EAP_CLIENT_LIST = [
{
ssid: 'WPA-EAP-TTLS',
keyManagement: 'WPA-EAP',
eap: 'TTLS',
identity: EAP_USERNAME,
password: EAP_PASSWORD,
serverCertificate: CLIENT_PKCS12_CERT.nickname,
phase2: 'MSCHAPV2'
}
];
/**
* Convert the given MozWifiNetwork object array to testAssociate chain.
*
* @param aNetworks
* An array of MozWifiNetwork which we want to convert.
*
* @return A promise chain which "then"s testAssociate accordingly.
*/
function convertToTestAssociateChain(aNetworks) {
let chain = Promise.resolve();
aNetworks.forEach(function (aNetwork) {
network = new window.MozWifiNetwork(aNetwork);
chain = chain.then(() => gTestSuite.testAssociate(network));
});
return chain;
}
gTestSuite.doTestWithCertificate(
new Blob([new Uint8Array(CLIENT_PKCS12_CERT.content)]),
CLIENT_PKCS12_CERT.password,
CLIENT_PKCS12_CERT.nickname,
CLIENT_PKCS12_CERT.usage,
function() {
return gTestSuite.ensureWifiEnabled(true)
// Load required server files.
.then(() => gTestSuite.writeFile(SERVER_EAP_USER_CONF.path, SERVER_EAP_USER_CONF.content))
.then(() => gTestSuite.writeFile(CA_CERT.path, CA_CERT.content))
.then(() => gTestSuite.writeFile(SERVER_CERT.path, SERVER_CERT.content))
.then(() => gTestSuite.writeFile(SERVER_KEY.path, SERVER_KEY.content))
// Start AP.
.then(() => gTestSuite.startHostapds(WPA_EAP_AP_LIST))
// Scan test.
.then(() => gTestSuite.testWifiScanWithRetry(SCAN_RETRY_CNT, WPA_EAP_AP_LIST))
// Associate test.
.then(() => convertToTestAssociateChain(WPA_EAP_CLIENT_LIST))
// Tear down.
.then(gTestSuite.killAllHostapd)
});
@@ -4,15 +4,41 @@
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
gTestSuite.doTest(function() {
const TESTING_HOSTAPD = [{ ssid: 'ap0' }];
gTestSuite.doTestWithoutStockAp(function() {
let firstNetwork;
return gTestSuite.ensureWifiEnabled(true)
// Start custom hostapd for testing.
.then(() => gTestSuite.startHostapds(TESTING_HOSTAPD))
.then(() => gTestSuite.verifyNumOfProcesses('hostapd', TESTING_HOSTAPD.length))
// Request the first scan.
.then(gTestSuite.requestWifiScan)
.then(function(networks) {
firstNetwork = networks[0];
return gTestSuite.testAssociate(firstNetwork);
})
// Note that due to Bug 1168285, we need to re-start testing hostapd
// after wifi has been re-enabled.
// Disable wifi and kill running hostapd.
.then(() => gTestSuite.requestWifiEnabled(false))
.then(gTestSuite.killAllHostapd)
.then(() => gTestSuite.verifyNumOfProcesses('hostapd', 0))
// Re-enable wifi.
.then(() => gTestSuite.requestWifiEnabled(true))
.then(() => gTestSuite.waitForConnected(firstNetwork));
// Restart hostapd.
.then(() => gTestSuite.startHostapds(TESTING_HOSTAPD))
.then(() => gTestSuite.verifyNumOfProcesses('hostapd', TESTING_HOSTAPD.length))
// Wait for connection automatically.
.then(() => gTestSuite.waitForConnected(firstNetwork))
// Kill running hostapd.
.then(gTestSuite.killAllHostapd)
.then(() => gTestSuite.verifyNumOfProcesses('hostapd', 0))
});
@@ -0,0 +1,338 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
// Binary form of test certificate.
var testCertInfo = {
nickname: 'Test Certificate',
password: '12345678',
usage: ['UserCert', 'ServerCert'],
blob: [0x30, 0x82, 0x09, 0xF1, 0x02, 0x01, 0x03, 0x30,
0x82, 0x09, 0xB7, 0x06, 0x09, 0x2A, 0x86, 0x48,
0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82,
0x09, 0xA8, 0x04, 0x82, 0x09, 0xA4, 0x30, 0x82,
0x09, 0xA0, 0x30, 0x82, 0x06, 0x9F, 0x06, 0x09,
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07,
0x06, 0xA0, 0x82, 0x06, 0x90, 0x30, 0x82, 0x06,
0x8C, 0x02, 0x01, 0x00, 0x30, 0x82, 0x06, 0x85,
0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
0x01, 0x07, 0x01, 0x30, 0x1C, 0x06, 0x0A, 0x2A,
0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01,
0x06, 0x30, 0x0E, 0x04, 0x08, 0x13, 0xB5, 0x2F,
0x5A, 0xB9, 0x49, 0xE6, 0x0B, 0x02, 0x02, 0x08,
0x00, 0x80, 0x82, 0x06, 0x58, 0x35, 0x77, 0x6B,
0xBF, 0x5C, 0x06, 0x09, 0xD8, 0xF0, 0x36, 0x06,
0x69, 0x8D, 0xA2, 0x86, 0xCF, 0x6B, 0x73, 0x86,
0x14, 0xFA, 0x51, 0x9A, 0x87, 0x73, 0x29, 0x71,
0xC5, 0xB1, 0x4F, 0xFB, 0xEC, 0x64, 0x84, 0x20,
0xFC, 0x06, 0x4A, 0x93, 0x74, 0x01, 0xFB, 0xEB,
0x1F, 0xDC, 0xF8, 0xF7, 0xBB, 0xDC, 0x42, 0xA1,
0x4A, 0x71, 0xDE, 0x08, 0x33, 0x7A, 0xCA, 0xD3,
0xD8, 0x40, 0x24, 0x47, 0xAE, 0x41, 0x42, 0x8E,
0xC8, 0x4E, 0xBE, 0x8B, 0xB3, 0xE5, 0x77, 0xAC,
0xBD, 0x98, 0x0C, 0x0E, 0x53, 0xBE, 0x38, 0xB7,
0xEA, 0xD2, 0x29, 0x35, 0xD2, 0xC4, 0xF4, 0xC7,
0xD8, 0xB1, 0x73, 0x2A, 0x13, 0x11, 0x65, 0xF7,
0x0C, 0x8B, 0xC0, 0x43, 0xFB, 0x31, 0x6C, 0xD2,
0xE4, 0x43, 0x85, 0x51, 0x16, 0xBF, 0x35, 0xB5,
0x05, 0x6B, 0x86, 0x11, 0xEA, 0x78, 0x64, 0x9F,
0x42, 0x29, 0xB9, 0x79, 0xAF, 0xB0, 0x7C, 0xBF,
0xC0, 0x89, 0xAD, 0xC7, 0x37, 0xD2, 0x30, 0x8C,
0xDC, 0xF6, 0x77, 0x5E, 0x1F, 0x26, 0x28, 0x8F,
0xAC, 0x19, 0x6C, 0xA0, 0x15, 0xC7, 0x12, 0xA3,
0x0A, 0xD5, 0xC6, 0x15, 0x60, 0x58, 0x16, 0xB8,
0x30, 0x12, 0x3C, 0x78, 0x3C, 0x93, 0x23, 0xA1,
0x56, 0x75, 0x0B, 0x77, 0xAA, 0x0B, 0x0B, 0x2B,
0x91, 0xB6, 0x41, 0xAB, 0xF5, 0x09, 0x4C, 0x1E,
0x36, 0xC0, 0x88, 0xC3, 0x08, 0xF2, 0x65, 0xCB,
0x58, 0x8F, 0x94, 0xB4, 0xB4, 0x05, 0xCC, 0x44,
0x49, 0x73, 0x1B, 0x25, 0x6F, 0x5D, 0x83, 0xBD,
0xF0, 0x70, 0xD0, 0xE8, 0x0D, 0x18, 0x2E, 0x44,
0xD7, 0x89, 0x64, 0x6A, 0xED, 0x23, 0x30, 0xDF,
0xAD, 0x84, 0x3B, 0x74, 0x2C, 0x0D, 0x2B, 0x51,
0x84, 0xA2, 0xA4, 0x9E, 0x42, 0xC3, 0x81, 0x69,
0xFA, 0x56, 0x76, 0x9F, 0xD9, 0x02, 0x64, 0x04,
0xFE, 0xF0, 0xD9, 0x01, 0xBC, 0xE2, 0xC9, 0xDD,
0x88, 0xAC, 0xFA, 0x24, 0x7E, 0xB1, 0xF8, 0x39,
0x27, 0xA2, 0xEB, 0xE4, 0x53, 0xC1, 0xF3, 0xFE,
0x2D, 0x9A, 0x49, 0x73, 0xFF, 0x7C, 0x8E, 0x39,
0xF7, 0x15, 0x27, 0xB3, 0x47, 0x48, 0x92, 0x8C,
0x57, 0x60, 0x9C, 0x97, 0xBA, 0x80, 0xD2, 0x25,
0x80, 0x94, 0xCE, 0x2C, 0x0C, 0x00, 0x44, 0x8C,
0x8C, 0x37, 0x82, 0x5D, 0x5F, 0x62, 0x8B, 0x05,
0x6F, 0xB0, 0x07, 0x34, 0xF9, 0xC3, 0xA1, 0x34,
0x3D, 0xE4, 0x90, 0xB0, 0x03, 0x59, 0x97, 0x6E,
0xFB, 0xF2, 0x92, 0xE5, 0xB5, 0x30, 0x7C, 0x0D,
0x3B, 0x8F, 0x90, 0x8E, 0x04, 0x47, 0x01, 0x0E,
0x88, 0x50, 0x4A, 0x88, 0xA0, 0xFF, 0xB7, 0x9E,
0x2B, 0x2C, 0x98, 0xD0, 0x3E, 0x16, 0x35, 0x5B,
0xD5, 0xEA, 0x54, 0x86, 0xE0, 0xFB, 0x9F, 0x2F,
0x62, 0x89, 0x36, 0x36, 0x9D, 0x6E, 0x62, 0xCB,
0xC8, 0x6C, 0x62, 0x34, 0x8F, 0x66, 0x07, 0x62,
0xA7, 0x00, 0x90, 0x31, 0xFA, 0x5D, 0xDD, 0x12,
0x33, 0x69, 0xD0, 0x74, 0x0E, 0x0B, 0x42, 0x9A,
0xF3, 0x40, 0x7E, 0x3E, 0x48, 0x1D, 0xF2, 0x5C,
0x71, 0x0B, 0x78, 0x7E, 0xD5, 0x15, 0xA4, 0x16,
0x1E, 0xBD, 0x71, 0x18, 0x87, 0x3A, 0xC9, 0xE3,
0x45, 0xEE, 0x70, 0xA2, 0x4C, 0x50, 0xF5, 0x16,
0x5C, 0xF8, 0x76, 0xE6, 0x9F, 0x8D, 0x86, 0x41,
0x7E, 0xF8, 0x60, 0x3D, 0x75, 0x6D, 0x55, 0x96,
0x9E, 0x43, 0x48, 0x82, 0xF7, 0xB6, 0xAC, 0x98,
0x6F, 0x10, 0xAA, 0x20, 0x64, 0xD0, 0x7C, 0x25,
0x24, 0xF7, 0xD8, 0xA4, 0xCC, 0x2D, 0xBF, 0x85,
0x62, 0x6C, 0x4F, 0xFF, 0x9D, 0x71, 0x04, 0x98,
0x61, 0xB0, 0xBC, 0x31, 0xC1, 0xE9, 0xB8, 0x29,
0xA5, 0xEB, 0xD1, 0x1D, 0x65, 0x8E, 0xAE, 0x38,
0x55, 0x65, 0x22, 0xC7, 0xFD, 0x7E, 0xF2, 0x6A,
0xB6, 0xB1, 0x51, 0x37, 0x4B, 0x05, 0x8F, 0xA7,
0x2D, 0x3F, 0x5C, 0x04, 0x2B, 0xBA, 0x2C, 0x37,
0xCA, 0xDE, 0xD5, 0x3E, 0xA0, 0xA5, 0x86, 0x59,
0xA7, 0xD7, 0x38, 0x07, 0xFB, 0x79, 0xF6, 0x2D,
0xE1, 0xAA, 0x7C, 0xD1, 0x91, 0xBE, 0x39, 0xDF,
0x53, 0x3C, 0xD1, 0x44, 0x2C, 0xF9, 0x12, 0x7D,
0xB1, 0xCD, 0xF3, 0x35, 0x1F, 0x85, 0xA6, 0x64,
0x2F, 0xFD, 0x28, 0xF2, 0x85, 0xA8, 0xA7, 0x1F,
0x7F, 0xD9, 0x79, 0x30, 0x9B, 0xFC, 0x69, 0x3A,
0x9B, 0x1F, 0x55, 0x70, 0xC9, 0x60, 0x82, 0x3D,
0xE9, 0x5A, 0x37, 0x5F, 0x8C, 0xBD, 0x19, 0x5D,
0xCC, 0x1C, 0xBE, 0x26, 0x4A, 0xEA, 0x8B, 0x39,
0xCE, 0x0D, 0xBD, 0x63, 0x05, 0x98, 0x75, 0xAB,
0x08, 0x79, 0x90, 0xC7, 0x20, 0xFF, 0xE4, 0x0D,
0xB1, 0xA0, 0x92, 0x2B, 0x0C, 0x4B, 0x0C, 0xDC,
0xB9, 0x72, 0x2A, 0xA4, 0xCC, 0xA6, 0x32, 0xA3,
0x57, 0x82, 0xB4, 0xB9, 0x0F, 0x81, 0xC5, 0xD9,
0x7C, 0xB8, 0x0F, 0x7D, 0xEA, 0x5D, 0xD3, 0xC4,
0x2F, 0x31, 0x79, 0x11, 0xAD, 0x36, 0x56, 0x1F,
0xFA, 0xE3, 0xCE, 0xD2, 0x29, 0x23, 0xE8, 0x2C,
0xDF, 0x7D, 0x94, 0x28, 0x28, 0x9A, 0x0E, 0x64,
0xFC, 0x07, 0x11, 0x96, 0x06, 0x1A, 0x39, 0xCD,
0x04, 0x37, 0x37, 0xDB, 0xFE, 0x68, 0x37, 0xF5,
0x59, 0x54, 0xBC, 0xEF, 0xDB, 0x0C, 0x80, 0xCD,
0xD3, 0x46, 0xA8, 0xA2, 0xBE, 0xE0, 0x63, 0x80,
0xA1, 0x5F, 0x5D, 0xF1, 0xFB, 0x96, 0x8C, 0x06,
0x38, 0xB6, 0xCB, 0x70, 0xB0, 0xFB, 0xD3, 0x26,
0xB3, 0x8B, 0xC6, 0x85, 0x34, 0xB7, 0xAB, 0x5F,
0x7E, 0xC6, 0xAA, 0x79, 0x5B, 0x48, 0x11, 0x65,
0x9E, 0x2A, 0xCD, 0x6A, 0xF0, 0xB2, 0x93, 0xF5,
0x2B, 0x88, 0x45, 0xB7, 0xC9, 0xBE, 0x1A, 0x72,
0x60, 0x62, 0xA4, 0xA5, 0x3B, 0xC2, 0x1C, 0xC6,
0x21, 0x09, 0xA9, 0x40, 0xF6, 0x58, 0x2B, 0xE5,
0x70, 0xDC, 0xFC, 0x47, 0x3B, 0x08, 0xEE, 0xA9,
0x94, 0x26, 0x43, 0xFE, 0xA7, 0x75, 0xD6, 0x4E,
0x52, 0xF6, 0x46, 0xD1, 0x80, 0xEB, 0x3B, 0x8E,
0xBE, 0x54, 0x4F, 0xBD, 0x42, 0x0E, 0x41, 0xF9,
0x36, 0x7D, 0xB6, 0x7F, 0x99, 0x20, 0xC9, 0x63,
0xE7, 0x93, 0x02, 0x62, 0x59, 0x94, 0xCB, 0xC6,
0x62, 0xA9, 0x26, 0xE1, 0x1E, 0x03, 0x5A, 0x41,
0x2F, 0x43, 0x28, 0x75, 0xB7, 0x0C, 0x02, 0x9C,
0x1E, 0xE0, 0x40, 0xB3, 0xE2, 0x9A, 0xED, 0xC6,
0x20, 0x49, 0xEC, 0xDD, 0xC5, 0x64, 0x95, 0x83,
0x51, 0xAE, 0x46, 0x9D, 0x70, 0x17, 0xC6, 0x47,
0xD3, 0x82, 0xCC, 0x6A, 0x5D, 0x93, 0xB2, 0x85,
0x5B, 0x25, 0x05, 0xE7, 0x26, 0x2E, 0xD3, 0xDA,
0x1C, 0xD9, 0x06, 0xB6, 0x16, 0x69, 0x8C, 0x7F,
0xC8, 0xCF, 0x95, 0x18, 0xB5, 0x98, 0xC0, 0x42,
0x61, 0xDE, 0x77, 0x41, 0x3A, 0xF6, 0xE1, 0xB0,
0xE8, 0x64, 0x4A, 0xC2, 0x58, 0xBE, 0x27, 0xC6,
0x9B, 0x0D, 0x47, 0x1A, 0x09, 0x56, 0x7D, 0x2B,
0x19, 0x01, 0x88, 0xC7, 0xFB, 0x1E, 0xCF, 0x5E,
0xF6, 0xB0, 0x82, 0x87, 0xC0, 0xBE, 0xD6, 0xA5,
0xC3, 0xAC, 0x3A, 0x97, 0x88, 0x25, 0x81, 0xAA,
0x3A, 0xCE, 0x66, 0x88, 0x0F, 0xC3, 0x02, 0x50,
0x1C, 0xC3, 0x2B, 0xBC, 0x53, 0x52, 0xFE, 0xD2,
0x3F, 0x50, 0xC8, 0xB2, 0x19, 0x0A, 0x14, 0xB1,
0x73, 0x18, 0xB4, 0xDF, 0xBD, 0xED, 0x43, 0xC5,
0x91, 0xF4, 0x91, 0xBA, 0x7E, 0xB0, 0x7E, 0xA9,
0x43, 0x67, 0x06, 0xCF, 0x51, 0xC1, 0xBF, 0x63,
0x7E, 0x91, 0x76, 0xFF, 0x4F, 0x48, 0x91, 0xCF,
0xDF, 0x01, 0x4D, 0x7E, 0x81, 0x22, 0xFB, 0x79,
0xFC, 0x1D, 0xE3, 0xA7, 0x45, 0x16, 0xFB, 0xF2,
0x83, 0xC7, 0xAE, 0xC6, 0xC5, 0x81, 0xDB, 0xA2,
0x9F, 0x2F, 0xEA, 0xE6, 0x8E, 0x12, 0x8D, 0x43,
0x14, 0x26, 0x25, 0x0E, 0xB4, 0x18, 0xE8, 0x41,
0x84, 0xA3, 0x04, 0xDF, 0x97, 0xFF, 0xAA, 0x45,
0xEC, 0x18, 0xAA, 0xB1, 0xFC, 0xDC, 0xB9, 0xAB,
0xEE, 0xD1, 0xC4, 0x9E, 0x42, 0x3F, 0x5B, 0x8F,
0x9F, 0x22, 0xAF, 0xCC, 0x6F, 0xA0, 0x41, 0x41,
0xCB, 0xD3, 0xAC, 0x96, 0x20, 0xF1, 0x63, 0x56,
0x65, 0xCE, 0x83, 0xC6, 0x62, 0x04, 0x85, 0x16,
0x7F, 0x4E, 0xFB, 0xA0, 0x68, 0x11, 0x85, 0x5B,
0x51, 0xB6, 0x9F, 0xA2, 0xF5, 0xA1, 0xCF, 0x01,
0x9A, 0x80, 0x68, 0xC3, 0xE9, 0x7F, 0x9E, 0x2E,
0x83, 0x84, 0xDC, 0x3C, 0x35, 0xCF, 0x24, 0xBF,
0xF5, 0x00, 0x91, 0x45, 0x14, 0x65, 0xE0, 0xC5,
0x75, 0xDA, 0xEF, 0x14, 0xBD, 0xDB, 0x28, 0x8D,
0x30, 0x96, 0xC9, 0xFE, 0xA8, 0x49, 0x76, 0xC9,
0xED, 0x90, 0x4C, 0x2E, 0xF1, 0x14, 0x2C, 0xF7,
0x13, 0x7C, 0xF1, 0xCC, 0x67, 0xA5, 0x11, 0x55,
0xBD, 0x66, 0x13, 0x8A, 0x76, 0xF9, 0xAC, 0xC9,
0x51, 0x8A, 0xBB, 0x5D, 0x29, 0xEF, 0xF6, 0x37,
0xA0, 0x3E, 0x99, 0x77, 0x6B, 0xE5, 0xCD, 0x06,
0xAC, 0x57, 0x07, 0x37, 0x44, 0x3D, 0x5D, 0xD7,
0xB6, 0x5C, 0xCB, 0x77, 0xD0, 0x4C, 0x28, 0x9D,
0x12, 0x69, 0x5A, 0x68, 0xD1, 0x15, 0x30, 0xC4,
0x30, 0xD2, 0x20, 0xDF, 0xD5, 0x73, 0x9F, 0x83,
0xE9, 0x4C, 0x55, 0xF5, 0xAF, 0xAA, 0x37, 0xF8,
0x28, 0xB6, 0x3F, 0x99, 0x4B, 0x15, 0x1E, 0x40,
0xAB, 0x4F, 0x58, 0x3D, 0x3B, 0x81, 0x7D, 0x62,
0x28, 0x6E, 0x73, 0x58, 0x50, 0x36, 0x49, 0x01,
0xF7, 0x04, 0x3A, 0x23, 0x28, 0xDA, 0x15, 0xC5,
0xE3, 0xF6, 0x6F, 0xE1, 0x79, 0x07, 0xFB, 0xAA,
0xFF, 0x44, 0x48, 0x53, 0x9E, 0x7F, 0x8D, 0x89,
0x88, 0x1A, 0x9A, 0xF9, 0x47, 0x58, 0x20, 0xBB,
0x79, 0x4A, 0x2A, 0x14, 0x03, 0x9B, 0x65, 0x4C,
0x67, 0x02, 0x02, 0xFE, 0xEB, 0xCD, 0xCB, 0x84,
0xF5, 0xCE, 0x32, 0x59, 0xBC, 0xEA, 0xEC, 0xB1,
0x3C, 0x22, 0xCF, 0x9D, 0xB0, 0x34, 0x6D, 0xE6,
0x5A, 0x37, 0xC0, 0x22, 0xAA, 0xF3, 0xB5, 0x71,
0x90, 0x21, 0xE0, 0xB6, 0x19, 0xE9, 0xB3, 0x10,
0xCE, 0x5B, 0xF9, 0xD4, 0x25, 0x30, 0x7D, 0xF6,
0x7D, 0xB6, 0x16, 0xFC, 0x20, 0x3C, 0x2F, 0x96,
0xD5, 0x79, 0x90, 0x88, 0x24, 0x5D, 0x46, 0x64,
0x99, 0xC1, 0xF8, 0x7F, 0x96, 0xA7, 0xB5, 0xA9,
0x47, 0xA3, 0x14, 0xED, 0x93, 0xED, 0x30, 0x56,
0x58, 0xA5, 0xD4, 0x54, 0x2A, 0xF3, 0x89, 0x27,
0x7C, 0x55, 0x41, 0x11, 0x27, 0x9D, 0xF6, 0x4D,
0xA6, 0xB1, 0x00, 0xE0, 0xB0, 0xF6, 0x1E, 0xAB,
0x20, 0x1F, 0xAE, 0x8A, 0x82, 0xA7, 0x49, 0xFC,
0xBB, 0x66, 0xAC, 0x97, 0x95, 0x49, 0x29, 0xCB,
0x6F, 0xF4, 0xC1, 0xB7, 0x6B, 0xF9, 0x8C, 0x25,
0xC6, 0xF0, 0xB5, 0x81, 0xB0, 0xA2, 0x4D, 0xCC,
0x2E, 0xD0, 0x13, 0x5F, 0x96, 0x3F, 0xCD, 0xD0,
0x52, 0xD1, 0xFE, 0xF9, 0xC2, 0x7E, 0x9D, 0xAB,
0xCB, 0x95, 0x0F, 0x27, 0x01, 0x9E, 0x23, 0x6B,
0x19, 0xFF, 0x52, 0x55, 0x71, 0x0A, 0xD4, 0xBB,
0x43, 0x65, 0x29, 0x66, 0xBE, 0x2D, 0x6C, 0xE3,
0x2A, 0x7C, 0xB4, 0x02, 0x32, 0x59, 0x94, 0x80,
0x14, 0xE7, 0x62, 0xE4, 0xCE, 0xB0, 0xCA, 0xCA,
0x37, 0xD7, 0x0C, 0x68, 0x29, 0xE2, 0x92, 0xE1,
0xEB, 0x91, 0xE5, 0xA1, 0x0C, 0xFC, 0x55, 0xCB,
0x56, 0xB3, 0x96, 0xFB, 0x64, 0xD9, 0x53, 0x8E,
0x82, 0x2B, 0xDF, 0x7F, 0xCB, 0x2A, 0xF6, 0x3C,
0xA7, 0x89, 0x52, 0x13, 0x2C, 0x6A, 0x93, 0xA2,
0x74, 0xF5, 0x91, 0x00, 0x17, 0xAA, 0x74, 0x45,
0x63, 0x5A, 0xE5, 0xC3, 0x16, 0xFC, 0x0E, 0xF7,
0xF3, 0xA4, 0x55, 0x8A, 0xA2, 0x60, 0x24, 0x57,
0x25, 0x2C, 0x94, 0xE0, 0xF5, 0x32, 0x54, 0x4A,
0x2D, 0x63, 0x5F, 0xD8, 0x35, 0x96, 0xBD, 0xFE,
0x90, 0x33, 0x17, 0xF6, 0xB5, 0x81, 0x02, 0xFA,
0x5C, 0x94, 0x3A, 0xBE, 0x22, 0xB9, 0xFC, 0x3E,
0x09, 0xE4, 0x76, 0xD7, 0x03, 0x38, 0x38, 0xC2,
0xC2, 0x0D, 0x66, 0x3C, 0xD0, 0x91, 0x5C, 0xF4,
0x0E, 0xC2, 0xDE, 0x46, 0x90, 0x2E, 0xF5, 0x22,
0xA9, 0x3D, 0x15, 0x20, 0x5F, 0x17, 0x10, 0x5A,
0x54, 0x63, 0x93, 0x7B, 0xC3, 0x00, 0x3D, 0x42,
0x73, 0xF1, 0xAD, 0xC1, 0xDE, 0x76, 0x18, 0x9C,
0x68, 0x17, 0xBF, 0x3B, 0xE0, 0x30, 0x82, 0x02,
0xF9, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, 0x02, 0xEA,
0x04, 0x82, 0x02, 0xE6, 0x30, 0x82, 0x02, 0xE2,
0x30, 0x82, 0x02, 0xDE, 0x06, 0x0B, 0x2A, 0x86,
0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01,
0x02, 0xA0, 0x82, 0x02, 0xA6, 0x30, 0x82, 0x02,
0xA2, 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48,
0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30,
0x0E, 0x04, 0x08, 0x34, 0x37, 0x27, 0x5F, 0xE8,
0xD6, 0x00, 0x0D, 0x02, 0x02, 0x08, 0x00, 0x04,
0x82, 0x02, 0x80, 0xC0, 0xE6, 0xB1, 0x63, 0x73,
0xFC, 0xBF, 0x50, 0xFB, 0x54, 0xCF, 0x67, 0x16,
0xF8, 0x28, 0x48, 0x13, 0x7F, 0xF2, 0xBD, 0x66,
0x70, 0xC7, 0xF6, 0x01, 0xD0, 0x58, 0xF4, 0xA4,
0xD9, 0x45, 0xE2, 0x63, 0x92, 0x7F, 0x78, 0x2B,
0xB6, 0xDB, 0x16, 0x44, 0x1D, 0x11, 0xCB, 0xC3,
0x20, 0xA9, 0x8A, 0x96, 0x13, 0xB8, 0x6E, 0xF3,
0xDA, 0x46, 0x05, 0x2C, 0xF9, 0x67, 0xBB, 0x05,
0x88, 0xC0, 0xC8, 0x60, 0x09, 0xA3, 0x82, 0x27,
0x33, 0xEB, 0xEE, 0x43, 0x98, 0xE9, 0xE2, 0x24,
0xA8, 0x06, 0xD5, 0xFF, 0xF5, 0xC0, 0x79, 0x4B,
0x06, 0x40, 0xE6, 0x28, 0xC6, 0x6E, 0x4E, 0x03,
0xCC, 0x9B, 0xB6, 0xBD, 0xB6, 0x81, 0x88, 0x5C,
0x34, 0x6B, 0x8B, 0x15, 0x23, 0x75, 0x21, 0xAC,
0x79, 0xFD, 0xDB, 0x80, 0x1D, 0x20, 0x84, 0xF1,
0x47, 0xAF, 0x7B, 0x40, 0x6C, 0xD2, 0x64, 0x52,
0x11, 0x1B, 0x01, 0x1E, 0xB5, 0xA9, 0x4B, 0xC4,
0x51, 0x54, 0x40, 0xE2, 0xC8, 0xEB, 0x20, 0x48,
0x2D, 0x40, 0xF8, 0xC6, 0x58, 0x5A, 0xE3, 0x34,
0xD8, 0x79, 0x04, 0xD7, 0xD6, 0x07, 0xF2, 0x12,
0x66, 0xC8, 0x31, 0x37, 0x71, 0x60, 0xF4, 0x75,
0xDC, 0x60, 0x54, 0x19, 0x6A, 0x75, 0x56, 0xC5,
0xA9, 0x67, 0x4A, 0x03, 0x7A, 0xFD, 0x12, 0x59,
0x2B, 0x74, 0xE6, 0xA5, 0xE2, 0xF8, 0xBB, 0x1E,
0x76, 0x96, 0xD4, 0xD4, 0x3F, 0x8B, 0xAD, 0x90,
0xAF, 0x04, 0x41, 0xDB, 0xD8, 0xCC, 0x2D, 0x37,
0x06, 0x20, 0x9B, 0xE7, 0x98, 0x87, 0x12, 0xAC,
0x70, 0xC9, 0xF4, 0x1C, 0x28, 0xFB, 0x2C, 0x9E,
0x18, 0xE1, 0x6D, 0x79, 0x34, 0xBC, 0xAC, 0xCB,
0x75, 0x92, 0x7E, 0x8E, 0x7C, 0xA9, 0x0B, 0x86,
0x4A, 0x88, 0xFB, 0xE8, 0xBE, 0x6A, 0x32, 0xEF,
0x58, 0xCC, 0x4C, 0x89, 0x50, 0xEF, 0xDF, 0xE0,
0xDD, 0x35, 0x07, 0x8C, 0x01, 0x8B, 0x57, 0x38,
0xB5, 0x64, 0xBB, 0x0A, 0xC2, 0xD8, 0xAB, 0xC5,
0x45, 0xA6, 0x83, 0xBF, 0xA6, 0xA2, 0xCC, 0x06,
0x64, 0xBE, 0x84, 0x04, 0x55, 0x8E, 0xF4, 0x4C,
0xB5, 0xBC, 0xE5, 0x97, 0x2B, 0x3C, 0x42, 0x44,
0x91, 0x9B, 0xB2, 0x65, 0x70, 0x02, 0xC5, 0xB7,
0x71, 0xB3, 0xF0, 0xAA, 0x46, 0x4F, 0x42, 0x40,
0x53, 0x65, 0x89, 0xA5, 0x6C, 0xBC, 0xB5, 0x6C,
0x0C, 0x3B, 0x50, 0x46, 0x67, 0xFA, 0x14, 0x68,
0x01, 0xE7, 0xA6, 0xD4, 0xB5, 0xD0, 0x82, 0x44,
0x92, 0x2C, 0xE3, 0x43, 0x5D, 0x34, 0x7C, 0x04,
0xA3, 0x4D, 0x2F, 0x5A, 0x75, 0xE7, 0x0B, 0x64,
0xD0, 0xAE, 0x7F, 0xCB, 0xDD, 0x7D, 0x05, 0x88,
0x4C, 0x34, 0xBB, 0xF4, 0x00, 0xCE, 0x1C, 0x13,
0x4E, 0xA3, 0xE3, 0x60, 0x4B, 0x50, 0x4E, 0xE1,
0x26, 0x22, 0x51, 0xD4, 0x32, 0x60, 0xC6, 0x3E,
0x7D, 0x4A, 0x3E, 0x56, 0x78, 0xBD, 0x5F, 0x23,
0x7F, 0x0A, 0xA0, 0xC1, 0x1A, 0x60, 0xA2, 0x7C,
0x9E, 0x17, 0x6F, 0xD8, 0x73, 0x0F, 0x1A, 0x1F,
0x47, 0x58, 0x44, 0x20, 0x80, 0xC6, 0x5D, 0x6E,
0xEC, 0xFF, 0xCA, 0x65, 0xA1, 0xFB, 0xEE, 0xF2,
0x56, 0x1A, 0x16, 0x9E, 0x4D, 0xCA, 0x67, 0x81,
0x23, 0xDE, 0xBE, 0x5E, 0x31, 0x56, 0xF0, 0x34,
0xBA, 0x12, 0xFC, 0x07, 0x03, 0x96, 0xD2, 0x8E,
0xCE, 0xA6, 0xF6, 0x74, 0x07, 0x4F, 0x63, 0x40,
0x14, 0x0A, 0xD6, 0x45, 0xB4, 0xF1, 0x72, 0x87,
0x34, 0x89, 0x5C, 0x06, 0x1B, 0x8C, 0x0E, 0xA2,
0x84, 0x50, 0x12, 0xAD, 0x26, 0x5B, 0x4F, 0x6B,
0x23, 0x9D, 0x3C, 0xBB, 0x8A, 0xDA, 0x08, 0x4B,
0x93, 0x47, 0x02, 0x96, 0x76, 0xD4, 0x87, 0xE9,
0x4B, 0x69, 0x82, 0xD6, 0xCC, 0x69, 0x02, 0xC0,
0xA4, 0x75, 0x7A, 0x90, 0xFD, 0xF6, 0xD6, 0x9D,
0xE2, 0x4C, 0xB6, 0xFA, 0x61, 0xA5, 0x7C, 0x18,
0xEA, 0x84, 0xA1, 0x74, 0x85, 0x2E, 0xCA, 0xF9,
0x17, 0x29, 0xFF, 0x67, 0x70, 0xC9, 0x6F, 0xF1,
0x41, 0xEF, 0xA1, 0x59, 0x54, 0xA0, 0x99, 0x14,
0x48, 0x74, 0x5D, 0x14, 0x3E, 0x04, 0xCE, 0xF7,
0x16, 0x9F, 0x8A, 0x41, 0xF4, 0xAE, 0xB3, 0x10,
0xCE, 0x19, 0xC2, 0x83, 0x7B, 0xD0, 0x26, 0x1E,
0x75, 0x8A, 0x0A, 0x40, 0x4A, 0xB8, 0xE0, 0x5C,
0x13, 0x8B, 0xCC, 0x6F, 0xF3, 0x00, 0xB3, 0x64,
0x1B, 0x3C, 0x3D, 0x08, 0x3B, 0x9F, 0xD0, 0x9B,
0xE5, 0x72, 0x45, 0x96, 0x95, 0x4D, 0x66, 0xC7,
0x79, 0x5D, 0x3A, 0x1A, 0x94, 0x64, 0x94, 0x07,
0x1A, 0xE8, 0x7C, 0xD1, 0x1C, 0xB1, 0x7E, 0x32,
0x28, 0x1A, 0x90, 0x22, 0xD9, 0x86, 0x9B, 0x9C,
0x9B, 0x0C, 0x04, 0x31, 0x85, 0x10, 0x42, 0x50,
0x40, 0x11, 0x72, 0xAB, 0x94, 0x0C, 0xAF, 0xC3,
0x22, 0x1A, 0xC1, 0x31, 0x25, 0x30, 0x23, 0x06,
0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0xFD, 0x78,
0xA7, 0x70, 0x1F, 0x8A, 0xE9, 0x07, 0xB9, 0xCA,
0x3C, 0xD1, 0xE8, 0xDC, 0x68, 0xFF, 0x02, 0x61,
0x29, 0x97, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09,
0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05,
0x00, 0x04, 0x14, 0x22, 0x7E, 0x99, 0x10, 0xB3,
0x99, 0x79, 0xE7, 0x14, 0x7F, 0x91, 0x59, 0x24,
0x4F, 0x2F, 0xCF, 0xE8, 0x53, 0x1D, 0x0F, 0x04,
0x08, 0x30, 0x1E, 0x5C, 0xE4, 0x3C, 0x66, 0xDF,
0xB0, 0x02, 0x02, 0x08, 0x00]
};
gTestSuite.doTestWithCertificate(
new Blob([new Uint8Array(testCertInfo.blob)]),
testCertInfo.password,
testCertInfo.nickname,
testCertInfo.usage
);
@@ -0,0 +1,106 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
// Binary form of test certificate.
var testCertInfo = {
nickname: 'Test Certificate',
password: '',
usage: ['ServerCert'],
blob: [0x30, 0x82, 0x02, 0xae, 0x30, 0x82, 0x02, 0x17,
0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
0x92, 0x49, 0xe2, 0x62, 0x71, 0xf6, 0xc7, 0x92,
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
0x70, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x54, 0x57, 0x31, 0x0f,
0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
0x06, 0x54, 0x61, 0x69, 0x70, 0x65, 0x69, 0x31,
0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a,
0x0c, 0x07, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c,
0x61, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x0b, 0x0c, 0x02, 0x51, 0x41, 0x31, 0x0e,
0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
0x05, 0x47, 0x65, 0x72, 0x72, 0x79, 0x31, 0x21,
0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x67,
0x63, 0x68, 0x61, 0x6e, 0x67, 0x40, 0x6d, 0x6f,
0x7a, 0x69, 0x6c, 0x6c, 0x61, 0x2e, 0x63, 0x6f,
0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30,
0x35, 0x32, 0x33, 0x30, 0x39, 0x34, 0x32, 0x33,
0x37, 0x5a, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x35,
0x32, 0x32, 0x30, 0x39, 0x34, 0x32, 0x33, 0x37,
0x5a, 0x30, 0x70, 0x31, 0x0b, 0x30, 0x09, 0x06,
0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x54, 0x57,
0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04,
0x08, 0x0c, 0x06, 0x54, 0x61, 0x69, 0x70, 0x65,
0x69, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55,
0x04, 0x0a, 0x0c, 0x07, 0x4d, 0x6f, 0x7a, 0x69,
0x6c, 0x6c, 0x61, 0x31, 0x0b, 0x30, 0x09, 0x06,
0x03, 0x55, 0x04, 0x0b, 0x0c, 0x02, 0x51, 0x41,
0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04,
0x03, 0x0c, 0x05, 0x47, 0x65, 0x72, 0x72, 0x79,
0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86,
0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16,
0x12, 0x67, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x40,
0x6d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0x2e,
0x63, 0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d,
0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00,
0xd3, 0xdb, 0x54, 0xcc, 0xca, 0x0b, 0xee, 0xf9,
0x8a, 0x37, 0x0d, 0x06, 0x8b, 0x20, 0x00, 0x4a,
0x55, 0x84, 0x90, 0x1a, 0xb7, 0x9c, 0x91, 0xb2,
0x38, 0x6b, 0x8b, 0x32, 0x7a, 0x89, 0x9e, 0x79,
0x71, 0x88, 0x43, 0x21, 0x94, 0x18, 0xa8, 0xfc,
0xe3, 0x7a, 0x8a, 0xb3, 0xa1, 0xf7, 0x23, 0xe7,
0x1a, 0xe3, 0xe7, 0x0d, 0xf1, 0x66, 0x21, 0x58,
0x21, 0x85, 0x5b, 0x35, 0xec, 0x68, 0xd2, 0xfd,
0x44, 0x76, 0x93, 0x05, 0xbb, 0x89, 0x7d, 0x92,
0xf9, 0xce, 0x75, 0xa3, 0xeb, 0x39, 0xc1, 0x7d,
0x7e, 0x50, 0xf9, 0xb8, 0x60, 0x61, 0xf7, 0x2f,
0x54, 0x39, 0xfe, 0x8a, 0x20, 0xb2, 0x0d, 0x48,
0x7f, 0x18, 0x0d, 0x02, 0xcc, 0x7b, 0x8e, 0x31,
0xe9, 0xbe, 0xfc, 0x96, 0x2e, 0x63, 0x6f, 0xfa,
0x4c, 0xc4, 0xcf, 0x8a, 0xe4, 0x13, 0x67, 0xf1,
0xec, 0x3e, 0xd8, 0x23, 0xa1, 0xbf, 0x67, 0x71,
0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x50, 0x30,
0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
0x04, 0x16, 0x04, 0x14, 0x13, 0xe1, 0xac, 0xa4,
0x75, 0x3d, 0x2c, 0x5f, 0xe5, 0x41, 0x42, 0x90,
0x5a, 0x48, 0x5c, 0x46, 0xbc, 0x24, 0x8e, 0xa1,
0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
0x18, 0x30, 0x16, 0x80, 0x14, 0x13, 0xe1, 0xac,
0xa4, 0x75, 0x3d, 0x2c, 0x5f, 0xe5, 0x41, 0x42,
0x90, 0x5a, 0x48, 0x5c, 0x46, 0xbc, 0x24, 0x8e,
0xa1, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81,
0x81, 0x00, 0xaa, 0x6b, 0x62, 0x53, 0x74, 0x2a,
0x20, 0x76, 0xab, 0xd2, 0x60, 0x06, 0xfd, 0x88,
0xf5, 0x1c, 0x85, 0xe6, 0x57, 0xf1, 0xf0, 0x18,
0x97, 0x7c, 0x70, 0xb8, 0xb4, 0x7c, 0xcc, 0x58,
0x8d, 0xf4, 0x7c, 0xb6, 0x34, 0xcc, 0x15, 0x79,
0xaf, 0x75, 0xa9, 0x0b, 0xd1, 0xea, 0xf8, 0x85,
0x7c, 0xe8, 0x19, 0xe9, 0x13, 0x90, 0x84, 0x5f,
0x21, 0x94, 0x0a, 0x4d, 0x15, 0xef, 0xd1, 0x16,
0xd4, 0xba, 0x2c, 0x59, 0x1b, 0x83, 0x23, 0xf5,
0xa5, 0xcd, 0xbd, 0xda, 0x32, 0x73, 0x46, 0x49,
0x98, 0xf3, 0xfb, 0x50, 0x6e, 0x30, 0xd7, 0x3e,
0x31, 0xd6, 0xe8, 0x65, 0x2f, 0x5a, 0xf1, 0x0f,
0x7b, 0x0a, 0x21, 0x61, 0x8e, 0x45, 0x29, 0x4f,
0x7a, 0x04, 0xda, 0x29, 0xfc, 0x6f, 0xc5, 0x5e,
0xee, 0xe1, 0x0f, 0xd5, 0x4b, 0xb7, 0xc9, 0x6a,
0x8e, 0x7c, 0x19, 0xef, 0x6e, 0x64, 0x98, 0xfe,
0xe3, 0x35]
};
gTestSuite.doTestWithCertificate(
new Blob([new Uint8Array(testCertInfo.blob)]),
testCertInfo.password,
testCertInfo.nickname,
testCertInfo.usage
);
@@ -0,0 +1,34 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
// Binary form of test certificate.
var testCertInfo = {
nickname: 'Test Certificate',
password: '',
usage: ['UserCert'],
blob: '-----BEGIN CERTIFICATE-----\n' +
'MIICTjCCAbegAwIBAgICNV4wDQYJKoZIhvcNAQEEBQAwgYUxCzAJBgNVBAYTAklU\n' +
'MRYwFAYDVQQKEw1aZXJvc2hlbGwubmV0MRAwDgYDVQQLEwdFeGFtcGxlMR0wGwYD\n' +
'VQQDExRaZXJvU2hlbGwgRXhhbXBsZSBDQTEtMCsGCSqGSIb3DQEJARYeRnVsdmlv\n' +
'LlJpY2NpYXJkaUB6ZXJvc2hlbGwubmV0MB4XDTEzMDMxMTAzMzg1MloXDTE0MDMx\n' +
'MTAzMzg1MlowIzEOMAwGA1UECxMFVXNlcnMxETAPBgNVBAMTCGNodWNrbGVlMIGf\n' +
'MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDvVzFhQAVqAIHW5DlAhp4FEGEei7k7\n' +
'uVUeqkH7JAsww6zmDLg9yZlcZAc95N0lkz022gLXehH2M0R1FOR++nkqofzWfc7w\n' +
'n79ith+dU2GQMeKq7vPGDYXpgIkEKbYfzKj3fY3129MlTxJQt1UD/ejz38V8HKgw\n' +
'qKSuwo0NVeY66QIDAQABoy4wLDALBgNVHQ8EBAMCBLAwHQYDVR0lBBYwFAYIKwYB\n' +
'BQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEBBAUAA4GBAJWgfX5vYSD7MGZk1rTF\n' +
'DSziWYGqpR+Moo3qQ+9qLG8m+XVM9hckWpY31A5sWAeCZCe1SSNLFbbgsaOyPZE2\n' +
'NqMyvs61Vszpc2mmWAYT6j2OU2tw8p5pcUZd6eIp7Gc3fLymiX/WoSmilZKmrGUZ\n' +
'Q15R+TCpclUsaNrUGjybgaw7\n' +
'-----END CERTIFICATE-----'
};
gTestSuite.doTestWithCertificate(
new Blob([testCertInfo.blob]),
testCertInfo.password,
testCertInfo.nickname,
testCertInfo.usage
);
@@ -0,0 +1,65 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
const STATIC_IP_CONFIG = {
enabled: true,
ipaddr: "192.168.111.222",
proxy: "",
maskLength: 24,
gateway: "192.168.111.1",
dns1: "8.8.8.8",
dns2: "8.8.4.4",
};
const TESTING_HOSTAPD = [{ ssid: 'ap0' }];
function testAssociateWithStaticIp(aNetwork, aStaticIpConfig) {
return gTestSuite.setStaticIpMode(aNetwork, aStaticIpConfig)
.then(() => gTestSuite.testAssociate(aNetwork))
// Check ip address and prefix.
.then(() => gTestSuite.exeAndParseNetcfg())
.then((aResult) => {
is(aResult["wlan0"].ip, aStaticIpConfig.ipaddr, "Check ip address");
is(aResult["wlan0"].prefix, aStaticIpConfig.maskLength, "Check prefix");
})
// Check routing.
.then(() => gTestSuite.exeAndParseIpRoute())
.then((aResult) => {
is(aResult["wlan0"].src, aStaticIpConfig.ipaddr, "Check ip address");
is(aResult["wlan0"].default, true, "Check default route");
is(aResult["wlan0"].gateway, aStaticIpConfig.gateway, "Check gateway");
});
}
function findDesireNetwork(aNetworks) {
let i = gTestSuite.getFirstIndexBySsid(TESTING_HOSTAPD[0].ssid, aNetworks);
if (-1 !== i) {
return aNetworks[i];
}
return aNetworks[0];
}
// Start test.
gTestSuite.doTestWithoutStockAp(function() {
return gTestSuite.ensureWifiEnabled(true)
// Start custom hostapd for testing.
.then(() => gTestSuite.startHostapds(TESTING_HOSTAPD))
.then(() => gTestSuite.verifyNumOfProcesses('hostapd',
TESTING_HOSTAPD.length))
// Perform a wifi scan, and then run the static ip test
.then(() => gTestSuite.requestWifiScan())
.then((aNetworks) => findDesireNetwork(aNetworks))
.then((aNetwork) => testAssociateWithStaticIp(aNetwork,
STATIC_IP_CONFIG))
// Kill running hostapd.
.then(gTestSuite.killAllHostapd)
.then(() => gTestSuite.verifyNumOfProcesses('hostapd', 0));
});
@@ -4,6 +4,8 @@
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
const TESTING_HOSTAPD = [{ ssid: 'ap0' }];
function connectToFirstNetwork() {
let firstNetwork;
return gTestSuite.requestWifiScan()
@@ -18,6 +20,11 @@ gTestSuite.doTestTethering(function() {
let firstNetwork;
return gTestSuite.ensureWifiEnabled(true)
// Start custom hostapd for testing.
.then(() => gTestSuite.startHostapds(TESTING_HOSTAPD))
.then(() => gTestSuite.verifyNumOfProcesses('hostapd', TESTING_HOSTAPD.length))
// Connect to the testing AP and wait for data becoming disconnected.
.then(function () {
return Promise.all([
// 1) Set up the event listener first:
@@ -46,8 +53,12 @@ gTestSuite.doTestTethering(function() {
// Wifi should be enabled, RIL data should become disconnected and
// we should connect to an wifi AP.
gTestSuite.waitForWifiManagerEventOnce('enabled'),
gTestSuite.waitForRilDataConnected(false),
gTestSuite.waitForConnected(firstNetwork),
// Due to Bug 1168285, after re-enablin wifi, the remembered network
// will not be connected automatically. Leave "auto connect test"
// covered by test_wifi_auto_connect.js.
//gTestSuite.waitForRilDataConnected(false),
//gTestSuite.waitForConnected(firstNetwork),
// 2) Stop wifi tethering.
gTestSuite.requestTetheringEnabled(false)
@@ -55,5 +66,9 @@ gTestSuite.doTestTethering(function() {
})
// Remove wlan0 from default route by disabling wifi. Otherwise,
// it will cause the subsequent test cases loading page error.
.then(() => gTestSuite.requestWifiEnabled(false));
.then(() => gTestSuite.requestWifiEnabled(false))
// Kill running hostapd.
.then(gTestSuite.killAllHostapd)
.then(() => gTestSuite.verifyNumOfProcesses('hostapd', 0));
});
+19 -43
View File
@@ -585,10 +585,8 @@ InterruptCallback(JSContext* aCx)
return worker->InterruptCallback(aCx);
}
class LogViolationDetailsRunnable final : public Runnable
class LogViolationDetailsRunnable final : public WorkerMainThreadRunnable
{
WorkerPrivate* mWorkerPrivate;
nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
nsString mFileName;
uint32_t mLineNum;
@@ -596,32 +594,17 @@ public:
LogViolationDetailsRunnable(WorkerPrivate* aWorker,
const nsString& aFileName,
uint32_t aLineNum)
: mWorkerPrivate(aWorker), mFileName(aFileName), mLineNum(aLineNum)
: WorkerMainThreadRunnable(aWorker,
NS_LITERAL_CSTRING("RuntimeService :: LogViolationDetails"))
, mFileName(aFileName), mLineNum(aLineNum)
{
MOZ_ASSERT(aWorker);
}
NS_DECL_ISUPPORTS_INHERITED
bool
Dispatch()
{
AutoSyncLoopHolder syncLoop(mWorkerPrivate);
mSyncLoopTarget = syncLoop.EventTarget();
MOZ_ASSERT(mSyncLoopTarget);
if (NS_FAILED(NS_DispatchToMainThread(this))) {
return false;
}
return syncLoop.Run();
}
virtual bool MainThreadRun() override;
private:
~LogViolationDetailsRunnable() {}
NS_DECL_NSIRUNNABLE
};
bool
@@ -644,7 +627,11 @@ ContentSecurityPolicyAllows(JSContext* aCx)
RefPtr<LogViolationDetailsRunnable> runnable =
new LogViolationDetailsRunnable(worker, fileName, lineNum);
runnable->Dispatch();
ErrorResult rv;
runnable->Dispatch(rv);
if (NS_WARN_IF(rv.Failed())) {
rv.SuppressException();
}
}
return worker->IsEvalAllowed();
@@ -1463,17 +1450,13 @@ RuntimeService::RegisterWorker(WorkerPrivate* aWorkerPrivate)
if (queued) {
domainInfo->mQueuedWorkers.AppendElement(aWorkerPrivate);
// Worker spawn gets queued due to hitting max workers per domain
// limit so let's log a warning.
WorkerPrivate::ReportErrorToConsole("HittingMaxWorkersPerDomain2");
if (isServiceWorker || isSharedWorker) {
AssertIsOnMainThread();
// ServiceWorker spawn gets queued due to hitting max workers per domain
// limit so let's log a warning.
// Note: aWorkerPrivate->GetDocument() call might result nullptr due to
// no window so the message warning will show up in the browser console.
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
NS_LITERAL_CSTRING("DOM"),
aWorkerPrivate->GetDocument(),
nsContentUtils::eDOM_PROPERTIES,
"HittingMaxWorkersPerDomain");
/* nothing */
}
}
else if (parent) {
@@ -2594,10 +2577,8 @@ RuntimeService::JSVersionChanged(const char* /* aPrefName */, void* /* aClosure
options.behaviors().setVersion(useLatest ? JSVERSION_LATEST : JSVERSION_DEFAULT);
}
NS_IMPL_ISUPPORTS_INHERITED0(LogViolationDetailsRunnable, Runnable)
NS_IMETHODIMP
LogViolationDetailsRunnable::Run()
bool
LogViolationDetailsRunnable::MainThreadRun()
{
AssertIsOnMainThread();
@@ -2612,12 +2593,7 @@ LogViolationDetailsRunnable::Run()
}
}
RefPtr<MainThreadStopSyncLoopRunnable> response =
new MainThreadStopSyncLoopRunnable(mWorkerPrivate, mSyncLoopTarget.forget(),
true);
MOZ_ALWAYS_TRUE(response->Dispatch());
return NS_OK;
return true;
}
NS_IMPL_ISUPPORTS(WorkerBackgroundChildCallback, nsIIPCBackgroundChildCreateCallback)
+48 -37
View File
@@ -9,6 +9,7 @@
#include "nsIChannel.h"
#include "nsIContentPolicy.h"
#include "nsIContentSecurityPolicy.h"
#include "nsIDocShell.h"
#include "nsIHttpChannel.h"
#include "nsIHttpChannelInternal.h"
#include "nsIInputStreamPump.h"
@@ -890,6 +891,28 @@ private:
nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL;
// Get the top-level worker.
WorkerPrivate* topWorkerPrivate = mWorkerPrivate;
WorkerPrivate* parent = topWorkerPrivate->GetParent();
while (parent) {
topWorkerPrivate = parent;
parent = topWorkerPrivate->GetParent();
}
// If the top-level worker is a dedicated worker and has a window, and the
// window has a docshell, the caching behavior of this worker should match
// that of that docshell.
if (topWorkerPrivate->IsDedicatedWorker()) {
nsCOMPtr<nsPIDOMWindow> window = topWorkerPrivate->GetWindow();
if (window) {
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(window);
if (docShell) {
nsresult rv = docShell->GetDefaultLoadFlags(&loadFlags);
NS_ENSURE_SUCCESS(rv, rv);
}
}
}
// If we are loading a script for a ServiceWorker then we must not
// try to intercept it. If the interception matches the current
// ServiceWorker's scope then we could deadlock the load.
@@ -1615,15 +1638,17 @@ CacheScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aCont
const uint8_t* aString)
{
AssertIsOnMainThread();
MOZ_ASSERT(mLoadInfo.mCacheStatus == ScriptLoadInfo::ReadingFromCache);
mPump = nullptr;
if (NS_FAILED(aStatus)) {
MOZ_ASSERT(mLoadInfo.mCacheStatus == ScriptLoadInfo::ReadingFromCache ||
mLoadInfo.mCacheStatus == ScriptLoadInfo::Cancel);
Fail(aStatus);
return NS_OK;
}
MOZ_ASSERT(mLoadInfo.mCacheStatus == ScriptLoadInfo::ReadingFromCache);
mLoadInfo.mCacheStatus = ScriptLoadInfo::Cached;
MOZ_ASSERT(mPrincipalInfo);
@@ -1632,43 +1657,42 @@ CacheScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aCont
return NS_OK;
}
class ChannelGetterRunnable final : public Runnable
class ChannelGetterRunnable final : public WorkerMainThreadRunnable
{
WorkerPrivate* mParentWorker;
nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
const nsAString& mScriptURL;
nsIChannel** mChannel;
nsresult mResult;
public:
ChannelGetterRunnable(WorkerPrivate* aParentWorker,
nsIEventTarget* aSyncLoopTarget,
const nsAString& aScriptURL,
nsIChannel** aChannel)
: mParentWorker(aParentWorker), mSyncLoopTarget(aSyncLoopTarget),
mScriptURL(aScriptURL), mChannel(aChannel), mResult(NS_ERROR_FAILURE)
: WorkerMainThreadRunnable(aParentWorker,
NS_LITERAL_CSTRING("ScriptLoader :: ChannelGetter"))
, mScriptURL(aScriptURL)
, mChannel(aChannel)
, mResult(NS_ERROR_FAILURE)
{
MOZ_ASSERT(mParentWorker);
MOZ_ASSERT(aParentWorker);
aParentWorker->AssertIsOnWorkerThread();
MOZ_ASSERT(aSyncLoopTarget);
}
NS_IMETHOD
Run() override
virtual bool
MainThreadRun() override
{
AssertIsOnMainThread();
nsIPrincipal* principal = mParentWorker->GetPrincipal();
nsIPrincipal* principal = mWorkerPrivate->GetPrincipal();
MOZ_ASSERT(principal);
// Figure out our base URI.
nsCOMPtr<nsIURI> baseURI = mParentWorker->GetBaseURI();
nsCOMPtr<nsIURI> baseURI = mWorkerPrivate->GetBaseURI();
MOZ_ASSERT(baseURI);
// May be null.
nsCOMPtr<nsIDocument> parentDoc = mParentWorker->GetDocument();
nsCOMPtr<nsIDocument> parentDoc = mWorkerPrivate->GetDocument();
nsCOMPtr<nsILoadGroup> loadGroup = mParentWorker->GetLoadGroup();
nsCOMPtr<nsILoadGroup> loadGroup = mWorkerPrivate->GetLoadGroup();
nsCOMPtr<nsIChannel> channel;
mResult =
@@ -1682,14 +1706,7 @@ public:
channel.forget(mChannel);
}
RefPtr<MainThreadStopSyncLoopRunnable> runnable =
new MainThreadStopSyncLoopRunnable(mParentWorker,
mSyncLoopTarget.forget(), true);
if (!runnable->Dispatch()) {
NS_ERROR("This should never fail!");
}
return NS_OK;
return true;
}
nsresult
@@ -1900,9 +1917,8 @@ ScriptExecutorRunnable::ShutdownScriptLoader(JSContext* aCx,
// 1) mScriptLoader.mRv.Failed(). In that case we just want to leave it
// as-is, except if it has a JS exception and we need to mute JS
// exceptions. In that case, we log the exception without firing any
// events and then replace it on the ErrorResult with a generic
// NS_ERROR_FAILURE for lack of anything better. XXXbz: This should
// throw a NetworkError per spec updates. See bug 1249673.
// events and then replace it on the ErrorResult with a NetworkError,
// per spec.
//
// 2) mScriptLoader.mRv succeeded. As far as I can tell, this can only
// happen when loading the main worker script and
@@ -1912,7 +1928,7 @@ ScriptExecutorRunnable::ShutdownScriptLoader(JSContext* aCx,
if (mScriptLoader.mRv.Failed()) {
if (aMutedError && mScriptLoader.mRv.IsJSException()) {
LogExceptionToConsole(aCx, aWorkerPrivate);
mScriptLoader.mRv.Throw(NS_ERROR_FAILURE);
mScriptLoader.mRv.Throw(NS_ERROR_DOM_NETWORK_ERR);
}
} else {
mScriptLoader.mRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
@@ -2023,19 +2039,14 @@ ChannelFromScriptURLWorkerThread(JSContext* aCx,
{
aParent->AssertIsOnWorkerThread();
AutoSyncLoopHolder syncLoop(aParent);
RefPtr<ChannelGetterRunnable> getter =
new ChannelGetterRunnable(aParent, syncLoop.EventTarget(), aScriptURL,
aChannel);
new ChannelGetterRunnable(aParent, aScriptURL, aChannel);
if (NS_FAILED(NS_DispatchToMainThread(getter))) {
ErrorResult rv;
getter->Dispatch(rv);
if (rv.Failed()) {
NS_ERROR("Failed to dispatch!");
return NS_ERROR_FAILURE;
}
if (!syncLoop.Run()) {
return NS_ERROR_FAILURE;
return rv.StealNSResult();
}
return getter->GetResult();
+24 -3
View File
@@ -35,6 +35,7 @@ NS_INTERFACE_MAP_END
ServiceWorkerClientInfo::ServiceWorkerClientInfo(nsIDocument* aDoc)
: mWindowId(0)
, mFrameType(FrameType::None)
{
MOZ_ASSERT(aDoc);
nsresult rv = aDoc->GetOrCreateId(mClientId);
@@ -64,8 +65,9 @@ ServiceWorkerClientInfo::ServiceWorkerClientInfo(nsIDocument* aDoc)
}
RefPtr<nsGlobalWindow> outerWindow = static_cast<nsGlobalWindow*>(aDoc->GetWindow());
MOZ_ASSERT(outerWindow);
if (!outerWindow->IsTopLevelWindow()) {
if (!outerWindow) {
MOZ_ASSERT(mFrameType == FrameType::None);
} else if (!outerWindow->IsTopLevelWindow()) {
mFrameType = FrameType::Nested;
} else if (outerWindow->HadOriginalOpener()) {
mFrameType = FrameType::Auxiliary;
@@ -126,6 +128,9 @@ private:
{
AssertIsOnMainThread();
MOZ_ASSERT(aTargetContainer->GetParentObject(),
"How come we don't have a window here?!");
JS::Rooted<JS::Value> messageData(aCx);
ErrorResult rv;
Read(aTargetContainer->GetParentObject(), aCx, &messageData, rv);
@@ -136,8 +141,24 @@ private:
RootedDictionary<ServiceWorkerMessageEventInit> init(aCx);
nsCOMPtr<nsIPrincipal> principal = aTargetContainer->GetParentObject()->PrincipalOrNull();
NS_WARN_IF_FALSE(principal, "Why is the principal null here?");
bool isNullPrincipal = false;
bool isSystemPrincipal = false;
if (principal) {
principal->GetIsNullPrincipal(&isNullPrincipal);
MOZ_ASSERT(!isNullPrincipal);
principal->GetIsSystemPrincipal(&isSystemPrincipal);
MOZ_ASSERT(!isSystemPrincipal);
}
init.mData = messageData;
init.mOrigin.Construct(EmptyString());
nsAutoCString origin;
if (principal && !isNullPrincipal && !isSystemPrincipal) {
principal->GetOrigin(origin);
}
init.mOrigin.Construct(NS_ConvertUTF8toUTF16(origin));
init.mLastEventId.Construct(EmptyString());
init.mPorts.Construct();
init.mPorts.Value().SetNull();
+120 -42
View File
@@ -42,6 +42,7 @@ namespace {
static const char* gSupportedRegistrarVersions[] = {
SERVICEWORKERREGISTRAR_VERSION,
"3",
"2"
};
@@ -143,6 +144,29 @@ ServiceWorkerRegistrar::GetRegistrations(
}
}
namespace {
bool Equivalent(const ServiceWorkerRegistrationData& aLeft,
const ServiceWorkerRegistrationData& aRight)
{
MOZ_ASSERT(aLeft.principal().type() ==
mozilla::ipc::PrincipalInfo::TContentPrincipalInfo);
MOZ_ASSERT(aRight.principal().type() ==
mozilla::ipc::PrincipalInfo::TContentPrincipalInfo);
const auto& leftPrincipal = aLeft.principal().get_ContentPrincipalInfo();
const auto& rightPrincipal = aRight.principal().get_ContentPrincipalInfo();
// Only compare the attributes, not the spec part of the principal.
// The scope comparison above already covers the origin and codebase
// principals include the full path in their spec which is not what
// we want here.
return aLeft.scope() == aRight.scope() &&
leftPrincipal.attrs() == rightPrincipal.attrs();
}
} // anonymous namespace
void
ServiceWorkerRegistrar::RegisterServiceWorker(
const ServiceWorkerRegistrationData& aData)
@@ -157,33 +181,7 @@ ServiceWorkerRegistrar::RegisterServiceWorker(
{
MonitorAutoLock lock(mMonitor);
MOZ_ASSERT(mDataLoaded);
const mozilla::ipc::PrincipalInfo& newPrincipalInfo = aData.principal();
MOZ_ASSERT(newPrincipalInfo.type() ==
mozilla::ipc::PrincipalInfo::TContentPrincipalInfo);
const mozilla::ipc::ContentPrincipalInfo& newContentPrincipalInfo =
newPrincipalInfo.get_ContentPrincipalInfo();
bool found = false;
for (uint32_t i = 0, len = mData.Length(); i < len; ++i) {
if (mData[i].scope() == aData.scope()) {
const mozilla::ipc::PrincipalInfo& existingPrincipalInfo =
mData[i].principal();
const mozilla::ipc::ContentPrincipalInfo& existingContentPrincipalInfo =
existingPrincipalInfo.get_ContentPrincipalInfo();
if (newContentPrincipalInfo == existingContentPrincipalInfo) {
mData[i] = aData;
found = true;
break;
}
}
}
if (!found) {
mData.AppendElement(aData);
}
RegisterServiceWorkerInternal(aData);
}
ScheduleSaveData();
@@ -207,9 +205,12 @@ ServiceWorkerRegistrar::UnregisterServiceWorker(
MonitorAutoLock lock(mMonitor);
MOZ_ASSERT(mDataLoaded);
ServiceWorkerRegistrationData tmp;
tmp.principal() = aPrincipalInfo;
tmp.scope() = aScope;
for (uint32_t i = 0; i < mData.Length(); ++i) {
if (mData[i].principal() == aPrincipalInfo &&
mData[i].scope() == aScope) {
if (Equivalent(tmp, mData[i])) {
mData.RemoveElementAt(i);
deleted = true;
break;
@@ -317,9 +318,12 @@ ServiceWorkerRegistrar::ReadData()
return NS_ERROR_FAILURE;
}
nsTArray<ServiceWorkerRegistrationData> tmpData;
bool overwrite = false;
bool dedupe = false;
while (hasMoreLines) {
ServiceWorkerRegistrationData* entry = mData.AppendElement();
ServiceWorkerRegistrationData* entry = tmpData.AppendElement();
#define GET_LINE(x) \
rv = lineInputStream->ReadLine(x, &hasMoreLines); \
@@ -331,6 +335,7 @@ ServiceWorkerRegistrar::ReadData()
}
nsAutoCString line;
nsAutoCString unused;
if (version.EqualsLiteral(SERVICEWORKERREGISTRAR_VERSION)) {
nsAutoCString suffix;
GET_LINE(suffix);
@@ -340,18 +345,19 @@ ServiceWorkerRegistrar::ReadData()
return NS_ERROR_INVALID_ARG;
}
GET_LINE(line);
entry->principal() =
mozilla::ipc::ContentPrincipalInfo(attrs, line);
GET_LINE(entry->scope());
entry->principal() =
mozilla::ipc::ContentPrincipalInfo(attrs, entry->scope());
GET_LINE(entry->currentWorkerURL());
nsAutoCString cacheName;
GET_LINE(cacheName);
CopyUTF8toUTF16(cacheName, entry->cacheName());
} else if (version.EqualsLiteral("2")) {
} else if (version.EqualsLiteral("3")) {
overwrite = true;
dedupe = true;
nsAutoCString suffix;
GET_LINE(suffix);
@@ -361,14 +367,40 @@ ServiceWorkerRegistrar::ReadData()
return NS_ERROR_INVALID_ARG;
}
GET_LINE(line);
entry->principal() =
mozilla::ipc::ContentPrincipalInfo(attrs, line);
// principal spec is no longer used; we use scope directly instead
GET_LINE(unused);
GET_LINE(entry->scope());
entry->principal() =
mozilla::ipc::ContentPrincipalInfo(attrs, entry->scope());
GET_LINE(entry->currentWorkerURL());
nsAutoCString cacheName;
GET_LINE(cacheName);
CopyUTF8toUTF16(cacheName, entry->cacheName());
} else if (version.EqualsLiteral("2")) {
overwrite = true;
dedupe = true;
nsAutoCString suffix;
GET_LINE(suffix);
OriginAttributes attrs;
if (!attrs.PopulateFromSuffix(suffix)) {
return NS_ERROR_INVALID_ARG;
}
// principal spec is no longer used; we use scope directly instead
GET_LINE(unused);
GET_LINE(entry->scope());
entry->principal() =
mozilla::ipc::ContentPrincipalInfo(attrs, entry->scope());
// scriptSpec is no more used in latest version.
nsAutoCString unused;
GET_LINE(unused);
GET_LINE(entry->currentWorkerURL());
@@ -397,6 +429,38 @@ ServiceWorkerRegistrar::ReadData()
stream->Close();
// Copy data over to mData.
for (uint32_t i = 0; i < tmpData.Length(); ++i) {
bool match = false;
if (dedupe) {
MOZ_ASSERT(overwrite);
// If this is an old profile, then we might need to deduplicate. In
// theory this can be removed in the future (Bug 1248449)
for (uint32_t j = 0; j < mData.Length(); ++j) {
// Use same comparison as RegisterServiceWorker. Scope contains
// basic origin information. Combine with any principal attributes.
if (Equivalent(tmpData[i], mData[j])) {
// Last match wins, just like legacy loading used to do in
// the ServiceWorkerManager.
mData[j] = tmpData[i];
// Dupe found, so overwrite file with reduced list.
match = true;
break;
}
}
} else {
#ifdef DEBUG
// Otherwise assert no duplications in debug builds.
for (uint32_t j = 0; j < mData.Length(); ++j) {
MOZ_ASSERT(!Equivalent(tmpData[i], mData[j]));
}
#endif
}
if (!match) {
mData.AppendElement(tmpData[i]);
}
}
// Overwrite previous version.
// Cannot call SaveData directly because gtest uses main-thread.
if (overwrite && NS_FAILED(WriteData())) {
@@ -441,6 +505,23 @@ ServiceWorkerRegistrar::DeleteData()
}
}
void
ServiceWorkerRegistrar::RegisterServiceWorkerInternal(const ServiceWorkerRegistrationData& aData)
{
bool found = false;
for (uint32_t i = 0, len = mData.Length(); i < len; ++i) {
if (Equivalent(aData, mData[i])) {
mData[i] = aData;
found = true;
break;
}
}
if (!found) {
mData.AppendElement(aData);
}
}
class ServiceWorkerRegistrarSaveDataRunnable final : public Runnable
{
public:
@@ -613,9 +694,6 @@ ServiceWorkerRegistrar::WriteData()
buffer.Append(suffix.get());
buffer.Append('\n');
buffer.Append(cInfo.spec());
buffer.Append('\n');
buffer.Append(data[i].scope());
buffer.Append('\n');
+3 -1
View File
@@ -16,7 +16,7 @@
#include "nsTArray.h"
#define SERVICEWORKERREGISTRAR_FILE "serviceworker.txt"
#define SERVICEWORKERREGISTRAR_VERSION "3"
#define SERVICEWORKERREGISTRAR_VERSION "4"
#define SERVICEWORKERREGISTRAR_TERMINATOR "#"
#define SERVICEWORKERREGISTRAR_TRUE "true"
#define SERVICEWORKERREGISTRAR_FALSE "false"
@@ -66,6 +66,8 @@ protected:
nsresult WriteData();
void DeleteData();
void RegisterServiceWorkerInternal(const ServiceWorkerRegistrationData& aData);
ServiceWorkerRegistrar();
virtual ~ServiceWorkerRegistrar();
@@ -970,6 +970,14 @@ ServiceWorkerRegistrationWorkerThread::Update(ErrorResult& aRv)
return nullptr;
}
// Avoid infinite update loops by ignoring update() calls during top
// level script evaluation. See:
// https://github.com/slightlyoff/ServiceWorker/issues/800
if (worker->LoadScriptAsPartOfLoadingServiceWorkerScript()) {
promise->MaybeResolve(JS::UndefinedHandleValue);
return promise.forget();
}
RefPtr<PromiseWorkerProxy> proxy = PromiseWorkerProxy::Create(worker, promise);
if (!proxy) {
aRv.Throw(NS_ERROR_DOM_ABORT_ERR);
+3 -1
View File
@@ -1013,7 +1013,9 @@ GenerateCacheName(nsAString& aName)
char chars[NSID_LENGTH];
id.ToProvidedString(chars);
aName.AssignASCII(chars, NSID_LENGTH);
// NSID_LENGTH counts the null terminator.
aName.AssignASCII(chars, NSID_LENGTH - 1);
return NS_OK;
}
-1
View File
@@ -137,7 +137,6 @@ SharedWorker::Close()
if (mMessagePort) {
mMessagePort->Close();
mMessagePort = nullptr;
}
}

Some files were not shown because too many files have changed in this diff Show More