* frescan_bwres_negotiate()
*
* negotiate a contract. For that we allocate a reply object and then
- * we enqueue our request in the master's requests queue (which can be
- * local or require a network message)
+ * we enqueue our request in the master's requests queue (if we are in
+ * the master node) or send it to the master through the network.
*/
int frescan_bwres_negotiate(frescan_network_t net,
params.to = FRESCAN_NEG_MASTER_NODE;
params.channel = FRESCAN_NEG_CHANNEL;
-// params.flags = FRESCAN_FP | FRESCAN_ASYNC;
-// params.prio = 8;
+ // NOTE: if we sent the negotiation msgs with fp:
+ // params.flags = FRESCAN_FP | FRESCAN_ASYNC;
+ // params.prio = 8;
+
params.flags = FRESCAN_SS | FRESCAN_ASYNC;
params.ss = the_networks[net].neg_messages_ss_id;
return return_info.error;
}
+
+/**
+ * frescan_bwres_renegotiate()
+ *
+ * renegotiate a contract. For that we allocate a reply object and then
+ * we enqueue our request in the master's requests queue (if we are in
+ * the master node) or send it to the master through the network.
+ */
+
+int frescan_bwres_renegotiate(frescan_network_t net,
+ const frescan_contract_t *contract,
+ frescan_ss_t id)
+{
+ int ret;
+ frescan_robj_id_t reply;
+ frescan_request_id_t request;
+ frescan_neg_return_info_t return_info;
+ uint8_t msg[200];
+ int size;
+ frescan_send_params_t params;
+
+ ret = frescan_replyobject_alloc(&reply, FRESCAN_BWRES_MX_PRIO);
+ if (ret != 0) {
+ ERROR("could not allocate reply object\n");
+ return ret;
+ }
+
+ ret = frescan_request_alloc(&request);
+ if (ret != 0) {
+ ERROR("could not allocate request\n");
+ return ret;
+ }
+
+ ret = frescan_request_set_return_info(request,
+ (void *) &return_info);
+ if (ret != 0) {
+ ERROR("could not set return_info pointer\n");
+ return ret;
+ }
+
+ ret = frescan_request_set_reply(request, reply);
+ if (ret != 0) {
+ ERROR("could not set reply\n");
+ return ret;
+ }
+
+ ret = frescan_request_set_ss(request, id);
+ if (ret != 0) {
+ ERROR("could not set server id\n");
+ return ret;
+ }
+
+ if (the_networks[net].local_node == FRESCAN_NEG_MASTER_NODE) {
+ DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
+ "I am master, renegotiation in local node\n");
+
+ DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
+ "set FRESCAN_RENEGOTIATE type: %d\n",
+ FRESCAN_RENEGOTIATE);
+
+ ret = frescan_request_set_type(request, FRESCAN_RENEGOTIATE);
+ if (ret != 0) {
+ ERROR("could not set type\n");
+ return ret;
+ }
+
+ ret = frescan_request_set_contract(request, contract);
+ if (ret != 0) {
+ ERROR("could not set contract\n");
+ return ret;
+ }
+
+ ret = frescan_request_set_src(request, FRESCAN_NEG_MASTER_NODE);
+ if (ret != 0) {
+ ERROR("could not set src\n");
+ return ret;
+ }
+
+ ret = frescan_requestqueue_enqueue(request);
+ if (ret != 0) {
+ ERROR("could not enqueue the request\n");
+ return ret;
+ }
+ } else {
+ DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
+ "I am slave, renegotiation in master node\n");
+
+ size = frescan_reneg_message_create(msg, request, contract);
+
+ DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
+ "created a reneg message, size: %d\n", size);
+
+ params.net = net;
+ params.to = FRESCAN_NEG_MASTER_NODE;
+ params.channel = FRESCAN_NEG_CHANNEL;
+
+ // NOTE: if we sent the negotiation msgs with fp:
+ // params.flags = FRESCAN_FP | FRESCAN_ASYNC;
+ // params.prio = 8;
+
+ params.flags = FRESCAN_SS | FRESCAN_ASYNC;
+ params.ss = the_networks[net].neg_messages_ss_id;
+
+ DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
+ "send msg to master, net:%u to:%u ss:%u\n",
+ params.net, params.to, params.ss);
+
+ ret = frescan_send(¶ms, msg, size);
+ if (ret != 0) {
+ ERROR("error while sending neg request to master\n");
+ return ret;
+ }
+ }
+
+ DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "wait on reply object\n");
+
+ ret = frescan_replyobject_wait(reply);
+ if (ret != 0) {
+ ERROR("error while waiting on the reply object\n");
+ return ret;
+ }
+
+ ret = frescan_replyobject_free(reply);
+ if (ret != 0) {
+ ERROR("could not free reply object\n");
+ return ret;
+ }
+
+ if (return_info.error) {
+ DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
+ "renegotiation was not accepted, error:%d\n",
+ return_info.error);
+ } else {
+ DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
+ "renegotiation finished succesfully for ss:%d\n",
+ id);
+ }
+
+ ret = frescan_request_free(request);
+ if (ret != 0) {
+ ERROR("could not free request\n");
+ return ret;
+ }
+
+ return return_info.error;
+}
return (int)bytes_written;
}
+int frescan_reneg_message_create(uint8_t *msg,
+ frescan_request_id_t id,
+ const frescan_contract_t *contract)
+{
+ size_t num, bytes_written;
+ uint8_t *tmp = msg;
+
+ DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
+ "creating a renegotiation request message\n");
+
+ *tmp = (uint8_t)FRESCAN_MSG_TYPE_RENEG;
+ tmp++;
+ DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
+ "type: %d (1 byte)\n", FRESCAN_MSG_TYPE_RENEG);
+
+ num = 2;
+ memcpy(tmp, &id, num);
+ tmp = tmp + num;
+ DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
+ "request id: %d (2 bytes)\n", id);
+
+ num = sizeof(frescan_contract_t);
+ memcpy(tmp, contract, num);
+ tmp = tmp + num;
+
+ DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
+ "contract (%d bytes)\n", num);
+
+ // TODO: ADD server id? or look up the label??
+
+ bytes_written = tmp - msg;
+
+ DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
+ "total bytes_written: %d\n", bytes_written);
+
+ return (int)bytes_written;
+}
+
int frescan_message_parse(frescan_network_t net,
const uint8_t *msg,
size_t size,
* frescan_pqueue_create() - creates a priority queue
*/
-static inline frescan_prio_queue_t *frescan_pqueue_create(uint32_t max_prio)
+static inline frescan_prio_queue_t *frescan_pqueue_create(uint32_t max_prio,
+ frescan_network_t net)
{
int ret, prio;
frescan_prio_queue_t *pq; // priority queue
}
pq->max_prio = max_prio;
+ pq->net = net;
ret = sem_init (&pq->sem, 0, 0);
if (ret != 0) {
uint32_t max_prio;
// create transmission fixed priority queue
- queues->tx_fp_queue = frescan_pqueue_create(params->tx_fp_max_prio);
+ queues->tx_fp_queue = frescan_pqueue_create(params->tx_fp_max_prio,
+ params->net);
if (queues->tx_fp_queue == NULL) {
ERROR("could not allocate memory for tx fp queue\n");
max_prio = params->rx_channel_max_prio[i];
}
- queues->rx_channel_queues[i] = frescan_pqueue_create(max_prio);
+ queues->rx_channel_queues[i] = frescan_pqueue_create
+ (max_prio, params->net);
if (queues->rx_channel_queues[i] == NULL) {
ERROR("could not allocate memory for rx pq %d\n", i);
DEBUG(FRESCAN_QUEUES_ENABLE_DEBUG,
"check priority fifo queues (max_prio=%u)\n", pqueue->max_prio);
- // TODO: the lock is currently hardwired to network 0!!!
- FRESCAN_ACQUIRE_LOCK(&the_networks[0].lock);
+ // NOTE: we only acquire the lock if we block because non-blocking
+ // calls are made from a context with no interrupts (when updating
+ // the buffer at 'frescan_hw_buffer_update' which is always called
+ // with interrupts disabled)
+ if (blocking) FRESCAN_ACQUIRE_LOCK(&the_networks[pqueue->net].lock);
for(prio=pqueue->max_prio-1; prio >= 0; prio--) {
if (!list_empty(&pqueue->fifo_queues[prio].fifo_list)) {
}
}
- FRESCAN_RELEASE_LOCK(&the_networks[0].lock);
+ if (blocking) FRESCAN_RELEASE_LOCK(&the_networks[pqueue->net].lock);
DEBUG(FRESCAN_QUEUES_ENABLE_DEBUG, "dequeued prio %u\n", prio);
*packet_prio = prio;