/* This is signalled every time a character is received over the UART. */ void uart_callback(uint8_t received) { /* 0x02 = STX */ if (received == 0x02) { uartIndex = 0; isUartError = false; return; } /* * If there has been an error (message is too long, or length doesn't match * specified length), ignore bytes until next STX is received. */ if (isUartError) { return; } /* 0x03 = ETX */ if (received == 0x03) { if (uartBuffer[0] != uartIndex - MSG_OVERHEAD_SIZE) { isUartError = true; return; } msg_callback((msgType*)&uartBuffer); return; } /* Don't let index go over buffer size */ if (uartIndex + 1 >= RF_MAX_PAYLOAD_SIZE) { isUartError = true; return; } uartBuffer[uartIndex++] = received; }
/* process pending comment */ static int NextIsComment(input_data *data, char **startp, int *lenp) { char *end; if (!(data->point[0] == '/' && data->point[1] == '*')) return 0; end = strstr(data->point, "*/"); *lenp = 0; if (end) { int skippedLines = 0; char *tempPoint; /* get current lineno */ IDL_file_get(NULL,(int *)&data->lineno); /* get line count */ for (tempPoint = data->point; tempPoint < end; tempPoint++) { if (*tempPoint == '\n') skippedLines++; } data->lineno += skippedLines; IDL_file_set(data->filename, (int)data->lineno); *startp = end + 2; /* If it's a ** comment, tell libIDL about it. */ if (data->point[2] == '*') { /* hack termination. +2 to get past '*' '/' */ char t = *(end + 2); *(end + 2) = '\0'; IDL_queue_new_ident_comment(data->point); *(end + 2) = t; } data->point = *startp; /* XXXmccabe move this out of function? */ return 1; } else { const char *filename; int lineno; IDL_file_get(&filename, &lineno); msg_callback(IDL_ERROR, 0, lineno, filename, "unterminated comment"); return -1; } }
void log_message(GLenum source, GLenum type, GLuint id, GLenum severity, const std::string& msg) { debug_msg_callback msg_callback = nullptr; GLvoid* user_param = nullptr; std::shared_ptr<context> current_locked_context = current_context.lock(); if (current_locked_context) { msg_callback = current_locked_context->log().callback(); user_param = current_locked_context->log().user_param(); } else { msg_callback = get_default_debug_msg_callback(); user_param = nullptr; } if (msg_callback) { msg_callback(source, type, id, severity, static_cast<GLsizei>(msg.length()), msg.c_str(), user_param); } }
/* process pending raw section */ static int NextIsRaw(input_data *data, char **startp, int *lenp) { char *end, *start; /* * XXXmccabe still needed: an in_raw flag to handle the case where we're in * a raw block, but haven't managed to copy it all to xpidl. This will * happen when we have a raw block larger than * IDL_input_data->fill.max_size (currently 8192.) */ if (!(data->point[0] == '%' && data->point[1] == '{')) return 0; start = *startp = data->point; end = NULL; while (start < data->max && (end = strstr(start, "%}"))) { if (end[-1] == '\r' || end[-1] == '\n') break; start = end + 1; } if (end && start < data->max) { *lenp = end - data->point + 2; return 1; } else { const char *filename; int lineno; IDL_file_get(&filename, &lineno); msg_callback(IDL_ERROR, 0, lineno, filename, "unterminated %{ block"); return -1; } }
/* * Our own version of IDL_tree_warning, which we use when IDL_tree_warning * would crash on us. */ void xpidl_tree_warning(IDL_tree p, int level, const char *fmt, ...) { va_list ap; char *msg, *file; int lineno; /* XXX need to check against __IDL_max_msg_level, no accessor */ va_start(ap, fmt); msg = g_strdup_vprintf(fmt, ap); if (p) { file = p->_file; lineno = p->_line; } else { file = NULL; lineno = 0; } /* call our message callback, like IDL_tree_warning would */ msg_callback(level, 0, lineno, file, msg); g_free(msg); va_end(ap); }
static int NextIsInclude(input_callback_state *callback_state, char **startp, int *lenp) { input_data *data = callback_state->input_stack; input_data *new_data; char *filename, *end; const char *scratch; /* process the #include that we're in now */ if (strncmp(data->point, "#include \"", 10)) { return 0; } filename = data->point + 10; /* skip #include " */ XPT_ASSERT(filename < data->max); end = filename; while (end < data->max) { if (*end == '\"' || *end == '\n' || *end == '\r') break; end++; } if (*end != '\"') { /* * Didn't find end of include file. Scan 'til next whitespace to find * some reasonable approximation of the filename, and use it to report * an error. */ end = filename; while (end < data->max) { if (*end == ' ' || *end == '\n' || *end == '\r' || *end == '\t') break; end++; } *end = '\0'; /* make sure we have accurate line info */ IDL_file_get(&scratch, (int *)&data->lineno); fprintf(stderr, "%s:%d: didn't find end of quoted include name \"%s\n", scratch, data->lineno, filename); return -1; } *end = '\0'; *startp = end + 1; if (data->next == NULL) { /* * If we're in the initial file, add this filename to the list * of filenames to be turned into #include "filename.h" * directives in xpidl_header.c. We do it here rather than in the * block below so it still gets added to the list even if it's * already been recursively included from some other file. */ char *filename_cp = xpidl_strdup(filename); /* note that g_slist_append accepts and likes null as list-start. */ callback_state->base_includes = g_slist_append(callback_state->base_includes, filename_cp); } /* store offset for when we pop, or if we skip this one */ data->point = *startp; if (!g_hash_table_lookup(callback_state->already_included, filename)) { filename = xpidl_strdup(filename); g_hash_table_insert(callback_state->already_included, filename, (void *)TRUE); new_data = new_input_data(filename, callback_state->include_path); if (!new_data) { char *error_message; IDL_file_get(&scratch, (int *)&data->lineno); error_message = g_strdup_printf("can't open included file %s for reading\n", filename); msg_callback(IDL_ERROR, 0, data->lineno, scratch, error_message); g_free(error_message); return -1; } new_data->next = data; /* tell libIDL to exclude this IDL from the toplevel tree */ IDL_inhibit_push(); IDL_file_get(&scratch, (int *)&data->lineno); callback_state->input_stack = new_data; IDL_file_set(new_data->filename, (int)new_data->lineno); } *lenp = 0; /* this is magic, see the comment below */ return 1; }
/* * This is signalled every time an RF packet is received. */ void rf_callback(volatile rf_msgType* msg) { msg_callback(msgBuffer); }
//---------------------------------------- // connect : TCP/UDP layer // handshake : // - once connected, send handshake // - wait for handshake response // - process (fail: close) //---------------------------------------- BOOL netlink_tick(NetLink *c) { MessageFp msg_callback; int i; char *hdr; int n; if(!c || c->sock == INVALID_SOCKET) return FALSE; if(!c->connected) { if(c->s) // server side sends handshake { LinkHandshake hs = {0}; // remember to add sends below assert_infunc_static(sizeof(hs) == 8); hs.vers = htonl(c->ctxt->vers); hs.flags = htonl(0); // todo n = 0; if(n>=0) n = send(c->sock, (char*)&hs.vers, sizeof(hs.vers), 0); if(n>=0) n = send(c->sock, (char*)&hs.flags, sizeof(hs.flags), 0); if(n < 0) { if(last_error() == ENOTCONN) // okay, still connecting return TRUE; else { LOG("error handshaking client %s",last_error_str()); goto netlinktick_error; } } c->connected = TRUE; } else { if(sock_canrecv(c->sock,0)) c->connected = TRUE; } } if(!c->handshaken) { if(!sock_recv(c->sock, &c->recv_frame, &c->closed)) { ERR("error in link %s:%p recv during handshake %s", linkip(c),c,last_error_str()); goto netlinktick_error; } if(c->s) // server-side handling of handshake response { U32 vers_res; if(achr_size(&c->recv_frame) < sizeof(vers_res)) return TRUE; achr_mv(&vers_res,&c->recv_frame,sizeof(vers_res)); vers_res = ntohl(vers_res); if(vers_res != c->ctxt->vers) { ERR("%s:%p link handshake responded with wrong version %u should be %u",linkip(c),c,vers_res,c->ctxt->vers); goto netlinktick_error; } } else { U32 tmp; LinkHandshake lh = {0}; if(achr_size(&c->recv_frame) < sizeof(lh)) return TRUE; assert_infunc_static(sizeof(lh) == 8); achr_mv(&lh.vers,&c->recv_frame,sizeof(lh.vers)); lh.vers = ntohl(lh.vers); achr_mv(&lh.flags,&c->recv_frame,sizeof(lh.flags)); lh.flags = ntohl(lh.flags); if(lh.vers != c->ctxt->vers) { ERR("%s:%p version mismatch between client(%c) and server(%c)",linkip(c),c,c->ctxt->vers,lh.vers); goto netlinktick_error; } tmp = htonl(c->ctxt->vers); n = send(c->sock,(char*)&tmp,sizeof(c->ctxt->vers),0); if(n < 0) { ERR("%s:%p couldn't send version response",linkip(c),c); goto netlinktick_error; } } c->handshaken = TRUE; if(c->conn_callback) c->conn_callback(c); else if(SAFE_MEMBER(c->s,conn_callback)) c->s->conn_callback(c); } // ---------------------------------------- // recv and turn into packets if(!sock_recv(c->sock, &c->recv_frame, &c->closed)) { ERR("%s:%p recv failed %s",linkip(c),c,last_error_str()); goto netlinktick_error; } net_process_frame(c); // ---------------------------------------- // dispatch n = apak_size(&c->recvs); if(n) { msg_callback = c->msg_callback; if(!msg_callback && c->s) msg_callback = c->s->msg_callback; if(!msg_callback) { ERR("%s:%p no msg handler for link",linkip(c),c); goto netlinktick_error; } for(i = 0;i < n; ++i) { Pak *m = c->recvs[i]; if(!msg_callback(c,m,m->hdr.msgid)) continue; Pak_Destroy(&m); apak_rm(&c->recvs,i,1); } } n = apak_size(&c->sends); if(n) { hdr = achr_create(sizeof(PakHdr)); for( i = 0; i < n; ++i ) { U32 tmp; Pak *p = c->sends[i]; // @todo -AB: encrypted, etc. :09/26/08 achr_setsize(&hdr,0); tmp = htonl(p->hdr.msgid); achr_append(&hdr,(char*)&tmp,sizeof(tmp)); tmp = htonl(p->hdr.id); achr_append(&hdr,(char*)&tmp,sizeof(tmp)); tmp = htonl(achr_size(&p->body)); achr_append(&hdr,(char*)&tmp,sizeof(tmp)); if(!sock_send(c->sock,&hdr,&p->body)) { if(last_error() == EMSGSIZE) // out of room to send. try again later { ERR("%s:%p send buffer full for socket: %s. waiting one tick",linkip(c),c,last_error_str()); break; } ERR("%s:%p failed to send on socket: %s",linkip(c),c,last_error_str()); net_shutdownlink(c); Pak_Destroy(&p); break; } Pak_Destroy(&p); } achr_destroy(&hdr); apak_rm(&c->sends,0,i); // cleanup happens above } // ---------- // cleanup // what are we doing here? The point is to allow a graceful // cleanup. At some point one side or the other is supposed // to initiate termination by calling 'shutdown'. there are // several ways this happens: // 1) link recvs 0 bytes : closed. all recvd packets are processed. sends are allowed. when all recv'd paks handled, shutdown is called // 2) link calls shutdown: no sends allowed, server should respond with FIN // e.g. // A: shutdown(send). sends FIN to B // B: recv returns 0. sets 'closed' flag. if no msgs to send // will call shutdown itself and close the socket. // A: recv returns 0. closesocket if(apak_size(&c->sends) == 0 && c->shutdown_req && !c->shutdown) { shutdown(c->sock,SD_SEND); c->shutdown = TRUE; } if(!c->closed) // @todo -AB: timeout code :09/25/08 return TRUE; else if(apak_size(&c->recvs)) return TRUE; if(!c->shutdown) { shutdown(c->sock,SD_SEND); c->shutdown = TRUE; } // if this link was made visibile above this layer if(c->handshaken) { if(c->disco_callback) c->disco_callback(c); else if(SAFE_MEMBER(c->s,disco_callback)) c->s->disco_callback(c); } return TRUE; netlinktick_error: closesocket(c->sock); c->sock = INVALID_SOCKET; return FALSE; }