RPi Locator and Display Services
skn_rpi_helpers.c File Reference
+ Include dependency graph for skn_rpi_helpers.c:

Go to the source code of this file.

Functions

static void skn_display_print_usage ()
 
static PDisplayManager skn_display_manager_create (char *welcome)
 
static void skn_display_manager_destroy (PDisplayManager pdm)
 
static void * skn_display_manager_message_consumer_thread (void *ptr)
 
static PLCDDevice skn_device_manager_init_i2c (PDisplayManager pdm)
 
PLCDDevice skn_device_manager_SerialPort (PDisplayManager pdm)
 
PLCDDevice skn_device_manager_MCP23017 (PDisplayManager pdm)
 
PLCDDevice skn_device_manager_MCP23008 (PDisplayManager pdm)
 
PLCDDevice skn_device_manager_PCF8574 (PDisplayManager pdm)
 
void skn_device_manager_backlight (int af_backlight, int state)
 
int skn_device_manager_LCD_setup (PDisplayManager pdm, char *device_name)
 
int skn_device_manager_LCD_shutdown (PDisplayManager pdm)
 
long getCpuTemps (PCpuTemps temps)
 
int generate_rpi_model_info (char *msg)
 
int generate_cpu_temps_info (char *msg)
 
char * skn_scroller_pad_right (char *buffer)
 
char * skn_scroller_wrap_blanks (char *buffer)
 
int skn_scroller_scroll_lines (PDisplayLine pdl, int lcd_handle, int line)
 
PDisplayLine skn_display_manager_add_line (PDisplayManager pdmx, char *client_request_message)
 
PDisplayManager skn_get_display_manager_ref ()
 
int skn_display_manager_do_work (char *client_request_message)
 
int skn_display_manager_message_consumer_startup (PDisplayManager pdm)
 
void skn_display_manager_message_consumer_shutdown (PDisplayManager pdm)
 
int skn_handle_display_command_line (int argc, char **argv)
 

Variables

int gd_i_rows = 4
 
int gd_i_cols = 20
 
char * gd_pch_serial_port
 
char * gd_pch_device_name = "pcf"
 
PDisplayManager gp_structure_pdm = NULL
 

Function Documentation

int generate_cpu_temps_info ( char *  msg)

DO NOT USE THIS IN MODULES THAT HANDLE A I2C Based LCD RPi cannot handle I2C and GetCpuTemp() without locking the process in an uniterrupted sleep; forcing a power cycle.

Definition at line 348 of file skn_rpi_helpers.c.

References _temps::c, _temps::f, getCpuTemps(), and SZ_INFO_BUFF.

348  {
349  static CpuTemps cpuTemp;
350  int mLen = 0;
351 
352  memset(&cpuTemp, 0, sizeof(CpuTemps));
353  if ( getCpuTemps(&cpuTemp) != -1 ) {
354  mLen = snprintf(msg, SZ_INFO_BUFF-1, "CPU: %s %s", cpuTemp.c, cpuTemp.f);
355  } else {
356  mLen = snprintf(msg, SZ_INFO_BUFF-1, "Temp: N/A");
357  }
358 
359  return mLen;
360 }
char c[SZ_CHAR_LABEL]
long getCpuTemps(PCpuTemps temps)
#define SZ_INFO_BUFF
Definition: cmdDC.c:56
char f[SZ_CHAR_LABEL]

+ Here is the call graph for this function:

int generate_rpi_model_info ( char *  msg)

Definition at line 328 of file skn_rpi_helpers.c.

References gd_ch_intfName, gd_ch_ipAddress, skn_get_number_of_cpu_cores(), and SZ_INFO_BUFF.

Referenced by skn_display_manager_do_work().

