Index: channel.c =================================================================== --- channel.c (revision 10804) +++ channel.c (working copy) @@ -1006,6 +1006,14 @@ while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) ast_var_delete(vardata); +#if defined(IMSG) + if (chan->pend_txt_in) + free(chan->pend_txt_in); + if (chan->pend_txt_out) + free(chan->pend_txt_out); +#endif + + free(chan); AST_LIST_UNLOCK(&channels); Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 10804) +++ channels/chan_sip.c (working copy) @@ -75,6 +75,9 @@ #include "asterisk/acl.h" #include "asterisk/manager.h" #include "asterisk/callerid.h" +#if defined(IMSG) +#include +#endif #include "asterisk/cli.h" #include "asterisk/app.h" #include "asterisk/musiconhold.h" @@ -2587,7 +2590,11 @@ transmit_response_reliable(p, "603 Declined", &p->initreq, 1); } } else { /* Call is in UP state, send BYE */ +#if defined(IMSG) + if (!p->pendinginvite && !(ast->pend_txt_in || ast->pend_txt_out)) { +#else if (!p->pendinginvite) { +#endif /* Send a hangup */ transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); } else { @@ -5637,7 +5644,13 @@ { struct sip_request req; - reqprep(&req, p, SIP_MESSAGE, 0, 1); +#ifndef IMSG + reqprep(&req, p, SIP_MESSAGE 0, 1); +#else + initreqprep(&req, p,SIP_MESSAGE );/*else the To: and From: field are empty, don't know why*/ + if (!p->initreq.headers) + copy_request(&p->initreq, &req); +#endif add_text(&req, text); return send_request(p, &req, 1, p->ocseq); } @@ -7372,7 +7385,6 @@ return 0; } - /*! \brief Receive SIP MESSAGE method messages \note We only handle messages within current calls currently Reference: RFC 3428 */ @@ -7381,14 +7393,12 @@ char buf[1024]; struct ast_frame f; char *content_type; - content_type = get_header(req, "Content-Type"); - if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */ + if (!strstr(content_type, "text/plain")) { /* No text/plain attachment */ transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ ast_set_flag(p, SIP_NEEDDESTROY); return; } - if (get_msg_text(buf, sizeof(buf), req)) { ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); transmit_response(p, "202 Accepted", req); @@ -7407,7 +7417,8 @@ f.datalen = strlen(buf); ast_queue_frame(p->owner, &f); transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ - } else { /* Message outside of a call, we do not support that */ + } + else { /* Message outside of a call, we do not support that */ ast_log(LOG_WARNING,"Received message to %s from %s, dropped it...\n Content-Type:%s\n Message: %s\n", get_header(req,"To"), get_header(req,"From"), content_type, buf); transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ } @@ -7415,6 +7426,43 @@ return; } +#if defined(IMSG) +/*! \brief Receive SIP MESSAGE method messages +\note We only handle messages out of call + Reference: RFC 3428 */ +static void receive_message_outofcall(struct sip_pvt *p, struct sip_request *req) +{ + char buf[1024]; + char *content_type; + struct ast_channel *owner; + + content_type = get_header(req, "Content-Type"); + if (!strstr(content_type, "text/plain")) { /* No text/plain attachment */ + transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ + ast_set_flag(p, SIP_NEEDDESTROY); + return; + } + if (get_msg_text(buf, sizeof(buf), req)) { + ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); + transmit_response(p, "202 Accepted", req); + ast_set_flag(p, SIP_NEEDDESTROY); + return; + } + owner = sip_new(p, AST_STATE_DOWN, ast_strlen_zero(p->username) ? NULL : p->username ); + owner->_state = AST_STATE_UP; + owner->pend_txt_in = ast_strdup(buf); + if (!ast_post_message(owner)){ + transmit_response(p, "202 Accepted", req); + } + else { + transmit_response(p, "488 Not acceptable here", req); + ast_hangup(p->owner); + } + ast_set_flag(p, SIP_NEEDDESTROY); + return; +} +#endif + /*! \brief CLI Command to show calls within limits set by call_limit */ static int sip_show_inuse(int fd, int argc, char *argv[]) { #define FORMAT "%-25.25s %-15.15s %-15.15s \n" @@ -9915,7 +9963,13 @@ break; case 200: /* 200 OK */ p->authtries = 0; /* Reset authentication counter */ + if (sipmethod == SIP_MESSAGE) { +#if defined(IMSG) + if (p->owner && p->owner->pend_txt_out){ + ast_queue_control(p->owner, AST_CONTROL_TXTACK); + } +#endif /* We successfully transmitted a message */ ast_set_flag(p, SIP_NEEDDESTROY); } else if (sipmethod == SIP_NOTIFY) { @@ -10085,6 +10139,11 @@ } else if (sipmethod == SIP_CANCEL) { ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); } else if (sipmethod == SIP_MESSAGE) +#if defined(IMSG) + if (p->owner && p->owner->pend_txt_out){ + ast_queue_control(p->owner, AST_CONTROL_TXTACK); + } +#endif /* We successfully transmitted a message */ ast_set_flag(p, SIP_NEEDDESTROY); break; @@ -10748,13 +10807,35 @@ return 1; } - +#if defined(IMSG) +static int handle_request_message(struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin, int *recount, char *e) +#else /*! \brief Handle incoming MESSAGE request */ static int handle_request_message(struct sip_pvt *p, struct sip_request *req, int debug, int ignore) +#endif { +#if defined(IMSG) + int res=0; +#endif if (!ignore) { if (debug) ast_verbose("Receiving message!\n"); +#if defined(IMSG) + if (!p->owner){ + + res = check_user(p, req, SIP_MESSAGE, e, 1, sin, ignore); + if (res > 0) /* We have challenged the user for auth */ + return 0; + if (res < 0) { /* Something failed in authentication */ + ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); + transmit_response_reliable(p, "403 Forbidden", req, 1); + ast_set_flag(p, SIP_NEEDDESTROY); + return 0; + } + receive_message_outofcall(p, req); + } + else +#endif receive_message(p, req); } else { transmit_response(p, "202 Accepted", req); @@ -11125,7 +11206,11 @@ res = handle_request_bye(p, req, debug, ignore); break; case SIP_MESSAGE: +#if defined(IMSG) + res = handle_request_message(p, req, debug, ignore, seqno, sin, recount, e); +#else res = handle_request_message(p, req, debug, ignore); +#endif break; case SIP_SUBSCRIBE: res = handle_request_subscribe(p, req, debug, ignore, sin, seqno, e); Index: channels/Makefile =================================================================== --- channels/Makefile (revision 10804) +++ channels/Makefile (working copy) @@ -13,6 +13,8 @@ # This program is free software, distributed under the terms of # the GNU General Public License # +WITHOUT_PRI=1 +WITHOUT_ZAPTEL=1 MODS:=$(patsubst %.c,%.so,$(wildcard chan_*.c)) Index: apps/app_dial.c =================================================================== --- apps/app_dial.c (revision 10804) +++ apps/app_dial.c (working copy) @@ -1068,6 +1068,12 @@ /* Inherit specially named variables from parent channel */ ast_channel_inherit_variables(chan, tmp->chan); +#if defined(IMSG) + tmp->chan->pend_txt_out = chan->pend_txt_in; + chan->pend_txt_in = NULL;/*moved*/ +#endif + + tmp->chan->appl = "AppDial"; tmp->chan->data = "(Outgoing Line)"; tmp->chan->whentohangup = 0; @@ -1111,6 +1117,15 @@ if (outbound_group) ast_app_group_set_channel(tmp->chan, outbound_group); +#if defined(IMSG) + if (tmp->chan->pend_txt_out){ + tmp->chan->_state = AST_STATE_UP; /*faking for regular hangup*/ + ast_send_message(tmp->chan); /*block until confirmed*/ + ast_hangup(tmp->chan); + return -1;/*time to hangup*/ + } +#endif + /* Place the call, but don't wait on the answer */ res = ast_call(tmp->chan, numsubst, 0); Index: Makefile =================================================================== --- Makefile (revision 10804) +++ Makefile (working copy) @@ -66,6 +66,8 @@ # will be received more reliably #OPTIONS += -DRADIO_RELAX +OPTIONS += -DIMSG + # If you don't have a lot of memory (e.g. embedded Asterisk), define LOW_MEMORY # to reduce the size of certain static buffers Index: include/asterisk/channel.h =================================================================== --- include/asterisk/channel.h (revision 10804) +++ include/asterisk/channel.h (working copy) @@ -421,6 +421,13 @@ int rawreadformat; /*! Raw write format */ int rawwriteformat; +#if defined(IMSG) + /*incoming pending text to forward, malloc'd*/ + char* pend_txt_in; + + /*outgoing text to transmit, malloc'd*/ + char* pend_txt_out; +#endif /*! Chan Spy stuff */ struct ast_channel_spy_list *spies; Index: include/asterisk/frame.h =================================================================== --- include/asterisk/frame.h (revision 10804) +++ include/asterisk/frame.h (working copy) @@ -158,6 +158,10 @@ /*! DTMF end event, subclass is the digit */ #define AST_FRAME_DTMF_END 13 +#if defined(IMSG) +#define AST_CONTROL_TXTACK 98 +#endif + #if defined(T38_SUPPORT) /* MODEM subclasses */ /*! T.38 Fax-over-IP */ Index: res/Makefile =================================================================== --- res/Makefile (revision 10804) +++ res/Makefile (working copy) @@ -108,6 +108,9 @@ res_config_odbc.so: res_config_odbc.o $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} ${CYG_RES_CONFIG_ODBC_LIB} +res_messaging.so: res_messaging.o + $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} ${CYG_RES_FEATURES_LIB} + ifneq ($(wildcard .depend),) include .depend endif