Cleaned up the use of __packed__. Added a description of the locking order used in chan_capi. Made sure that all parameters used get passed to the 'return_on_no_interface' macro. Added a 'cc_mutex_assert' macro.
This commit is contained in:
parent
9f350c412a
commit
30bc33755b
58
chan_capi.c
58
chan_capi.c
|
@ -78,6 +78,37 @@ LOCAL_USER_DECL;
|
||||||
|
|
||||||
static int usecnt;
|
static int usecnt;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LOCKING RULES
|
||||||
|
* =============
|
||||||
|
*
|
||||||
|
* This channel driver uses several locks. One must be
|
||||||
|
* careful not to reverse the locking order, which will
|
||||||
|
* lead to a so called deadlock. Here is the locking order
|
||||||
|
* that must be followed:
|
||||||
|
*
|
||||||
|
* struct capi_pvt *i;
|
||||||
|
*
|
||||||
|
* 1. cc_mutex_lock(&i->owner->lock); **
|
||||||
|
*
|
||||||
|
* 2. cc_mutex_lock(&i->lock);
|
||||||
|
* 3. cc_mutex_lock(&i->lockB3q);
|
||||||
|
*
|
||||||
|
* 4. cc_mutex_lock(&iflock);
|
||||||
|
* 5. cc_mutex_lock(&contrlock);
|
||||||
|
*
|
||||||
|
* 6. cc_mutex_lock(&messagenumber_lock);
|
||||||
|
* 7. cc_mutex_lock(&usecnt_lock);
|
||||||
|
* 8. cc_mutex_lock(&capi_put_lock);
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* ** the PBX will call the callback functions with
|
||||||
|
* this lock locked. This lock protects the
|
||||||
|
* structure pointed to by 'i->owner'. Also note
|
||||||
|
* that calling some PBX functions will lock
|
||||||
|
* this lock!
|
||||||
|
*/
|
||||||
|
|
||||||
AST_MUTEX_DEFINE_STATIC(messagenumber_lock);
|
AST_MUTEX_DEFINE_STATIC(messagenumber_lock);
|
||||||
AST_MUTEX_DEFINE_STATIC(usecnt_lock);
|
AST_MUTEX_DEFINE_STATIC(usecnt_lock);
|
||||||
AST_MUTEX_DEFINE_STATIC(iflock);
|
AST_MUTEX_DEFINE_STATIC(iflock);
|
||||||
|
@ -112,11 +143,12 @@ static int capi_indicate(struct ast_channel *c, int condition);
|
||||||
extern char *capi_info_string(unsigned int info);
|
extern char *capi_info_string(unsigned int info);
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
#define return_on_no_interface(x) \
|
#define return_on_no_interface(i,PLCI,msg) \
|
||||||
if (!i) { \
|
if (!(i)) { \
|
||||||
cc_verbose(4, 1, "CAPI: %s no interface for PLCI=%#x\n", x, PLCI); \
|
cc_verbose(4, 1, "CAPI: %s no interface for " \
|
||||||
return; \
|
"PLCI=%#x\n", msg, PLCI); \
|
||||||
}
|
return; \
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* command to string function
|
* command to string function
|
||||||
*/
|
*/
|
||||||
|
@ -2340,7 +2372,7 @@ static void capi_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsigned
|
||||||
INFO_RESP_HEADER(&CMSG2, capi_ApplID, HEADER_MSGNUM(CMSG), PLCI);
|
INFO_RESP_HEADER(&CMSG2, capi_ApplID, HEADER_MSGNUM(CMSG), PLCI);
|
||||||
_capi_put_cmsg(&CMSG2);
|
_capi_put_cmsg(&CMSG2);
|
||||||
|
|
||||||
return_on_no_interface("INFO_IND");
|
return_on_no_interface(i,PLCI,"INFO_IND");
|
||||||
|
|
||||||
switch(INFO_IND_INFONUMBER(CMSG)) {
|
switch(INFO_IND_INFONUMBER(CMSG)) {
|
||||||
case 0x0008: /* Cause */
|
case 0x0008: /* Cause */
|
||||||
|
@ -2557,7 +2589,7 @@ static void capi_handle_facility_indication(_cmsg *CMSG, unsigned int PLCI, unsi
|
||||||
FACILITY_RESP_FACILITYRESPONSEPARAMETERS(&CMSG2) = FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG);
|
FACILITY_RESP_FACILITYRESPONSEPARAMETERS(&CMSG2) = FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG);
|
||||||
_capi_put_cmsg(&CMSG2);
|
_capi_put_cmsg(&CMSG2);
|
||||||
|
|
||||||
return_on_no_interface("FACILITY_IND");
|
return_on_no_interface(i,PLCI,"FACILITY_IND");
|
||||||
|
|
||||||
if (FACILITY_IND_FACILITYSELECTOR(CMSG) == FACILITYSELECTOR_LINE_INTERCONNECT) {
|
if (FACILITY_IND_FACILITYSELECTOR(CMSG) == FACILITYSELECTOR_LINE_INTERCONNECT) {
|
||||||
/* line interconnect */
|
/* line interconnect */
|
||||||
|
@ -2690,7 +2722,7 @@ static void capi_handle_data_b3_indication(_cmsg *CMSG, unsigned int PLCI, unsig
|
||||||
DATA_B3_RESP_DATAHANDLE(&CMSG2) = DATA_B3_IND_DATAHANDLE(CMSG);
|
DATA_B3_RESP_DATAHANDLE(&CMSG2) = DATA_B3_IND_DATAHANDLE(CMSG);
|
||||||
_capi_put_cmsg(&CMSG2);
|
_capi_put_cmsg(&CMSG2);
|
||||||
|
|
||||||
return_on_no_interface("DATA_B3_IND");
|
return_on_no_interface(i,PLCI,"DATA_B3_IND");
|
||||||
|
|
||||||
if (i->fFax) {
|
if (i->fFax) {
|
||||||
/* we are in fax-receive and have a file open */
|
/* we are in fax-receive and have a file open */
|
||||||
|
@ -2786,7 +2818,7 @@ static void capi_handle_connect_active_indication(_cmsg *CMSG, unsigned int PLCI
|
||||||
CONNECT_ACTIVE_RESP_PLCI(&CMSG2) = PLCI;
|
CONNECT_ACTIVE_RESP_PLCI(&CMSG2) = PLCI;
|
||||||
_capi_put_cmsg(&CMSG2);
|
_capi_put_cmsg(&CMSG2);
|
||||||
|
|
||||||
return_on_no_interface("CONNECT_ACTIVE_IND");
|
return_on_no_interface(i,PLCI,"CONNECT_ACTIVE_IND");
|
||||||
|
|
||||||
if (i->state == CAPI_STATE_DISCONNECTING) {
|
if (i->state == CAPI_STATE_DISCONNECTING) {
|
||||||
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: CONNECT_ACTIVE in DISCONNECTING.\n",
|
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: CONNECT_ACTIVE in DISCONNECTING.\n",
|
||||||
|
@ -2835,7 +2867,7 @@ static void capi_handle_connect_b3_active_indication(_cmsg *CMSG, unsigned int P
|
||||||
CONNECT_B3_ACTIVE_RESP_NCCI(&CMSG2) = NCCI;
|
CONNECT_B3_ACTIVE_RESP_NCCI(&CMSG2) = NCCI;
|
||||||
_capi_put_cmsg(&CMSG2);
|
_capi_put_cmsg(&CMSG2);
|
||||||
|
|
||||||
return_on_no_interface("CONNECT_ACTIVE_B3_IND");
|
return_on_no_interface(i,PLCI,"CONNECT_ACTIVE_B3_IND");
|
||||||
|
|
||||||
cc_mutex_lock(&contrlock);
|
cc_mutex_lock(&contrlock);
|
||||||
if (i->controller > 0) {
|
if (i->controller > 0) {
|
||||||
|
@ -2884,7 +2916,7 @@ static void capi_handle_disconnect_b3_indication(_cmsg *CMSG, unsigned int PLCI,
|
||||||
DISCONNECT_B3_RESP_NCCI(&CMSG2) = NCCI;
|
DISCONNECT_B3_RESP_NCCI(&CMSG2) = NCCI;
|
||||||
_capi_put_cmsg(&CMSG2);
|
_capi_put_cmsg(&CMSG2);
|
||||||
|
|
||||||
return_on_no_interface("DISCONNECT_B3_IND");
|
return_on_no_interface(i,PLCI,"DISCONNECT_B3_IND");
|
||||||
|
|
||||||
i->reasonb3 = DISCONNECT_B3_IND_REASON_B3(CMSG);
|
i->reasonb3 = DISCONNECT_B3_IND_REASON_B3(CMSG);
|
||||||
i->NCCI = 0;
|
i->NCCI = 0;
|
||||||
|
@ -2939,7 +2971,7 @@ static void capi_handle_connect_b3_indication(_cmsg *CMSG, unsigned int PLCI, un
|
||||||
CONNECT_B3_RESP_REJECT(&CMSG2) = 0;
|
CONNECT_B3_RESP_REJECT(&CMSG2) = 0;
|
||||||
_capi_put_cmsg(&CMSG2);
|
_capi_put_cmsg(&CMSG2);
|
||||||
|
|
||||||
return_on_no_interface("CONNECT_B3_IND");
|
return_on_no_interface(i,PLCI,"CONNECT_B3_IND");
|
||||||
|
|
||||||
i->NCCI = NCCI;
|
i->NCCI = NCCI;
|
||||||
|
|
||||||
|
@ -2961,7 +2993,7 @@ static void capi_handle_disconnect_indication(_cmsg *CMSG, unsigned int PLCI, un
|
||||||
|
|
||||||
show_capi_info(DISCONNECT_IND_REASON(CMSG));
|
show_capi_info(DISCONNECT_IND_REASON(CMSG));
|
||||||
|
|
||||||
return_on_no_interface("DISCONNECT_IND");
|
return_on_no_interface(i,PLCI,"DISCONNECT_IND");
|
||||||
|
|
||||||
state = i->state;
|
state = i->state;
|
||||||
i->state = CAPI_STATE_DISCONNECTED;
|
i->state = CAPI_STATE_DISCONNECTED;
|
||||||
|
|
25
chan_capi.h
25
chan_capi.h
|
@ -81,21 +81,26 @@ static inline unsigned short read_capi_dword(void *m)
|
||||||
*/
|
*/
|
||||||
#define cc_mutex_lock(x) ast_mutex_lock(x)
|
#define cc_mutex_lock(x) ast_mutex_lock(x)
|
||||||
#define cc_mutex_unlock(x) ast_mutex_unlock(x)
|
#define cc_mutex_unlock(x) ast_mutex_unlock(x)
|
||||||
|
#define cc_mutex_assert(x,what)
|
||||||
|
#define MA_OWNED 0x01
|
||||||
|
#define MA_NOTOWNED 0x02
|
||||||
|
#define MA_RECURSED 0x04
|
||||||
|
#define MA_NOTRECURSED 0x08
|
||||||
#define cc_log(x...) ast_log(x)
|
#define cc_log(x...) ast_log(x)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* definitions for compatibility with older versions of ast*
|
* definitions for compatibility with older versions of ast*
|
||||||
*/
|
*/
|
||||||
#ifdef CC_AST_HAVE_TECH_PVT
|
#ifdef CC_AST_HAVE_TECH_PVT
|
||||||
#define CC_CHANNEL_PVT(c) c->tech_pvt
|
#define CC_CHANNEL_PVT(c) (c)->tech_pvt
|
||||||
#else
|
#else
|
||||||
#define CC_CHANNEL_PVT(c) c->pvt->pvt
|
#define CC_CHANNEL_PVT(c) (c)->pvt->pvt
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CC_AST_HAS_BRIDGED_CHANNEL
|
#ifdef CC_AST_HAS_BRIDGED_CHANNEL
|
||||||
#define CC_AST_BRIDGED_CHANNEL(x) ast_bridged_channel(x)
|
#define CC_AST_BRIDGED_CHANNEL(x) ast_bridged_channel(x)
|
||||||
#else
|
#else
|
||||||
#define CC_AST_BRIDGED_CHANNEL(x) x->bridge
|
#define CC_AST_BRIDGED_CHANNEL(x) (x)->bridge
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CC_AST_HAS_BRIDGE_RESULT
|
#ifdef CC_AST_HAS_BRIDGE_RESULT
|
||||||
|
@ -128,12 +133,14 @@ static inline unsigned short read_capi_dword(void *m)
|
||||||
#define FAX_BINARY_FILE_TRANSFER_FORMAT 7
|
#define FAX_BINARY_FILE_TRANSFER_FORMAT 7
|
||||||
|
|
||||||
/* Fax struct */
|
/* Fax struct */
|
||||||
typedef struct fax3proto3 {
|
struct fax3proto3 {
|
||||||
unsigned char len;
|
unsigned char len;
|
||||||
unsigned short resolution __attribute__ ((packed));
|
unsigned short resolution;
|
||||||
unsigned short format __attribute__ ((packed));
|
unsigned short format;
|
||||||
unsigned char Infos[100] __attribute__ ((packed));
|
unsigned char Infos[100];
|
||||||
} B3_PROTO_FAXG3;
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
|
typedef struct fax3proto3 B3_PROTO_FAXG3;
|
||||||
|
|
||||||
/* duration in ms for sending and detecting dtmfs */
|
/* duration in ms for sending and detecting dtmfs */
|
||||||
#define CAPI_DTMF_DURATION 0x40
|
#define CAPI_DTMF_DURATION 0x40
|
||||||
|
@ -343,7 +350,7 @@ struct cc_capi_profile {
|
||||||
unsigned int b3protocols;
|
unsigned int b3protocols;
|
||||||
unsigned int reserved3[6];
|
unsigned int reserved3[6];
|
||||||
unsigned int manufacturer[5];
|
unsigned int manufacturer[5];
|
||||||
};
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
struct cc_capi_conf {
|
struct cc_capi_conf {
|
||||||
char name[CAPI_MAX_STRING];
|
char name[CAPI_MAX_STRING];
|
||||||
|
|
Loading…
Reference in New Issue