#include "fwp_util.h"
#include "fwp_contract.h"
-#include "fwp_vres.h"
#include "fwp_msg.h"
extern int fwp_client_sockfd;
extern struct sockaddr_un fwp_client_addr;
extern struct sockaddr_un fwp_agent_addr;
+/**< Contract Status */
+typedef enum {
+ FWP_CONT_INVALID = 0,
+ FWP_CONT_REQUESTED = 1,
+ FWP_CONT_REJECTED = 2,
+ FWP_CONT_NEGOTIATED = 3,
+ FWP_CONT_ACCEPTED = 4
+} fwp_contract_status_t;
+
/**
* Negotiates contract for application. Negotiation request is sent to
* fwp agent and then waits for response.
*
* If an error occured it returns negative error code.
*/
-int fwp_contract_negotiate(struct fwp_contract *contract, int *vres_id)
+int fwp_contract_negotiate(struct fwp_contract *contract, fwp_vres_d_t *vresdp)
{
fwp_vres_params_t vparams;
fwp_contract_status_t status;
FWP_DEBUG("status = %d\n", status);
if (status == FWP_CONT_NEGOTIATED) {
FWP_DEBUG("Contract negotiated\n");
- if ((rc = fwp_vres_open(&vparams)) < 0){
+ if ((rc = fwp_vres_create(&vparams, vresdp)) < 0){
return rc;
}
- *vres_id = rc;
return FWP_CONTNEGT_ACCEPTED;
} else {
#ifndef _FWP_CONTRACT_H
#define _FWP_CONTRACT_H
-#include "fwp_msgb.h"
+#include "fwp_vres.h"
/**< Contract negotiation status */
enum fwp_contnegt_status {
FWP_CONTNEGT_RUNNING = 3, /**< for asynchronous negotiations*/
} fwp_contnegt_status_t;
-/**< Contract Status */
-typedef enum {
- FWP_CONT_INVALID = 0,
- FWP_CONT_REQUESTED = 1,
- FWP_CONT_REJECTED = 2,
- FWP_CONT_NEGOTIATED = 3,
- FWP_CONT_ACCEPTED = 4
-} fwp_contract_status_t;
-
-
/**
* FWP contract.
* It is an external representation of contract intented for application
int period_usec; /**< all time units are in microseconds */
} fwp_contract_t;
-int fwp_contract_negotiate (struct fwp_contract *contract, int *vres_id);
-int fwp_contract_cancel(unsigned int vres_id);
+int fwp_contract_negotiate(struct fwp_contract *contract, fwp_vres_d_t *vresdp);
#endif /*_FWP_CONTRACT_H */
struct fwp_endpoint{
fwp_endpoint_type_t type;
fwp_endpoint_id_t id;
- /* struct fwp_vres *vres; */
- /**< id of vres, send endpoint is bound to */
- fwp_vres_id_t vres_id;
+ /**< the vres send endpoint is bound to */
fwp_vres_t *vres;
/**< for send enpoint it contains destination address
* for receive endpoint it is filled with the source address
/**<specific operation options*/
int flags;
fwp_endpoint_status_t status;
- gavl_node_t tree_node;
+ //gavl_node_t tree_node;
+ ul_list_node_t list_node;
} fwp_endpoint_t;
typedef
struct fwp_endpoint_table {
unsigned int nr_endpoints;
- gavl_node_t *endpoint_tree;
+ //gavl_node_t *endpoint_tree;
+ ul_list_head_t endpoint_list;
pthread_mutex_t lock;
} fwp_endpoint_table_t;
static fwp_endpoint_table_t fwp_endpoint_table = {
.nr_endpoints = 0,
.id_counter = 0;
- .endpoint_tree = NULL,
+ //.endpoint_tree = NULL,
+ .endpoint_list = {NULL,NULL},
.lock = PTHREAD_MUTEX_INITIALIZER,
};
-GAVL_CUST_NODE_INT_DEC(_fwp_endpoint_table, fwp_endpoint_table_t, fwp_endpoint_t,
+UL_LIST_CUST_DEC(fwp_endpoint_table, fwp_endpoint_table_t, fwp_contract_endpoint_t,
+ endpoint_list, list_node);
+
+/*GAVL_CUST_NODE_INT_DEC(_fwp_endpoint_table, fwp_endpoint_table_t, fwp_endpoint_t,
fwp_endpoint_id_t , endpoint_tree, tree_node, params.id,
gavl_cmp_int);
{
return _fwp_endpoint_table_find(&fwp_endpoint_table, &epoint_id);
}
+*/
inline int fwp_endpoint_table_insert(fwp_endpoint_t *epoint)
{
int rv;
- /* obtain fwp_vres_table mutex */
+ /* obtain fwp_endpoint_table mutex */
pthread_mutex_lock(&fwp_endpoint_table.lock);
/* set endpoint id */
epoint->id = fwp_endpoint_table.id_counter++;
rv = _fwp_endpoint_table_insert(&fwp_endpoint_table, epoint);
- /* release fwp_vres_table mutex */
+ /* release fwp_endpoint_table mutex */
pthread_mutex_unlock(&fwp_endpoint_table.lock);
return rv;
* On error, negative error code is returned.
*
*/
-int fwp_send_endpoint_create(unsigned int node, unsigned int port)
+fwp_endpoint_t* fwp_send_endpoint_create(unsigned int node, unsigned int port,
+ fwp_endpoint_d_t *epointdp)
{
struct sockaddr_in *addr;
fwp_endpoint_t *epoint;
}
FWP_DEBUG("Send endpoint id=%d created.\n", epoint->id);
- return epoint->id;
+ *epointdp = epoint;
+ return 0;
}
* On error, negative error code is returned.
*
*/
-int fwp_receive_endpoint_create(unsigned int port)
+fwp_endpoint_t fwp_receive_endpoint_create(unsigned int port,
+ fwp_endpoint_d_t *epointdp)
{
struct fwp_endpoint *epoint;
int rv;
rv = fwp_create_inet_socket(port,
(struct sockaddr_in*)epoint->peer.addr);
if (rv < 0) {
- free(epoint);
- return rv;
+ goto err;
}
epoint->sockd = rv;
&rcvbuf_size, sizeof(rcvbuf_size)) == -1) {
perror("Unable to set socket buffer size");
- free(epoint);
- return -1;
+ goto err;
+ //return -1;
}
FWP_DEBUG("Receive endpoint buffer size is set.\n");
if ((rv = fwp_endpoint_table_insert(epoint)) < 0) {
- free(epoint);
- return rv;
+ goto err;
}
FWP_DEBUG("Receive endpoint id=%d created.\n", epoint->id);
- return epoint->id;
+ *epointdp = epoint;
+ return 0;
+err:
+ free(epoint);
+ return rv;
}
*
* \return On success returns 0. On error, negative error code is returned
*/
-int fwp_send_endpoint_bind(unsigned int epoint_id, unsigned int vres_id)
+int fwp_send_endpoint_bind(fwp_endpoint_d_t epointd, fwp_vres_d_t vresd)
{
- fwp_endpoint_t *epoint;
- fwp_vres_t *vres;
+ fwp_endpoint_t *epoint = epointd;
+ fwp_vres_t *vres = vresd;
- if (!(epoint = fwp_endpoint_find(epoint_id)) ||
+ /*if (!(epoint = fwp_endpoint_find(epoint_id)) ||
(epoint->type != FWP_SEND_EPOINT) ||
(epoint->status != FWP_EPOINT_UNBOUND)) {
return (-EINVAL);
(vres->epoint != NULL)) {
return (-EINVAL);
}
-
+ */
/* link epoint-vres mutually */
+ pthread_mutex_lock(&fwp_endpoint_table.lock);
+ if (_fwp_vres_endpoint_bind(vresd, epoint) < 0) {
+ pthread_mutex_unlock(&fwp_endpoint_table.lock);
+ return -EPERM;
+ }
+
+ if (!epoint->vres) { /* if send endpoint is bound */
+ fwp_send_endpoint_unbind(epoint);
+ }
+
epoint->vres = vres;
- vres->epoint = epoint;
- epoint->vres_id = vres_id;
epoint->status = FWP_EPOINT_BOUND;
-
+
+ pthread_mutex_unlock(&fwp_endpoint_table.lock);
return 0;
}
* \return On success returns 0. On error, negative error code is returned
*
*/
-int fwp_send_endpoint_unbind(unsigned int epoint_id)
+int fwp_send_endpoint_unbind(fwp_endpoint_d_t epointd)
{
- fwp_endpoint_t *epoint;
- fwp_vres_t *vres;
-
- if (!(epoint = fwp_endpoint_find(epoint_id)) ||
- (epoint->type != FWP_SEND_EPOINT) ||
- (epoint->status != FWP_EPOINT_UNBOUND)) {
- return (-EINVAL);
- }
+ fwp_endpoint_t *epoint = epointd;
- if (!(vres = fwp_vres_find(vres_id)) ||
- (vres->epoint != NULL)) {
- return (-EINVAL);
- }
-
/* unlink epoint-vres mutually */
- epoint->vres->epoint = vres;
- vres->epoint = epoint;
- epoint->status = FWP_EPOINT_BOUND;
-
-
+ fwp_vres_unbind(epoint->vres);
+ epoint->vres = NULL;
epoint->status = FWP_EPOINT_UNBOUND;
return 0;
-
-
-
#if 0
static struct fwp_endpoint fwp_endpoint_table[FWP_EPOINT_MAX];
static pthread_mutex_t fwp_endpoint_table_lock = PTHREAD_MUTEX_INITIALIZER;
#ifndef _FWP_ENDPOINT_H
#define _FWP_ENDPOINT_H
-#include "fwp_types.h"
#include "fwp_conf.h"
#include "fwp_util.h"
#include "fwp_msgb.h"
+typedef unsigned int fwp_endpoint_id_t;
+
+struct fwp_endpoint;
+typedef struct fwp_endpoint fwp_endpoint_t;
+/* fwp endpoint descriptor type */
+typedef struct fwp_endpoint* fwp_endpoint_d_t;
+
inline int fwp_endpoint_is_valid(unsigned int epoint_id);
inline int fwp_send_endpoint_is(unsigned int epoint_id);
*
* @param[in] msgq Message queue
* @return
- * NULL it there are an error (
+ * NULL if message queue in empty
* else returns pointer to message buffer(msgb)
**/
struct fwp_msgb* fwp_msgq_dequeue(struct fwp_msgq *msgq)
return msgb;
}
+/*
+ * Dequeue all messages from message queue
+ *
+ * @param[in] msgq Message queue
+ * @return
+ * NULL if message queue is empty
+ * else returns pointer to message buffer(msgb)
+ **/
+struct fwp_msgb* fwp_msgq_dequeue_all(struct fwp_msgq *msgq)
+{
+ struct fwp_msgb *msgb;
+
+ while ((msgb = fwp_msgq_dequeue(msgq))) {
+ fwp_msgb_free(msgb);
+ }
+}
int fwp_msgq_enqueue(struct fwp_msgq *msgq, struct fwp_msgb* msgb);
struct fwp_msgb* fwp_msgq_dequeue(struct fwp_msgq *msgq);
+struct fwp_msgb* fwp_msgq_dequeue_all(struct fwp_msgq *msgq);
#endif /* _FWP_MSGQ_H */
#ifndef _FWP_TYPES
+#define _FWP_TYPES
-typedef unsigned int fwp_endpoint_id_t;
-typedef unsigned int fwp_vresid_t;
+//struct fwp_vres;
+//typedef struct fwp_vres* fwp_vres_d_t;
#endif /* _FWP_TYPES */
#include "fwp_util.h"
#include "fwp_vres.h"
-#include "ul_gavlcust.h"
-
static void* fwp_vres_tx_thread(void *_vres);
+
typedef enum {
FWP_VRES_CLOSED = 0 ,
FWP_VRES_CLOSING = 1 ,
int ac_sockd; /**< ac socket descriptor */
fwp_vres_status_t status;
gavl_node_t tree_node;
-} fwp_vres_t;
+};
typedef
struct fwp_vres_table {
static const int prio_to_ac[8] = {2,3,3,2,1,1,0,0};
static const unsigned int ac_to_tos[4] = {224,160,96,64};
-static inline int _fwp_vres_send(unsigned int ac_sockd, struct fwp_msgb* msgb)
+static inline int __fwp_vres_send(unsigned int ac_sockd, struct fwp_msgb* msgb)
{
_fwp_sendto(ac_sockd, msgb->data, msgb->len, 0,
msgb->peer->addr, msgb->peer->addrlen);
return 0;
}
+static inline fwp_vres_t* fwp_vres_find(fwp_vres_id_t vres_id)
+{
+ return _fwp_vres_table_find(&fwp_vres_table, &vres_id);
+}
+
static int fwp_vres_ac_open(fwp_ac_t ac_id)
{
int sockd;
return sockd;
}
-inline fwp_vres_t* fwp_vres_find(fwp_vresid_t vres_id)
-{
- return _fwp_vres_table_find(&fwp_vres_table, &vres_id);
-}
static int fwp_vres_insert(fwp_vres_t *vres)
{
return rv;
}
-int fwp_vres_create(struct fwp_vres_params *params)
+int fwp_vres_create(fwp_vres_params_t *params, fwp_vres_d_t *vresdp)
{
int rv;
- struct fwp_vres *vres;
+ fwp_vres_t *vres;
/* Check for validity of the contract */
goto err;
}
- return vres->params.id;
+/* return vres->params.id; */
+ *vresdp = vres;
+ return 0;
err:
free(vres);
return rv;
}
-int fwp_vres_close(fwp_vresid_t vres_id)
+int fwp_vres_destroy(fwp_vres_d_t vresd)
{
- struct fwp_vres *vres;
+ fwp_vres_t *vres;
+
+ vres = vresd;
- vres = _fwp_vres_table_find(&fwp_vres_table, &vres_id);
+ /* vres = _fwp_vres_table_find(&fwp_vres_table, &vresd);
if (!vres)
- return -EINVAL;
+ return -EINVAL;*/
if ((vres->status != FWP_VRES_OPENED))
return -EPERM;
vres->status = FWP_VRES_CLOSING;
/* unbind endpoint */
- vres->epoint->status = FWP_EPOINT_UNBOUND;
+ fwp_send_endpoint_unbind(vres->epoint);
pthread_cancel(vres->tx_thread);
close(vres->ac_sockd);
- FWP_DEBUG("Vres id %d closed.\n", vres_id);
+ FWP_DEBUG("Vres id %d closed.\n", vres->params.id);
return 0;
}
-int fwp_vres_send(fwp_vres_t *vres, struct fwp_msgb* msgb)
-{
- if (vres->status == FWP_VRES_OPENED) {
- return fwp_msgq_enqueue(&vres->tx_queue, msgb);
- } else
- return -EPERM;
-}
-
-static inline void fwp_vres_free_msgq(struct fwp_msgq *msgq)
-{
- struct fwp_msgb *msgb;
-
- while ((msgb = fwp_msgq_dequeue(msgq))) {
- fwp_msgb_free(msgb);
- }
-}
-
static void fwp_vres_cleanup(void *_vres)
{
struct fwp_vres *vres = (struct fwp_vres*)_vres;
- struct fwp_msgq *msgq = &vres->tx_queue;
- fwp_vres_free_msgq(msgq);
+ fwp_msgq_dequeue_all(&vres->tx_queue);
vres->status = FWP_VRES_CLOSED;
}
while ((curr_budget < budget)&&
(msgb = fwp_msgq_dequeue(msgq))) {
- rc = _fwp_vres_send(ac_sockd, msgb);
+ rc = __fwp_vres_send(ac_sockd, msgb);
if (!(rc < 0)) {
FWP_DEBUG("Message sent through AC%d\n",ac_id);
/* Switch to this in the future
return NULL;
}
-int fwp_vres_endpoint_bind(fwp_vresid_t vres_id,
- struct fwp_endpoint *epoint)
+int _fwp_vres_send(fwp_vres_t vres, struct fwp_msgb* msgb)
{
- fwp_vres_t *vres;
+ if (vres->status == FWP_VRES_OPENED) {
+ return fwp_msgq_enqueue(&vres->tx_queue, msgb);
+ } else
+ return -EPERM;
+}
- if (!(vres = fwp_vres_find(vres_id)))
- return -EINVAL;
- vres->epoint = epoint;
- return 0;
+int _fwp_vres_bind(fwp_vres_t vres, fwp_endpoint_t *epoint)
+{
+ int rv = 0;
+
+ /*if (!(vres = fwp_vres_find(vres_id)))
+ return -EINVAL;*/
+ pthread_mutex_lock(&fwp_vres_table.lock);
+ if (vres->epoint) /*if other endpoint is assigned to vres*/
+ rv = -EPERM;
+ else
+ vres->epoint = epoint;
+ pthread_mutex_unlock(&fwp_vres_table.lock);
+ return rv;
}
-int fwp_vres_endpoint_unbind(fwp_vresid_t vres_id)
+int _fwp_vres_unbind(fwp_vres_t vres)
{
- fwp_vres_t *vres;
-
- if (!(vres = fwp_vres_find(vres_id)))
- return -EINVAL;
vres->epoint = NULL;
/* TODO: consider what to do with pending messages */
/* fwp_vres_free_msgb(vres->tx_queue); */
+
return 0;
}
+
+#endif
#ifndef _FWP_VRES_H
#define _FWP_VRES_H
-#include "fwp_types.h"
#include "fwp_conf.h"
#include "fwp_msgq.h"
#include "fwp_endpoint.h"
+#include "ul_gavlcust.h"
#include <string.h>
+typedef unsigned int fwp_vres_id_t;
+
+struct fwp_vres;
+typedef struct fwp_vres fwp_vres_t;
+typedef struct fwp_vres* fwp_vres_d_t;
+
/**< WMM defines 4 queues */
typedef enum {
FWP_AC_VO = 0,
FWP_AC_BK = 3
} fwp_ac_t;
-
typedef
struct fwp_appcall_id {
unsigned int callid;
/**< all time units are in microseconds */
int period_usec;
/**< STA-unique identifier of vres params assigned by manager*/
- fwp_vresid_t id;
+ fwp_vres_id_t id;
fwp_ac_t ac_id; /**< AC id ~ priority of vres */
} fwp_vres_params_t;
-void fwp_vres_table_init();
-
-int fwp_vres_open(struct fwp_vres_params *params);
-int fwp_vres_close(fwp_vresid_t vresid);
+int fwp_vres_create(fwp_vres_params_t *params, fwp_vres_d_t *vresdp);
+int fwp_vres_destroy(fwp_vres_d_t vresd);
-inline int fwp_vres_endpoint_bind(fwp_vresid_t vresid,
- struct fwp_endpoint *epoint);
-inline int fwp_vres_endpoint_unbind(fwp_vresid_t vresid);
+int _fwp_vres_send(fwp_vres_t *vres, struct fwp_msgb* msgb);
+int _fwp_vres_bind(fwp_vres_t *vres, fwp_endpoint_t *epoint);
+int _fwp_vres_unbind(fwp_vres_t *vres);
#endif /* _FWP_VRES_H */