Пример #1
0
static void 
accept_new(int accept_fd)
{
	int from, to, feid, teid;

	while (1) {
		feid = evt_get();
		assert(feid > 0);
		from = from_tsplit(cos_spd_id(), accept_fd, "", 0, TOR_RW, feid);
		assert(from != accept_fd);
		if (-EAGAIN == from) {
			evt_put(feid);
			return;
		} else if (from < 0) {
			printc("from torrent returned %d\n", from);
			BUG();
			return;
		}
		teid = evt_get();
		assert(teid > 0);
		to = tsplit(cos_spd_id(), td_root, "", 0, TOR_RW, teid);
		if (to < 0) {
			printc("torrent split returned %d", to);
			BUG();
		}

		mapping_add(from, to, feid, teid);
	}
}
Пример #2
0
static void 
from_data_new(struct tor_conn *tc)
{
	int from, to, amnt;
	char *buf;

	from = tc->from;
	to   = tc->to;
	while (1) {
		int ret;
		cbuf_t cb;

		buf = cbuf_alloc(BUFF_SZ, &cb);
		assert(buf);
		amnt = from_tread(cos_spd_id(), from, cb, BUFF_SZ-1);
		if (0 == amnt) break;
		else if (-EPIPE == amnt) {
			goto close;
		} else if (amnt < 0) {
			printc("read from fd %d produced %d.\n", from, amnt);
			BUG();
		}
		assert(amnt <= BUFF_SZ);
		if (amnt != (ret = twrite(cos_spd_id(), to, cb, amnt))) {
			printc("conn_mgr: write failed w/ %d on fd %d\n", ret, to);
			goto close;

		}
		cbuf_free(buf);
	}
done:
	cbuf_free(buf);
	return;
close:
	mapping_remove(from, to, tc->feid, tc->teid);
	from_trelease(cos_spd_id(), from);
	trelease(cos_spd_id(), to);
	assert(tc->feid && tc->teid);
	evt_put(tc->feid);
	evt_put(tc->teid);
	goto done;
}
Пример #3
0
// Searching for either a NAND block or a sync point
static int st_scanning(struct state *st) {
    struct pkt pkt;
    int ret;
    while ((ret = packet_get_next(st, &pkt)) == 0) {

        if (pkt.header.type == PACKET_HELLO) {
            evt_write_hello(st, &pkt);
        }

        else if (pkt.header.type == PACKET_RESET) {
            evt_write_reset(st, &pkt);
        }

        else if (pkt.header.type == PACKET_NAND_CYCLE) {
            write_nand_cmd(st, &pkt);
        }

        else if (pkt.header.type == PACKET_COMMAND) {
            if (pkt.data.command.start_stop == CMD_STOP) {
                struct evt_net_cmd *net = evt_take(st, EVT_NET_CMD);
                if (!net) {
                    struct evt_net_cmd evt;
                    fprintf(stderr, "NET_CMD end without begin\n");
                    evt_fill_header(&evt, pkt.header.sec, pkt.header.nsec,
                                    sizeof(evt), EVT_NET_CMD);
                    evt.cmd[0] = pkt.data.command.cmd[0];
                    evt.cmd[1] = pkt.data.command.cmd[1];
                    evt.arg = pkt.data.command.arg;
                    evt_fill_end(&evt, pkt.header.sec, pkt.header.nsec);
                    evt.arg = htonl(evt.arg);
                    write(st->out_fd, &evt, sizeof(evt));
                }
                else {
                    evt_fill_end(net, pkt.header.sec, pkt.header.nsec);
                    net->arg = htonl(net->arg);
                    write(st->out_fd, net, sizeof(*net));
                    free(net);
                }
            }
            else {
                struct evt_net_cmd *net = evt_take(st, EVT_NET_CMD);
                if (net) {
                    fprintf(stderr, "Multiple NET_CMDs going at once\n");
                    free(net);
                }

                net = malloc(sizeof(struct evt_net_cmd));
                evt_fill_header(net, pkt.header.sec, pkt.header.nsec,
                                sizeof(*net), EVT_NET_CMD);
                net->cmd[0] = pkt.data.command.cmd[0];
                net->cmd[1] = pkt.data.command.cmd[1];
                net->arg = pkt.data.command.arg;
                evt_put(st, net);
            }
        }

        else if (pkt.header.type == PACKET_BUFFER_DRAIN) {
            if (pkt.data.buffer_drain.start_stop == PKT_BUFFER_DRAIN_STOP) {
                struct evt_buffer_drain *evt = evt_take(st, EVT_BUFFER_DRAIN);
                if (!evt) {
                    struct evt_buffer_drain evt;
                    fprintf(stderr, "BUFFER_DRAIN end without begin\n");
                    evt_fill_header(&evt, pkt.header.sec, pkt.header.nsec,
                                    sizeof(evt), EVT_BUFFER_DRAIN);
                    evt_fill_end(&evt, pkt.header.sec, pkt.header.nsec);
                    write(st->out_fd, &evt, sizeof(evt));
                }
                else {
                    evt_fill_end(evt, pkt.header.sec, pkt.header.nsec);
                    write(st->out_fd, evt, sizeof(*evt));
                    free(evt);
                }
            }
            else {
                struct evt_buffer_drain *evt = evt_take(st, EVT_BUFFER_DRAIN);
                if (evt) {
                    fprintf(stderr, "Multiple BUFFER_DRAINs going at once\n");
                    free(evt);
                }

                evt = malloc(sizeof(struct evt_buffer_drain));
                evt_fill_header(evt, pkt.header.sec, pkt.header.nsec,
                                sizeof(*evt), EVT_BUFFER_DRAIN);
                evt_put(st, evt);
            }
        }

        else if (pkt.header.type == PACKET_SD_CMD_ARG) {
            struct evt_sd_cmd *evt = evt_take(st, EVT_SD_CMD);
            struct pkt_sd_cmd_arg *sd = &pkt.data.sd_cmd_arg;
            if (!evt) {
                evt = malloc(sizeof(struct evt_sd_cmd));
                memset(evt, 0, sizeof(*evt));
                evt_fill_header(evt, pkt.header.sec, pkt.header.nsec,
                                sizeof(*evt), EVT_SD_CMD);
            }

            // Ignore args for CMD55
            if ((evt->num_args || sd->reg>0) && evt->cmd != 0x55) {
                evt->args[evt->num_args++] = sd->val;
            }

            // Register 0 implies this is a CMD.
            else if (sd->reg == 0) {
                if (evt->cmd == 0x55)
                    evt->cmd = 0x80 | (0x3f & sd->val);
                else
                    evt->cmd = 0x3f & sd->val;
            }
            evt_put(st, evt);
        }
        else if (pkt.header.type == PACKET_SD_RESPONSE) {
            struct evt_sd_cmd *evt = evt_take(st, EVT_SD_CMD);
            // Ignore CMD17, as we'll pick it up on the PACKET_SD_DATA packet
            if (evt->cmd == 17) {
                evt_put(st, evt);
            }
            else {
                struct pkt_sd_response *sd = &pkt.data.response;
                if (!evt) {
                    fprintf(stderr, "Couldn't find old EVT_SD_CMD in SD_RESPONSE\n");
                    continue;
                }

                evt->result[evt->num_results++] = sd->byte;
                evt->num_results = htonl(evt->num_results);
                evt->num_args = htonl(evt->num_args);

                evt_fill_end(evt, pkt.header.sec, pkt.header.nsec);
                write(st->out_fd, evt, sizeof(*evt));
                free(evt);
            }
        }

        else if (pkt.header.type == PACKET_SD_DATA) {
            struct evt_sd_cmd *evt = evt_take(st, EVT_SD_CMD);
            struct pkt_sd_data *sd = &pkt.data.sd_data;
            int offset;
            if (!evt) {
                fprintf(stderr, "Couldn't find old SD_EVT_CMD in SD_DATA\n");
                continue;
            }

            for (offset=0; offset<sizeof(sd->data); offset++)
                evt->result[evt->num_results++] = sd->data[offset];

            evt->num_results = htonl(evt->num_results);
            evt->num_args = htonl(evt->num_args);
            evt_fill_end(evt, pkt.header.sec, pkt.header.nsec);
            write(st->out_fd, evt, sizeof(*evt));
            free(evt);
        }

        else {
            printf("Unknown packet type: %s\n", types[pkt.header.type]);
        }
    }

    return ret;
}