Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QRcode #102

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
19 changes: 19 additions & 0 deletions .github/workflows/ccpp.yml
@@ -0,0 +1,19 @@
name: C/C++ CI

on: [push]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1
- name: Checkout submodules
uses: textbook/git-checkout-submodule-action@2.0.0
- name: make
run: cd src && make
# - name: make check
# run: make check
# - name: make distcheck
# run: make distcheck
3 changes: 3 additions & 0 deletions .gitmodules
@@ -0,0 +1,3 @@
[submodule "src/libqrencode"]
path = src/libqrencode
url = https://github.com/fukuchi/libqrencode.git
14 changes: 8 additions & 6 deletions src/Makefile
Expand Up @@ -4,7 +4,7 @@
#

CLEANUP :=
CFLAGS :=
CFLAGS := -DHAVE_CONFIG_H
ASFLAGS :=
LDFLAGS :=
HOST_CFLAGS :=
Expand Down Expand Up @@ -101,6 +101,7 @@ SRCDIRS += hci/mucurses hci/mucurses/widgets
SRCDIRS += hci/keymap
SRCDIRS += usr
SRCDIRS += config
SRCDIRS += libqrencode

# These directories contain code that is not eligible for UEFI Secure
# Boot signing.
Expand All @@ -118,6 +119,7 @@ SRCDIRS_INSEC += drivers/net/ath/ath9k
NON_AUTO_SRCS :=
NON_AUTO_SRCS += core/version.c
NON_AUTO_SRCS += drivers/net/prism2.c
NON_AUTO_SRCS += libqrencode/qrenc.c

# INCDIRS lists the include path
#
Expand All @@ -129,11 +131,11 @@ INCDIRS += include .
# Default build target: build the most common targets and print out a
# helpfully suggestive message
#
ALL := bin/blib.a bin/ipxe.dsk bin/ipxe.lkrn bin/ipxe.iso \
bin/ipxe.usb bin/ipxe.pxe bin/undionly.kpxe bin/rtl8139.rom \
bin/8086100e.mrom bin/80861209.rom bin/10500940.rom \
bin/10222000.rom bin/10ec8139.rom bin/1af41000.rom \
bin/8086100f.mrom bin/808610d3.mrom bin/15ad07b0.rom
ALL := bin/blib.a bin/ipxe.dsk bin/ipxe.lkrn bin/ipxe.iso \
bin/ipxe.usb bin/ipxe.pxe bin/undionly.kpxe bin/rtl8139.rom \
bin/8086100e.mrom bin/80861209.rom bin/10500940.rom \
bin/10222000.rom bin/10ec8139.rom bin/1af41000.rom \
bin/8086100f.mrom bin/808610d3.mrom bin/15ad07b0.rom

all : $(ALL)
@$(ECHO) '==========================================================='
Expand Down
28 changes: 21 additions & 7 deletions src/hci/strerror.c
Expand Up @@ -21,6 +21,8 @@

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

int uriqrencode(const char * URI, char *outbuff, size_t outbuff_sz);

