Invoking Win32 Functions from the Command Line

I’m testing some code that accepts some work items and performs a long running task on the work items. For this project, I generally want the screen to be locked since I’m going to be away from the computer for some time while it runs. I recently decided to make locking the screen part of the script that invokes the tasks. Yes, I could just press [Windows Key]+[L], but if there’s something that I’m doing repeatedly, I would prefer to just automate it and not worry about it.

Locking the screen from a program is easy. Making a call to the parameter-less function LockWorkStation* results is what I want. I thought I would just make a simple C++ program that does nothing more than make this call and be done with it. But something about that didn’t feel right; why make an entire program to invoke that single problem. It actually isn’t necessary to make a program to do this. Windows has a utility in the System32 folder. RunDll32.exe. The utility is specifically made for calling functions in DLLs that were written to process Windows message. If you have ever done Windows 32 programming with C++ then you are already familiar with these. Calling functions with no parameters is fine also

In the general case, Rundll32.exe accepts the name of the DLL to invoke and the name of the function within the DLL. For my need, the call looks like the following.

Rundll32.exe user32.dll,LockWorkStation

Win32 functions generally have the following call signature.

void CALLBACK funcName(
       HWND      hwnd,
       HINSTANCE hinst,
       LPSTR     lpszCmdLine,
       int       nCmdShow
);

RunDLL32 will take care of converting arguments from strings on the command line to the data types being passed. Be careful about using this utility; if you pass bad values, expect bad results. For the following, I passed the name of an HTML file from the command prompt and a print dialog opened for printing it out.

rundll32 mshtml.dll,PrintHTML "A title for my document", "C:\temp\map.html"

While I find this to be a useful utility, I don’t recommend it for anyone that isn’t already familiar with calling Win32 functions.

* – the command tsdiscon has a similar affect. It disconnects the current session from the graphical desktop. But when I use this command logging back in takes much longer and I prefer not to use it.

“listen EACCES: permission denied 127.0.0.1:443”

After some holiday time off I returned to a work project that uses Angular, started it up, and got this error.

An unhandled exception occurred: listen EACCES: permission denied 127.0.0.1:443

I’ve seen this error before, but did not immediately realized what caused it. It took me a few minutes to recall the source of the problem. This error occurs when there is another application that is already using the port that Angular is trying to open. In my case, it was a VMWare service that was occupying the port. I stopped the service and my project started up. If it happened to you, how would you know what process is using the port?

On Windows, you can list which processes are using which port with the following command

netstat -aon

You’ll get a full list of ports, addresses, and process IDs.

Active Connections
 Proto  Local Address          Foreign Address        State           PID
   TCP    0.0.0.0:80             0.0.0.0:0              LISTENING       4
   TCP    0.0.0.0:135            0.0.0.0:0              LISTENING       1348
   TCP    0.0.0.0:443            0.0.0.0:0              LISTENING       38880
   TCP    0.0.0.0:445            0.0.0.0:0              LISTENING       4
   TCP    0.0.0.0:902            0.0.0.0:0              LISTENING       39848
   TCP    0.0.0.0:912            0.0.0.0:0              LISTENING       39848
   TCP    0.0.0.0:2179           0.0.0.0:0              LISTENING       2304
   TCP    0.0.0.0:2869           0.0.0.0:0              LISTENING       4
   TCP    0.0.0.0:3389           0.0.0.0:0              LISTENING       1600
   TCP    0.0.0.0:5040           0.0.0.0:0              LISTENING       884
   TCP    0.0.0.0:5800           0.0.0.0:0              LISTENING       5252
   TCP    0.0.0.0:5900           0.0.0.0:0              LISTENING       5252
   TCP    0.0.0.0:7680           0.0.0.0:0              LISTENING       37976
   TCP    0.0.0.0:27036          0.0.0.0:0              LISTENING       17928
   TCP    0.0.0.0:44367          0.0.0.0:0              LISTENING       4
   TCP    0.0.0.0:49664          0.0.0.0:0              LISTENING       704

If you wanted to filter those results, you can pass the output through “findstr” using a port number as the string to filter by.

C:\Users\Joel>netstat -aon | findstr 443
   TCP    0.0.0.0:443            0.0.0.0:0              LISTENING       38880
   TCP    0.0.0.0:44367          0.0.0.0:0              LISTENING       4
   TCP    192.168.1.81:49166     72.21.81.200:443       TIME_WAIT       0
   TCP    192.168.1.81:49169     64.233.177.101:443     TIME_WAIT       0
   TCP    192.168.1.81:49206     13.249.111.97:443      ESTABLISHED     24324
   TCP    192.168.1.81:49209     52.167.253.237:443     ESTABLISHED     1996
   TCP    192.168.1.81:49220     52.184.216.246:443     ESTABLISHED     37976
   TCP    192.168.1.81:49222     168.62.57.154:443      ESTABLISHED     24324
   TCP    192.168.1.81:49224     52.114.74.45:443       ESTABLISHED     13304
   TCP    192.168.1.81:49227     52.113.194.132:443     ESTABLISHED     10376
   TCP    192.168.1.81:49228     184.24.37.85:443       ESTABLISHED     27828
   TCP    192.168.1.81:49231     13.92.225.245:443      ESTABLISHED     27828
   TCP    192.168.1.81:49233     140.82.113.3:443       ESTABLISHED     24324
   TCP    192.168.1.81:49234     20.190.133.75:443      ESTABLISHED     39168
   TCP    192.168.1.81:49236     204.79.197.203:443     ESTABLISHED     27828
   TCP    192.168.1.81:49238     52.96.104.18:443       ESTABLISHED     12440
   TCP    192.168.1.81:49239     52.96.104.18:443       ESTABLISHED     12440

You will be more interested in matches from the left column, since that is the port number being used on your machine. Right now, I can see that on my machine the process occupying port 443 is process 38,880. Great, I have a process number. But what can I do with it. There is another command named “tasklist” that list processes names and their process ID. Combined with findstr, I can get the name of the process using the specific port.

C:\Users\Joel>tasklist | findstr 38880
 vmware-hostd.exe             38880 Services                   0     32,084 K

Video Streaming with Node and Express

I’ve got a range of media that I’m moving from its original storage to hard drives. Among this media are some DVDs that I’ve collected over time. It took a while, but I managed to convert the collection of movies and TV shows to video files on my hard drive. Now that they are converted, I wanted to build a solution for browsing and playing them. I tried using a drive with DLNA built in, but the DLNA clients I have appear to have been built with a smaller collection of videos in mind. They present an alphabetical list of the video files. Not the way I want to navigate.

I decided to instead make my own solution. To start though, I wanted to make a solution that would stream a file video file. Unlike most HTML resources, which are relatively small, video files can be several gigabytes. Rather than have the web server present the file in its entirety I need for the web server to present the file in chunks. My starting point is a simple NodeJS project that is presenting HTML pages through Express.

const express = require('express');
const fileUpload = require('express-fileupload');
const session = require('express-session');
const bodyParser = require('body-parser');
const createError = require('http-errors');
const path = require('path');
const { uuid } = require('uuidv4');
require('dotenv').config();

var sessionSettings = {
   saveUninitialized: true,
   secret: "sdlkvkdfbjv",
   resave: false,
   cookie: {},
   unset: 'destroy',
   genid: function (req) {
      return uuid();
   }
}

app = express();
app.use(session(sessionSettings));
if (app.get('env') === 'production') {
   app.set('trust proxy', 1);
   sessionSettings.cookie.secure = true;
}
app.use(express.static('public'));
app.use(bodyParser.json());
app.use(fileUpload({
   createPath: true
}));
app.use(function (req, res, next) {
   console.log(req.originalUrl);
   next(createError(404));
});
app.set('views', path.join(__dirname, 'views'));
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');

module.exports = app;

