/* send_resp * * Send a response back to the user. * * If the send is successful, this will return its 'length' parameter. If * not, it will close the connection, and then return -1. This is intended * for use by recv_fsm, which can tail-call send_resp with the number of * bytes that were consumed from the input. If the send succeeds, then that * value is returned; otherwise, the error is propagated up. */ static int RV send_resp(struct tcp_pcb *pcb, char resp, char cmd, int len) { struct dac_response response; response.response = resp; response.command = cmd; fill_status(&response.dac_status); err_t err = tcp_write(pcb, &response, sizeof(response), TCP_WRITE_FLAG_COPY); if (err == ERR_MEM) { if (ps_defer_ack(cmd, resp) < 0) { outputf("!!! DROPPING ACK !!!"); } else { outputf("deferring ACK"); } } else if (err != ERR_OK) { outputf("tcp_write returned %d", err); return close_conn(pcb, CONNCLOSED_SENDFAIL, len); } err = tcp_output(pcb); if (err != ERR_OK) { outputf("tcp_output returned %d", err); return close_conn(pcb, CONNCLOSED_SENDFAIL, len); } return len; }
static BOOL reset_current(){ SERVICE_STATUS stat; fill_status(&stat); EnterCriticalSection(&crit); stat.dwCurrentState = currentState; LeaveCriticalSection(&crit); return SetServiceStatus(statusHandle, &stat); }
static BOOL set_running(){ SERVICE_STATUS stat; fill_status(&stat); EnterCriticalSection(&crit); currentState = stat.dwCurrentState = SERVICE_RUNNING; LeaveCriticalSection(&crit); return SetServiceStatus(statusHandle, &stat); }
static BOOL set_stopped(int error){ SERVICE_STATUS stat; fill_status(&stat); EnterCriticalSection(&crit); currentState = stat.dwCurrentState = SERVICE_STOPPED; LeaveCriticalSection(&crit); stat.dwWin32ExitCode = error; return SetServiceStatus(statusHandle, &stat); }
static BOOL set_stop_pending(int waithint, int checkpoint){ SERVICE_STATUS stat; fill_status(&stat); EnterCriticalSection(&crit); currentState = stat.dwCurrentState = SERVICE_STOP_PENDING; LeaveCriticalSection(&crit); stat.dwControlsAccepted = 0; stat.dwCheckPoint = checkpoint; stat.dwWaitHint = waithint; return SetServiceStatus(statusHandle, &stat); }
static int ps_send_deferred_acks(struct tcp_pcb *pcb) { int num = (ps_deferred_ack_produce + PS_DEFERRED_ACK_MAX - ps_deferred_ack_consume) % PS_DEFERRED_ACK_MAX; if (num) { outputf("%d deferred acks\n", num); } int count = 0; int consume = ps_deferred_ack_consume; err_t err = 0; while (consume != ps_deferred_ack_produce) { struct dac_response response; response.response = ps_deferred_ack_queue[consume].resp; response.command = ps_deferred_ack_queue[consume].cmd; fill_status(&response.dac_status); err = tcp_write(pcb, &response, sizeof(response), TCP_WRITE_FLAG_COPY); if (err < 0) break; count++; consume = (consume + 1) % PS_DEFERRED_ACK_MAX; } ps_deferred_ack_consume = consume; if (err == ERR_MEM) err = 0; if (num) outputf("sent %d deferred acks, err %d", count, err); return err; }
/* broadcast_send * * Fire off a broadcast packet with information about this DAC. */ void broadcast_send(void) { /* Because lwip is an enormous steaming pile of the finest software * engineering, it is not possible to just allocate *one* pbuf * during initialization - udp_send modifies the pbuf it is given * and changes, among other things, its total length. (??!) So we * allocatea fresh one each time. */ udp_new(&broadcast_pcb); udp_bind(&broadcast_pcb, IP_ADDR_ANY, BROADCAST_PORT); udp_connect(&broadcast_pcb, IP_ADDR_BROADCAST, BROADCAST_PORT); struct pbuf * p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dac_broadcast), PBUF_RAM); /* Shamefully bail out. */ if (!p) return; struct dac_broadcast *pkt = (struct dac_broadcast *) p->payload; eth_get_mac(pkt->mac_address); fill_status(&pkt->status); pkt->buffer_capacity = DAC_BUFFER_POINTS - 1; pkt->max_point_rate = DAC_MAX_POINT_RATE; pkt->hw_revision = 0; // XXX TODO pkt->sw_revision = 1; // XXX TODO - integrate into build system udp_send(&broadcast_pcb, p); pbuf_free(p); udp_remove(&broadcast_pcb); }