328  {
329  int model = 0, rev = 0, mem = 0, maker = 0, overVolted = 0, mLen = 0;
330  char * message = "Device has an unknown model type.\n";
331 
332  piBoardId(&model, &rev, &mem, &maker, &overVolted);
333  if (model == PI_MODEL_UNKNOWN) {
334  mLen = snprintf(msg, SZ_INFO_BUFF -1, "%s", message);
335  } else {
336  mLen = snprintf(msg, SZ_INFO_BUFF -1, "Device: %s, Cpus: %ld, Rev: %s, Mem: %dMB, Maker: %s %s, %s:%s", piModelNames[model],
337  skn_get_number_of_cpu_cores(), piRevisionNames[rev], mem, piMakerNames[maker], overVolted ? "[OV]" : "", gd_ch_intfName,
339  }
340  return mLen;
341 }
long skn_get_number_of_cpu_cores()
char gd_ch_intfName[SZ_CHAR_BUFF]
#define SZ_INFO_BUFF
Definition: cmdDC.c:56
char gd_ch_ipAddress[SZ_CHAR_BUFF]

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

long getCpuTemps ( PCpuTemps  temps)

DO NOT USE THIS IN MODULES THAT HANDLE A I2C Based LCD RPi cannot handle I2C and GetCpuTemp() without locking the process in an uniterrupted sleep; forcing a power cycle.

Redhat/Centos: /sys/class/hwmon/hwmon0/device/temp1_input Ubuntu/Debian: /sys/class/thermal/thermal_zone0/temp

Definition at line 293 of file skn_rpi_helpers.c.

References _temps::c, _temps::cbName, _temps::f, _temps::raw, and SD_WARNING.

Referenced by generate_cpu_temps_info().

293  {
294  long lRaw = 0;
295  int rc = 0;
296 
297  FILE *sysFs = fopen("/sys/class/thermal/thermal_zone0/temp", "r");
298  if (sysFs == NULL) {
299  skn_logger(SD_WARNING, "Warning: Failed to open Debian CPU temperature: %d:%s\n", errno, strerror(errno));
300  sysFs = fopen("/sys/class/hwmon/hwmon0/device/temp1_input", "r");
301  if (sysFs == NULL) {
302  skn_logger(SD_WARNING, "Warning: Failed to open Centos CPU temperature: %d:%s\n", errno, strerror(errno));
303  return -1;
304  }
305  }
306 
307  rc = fscanf(sysFs, "%ld", &lRaw);
308  fclose(sysFs);
309 
310  if (rc != 1 || lRaw < 0) {
311  skn_logger(SD_WARNING, "Warning: Failed to READ CPU temperature: %d:%s\n", strerror(errno));
312  return -1;
313  }
314 
315  if (temps != NULL) { // populate struct
316  snprintf(temps->c, sizeof(temps->c), "%3.1fC", (double )(lRaw / 1000.0));
317  snprintf(temps->f, sizeof(temps->f), "%3.1fF", (double )(lRaw / 1000.0 * 9 / 5 + 32));
318  temps->raw = lRaw;
319  strncpy(temps->cbName, "CpuTemps", sizeof(temps->cbName) - 1);
320  }
321 
322  return lRaw;
323 }
char c[SZ_CHAR_LABEL]
#define SD_WARNING
char f[SZ_CHAR_LABEL]
char cbName[SZ_CHAR_LABEL]

+ Here is the caller graph for this function:

void skn_device_manager_backlight ( int  af_backlight,
int  state 
)

Definition at line 184 of file skn_rpi_helpers.c.

Referenced by skn_device_manager_init_i2c(), and skn_device_manager_LCD_shutdown().

184  {
185  digitalWrite(af_backlight, state);
186 }

+ Here is the caller graph for this function:

static PLCDDevice skn_device_manager_init_i2c ( PDisplayManager  pdm)
static

Definition at line 188 of file skn_rpi_helpers.c.

References _IICLCD::af_backlight, _IICLCD::af_base, _IICLCD::af_blue, _IICLCD::af_db0, _IICLCD::af_db1, _IICLCD::af_db2, _IICLCD::af_db3, _IICLCD::af_db4, _IICLCD::af_db5, _IICLCD::af_db6, _IICLCD::af_db7, _IICLCD::af_e, _IICLCD::af_green, _IICLCD::af_red, _IICLCD::af_rs, _IICLCD::af_rw, _DISPLAY_MANAGER::dsp_cols, _DISPLAY_MANAGER::dsp_rows, gd_pch_device_name, _IICLCD::i2c_address, _DISPLAY_MANAGER::lcd, _IICLCD::lcd_handle, _DISPLAY_MANAGER::lcd_handle, PLATFORM_ERROR, SD_ERR, _IICLCD::setup, and skn_device_manager_backlight().

Referenced by skn_device_manager_MCP23008(), skn_device_manager_MCP23017(), and skn_device_manager_PCF8574().

188  {
189  PLCDDevice plcd = (PLCDDevice)&pdm->lcd;
190 
191  // call the initializer
192  plcd->setup(plcd->af_base, plcd->i2c_address);
193 
194 // Control signals
195  pinMode(plcd->af_rw, OUTPUT);
196  digitalWrite(plcd->af_rw, LOW); // Not used with wiringPi - always in write mode
197 
198  // Backlight LEDs
199  if (strcmp(gd_pch_device_name, "mc7") == 0) {
200  pinMode(plcd->af_red, OUTPUT);
202  pinMode(plcd->af_green, OUTPUT);
204  pinMode(plcd->af_blue, OUTPUT);
206  } else {
207  pinMode(plcd->af_backlight, OUTPUT);
209  }
210 
211 
212 
213  // The other control pins are initialised with lcdInit ()
214  plcd->lcd_handle = pdm->lcd_handle = lcdInit(pdm->dsp_rows, pdm->dsp_cols, 4,
215  plcd->af_rs, plcd->af_e,
216  plcd->af_db4, plcd->af_db5, plcd->af_db6, plcd->af_db7,
217  plcd->af_db0, plcd->af_db1, plcd->af_db2, plcd->af_db3);
218 
219  if (pdm->lcd_handle == PLATFORM_ERROR) {
220  skn_logger(SD_ERR, "I2C Services failed to initialize. lcdInit(%d)", pdm->lcd_handle);
221  return NULL;
222  } else {
223  lcdClear(pdm->lcd_handle);
224  }
225 
226  return plcd;
227 }
#define PLATFORM_ERROR
Definition: cmdDC.c:63
void skn_device_manager_backlight(int af_backlight, int state)
int(* setup)(const int, const int)
#define SD_ERR
char * gd_pch_device_name
struct _IICLCD * PLCDDevice

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int skn_device_manager_LCD_setup ( PDisplayManager  pdm,
char *  device_name 
)

Definition at line 234 of file skn_rpi_helpers.c.

References _DISPLAY_MANAGER::lcd_handle, PLATFORM_ERROR, skn_device_manager_MCP23008(), skn_device_manager_MCP23017(), skn_device_manager_PCF8574(), and skn_device_manager_SerialPort().

Referenced by skn_display_manager_do_work().

234  {
235  PLCDDevice rc = NULL;
236 
237  /*
238  * Initial I2C Services */
239  wiringPiSetupSys();
240 
241  if (strcmp(device_name, "mcp") == 0) {
242  rc = skn_device_manager_MCP23008(pdm);
243  } else if (strcmp(device_name, "mc7") == 0) {
244  rc = skn_device_manager_MCP23017(pdm);
245  } else if (strcmp(device_name, "ser") == 0) {
247  } else { // PCF8574
248  rc = skn_device_manager_PCF8574(pdm);
249  }
250 
251  if (rc == NULL) {
252  return PLATFORM_ERROR;
253  } else {
254  return pdm->lcd_handle;
255  }
256 }
#define PLATFORM_ERROR
Definition: cmdDC.c:63
PLCDDevice skn_device_manager_SerialPort(PDisplayManager pdm)
PLCDDevice skn_device_manager_MCP23017(PDisplayManager pdm)
PLCDDevice skn_device_manager_PCF8574(PDisplayManager pdm)
PLCDDevice skn_device_manager_MCP23008(PDisplayManager pdm)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int skn_device_manager_LCD_shutdown ( PDisplayManager  pdm)

Definition at line 257 of file skn_rpi_helpers.c.

References _IICLCD::af_backlight, _IICLCD::af_blue, _IICLCD::af_green, _IICLCD::af_red, gd_pch_device_name, _DISPLAY_MANAGER::lcd, _DISPLAY_MANAGER::lcd_handle, and skn_device_manager_backlight().

Referenced by skn_display_manager_do_work().

257  {
258  if (strcmp("ser", gd_pch_device_name) == 0) {
259  char display_off[] = { 0xfe, 0x46 };
260  char cls[] = { 0xfe, 0x58 };
261 
262  write(pdm->lcd_handle, display_off, sizeof(display_off));
263  sleep(1);
264  write(pdm->lcd_handle, cls, sizeof(cls));
265 
266  serialClose(pdm->lcd_handle);
267  } else {
268  lcdClear(pdm->lcd_handle);
269  if (strcmp(gd_pch_device_name, "mc7") == 0) {
273  } else {
275  }
276  }
277  return EXIT_SUCCESS;
278 }
void skn_device_manager_backlight(int af_backlight, int state)
char * gd_pch_device_name

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

PLCDDevice skn_device_manager_MCP23008 ( PDisplayManager  pdm)

Definition at line 110 of file skn_rpi_helpers.c.

References _IICLCD::af_backlight, _IICLCD::af_base, _IICLCD::af_db4, _IICLCD::af_db5, _IICLCD::af_db6, _IICLCD::af_db7, _IICLCD::af_e, _IICLCD::af_rs, _IICLCD::af_rw, _IICLCD::cbName, gd_i_i2c_address, _IICLCD::i2c_address, _DISPLAY_MANAGER::lcd, SD_ERR, SD_NOTICE, _IICLCD::setup, skn_device_manager_init_i2c(), and SZ_CHAR_BUFF.

Referenced by skn_device_manager_LCD_setup().

110  {
111  PLCDDevice plcd = NULL;
112  int base = 0;
113 
114  if (pdm == NULL) {
115  skn_logger(SD_ERR, "DeviceManager failed to acquire needed resources. %d:%s", errno, strerror(errno));
116  return NULL;
117  }
118 
119  plcd = (PLCDDevice)&pdm->lcd;
120  strncpy(plcd->cbName, "LCDDevice#MCP23008", SZ_CHAR_BUFF-1);
121  if (gd_i_i2c_address != 0) {
123  } else {
124  plcd->i2c_address = 0x20;
125  }
126 
127  skn_logger(SD_NOTICE, "DeviceManager using device [%s](0x%02x)", plcd->cbName, plcd->i2c_address);
128 
129  base = plcd->af_base = 100;
130  plcd->af_backlight = base + 7;
131  plcd->af_e = base + 2;
132  plcd->af_rs = base + 1;
133  plcd->af_rw = base + 0;
134 
135  plcd->af_db4 = base + 3;
136  plcd->af_db5 = base + 4;
137  plcd->af_db6 = base + 5;
138  plcd->af_db7 = base + 6;
139 
140  plcd->setup = &mcp23008Setup; // mcp23008Setup(AF_BASE, 0x20);
141 
142  return skn_device_manager_init_i2c(pdm);
143 }
int(* setup)(const int, const int)
#define SZ_CHAR_BUFF
Definition: cmdDC.c:57
int gd_i_i2c_address
#define SD_ERR
char cbName[SZ_CHAR_BUFF]
#define SD_NOTICE
struct _IICLCD * PLCDDevice
static PLCDDevice skn_device_manager_init_i2c(PDisplayManager pdm)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

PLCDDevice skn_device_manager_MCP23017 ( PDisplayManager  pdm)

Definition at line 72 of file skn_rpi_helpers.c.

References _IICLCD::af_backlight, _IICLCD::af_base, _IICLCD::af_blue, _IICLCD::af_db4, _IICLCD::af_db5, _IICLCD::af_db6, _IICLCD::af_db7, _IICLCD::af_e, _IICLCD::af_green, _IICLCD::af_red, _IICLCD::af_rs, _IICLCD::af_rw, _IICLCD::cbName, gd_i_i2c_address, _IICLCD::i2c_address, _DISPLAY_MANAGER::lcd, SD_ERR, SD_NOTICE, _IICLCD::setup, skn_device_manager_init_i2c(), and SZ_CHAR_BUFF.

Referenced by skn_device_manager_LCD_setup().

72  {
73  PLCDDevice plcd = NULL;
74  int base = 0;
75 
76  if (pdm == NULL) {
77  skn_logger(SD_ERR, "DeviceManager failed to acquire needed resources. %d:%s", errno, strerror(errno));
78  return NULL;
79  }
80 
81  plcd = (PLCDDevice)&pdm->lcd;
82  strncpy(plcd->cbName, "LCDDevice#MCP23017", SZ_CHAR_BUFF-1);
83  if (gd_i_i2c_address != 0) {
85  } else {
86  plcd->i2c_address = 0x20;
87  }
88 
89  skn_logger(SD_NOTICE, "DeviceManager using device [%s](0x%02x)", plcd->cbName, plcd->i2c_address);
90 
91  base = plcd->af_base = 100;
92  plcd->af_backlight = base + 8;
93  plcd->af_red = base + 6;
94  plcd->af_green = base + 7;
95  plcd->af_blue = base + 8;
96 
97  plcd->af_e = base + 13;
98  plcd->af_rs = base + 15;
99  plcd->af_rw = base + 14;
100 
101  plcd->af_db4 = base + 12;
102  plcd->af_db5 = base + 11;
103  plcd->af_db6 = base + 10;
104  plcd->af_db7 = base + 9;
105 
106  plcd->setup = &mcp23017Setup; // mcp23017Setup(AF_BASE, 0x20);
107 
108  return skn_device_manager_init_i2c(pdm);
109 }
int(* setup)(const int, const int)
#define SZ_CHAR_BUFF
Definition: cmdDC.c:57
int gd_i_i2c_address
#define SD_ERR
char cbName[SZ_CHAR_BUFF]
#define SD_NOTICE
struct _IICLCD * PLCDDevice
static PLCDDevice skn_device_manager_init_i2c(PDisplayManager pdm)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

PLCDDevice skn_device_manager_PCF8574 ( PDisplayManager  pdm)

Definition at line 145 of file skn_rpi_helpers.c.

References _IICLCD::af_backlight, _IICLCD::af_base, _IICLCD::af_db4, _IICLCD::af_db5, _IICLCD::af_db6, _IICLCD::af_db7, _IICLCD::af_e, _IICLCD::af_rs, _IICLCD::af_rw, _IICLCD::cbName, gd_i_i2c_address, _IICLCD::i2c_address, _DISPLAY_MANAGER::lcd, SD_ERR, SD_NOTICE, _IICLCD::setup, skn_device_manager_init_i2c(), and SZ_CHAR_BUFF.

Referenced by skn_device_manager_LCD_setup().

145  {
146  PLCDDevice plcd = NULL;
147  int base = 0;
148 
149  if (pdm == NULL) {
150  skn_logger(SD_ERR, "DeviceManager failed to acquire needed resources. %d:%s", errno, strerror(errno));
151  return NULL;
152  }
153 
154  plcd = (PLCDDevice)&pdm->lcd;
155  memset(plcd, 0, sizeof(LCDDevice));
156  strncpy(plcd->cbName, "LCDDevice#PCF8574", SZ_CHAR_BUFF-1);
157  if (gd_i_i2c_address != 0) {
159  } else {
160  plcd->i2c_address = 0x27;
161  }
162 
163  skn_logger(SD_NOTICE, "DeviceManager using device [%s](0x%02x)", plcd->cbName, plcd->i2c_address);
164 
165  base = plcd->af_base = 100;
166  plcd->af_backlight = base + 3;
167  plcd->af_e = base + 2;
168  plcd->af_rs = base + 0;
169  plcd->af_rw = base + 1;
170 
171  plcd->af_db4 = base + 4;
172  plcd->af_db5 = base + 5;
173  plcd->af_db6 = base + 6;
174  plcd->af_db7 = base + 7;
175 
176 
177  plcd->setup = &pcf8574Setup; // pcf8574Setup(AF_BASE, 0x27);
178 
179  return skn_device_manager_init_i2c(pdm);
180 }
int(* setup)(const int, const int)
#define SZ_CHAR_BUFF
Definition: cmdDC.c:57
int gd_i_i2c_address
#define SD_ERR
char cbName[SZ_CHAR_BUFF]
#define SD_NOTICE
struct _IICLCD * PLCDDevice
static PLCDDevice skn_device_manager_init_i2c(PDisplayManager pdm)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

PLCDDevice skn_device_manager_SerialPort ( PDisplayManager  pdm)

Definition at line 26 of file skn_rpi_helpers.c.

References _IICLCD::cbName, _IICLCD::ch_serial_port_name, gd_pch_serial_port, _DISPLAY_MANAGER::lcd, _IICLCD::lcd_handle, _DISPLAY_MANAGER::lcd_handle, PLATFORM_ERROR, SD_ERR, SD_NOTICE, and SZ_CHAR_BUFF.

Referenced by skn_device_manager_LCD_setup().

26  {
27  PLCDDevice plcd = NULL;
28 
29  if (pdm == NULL) {
30  skn_logger(SD_ERR, "DeviceManager failed to acquire needed resources. %d:%s", errno, strerror(errno));
31  return NULL;
32  }
33 
34  plcd = (PLCDDevice)&pdm->lcd;
35  strncpy(plcd->cbName, "LCDDevice#SerialPort", SZ_CHAR_BUFF-1);
36  if (gd_pch_serial_port != NULL) {
38  } else {
39  strncpy(plcd->ch_serial_port_name, "/dev/ttyACM0", SZ_CHAR_BUFF-1);
40  }
41 
42  skn_logger(SD_NOTICE, "DeviceManager using device [%s](%s)", plcd->cbName, gd_pch_serial_port);
43 
44  pdm->lcd_handle = plcd->lcd_handle = serialOpen (plcd->ch_serial_port_name, 9600);
45  if (plcd->lcd_handle == PLATFORM_ERROR) {
46  skn_logger(SD_ERR, "DeviceManager failed to acquire needed resources: SerialPort=%s %d:%s",
47  plcd->ch_serial_port_name, errno, strerror(errno));
48  return NULL;
49  }
50 
51  // set backlight & clear screen
52  char display_on[] = { 0xfe, 0x42 };
53  char cls[] = { 0xfe, 0x58 };
54  char home[] = { 0xfe, 0x48 };
55 // char set_cols_rows[] = {0xfe, 0xd1, gd_i_cols, gd_i_rows };
56  char set_contrast[] = {0xfe, 0x50, 0xdc};
57  char cursor_off[] = {0xfe, 0x4B };
58 
59  write(pdm->lcd_handle, set_contrast, sizeof(set_contrast));
60  sleep(1);
61  write(pdm->lcd_handle, home, sizeof(home));
62  sleep(1);
63  write(pdm->lcd_handle, cursor_off, sizeof(cursor_off));
64  sleep(1);
65  write(pdm->lcd_handle, cls, sizeof(cls));
66  sleep(1);
67  write(pdm->lcd_handle, display_on, sizeof(display_on));
68  sleep(1);
69 
70  return plcd;
71 }
#define PLATFORM_ERROR
Definition: cmdDC.c:63
char ch_serial_port_name[SZ_CHAR_BUFF]
#define SZ_CHAR_BUFF
Definition: cmdDC.c:57
#define SD_ERR
char cbName[SZ_CHAR_BUFF]
#define SD_NOTICE
struct _IICLCD * PLCDDevice
char * gd_pch_serial_port

+ Here is the caller graph for this function:

PDisplayLine skn_display_manager_add_line ( PDisplayManager  pdmx,
char *  client_request_message 
)

Definition at line 483 of file skn_rpi_helpers.c.

References _DISPLAY_LINE::active, ARY_MAX_DM_LINES, _DISPLAY_LINE::ch_display_msg, _DISPLAY_MANAGER::current_line, _DISPLAY_LINE::display_pos, gd_i_cols, _DISPLAY_LINE::msg_len, _DISPLAY_MANAGER::next_line, _DISPLAY_MANAGER::pdsp_collection, _DISPLAY_LINE::scroll_enabled, SD_DEBUG, skn_get_display_manager_ref(), skn_scroller_wrap_blanks(), and SZ_INFO_BUFF.

Referenced by skn_display_manager_do_work(), and skn_display_manager_message_consumer_thread().

483  {
484  PDisplayLine pdl = NULL;
485  PDisplayManager pdm = NULL;
486 
487  pdm = ((pdmx == NULL) ? skn_get_display_manager_ref() : pdmx);
488  if (pdm == NULL || client_request_message == NULL) {
489  return NULL;
490  }
491 
492  /*
493  * manage next index */
494  pdl = pdm->pdsp_collection[pdm->next_line++]; // manage next index
495  if (pdm->next_line == ARY_MAX_DM_LINES) {
496  pdm->next_line = 0; // roll it
497  }
498 
499  /*
500  * load new message */
501  strncpy(pdl->ch_display_msg, client_request_message, (SZ_INFO_BUFF-1));
502  pdl->ch_display_msg[SZ_INFO_BUFF - 1] = 0; // terminate string in case
503  pdl->msg_len = strlen(pdl->ch_display_msg);
504  pdl->active = 1;
505  pdl->display_pos = 0;
506  if (pdl->msg_len > gd_i_cols) {
507  pdl->scroll_enabled = 1;
509  pdl->ch_display_msg[(SZ_INFO_BUFF - 1)] = 0; // terminate string in case
510  pdl->msg_len = strlen(pdl->ch_display_msg);
511  } else {
512  pdl->scroll_enabled = 0;
513  }
514 
515  /*
516  * manage current_line */
517  pdm->pdsp_collection[pdm->current_line]->active = 0;
518  pdm->pdsp_collection[pdm->current_line++]->msg_len = 0;
519  if (pdm->current_line == ARY_MAX_DM_LINES) {
520  pdm->current_line = 0;
521  }
522 
523  skn_logger(SD_DEBUG, "DM Added msg=%d:%d:[%s]", ((pdm->next_line - 1) < 0 ? 0 : (pdm->next_line - 1)), pdl->msg_len, pdl->ch_display_msg);
524 
525  /* return this line's pointer */
526  return pdl;
527 }
#define SD_DEBUG
char * skn_scroller_wrap_blanks(char *buffer)
int gd_i_cols
PDisplayLine pdsp_collection[ARY_MAX_DM_LINES]
#define SZ_INFO_BUFF
Definition: cmdDC.c:56
#define ARY_MAX_DM_LINES
char ch_display_msg[SZ_INFO_BUFF]
PDisplayManager skn_get_display_manager_ref()

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static PDisplayManager skn_display_manager_create ( char *  welcome)
static

skn_display_manager_select_set

  • adds newest to top of double-linked-list
  • only keeps 8 in collections
  • reuses in top down fashion

Definition at line 439 of file skn_rpi_helpers.c.

References _DISPLAY_LINE::active, ARY_MAX_DM_LINES, _DISPLAY_LINE::cbName, _DISPLAY_MANAGER::cbName, _DISPLAY_LINE::ch_display_msg, _DISPLAY_MANAGER::ch_welcome_msg, _DISPLAY_MANAGER::current_line, _DISPLAY_MANAGER::dsp_cols, _DISPLAY_MANAGER::dsp_rows, gd_i_cols, gd_i_rows, _DISPLAY_LINE::msg_len, _DISPLAY_MANAGER::msg_len, _DISPLAY_LINE::next, _DISPLAY_MANAGER::next_line, _DISPLAY_MANAGER::pdsp_collection, _DISPLAY_LINE::prev, _DISPLAY_LINE::scroll_enabled, SD_ERR, skn_scroller_wrap_blanks(), and SZ_INFO_BUFF.

Referenced by skn_display_manager_do_work().

439  {
440  int index = 0, next = 0, prev = 0;
441  PDisplayManager pdm = NULL;
442  PDisplayLine pdl = NULL;
443 
444  pdm = (PDisplayManager) malloc(sizeof(DisplayManager));
445  if (pdm == NULL) {
446  skn_logger(SD_ERR, "Display Manager cannot acquire needed resources. %d:%s", errno, strerror(errno));
447  return NULL;
448  }
449 
450  memset(pdm, 0, sizeof(DisplayManager));
451  strcpy(pdm->cbName, "PDisplayManager");
452  memmove(pdm->ch_welcome_msg, welcome, SZ_INFO_BUFF-1);
453  pdm->msg_len = strlen(welcome);
454 
455  pdm->dsp_cols = gd_i_cols;
456  pdm->dsp_rows = gd_i_rows;
457  pdm->current_line = 0;
458  pdm->next_line = gd_i_rows;
459 
460  for (index = 0; index < ARY_MAX_DM_LINES; index++) {
461  pdl = pdm->pdsp_collection[index] = (PDisplayLine) malloc(sizeof(DisplayLine)); // line x
462  memset(pdl, 0, sizeof(DisplayLine));
463  strcpy(pdl->cbName, "PDisplayLine");
464  strncpy(pdl->ch_display_msg, welcome, (SZ_INFO_BUFF -1)); // load all with welcome message
465  pdl->ch_display_msg[(SZ_INFO_BUFF - 1)] = 0; // terminate string in case
466  pdl->msg_len = pdm->msg_len;
467  pdl->active = 1;
468  if (pdl->msg_len > gd_i_cols) {
469  pdl->scroll_enabled = 1;
471  pdl->ch_display_msg[(SZ_INFO_BUFF - 1)] = 0; // terminate string in case
472  pdl->msg_len = strlen(pdl->ch_display_msg);
473  }
474  }
475  for (index = 0; index < ARY_MAX_DM_LINES; index++) { // enable link list routing
476  next = (((index + 1) == ARY_MAX_DM_LINES) ? 0 : (index + 1));
477  prev = (((index - 1) == -1) ? (ARY_MAX_DM_LINES - 1) : (index - 1));
478  pdm->pdsp_collection[index]->next = pdm->pdsp_collection[next];
479  pdm->pdsp_collection[index]->prev = pdm->pdsp_collection[prev];
480  }
481  return pdm;
482 }
int gd_i_rows
char * skn_scroller_wrap_blanks(char *buffer)
int gd_i_cols
PDisplayLine pdsp_collection[ARY_MAX_DM_LINES]
#define SD_ERR
#define SZ_INFO_BUFF
Definition: cmdDC.c:56
#define ARY_MAX_DM_LINES
struct _DISPLAY_LINE * PDisplayLine
char ch_display_msg[SZ_INFO_BUFF]
char cbName[SZ_CHAR_BUFF]
struct _DISPLAY_MANAGER * PDisplayManager
char ch_welcome_msg[SZ_INFO_BUFF]
char cbName[SZ_CHAR_BUFF]

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void skn_display_manager_destroy ( PDisplayManager  pdm)
static

Definition at line 611 of file skn_rpi_helpers.c.

References ARY_MAX_DM_LINES, and _DISPLAY_MANAGER::pdsp_collection.

Referenced by skn_display_manager_do_work().

611  {
612  int index = 0;
613 
614  // free collection
615  for (index = 0; index < ARY_MAX_DM_LINES; index++) {
616  if (pdm->pdsp_collection[index] != NULL) {
617  free(pdm->pdsp_collection[index]);
618  }
619  }
620  // free manager
621  if (pdm != NULL)
622  free(pdm);
623 }
PDisplayLine pdsp_collection[ARY_MAX_DM_LINES]
#define ARY_MAX_DM_LINES

+ Here is the caller graph for this function:

int skn_display_manager_do_work ( char *  client_request_message)

Definition at line 531 of file skn_rpi_helpers.c.

References _DISPLAY_LINE::active, _DISPLAY_MANAGER::current_line, _DISPLAY_MANAGER::dsp_rows, gd_pch_device_name, generate_datetime_info(), generate_loadavg_info(), generate_rpi_model_info(), generate_uname_info(), gi_exit_flag, _DISPLAY_MANAGER::lcd_handle, _DISPLAY_LINE::next, _DISPLAY_MANAGER::pdsp_collection, PLATFORM_ERROR, SD_ERR, SD_NOTICE, skn_device_manager_LCD_setup(), skn_device_manager_LCD_shutdown(), skn_display_manager_add_line(), skn_display_manager_create(), skn_display_manager_destroy(), skn_display_manager_message_consumer_shutdown(), skn_display_manager_message_consumer_startup(), SKN_RUN_MODE_RUN, SKN_RUN_MODE_STOP, skn_scroller_scroll_lines(), skn_time_delay(), and SZ_INFO_BUFF.

Referenced by main().

531  {
532  int index = 0, dsp_line_number = 0;
533  PDisplayManager pdm = NULL;
534  PDisplayLine pdl = NULL;
535  char ch_lcd_message[4][SZ_INFO_BUFF];
536  long host_update_cycle = 0;
537 
538  gp_structure_pdm = pdm = skn_display_manager_create(client_request_message);
539  if (pdm == NULL) {
541  skn_logger(SD_ERR, "Display Manager cannot acquire needed resources. DMCreate()");
542  return gi_exit_flag;
543  }
544  generate_datetime_info (ch_lcd_message[0]);
545  generate_rpi_model_info(ch_lcd_message[1]);
546 // generate_cpu_temps_info(ch_lcd_message[2]);
547  generate_uname_info (ch_lcd_message[2]);
548  generate_loadavg_info (ch_lcd_message[3]);
549  skn_display_manager_add_line(pdm, ch_lcd_message[0]);
550  skn_display_manager_add_line(pdm, ch_lcd_message[1]);
551  skn_display_manager_add_line(pdm, ch_lcd_message[2]);
552  skn_display_manager_add_line(pdm, ch_lcd_message[3]);
553 
556  skn_logger(SD_ERR, "Display Manager cannot acquire needed resources: lcdSetup().");
558  return gi_exit_flag;
559  }
560 
561  if (skn_display_manager_message_consumer_startup(pdm) == EXIT_FAILURE) {
563  skn_logger(SD_ERR, "Display Manager cannot acquire needed resources: Consumer().");
565  return gi_exit_flag;
566  }
567 
568  skn_logger(SD_NOTICE, "Application Active... ");
569 
570  /*
571  * Do the Work
572  */
573  while (gi_exit_flag == SKN_RUN_MODE_RUN) {
574  dsp_line_number = 0;
575  pdl = pdm->pdsp_collection[pdm->current_line];
576 
577  for (index = 0; index < pdm->dsp_rows; index++) {
578  if (pdl->active == 1) {
579  skn_scroller_scroll_lines(pdl, pdm->lcd_handle, dsp_line_number++);
580  skn_time_delay(0.18); // delay(180);
581  }
582  pdl = (PDisplayLine) pdl->next;
583  }
584 
585  if ((host_update_cycle++ % 900) == 0) { // roughly every fifteen minutes
586  generate_datetime_info (ch_lcd_message[0]);
587 // generate_cpu_temps_info(ch_lcd_message[2]);
588  generate_loadavg_info (ch_lcd_message[3]);
589  skn_display_manager_add_line(pdm, ch_lcd_message[0]);
590  skn_display_manager_add_line(pdm, ch_lcd_message[1]);
591  skn_display_manager_add_line(pdm, ch_lcd_message[2]);
592  skn_display_manager_add_line(pdm, ch_lcd_message[3]);
593  host_update_cycle = 1;
594  }
595  }
596 
598 
599  skn_logger(SD_NOTICE, "Application InActive...");
600 
601  /*
602  * Stop UDP Listener
603  */
605 
607  gp_structure_pdm = pdm = NULL;
608 
609  return gi_exit_flag;
610 }
static void skn_display_manager_destroy(PDisplayManager pdm)
#define PLATFORM_ERROR
Definition: cmdDC.c:63
int skn_time_delay(double delay_time)
#define SKN_RUN_MODE_STOP
PDisplayLine pdsp_collection[ARY_MAX_DM_LINES]
#define SD_ERR
int skn_display_manager_message_consumer_startup(PDisplayManager pdm)
static PDisplayManager skn_display_manager_create(char *welcome)
void skn_display_manager_message_consumer_shutdown(PDisplayManager pdm)
char * gd_pch_device_name
int skn_device_manager_LCD_setup(PDisplayManager pdm, char *device_name)
#define SZ_INFO_BUFF
Definition: cmdDC.c:56
int skn_scroller_scroll_lines(PDisplayLine pdl, int lcd_handle, int line)
int generate_uname_info(char *msg)
struct _DISPLAY_LINE * PDisplayLine
#define SKN_RUN_MODE_RUN
int skn_device_manager_LCD_shutdown(PDisplayManager pdm)
sig_atomic_t gi_exit_flag
#define SD_NOTICE
PDisplayManager gp_structure_pdm
int generate_rpi_model_info(char *msg)
int generate_datetime_info(char *msg)
int generate_loadavg_info(char *msg)
PDisplayLine skn_display_manager_add_line(PDisplayManager pdmx, char *client_request_message)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void skn_display_manager_message_consumer_shutdown ( PDisplayManager  pdm)