With the above application, static content any files that are put in the folder named “public” will be served when requested. In that folder, the stylesheet, JavaScript, HTML, and other static content will be placed. The videos will be in another folder that is not part of the project. The path to this folder is specified by the setting VIDEO_ROOT in the .env file.

For this to stream files, there are two additional routes that I am going to add. One route will return a list of all of the video IDs. The other route will return the video itself.

For this first iteration for video streaming, I’m going to return file names as video IDs. At some point during the development of my solution this may change. But for testing streaming the file name is sufficient. The route handler for the library will get a list of the files and return it in a structure that is marked with a date. The files it returns are filtered to only include those with an .mp4 extension.

const fs = require('fs');
const express = require('express');
require('dotenv').config();

var router = express.Router();

var fileInformation = { 
    lastUpdated: null, 
    fileList: []
}

function isVideoFile(path) { 
    return path.toLowerCase().endsWith('.mp4')||path.toLowerCase().endsWith('.m4v');
}

function updateFileList() { 
    return new Promise((resolve,reject)=> {
        console.log('getting file list');
        console.log([process.env.VIDEO_ROOT])
        fs.readdir(process.env.VIDEO_ROOT, (err, files) => {
            if(err) reject(err);
            else {
                var videoFiles = files.filter(x=>isVideoFile(x));
                fileInformation.fileList = videoFiles;
                fileInformation.lastUpdated = Date.now();
                resolve(fileInformation);
            } 
        });
    });
}

router.get('/',(req,res,next)=> {
    console.log('library')
    updateFileList()
    .then(fileList => {
        res.json(fileList);
    })
    .catch(err => {
        console.error(err);
        res.status(500).json(err)
    });
});

module.exports = router;

The video element in an HTML page will download a video in chunks (if the server supports range headers). The video element sends a request with a header stating the byte range being requested. In the response, the header will also state the byte range that is being sent. Our express application must read the range headers and parse out the range being request. The range header will contain a starting byte offset and may or may not contain an ending byte offset. The value in the content range may look something like the following.

byte=0-270
byte=500-

In the first example, there is a starting and ending byte range. In the second, the request only specifies a starting byte. It is up to the server to decide how many bytes to send. This header is easily parsed with a couple of String.split operations and integer parsing.


function getByteRange(rangeHeader) {
    var byteRangeString = rangeHeader.split('=')[1];
    byteParts = byteRangeString.split('-');
    var range = [];
    range.push(Number.parseInt(byteParts[0]));
    if(byteParts[1].length == 0 ) {
        range.push(null);
    } else {
        range.push(Number.parseInt(byteParts[1]))
    }
    return range;
}

There is the possibility that the second number in the range is not there, or is present but is outside of the range of bytes for the file. To handle this, there’s a default chunk size defined that will be used when the byte range is not specified. But the range is also checked against the file size and clamped to ensure that there is no attempt to read past the end of the file.

const CHUNK_SIZE = 2 ** 18;
//...
var start = range[0];
if(range[1]==null)
    range[1] = Math.min(fileSize, start+CHUNK_SIZE);
var end = range[1] ;
end = Math.min(end, fileSize);

In the response, the header contains a header defining the range of bytes in the response and it’s length. We build out those headers, set them on the response header, and then write the range of bytes. To write out the bytes, a read stream from the video file and piped to the response stream.

const contentLength = end - start + 1;
const headers = { 
    "Content-Range": `bytes ${start}-${end}/${fileSize}`,
    "Accept-Ranges":"bytes",
    "Content-Length": contentLength,
    "Content-Type": getContentType(videoID)
};

console.log('headers', headers);
res.writeHead(206, headers);
const videoStream = fs.createReadStream(videoPath, {start, end});
videoStream.pipe(res);

The server can now serve video files for streaming. For the client side, some HTML and JavaScript is needed. The HTML contains a video element and a <div/> element that will be populated with a list of the videos.

<!DOCTYPE html>
<html>
    <head>
        
        <link rel="stylesheet" href="./style/main.css" />
        <script src="scripts/jquery-3.5.1.min.js"></script>
        <script src="scripts/main.js"></script>
    </head>
    <body>
        <div id="videoBrowser" ></div>
        <video id="videoPlayer" autoplay controls></video>
    </body>
</html>

The JavaScript will request a list of the videos from the /library route. For each video file, it will create a text element containing the name of the video. Clicking on the text will set the src element on the video.

function start() { 
    fetch('/library')
    .then(data=>data.json())
    .then(data=> { 
        console.log(data);
        var elementRoot = $('#videoBrowser');
        data.fileList.forEach(x=>{
            var videoElement = $(`<div>${x}</div>`);
            $(elementRoot).append(videoElement);
            $(videoElement).click(()=>{
                var videoURL = `/video/${x}`;
                console.log(videoURL);
                $('#videoPlayer').attr('src', videoURL );
            })
        });
        
    });
}

$(document).ready(start());

Almost done! The only thing missing is adding these routes to the source of app.js. As it stands now, app.js will only serve static HTML file.

const libraryRouter = require('./routers/libraryRouter');
const videoRouter = require('./routers/videoRouter');
app.use('/library', libraryRouter);
app.use('/video', videoRouter);

I started the application (npm start) and at first, I thought that the application was not working. The problem was in the encoding of the first MP4 file that I tried. There are a range of different video encoding options that one can use for MP4 files. Looking at the encoding properties of two MP4 files (one file streamed successfully, the other did not) there was no obvious difference at first.

The problem was with metadata stored in the file. A discussion of video encodings is a topic that could be several posts of its own. But the short explanation is that we need to ensure that the metadata is at the begining of the file. We can use ffmpeg to write a new file. Unlike the process of re-encoding a file, for this process the video data is untouched. I used the tool on a movie and it completed within a few seconds.

./ffmpeg  -i Ultraviolet-1.mp4  -c copy -movflags faststart Ultraviolet.mp4

With that change applied, I the videos now stream fine.

If you would like to try this code out, it is available in GitHub at the following URL.

https://github.com/j2inet/VideoStreamNode

Creating Development Certificates for Samsung Tizen TVs

Whether you are developing for a consumer Samsung TV or for one of the commercial SSSP displays you’ll need to have a development certificate for your code to run. There is a difference in how the certificate is created for the commercial and consumer displays. But the process is similar off the same for both.

To get started you’ll need to already have Tizen Studio installed. Open the Tizen Studio package manager and make sure that you have the following components installed.

  • Samsung Certificate Extensions

If you don’t already have the component installed select it for installation. You’ll also need to have the SDK component installed for the version of Tizen that you are targeting (ex: “5.0 TV”).  Once the component is present start the Tizen Studio Device Manager.

The device manager will be used to get the device’s ID (DUID) for consumer TVs and for installing the development certificate onto the display. For these steps to work the TV must have development mode enabled and must be set to accept development requests from the same IP address as your development machine; it will refuse request from other addresses.  If you haven’t already enabled development mode I have another posts on how to do that
here
.

In the device manager there is an icon in the upper right corner of a phone connected a computer. Select this icon. It is for establishing connections to the device manager. In the window that opens you will see a list of devices that you’ve previously connect to. If the IP address of your display is there you can click on the icon of the on/off switch to reconnect to it. If the IP address of your display is not present click on the + icon to add it. When adding you can give the TV a descriptive name, enter the IP address, and the port on which to connect (usually 26101). Click on OK to return to the main Device Manager user interface and you should see your display connected. Right-click on the display and select DUID to see the ID of the display. Go ahead and copy it to the clipboard.  You will need it in later on.  If you have multiple displays for which you will develop  repeat the same steps to collect the DUID values for the other displays and save them to a text document.  Note that if you have both consumer and commercial displays that the DUIDs for them cannot be used  mixed with each other. You can perform the following steps for all of your consumer displays at once and then all of your commercial displays at once.

