static void server_input_channel_req(int type, u_int32_t seq, void *ctxt) { Channel *c; int id, reply, success = 0; char *rtype; id = packet_get_int(); rtype = packet_get_string(NULL); reply = packet_get_char(); debug("server_input_channel_req: channel %d request %s reply %d", id, rtype, reply); if ((c = channel_lookup(id)) == NULL) packet_disconnect("server_input_channel_req: " "unknown channel %d", id); if (!strcmp(rtype, "*****@*****.**")) { packet_check_eom(); chan_rcvd_eow(c); } else if ((c->type == SSH_CHANNEL_LARVAL || c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0) success = session_input_channel_req(c, rtype); if (reply) { packet_start(success ? SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); packet_put_int(c->remote_id); packet_send(); } free(rtype); }
struct channel *null_test_setup(void) { struct channel *channel; channel = channel_lookup("null"); channel->send(channel, NULL); syslog(LOG_INFO, "loaded null_test module"); return NULL; }
/*---------------------------------------------------------------------------*/ void channel_set_attributes(uint16_t channelno, const struct rimebuf_attrlist attrlist[]) { struct channel *c; c = channel_lookup(channelno); if(c != NULL) { c->attrlist = attrlist; c->hdrsize = chameleon_hdrsize(attrlist); } }
/*---------------------------------------------------------------------------*/ static struct channel * input(void) { const struct packetbuf_attrlist *a; int byteptr, bitptr, len; uint8_t *hdrptr; struct raw_hdr *hdr; struct channel *c; /* The packet has a header that tells us what channel the packet is for. */ hdr = (struct raw_hdr *)packetbuf_dataptr(); packetbuf_hdrreduce(sizeof(struct raw_hdr)); c = channel_lookup(hdr->channel); if(c == NULL) { PRINTF("chameleon-raw: input: channel %d not found\n", hdr->channel); return NULL; } hdrptr = packetbuf_dataptr(); packetbuf_hdrreduce(c->hdrsize); byteptr = bitptr = 0; for(a = c->attrlist; a->type != PACKETBUF_ATTR_NONE; ++a) { PRINTF("%d.%d: unpack_header type %s, len %d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], packetbuf_attr_strings[a->type], a->len); len = (a->len & 0xf8) + ((a->len & 7) ? 8: 0); if(a->type == PACKETBUF_ADDR_SENDER || a->type == PACKETBUF_ADDR_RECEIVER || a->type == PACKETBUF_ADDR_ESENDER || a->type == PACKETBUF_ADDR_ERECEIVER) { const rimeaddr_t addr; memcpy((uint8_t *)&addr, &hdrptr[byteptr], len / 8); PRINTF("%d.%d: unpack_header type %s, addr %d.%d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], packetbuf_attr_strings[a->type], addr.u8[0], addr.u8[1]); packetbuf_set_addr(a->type, &addr); } else { packetbuf_attr_t val = 0; memcpy((uint8_t *)&val, &hdrptr[byteptr], len / 8); packetbuf_set_attr(a->type, val); PRINTF("%d.%d: unpack_header type %s, val %d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], packetbuf_attr_strings[a->type], val); } byteptr += len / 8; } return c; }
ipc_ret_t ipc_put_pkt(uint8_t slave, struct ipc_packet_t *pkt) { uint8_t data; ipc_ret_t result = IPC_RET_OK; uint16_t wait_cnt = PUT_WAIT_CNT; struct hw_channel_t *hw_ch = channel_lookup(slave); if (pkt == NULL || hw_ch == NULL) return IPC_RET_ERROR_BAD_PARAMS; enable(hw_ch); do { data = spi_transfer(IPC_PUT_BYTE); if (!wait_cnt--) { result = IPC_RET_ERROR_PUT_SYNC; goto no_answer; } }while(data != IPC_SYNC_BYTE); /* Wait for ACK */ /* Put packet overhead data */ spi_transfer(pkt->len); spi_transfer(pkt->cmd); spi_transfer(pkt->crc); /* Put packet payload */ for (uint8_t i = 0; i < pkt->len - IPC_PKT_OVERHEAD; i++) spi_transfer(pkt->data[i]); wait_cnt = WAIT_CNT; do { /* TODO: Fix this magic number */ data = spi_transfer(0x10); if (!wait_cnt--) { result = IPC_RET_ERROR_PUT_FINALIZE; goto no_answer; } }while(data != IPC_FINALIZE_BYTE); /* Wait for ACK */ no_answer: disable(hw_ch); return result; }
static int server_input_channel_req(int type, u_int32_t seq, struct ssh *ssh) { Channel *c; int r, success = 0; u_int id; u_char reply; char *rtype = NULL; if ((r = sshpkt_get_u32(ssh, &id)) != 0 || (r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 || (r = sshpkt_get_u8(ssh, &reply)) != 0) goto out; debug("server_input_channel_req: channel %u request %s reply %d", id, rtype, reply); if ((c = channel_lookup(id)) == NULL) ssh_packet_disconnect(ssh, "server_input_channel_req: " "unknown channel %u", id); if (!strcmp(rtype, "*****@*****.**")) { if ((r = sshpkt_get_end(ssh)) != 0) goto out; chan_rcvd_eow(c); } else if ((c->type == SSH_CHANNEL_LARVAL || c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0) success = session_input_channel_req(c, rtype); if (reply && !(c->flags & CHAN_CLOSE_SENT)) { if ((r = sshpkt_start(ssh, success ? SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE)) != 0 || (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; } r = 0; out: if (rtype) free(rtype); return r; }
/*---------------------------------------------------------------------------*/ static struct channel * input(void) { const struct packetbuf_attrlist *a; int byteptr, bitptr, len; uint8_t *hdrptr; struct raw_hdr *hdr; struct channel *c; /* The packet has a header that tells us what channel the packet is for. */ hdr = (struct raw_hdr *)packetbuf_dataptr(); if(packetbuf_hdrreduce(sizeof(struct raw_hdr)) == 0) { PRINTF("chameleon-raw: too short packet\n"); return NULL; } c = channel_lookup((hdr->channel[1] << 8) + hdr->channel[0]); if(c == NULL) { PRINTF("chameleon-raw: input: channel %u not found\n", (hdr->channel[1] << 8) + hdr->channel[0]); return NULL; } hdrptr = packetbuf_dataptr(); if(packetbuf_hdrreduce(c->hdrsize) == 0) { PRINTF("chameleon-raw: too short packet\n"); return NULL; } byteptr = bitptr = 0; for(a = c->attrlist; a->type != PACKETBUF_ATTR_NONE; ++a) { #if CHAMELEON_WITH_MAC_LINK_ADDRESSES if(a->type == PACKETBUF_ADDR_SENDER || a->type == PACKETBUF_ADDR_RECEIVER) { /* Let the link layer handle sender and receiver */ continue; } #endif /* CHAMELEON_WITH_MAC_LINK_ADDRESSES */ PRINTF("%d.%d: unpack_header type %d, len %d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], a->type, a->len); len = (a->len & 0xf8) + ((a->len & 7) ? 8: 0); if(PACKETBUF_IS_ADDR(a->type)) { const rimeaddr_t addr; memcpy((uint8_t *)&addr, &hdrptr[byteptr], len / 8); PRINTF("%d.%d: unpack_header type %d, addr %d.%d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], a->type, addr.u8[0], addr.u8[1]); packetbuf_set_addr(a->type, &addr); } else { packetbuf_attr_t val = 0; memcpy((uint8_t *)&val, &hdrptr[byteptr], len / 8); packetbuf_set_attr(a->type, val); PRINTF("%d.%d: unpack_header type %d, val %d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], a->type, val); } byteptr += len / 8; } return c; }
ipc_ret_t ipc_get_pkt(uint8_t slave, struct ipc_packet_t *pkt) { /* TODO: Handle return values */ volatile uint8_t data; uint8_t buf = IPC_GET_BYTE; uint16_t wait_cnt = WAIT_CNT; struct hw_channel_t *hw_ch = channel_lookup(slave); ipc_ret_t result = IPC_RET_OK; enable(hw_ch); do { data = spi_transfer(buf); if (!wait_cnt--) { printk("Transfer failed! 0x%x\n", data); result = IPC_RET_ERROR_GET_SYNC; goto no_answer; } }while(data != IPC_SYNC_BYTE); /* Wait for ACK */ /* First byte is data length */ uint8_t rx_len = spi_transfer(buf); pkt->len = rx_len; /* Allocate enough bytes for data */ pkt->data = (uint8_t*)malloc(pkt->len - IPC_PKT_OVERHEAD); if (pkt->data == NULL) { result = IPC_RET_ERROR_OUT_OF_MEMORY; goto no_answer; } if (pkt->len == 0) { /* TODO: Add return value */ printk("Len is zero\n"); result = IPC_RET_ERROR_GENERIC; goto no_answer; } /* TODO: Remove duplication of length variable * on slave side. */ data = spi_transfer(buf); rx_len--; pkt->cmd = spi_transfer(buf); rx_len--; pkt->crc = spi_transfer(buf); rx_len--; while(rx_len--) { pkt->data[rx_len] = spi_transfer(buf); /* * This delay is dependant on system * clocks on master and slave. */ _delay_us(8); } /* Synchronize end of transmission */ wait_cnt = WAIT_CNT; do { data = spi_transfer(buf); if (!wait_cnt--) { printk("Finalize failed! Received: 0x%x\n", data); result = IPC_RET_ERROR_GET_FINALIZE; goto no_answer; } }while(data != IPC_FINALIZE_BYTE); /* Wait for ACK */ no_answer: irq_from_slave[slave]--; if (irq_from_slave[slave] < 0) return IPC_RET_ERROR_GENERIC; disable(hw_ch); return result; }