Brightscript library called directly by firmware

It is obvious that main/runUserInterface in a channel, instead of library, is called by firmware.
How to make a function in library, instead of channel, that gets called without involving main/runUserInterface?
Here is a sample library to show how FW call BRS as it does with GrandCentral library.
Firmware loads, and calls launchContent.
On Brightscript side:
manifest file:
required: os_markup=1 sg_component_libs_provided=Roku_GrandCentral
sg_component_libs_provided so that FW knows it is a library instead of channel
optional: major_version, hidden=1
.xml file:
required: <field id=”scene” type=”node”/>
optional: base class of ContentLauncher, extends=”Node”, is not required
required: the function being caalled by FW: launchContent
optional: init()
Folder structure and file name of xml and brs dont make difference.

On FW side:called in LaunchController.cpp

The way we know the function did get called:
check port 8085, and look for log message “Function launchContent is called by FW.”

Email out thru Gmail as domain is a public facing ec2 instance, over which I have full control.
When we ask gmail to send out an email as,
Gmail doesnt send out email with “MAIL FROM: <>”, even though it is capable.
Instead, gmail request host to send the email.
gmail requires TLS. use Cyrus SASL
SASL: Simple Authentication Security Layer
Cyrus SASL library implementation
Config SASL
Install: apt-get install sasl2-bin libsasl2-modules
Create credential: saslpasswd2 -c -u smtp
this create username smtp, enter password when prompted.
Notify Cyrus how to check password by editting /etc/postfix/sasl/smtpd.conf with:
pwcheck_method: auxprop
mech_list: PLAIN LOGIN
Create certificate, self signed:
create keypair: openssl genrsa -des3 -out smtpRioWing.key 1024
create signing request: openssl req -new -key smtpRioWing.key -out smtpRioWing.csr
remove password: openssl rsa -in smtpRioWing.key.orig -out smtpRioWing.key
make cert: openssl x509 -req -days 3650 -in smtpRioWing.csr -signkey smtpRioWing.key -out smtpRioWing.crt
create .pem: cat smtpRioWing.crt smtpRioWing.key > smtpRioWing.pem
Config Postfix:
Edit /etc/postfix/ so that:
both smtpd_tls_cert_file and smtpd_tls_key_file point to /etc/postfix/smtpRioWing.pem

Edit /etc/postfix/ this opens up 587
submission inet n – n – – smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=may was encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_reject_unlisted_recipient=no
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
sudo postfix reload
Security group on aws:
Make sure port 587 is listening: netstat -ltn |grep 587
Open it up.

Add to gmail account so that it appears as one option in From.
This is straighforward; just enter smtp domain name, user name and password.

Email by telnet to port 587 with “AUTH LOGIN” with base64 user name and password also works.


BrightScript m variable

BrightScript is the language to program Roku streaming player.
The m keyword can be confusing.
code snippet from source/main.brs tagged with MvsThis, which stands for m vs this.

Function MvsThisCreate() as Object
	print "MvsThisCreate entered"
	obj = CreateObject("roAssociativeArray")
	obj.svc = "MvsThisSvc"
	obj.MvsThisFunc = MvsThisFunc
	obj.MvsThisFunc2 = MvsThisFunc2
	return obj
End Function

Function MvsThisFunc() as Void
	print "MvsThisFunc entered"
	print "MvsThisFunc m.svc="m.svc
	print "MvsThisFunc m.MvsThisFunc2="m.MvsThisFunc2
	print "MvsThisFunc MvsThisFunc2="MvsThisFunc2
End Function

Function MvsThisFunc2(str as String) as Void
	print "MvsThisFunc2 called by: "str
End Function

Function MvsThisTest() as Void
	print "MvsThisTest start"
	MvsThis = MvsThisCreate()
	print "MvsThisTest done"
End Function

When we run MvsThisTest(), we get these output:

	MvsThisTest start
	MvsThisCreate entered
	MvsThisFunc entered
	MvsThisFunc m.svc=MvsThisSvc
	MvsThisFunc m.MvsThisFunc2=<Function: mvsthisfunc2>
	MvsThisFunc MvsThisFunc2=<Function: mvsthisfunc2>
	MvsThisFunc2 called by: m.MvsThisFunc2
	MvsThisFunc2 called by: MvsThisFunc2

As shown above, m is for accessing data in roAssociativeArray from roAssociativeArray’s function fields.
Calling m.MvsThisFunc2( and MvsThisFunc2(, without the m. are the same thing when the object is roAssociativeArray.
Calling m.MvsThisFunc2() doesn’t work if the object is SceneGraph node, e.g. loaded as xml file.

Customized email address

Goal: setup and forward to
done by MTA postfix

Domain server: point MX record to
OS: user rio must exist since is alias of
Email server: AWS EC2 named, Ubuntu18
Install postfix: apt-get install postfix
vi /etc/postfix/
add this line: myhostname =
virtual_alias_domains is not involved here since no virtual domain
vi /etc/aliases
add this line: me: rio
run this: sudo postmap /etc/postfix/virtual
create this file: sudo vi /etc/postfix/virtual
add this line:
run this: sudo newaliases
Check status:
#service postfix status
#netstat -ltnp | grep 25
contact AWS support to unblock outgoing port 25, which is blocked by default.
open incoming port 25 from security group.
Notes: IMAP and POP3 are not configured since emails are forwarded to gmail.
Telnet to port 25 and watch response to commands such as “RCPT TO”
log files: /var/log/mail.log and mail.err
restart server: sudo service postfix restart or reload