Open the Certificate Manager.  When it is opened for the first time you may be asked to select a location from which you want to import certificate profiles. Select Cancel here.  You will need to create both an Author certificate and a Distributor certificate. Click on the + icon in the upper right corner to start the process of creating a new certificate. What you select on the window that appears is dependent on the type of display for which you are developing.

TizenCertificateTypeSelection

Commercial (SSSP) Display Steps

For the commercial displays select “Tizen. ” In the next step you’ll be asked to enter a name for the certificate profile. If you develop for other device types (such as the mobile device, watch, or the consumer displays) you’ll need to have more than one certificate profile. It will be good for them to have easily identifiable names.  Enter a name here that let’s you know that this is a certificate for developing for a commercial display and select Next.

TizenEnteringCertificateProfileName

Next you must select an author certificate. If you’ve created an author certificate before you have the option to select it. If not then select the option to create a new one. I’ll assume that an author certificate has not been created yet. The minimal amount of information that you need for an author certificate is a name, a password for the certificate (don’t forget this password!). You can optionally enter your country code, State, City, Organization, department, and an e-mail address and a filename in which the key file for the certificate will be saved. Enter your options and select “Next”

TizenEnteringCertificateAuthorData

The last selection to make is whether you want to use the default Tizen distributer certificate . While this selection will allow you to submit mobile applications to the Tizen store it is fine for our purposes. Select it and click on “Finish.” With this you have a

TizenDistributerCertificateType

Consumer Display Steps

For the consumer displays when asked for the certificate type select “Samsung”.

TizenCertificateTypeSelection

On the next screen you’ll be asked for the device type. Select “TV.”

TizenDCertificateeviceType

Enter a name for the profile and select next.

TizenCertificateProfileName

Next you’ll select an author certificate. If you already have an author certificate that you’d like to use  you can select it here. If you would like to create a new certificate (which you would do if you’ve never created one before) select the first option. You would also select this option if you had a certificate but it has expired. If you had a certificate that has expired you may want to select the option to create a new certificate and check the box that says “Use an Existing Certificate.” If you have an application that has been published to the Tizen store before and are creating a new certificate then you’ll want to use this option since an application’s ID is in part based on the certificate with which it was signed.

TizenAuthorCertificateInformation

Enter the your author information. Remember what your password is, especially if you plan to publish your application under this certificate. When you click on “Next” you’ll be asked to sign into your Samsung account. After signing in your Author certificate is created.

You’ll be presented with the option of backing up your certificate. While this isn’t required it is strongly encouraged. You will want to keep this secure as it forms part of the identity for your apps. But you are almost done. You need a distributor certificate

TizenBackupCertificate

On the next screen you are prompted to either create a new distributor certificate or select an existing one. Choose the option to create a new one.

TizenNewDistributorCert

Now it is time to use the DUID that you copied earlier. If it is already on your clipboard it will automatically be pasted into one of the entries for DUID. You also have the option to change the privilege level, but not really. The two privileges available are “Public” and “Partner.” Partner gives you application to functionality that isn’t available to everyone. But to use Partner level privileges they have to be granted to you by Samsung.

TizenEnterDUID

After you click on “Next” you’ll be greeted with a confirmation that the certificate has been created along with the path to the certificate being shown.

TizenCertificateCreationComplete

For Both Consumer and Commercial

Now that your certificates have been created you need to let the display know about it so that it can recognize applications that were signed with your certificate and allow them to run. To do this return to the device manager. Right-click on the your display in the device manager and select “Permit to install apps.” The display is ready to accept applications now.

Switching Certificate Profiles

If you are developing for more than one type of Tizen device you’ll probably have to change which certificate profile that you are using as you change which platform you are working on. When you need to change profile open the certificate manager. You will see a list of the profiles that you’ve set up and a check-mark next to one marking it as the active profile. If you want to change which profile is active select it from the list and click on the check mark in the upper right corner.

With the certificate created and selected you can now move forward with deploying an application to the display. Start off with a hello world program just to see that it works.

51thAkzZ9BL._SL160_

Tizen Compatible TV

Introduction to Web Assembly with C/C++: Part 1

webassembly-logo

I’ve been taking advantage of Web Assembly lately. It is supported by all the major browsers, let’s one make use of already existing useful code that has been written for other environments, and provides some performance benefits over JavaScript. Web Assembly has a lot of potential and support and I’d like to introduce other developers to it. I’m going to be using C++ in this post. But by no means is this the only language in which someone can make use of Web Assembly. In this post I talk about why someone might want to consider web assembly and how to get a development environment setup.

What is Web Assembly?

Web Assembly is a specification for a virtual machine that runs in the browser. Compared the the highly dynamic JavaScript Web Assembly can achieve much higher performance. Contrary to popular misconception though Web Assembly doesn’t completely replace JavaScript. You will probably use the two together.  Web Assembly is based on LLVM  (Low Level Virtual Machine), a stack based virtual machine that compilers can target.  If someone wanted to make a new programming language they could have the compiler for their language produce LLVM code and then use an already existing tool chain to compile it to platform specific code. A person building a compiler for a new language wouldn’t need to make completely separate systems for different CPU architectures.  Web Assembly being LLVM based could run code that was written by a variety of languages. Currently there isn’t support for garbage collection yet which restricts the languages that target it presently. C/C++, C#, and Rust are a few languages that can be used with Web Assembly presently with more expected in the future.

What Other Languages Can I Use?

  • C/C++ – I’ll be using that language in this article
  • C#/.Net – I’ve got interest in this one and will write about it in the future.
  • Elixir
  • Go
  • Java
  • Python
  • Rust – This is a newer language

Why Use Web Assembly?

I suggest Web Assembly primarily for the performance benefits in computationally expensive operations.  The binary format it uses is much more strict than JavaScript and it is more suitable for computationally intensive operations. There is also a lot of existing and tested code for work such as cryptography or video decoders that exists in C/C++ that one might want to use in a page. Despite all its flexibility interpreted JavaScript code doesn’t run as fast as a native binary. For some types of applications this difference in performance isn’t important (such as in a word processor). For other applications differences in performance translate into differences in experiences.

While the demand for performance is a motivation to make a native binary there are also security considerations. Native binaries may have access to more system resources than a web implemented solution. There may be more concern with ensuring that a program (especially if it is from a third party) doesn’t do anything malicious or access resources without permission. Web Assembly helps bridge the gap between these two needs; it provides a higher performance execution environment within a sandbox.

WebAssemblySupport

C++? Can’t I Cause a Buffer Overflow With That?

Sure. But only within the confines of the sandbox in which the code will run. It could crash your program, but it can’t cause arbitrary execution of code outside the sandbox. Also note that presently Web Assembly doesn’t have any bindings to Host APIs. When you target Web Assembly you don’t have an environment that allows you to bypass the security restrictions in which JavaScript code will run. There’s no direct access to the file system, there’s not access to memory outside of your program, you will still be restricted to communicating with WebSockets and HTTP request that don’t violate CORS restrictions.

How Do I Setup a Developer Environment

There are different versions of instructions on the Internet for installing the Web Assembly tools. If you are running Windows 10 you may come across a set of instructions that start with telling you to install the Windows Subsystem for Linux. Don’t use those instructions; I personally think they are unnecessarily complex. While I have the Windows Sub System for Linux installed and running for other purposes that’s not where I like to compile my Web Assembly code.

Using your operating system of choice (Windows 10/8/7, macOS, Linux) clone the Emscripten git repository, run a few scripts from it, and you are ready to go. Here are the commands to use.  If you are on Windows omit the ./ at the beginning of the commands.

git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
git pull
./emsdk install latest
./emsdk activate latest

With the tools installed you will also want to set the some environment variables. There is a script for doing this. On Windows 10 run

emsdk_env.bat

For the other operating systems run

source emsdk_env.sh

The updates that this makes to environment variables isn’t persistent; it will need to be run again with the next reboot.  For an editor I suggest using Visual Studio Code. I’ll be compiling from the command line in this article. Feel free to use the editor of your choice.