skn_display_manager_message_consumer(PDisplayManager pdm)

Definition at line 654 of file skn_rpi_helpers.c.

References _DISPLAY_MANAGER::dm_thread, _DISPLAY_MANAGER::i_socket, SD_NOTICE, SD_WARNING, and _DISPLAY_MANAGER::thread_complete.

Referenced by skn_display_manager_do_work().

654  {
655  void *trc = NULL;
656 
657  if (pdm->thread_complete != 0) {
658  skn_logger(SD_WARNING, "DisplayManager: Canceling thread.");
659  pthread_cancel(pdm->dm_thread);
660  sleep(1);
661  } else {
662  skn_logger(SD_WARNING, "DisplayManager: Thread was already stopped.");
663  }
664  pthread_join(pdm->dm_thread, &trc);
665  close(pdm->i_socket);
666  skn_logger(SD_NOTICE, "DisplayManager: Thread ended:(%ld)", (long int) trc);
667 }
#define SD_WARNING
#define SD_NOTICE

+ Here is the caller graph for this function:

int skn_display_manager_message_consumer_startup ( PDisplayManager  pdm)

skn_display_manager_message_consumer(PDisplayManager pdm)

  • returns Socket or EXIT_FAILURE

Definition at line 629 of file skn_rpi_helpers.c.