/**
* Find error description
*
Expand Down Expand Up @@ -76,7 +78,13 @@ static struct errortab * find_closest_error ( int errno ) {
*
*/
char * strerror ( int errno ) {
static char errbuf[64];
#define SQUARE 46

static char errbuf[(((SQUARE/2)+1)*SQUARE)];
// static char errbuf[64];
char errURL[32];
int offset = 0;

struct errortab *errortab;

/* Allow for strerror(rc) as well as strerror(errno) */
Expand All @@ -86,17 +94,23 @@ char * strerror ( int errno ) {
/* Find the error description, if one exists */
errortab = find_closest_error ( errno );

snprintf ( errURL, sizeof ( errURL ),
PRODUCT_ERROR_URI,
errno );

/* Construct the error message */
if ( errortab ) {
snprintf ( errbuf, sizeof ( errbuf ),
"%s (" PRODUCT_ERROR_URI ")",
errortab->text, errno );
offset = snprintf ( &errbuf[offset], sizeof ( errbuf ) - offset,
"%s (%s)",
errortab->text, errURL );
} else {
snprintf ( errbuf, sizeof ( errbuf ),
"Error %#08x (" PRODUCT_ERROR_URI ")",
errno, errno );
offset = snprintf ( &errbuf[offset], sizeof ( errbuf ) - offset,
"Error %#08x (%s)",
errno, errURL );
}

uriqrencode(errURL, &errbuf[offset], sizeof(errbuf) - offset );

return errbuf;
}

Expand Down
132 changes: 132 additions & 0 deletions src/hci/urlqrencode.c
@@ -0,0 +1,132 @@
/* Based on code example from libqrencode and modified to use IBM CP 437 chars */

#include "libqrencode/qrencode.h"
#include <stdio.h>
#include <stdlib.h>

#include <string.h>

#define margin 4

static const char glyphs[] =
" " /* White Space */
"\xDC" /* Low Block */
"\xDF" /* High Block */
"\xDB"; /* Full Block */

static int writeANSI_margin(char* outbuff, size_t outbuff_sz, int width, int p_margin, const char *white, const char *reset )
{
int y;
int len = 0;

for (y = 0; y < margin; y+=2 ) {
len += snprintf( &outbuff[len], outbuff_sz - len, "%s", white); /* Initialize the color - default white */
len += snprintf( &outbuff[len], outbuff_sz - len, "%*c", width + (p_margin*2), ' ');
len += snprintf( &outbuff[len], outbuff_sz - len, "%s\n", reset); // reset to default colors for newline
}
return len;
}

static int writeANSI(const QRcode *qrcode, char *outbuff, size_t outbuff_sz)
{
unsigned char *rowH;
unsigned char *rowL;
unsigned char *p;
int x, y;
int len = 0;

const unsigned char *E = (const unsigned char *)"";

// const char white[] = "\033[47m";
const char white[] = "";
const int white_s = sizeof( white ) -1;
// const char black[] = "\033[40m";
// const char reset[] = "\033[0m";
const char reset[] = "";

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
const size_t minLen = (( (white_s) * 2 ) + ( (qrcode->width * 2) * qrcode->width )); // Unlikely
// const size_t maxLen = (( (white_s) * 2 ) + ( (qrcode->width * 2) * qrcode->width * (white_s + 1 ))); // Unlikely
// const size_t typLen = (minLen + maxLen)/2; // More typical?
#pragma GCC diagnostic pop

if ( outbuff_sz < minLen ) {
snprintf(outbuff, outbuff_sz, "Insufficient buffer to render URL QR-Code.\n\tNeed at least %d bytes, only have %d\n", minLen, outbuff_sz);
// return( -1 ); // Error
}

/* top margin */
len += writeANSI_margin(&outbuff[len], outbuff_sz-len, qrcode->width, margin, white, reset);
/* data */
p = qrcode->data;
for(y = 0; y < qrcode->width; y+=2) {
rowH = (p+((y+0)*qrcode->width));
rowL = (p+((y+1)*qrcode->width));

len += snprintf( &outbuff[len], outbuff_sz - len, "%s", white); /* Initialize the color - default white */
for(x = 0; x < margin; x++ ){
len += snprintf( &outbuff[len], outbuff_sz - len, "%s", " ");
}

for(x = 0; x < qrcode->width; x++) {
len += snprintf( &outbuff[len], outbuff_sz - len, "%c", glyphs[
( ((*( rowH+x )&0x1)<<1) |
((*((y+1)<qrcode->width?rowL+x:E)&0x1)<<0) )
]);
}

for(x = 0; x < margin; x++ ){
len += snprintf( &outbuff[len], outbuff_sz - len, "%s", " ");
}
len += snprintf( &outbuff[len], outbuff_sz - len, "%s\n", reset);
}

/* bottom margin */
len += writeANSI_margin(&outbuff[len], outbuff_sz-len, qrcode->width, margin, white, reset);

return len;
}

int uriqrencode(const char * URI, char *outbuff, size_t outbuff_sz)
{

QRcode *qrcode = QRcode_encodeString(URI, 0, QR_ECLEVEL_L,
QR_MODE_8, 1);

outbuff_sz = writeANSI( qrcode, outbuff, outbuff_sz );

QRcode_free(qrcode);
return outbuff_sz;
}

//#define TEST_QRCODE

#ifdef TEST_QRCODE
int main(int argc, char *argv[])
{
#define SQUARE 46

char buffer[((SQUARE*2)*SQUARE)];
char* arg;

int len;

if (argc < 2) {
fprintf(stderr, "Usage: %s string\n", argv[0]);

arg = "https://youtu.be/Xe1o5JDwp2k";
} else {
arg = argv[1];
}

len = uriqrencode( arg, buffer, sizeof( buffer ) );

if (len < 0) {
fputs( "Error\n", stdout );
}
fputs( buffer, stdout );

return 0;
}
#endif /* TEST_QRCODE */
1 change: 1 addition & 0 deletions src/libqrencode
Submodule libqrencode added at 13b159