Skip to content

Instantly share code, notes, and snippets.

@mon-jai
Last active April 21, 2023 04:36
Show Gist options
  • Save mon-jai/bde53f3681e9d385719369a2405bcab6 to your computer and use it in GitHub Desktop.
Save mon-jai/bde53f3681e9d385719369a2405bcab6 to your computer and use it in GitHub Desktop.

Lab 2

#include <errno.h>
#include <fcntl.h>
#include <iostream>
#include <map>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

using namespace std;

map<int, int> led_id_to_gpio = {{1, 255}, {2, 429}, {3, 398}, {4, 389}};

int gpio_export(unsigned int gpio) {
  int fd, len;
  char buf[64];
  fd = open("/sys/class/gpio/export", O_WRONLY);

  if (fd < 0) {
    perror("gpio/export");
    return fd;
  }

  len = snprintf(buf, sizeof(buf), "%d", gpio);
  write(fd, buf, len);
  return 0;
}

int gpio_unexport(unsigned int gpio) {
  int fd, len;
  char buf[64];
  fd = open("/sys/class/gpio/unexport", O_WRONLY);

  if (fd < 0) {
    perror("gpio/export");
    return fd;
  }

  len = snprintf(buf, sizeof(buf), "%d", gpio);
  write(fd, buf, len);
  return 0;
}

int gpio_set_dir(unsigned int gpio, string dirStatus) {
  int fd;
  char buf[64];

  snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio);

  fd = open(buf, O_WRONLY);

  if (fd < 0) {
    perror("gpio/export");
    return fd;
  }

  if (dirStatus == "out") write(fd, "out", 4);
  else write(fd, "in", 3);

  close(fd);
  return 0;
}

int gpio_set_value(unsigned int gpio, int value) {
  int fd;
  char buf[64];

  snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio);

  fd = open(buf, O_WRONLY);

  if (fd < 0) {
    perror("gpio/export");
    return fd;
  }

  if (value == 0) write(fd, "0", 2);
  else write(fd, "1", 2);

  close(fd);
  return 0;
}

void turn_on_led(int led_id) {
  int gpio = led_id_to_gpio[led_id];
  gpio_export(gpio);
  gpio_set_dir(gpio, "out");
  gpio_set_value(gpio, 1);
  printf("ON: LED%d %d\n", led_id, gpio);
}

void turn_off_led(int led_id) {
  int gpio = led_id_to_gpio[led_id];
  gpio_set_value(gpio, 0);
  gpio_unexport(gpio);
  printf("OFF: LED%d %d\n", led_id, gpio);
}

int main(int argc, char* argv[]) {
  int input;

  if (argv[1][0] == 'L' && argv[1][1] == 'E' && argv[1][2] == 'D') {
    int led_id = argv[1][3] - '0';

    if (argv[2][0] == 'O' && argv[2][1] == 'N') {
      turn_on_led(led_id);
    } else {
      turn_off_led(led_id);
    }
  } else {
    for (int led_id = 0; led_id >= 4; led_id++) turn_off_led(led_id);

    int cycle_no = argv[2][0] - '0';
    for (int i = 0; i < cycle_no; i++) {
      int led_to_light_up[2];
      int odd_leds[2] = {1, 2};
      int even_leds[2] = {3, 4};

      // https://stackoverflow.com/a/28008133
      memcpy(led_to_light_up, (i % 2) == 0 ? odd_leds : even_leds, sizeof led_to_light_up);

      for (auto led_id : led_to_light_up) turn_on_led(led_id);
      sleep(1);
      for (auto led_id : led_to_light_up) turn_off_led(led_id);

      printf("\n");
    }
  }
}
all: clean L2Program

L2Program:
	aarch64-linux-gnu-g++ -std=c++11 -o L2Program L2Program.cpp

scp:
	scp ./L2Program [email protected]:/home/nvidia 

clean:
	rm -f L2Program

Lab 4

import { createServer } from "http"
import { readFile } from "fs/promises"
import { dirname, resolve } from "path"
import { fileURLToPath } from "url"
import { execFile as execFile_callback } from "child_process"
import { promisify } from "util"
import { appendFile, unlink } from "fs/promises"
import { createTransport } from "nodemailer"

const execFile = promisify(execFile_callback)

async function log(message) {
  message = message.trim() + "\n"
  console.log(message)
  await appendFile(log_path, message)
}

const port = 80
const current_directory = dirname(fileURLToPath(import.meta.url))
const log_filename = "gpio.log"
const log_path = resolve(current_directory, log_filename)
const gpio_path = resolve(current_directory, "bin", "gpio")
const html_path = resolve(current_directory, "index.html")

await unlink(log_path)

createServer(async (request, response) => {
  const { url, method } = request
  await log(`REQUEST: ${JSON.stringify({ url, method })}`)

  if (url == "/" || url == "/index.html") {
    response.end(await readFile(html_path))
  }

  if (url.startsWith("/led/")) {
    const { led_id } = url.match(/^\/led\/(?<led_id>\d)\/?$/).groups
    const { stdout } = await execFile("sudo", [gpio_path, `LED${led_id}`, method === "PUT" ? "ON" : "OFF"])
    await log(stdout)
  }

  if (url.startsWith("/make_shine/")) {
    const { shine_count } = url.match(/^\/make_shine\/(?<shine_count>\d)\/?$/).groups
    const { stdout } = await execFile("sudo", [gpio_path, "make_shine", shine_count])
    await log(stdout)
    await log("Switch End")
  }

  response.status = 200
  response.end()
}).listen(port, async () => {
  await log(`Server is running on port ${port}`)
})

process.on("SIGINT", async () => {
  await log("Server is down")

  const transporter = createTransport({
    service: "Gmail",
    auth: {
      user: "[email protected]",
      pass: "bbfvlwcstpetwlfi",
    },
  })

  // https://github.com/nodemailer/nodemailer/issues/759#issuecomment-292861074
  await promisify(transporter.sendMail).bind(transporter)({
    from: "[email protected]",
    to: "[email protected]",
    subject: `Server log ${new Date().toLocaleString()}`,
    attachments: [
      {
        filename: log_filename,
        content: await readFile(log_path),
      },
    ],
  })

  process.exit()
})

// sudo snap install node --classic --channel=18
// export PATH=/snap/node/current/bin:$PATH
// npm start
BIN_PATH = bin/gpio

all: $(BIN_PATH)

.PONY: $(BIN_PATH)

setup:
	sudo apt update
	sudo apt install -y g++-aarch64-linux-gnu

$(BIN_PATH):
	aarch64-linux-gnu-g++ -std=c++11 -o $(BIN_PATH) bin/L2Program.cpp
rsync -r ./* [email protected]:/home/nvidia/web-server
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment