Ejemplo n.º 1
0
bool serial_handler_event_send(serial_evt_t* evt)
{
    if (fifo_is_full(&tx_fifo))
    {
        return false;
    }

    enable_pin_listener(false);
    NVIC_DisableIRQ(SPI1_TWI1_IRQn); /* critical section */

    serial_data_t raw_data;
    raw_data.status_byte = 0;
    memcpy(raw_data.buffer, evt, evt->length + 1);
    fifo_push(&tx_fifo, &raw_data);

    if (fifo_is_full(&rx_fifo))
    {
        enable_pin_listener(true);
        serial_state = SERIAL_STATE_WAIT_FOR_QUEUE;
    }
    else if (serial_state == SERIAL_STATE_IDLE)
    {
        do_transmit();
    }

    NVIC_EnableIRQ(SPI1_TWI1_IRQn); /* critical section complete */
    return true;
}
Ejemplo n.º 2
0
bool serial_handler_command_get(serial_cmd_t* cmd)
{
    /* want to do this without being pre-empted, as there's a potential
    race condition */
    NVIC_DisableIRQ(SPI1_TWI1_IRQn);
    enable_pin_listener(false);
    serial_data_t temp;
    if (fifo_pop(&rx_fifo, &temp) != NRF_SUCCESS)
    {
        enable_pin_listener(true);
        NVIC_EnableIRQ(SPI1_TWI1_IRQn);
        return false;
    }
    if (temp.buffer[SERIAL_LENGTH_POS] > 0)
    {
        memcpy(cmd, temp.buffer, temp.buffer[SERIAL_LENGTH_POS] + 1);
    }


    /* just made room in the queue */
    if (serial_state == SERIAL_STATE_WAIT_FOR_QUEUE)
    {
        /* would have race condition here with several irq contexts */
        do_transmit();
    }
    else if (serial_state == SERIAL_STATE_IDLE)
    {
        /* only want GPIOTE IRQ in IDLE */
        enable_pin_listener(true);
    }

    NVIC_EnableIRQ(SPI1_TWI1_IRQn);
    return true;
}
Ejemplo n.º 3
0
/**
 * We can now transmit a message to NAMESTORE. Do it.
 *
 * @param cls the 'struct GNUNET_NAMESTORE_Handle'
 * @param size number of bytes we can transmit
 * @param buf where to copy the messages
 * @return number of bytes copied into buf
 */
static size_t
transmit_message_to_namestore (void *cls, size_t size, void *buf)
{
  struct GNUNET_NAMESTORE_Handle *h = cls;
  struct PendingMessage *p;
  size_t ret;
  char *cbuf;

  h->th = NULL;
  if ((size == 0) || (buf == NULL))
  {
    force_reconnect (h);
    return 0;
  }
  ret = 0;
  cbuf = buf;
  while ((NULL != (p = h->pending_head)) && (p->size <= size))
  {
    memcpy (&cbuf[ret], &p[1], p->size);
    ret += p->size;
    size -= p->size;
    GNUNET_CONTAINER_DLL_remove (h->pending_head, h->pending_tail, p);
    if (GNUNET_YES == p->is_init)
      GNUNET_CLIENT_receive (h->client, &process_namestore_message, h,
                             GNUNET_TIME_UNIT_FOREVER_REL);
    GNUNET_free (p);
  }
  do_transmit (h);
  return ret;
}
Ejemplo n.º 4
0
/**
* @brief SPI event handler, from SPI driver
*/
void spi_event_handler(spi_slave_evt_t evt)
{
    switch (evt.evt_type)
    {
        case SPI_SLAVE_BUFFERS_SET_DONE:
            if (has_pending_tx)
            {
                NRF_GPIO->OUTCLR = (1 << PIN_RDYN);
            }
            has_pending_tx = false;
            break;

        case SPI_SLAVE_XFER_DONE:
            NRF_GPIO->OUTSET = (1 << PIN_RDYN);
            nrf_gpio_pin_set(1);
            nrf_gpio_pin_clear(1);
            /* handle incoming */
            if (rx_buffer.buffer[SERIAL_LENGTH_POS] > 0)
            {
                if (fifo_push(&rx_fifo, &rx_buffer) == NRF_SUCCESS)
                {

                    /* notify ACI handler */
                    async_event_t async_evt;
                    async_evt.callback.generic = mesh_aci_command_check;
                    async_evt.type = EVENT_TYPE_GENERIC;
                    event_handler_push(&async_evt);
                }
                else
                {
                    APP_ERROR_CHECK(NRF_ERROR_NO_MEM);
                }
            }

            if (fifo_is_empty(&tx_fifo))
            {
                serial_state = SERIAL_STATE_IDLE;
                prepare_rx();
                enable_pin_listener(true);
            }
            else if (fifo_is_full(&rx_fifo))
            {
                prepare_rx();
                serial_state = SERIAL_STATE_WAIT_FOR_QUEUE;
            }
            else
            {
                do_transmit();
            }

            break;

        default:
            /* no implementation necessary */
            break;
    }
}
Ejemplo n.º 5
0
/**
 * Get a result for a particular key from the namestore.  The processor
 * will only be called once.  
 *
 * @param h handle to the namestore
 * @param zone zone to look up a record from
 * @param name name to look up
 * @param record_type desired record type, 0 for all
 * @param proc function to call on the matching records, or with
 *        NULL (rd_count == 0) if there are no matching records
 * @param proc_cls closure for proc
 * @return a handle that can be used to
 *         cancel
 */
struct GNUNET_NAMESTORE_QueueEntry *
GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h, 
			      const struct GNUNET_CRYPTO_ShortHashCode *zone,
			      const char *name,
			      uint32_t record_type,
			      GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls)
{
  struct GNUNET_NAMESTORE_QueueEntry *qe;
  struct PendingMessage *pe;
  size_t msg_size = 0;
  size_t name_len = 0;
  uint32_t rid = 0;

  GNUNET_assert (NULL != h);
  GNUNET_assert (NULL != zone);
  GNUNET_assert (NULL != name);

  name_len = strlen (name) + 1;
  if ((name_len == 0) || (name_len > 256))
  {
    GNUNET_break (0);
    return NULL;
  }

  rid = get_op_id(h);
  qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
  qe->nsh = h;
  qe->proc = proc;
  qe->proc_cls = proc_cls;
  qe->op_id = rid;
  GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe);

  /* set msg_size*/
  msg_size = sizeof (struct LookupNameMessage) + name_len;
  pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);

  /* create msg here */
  struct LookupNameMessage * msg;
  pe->size = msg_size;
  pe->is_init = GNUNET_NO;
  msg = (struct LookupNameMessage *) &pe[1];
  msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME);
  msg->gns_header.header.size = htons (msg_size);
  msg->gns_header.r_id = htonl (rid);
  msg->record_type = htonl (record_type);
  msg->name_len = htonl (name_len);
  msg->zone = *zone;
  memcpy (&msg[1], name, name_len);

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s'\n", "NAMESTORE_LOOKUP_NAME", name);

  /* transmit message */
  GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
  do_transmit(h);

  return qe;
}
Ejemplo n.º 6
0
/**
 * Look for an existing PKEY delegation record for a given public key.
 * Returns at most one result to the processor.
 *
 * @param h handle to the namestore
 * @param zone hash of public key of the zone to look up in, never NULL
 * @param value_zone hash of the public key of the target zone (value), never NULL
 * @param proc function to call on the matching records, or with
 *        NULL (rd_count == 0) if there are no matching records
 * @param proc_cls closure for proc
 * @return a handle that can be used to
 *         cancel
 */
struct GNUNET_NAMESTORE_QueueEntry *
GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h,
                               const struct GNUNET_CRYPTO_ShortHashCode *zone,
                               const struct GNUNET_CRYPTO_ShortHashCode *value_zone,
                               GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls)
{
  struct GNUNET_NAMESTORE_QueueEntry *qe;
  struct PendingMessage *pe;
  size_t msg_size = 0;
  uint32_t rid = 0;

  GNUNET_assert (NULL != h);
  GNUNET_assert (NULL != zone);
  GNUNET_assert (NULL != value_zone);

  rid = get_op_id(h);
  qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
  qe->nsh = h;
  qe->proc = proc;
  qe->proc_cls = proc_cls;
  qe->op_id = rid;
  GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe);

  /* set msg_size*/
  msg_size = sizeof (struct ZoneToNameMessage);
  pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);

  /* create msg here */
  struct ZoneToNameMessage * msg;
  pe->size = msg_size;
  pe->is_init = GNUNET_NO;
  msg = (struct ZoneToNameMessage *) &pe[1];
  msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME);
  msg->gns_header.header.size = htons (msg_size);
  msg->gns_header.r_id = htonl (rid);
  msg->zone = *zone;
  msg->value_zone = *value_zone;

  char * z_tmp = GNUNET_strdup (GNUNET_short_h2s (zone));
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for zone `%s' in zone `%s'\n",
      "NAMESTORE_ZONE_TO_NAME",
      z_tmp,
      GNUNET_short_h2s (value_zone));
  GNUNET_free (z_tmp);

  /* transmit message */
  GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
  do_transmit(h);

  return qe;
}
Ejemplo n.º 7
0
/**
* @brief IRQ handler for treating incoming SPI message. The master will not
*   start sending before we lower the RDYN pin.
*/
void GPIOTE_IRQHandler(void)
{
    NRF_GPIO->OUTSET = (1 << 2);
    if (NRF_GPIOTE->EVENTS_IN[SERIAL_REQN_GPIOTE_CH] && serial_state == SERIAL_STATE_IDLE)
    {
        
        NRF_GPIO->OUTSET = (1 << 3);
        if (fifo_is_full(&rx_fifo))
        {
            /* wait until the application pops an event off the rx queue */
            serial_state = SERIAL_STATE_WAIT_FOR_QUEUE;
        }
        else
        {
            do_transmit();
        }
        NRF_GPIO->OUTCLR = (1 << 3);
    }
    NRF_GPIOTE->EVENTS_IN[SERIAL_REQN_GPIOTE_CH] = 0;
    NRF_GPIO->OUTCLR = (1 << 2);
}
Ejemplo n.º 8
0
/**
 * Stops iteration and releases the namestore handle for further calls.
 *
 * @param it the iterator
 */