References _DISPLAY_MANAGER::dm_thread, _DISPLAY_MANAGER::i_socket, SD_EMERG, SD_NOTICE, SD_WARNING, skn_display_manager_message_consumer_thread(), SKN_RPI_DISPLAY_SERVICE_PORT, and skn_udp_host_create_regular_socket().

Referenced by skn_display_manager_do_work().

629  {
630  /*
631  * Start UDP Listener */
633  if (pdm->i_socket == EXIT_FAILURE) {
634  skn_logger(SD_EMERG, "DisplayManager: Host Init Failed!");
635  return EXIT_FAILURE;
636  }
637 
638  /*
639  * Create Thread */
640  int i_thread_rc = pthread_create(&pdm->dm_thread, NULL, skn_display_manager_message_consumer_thread, (void *) pdm);
641  if (i_thread_rc == -1) {
642  skn_logger(SD_WARNING, "DisplayManager: Create thread failed: %s", strerror(errno));
643  close(pdm->i_socket);
644  return EXIT_FAILURE;
645  }
646  sleep(1); // give thread a chance to start
647 
648  skn_logger(SD_NOTICE, "DisplayManager: Thread startup successful... ");
649 
650  return pdm->i_socket;
651 }
int skn_udp_host_create_regular_socket(int port, double rcvTimeout)
#define SD_WARNING
#define SD_EMERG
#define SKN_RPI_DISPLAY_SERVICE_PORT
static void * skn_display_manager_message_consumer_thread(void *ptr)
#define SD_NOTICE

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void * skn_display_manager_message_consumer_thread ( void *  ptr)
static

