I'm trying to control my WS2801 LED Stripe with my Raspberry Pi 4 over the SPI interface.
The Pi is running un Ubuntu 20.04 with the kernel version: Linux ubuntu 5.3.0-1030-raspi2 #32-Ubuntu SMP Sun Jul 12 21:20:28 UTC 2020 aarch64 aarch64 aarch64 GNU/Linux
The setup and connection to the LED Strip should be fine. I've validated it with a test script on my Pi3 and it worked properly. With the test script running on the PI there is no error, but nothing happens on the LED stripe.
So far, I have the understanding that in order to communicate over the SPI we need the spidev and the spi-bcm2835 module to be loaded.
Output of lsmod | grep spi:
spidev 28672 0
IMO, there should be spi_bcm2835 as well. In the /dev/ folder there is spidev0.0 and spidev0.1, as it should be. Calling sudo modprobe spi_bcm2835 gives no error but does not solve the issue.
My /boot/firmware/config.txt:
[pi4]
kernel=uboot_rpi_4.bin
max_framebuffers=2
[pi3]
kernel=uboot_rpi_3.bin
[all]
arm_64bit=1
device_tree_address=0x03000000
start_x=1
gpu_mem=512
dtparam=spi=on
dtparam=sound=on
dtparam=i2c_arm=on
dtparam=i2s=on
dtoverlay=spi-bcm2835
My /etc/modules:
i2c-dev
spi-bcm2835
spi-dev
snd-bcm2835
There is no blacklist entry with respect to the spi inside the /etc/modeprob.d/ files.
The only related entry in dmesg is [ 1.559971] spi-bcm2835 fe204000.spi: could not get clk: -517. But as far as I know -517 means that the module is just loaded later because it's not ready at this timestep.
Does anybody know what the issue might be here?
Thanks!
This is my test_script:
/******************************************************************************/
/* */
/* FILE: ledstrip.cpp */
/* */
/* Displays the contents of a file on a LED strip */
/* ============================================== */
/* */
/* V0.01 18-DEC-2015 Te */
/* */
/******************************************************************************/
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
static const char *device = "/dev/spidev0.0" ;
static uint32_t speed = 500000 ;
static uint8_t mode = SPI_MODE_0 ;
static uint8_t bits = 8 ;
static unsigned char tx[75] ;
static unsigned char rx[75] ;
static struct spi_ioc_transfer parameters[1];
static int offset = 0 ;
static int spi ;
/*************/
int OpenSPI()
/*************/
{
spi = open( device, O_RDWR ) ;
if( spi < 0 )
{
fprintf( stderr, "can't open device\n" ) ;
return 1 ;
}
int ret = ioctl( spi, SPI_IOC_WR_MODE, &mode ) ;
if( ret == -1 )
{
close( spi ) ;
fprintf( stderr, "can't set mode\n" ) ;
return 2 ;
}
ret = ioctl( spi, SPI_IOC_WR_BITS_PER_WORD, &bits ) ;
if( ret == -1 )
{
close( spi ) ;
fprintf( stderr, "can't set bits\n" ) ;
return 3 ;
}
ret = ioctl( spi, SPI_IOC_WR_MAX_SPEED_HZ, &speed ) ;
if( ret == -1 )
{
close( spi ) ;
fprintf( stderr, "can't set speed\n" ) ;
return 4 ;
}
memset( ¶meters, 0, sizeof(spi) ) ;
parameters[0].tx_buf = (unsigned long)tx ;
parameters[0].rx_buf = (unsigned long)rx ;
parameters[0].len = 75 ;
parameters[0].delay_usecs = 0 ;
parameters[0].speed_hz = speed ;
parameters[0].bits_per_word = bits ;
parameters[0].cs_change = 0 ;
return 0 ;
}
/***************/
void CloseSPI()
/***************/
{
close( spi ) ;
}
/*****************/
void ResetState()
/*****************/
{
memset( tx, 0, sizeof(tx) ) ;
}
/****************/
void ShowState()
/****************/
{
if( ioctl(spi,SPI_IOC_MESSAGE(1),¶meters) == -1 )
fprintf( stderr, "can't transfer data\n" ) ;
}
/*******************************/
void Token( const char *token )
/*******************************/
{
if( isdigit(*token) )
{
int value = atoi( token ) - 1 ;
if( (value >= 0) && (value <= 24) )
tx[value*3+offset] = 255 ;
}
else
{
switch( tolower(*token) )
{
case 'r' : offset = 0 ;
break ;
case 'g' : offset = 1 ;
break ;
case 'b' : offset = 2 ;
break ;
}
}
}
/***************************/
void Line( const char *ps )
/***************************/
{
ResetState() ;
char token[25] ;
size_t i = 0 ;
while( *ps != '\0' )
{
if( isspace(*ps) )
{
if( i > 0 )
{
token[i] = '\0' ;
Token( token ) ;
}
i = 0 ;
}
else
{
if( i < sizeof(token) - 1 )
token[i++] = *ps ;
}
++ps ;
}
ShowState() ;
}
/***************************/
void ReadFile( FILE *file )
/***************************/
{
char line[1024] ;
struct timespec in ;
struct timespec out ;
while( fgets(line,sizeof(line),file) != NULL )
{
Line( line ) ;
in.tv_sec = 0 ;
in.tv_nsec = 125000000 ;
nanosleep( &in, &out ) ;
}
}
/*********************************/
void File( const char *filename )
/*********************************/
{
FILE *file = fopen( filename, "r" ) ;
if( file != NULL )
{
ReadFile( file ) ;
fclose( file ) ;
}
}
/**********************************/
int main( int argc, char *argv[] )
/**********************************/
{
if( OpenSPI() != 0 )
return 1 ;
if( argc == 1 )
ReadFile( stdin ) ;
else
{
for( int i = 1; i < argc; i++ )
File( argv[i] ) ;
}
CloseSPI() ;
return 0 ;
}
I had a similar problem. This answer has helped me.
Change usercfg.txt instead of config.txt.
Related
I am using a Linux system, not a Windows system. I've posted some code, below. Please bear in mind that this code was never intended to be "production quality."
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <netdb.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 9909
void die ( const char *fmt, ... )
{
va_list vargs;
va_start( vargs, fmt );
vfprintf( stderr, fmt, vargs );
va_end( vargs );
exit( 1 );
}
int main ( int argc, char **argv )
{
/* *** */
int listener = socket( PF_INET, SOCK_STREAM, 0 );
if( listener < 0 ) die( "socket(listener)" );
int flag = 1;
if( setsockopt( listener, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(int) ) < 0 )
die( "setsockopt()" );
struct sockaddr_in svr_addr;
memset( &svr_addr, 0, sizeof(struct sockaddr) );
svr_addr.sin_family = PF_INET;
svr_addr.sin_port = htons( PORT );
svr_addr.sin_addr.s_addr = INADDR_ANY;
if( bind( listener, (struct sockaddr*)&svr_addr, (socklen_t)sizeof(struct sockaddr) ) < 0 )
die( "bind()" );
if( listen( listener, 10 ) < 0 )
die( "listen()" );
/* *** */
fd_set fd_master;
fd_set fd_select;
int fd_max = listener;
FD_ZERO( &fd_master );
FD_ZERO( &fd_select );
FD_SET( listener, &fd_master );
while( 1 )
{
fd_select = fd_master;
if( select( fd_max + 1, &fd_select, NULL, NULL, NULL ) < 0 )
die( "select()" );
for( int ifd = 0; ifd <= fd_max; ++ifd )
{
if( ! FD_ISSET( ifd, &fd_select ) ) continue;
struct sockaddr_in cli_addr; memset( &cli_addr, 0, sizeof(cli_addr) );
socklen_t cli_alen = sizeof(cli_addr);
if( ifd == listener )
{
int cli = accept( listener, (struct sockaddr*)&cli_addr, &cli_alen );
if( cli < 0 ) die( "accept()" );
FD_SET( cli, &fd_master );
if( cli > fd_max ) fd_max = cli;
printf( "new connection> %s:%u\n", inet_ntoa( cli_addr.sin_addr ), ntohs( cli_addr.sin_port ) );
fflush( stdout );
}
else
{
char buf[256];
cli_alen = sizeof(cli_addr);
ssize_t nbytes = recvfrom( ifd, buf, sizeof(buf), 0, (struct sockaddr*)&cli_addr, &cli_alen );
if( nbytes <= 0 )
{
close( ifd );
FD_CLR( ifd, &fd_master );
if( nbytes == 0 )
printf( "connection hung up> %u\n", ifd );
else
printf( "recvfrom() : %s\n", strerror( errno ) );
fflush( stdout );
}
else
{
// build a "from identifier" for each of the recipients
char msg[sizeof(buf) * 2];
sprintf( msg, "%s:%u> ", inet_ntoa( cli_addr.sin_addr ), ntohs( cli_addr.sin_port ) );
memcpy( msg + strlen( msg ), buf, nbytes );
nbytes += strlen( msg );
// send incoming data to all clients (excluding the originator)
for( int ofd = 0; ofd <= fd_max; ++ofd )
{
if( FD_ISSET( ofd, &fd_master ) )
if( ofd != listener && ofd != ifd )
if( send( ofd, msg, nbytes, 0 ) < 0 )
{ printf( "send() %s\n", strerror( errno ) ); fflush( stdout ); }
}
}
}
}
}
return 0;
}
When the code is run and you connect from two or more clients (via telnet), each message shows the sender as "0.0.0.0" with a port of 0.
The Windows documentation for recvfrom() states "[t]he from and fromlen parameters are ignored for connection-oriented sockets." The Linux and POSIX documentation make no such claim and goes as far as to say that recvfrom() "...may be used to receive data on a socket whether or not it is connection-oriented." No where does it say that src_addr and addrlen will be ignored ... so I would expect these to be filled in.
On connected sockets you have to call getpeername and then carry on with your inet_ntoa (consider using inet_ntop instead as it supports multiple address families). As per the man pages:
int getpeername(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len);
Nowhere does it say that src_addr and addrlen will be ignored.
That is simply untrue. It says
If src_addr is not NULL, and the underlying protocol provides the source address, this source address is filled in. [emphasis added]
You can argue about whether TCP can be said to provide the source address, but you can't claim 'nowhere does it say ...'.
I'm writing a program to communicate with an existing device via serial port, and I am noticing a weird pattern. This is being tested with both a real serial port, and a USB-to-serial adapter. I get the same results for both.
Immediately after booting up the computer or plugging in the adapter, serial port communication works fine. I can send binary data to the device, and get a response back. The program can continue to communicate with the device as long as it wants.
However, once the program ends (cleanly closing the port), running the program again results in failure to communicate. It can access the serial port just fine, but all it gets back is garbage.
(Oddly, the garbage appears to be binary data mixed with modem commands like ATE0Q0S0=0, which makes no sense. Again, I don't need to reset the device to communicate with it, just the port, so I don't know where this is coming from.)
Power-cycling or unplugging the device has no effect. It is only when I reboot the computer, or reset the USB device (via unplug, or driver reset), that I can run the program once more and get it to communicate successfully.
What would cause this? From the results, I can only assume that the serial port is not being left in a clean state after use, but I can find no documentation about properly cleaning the serial port state, other than re-applying ioctl attributes and closing the file descriptor after use, both of which I already do.
Maybe a serial port pin gets left on or something? I don't know how I would test for that, or why it would even happen.
My current "solution" is to just stick with the USB adapter, and have my program perform a USB driver reset before attempting to use the serial port, but I'm hoping there is a better solution.
Edit
As requested, here is the C program I'm using to test the serial port read/write.
include
#include <fcntl.h>
#include <inttypes.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
// Saved termios that we can re-apply when we exit
struct termios savedPortAttributes;
// Set the serial port attributes so we can use it
void setPortAttributes( int fd )
{
struct termios tty;
memset( &tty, 0, sizeof(tty) );
if ( tcgetattr( fd, &tty ) != 0 ) {
printf( "tcgetaddr error: $i\n", errno );
return;
}
cfsetispeed( &tty, B9600 );
cfsetospeed( &tty, B9600 );
cfmakeraw( &tty );
tty.c_lflag = 0;
tty.c_oflag = 0;
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
tty.c_cflag |= (CLOCAL | CREAD);
tty.c_cflag &= ~(PARENB | PARODD);
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;
tty.c_cc[VMIN] = 0;
tty.c_cc[VTIME] = 5;
if ( tcsetattr( fd, TCSANOW, &tty ) != 0 ) {
printf( "tcsetaddr error: $i\n", errno );
return;
}
if ( tcflush( fd, TCIOFLUSH ) != 0 ) {
printf( "tcflush error: $i\n", errno );
return;
}
}
void test( int fd )
{
// Send a sample MODBUS command
printf( "Writing command\n" );
char sendBuffer[] = { 0x01, 0x03, 0x00, 0x0B, 0x00, 0x02, 0xB5, 0xC9 };
int bytesWritten = write( fd, sendBuffer, sizeof(sendBuffer) );
if ( bytesWritten < 0 ) {
printf( "Error writing command.\n" );
return;
}
// We don't want to wait more than 1000ms for a response
struct timespec spec;
clock_gettime( CLOCK_MONOTONIC, &spec );
int64_t startMs = spec.tv_sec * 1000 + round( spec.tv_nsec / 1.0e6 );
// Read data back from the port
printf( "Reading from port...\n" );
unsigned char buffer[1024];
int bufferOffset = 0;
int count = 0;
while ( 1 ) {
count = read( fd, &buffer[bufferOffset], sizeof(buffer) - bufferOffset );
if ( count < 0 ) {
printf( "Error reading command.\n" );
return;
}
if ( count > 0 ) {
printf( "Bytes read: " );
for ( int i = bufferOffset; i < bufferOffset + count; i++ ) {
printf( "%02x ", buffer[i] );
}
printf( "\n" );
}
bufferOffset += count;
// Test code. If we receive part of a valid MODBUS response, grab the
// field length byte so we know if we're done reading
if ( bufferOffset >= 3 && buffer[0] == 1 && buffer[1] == 3 ) {
int messageLength = buffer[2];
if ( bufferOffset >= messageLength + 5 ) {
break;
}
}
// If it's been 1000ms, stop reading
clock_gettime( CLOCK_MONOTONIC, &spec );
int64_t timeMs = spec.tv_sec * 1000 + round( spec.tv_nsec / 1.0e6 );
//printf( "%" PRId64 " , %" PRId64 "\n", startMs, timeMs );
if ( timeMs - startMs > 1000 ) {
break;
}
}
}
void main()
{
printf( "Opening port\n" );
int fd = open( "/dev/ttyUSB0", O_RDWR|O_NOCTTY );
if ( fd == -1 ) {
printf( "Unable to open port.\n" );
return;
}
tcgetattr( fd, &savedPortAttributes );
setPortAttributes( fd );
test( fd );
test( fd );
tcsetattr( fd, TCSANOW, &savedPortAttributes );
close( fd );
}
I am trying to solve producer consumer problem using threads without semaphoere.In my client i create 4 threads 2 for producer and 2 for consumer, each of them send M produce/consume messages. Here is my client code.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <pthread.h>
#define BUFSIZE 4096
#define N 4
/*
** Client
*/
int M = 10;
pthread_t threads[N];
char buf[BUFSIZE];
char *service;
char *host = "localhost";
int cc;
int csock;
int consumed,produced;
void *connect_and_handle(void *msg){
/* Create the socket to the controller */
if ( ( csock = connectsock( host, service, "tcp" )) == 0 ) {
fprintf( stderr, "Cannot connect to server.\n" );
exit( -1 );
}
printf( "The server is ready, please start entering commands.\n" );
fflush( stdout );
// Start the loop
int k;
//char msg[50];
for (k=0;k<M;k++){
strcpy(buf, msg);
// Send to the server
if ( write( csock, buf, strlen(buf) ) < 0 ) {
fprintf( stderr, "client write failed: %s\n", strerror(errno) );
exit( -1 );
}
if ( (cc = read( csock, buf, BUFSIZE )) <= 0 )
break;
buf[cc] = 0;
printf( "Server replied: %s\n", buf );
}
close( csock );
// exit thread
pthread_exit(NULL);
}
int main( int argc, char *argv[] ){
char *msg, *msg2;
switch( argc ) {
case 2:
service = argv[1];
break;
case 3:
host = argv[1];
service = argv[2];
break;
default:
fprintf( stderr, "usage: chat [host] port\n" );
exit(-1);
}
// thread code goes here
int i, n = N;
for (i=0;i<N;i++){
msg = (char*)malloc(32*sizeof(char));
msg2 = (char*)malloc(32*sizeof(char));
sprintf(msg,"PRODUCE This is the item #%i", i);
sprintf(msg2, "CONSUME");
//producer thread
produced = pthread_create( &threads[i], NULL, connect_and_handle, (void *) msg );
if ( produced != 0 ) { printf( "Error: pthread_create returned code %d.\n", produced); exit( -1 );}
//consumer thread
/*
i++;
consumed = pthread_create( &threads[i], NULL, connect_and_handle, (void *) msg2 );
if ( consumed != 0 ){ printf( "Error: pthread_create returned code %d.\n", consumed ); exit( -1 );}
*/
}
}
and server :
// This server implements part of the 333 protocol
// NUMBER - number of clients served
// NAMES - developers
// GOODBYE - close connection
// ADD - increment
// SUBTRACT- decrement
//
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <semaphore.h>
#define QLEN 5
#define BUFSIZE 4096
#define MAX 100
/*
** This server ... is threaded
*/
// Function prototypes
int passivesock( char *, char *, int, int * );
void *handle_a_client( void *arg );
// Global variables are shared by the threads
int clients = 0;
char *buffer[MAX];
char *maloc_buf;
int count=0;
int full_count=0;
int empty_count=MAX;
int main( int argc, char *argv[] ) {
char *service;
struct sockaddr_in fsin;
int alen;
int msock;
int ssock;
int rport = 0;
switch (argc) {
case 1:
// No args? let the OS choose a port and tell the user
rport = 1;
break;
case 2:
// User provides a port? then use it
service = argv[1];
break;
default:
fprintf( stderr, "usage: server [port]\n" );
exit(-1);
}
msock = passivesock( service, "tcp", QLEN, &rport );
if (rport) {
// Tell the user the selected port
printf( "server: port %d\n", rport );
fflush( stdout );
}
// Keep accepting clients until you are killed
for (;;) {
int ssock;
pthread_t pid;
alen = sizeof(fsin);
ssock = accept( msock, (struct sockaddr *)&fsin, &alen );
if (ssock < 0) {
fprintf( stderr, "accept: %s\n", strerror(errno) );
exit(-1);
}
clients++;
printf("connected , %i", clients);
// Launch a thread to manage this client
// YES, pid is getting overwritten each time, but it is unused
pthread_create( &pid, NULL, handle_a_client, (void *) ssock );
}
}
void *handle_a_client( void *arg ) {
char requestbuf[BUFSIZE];
char replybuf[BUFSIZE];
int ssock = (int) arg;
int cc;
for (;;) {
if ( (cc = read( ssock, requestbuf, BUFSIZE )) <= 0 ) {
printf( "The client has gone.\n");
(void) close(ssock);
pthread_exit(0);
break;
}
else {
// Remove the newline and null-terminate the string
requestbuf[cc] = '\0';
int size = cc-7;
printf( "The client on %d says: %s\n", ssock, requestbuf );
if ( strncasecmp( requestbuf, "goodbye", 7 ) == 0 ) {
close( ssock );
break;
}
else if ( strncasecmp( requestbuf, "PRODUCE", 7 ) == 0 ) {
if (full_count == MAX){
strcpy(replybuf,"FULL\n");
write(ssock,replybuf,strlen(replybuf));
}
else {
maloc_buf=(char*) malloc((size)*sizeof(char));
strcpy(maloc_buf, (requestbuf+8));
buffer[full_count]=maloc_buf;
int num=full_count+1;
sprintf(replybuf, "Client produced item no%i: %s",full_count, buffer[full_count]);
full_count++;
empty_count--;
}
}
else if ( strncasecmp( requestbuf, "CONSUME", 7 ) == 0 ) {
if (empty_count == MAX) {
strcpy(replybuf,"EMPTY\n");
write( ssock, replybuf, strlen(replybuf) );
}
else {
sprintf(replybuf,"OK %s", buffer
[full_count]);
free(buffer[full_count]);
full_count--;
empty_count++;
}
}
}
}
}
When i run my server and then try to connect to it in client, nothing happens. Debugging showed (i am not sure) that in client code after
if ( ( csock = connectsock( host, service, "tcp" )) == 0 ) {
i am exiting, nothing is printed to console both in client and server.
I know we can use 'NETLINK_ROUTE' socket with RTM_F_NOTIFY flag to notify user if route changes according to the RFC3549. But I can't find one method to notify the user when arp table changes.
PS: I use linux kernel 3.0.6
One should use NETLINK_ROUTE socket and bind() to the group RTNLGRP_NEIGH.
After that one can get ndmsg notifications with recv(). Pls note, that all notifications must be consumed, otherwise the socket will raise the ENOBUF exception with the next recv() after the overflow.
Or with external ip(8) utility:
$ ip monitor all # get all the notifications
$ ip monitor neigh # get only arp notifications
Or with a Python library:
from pyroute2 import IPRoute
from pprint import pprint
ip = IPRoute()
ip.bind() # subscribe to all the events
while True:
pprint(ip.get())
If I understood you right - I would suggest you to analyse sources of "ip" program. When you run "ip monitor" and add or remove any ARP entry then "ip monitor" will show you appropriate message.
I'm not aware of pure arp notifications but you could use the arpd which runs in user-space and is intended for cases where the arp table is very large. If you use arpd and modify it you can make it send you notifications on arp table changes.
You can use this to catch arp add/del messages.
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <linux/rtnetlink.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <time.h>
/* convert the netlink multicast group number into a bit map */
/* ( e.g. 4 => 16, 5 => 32 ) */
static __u32 nl_mgrp( __u32 group )
{
if ( group > 31 )
{
printf( "Netlink: Use setsockopt() for this group: %d\n", group ) ;
return 0 ;
}
return ( group ? ( 1 << ( group - 1 ) ) : 0 ) ;
}
void process_message( char *buf , int raw_msg_len )
{
struct nlmsghdr *nlmp ;
struct ndmsg *rtmp ;
struct rtattr *rtatp ;
int rtattrlen, len, req_len ;
struct in_addr *inp ;
char ipv4string[INET_ADDRSTRLEN] ;
printf( "process_message: raw_msg_len: %d\n" , raw_msg_len ) ;
for ( nlmp = ( struct nlmsghdr * ) buf ; raw_msg_len > sizeof( *nlmp ) ; )
{
int len = nlmp->nlmsg_len ;
int req_len = len - sizeof( *nlmp ) ;
//check if arp is changed
if(nlmp->nlmsg_type == RTM_NEWNEIGH){
printf("RTM_NEWNEIGH\n");
} else if (nlmp->nlmsg_type == RTM_DELNEIGH){
printf("RTM_DELNEIGH\n");
}
if ( ( req_len < 0 ) || ( len > raw_msg_len ) || ( ! NLMSG_OK( nlmp, raw_msg_len ) ) )
{
printf( "error\n" ) ;
// Should processing of the message continue if there are certain types of problems?
}
rtmp = ( struct ndmsg * ) NLMSG_DATA( nlmp ) ;
rtatp = ( struct rtattr * ) IFA_RTA( rtmp ) ;
rtattrlen = IFA_PAYLOAD( nlmp ) ;
for ( ; RTA_OK( rtatp, rtattrlen ) ; rtatp = RTA_NEXT( rtatp, rtattrlen ) )
{
if( rtatp->rta_type == NDA_DST )
{
inp = ( struct in_addr * ) RTA_DATA( rtatp ) ;
inet_ntop( AF_INET, inp, ipv4string, INET_ADDRSTRLEN ) ;
printf( "addr: %s\n" , ipv4string ) ;
}
}
raw_msg_len -= NLMSG_ALIGN( len ) ;
nlmp = ( struct nlmsghdr * ) ( ( char* ) nlmp + NLMSG_ALIGN( len ) ) ;
}
// How is the event to be parsed?
}
int main( int argc , char** argv )
{
int sock ;
static struct sockaddr_nl g_addr ;
char buffer[4096] ;
int received_bytes = 0 ;
int ret ;
/* Zeroing addr */
bzero( &g_addr, sizeof( g_addr ) ) ;
g_addr.nl_family = AF_NETLINK ;
g_addr.nl_groups = nl_mgrp( RTNLGRP_NEIGH ) ;
if ( ( sock = socket( AF_NETLINK, SOCK_RAW, NETLINK_ROUTE ) ) < 0 )
{
printf( "socket() error: %s\n", strerror( errno ) ) ;
return -1 ;
}
if ( bind( sock, ( struct sockaddr * ) &g_addr, sizeof( g_addr ) ) < 0 )
{
printf( "bind() error: %s\n" , strerror( errno ) ) ;
return -1 ;
}
while ( 1 )
{
received_bytes = recv( sock , buffer , sizeof( buffer ) , 0 ) ;
if ( received_bytes > 0 )
{
printf( "\n- Event -\n" ) ;
process_message( buffer, received_bytes ) ;
}
}
}
I need to write an application that can disable shutdown, logoff, restart buttons and does some work and before terminating it again enables all these buttons.
#include <windows.h>
#include <stdio.h>
//#include <Winerror.h>
int main()
{
HKEY Regkey,RegSubkey ;
DWORD buf = 1 ;
DWORD Disposition ;
LONG ret ;
ret = RegOpenKeyEx(HKEY_CURRENT_USER,TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer"),0,KEY_ALL_ACCESS,&Regkey) ;
if(ret != ERROR_SUCCESS)
{
printf("RegOpenKeyEx failed......%d\n",GetLastError()) ;
getchar() ;
return 0 ;
}
else
printf("RegOpenKeyEx success......\n") ;
ret = RegSetValueEx(Regkey,TEXT("NoClose"),0,REG_DWORD,(const BYTE*)&buf,sizeof(buf)) ;
if(ret != ERROR_SUCCESS)
{
printf("RegSetValueEx failed......%d\n",GetLastError()) ;
getchar() ;
return 0 ;
}
else
printf("RegSetValueEx success......\n") ;
//getchar() ;
RegCloseKey(Regkey) ;
return 0 ;
}