Created
May 25, 2017 16:08
-
-
Save jsinai/665fb6d77172ca0ad155b77afc371870 to your computer and use it in GitHub Desktop.
A script suitable for serving from an Option 43 DHCP server.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'This script will bootstrap a BrightSign and is suitable for use with DHCP option | |
'43. It's job is to download an application/presentation zip file, and/or a | |
'firmware update. | |
' | |
'The application zip file is a standard zip file that can contain any combination | |
'of files that can run on a BrightSign. The only requirement is that it contains | |
' an autorun.brs to bootstrap the application. | |
' | |
'There are several tokens that need to be filled in for this script to work. It | |
'is designed to download two files at once, usually the application zip and a | |
'firmware update. But it can be used to download just one file also. | |
' | |
' ##fileName1## | |
'The name of the file when downloaded to the sd card. E.g. autorun.zip. | |
' ##fileType1## | |
'"presentation" or "firmware" | |
' ##url1## | |
'Where to get the file. E.g. "https://my.company.com/brightsign/application" | |
' ##addBsHeaders1## | |
'Whether to add headers to the request like serial number and firmware version. | |
'Value: true or false. | |
' ##optionalHeaders## | |
'Optional headers to add. These get added if addBsHeaders is true. Example of an | |
'authentication header: | |
' "xfer.AddHeader(\"Authorization\", \"Bearer " + authToken + "\")" | |
' | |
'The second set of download parameters is the same (##fileName2##, ##fileType2## | |
'etc.). If not required, set their values to invalid or false, as the case may | |
'be. | |
' | |
' ##recoveryUrl## | |
'This is the option 43 url that this script was originally downloaded from. | |
' | |
'Note that this url must obey the recovery rules, namely, it should examine the | |
'storagestatus header, and if an autorun is present (it's probably enough to look | |
'for the string "autorun" in the header), return http status 204. Otherwise, | |
'return 200 and this script in the body. | |
' | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
Sub Main() | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
CheckStorageDriveIsWritable() | |
modelObject = CreateObject("roDeviceInfo") | |
msgPort = CreateObject("roMessagePort") | |
drive$ = GetDefaultDrive() | |
file1AA = { | |
fileName: ##fileName1## | |
fileType: ##fileType1## | |
url: ##url1## | |
addBsHeaders: ##addBsHeaders1## | |
downloadingFile: false | |
downloadedFile: false | |
} | |
print "=== file1AA: ";file1AA | |
file2AA = { | |
fileName: ##fileName2## | |
fileType: ##fileType2## | |
url: ##url2## | |
addBsHeaders: ##addBsHeaders2## | |
downloadingFile: false | |
downloadedFile: false | |
} | |
print "=== file2AA: ";file2AA | |
xfer1 = CreateXfer(modelObject, msgPort, file1AA) | |
xfer2 = CreateXfer(modelObject, msgPort, file2AA) | |
DownloadFile(file1AA, drive$, xfer1, modelObject) | |
DownloadFile(file2AA, drive$, xfer2, modelObject) | |
recoveryUrl$ = ##recoveryUrl## | |
while true | |
event = wait(0, msgPort) | |
print "Received event ";type(event) | |
If (type(event) = "roUrlEvent") Then | |
ProcessDownloadEvent(event, xfer1, file1AA, file2AA, drive$, recoveryUrl$) | |
ProcessDownloadEvent(event, xfer2, file2AA, file1AA, drive$, recoveryUrl$) | |
End If | |
End while | |
End Sub | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
Sub CheckStorageDriveIsWritable() | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
ok = false | |
' get mounted drive and attempt to write to it | |
drive$ = GetMountedDrive() | |
If drive$ <> "" Then | |
SetDefaultDrive(drive$) | |
' determine If the storage drive is writable | |
tmpFileName$ = "bs~69-96.txt" | |
WriteAsciiFile(tmpFileName$, "1") | |
readValue$ = ReadAsciiFile(tmpFileName$) | |
If len(readValue$) = 1 and readValue$ = "1" Then | |
DeleteFile(tmpFileName$) | |
ok = true | |
End If | |
End If | |
If not ok Then | |
videoMode = CreateObject("roVideoMode") | |
resX = videoMode.GetResX() | |
resY = videoMode.GetResY() | |
videoMode = invalid | |
r = CreateObject("roRectangle", 0, 0, resX, resY) | |
twParams = CreateObject("roAssociativeArray") | |
twParams.LineCount = 1 | |
twParams.TextMode = 2 | |
twParams.Rotation = 0 | |
twParams.Alignment = 1 | |
tw=CreateObject("roTextWidget",r,1,2,twParams) | |
tw.PushString("") | |
tw.Show() | |
r=CreateObject("roRectangle",0,resY/2-resY/32,resX,resY/32) | |
tw=CreateObject("roTextWidget",r,1,2,twParams) | |
tw.PushString("The attached storage drive is write protected.") | |
tw.Show() | |
r2=CreateObject("roRectangle",0,resY/2,resX,resY/32) | |
tw2=CreateObject("roTextWidget",r2,1,2,twParams) | |
tw2.PushString("Remove it, enable writing, and reboot the device.") | |
tw2.Show() | |
msgPort = CreateObject("roMessagePort") | |
msg = wait(0, msgPort) | |
End If | |
End Sub | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
Function GetMountedDrive() As String | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
drives = ["USB1:/","SD:/","SD2:/","SSD:/"] | |
for each drive in drives | |
If DriveIsMounted(drive) Then | |
return drive | |
End If | |
next | |
return "" | |
End Function | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
Function DriveIsMounted(driveName$ As String) As Boolean | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
du = CreateObject("roStorageInfo", driveName$) | |
If type(du) = "roStorageInfo" Then | |
return true | |
End If | |
return false | |
End Function | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
Sub Notify(message As String, delay As Integer) | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
print message | |
videoMode = CreateObject("roVideoMode") | |
resX = videoMode.GetResX() | |
resY = videoMode.GetResY() | |
videoMode = invalid | |
rectangle = CreateObject("roRectangle", 0, resY/2-resY/64, resX, resY/32) | |
textParameters = CreateObject("roAssociativeArray") | |
textParameters.LineCount = 1 | |
textParameters.TextMode = 2 | |
textParameters.Rotation = 0 | |
textParameters.Alignment = 1 | |
textWidget = CreateObject("roTextWidget", rectangle, 1, 2, textParameters) | |
textWidget.PushString(message) | |
textWidget.Show() | |
If delay = -1 Then | |
while true | |
sleep(1000) | |
End while | |
Else | |
sleep(delay) | |
End If | |
End Sub | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
Sub DownloadFile(fileAA As Object, drive$ As String, xfer As Object, modelObject As Object) | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
If fileAA.url <> invalid Then | |
firmwareVersion$ = modelObject.GetVersion() | |
' If the filename contains the firmware version, we are up to date | |
If fileAA.filetype = "firmware" And fileAA.fileName.Instr(firmwareVersion$) > -1 Then | |
Notify("Firmware is up to date, no download necessary. Version: " + firmwareVersion$ + ".", 3000) | |
Else | |
xfer.SetUrl(fileAA.url) | |
Notify("Downloading " + fileAA.fileType + " files.", 3000) | |
print "File source: " + fileAA.url + "." | |
print "File destination: " + drive$ + fileAA.fileName + "." | |
fileAA.downloadingFile = xfer.AsyncGetToFile(drive$ + fileAA.fileName) | |
print "File status at start of download: ";fileAA.downloadingFile;"." | |
End If | |
End If | |
End Sub | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
Function CreateXfer(modelObject As Object, msgPort As Object, fileAA As Object) | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
xfer = CreateObject("roUrlTransfer") | |
xfer.SetPort(msgPort) | |
If fileAA.addBsHeaders Then | |
deviceUniqueID$ = modelObject.GetDeviceUniqueId() | |
deviceModel$ = modelObject.GetModel() | |
deviceFamily$ = modelObject.GetFamily() | |
firmwareVersion$ = modelObject.GetVersion() | |
xfer.AddHeader("DeviceID", deviceUniqueID$) | |
xfer.AddHeader("DeviceModel", deviceModel$) | |
xfer.AddHeader("DeviceFamily", deviceFamily$) | |
xfer.AddHeader("DeviceFWVersion", firmwareVersion$) | |
##optionalHeaders## | |
End If | |
return xfer | |
End Function | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
Sub DoReboot(drive$ As String) | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
isSuccess = RebootSystem() | |
If not isSuccess Then | |
Notify("Error while rebooting device.", -1) | |
End If | |
End Sub | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
Sub ProcessDownloadEvent(event As Object, xfer As Object, myFileAA as Object, otherFileAA as Object, drive$ As String, recoveryUrl$ As String) | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
If xfer <> invalid And event.GetSourceIdentity() = xfer.GetIdentity() Then | |
code = event.GetResponseCode() | |
If code = 200 Then | |
myFileAA.downloadedFile = true | |
' Upon successful download, save the recovery URL for the application to the registry | |
If myFileAA.filetype = "presentation" Then | |
SaveRecoveryUrl(recoveryUrl$) | |
End If | |
If otherFileAA.downloadingFile Then | |
If otherFileAA.downloadedFile Then | |
Notify("Successfully downloaded " + myFileAA.fileType + " files. Player will reboot.", 3000) | |
DoUnzip(drive$, myFileAA.filename) | |
DoReboot(drive$) | |
Else | |
Notify("Successfully downloaded " + myFileAA.fileType + " files.", 3000) | |
End If | |
Else | |
Notify("Successfully downloaded " + myFileAA.fileType + " files. Player will reboot.", 3000) | |
DoUnzip(drive$, myFileAA.filename) | |
DoReboot(drive$) | |
End If | |
Else | |
Notify("Error while downloading " + myFileAA.fileType + " files: " + str(code) + ". Failure reason: " + xfer.GetFailureReason() + ".", -1) | |
End If | |
End If | |
End Sub | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
Sub SaveRecoveryUrl(recoveryUrl$ As String) | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
registrySection = CreateObject("roRegistrySection", "networking") | |
registrySection.Write("ru", recoveryUrl$) | |
End Sub | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
Sub DoUnzip(drive$, filename$) | |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | |
If Len(filename$) > 4 And Lcase(Right(filename$, 4)) = ".zip" Then | |
package = CreateObject("roBrightPackage", drive$ + filename$) | |
package.Unpack(drive$) | |
MoveFile(drive$ + filename$, drive$ + filename$ + "_invalid") | |
End If | |
end Sub |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment