Index: channels/chan_mgcp.c =================================================================== --- channels/chan_mgcp.c (revision 188382) +++ channels/chan_mgcp.c (working copy) @@ -223,7 +223,7 @@ static struct io_context *io; /*! The private structures of the mgcp channels are linked for ! selecting outgoing channels */ - + #define MGCP_MAX_HEADERS 64 #define MGCP_MAX_LINES 64 @@ -271,20 +271,20 @@ #define SUB_ALT 1 struct mgcp_subchannel { - /*! subchannel magic string. - Needed to prove that any subchannel pointer passed by asterisk + /*! subchannel magic string. + Needed to prove that any subchannel pointer passed by asterisk really points to a valid subchannel memory area. Ugly.. But serves the purpose for the time being. */ #define MGCP_SUBCHANNEL_MAGIC "!978!" - char magic[6]; + char magic[6]; ast_mutex_t lock; int id; struct ast_channel *owner; struct mgcp_endpoint *parent; struct ast_rtp *rtp; struct sockaddr_in tmpdest; - char txident[80]; /*! \todo FIXME txident is replaced by rqnt_ident in endpoint. + char txident[80]; /*! \todo FIXME txident is replaced by rqnt_ident in endpoint. This should be obsoleted */ char cxident[80]; char callid[80]; @@ -304,6 +304,33 @@ #define TYPE_TRUNK 1 #define TYPE_LINE 2 +static struct rfc3149_xml_post_map{ + char *deck; + char *card; + int action; + struct ast_variable *vars; + struct rfc3149_xml_functions *func; + struct rfc3149_xml_post_map *next; +} *xml_mapped; + +static struct rfc3149_xml_functions{ + char *name; + char *desc; + void (*p_fc)( struct mgcp_subchannel *sub, struct ast_variable *config , struct ast_variable *vars ); + struct rfc3149_xml_functions *next; +} *xml_functions; + +struct rfc3149_ky_functions{ + char *name; + void (*p_fc)( int fk_num, struct mgcp_subchannel *sub, struct ast_variable *vars ); + struct ast_variable *vars; + char *desc; + char *label; + char *state; + int enabled; + struct rfc3149_ky_functions *next; +} *ky_functions; + struct mgcp_endpoint { ast_mutex_t lock; char name[80]; @@ -316,7 +343,7 @@ char cid_name[AST_MAX_EXTENSION]; /*!< Caller*ID name */ char lastcallerid[AST_MAX_EXTENSION]; /*!< Last Caller*ID */ char dtmf_buf[AST_MAX_EXTENSION]; /*!< place to collect digits be */ - char call_forward[AST_MAX_EXTENSION]; /*!< Last Caller*ID */ + char call_forward[AST_MAX_EXTENSION]; /*!< Where is call forwarded */ char musicclass[MAX_MUSICCLASS]; char curtone[80]; /*!< Current tone */ char mailbox[AST_MAX_EXTENSION]; @@ -350,6 +377,7 @@ int immediate; int hookstate; int adsi; + int disp; char rqnt_ident[80]; /*!< request identifier */ struct mgcp_request *rqnt_queue; /*!< pending RQNT commands */ ast_mutex_t rqnt_queue_lock; @@ -363,8 +391,10 @@ /* struct ast_rtp *rtp; */ /* struct sockaddr_in tmpdest; */ /* message go the the endpoint and not the channel so they stay here */ + struct mgcp_endpoint *endp; struct mgcp_endpoint *next; struct mgcp_gateway *parent; + struct rfc3149_ky_functions *fk[100]; /* functions assigned to a particular button defined in RFC3149 */ }; static struct mgcp_gateway { @@ -386,7 +416,7 @@ /* Wildcard endpoint name */ char wcardep[30]; struct mgcp_message *msgs; /*!< gw msg queue */ - ast_mutex_t msgs_lock; /*!< queue lock */ + ast_mutex_t msgs_lock; /*!< queue lock */ int retransid; /*!< retrans timer id */ int delme; /*!< needed for reload */ struct mgcp_response *responses; @@ -411,8 +441,42 @@ static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp *rtp, int codecs); static int transmit_connection_del(struct mgcp_subchannel *sub); static int transmit_audit_endpoint(struct mgcp_endpoint *p); +/* RFC3149 config functions */ +void rfc3149_allocate_ky_functions(void); +void rfc3149_allocate_xml_functions(void); +struct ast_variable *parse_params(char *var_val, int offset ); +char *rfc3149_ky_wrap( struct mgcp_endpoint *p, char *rq ); +void rfc3149_indication(struct mgcp_subchannel *sub); +char *rfc3149_reindicate( struct mgcp_endpoint *p, char *rq ); +void rfc3149_fk_set_state(struct mgcp_endpoint *p, char *name,char *state ); +void rfc3149_conf_pickup( struct ast_variable *var , char *name, char **value ); + +/* RFC3149 transmit functions */ +static int transmit_rfc3149_xml(struct mgcp_endpoint *p, char *xml); +static int transmit_rfc3149_ky_fk(struct mgcp_endpoint *p, char *fk_num); +static int transmit_rfc3149_ky_ls(struct mgcp_endpoint *p, char *fk_num, char *label ); +static int transmit_rfc3149_ky_ks(struct mgcp_endpoint *p, char *fk_num, char *state ); +static int transmit_rfc3149_ignition(struct mgcp_endpoint *p ); + +/* Endpoint functions - for RFC3149 / KY */ +static void rfc3149_ky_dnd( int fk_num, struct mgcp_subchannel *p, struct ast_variable *vars); +void rfc3149_ky_forward( int fk_num, struct mgcp_subchannel *p, struct ast_variable *vars ); +static void rfc3149_ky_hold( int fk_num, struct mgcp_subchannel *p, struct ast_variable *vars ); +static void rfc3149_ky_call( int fk_num, struct mgcp_subchannel *sub, struct ast_variable *vars ); + +/* Endpoint functions - for RFC3149 / XML */ +void handle_rfc3149_xml(struct mgcp_subchannel *sub, char *ev); +char *rfc3149_create_xml(char *deck, char* card, struct ast_variable *variables); +int rfc3149_register_xml_function( struct rfc3149_xml_functions *xml_functions, char *xml_deck, char *xml_card, struct ast_variable *vars ); +int rfc3149_register_xml_action( struct rfc3149_xml_functions *xml_functions, char *action, struct ast_variable *vars ); + +static void rfc3149_xml_dnd( struct mgcp_subchannel *p, struct ast_variable *config, struct ast_variable *vars ); +static void rfc3149_xml_returnka( struct mgcp_subchannel *p, struct ast_variable *config, struct ast_variable *vars ); +static void rfc3149_xml_fwd_active( struct mgcp_subchannel *sub, struct ast_variable *config , struct ast_variable *vars); +static void rfc3149_xml_fwd_deactive( struct mgcp_subchannel *sub, struct ast_variable *config , struct ast_variable *vars); + static void start_rtp(struct mgcp_subchannel *sub); -static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, +static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, int result, unsigned int ident, struct mgcp_request *resp); static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub); static char *mgcp_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); @@ -516,7 +580,7 @@ int res; if (gw->addr.sin_addr.s_addr) res=sendto(mgcpsock, data, len, 0, (struct sockaddr *)&gw->addr, sizeof(struct sockaddr_in)); - else + else res=sendto(mgcpsock, data, len, 0, (struct sockaddr *)&gw->defaddr, sizeof(struct sockaddr_in)); if (res != len) { ast_log(LOG_WARNING, "mgcp_xmit returned %d: %s\n", res, strerror(errno)); @@ -564,7 +628,7 @@ else gw->msgs = cur->next; - ast_log(LOG_NOTICE, "Removing message from %s transaction %u\n", + ast_log(LOG_NOTICE, "Removing message from %s transaction %u\n", gw->name, cur->seqno); w = cur; @@ -680,7 +744,7 @@ while (exq) { cur = exq; /* time-out transaction */ - handle_response(cur->owner_ep, cur->owner_sub, 406, cur->seqno, NULL); + handle_response(cur->owner_ep, cur->owner_sub, 406, cur->seqno, NULL); exq = exq->next; ast_free(cur); } @@ -689,7 +753,7 @@ } /* modified for the new transaction mechanism */ -static int mgcp_postrequest(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, +static int mgcp_postrequest(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, char *data, int len, unsigned int seqno) { struct mgcp_message *msg; @@ -754,7 +818,7 @@ } /* modified for new transport */ -static int send_request(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, +static int send_request(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request *req, unsigned int seqno) { int res = 0; @@ -813,14 +877,14 @@ if (!(*queue)) { if (mgcpdebug) { - ast_verbose("Posting Request:\n%s to %s:%d\n", req->data, + ast_verbose("Posting Request:\n%s to %s:%d\n", req->data, ast_inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port)); } res = mgcp_postrequest(p, sub, req->data, req->len, seqno); } else { if (mgcpdebug) { - ast_verbose("Queueing Request:\n%s to %s:%d\n", req->data, + ast_verbose("Queueing Request:\n%s to %s:%d\n", req->data, ast_inet_ntoa(p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port)); } } @@ -1050,7 +1114,7 @@ return NULL; } - if (a->argc != 3) + if (a->argc != 3) return CLI_SHOWUSAGE; ast_mutex_lock(&gatelock); mg = gateways; @@ -1060,7 +1124,7 @@ while(me) { /* Don't show wilcard endpoint */ if (strcmp(me->name, mg->wcardep) != 0) - ast_cli(a->fd, " -- '%s@%s in '%s' is %s\n", me->name, mg->name, me->context, me->sub->owner ? "active" : "idle"); + ast_cli(a->fd, " -- '%s@%s' in '%s' is %s\n", me->name, mg->name, me->context, me->sub->owner ? "active" : "idle"); hasendpoints = 1; me = me->next; } @@ -1145,7 +1209,7 @@ e->command = "mgcp set debug {on|off}"; e->usage = "Usage: mgcp set debug {on|off}\n" - " Enables/Disables dumping of MGCP packets for debugging purposes\n"; + " Enables/Disables dumping of MGCP packets for debugging purposes\n"; return NULL; case CLI_GENERATE: return NULL; @@ -1166,10 +1230,355 @@ return CLI_SUCCESS; } +static char *handle_mgcp_rfc3149_ky(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a){ + struct mgcp_gateway *mg; + struct mgcp_endpoint *me; + int found = 0; + char *ename,*gname, *c; + + switch (cmd) { + case CLI_INIT: + e->command = "mgcp rfc3149 ky {fk|ls|ks}"; + e->usage = + "Usage: mgcp rfc3149 ky {fk|ls|ks} ..\n" + " fk : sets request for event from button fk.\n" + " ls