38 #include "ircc-strings.h"
44 #ifdef IRC_CONF_SYSTEM_STRING
45 #define IRC_SYSTEM_STRING IRC_CONF_SYSTEM_STRING
47 #define IRC_SYSTEM_STRING "Contiki"
52 #define SEND_STRING(s, str) PSOCK_SEND(s, (uint8_t *)str, (unsigned int)strlen(str))
54 #define ISO_space 0x20
59 #define ISO_colon 0x3a
80 copystr(
char *dest,
const char *src,
size_t n)
85 strncpy(dest, src, n);
95 PT_THREAD(setup_connection(
struct ircc_state *s))
103 ptr = copystr(ptr, ircc_strings_nick,
sizeof(s->outputbuf));
104 ptr = copystr(ptr, s->nick, (
int)
sizeof(s->outputbuf) - (ptr - s->outputbuf));
105 ptr = copystr(ptr, ircc_strings_crnl_user,
sizeof(s->outputbuf) - (ptr - s->outputbuf));
106 ptr = copystr(ptr, s->nick,
sizeof(s->outputbuf) - (ptr - s->outputbuf));
107 ptr = copystr(ptr, ircc_strings_contiki,
sizeof(s->outputbuf) - (ptr - s->outputbuf));
108 ptr = copystr(ptr, s->server,
sizeof(s->outputbuf) - (ptr - s->outputbuf));
109 ptr = copystr(ptr, ircc_strings_colon_contiki,
sizeof(s->outputbuf) - (ptr - s->outputbuf));
111 SEND_STRING(&s->s, s->outputbuf);
117 PT_THREAD(join_channel(
struct ircc_state *s))
121 SEND_STRING(&s->s, ircc_strings_join);
122 SEND_STRING(&s->s, s->channel);
123 SEND_STRING(&s->s, ircc_strings_crnl);
131 PT_THREAD(part_channel(
struct ircc_state *s))
135 SEND_STRING(&s->s, ircc_strings_part);
136 SEND_STRING(&s->s, s->channel);
137 SEND_STRING(&s->s, ircc_strings_crnl);
145 PT_THREAD(list_channel(
struct ircc_state *s))
149 SEND_STRING(&s->s, ircc_strings_list);
150 SEND_STRING(&s->s, s->channel);
151 SEND_STRING(&s->s, ircc_strings_crnl);
159 PT_THREAD(send_message(
struct ircc_state *s))
166 ptr = copystr(ptr, ircc_strings_privmsg,
sizeof(s->outputbuf));
167 ptr = copystr(ptr, s->channel,
sizeof(s->outputbuf) - (ptr - s->outputbuf));
168 ptr = copystr(ptr, ircc_strings_colon,
sizeof(s->outputbuf) - (ptr - s->outputbuf));
169 ptr = copystr(ptr, s->msg,
sizeof(s->outputbuf) - (ptr - s->outputbuf));
170 ptr = copystr(ptr, ircc_strings_crnl,
sizeof(s->outputbuf) - (ptr - s->outputbuf));
172 SEND_STRING(&s->s, s->outputbuf);
180 PT_THREAD(send_actionmessage(
struct ircc_state *s))
187 ptr = copystr(ptr, ircc_strings_privmsg,
sizeof(s->outputbuf));
188 ptr = copystr(ptr, s->channel,
sizeof(s->outputbuf) - (ptr - s->outputbuf));
189 ptr = copystr(ptr, ircc_strings_colon,
sizeof(s->outputbuf) - (ptr - s->outputbuf));
190 ptr = copystr(ptr, ircc_strings_action,
sizeof(s->outputbuf) - (ptr - s->outputbuf));
191 ptr = copystr(ptr, s->msg,
sizeof(s->outputbuf) - (ptr - s->outputbuf));
192 ptr = copystr(ptr, ircc_strings_ctcpcrnl,
sizeof(s->outputbuf) - (ptr - s->outputbuf));
195 SEND_STRING(&s->s, s->outputbuf);
202 struct parse_result {
212 static struct parse_result r;
214 parse_whitespace(
void)
216 while(*r.msg == ISO_space) ++r.msg;
222 ptr = strchr(r.msg, ISO_space);
260 if(*r.msg == ISO_bang) {
264 if(*r.msg == ISO_at) {
295 ptr = strchr(r.msg, ISO_colon);
297 r.trailing = ptr + 1;
298 ptr = strchr(ptr, ISO_cr);
306 parse(
char *msg,
struct parse_result *dummy)
309 if(*r.msg == ISO_cr || *r.msg == ISO_nl) {
312 if(*r.msg == ISO_colon) {
326 PT_THREAD(handle_input(
struct ircc_state *s))
339 if(strncmp(s->inputbuf, ircc_strings_ping, 5) == 0) {
340 strncpy(s->outputbuf, s->inputbuf,
sizeof(s->outputbuf));
343 s->outputbuf[1] = ISO_O;
344 SEND_STRING(&s->s, s->outputbuf);
347 memset(&r, 0,
sizeof(r));
349 parse(s->inputbuf, &r);
352 ptr = strchr(r.name, ISO_bang);
358 if(r.command !=
NULL && strncmp(r.command, ircc_strings_join, 4) == 0) {
359 ircc_text_output(s,
"Joined channel", r.name);
360 }
else if(r.command !=
NULL && strncmp(r.command, ircc_strings_part, 4) == 0) {
361 ircc_text_output(s,
"Left channel", r.name);
362 }
else if(r.trailing !=
NULL) {
363 if(strncmp(r.trailing, ircc_strings_action,
364 strlen(ircc_strings_action)) == 0) {
365 ptr = strchr(&r.trailing[1], 1);
369 ptr = &r.trailing[strlen(ircc_strings_action)];
370 petsciiconv_topetscii(r.name, strlen(r.name));
371 petsciiconv_topetscii(ptr, strlen(ptr));
372 ircc_text_output(s, r.name, ptr);
373 }
else if(strncmp(r.trailing, ircc_strings_version_query,
374 strlen(ircc_strings_version_query)) == 0) {
376 strncpy(s->outputbuf, r.name,
sizeof(s->outputbuf));
377 SEND_STRING(&s->s, ircc_strings_notice);
379 SEND_STRING(&s->s, s->outputbuf);
380 SEND_STRING(&s->s, ircc_strings_colon);
381 SEND_STRING(&s->s, ircc_strings_version);
382 SEND_STRING(&s->s, ircc_strings_version_string);
383 SEND_STRING(&s->s, IRC_SYSTEM_STRING);
384 SEND_STRING(&s->s, ircc_strings_ctcpcrnl);
387 petsciiconv_topetscii(r.name, strlen(r.name));
388 petsciiconv_topetscii(r.trailing, strlen(r.trailing));
389 ircc_text_output(s, r.name, r.trailing);
399 PT_THREAD(data_or_command(
struct ircc_state *s))
404 (s->command != COMMAND_NONE));
410 PT_THREAD(handle_connection(
struct ircc_state *s))
414 PSOCK_INIT(&s->s, (uint8_t *)s->inputbuf,
sizeof(s->inputbuf) - 1);
426 if(s->command == COMMAND_JOIN) {
427 s->command = COMMAND_NONE;
429 }
else if(s->command == COMMAND_PART) {
430 s->command = COMMAND_NONE;
432 }
else if(s->command == COMMAND_MSG) {
433 s->command = COMMAND_NONE;
435 }
else if(s->command == COMMAND_ACTIONMSG) {
436 s->command = COMMAND_NONE;
438 }
else if(s->command == COMMAND_LIST) {
439 s->command = COMMAND_NONE;
441 }
else if(s->command == COMMAND_QUIT) {
442 s->command = COMMAND_NONE;
454 ircc_appcall(
void *s)
460 PT_INIT(&((
struct ircc_state *)s)->pt);
461 memset(((
struct ircc_state *)s)->channel, 0,
462 sizeof(((
struct ircc_state *)s)->channel));
463 ((
struct ircc_state *)s)->command = COMMAND_NONE;
464 handle_connection(s);
465 }
else if(s !=
NULL) {
466 handle_connection(s);
471 ircc_connect(
struct ircc_state *s,
char *servername, uip_ipaddr_t *ipaddr,
475 if(s->conn ==
NULL) {
478 s->server = servername;
484 ircc_list(
struct ircc_state *s)
486 s->command = COMMAND_LIST;
490 ircc_join(
struct ircc_state *s,
char *channel)
492 strncpy(s->channel, channel,
sizeof(s->channel));
493 s->command = COMMAND_JOIN;
497 ircc_part(
struct ircc_state *s)
499 s->command = COMMAND_PART;
503 ircc_quit(
struct ircc_state *s)
505 s->command = COMMAND_QUIT;
509 ircc_msg(
struct ircc_state *s,
char *msg)
512 s->command = COMMAND_MSG;
516 ircc_actionmsg(
struct ircc_state *s,
char *msg)
519 s->command = COMMAND_ACTIONMSG;
#define PROCESS_CURRENT()
Get a pointer to the currently running process.
#define PT_WAIT_THREAD(pt, thread)
Block and wait until a child protothread completes.
#define PSOCK_READTO(psock, c)
Read data up to a specified character.
#define PSOCK_BEGIN(psock)
Start the protosocket protothread in a function.
Representation of a uIP TCP connection.
CCIF struct uip_conn * tcp_connect(uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
Open a TCP connection to the specified IP address and port.
#define uip_aborted()
Has the connection been aborted by the other end?
#define NULL
The null pointer.
#define PT_INIT(pt)
Initialize a protothread.
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
#define PT_THREAD(name_args)
Declaration of a protothread.
#define uip_connected()
Has the connection just been connected?
#define PT_WAIT_UNTIL(pt, condition)
Block and wait until condition is true.
#define PSOCK_WAIT_UNTIL(psock, condition)
Wait until a condition is true.
PETSCII/ASCII conversion functions.
#define PSOCK_INIT(psock, buffer, buffersize)
Initialize a protosocket.
#define PSOCK_CLOSE(psock)
Close a protosocket.
#define PSOCK_END(psock)
Declare the end of a protosocket's protothread.
#define PT_BEGIN(pt)
Declare the start of a protothread inside the C function implementing the protothread.
#define uip_timedout()
Has the connection timed out?
#define PSOCK_NEWDATA(psock)
Check if new data has arrived on a protosocket.
#define PT_END(pt)
Declare the end of a protothread.
#define PSOCK_DATALEN(psock)
The length of the data that was previously read.
#define uip_closed()
Has the connection been closed by the other end?
#define PT_EXIT(pt)
Exit the protothread.