/* * Ouroboros - Copyright (C) 2016 - 2017 * * Protocol Control Information in Shared Memory Map * * Dimitri Staessens * Sander Vrijders * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define OUROBOROS_PREFIX "shm-pci" #include #include #include #include #include #include "shm_pci.h" #include "dt_const.h" #include #include #define PDU_TYPE_SIZE 1 #define QOS_ID_SIZE 1 #define DEFAULT_TTL 60 #define TTL_SIZE 1 #define CHK_SIZE 4 #define BOOT_PATH "/" BOOT_NAME struct { struct dt_const dtc; size_t head_size; size_t tail_size; } pci_info; static void ser_pci_head(uint8_t * head, struct pci * pci) { int offset = 0; uint8_t ttl = DEFAULT_TTL; memcpy(head, &pci->pdu_type, PDU_TYPE_SIZE); offset += PDU_TYPE_SIZE; memcpy(head + offset, &pci->dst_addr, pci_info.dtc.addr_size); offset += pci_info.dtc.addr_size; memcpy(head + offset, &pci->src_addr, pci_info.dtc.addr_size); offset += pci_info.dtc.addr_size; memcpy(head + offset, &pci->dst_cep_id, pci_info.dtc.cep_id_size); offset += pci_info.dtc.cep_id_size; memcpy(head + offset, &pci->src_cep_id, pci_info.dtc.cep_id_size); offset += pci_info.dtc.cep_id_size; memcpy(head + offset, &pci->pdu_length, pci_info.dtc.pdu_length_size); offset += pci_info.dtc.pdu_length_size; memcpy(head + offset, &pci->seqno, pci_info.dtc.seqno_size); offset += pci_info.dtc.seqno_size; memcpy(head + offset, &pci->qos_id, QOS_ID_SIZE); offset += QOS_ID_SIZE; if (pci_info.dtc.has_ttl) memcpy(head + offset, &ttl, TTL_SIZE); } int shm_pci_init(void) { /* read dt constants from the RIB */ if (rib_read(BOOT_PATH "/dt/const/addr_size", &pci_info.dtc.addr_size, sizeof(pci_info.dtc.addr_size)) || rib_read(BOOT_PATH "/dt/const/cep_id_size", &pci_info.dtc.cep_id_size, sizeof(pci_info.dtc.cep_id_size)) || rib_read(BOOT_PATH "/dt/const/seqno_size", &pci_info.dtc.seqno_size, sizeof(pci_info.dtc.seqno_size)) || rib_read(BOOT_PATH "/dt/const/has_ttl", &pci_info.dtc.has_ttl, sizeof(pci_info.dtc.has_ttl)) || rib_read(BOOT_PATH "/dt/const/has_chk", &pci_info.dtc.has_chk, sizeof(pci_info.dtc.has_chk)) || rib_read(BOOT_PATH "/dt/const/min_pdu_size", &pci_info.dtc.min_pdu_size, sizeof(pci_info.dtc.min_pdu_size)) || rib_read(BOOT_PATH "/dt/const/max_pdu_size", &pci_info.dtc.max_pdu_size, sizeof(pci_info.dtc.max_pdu_size))) return -1; pci_info.head_size = PDU_TYPE_SIZE + pci_info.dtc.addr_size * 2 + pci_info.dtc.cep_id_size * 2 + pci_info.dtc.pdu_length_size + pci_info.dtc.seqno_size + QOS_ID_SIZE; if (pci_info.dtc.has_ttl) pci_info.head_size += TTL_SIZE; pci_info.tail_size = pci_info.dtc.has_chk ? CHK_SIZE : 0; return 0; } void shm_pci_fini(void) { return ; } int shm_pci_ser(struct shm_du_buff * sdb, struct pci * pci) { uint8_t * head; uint8_t * tail; head = shm_du_buff_head_alloc(sdb, pci_info.head_size); if (head == NULL) return -1; ser_pci_head(head, pci); if (pci_info.dtc.has_chk) { tail = shm_du_buff_tail_alloc(sdb, pci_info.tail_size); if (tail == NULL) { shm_du_buff_head_release(sdb, pci_info.head_size); return -1; } crc32((uint32_t *) tail, head, tail - head); } return 0; } buffer_t * shm_pci_ser_buf(buffer_t * buf, struct pci * pci) { buffer_t * buffer; if (buf == NULL || pci == NULL) return NULL; buffer = malloc(sizeof(*buffer)); if (buffer == NULL) return NULL; buffer->len = buf->len + pci_info.head_size + pci_info.tail_size; buffer->data = malloc(buffer->len); if (buffer->data == NULL) { free(buffer); return NULL; } ser_pci_head(buffer->data, pci); memcpy(buffer->data + pci_info.head_size, buf->data, buf->len); free(buf->data); if (pci_info.dtc.has_chk) crc32((uint32_t *) (buffer->data + pci_info.head_size + buf->len), buffer->data, pci_info.head_size + buf->len); return buffer; } struct pci * shm_pci_des(struct shm_du_buff * sdb) { uint8_t * head; struct pci * pci; int offset = 0; if (sdb == NULL) return NULL; head = shm_du_buff_head(sdb); pci = malloc(sizeof(*pci)); if (pci == NULL) return NULL; memcpy(&pci->pdu_type, head, PDU_TYPE_SIZE); offset += PDU_TYPE_SIZE; memcpy(&pci->dst_addr, head + offset, pci_info.dtc.addr_size); offset += pci_info.dtc.addr_size; memcpy(&pci->src_addr, head + offset, pci_info.dtc.addr_size); offset += pci_info.dtc.addr_size; memcpy(&pci->dst_cep_id, head + offset, pci_info.dtc.cep_id_size); offset += pci_info.dtc.cep_id_size; memcpy(&pci->src_cep_id, head + offset, pci_info.dtc.cep_id_size); offset += pci_info.dtc.cep_id_size; memcpy(&pci->pdu_length, head + offset, pci_info.dtc.pdu_length_size); offset += pci_info.dtc.pdu_length_size; memcpy(&pci->seqno, head + offset, pci_info.dtc.seqno_size); offset += pci_info.dtc.seqno_size; memcpy(&pci->qos_id, head + offset, QOS_ID_SIZE); offset += QOS_ID_SIZE; pci->has_ttl = pci_info.dtc.has_ttl; if (pci_info.dtc.has_ttl) memcpy(&pci->ttl, head + offset, TTL_SIZE); return pci; } int shm_pci_shrink(struct shm_du_buff * sdb) { if (sdb == NULL) return -1; if (shm_du_buff_head_release(sdb, pci_info.head_size)) { LOG_ERR("Failed to shrink head."); return -1; } if (shm_du_buff_tail_release(sdb, pci_info.tail_size)) { LOG_ERR("Failed to shrink tail."); return -1; } return 0; } int shm_pci_dec_ttl(struct shm_du_buff * sdb) { uint8_t * head; uint8_t * tail; if (pci_info.dtc.has_ttl == false) return 0; head = shm_du_buff_head(sdb); if (head == NULL) return -1; head[pci_info.head_size - TTL_SIZE]--; if (pci_info.dtc.has_chk) { tail = shm_du_buff_tail(sdb); if (tail == NULL) return -1; tail -= CHK_SIZE; crc32((uint32_t *) tail, head, tail - head); } return 0; }