void
GNUNET_NAMESTORE_zone_iteration_stop (struct GNUNET_NAMESTORE_ZoneIterator *it)
{
  GNUNET_assert (NULL != it);
  struct PendingMessage *pe;
  size_t msg_size = 0;
  struct GNUNET_NAMESTORE_Handle *h = it->h;
  struct GNUNET_NAMESTORE_ZoneIterator *tmp = it->h->z_head;

  while (tmp != NULL)
  {
    if (tmp == it)
      break;
    tmp = tmp->next;
  }
  GNUNET_assert (NULL != tmp);

  /* set msg_size*/
  msg_size = sizeof (struct ZoneIterationStopMessage);
  pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);

  /* create msg here */
  struct ZoneIterationStopMessage * msg;
  pe->size = msg_size;
  pe->is_init = GNUNET_NO;
  msg = (struct ZoneIterationStopMessage *) &pe[1];
  msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP);
  msg->gns_header.header.size = htons (msg_size);
  msg->gns_header.r_id = htonl (it->op_id);

  if (GNUNET_YES == it->has_zone)
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for zone `%s'\n", "ZONE_ITERATION_STOP", GNUNET_short_h2s(&it->zone));
  else
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for all zones\n", "ZONE_ITERATION_STOP");

  /* transmit message */
  GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
  do_transmit(h);
}
Ejemplo n.º 9
0
/**
 * Reconnect to namestore service.
 *
 * @param h the handle to the namestore service
 */
static void
reconnect (struct GNUNET_NAMESTORE_Handle *h)
{
  struct PendingMessage *p;
  struct StartMessage *init;

  GNUNET_assert (NULL == h->client);
  h->client = GNUNET_CLIENT_connect ("namestore", h->cfg);
  GNUNET_assert (NULL != h->client);

  if ((NULL == (p = h->pending_head)) || (GNUNET_YES != p->is_init))
  {
    p = GNUNET_malloc (sizeof (struct PendingMessage) +
                       sizeof (struct StartMessage));
    p->size = sizeof (struct StartMessage);
    p->is_init = GNUNET_YES;
    init = (struct StartMessage *) &p[1];
    init->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_START);
    init->header.size = htons (sizeof (struct StartMessage));
    GNUNET_CONTAINER_DLL_insert (h->pending_head, h->pending_tail, p);
  }
  do_transmit (h);
}
Ejemplo n.º 10
0
/**
 * Store an item in the namestore.  If the item is already present,
 * the expiration time is updated to the max of the existing time and
 * the new time.  This API is used when we cache signatures from other
 * authorities.
 *
 * @param h handle to the namestore
 * @param zone_key public key of the zone
 * @param name name that is being mapped (at most 255 characters long)
 * @param freshness when does the corresponding block in the DHT expire (until
 *               when should we never do a DHT lookup for the same name again)?
 * @param rd_count number of entries in 'rd' array
 * @param rd array of records with data to store
 * @param signature signature for all the records in the zone under the given name
 * @param cont continuation to call when done
 * @param cont_cls closure for cont
 * @return handle to abort the request
 */
struct GNUNET_NAMESTORE_QueueEntry *
GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h,
			     const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
			     const char *name,
			     struct GNUNET_TIME_Absolute freshness,
			     unsigned int rd_count,
			     const struct GNUNET_NAMESTORE_RecordData *rd,
			     const struct GNUNET_CRYPTO_RsaSignature *signature,
			     GNUNET_NAMESTORE_ContinuationWithStatus cont,
			     void *cont_cls)
{
  struct GNUNET_NAMESTORE_QueueEntry *qe;
  struct PendingMessage *pe;

  /* pointer to elements */
  char * rd_tmp;
  char * name_tmp;

  size_t msg_size = 0;
  size_t name_len = 0;
  size_t rd_ser_len = 0;
  uint32_t rid = 0;

  GNUNET_assert (NULL != h);
  GNUNET_assert (NULL != zone_key);
  GNUNET_assert (NULL != name);
  GNUNET_assert (NULL != rd);
  GNUNET_assert (NULL != signature);

  name_len = strlen(name) + 1;
  if (name_len > 256)
  {
    GNUNET_break (0);
    return NULL;
  }

  rid = get_op_id(h);
  qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
  qe->nsh = h;
  qe->cont = cont;
  qe->cont_cls = cont_cls;
  qe->op_id = rid;
  GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe);

  /* set msg_size*/
  rd_ser_len = GNUNET_NAMESTORE_records_get_size(rd_count, rd);
  char rd_ser[rd_ser_len];
  GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser);

  struct RecordPutMessage * msg;
  msg_size = sizeof (struct RecordPutMessage) + name_len  + rd_ser_len;

  /* create msg here */
  pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
  pe->size = msg_size;
  pe->is_init = GNUNET_NO;
  msg = (struct RecordPutMessage *) &pe[1];
  name_tmp = (char *) &msg[1];
  rd_tmp = &name_tmp[name_len];

  msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT);
  msg->gns_header.header.size = htons (msg_size);
  msg->gns_header.r_id = htonl (rid);
  msg->signature = *signature;
  msg->name_len = htons (name_len);
  msg->expire = GNUNET_TIME_absolute_hton (freshness);
  msg->rd_len = htons (rd_ser_len);
  msg->rd_count = htons (rd_count);

  msg->public_key = *zone_key;
  memcpy (name_tmp, name, name_len);
  memcpy (rd_tmp, rd_ser, rd_ser_len);

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s' with size %u\n", "NAMESTORE_RECORD_PUT", name, msg_size);

  GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
  do_transmit(h);

  return qe;
}
Ejemplo n.º 11
0
/**
 * Starts a new zone iteration (used to periodically PUT all of our
 * records into our DHT). This MUST lock the GNUNET_NAMESTORE_Handle
 * for any other calls than GNUNET_NAMESTORE_zone_iterator_next and
 * GNUNET_NAMESTORE_zone_iteration_stop.  "proc" will be called once
 * immediately, and then again after
 * "GNUNET_NAMESTORE_zone_iterator_next" is invoked.
 *
 * @param h handle to the namestore
 * @param zone zone to access, NULL for all zones
 * @param must_have_flags flags that must be set for the record to be returned
 * @param must_not_have_flags flags that must NOT be set for the record to be returned
 * @param proc function to call on each name from the zone; it
 *        will be called repeatedly with a value (if available)
 *        and always once at the end with a name of NULL.
 * @param proc_cls closure for proc
 * @return an iterator handle to use for iteration
 */
struct GNUNET_NAMESTORE_ZoneIterator *
GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h,
				       const struct GNUNET_CRYPTO_ShortHashCode *zone,
				       enum GNUNET_NAMESTORE_RecordFlags must_have_flags,
				       enum GNUNET_NAMESTORE_RecordFlags must_not_have_flags,
				       GNUNET_NAMESTORE_RecordProcessor proc,
				       void *proc_cls)
{
  struct GNUNET_NAMESTORE_ZoneIterator *it;
  struct PendingMessage *pe;
  size_t msg_size = 0;
  uint32_t rid = 0;

  GNUNET_assert (NULL != h);


  rid = get_op_id(h);
  it = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_ZoneIterator));
  it->h = h;
  it->proc = proc;
  it->proc_cls = proc_cls;
  it->op_id = rid;

  if (NULL != zone)
  {
    it->zone = *zone;
    it->has_zone = GNUNET_YES;
  }
  else
  {
    memset (&it->zone, '\0', sizeof (it->zone));
    it->has_zone = GNUNET_NO;
  }
  GNUNET_CONTAINER_DLL_insert_tail(h->z_head, h->z_tail, it);

  /* set msg_size*/
  msg_size = sizeof (struct ZoneIterationStartMessage);
  pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);

  /* create msg here */
  struct ZoneIterationStartMessage * msg;
  pe->size = msg_size;
  pe->is_init = GNUNET_NO;
  msg = (struct ZoneIterationStartMessage *) &pe[1];
  msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START);
  msg->gns_header.header.size = htons (msg_size);
  msg->gns_header.r_id = htonl (rid);
  if (NULL != zone)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for zone `%s'\n", "ZONE_ITERATION_START", GNUNET_short_h2s(zone));
    msg->zone = *zone;
  }
  else
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for all zones\n", "ZONE_ITERATION_START");
    memset (&msg->zone, '\0', sizeof (msg->zone));
  }
  msg->must_have_flags = ntohs (must_have_flags);
  msg->must_not_have_flags = ntohs (must_not_have_flags);



  /* transmit message */
  GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
  do_transmit(h);

  return it;
}
Ejemplo n.º 12
0
/**
 * Explicitly remove some content from the database.  The
 * "cont"inuation will be called with status "GNUNET_OK" if content
 * was removed, "GNUNET_NO" if no matching entry was found and
 * "GNUNET_SYSERR" on all other types of errors.
 * This API is used by the authority of a zone.
 *
 * @param h handle to the namestore
 * @param pkey private key of the zone
 * @param name name that is being mapped (at most 255 characters long)
 * @param rd record data, remove specific record,  NULL to remove the name and all records
 * @param cont continuation to call when done
 * @param cont_cls closure for cont
 * @return handle to abort the request
 */
struct GNUNET_NAMESTORE_QueueEntry *
GNUNET_NAMESTORE_record_remove (struct GNUNET_NAMESTORE_Handle *h,
				const struct GNUNET_CRYPTO_RsaPrivateKey *pkey,
				const char *name,
				const struct GNUNET_NAMESTORE_RecordData *rd,
				GNUNET_NAMESTORE_ContinuationWithStatus cont,
				void *cont_cls)
{
  struct GNUNET_NAMESTORE_QueueEntry *qe;
  struct PendingMessage *pe;
  char *pkey_tmp;
  char *rd_tmp;
  char *name_tmp;
  size_t rd_ser_len = 0;
  size_t msg_size = 0;
  size_t name_len = 0;
  size_t key_len = 0;
  uint32_t rid = 0;
  uint16_t rd_count = 1;

  GNUNET_assert (NULL != h);

  rid = get_op_id(h);
  qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
  qe->nsh = h;
  qe->cont = cont;
  qe->cont_cls = cont_cls;
  qe->op_id = rid;
  GNUNET_CONTAINER_DLL_insert_tail(h->op_head, h->op_tail, qe);

  /* set msg_size*/
  struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded * pkey_enc = GNUNET_CRYPTO_rsa_encode_key (pkey);
  GNUNET_assert (pkey_enc != NULL);
  key_len = ntohs (pkey_enc->len);

  if (NULL == rd)
    rd_count = 0;
  else
    rd_count = 1;
  rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
  char rd_ser[rd_ser_len];
  GNUNET_NAMESTORE_records_serialize (rd_count, rd, rd_ser_len, rd_ser);

  name_len = strlen (name) + 1;

  struct RecordRemoveMessage * msg;
  msg_size = sizeof (struct RecordRemoveMessage) + key_len + name_len + rd_ser_len;

  /* create msg here */
  pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
  pe->size = msg_size;
  pe->is_init = GNUNET_NO;
  msg = (struct RecordRemoveMessage *) &pe[1];

  pkey_tmp = (char *) &msg[1];
  name_tmp = &pkey_tmp[key_len];
  rd_tmp = &name_tmp[name_len];

  msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE);
  msg->gns_header.header.size = htons (msg_size);
  msg->gns_header.r_id = htonl (rid);
  msg->name_len = htons (name_len);
  msg->rd_len = htons (rd_ser_len);
  msg->rd_count = htons (rd_count);
  msg->pkey_len = htons (key_len);
  memcpy (pkey_tmp, pkey_enc, key_len);
  memcpy (name_tmp, name, name_len);
  memcpy (rd_tmp, rd_ser, rd_ser_len);

  GNUNET_free (pkey_enc);

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s' with size %u\n", "NAMESTORE_RECORD_REMOVE", name, msg_size);

  GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
  do_transmit(h);
  return qe;
}
void SWI1_IRQHandler(void)
{
    do_transmit(NULL);
}