skn_display_manager_message_consumer_thread(PDisplayManager pdm)

Definition at line 673 of file skn_rpi_helpers.c.

References get_broadcast_ip_array(), gi_exit_flag, _DISPLAY_MANAGER::i_socket, SD_ERR, SD_NOTICE, skn_display_manager_add_line(), SKN_RPI_DISPLAY_SERVICE_PORT, SKN_RUN_MODE_RUN, SKN_RUN_MODE_STOP, skn_time_delay(), SZ_INFO_BUFF, and _DISPLAY_MANAGER::thread_complete.

Referenced by skn_display_manager_message_consumer_startup().

673  {
674  PDisplayManager pdm = (PDisplayManager) ptr;
675  struct sockaddr_in remaddr; /* remote address */
676  socklen_t addrlen = sizeof(remaddr); /* length of addresses */
677  IPBroadcastArray aB;
678  char strPrefix[SZ_INFO_BUFF];
679  char request[SZ_INFO_BUFF];
680  char recvHostName[SZ_INFO_BUFF];
681  char *pch = NULL;
682  signed int rLen = 0, rc = 0;
683  long int exit_code = EXIT_SUCCESS;
684 
685  bzero(request, sizeof(request));
686  memset(recvHostName, 0, sizeof(recvHostName));
687 
688  rc = get_broadcast_ip_array(&aB);
689  if (rc == -1) {
690  exit_code = rc;
691  pthread_exit((void *) exit_code);
692  }
693 
694  pdm->thread_complete = 1;
695 
696  while (gi_exit_flag == SKN_RUN_MODE_RUN) {
697  memset(&remaddr, 0, sizeof(remaddr));
698  remaddr.sin_family = AF_INET;
699  remaddr.sin_port = htons(SKN_RPI_DISPLAY_SERVICE_PORT);
700  remaddr.sin_addr.s_addr = htonl(INADDR_ANY);
701  addrlen = sizeof(remaddr);
702 // V- MSG_DONTWAIT or O_NONBLOCK flag with the F_SETFL fcntl(2)
703  if ((rLen = recvfrom(pdm->i_socket, request, sizeof(request) - 1, 0, (struct sockaddr *) &remaddr, &addrlen)) < 0) {
704  if (errno == EAGAIN || errno == EWOULDBLOCK) {
705  continue;
706  }
707  skn_logger(SD_ERR, "DisplayManager: RcvFrom() Failure code=%d, etext=%s", errno, strerror(errno));
708  exit_code = errno;
709  break;
710  }
711  request[rLen] = 0;
712 
713  rc = getnameinfo(((struct sockaddr *) &remaddr), sizeof(struct sockaddr_in), recvHostName, sizeof(recvHostName) - 1, NULL, 0, NI_DGRAM);
714  if (rc != 0) {
715  skn_logger(SD_ERR, "GetNameInfo() Failure code=%d, etext=%s", errno, strerror(errno));
716  exit_code = errno;
717  break;
718  }
719  skn_logger(SD_NOTICE, "Received request from %s @ %s:%d", recvHostName, inet_ntoa(remaddr.sin_addr), ntohs(remaddr.sin_port));
720 
721  /*
722  * Add receive data to display set */
723  pch = strtok(recvHostName, ".");
724  snprintf(strPrefix, sizeof(strPrefix) -1 , "%s|%s", pch, request);
725  skn_display_manager_add_line(pdm, strPrefix);
726 
727  if (sendto(pdm->i_socket, "200 Accepted", strlen("200 Accepted"), 0, (struct sockaddr *) &remaddr, addrlen) < 0) {
728  skn_logger(SD_ERR, "SendTo() Failure code=%d, etext=%s", errno, strerror(errno));
729  exit_code = errno;
730  break;
731  }
732 
733  /*
734  * Shutdown by command */
735  if (strcmp("QUIT!", request) == 0) {
736  exit_code = 0;
737  gi_exit_flag = SKN_RUN_MODE_STOP; // shutdown
738  skn_logger(SD_NOTICE, "COMMAND: Shutdown Requested! exit code=%d", exit_code);
739  break;
740  }
741 
742  }
743  gi_exit_flag = SKN_RUN_MODE_STOP; // shutdown
744 // kill(getpid(), SIGUSR1); // cause a shutdown
745  skn_time_delay(0.5);
746 
747  skn_logger(SD_NOTICE, "Display Manager Thread: shutdown complete: (%ld)", exit_code);
748 
749  pdm->thread_complete = 0;
750 
751  pthread_exit((void *) exit_code);
752 
753 }
int skn_time_delay(double delay_time)
#define SKN_RUN_MODE_STOP
#define SD_ERR
#define SZ_INFO_BUFF
Definition: cmdDC.c:56
#define SKN_RPI_DISPLAY_SERVICE_PORT
#define SKN_RUN_MODE_RUN
sig_atomic_t gi_exit_flag
struct _DISPLAY_MANAGER * PDisplayManager
#define SD_NOTICE
int get_broadcast_ip_array(PIPBroadcastArray paB)
PDisplayLine skn_display_manager_add_line(PDisplayManager pdmx, char *client_request_message)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void skn_display_print_usage ( )
static