Web Assembly Explorer

I don’t use it in this tool within this article, but Web Assembly Explorer is available as an online tool for compiling C++ into Web Assembly and is an option if you don’t have the tools installed.

https://mbebenita.github.io/WasmExplorer/

Hello World

Now that we have the tools installed we can compile and run something. We will do a hello world program. Type the following source code and save it in hello.cpp.

#include 
int main(int argc, char**argv) 
{
     printf("Hello World!\n");
    return 0;
}

To compile the code from the command line type the following.

emcc hello.cpp -o hello.html

After the compiler runs you will have three new files.

  • hello.wasm – the compiled version of your program
  • hello.html – an HTML page for hosting your web assembly
  • hello.js – JavaScript for loading your web assembly into the page

If you try to open the HTML file directly your code probably will not run. Instead the page will have to be served through an HTTP server. If you have node installed use the node http-server. You can install the http-server with

npm install  http-server -g

Then start the server from the directory with your hello.html

http-server . -p 81

Here I’ve instructed the http-server to run on port 81. You can use the port of your choice here provided nothing else is using it. Remember to substitute the port that you chose throughout the rest of these instructions.

Open a browser and navigate to http://localhost:81/hello.html. You’ll see your code run. If you view the source for the page there is a lot of “noise” in the file. Much of that noise is from the displayed images being embedded within the HTML.  That’s fine for playing around. But you will want to have something customized to your own needs.

We can provide a shell or template file for the compiler to use. Emscripten has a minimal file available at https://github.com/emscripten-core/emscripten/blob/master/src/shell_minimal.html. Download that file. It will be used as our starting point. It is convenient for the sake of distribution for everything to be in one file. But I don’t like the CSS and JavaScript being embedded within the file.  The CSS here isn’t needed and is being deleted. I’m moving the  JavaScript  to its own file and added a script references to it in my HTML.  There are several items within the HTML and the script that are not necessarily needed. Let’s look at the script first and start making this minimal file even more minimalist.

At the top of the script there are three variables to page elements to indicate download and progress. Those are not absolutely necessary. I’m deleting them.  I need to delete references to them too. Lower in the JavaScript is a method named setStatus . I’m replacing it’s body with a call to console.log() to print the text that is passed to it.  The first set of programs that I’m going to write won’t use a canvas. The element isn’t needed for now; I’m commenting it out instead of deleting it so that I can use it later.  Having deleted the first three lines of this file and and code that references them I’m returning to the HTML. Most of it is being deleted. I’ve commented out the canvas reference. There is a line in the HTML file with the text {{{ SCRIPT }}}. The compiler will take this file as a template and replace {{{ SCRIPT }}} with the reference to the script specific to our Web Assembly file.

webAssemble-templateHTML

When the Web Assembly program executes a printf() the text will be written to the textarea element. I place my hello.cpp file among these files and then compile it with the following command.

emcc hello.cpp --shell-file shell_minimal.html -o hello.html

The –shell-file argument indicates what file to use as a template. The -o parameter tells the name of the HTML file to write to. If you look at hello.html you can see it is almost identical to the input template. Run the site now and you’ll see the same result, but with a much cleaner interface. Run the program again and you will see the same result with a much cleaner interface.

Binding Functions

I earlier mentioned that Web Assembly doesn’t have any bindings to any operating system functions. It also doesn’t have bindings do the browser. Nor does it have access to the DOM. It is up to the page that loads the web assembly to expose functions to it. In emscripten.js the Modules object defines a number of functions that are going to be made available to the Web Assembly. When the C/C++ code calls printf it will be passed through the JavaScript function defined here of the same name. It isn’t a requirement that the names be the same, but it is easier to keep track of function associations if they are.

Calling C/C++ From JavaScript

But what if you have your own functions that you wish to bind so that your JavaScript code can call the C++ code? The Module object has a function named ccall that can be used to call C/C++ code from JavaScript and another function named cwrap to build a function object that we can hold onto for repeated calls to the same function. To use these functions some additional compile flags will be needed.

To demonstrate the use of both of these methods of calling C/C++ code from JavaScript I’m going to declare three new functions in the C++ code.

  • void testCall() – accepts no parameters and returns no value. This method only prints a string so that we know that our call to it was successful.
  • void printNumber(int num) – accepts an integer argument and prints it. This lets us know that our value was successfully called.
  • int square(int c) – accepts an integer and returns the square of that integer. This let’s us see that a value can be returned back from the code.

The C++ language perform what is called name mangling; the names of the functions in the compiled code is different than the uncompiled code. For the functions that we want to use from outside the C++ code we need to wrap declarations for the functions in an extern “C” block. If our code were being written in C instead of C++ this wouldn’t be necessary. I still prefer C++ because of some of the features that the language offers.  Normally I would have a declaration such as this in a header file. But for now my C++ program is in a single file. Close to the top of the program I make the following declarations.

extern "C" {
    void testCall();
    void printNumber(int f);
    int square(int c);
}
The implementation for the functions is what you would expect.
void testCall() 
{
    printf("function was called!\n");
}

void printNumber(int f) {
    printf("Printing the number %d\n", f);
}

int square(int c)
{
    return c*c;
}
There’s a change to my main method too. I’ve had to include a new header file, enscripten.h, because I am about to use one of the functions that it provides.  In main added the following line.
EM_ASM ( InitWrappers());
It will result in a JavaScript function named InitWrappers() to get called. I will talk about how EM_ASM works in a following section.   I’m adding a third

Tizen 6.0 M2 Release

Tizen recently announced the release of Tizen 6.0 M2. The Tizen operating system is most well known for running on Samsung TVs and smart watches. It can also be found on Samsung’s high-end TVs, custom embedded systems, and Samsung has spoken of licensing the OS and service to other TV manufacturers.

This release provides developers with a new kernel, device drivers, middleware subsystems, and APIs. The new kernel includes improved support for the Raspberry Pi 4. Also added is a new C# API for power management. The key features that Tizen is highlighting include the following.

  • Supports On-Device AI Vision (Media Vision Human Recognition Reference Model – Hand Skeleton, Human body pose)
  • Supports Tizen 64-bit AI platform development
  • Supports NUI 2.0 (2D and 3D Unified Framework, OneUI 2.x)
  • Supports Flexible Media Playback Engine and Interface
  • Supports BLE Mesh Framework for IoT devices
  • Supports Customizable Home Framework
  • Enhanced AI Programming Interfaces for voice
  • Enhanced Wearable Gesture Framework
  • Optimized power consumption for wearables, up to 3% improvement.

You can find more information on the release from this URL: https://docs.tizen.org/platform/release-notes/tizen-6-0-m2/


Follow me on

Twitter: @j2inet
Instagram: @j2inet
Facebook: j2inet
YouTube: j2inet

Posts may contain products with affiliate links. When you make purchases using these links, we receive a small commission at no extra cost to you. Thank you for your support.

ARM Development Summit

Like many conferences in 2020, ARM’s conference on development is available online. The videos of the summit are online until November 28th, but if you want to see them, you will need to register to see them by October 28. To register, go to this site. The conference list having the following tracks for their presentations.

AI in the Real World

Gain experience with the tools and techniques that will shape the future of AI and solve real-world challenges.

Building the IoT

Dive into transformative IoT technologies that train to take your ideas from concept through production.

Chip Design Methodology

Beyond silicon, see how to deliver your designs for more efficient targeted solutions.

Cloud Native Developer Experience

From operating systems to CI/CD tooling and more, learn cloud-native development for scalable architectures.

Creating the Next Generation of Interactive Experiences

Hear how to apply advanced technologies like ML and AR to your next mobile development project.

Infrastructure of Modern Computing

Learn how to make the most of the ARM architecture in High-Performance Computing networking and storage.

Tech for Global Goals: The World’s Largest To-Do List

Learn how organizations deploy technology to tackle some of the world’s most pressing problems

The Journey to Autonomous

Explore some of today’s most interesting engineering challenges from real-time signal processing, machinery control, embedded vision, and more.


Follow me on

Twitter: @j2inet
Instagram: @j2inet
Facebook: j2inet
YouTube: j2inet

Installing Visual Studio Code on Raspberry Pi and NVIDIA Jetson

While it is possible to run Visual Studio Code on a Raspberry Pi or a NVIDIA Jetson, the process previously had a few challenges. With one method, a user could grab the code from Microsoft and compile it for their device. This was time consuming and required that a person perform some steps to be set up for development. An easier method involved acquiring a build from a third party source. The issue there is the user must trust the third party source. Now these are no longer issues because Microsoft provides ARM binaries for Visual Studio Code. The installation can be done on both devices with the same steps.

To install VS code, navigate to VisualStudio.com and click on the Learn More link on the Visual Studio Code box. From there, if you click on Other Platforms you will see all of the downloads that are available for Visual Studio Code. For the Jetson series of hardware you will want to download the ARM64 deb installer. For Raspberry Pi, if you are using the a 64-bit OS installation grab an ARM64 build. Otherwise grab the ARM build.

After the build has downloaded, open a terminal and navigate to the folder where you saved the ARM file. From the terminal type the following command.

sudo dpkg -i name_of_file.deb

An actual file name should replace name_of_file.deb. After a minute or two the installation completes. You can start VS Code from the command line by typing the command code and pressing Enter. You can also find it within your program files. Videos of the installation are available below.

Video of Installation for Raspberry Pi
Video of Installation for NVIDIA Jetson

Instagram LogoLinked In

Web Conferences with a DSLR/Video Camera

I decided to make the switch from using my Microsoft LifeCam or the camera built into the computer to using my DSLR. When I made the switch, I didn’t disclose that I was using a different camera. I wanted to see if anyone noticed. It was noticed, and almost distracting😊! I received a few questions from coworkers from what I was doing different. In response, I’ve made this post and a video. In the video at the end of this post, you can see comparisons of quality for the cameras that I had used.

Note that some cameras can already be use as web cameras by downloading a firmware update or other camera specific software. You may want to check if your camera has this functionality available before making any purchases.

Canon 5D Mark II with Remote Focusing Motor

There are two primary pieces of hardware that are needed. Everything else is optional or can be improvised. The first is a camera that will produce clean HDMI output. By “Clean” I mean without the user interface elements on it. For a camera that supports this you may have to change a setting instructing it not show the UI elements on the output. You also will want to be able to disable the power saving features of the camera so that it does not power off while using it.

The second item that you need is an HDMI capture device that the computer “sees” as a Web Cam. Right now, the popular unit is the CamLink 4K. I’ve used a few of these for my day job and while they work, they also sometimes have errors that is just plain annoying. The device sometimes looses video signal. When it does, the only way I’ve been able to get it back is to unplug it and plug it back in. Another option that is not out yet is an HDMI capture decide from ATMOS. This device isn’t out yet, so I can’t recommend on its reliability. But I think it is worth considering.

Cam Link 4K HDMI Capture Device

The basic setup is to connect the HDMI capture device to the camera, turn the camera on, and plug it into a computer to use it as a web camera. That should be it, everything should work with no software installation required. For my setup, I do have additional hardware. While a table-top tripod would work, I prefer not to have fixtures take up space on my desk. To minimize the space being consumed I’m using a photography clamp to set an anchor point on the desk. A tripod extension attached to the clamp supports the camera. So that I can have the camera positioned as needed, I have a ball head between the camera and the tripod extension.

My camera is an older unit. It is a Canon 5D Mark III. A feature this camera does not have is refocusing automatically. Though even if it did, since my favourite lenses are fully manually, I would not have access to autofocus anyway. A potential focusing issue (since I prefer a shallow depth of field with my background blurred out) is that manual focusing on one’s self can be difficult. To adjust the focus I have to move to be able to reach the camera. But if I move then I am no longer in the field of vision where I need to be to know whether or not the camera is properly focused. The solution that I’m using for this the Nucleus-N wireless focusing unit. The Nucleus-N is composed of a wireless focusing knob and a motor that attached to the camera. When the knob is turned, the motor reacts and adjusts the lens.

If I were trying to setup this up from scratch and had to acquire a camera today, I would consider a mirrorless camera. The Canon EOS R and the Sony Alpha a7 would be at the top of my list.

Posts may contain products with affiliate links. When you make purchases using these links, we receive a small commission at no extra cost to you. Thank you for your support.

Debugging Android Applications over WiFi

I was recently working on an application that used the device’s accelerometer to extract information from the way that a person walks. While I was aware that it was possible to debug applications over WiFi, until now it wasn’t something that was absolutely needed. If I needed to get up and move a bit for an application, I had just used a longer USB cable. With this application it was essential that I want the way that I normally do. There was no way to do that with a USB cable connected to the device. Instead, it was necessary to use WiFi debugging.

Another reason why one might want to debug over WiFi simply to charge a device; some computers output a disappointing amount of current over their USB ports. For some applications, the device’s battery could continue to diminish as it is being used while connected to a computer. Using a higher wattage charge may be necessary if only to maintain the current battery amount.

For devices running Android 10 and earlier, making the network connection is easy. Start by making a USB connection. To ensure that there is a connection established use the following command.

adb devices

You should see your device listed. If it is, the next step is to establish a connection over the network. Ensure that your device and the computer being used for debugging are on the same network and subnet. Enable network debugging on your computer using the following command.

adb tcpip 5556

Here 5555 is the port number that will be used. You can use a different port number if you like. Using the IP address of your android device, you can establish a connection with the following command.

adb tcpip 192.168.1.97:5556

If all goes well, a message will be received that the device is connected. The device can now be physically disconnected from the computer. It will remain connected to the computer over the network connection.

Within Android Studio or adb if left connected the device will show twice.

Both devices showing within Android Studio

The device will continue to show as a connection until manually disconnected. To manually disconnect use the following command.

adb disconnect

Power Options for the Raspberry Pi 4

The Raspberry Pi has a few more power options than what one might gather from a quick glance. With the exception of the computer modules (which will get no further mention here) the Pis have a USB port for providing power. The Pi-4 has a USB-C port while the other units use micro-USB. In most cases having a 5-volt power supply with a the appropriate USB interface is sufficient. Using the USB interface, the Pi can be powered through a phone charger. This includes portable chargers, which might be used if the Pi needs to be placed where outlets are not available or if they must be movable. The USB port isn’t the only way to power the Pi though.

View this content in Video Form

Another way of powering the Pi is through the 40-pin connector. There are pins labeled 5V and GND. these pins are often used as a voltage output. But these pins can also be used as a voltage input. Applying appropriate voltage to these pines will power the Pi on. In addition to applying 5-volts directly, there are also Pi-hats made for interfacing to these pins. On the Pi-4 and Pi-3, just behind the Ethernet connector, there are 4 pins. These pins connect to the unused connections in the Ethernet jack. With a Power over Ethernet (PoE) hat, voltage supplied over these pins can be passed through a voltage regulator and then fed into the Pi.

Pi PoE Pins

To use this there are a few conditions that must be met. If you are considering this this solution then you will undoubtedly be using the Pi with a wired network connection. You also need a means of injecting power into the network. Some routers have this functionality build in. For routers that do not, there are various forms of PoE power injectors. With this solution a headless Pi only needs one cable for providing a network connection and a the power. Such hats are available in a number of form-factors. My preference is towards the one of the minimalist PoE adapters.

This adapter leaves many of the other pins open. If cooling is needed, the official Raspberry Pi PoE hat also has a fan.

Official Raspberry Pi PoE Hat

If you have a Pi that doesn’t support PoE, you are not out of luck! You can still take advantage of it with adapters for extracting power from the extra lines and routing it to the USB input on your Pi.

PoE Extractor with Micro-USB

Another way of powering a Pi is with batteries. While it is possible to take consumer batteries (AA or AAA batteries) and power a Pi with those, I would not suggest it. There are options available with higher capacities and other features that are worth considering. In looking at a battery solution not only might you want to consider the battery capacity, but the inclusion of a real time clock and the ability to query the power level of the batteries. The most basic solutions only provided power and a USB port for charging the battery.

Many of the solutions use 18650 batteries. So named because they are 18mm in diameter and 65mm long. These cells look a lot like enlarged AA batteries. Even if you don’t recognize them, you’ve probably encountered these batteries before in laptop computers. Unlike the diminutive consumer batteries of similar shape, these cells rate at having a nominal voltage of 3.7 volts each. With two batteries together they are able to meet and exceed the 5-volt power requirement for the Pi. Power regulation circuits within the battery adapters ensure that the power delivered to the Pi doesn’t exceed 5-volts.

Laptop battery with the contents shown.
A laptop battery that has been opened up to show the 18650 batteries from the inside.

One of my favourite is the Geekworm X728. This unit contains a real-time clock and has scripts available for probing the state of the battery. The unit allows settings for having the pi automatically startup when power is applied and shutting down when when the battery level is low. For increasing the battery capacity, additional pairs of batteries can be added to the X728-A2 . The X728-A2 is made only for connecting to the X728 and add additional batteries. Though if you have the know-how, you can connect additional batteries in parallel to the ones in the X728. The board shows the power level through three LEDS on the side. There’s also a dedicated power-button on the board for powering up and shutting down.

X728 In an Acrylic Case

In close second is the PiJuice. Right now the PiJuice is a lot more expensive than the X728 at almost twice the price. But it has an additional feature; the PiJuice allows scripts to be scheduled to run under specific power or time conditions. While the battery included with the PiJuice has lower capacity than a pair of 18650 batteries, there are use cases under which it could have longer usage before requiring a charge. On the PiJuice the Pi can be put to sleep, consuming much less power, and then wake up to perform some work and go back to sleep.

The PiJuice mounted to the back of a Pi 3B

The last battery kit I want to mention is sold under various names. When I ordered one, it was branded under GeekPi. While that specific SKU is no longer available, the same unit is available branded from MakerHawk. It is often described as a UPS (Uninterruptible Power Supply). It is the least expensive of the battery kits, costing less than half the price of either of the other two. But it doesn’t have any way for the pi to detect the battery level or a way to have the Pi react to power events. It only provides power and nothing more. Like the X728, one could connect additional batteries in parallel to increase the available energy.

UPS mounted to the underside of a Raspberry Pi 4

All of the battery solutions can also function as a UPS; if external power fails your Pi would be able to continue working. I’ve been able to keep the Pis running for hours at a time (days in the case of the Pi Juice on a wake/sleep schedule). I love the overall compactness of the the battery solutions made for the Pi. Some time in the future I plan to present one of the Pi based solutions that I made using the batteries.

Instagram LogoLinked In

Posts may contain products with affiliate links. When you make purchases using these links, we receive a small commission at no extra cost to you. Thank you for your support.

USB Networking with the Pi

 

I stumbled upon a thread in the Raspberry Pi forums about enabling networking on the USB-C port on the Raspberry Pi 4. At first glance I thought this would be about networking with a USB-C to Ethernet dongle. It’s not. It is about configuring the Raspberry Pi to present as a network adapter when connected to another device with a USB-C cable. While this might sounds like a rather pedestrian capability at first it is something that has a lot of potential. I see using this when I want to do development on the Pi and I’m in an environment in which a network isn’t available (such as when I’m on a long plane trip) or when there’s a network but I just can’t connect the Pi to it (such as on a corporate network).  Additionally since I expect my Android tablet to loose it’s ability to run Linux this provides a portable dev environment in which I can put the capabilities that I need.

The basic steps in what to do can be found on this thread posted by the user thagrol.  The steps are simple. I am re-posting the steps here.

  1. Open /boot/config.txt and add the line
    dtoverlay=dwc2
  2. Open /boot/cmdline.txt and append the following
    modules-load=dwc2,g_ether
  3. Reboot the Pi

After doing these steps when the Pi is connected to a computer the computer will see it as a networking device. If you list the network adapters on the Pi you will see a new network adapter with the name usb0.

thagrol notes that the mac address generated for both sides of this virtual network adapter will be different every time that the service is started. This can cause issues when using DHCP.   He provides a solution in the form of a script that will generate a set of MAC addresses based on a unique identifier in the Raspberry Pi.  After cloning the GIT repository for the script run it as root.

sudo ./set_id.py --test

PiMakeMAC

Once the addresses are generated they can be added to /boot/cmdline.txt. The addition will follow this format.

g_ether.host_addr=HOST_MAC_ADDRESS g_ether.dev_addr=DEVICE_MAC_ADDRESS

In my case  the additional entry will be

g_ether.host_addr=02:00:27:75:0a:a5 g_ether.dev_addr=06:00:27:75:0a:a5

I’m going to set a static IP on my pi. To do this the file /etc/dhcpcd.conf must be edited. Scrolling to the bottom of the file commented out is a demonstration of how to set a static address.

piDHCPSettings

For the USB interface I’e added two lines to the bottom of this file

interface usb0
static ip_address=10.11.12.13/24

After rebooting the Pi now shows this address for the USB network interface. I’m connecting to my pi with a Windows machine. After physically connecting the device a static IP address was set on the Windows side.

WindowsIPSettings

To ensure that things are working I started off trying to ping the device and received positive responses.

C:\Users\joel>ping 10.11.12.14

Pinging 10.11.12.14 with 32 bytes of data:
Reply from 10.11.12.14: bytes=32 time<1ms TTL=128
Reply from 10.11.12.14: bytes=32 time<1ms TTL=128
Reply from 10.11.12.14: bytes=32 time<1ms TTL=128
Reply from 10.11.12.14: bytes=32 time<1ms TTL=128

To try something a bit more functional I tried opening a folder on the Pi using Visual Studio Code running from my computer. Success!

vsRemote

In theory this could work with a phone or other mobile device. The restricting factor is whether someone’s mobile device allows changing settings on external network adapters. Many will allow communication over such adapters, but a much smaller set will allow you to change the settings.

20200507_163400.jpg
Editing a C# file on the Pi over SSH from a Chromebook

Something to note though, when using this solution on a mobile device there is a significant power drain, which makes sense; the mobile device’s battery is now working for two. There are a few ways to mitigate this but they break down to either batteries or external power. For batteries someone could add a battery to the Pi itself. There are a number of solutions that work well. I prefer PiJuice since it comes with some other options on invoking behaviours based power levels or time. Unfortunately at the time that I am writing this (during the 2020 shelter-at-home directive) this specific unit looks to be unavailable.

There are many other Pi batteries available. If you shop for one make sure that you purchase one that provides power through the headers or through pogo pens. Some provide power through the USB-C connector, which you need to keep available to act as a network connection.  Also give consideration to the connector used to charge the unit you select. You might prefer micro-USB or USB-C.  I would suggest not overclocking your Pi if it is running off of a battery. Some batteries might not be compatible with some types of cases. Ex: there is a Pi case that is essentially a heatsink that wraps the entire device. That would not work with with a power solution that uses pogo pens.

twitterLogofacebookLogo  youtubeLogo


Raspberry Pi 4


GeeekPi Raspbery Pi 4 UPS Power Supply


4PK 18650 Battery

Windows Terminal Preview

Windows_Terminal_Logo_256x256

I’ve started using the Windows Terminal preview and wish I had started sooner. Some of the functionality that is provides while simple is useful and gives a productivity boost. I’m bringing attention to the Windows Terminal because I find it so useful. The first question to answer is “What is it?”

From the name alone you might think that the Windows Terminal is yet another command line in the same ranks as the command prompt and PowerShell. This isn’t what it is. It is a new console host. The console host (c:\Windows\System32\conhost.exe)  may be something to which there’s not a lot of awareness, but it is a behind-the-scenes component that host console programs. When you start the command prompt it runs within the console host.

 

The Windows Terminal is an alternative console host. It is a program for managing various console environments in a single window with tabs.  Upon installation it is pre-configured for the Command Prompt, Powershell, and the Azure Cloud Shell. The availability of these items in a tabbed window alone is sufficient for me to find it useful. It isn’t limited to these programs though. The Windows Terminal is configurable to host other console programs through editing a JSON configuration file. There are some devices that I regularly connect to using SSH.  I’ve extended my configuration to have entries for these specific devices.  I had been previously using PUTTY for this but I find that with the Windows Terminal the process of opening a new tab into a device is easier.  The other connections are available in two clicks; one on a down-arrow on the tab, and another on the terminal to be opened.

WindowsTerminalOpenShell

Figuring out how to add items to the Windows Terminal is easy even without looking at the documentation. The Settings menu item in the drop down opens the configuration file in which you can see the entries for the PowerShell, Command Propmt, and Azure Cloud Shell.  If you wanted to add a new terminal you can copy one of the entries and makes changes.  There are a lot of other settings that haven’t been defined here. The fuller range of possible settings are published in Microsoft’s Github account.

https://github.com/microsoft/terminal/blob/master/doc/cascadia/SettingsSchema.md

A feature I find especially useful is the ability to set the a background image to the terminal The background image could be an animated GIF (I won’t do that, it is too distracting).  I have set the background images to something relevant to the terminal so that at a glance I can tell what terminal I’m looking at. For example, when I had a connection to one of my NVIDIA devices and a Raspberry Pi my windows look like the following.

terminals

I’ve made my images intentionally dark, but they can be within what ever color range is of your choosing. Color schemes for the text itself are also definable.  Custom images for icons and terminal backgrounds must be placed in one of two locations.

URI Scheme Location
ms-appdata:///Local/ %localappdata%\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\
ms-appdata:///Roaming/ %localappdata%\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\RoamingState\

For the entry for one of my Raspberry Pi’s I’ve got the following configuration using the Roaming URI scheme to refer to a background image.

{

    "guid": "{89CF3D23-06EA-4B1E-B42D-FC61239443ED}",
    "closeOnExit": true,
    "backgroundImage": "ms-appdata:///roaming/pi.png",
    "backgroundImageOpacity": 0.75,
    "backgroundImageStrechMode": "fill",
    "name": "SSH Raspberry Pi 3 (Sense Hat)",
    "commandline": "ssh 192.168.1.192 -l pi",
    "hidden": false
}

As with many keyboard driven interfaces there are hotkeys that you can press to perform actions. Some hotkeys are predefined, but you can define your own or change the predefined commands through the same JSON file in which the terminal entries exists.

In many programs pressing shift+enter will change a program to full screen model. I wanted to have the same behaviour in Windows Terminal and made an entry in the keybindings section for this.

{"command": "togleFullScreen", "keys": "shift+enter"}

The Windows Terminal also supports the full range of Unicode characters.  To take advantage of this the shell that you are using also needs to have support for it to. Many already do but had no way of properly displaying the characters.

unicode

The Windows Terminal is available in the Microsoft Store for free or from Github.

twitterLogofacebookLogo youtubeLogo

 


 
 
Windows Powershell Cookbook



Going Text:Mastering the Power of the Command Line

Sending Text Message from .NET

SMS

I met with some others in Singapore for a project deployment, and one of the other people there wanted a snippet of information sent to him. He wanted it sent to his phone. He asked what the most popular messaging application is in the USA. While Facebook Messenger is the most popular the messaging landscape in the USA is fractured. One’s preferred messenger is going to depend on their preferences and social circle (Telegram is my favourite). Because of this SMS remains the most reliable way of sending short messages to someone. When I am traveling around the USA or in some environments (the subway, inside certain buildings) I use SMS because data service becomes incredibly spotty.

I am making an ASP.NET application for which I want to be able to send notifications to a phone with no application installation necessary.  I will be using SMS as my message transport of choice. How does an application do this? There are a few solutions. One is to subscribe to an SMS Gateway Service and use their API.  I found several companies that provide these services. But many of them do not have price information openly available; speaking to a sales agent is necessary to get the price. A few that I encountered did share their prices. I share what I found here. Note that prices are subject to change and the older this post is the more likely the pricing information is stale.

SMS Gateway Services

Vonage

Vonage offers SMS services starting at 0.0068 USD per message sent and and 0.0062 per message received. They also rent out virtual phone numbers at 0.98 USD per month. Verizon and US Cellular charge an additional fee for sending messages via long codes (0.0025 USD for Vzw and 0.0050 USD for US Cellular).  If you would like to try it out a trial level subscription is available for free. Vonage provides SDKs for several languages. They also have full code samples for each one of these languages.

  • Ruby
  • PHP
  • Python
  • .Net
  • NodeJS
  • Java
  • CLI

ClickSend

ClickSend offers a REST API for accessing their services. Like Vonage they also offer SDKs for several environments and code samples on how to perform various actions. You will find code samples and/or SDKs for

  • cURL
  • PHP
  • C#
  • Java
  • Node.JS
  • Ruby
  • Python
  • Perl
  • Go
  • Objective-C
  • Swift

Pricing is structured much differently. There are pricing tiers dependent on how many messages are sent. The pricing tiers look like the following.

  • 0.0214 USD/message up to 2,000 messages
  • 0.0153 USD/message for more than 2,000 messages
  • 0.0104 USD/message for 10k messages or more
  • 0.0076 USD/message for 100k messages or more
  • Unspecified pricing for more than 200k messages

A dedicated number is purchasable for 3.06 USD/month. Short codes cost 886.82 USD/month.

D7 Networks

D7 Networks pricing is  0.005 USD/month for sending SMS for one-way communication. For 2-way communication the fee is 2.00 USD/month + 0.012 USD/message for outbound messages and 0.00 USD for incoming messages.  While there is no SDK there is a REST API (which is easy enough to consume from most development environments).

E-mail

Provided someone can identify their service provider e-mail is an option. An advantage of using Email to send an SMS is that it is free. A downside is that when registering with your service the recipient must know the service provider. While I do not think that is a general problem there may be cases where someone does not know; such as when their phone is part of a family plan and someone else handles the service. Another possible issue is a person properly registers but later changes their service provider and does not update it within your service.

Why does a user need to know their service provider for this to work? The USA carriers have domains that that are used for sending e-SMS messages via e-mail. Appending this domain to the end of someone’s phone number results in the e-mail address that is routed to their phones.

  • AT&T – @mms.att.net
  • Boost Mobile – @myboostmobile.com
  • Cricket Wireless – @mms.cricketwireless.net
  • Google Project Fi – @msg.fi.google.com
  • Republic Wireless – @text.republicwireless.com
  • Sprint – @messaging.sprintpcs.com
  • Straight Talk – @mypicmessages.com
  • T-Mobile – @tmobile.net
  • Ting – @message.ting.com
  • Tracfone – @mmst5.tracfone.com
  • US Cellular – @mms.usc.net
  • Verizon – @vzwpix.com
  • Virgin Mobile – @vmpix.com

Sending messages in .Net is just a matter of using the SmtpClient class. The exact configuration that you need will be dependent on your mail service. For my mail service I have pre-configured the credentials in the computer’s credential store so that the information does not need to be stored in my application’s configuration.

SmtpClient mailClient = new SmtpClient("myMailServer.com")
{
     Credentials = CredentialCache.DefaultNetworkCredentials
};
var message = new MailMessage(
   "FromAddress@myserver.com", 
   "phoneMailAddress@carrierDomain.com", 
   "", //blank subject
   "test body"
);
mailClient.Send(message);
twitterLogofacebookLogo   youtubeLogo

j2i.net posts may contain products with affiliate links. When you make purchases using these links, we receive a small commission at no extra cost to you. Thank you for your support.


PRO ASP.NET CORE 3


c# 8

Introduction to SASS

SASS, or Syntactically Awesome Style Sheets, are a style sheet language that compile to CSS. I have mentioned languages that compile to another language before. TypeScript is an example. If you have used a system that compiles one language to another you may be able to guess why someone might want to make a new style sheet language that compiles to another.

SASS retains some amount of familiarity with CSS. This alternative syntax is more expressive; a developer can write less code to express the same design as the equivalent CSS. It also is not necessary to wait on browsers to have some feature to start using SASS; the layer of separation provided by the compiler allows SASS to have less dependencies on a browser supporting a set of features to be useful. In this first of a two part post I wanted o introduce some of the elements of SASS. Here I demonstrate variables, nesting, and replacement. In the second post I will focus on control structures and functions.

There are several GUI and command line solutions for compiling SASS. My preference is for the command line tool. The command line tool is easy enough to use both directly and to integrate into other build tools.  Installation using the Node Package Manager works on Windows, Linux, and macOS (though for me it does not work with the Windows Power Shell while it works fine in the command terminal).

npm install sass -g

If you would like to check if a system has sass installed and the version number type the following.

sass --version

Much like TypeScript, think of SASS as a super set of CSS. This is not 100% the case, but it is a good starting point for understanding. SASS styles might be distributed among several files, but when compiled the output will be in a single files.  SASS files will typically have the extension *.scss.  As an initial test I have created two files in a folder. One is named first.scss and the other is named second.scss. The following is the contents of first.sass:

@import 'second';
first {
font-family: Arial;
}

And of second.sass:

second{
font-family: Arial;
}

Since first.sass is my main file of this set to compile these files I am selecting first.sass as the input to the pre-processor. When the pre-processor encounters the @import keyword it will replace that line with the contents of the files whose name is specified there. Note that I did not need to include the extension to the file name here.  To compile these files I use the following command:

sass first.sass output.css

After running the command there is a new file named output.css.

second {
font-family: Arial;
}

first {
font-family: Arial;
}

Chances are that you are not going to want to issue a command at the command prompt every time you make a change to one of the SASS files.  To avoid this you can add the parameter –watch to the command line and allow it to continue to run. Every time you modify a SASS file the compiler will regenerate output.css.

sass --watch first.scss output.css

Variables

One of the first constructs that you will use in SASS is variables. Variables are recognizable from the $ prefix that they have. A variable can hold a Boolean, color, numeric, or string values. It is easy to undervalue variables at first; CSS already provide variables. Why are SASS variables needed? SASS variables are usable in places and ways in which CSS variables are not.  Some of the ways that variables can be used to create a style sheet will come up in some of the following sections. Let us look at a typical scenario first.

$primaryColor : #FF0000;
$secondaryColor: #FFFFD0;
This creates two variables that hold colors. These colors can be used within the SASS  in place of an actual color code.
body {
   color:$primaryColor;
   background-color: $secondaryColor;
}

.container > div {
   margin:1px;
   color:$secondaryColor;
   background-color: $primaryColor;
}

Variables have a scope. If a variable is declared outside of brackets it is globally accessible. If it is declared within the SASS block enveloped by brackets it is only visible to the SASS code within that block. In the following the second instance of $borderColor will cause an error from a variable not being defined. The variable of the same name declared in the first block is not within scope.

body {
   $borderColor: #0000FF;
   color:$primaryColor;
   background-color: $secondaryColor;
}

.container > div {
   margin:1px;
   color:$secondaryColor;
   background-color: $primaryColor;
   border: 1px solid $borderColor;
}

Default Values for Variables

You may make a SASS and want to allow a user to customize it through defining values for some variables. But you might not want to obligate the user to define values for all of the variables that your SASS uses. For this scenario there are default values.  To assign a variable a default values append the assignment with !default.
$primaryColor: #FF0000 !default;
The assignment occurs only if the variable is undefined or has a null values.  If there are any SASS definitions that use the variable before it is assigned a values other than its default those blocks that occur before the new assignment will not have the new values. The default would need to be overridden before it was used.  This could mean defining a variable before including the library that will be used. But there is another way that I think is cleaner.
With the @use directive a SASS library can be included and the variables to be assigned new values can be specified using the keyword “with” and a list of the variable assignments.
@use  'second' with (
   $primaryColor: #FF00FF
)

Nesting Selectors

The ability to nest selectors is a feature that in my opinion allows for much neater style sheets. It is common within CSS to have selectors based on some parent/child relationship. Here is a simple example.

.demoView {
   width:1080px;
   height:1920px;
}

.demoView .left {
   background-color: red;
}

.demoView .middle {
   background-color: green;
}

.demoView .right {
   background-color: blue;
}
While these style selectors are all related they are each in their own  own declaration independent of each other. Under SASS they could be grouped together. Each selector is referring to elements that are children of an element of the demoView class. A single demoView declaration is made in my SASS file. For selectors that are targeting children of demoView within SASS they are declared within  the demoView class selector.
.demoView {
   width:1080px;
   height:1920px;

   .left {
      background-color: red;
   }
   .middle {
      background-color: green;
   }
   .right {
      background-color: blue;
   }
}
I personally find this pleasing since the SASS’s layout is now closer to the arrangement of the elements within the HTML.

Parent Selector

The ampersand (&) character is used as a parent selector operator.  The & is replaced with what ever the parent selector is.
a {
   text-decoration: none;;
   &:hover {
      color:red;
   }
}
Here the potential use of the operator might not be entirely obvious. Think of it as performing a string replacement.
.icon {
   &-left {
      color:red;
   }
   &-right {
      color:yellow;
   }
}
This expands to the following.
.icon {
   &-left {
      color:red;
   }
   &-right {
      color:yellow;
   }
}
Not that this is the only way that a string substitution can occur. There is also the string interpolation operation.

String Interpolation

String interpolation substitutes the values of a variable into a string. String interpolation operations use #{}  with a variable name inserted between the brackets. String interpolation can be used in a selector, attribute name, or values.
$index:4;
item-#{$index} {
   color:red;
}
expands to
item-4 {
color: red;
}
The potential for this operation becomes more powerful once used within other constructs such as loops. Control structures will be the topic of the second half of this post, but I will show a brief example here.
@for $i from 1 to 4 {
   item-#{$i} {
      animation-delay: #{$i}s;
   }
}
item-1 {
   animation-delay: 1s;
}

item-2 {
   animation-delay: 2s;
}

item-3 {
   animation-delay: 3s;
}

Placeholder Selectors and @extend

Placeholder selectors look like class selectors. But they are proceeded with a % instead of a period. The first thing to note about placeholder selectors is that they do not generate any CSS output. Any selector that contains a place holder selector will not be rendered to the CSS output. At first, placeholders appear useless. The placeholder selectors are made to be used with @extend. Use @extend to import the attributes from a place holder selector into another selector.
%blockElement {
   display:block;
   width:100px;
   height:100px;
}

.redBlock {
   @extend %blockElement;
   background-color: red;
}

.greenBlock {
   @extend %blockElement;
   background-color: green;
}
This is the CSS produced by the above.
.greenBlock, .redBlock {
display: block;
width: 100px;
height: 100px;
}

.redBlock {
background-color: red;
}

.greenBlock {
background-color: green;
}
Nothing in what I have shown thus far is complex and I think it is easy to to understand the individual elements. But for a deeper understanding I think it best to start putting this information to use. Exercise one’s understanding through some simple projects to strengthen that understanding.  When the next portion of this post is published  will dive straight into control structures and functions. With those the potential to generate complex CSS from much simpler SASS increases significantly.
Until the next entry if you would like to see my other posts on HTMLrelated topics click here.
twitterLogofacebookLogo  youtubeLogo


Mastering SASS


SASS and Compass