I am having trouble with my Raspberry Pi sending things to the Spark Core. I thought it could’ve been an issue that another member was seeing, but it’s just an issue in my code. I will post the spark core code here:
EDIT: pastebin links are 3-4 posts below
#define NUM_TRIES 2
#define MAXLINE 1024
TCPClient client;
byte server[] = { 10,0,0,18 }; // Rpi server
int port = 17060;
char *connect_and_send(char* message);
void *get_response(char *response);
char *response_buf = (char*)malloc(sizeof(char) * MAXLINE/4);;
void setup()
{
pinMode(D7, OUTPUT);
Spark.variable("response", response_buf, STRING);
}
void loop()
{
char *response = connect_and_send("GET pi.txt");
if(response == NULL)
{
return;
}
strcpy(response_buf, response);
digitalWrite(D7, HIGH);
delay(5000);
if(response != NULL)
free(response);
digitalWrite(D7, LOW);
}
//Call this function to connect and send a message. Returns the message it received
//TODO: make it return an array and make verbose mode where it will echo the response
inline char *connect_and_send(char *message)
{
bool connected = false;
char *response = (char*)malloc(sizeof(char) * MAXLINE/4);
if(response == NULL)
return response;
// Tries to connect to server multiple times
for(int i = 0; i < NUM_TRIES; i++)
{
if(client.connect(server,port)) //if connected, send message
{
connected = true;
client.println(message);
break;
}
}
if(connected) //if connection succeeded, get the file
{
get_response(response);
}
delay(100);
client.flush();
client.stop();
return response;
}
//Gets the file response from the Raspberry Pi and modifies pointer response
void *get_response(char *response)
{
int count = 0;
if (client.connected())
{
// echo all available bytes back to the client
while (client.available())
{
char c = client.read();
response[count] = c;
count += 1;
}
}
else
{
digitalWrite(D7, HIGH);
delay(500);
digitalWrite(D7, LOW);
}
}
/*
*
* This is the implementation of my Raspberry Pi TCP Server.
*
* The RPi will connect to the Spark Core through a TCP connection
* on the port specified on the command line, and will wait for incoming
* connections on that port.
*
* When a connection is made, the request will be split into two parts,
* where the request follows the format "method option". Different
* methods will have different results but the behavior of the
* current supported methods are listed below:
*
* GET option
* - The GET method will request a file, where option is the file to be
* requested. The file will then be opened and sent to the core.
*
*`
*/
#include <stdio.h>
#include "csapp.h"
#include <stdbool.h>
#include <time.h>
//Permission and flags for opening the log file
#define PERMISSION (S_IROTH | S_IWOTH | S_IXOTH)
#define FLAGS (O_RDWR | O_CREAT | O_APPEND)
//Assert to print log entries to standard output
#define PRINT_LOG_ENTRY 1
//Log file and file descriptor
static const char *log_file = "log.txt";
int log_fd;
//boolean to help make logs easier to read
bool put_time = true;
/* Function prototypes */
void handle_request(int core_fd, char *method, char *option);
inline void make_log_entry(char *message);
int main(int argc, char **argv)
{
int listenfd; /* listening file descriptor */
int port; /* port to listen to connections */
struct sockaddr_in clientaddr;
unsigned clientlen;
int fd;
rio_t rio_client;
char buf[MAXLINE];
char method[100];
char option[100];
// Ignore SIGPIPE
Signal(SIGPIPE, SIG_IGN);
if(argc != 2)
{
printf("User error. Please enter in ./server <port> \n");
exit(1);
}
/* Get port number */
port = atoi(argv[1]);
/* Open the log file and make a log entry stating the port*/
log_fd = Open(log_file, FLAGS, PERMISSION);
char temp[MAXLINE];
sprintf(temp, "Opening connection on port: %d", port);
make_log_entry(temp);
/* Open listening socket on server side */
listenfd = Open_listenfd(port);
while(1)
{
clientlen = sizeof(clientaddr);
fd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
//Read and parse the request line
Rio_readinitb(&rio_client, fd);
Rio_readlineb(&rio_client, buf, MAXLINE);
sscanf(buf, "%s %s", method, option);
handle_request(fd, method, option);
Close(fd);
put_time = true;
}
return 0;
}
/* Handles requests from the Spark Core.
* Current supported methods:
* GET:
* - When GET is called, we open the file specified by option
* and send it to the Spark Core.
*
* METHOD2:
* - Put more information about METHOD2.
*
*/
void handle_request(int core_fd, char *method, char *option)
{
int file_fd;
rio_t rio;
char buf[MAXLINE]; //buffer for contents of file to be written to
char temp[MAXLINE];
int n;
sprintf(temp, "Method:%s\nOption:%s", method, option);
make_log_entry(temp);
put_time = false;
if(strcmp(method, "GET") == 0)
{
sprintf(temp, "Opening file: %s", option);
make_log_entry(temp);
//Open file
file_fd = Open(option, O_RDONLY, 0);
make_log_entry("Succuess opening file. Starting to send");
Rio_readinitb(&rio, file_fd);
//Send file to Spark Core
while((n = Rio_readnb(&rio, buf, MAXLINE)) > 2)
{
make_log_entry(buf);
Rio_writen(core_fd, buf, n);
}
make_log_entry("Done sending file\n");
Close(file_fd);
}
return;
}
/* Makes a log entry with message to the log file declared at the top
* of this file. Only displays the time on the log if its a new request.
*/
inline void make_log_entry(char *message)
{
if(put_time)
{
time_t curr_time;
char *curr_time_str;
curr_time = time(NULL);
curr_time_str = ctime(&curr_time);
write(log_fd, curr_time_str, strlen(curr_time_str));
}
if(PRINT_LOG_ENTRY) printf("%s\n", message);
write(log_fd, message, strlen(message));
write(log_fd, "\n", strlen("\n"));
}