Definition at line 764 of file skn_rpi_helpers.c.

References gd_ch_program_desc, and gd_ch_program_name.

Referenced by skn_handle_display_command_line().

764  {
765  skn_logger(" ", "%s -- %s", gd_ch_program_name, gd_ch_program_desc);
766  skn_logger(" ", "\tSkoona Development <skoona@gmail.com>");
767  skn_logger(" ", "Usage:\n %s [-v] [-m 'Welcome Message'] [-r 4|2] [-c 20|16] [-i 39|32] [-t pcf|mcp|mc7|ser] [-p string] [-h|--help]", gd_ch_program_name);
768  skn_logger(" ", "\nOptions:");
769  skn_logger(" ", " -r, --rows=dd\t\tNumber of rows in physical display.");
770  skn_logger(" ", " -c, --cols=dd\t\tNumber of columns in physical display.");
771  skn_logger(" ", " -m, --message\tWelcome Message for line 1.");
772  skn_logger(" ", " -p, --serial-port=string\tSerial port. | ['/dev/ttyACM0']");
773  skn_logger(" ", " -i, --i2c-address=ddd\tI2C decimal address. | [0x27=39, 0x20=32]");
774  skn_logger(" ", " -t, --i2c-chipset=pcf\tI2C Chipset. | [pcf|mc7|mcp|ser]");
775  skn_logger(" ", " -v, --version\tVersion printout.");
776  skn_logger(" ", " -h, --help\t\tShow this help screen.");
777 }
char gd_ch_program_desc[SZ_INFO_BUFF]
char gd_ch_program_name[SZ_INFO_BUFF]

+ Here is the caller graph for this function:

PDisplayManager skn_get_display_manager_ref ( )

Definition at line 528 of file skn_rpi_helpers.c.

References gp_structure_pdm.

Referenced by skn_display_manager_add_line().

528  {
529  return gp_structure_pdm;
530 }
PDisplayManager gp_structure_pdm

+ Here is the caller graph for this function:

int skn_handle_display_command_line ( int  argc,
char **  argv 
)

Definition at line 785 of file skn_rpi_helpers.c.

References gd_ch_program_name, gd_i_cols, gd_i_debug, gd_i_i2c_address, gd_i_rows, gd_pch_device_name, gd_pch_message, gd_pch_serial_port, PACKAGE_VERSION, SD_ERR, SD_WARNING, and skn_display_print_usage().

Referenced by main().

785  {
786  int opt = 0;
787  int longindex = 0;
788  struct option longopts[] = {
789  { "debug", 1, NULL, 'd' }, /* required param if */
790  { "rows", 1, NULL, 'r' }, /* required param if */
791  { "cols", 1, NULL, 'c' }, /* required param if */
792  { "message", 1, NULL, 'm' }, /* required param if */
793  { "i2c-address", 1, NULL, 'i' }, /* required param if */
794  { "12c-chipset", 1, NULL, 't' }, /* required param if */
795  { "serial-port", 1, NULL, 'p' }, /* required param if */
796  { "version", 0, NULL, 'v' }, /* set true if present */
797  { "help", 0, NULL, 'h' }, /* set true if present */
798  { 0, 0, 0, 0 } };
799 
800  /*
801  * Get commandline options
802  * longindex is the current index into longopts
803  * optind is current/last index into argv
804  * optarg is value attached(-d88) or next element(-d 88) of argv
805  * opterr flags a scanning error
806  */
807  while ((opt = getopt_long(argc, argv, "d:m:r:c:i:t:p:vh", longopts, &longindex)) != -1) {
808  switch (opt) {
809  case 'd':
810  if (optarg) {
811  gd_i_debug = atoi(optarg);
812  } else {
813  skn_logger(SD_ERR, "%s: input param was invalid! %c[%d:%d:%d]\n", gd_ch_program_name, (char) opt, longindex, optind,
814  opterr);
815  return (EXIT_FAILURE);
816  }
817  break;
818  case 'r':
819  if (optarg) {
820  gd_i_rows = atoi(optarg);
821  switch (gd_i_rows) {
822  case 2:
823  case 4:
824  break;
825  default:
826  gd_i_rows = 4;
827  skn_logger(SD_WARNING, "%s: input param was invalid! (default of 4 used) %c[%d:%d:%d]\n", gd_ch_program_name,
828  (char) opt, longindex, optind, opterr);
829 
830  }
831  } else {
832  skn_logger(SD_ERR, "%s: input param was invalid! %c[%d:%d:%d]\n", gd_ch_program_name, (char) opt, longindex, optind,
833  opterr);
834  return (EXIT_FAILURE);
835  }
836  break;
837  case 'c':
838  if (optarg) {
839  gd_i_cols = atoi(optarg);
840  switch (gd_i_cols) {
841  case 16:
842  case 20:
843  break;
844  default:
845  gd_i_cols = 20;
846  skn_logger(SD_WARNING, "%s: input param was invalid! (default of 20 used) %c[%d:%d:%d]\n", gd_ch_program_name,
847  (char) opt, longindex, optind, opterr);
848 
849  }
850  } else {
851  skn_logger(SD_ERR, "%s: input param was invalid! %c[%d:%d:%d]\n", gd_ch_program_name, (char) opt, longindex, optind,
852  opterr);
853  return (EXIT_FAILURE);
854  }
855  break;
856  case 'm':
857  if (optarg) {
858  gd_pch_message = strdup(optarg);
859  } else {
860  skn_logger(SD_ERR, "%s: input param was invalid! %c[%d:%d:%d]\n", gd_ch_program_name, (char) opt, longindex, optind,
861  opterr);
862  return (EXIT_FAILURE);
863  }
864  break;
865  case 'i':
866  if (optarg) {
867  gd_i_i2c_address = atoi(optarg);
868  } else {
869  skn_logger(SD_ERR, "%s: input param was invalid! %c[%d:%d:%d]\n", gd_ch_program_name, (char) opt, longindex, optind,
870  opterr);
871  return (EXIT_FAILURE);
872  }
873  break;
874  case 't':
875  if (optarg) {
876  gd_pch_device_name = strdup(optarg);
877  if ( (strcmp(gd_pch_device_name, "mcp") != 0) &&
878  (strcmp(gd_pch_device_name, "mc7") != 0) &&
879  (strcmp(gd_pch_device_name, "pcf") != 0) &&
880  (strcmp(gd_pch_device_name, "ser") != 0)) {
881  skn_logger(SD_ERR, "%s: unsupported option was invalid! %c[%d:%d:%d] %s\n", gd_ch_program_name, (char) opt, longindex, optind, opterr, gd_pch_device_name);
882  return EXIT_FAILURE;
883  }
884  } else {
885  skn_logger(SD_ERR, "%s: input param was invalid! %c[%d:%d:%d]\n", gd_ch_program_name, (char) opt, longindex, optind,
886  opterr);
887  return (EXIT_FAILURE);
888  }
889  break;
890  case 'p':
891  if (optarg) {
892  gd_pch_serial_port = strdup(optarg);
893  if (strlen(gd_pch_serial_port) < 5) {
894  skn_logger(SD_ERR, "%s: input param was invalid! %c[%d:%d:%d]\n", gd_ch_program_name, (char) opt, longindex, optind, opterr);
895  return EXIT_FAILURE;
896  }
897  } else {
898  skn_logger(SD_ERR, "%s: input param was invalid! %c[%d:%d:%d]\n", gd_ch_program_name, (char) opt, longindex, optind, opterr);
899  return (EXIT_FAILURE);
900  }
901  break;
902  case 'v':
903  skn_logger(SD_ERR, "\n\tProgram => %s\n\tVersion => %s\n\tSkoona Development\n\t<skoona@gmail.com>\n", gd_ch_program_name,
905  return (EXIT_FAILURE);
906  break;
907  case '?':
908  skn_logger(SD_ERR, "%s: unknown input param! %c[%d:%d:%d]\n", gd_ch_program_name, (char) opt, longindex, optind, opterr);
910  return (EXIT_FAILURE);
911  break;
912  default: /* help and default */
914  return (EXIT_FAILURE);
915  break;
916  }
917  }
918 
919  return EXIT_SUCCESS;
920 }
int gd_i_rows
char * gd_pch_message
int gd_i_i2c_address
int gd_i_cols
#define SD_ERR
#define SD_WARNING
char * gd_pch_device_name
char gd_ch_program_name[SZ_INFO_BUFF]
signed int gd_i_debug
char * gd_pch_serial_port
#define PACKAGE_VERSION
Definition: cmdDC.c:19
static void skn_display_print_usage()

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

char* skn_scroller_pad_right ( char *  buffer)

skn_scroller_pad_right

  • fills remaining with spaces and 0 terminates
  • buffer message to adjust

Definition at line 367 of file skn_rpi_helpers.c.

References gd_i_cols.

Referenced by skn_scroller_scroll_lines().

367  {
368  int hIndex = 0;
369 
370  for (hIndex = strlen(buffer); hIndex < gd_i_cols; hIndex++) {
371  buffer[hIndex] = ' ';
372  }
373  buffer[gd_i_cols] = 0;
374 
375  return buffer;
376 }
int gd_i_cols

+ Here is the caller graph for this function:

int skn_scroller_scroll_lines ( PDisplayLine  pdl,
int  lcd_handle,
int  line 
)

Scrolls a single line across the lcd display

  • best when wrapped in column chars on each side

Definition at line 402 of file skn_rpi_helpers.c.

References _DISPLAY_LINE::ch_display_msg, _DISPLAY_LINE::display_pos, gd_i_cols, gd_pch_device_name, _DISPLAY_LINE::msg_len, skn_scroller_pad_right(), and skn_time_delay().

Referenced by skn_display_manager_do_work().

403 {
404  char buf[40];
405  signed int hAdjust = 0, mLen = 0, mfLen = 0;
406  char set_col_row_position[] = {0xfe, 0x47, 0x01, 0x01};
407 
408  mLen = strlen(&(pdl->ch_display_msg[pdl->display_pos]));
409  if (gd_i_cols < mLen) {
410  mfLen = pdl->msg_len;
411  hAdjust = (mfLen - gd_i_cols);
412  }
413 
414  snprintf(buf, sizeof(buf) - 1, "%s", &(pdl->ch_display_msg[pdl->display_pos]));
416 
417  if (strcmp("ser", gd_pch_device_name) == 0 ) {
418  set_col_row_position[3] = (unsigned int)line + 1;
419  write(lcd_handle, set_col_row_position, sizeof(set_col_row_position));
420  skn_time_delay(0.2); // delay(200);
421  write(lcd_handle, buf, gd_i_cols - 1);
422  } else {
423  lcdPosition(lcd_handle, 0, line);
424  lcdPuts(lcd_handle, buf);
425  }
426  if (++pdl->display_pos > hAdjust) {
427  pdl->display_pos = 0;
428  }
429 
430  return pdl->display_pos;
431 }
int skn_time_delay(double delay_time)
int gd_i_cols
char * gd_pch_device_name
char * skn_scroller_pad_right(char *buffer)
char ch_display_msg[SZ_INFO_BUFF]

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

char* skn_scroller_wrap_blanks ( char *  buffer)

skn_scroller_wrap_blanks

  • builds str with 20 chars in front, and 20 at right end

Definition at line 382 of file skn_rpi_helpers.c.

References gd_i_cols, and SZ_INFO_BUFF.

Referenced by skn_display_manager_add_line(), and skn_display_manager_create().

382  {
383  char worker[SZ_INFO_BUFF];
384  char col_width_padding[16];
385 
386  if (buffer == NULL || strlen(buffer) > SZ_INFO_BUFF) {
387  return NULL;
388  }
389 
390  snprintf(col_width_padding, 16, "%%%ds%%s%%%ds", gd_i_cols, gd_i_cols);
391  snprintf(worker, (SZ_INFO_BUFF - 1), col_width_padding, " ", buffer, " ");
392  memmove(buffer, worker, SZ_INFO_BUFF-1);
393  buffer[SZ_INFO_BUFF - 1] = 0;
394 
395  return buffer;
396 }
int gd_i_cols
#define SZ_INFO_BUFF
Definition: cmdDC.c:56

+ Here is the caller graph for this function:

Variable Documentation

int gd_i_rows = 4
char* gd_pch_serial_port
PDisplayManager gp_structure_pdm = NULL

Definition at line 15 of file skn_rpi_helpers.c.

Referenced by skn_get_display_manager_ref().