⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smsc_emi2.c

📁 gnu的专业网关smpp协议支持源代码。
💻 C
📖 第 1 页 / 共 4 页
字号:
	octstr_append_char(str, dcs);	octstr_binary_to_hex(str, 1);	octstr_append(emimsg->fields[E50_XSER],str);	octstr_destroy(str);    }    if (msg->sms.coding == DC_8BIT || msg->sms.coding == DC_UCS2) {	emimsg->fields[E50_MT] = octstr_create("4");	emimsg->fields[E50_MCLS] = octstr_create("1");	str = octstr_duplicate(msg->sms.msgdata);	emimsg->fields[E50_NB] =	    octstr_format("%04d", 8 * octstr_len(str));	octstr_binary_to_hex(str, 1);	emimsg->fields[E50_TMSG] = str;    }    else {	emimsg->fields[E50_MT] = octstr_create("3");	str = octstr_duplicate(msg->sms.msgdata);	charset_latin1_to_gsm(str);	/* Could still be too long after truncation if there's an UDH part,	 * but this is only to notice errors elsewhere (should never happen).*/	if (charset_gsm_truncate(str, 160))	    error(0, "EMI2[%s]: Message to send is longer "		  "than 160 gsm characters",		  octstr_get_cstr(privdata->name));	octstr_binary_to_hex(str, 1);	emimsg->fields[E50_AMSG] = str;    }    if (msg->sms.validity) {	tm = gw_localtime(time(NULL) + msg->sms.validity * 60);	sprintf(p, "%02d%02d%02d%02d%02d",	    tm.tm_mday, tm.tm_mon + 1, tm.tm_year % 100, 	    tm.tm_hour, tm.tm_min);	str = octstr_create(p);	emimsg->fields[E50_VP] = str;    }    if (msg->sms.deferred) {	str = octstr_create("1");	emimsg->fields[E50_DD] = str;	tm = gw_localtime(time(NULL) + msg->sms.deferred * 60);	sprintf(p, "%02d%02d%02d%02d%02d",	    tm.tm_mday, tm.tm_mon + 1, tm.tm_year % 100, 	    tm.tm_hour, tm.tm_min);	str = octstr_create(p);	emimsg->fields[E50_DDT] = str;    }    /* if delivery reports are asked, lets ask for them too */    /* even the sender might not be interested in delivery or non delivery */    /* we still need them back to clear out the memory after the message */    /* has been delivered or non delivery has been confirmed */    if (msg->sms.dlr_mask & (DLR_SUCCESS | DLR_FAIL | DLR_BUFFERED)) {    	emimsg->fields[E50_NRQ] = octstr_create("1");        emimsg->fields[E50_NT] = octstr_create("");	    octstr_append_decimal(emimsg->fields[E50_NT], 3 + (msg->sms.dlr_mask & DLR_BUFFERED)); 	    if (privdata->npid)            emimsg->fields[E50_NPID] = octstr_duplicate(privdata->npid);	    if (privdata->nadc)            emimsg->fields[E50_NADC] = octstr_duplicate(privdata->nadc);     }    return emimsg;}/* Return -1 if the connection broke, 0 if the request couldn't be handled * (unknown type), or 1 if everything was successful */static int handle_operation(SMSCConn *conn, Connection *server,			   struct emimsg *emimsg){    struct emimsg *reply;    Octstr *tempstr, *xser;    int type, len;    Msg *msg = NULL;    struct universaltime unitime;    int st_code;    PrivData *privdata = conn->data;      switch(emimsg->ot) {    case 01:	msg = msg_create(sms);	if (emimsg->fields[E01_AMSG] == NULL)	    emimsg->fields[E01_AMSG] = octstr_create("");	else if (octstr_hex_to_binary(emimsg->fields[E01_AMSG]) == -1)	    warning(0, "EMI2[%s]: Couldn't decode message text",		    octstr_get_cstr(privdata->name));	if (emimsg->fields[E01_MT] == NULL) {	    warning(0, "EMI2[%s]: required field MT missing",		    octstr_get_cstr(privdata->name));	    /* This guess could be incorrect, maybe the message should just	       be dropped */	    emimsg->fields[E01_MT] = octstr_create("3");	}	if (octstr_get_char(emimsg->fields[E01_MT], 0) == '3') {	    msg->sms.msgdata = emimsg->fields[E01_AMSG];	    emimsg->fields[E01_AMSG] = NULL; /* So it's not freed */	    charset_gsm_to_latin1(msg->sms.msgdata);	}	else {	    error(0, "EMI2[%s]: MT == %s isn't supported for operation type 01",		  octstr_get_cstr(privdata->name),		  octstr_get_cstr(emimsg->fields[E01_MT]));	    msg->sms.msgdata = octstr_create("");	}	msg->sms.sender = octstr_duplicate(emimsg->fields[E01_OADC]);	if (msg->sms.sender == NULL) {	    warning(0, "EMI2[%s]: Empty sender field in received message",		    octstr_get_cstr(privdata->name));	    msg->sms.sender = octstr_create("");	}	if(octstr_len(PRIVDATA(conn)->my_number)) {	    msg->sms.receiver = octstr_duplicate(PRIVDATA(conn)->my_number);	}	else {	    msg->sms.receiver = octstr_duplicate(emimsg->fields[E01_ADC]);	}	if (msg->sms.sender == NULL) {	    warning(0, "EMI2[%s]: Empty receiver field in received message",		    octstr_get_cstr(privdata->name));	    msg->sms.receiver = octstr_create("");	}	/* Operation type 01 doesn't have a time stamp field */	time(&msg->sms.time);	msg->sms.smsc_id = octstr_duplicate(conn->id);	bb_smscconn_receive(conn, msg);	reply = emimsg_create_reply(01, emimsg->trn, 1, privdata->name);	if (emi2_emimsg_send(conn, server, reply) < 0) {	    emimsg_destroy(reply);	    return -1;	}	emimsg_destroy(reply);	return 1;    case 52:	msg = msg_create(sms);	/* AMSG is the same field as TMSG */	if (emimsg->fields[E50_AMSG] == NULL)	    emimsg->fields[E50_AMSG] = octstr_create("");	else if (octstr_hex_to_binary(emimsg->fields[E50_AMSG]) == -1)	    warning(0, "EMI2[%s]: Couldn't decode message text",		      octstr_get_cstr(privdata->name));	xser = emimsg->fields[E50_XSER];	while (octstr_len(xser) > 0) {	    tempstr = octstr_copy(xser, 0, 4);	    if (octstr_hex_to_binary(tempstr) == -1)		error(0, "EMI2[%s]: Invalid XSer", 		      octstr_get_cstr(privdata->name));	    type = octstr_get_char(tempstr, 0);	    len = octstr_get_char(tempstr, 1);	    octstr_destroy(tempstr);	    if (len < 0) {		error(0, "EMI2[%s]: Malformed emi XSer field",		      octstr_get_cstr(privdata->name));		break;	    }	    if (type != 1 && type != 2)		warning(0, "EMI2[%s]: Unsupported EMI XSer field %d", 			octstr_get_cstr(privdata->name), type);	    else {		if (type == 1) {		    tempstr = octstr_copy(xser, 4, len * 2);		    if (octstr_hex_to_binary(tempstr) == -1)			error(0, "EMI2[%s]: Invalid UDH contents",			      octstr_get_cstr(privdata->name));		    msg->sms.udhdata = tempstr;		}		if (type == 2) {		    int dcs;		    tempstr = octstr_copy(xser, 4, 2);		    octstr_hex_to_binary(tempstr);		    dcs = octstr_get_char(tempstr, 0);		    octstr_destroy(tempstr);		    if (! dcs_to_fields(&msg, dcs)) {			error(0, "EMI2[%s]: invalid dcs received",			      octstr_get_cstr(privdata->name));			/* XXX Should we discard message ? */			dcs_to_fields(&msg, 0);		    }		}	    }	    octstr_delete(xser, 0, 2 * len + 4);	}	if (emimsg->fields[E50_MT] == NULL) {	    warning(0, "EMI2[%s]: required field MT missing",		    octstr_get_cstr(privdata->name));	    /* This guess could be incorrect, maybe the message should just	       be dropped */	    emimsg->fields[E50_MT] = octstr_create("3");	}	if (octstr_get_char(emimsg->fields[E50_MT], 0) == '3') {	    msg->sms.msgdata = emimsg->fields[E50_AMSG];	    emimsg->fields[E50_AMSG] = NULL; /* So it's not freed */	    charset_gsm_to_latin1(msg->sms.msgdata);	}	else if (octstr_get_char(emimsg->fields[E50_MT], 0) == '4') {	    msg->sms.msgdata = emimsg->fields[E50_TMSG];	    emimsg->fields[E50_TMSG] = NULL;	}	else {	    error(0, "EMI2[%s]: MT == %s isn't supported yet",		  octstr_get_cstr(privdata->name),		  octstr_get_cstr(emimsg->fields[E50_MT]));	    msg->sms.msgdata = octstr_create("");	}	msg->sms.sender = octstr_duplicate(emimsg->fields[E50_OADC]);	if (msg->sms.sender == NULL) {	    warning(0, "EMI2[%s]: Empty sender field in received message",		    octstr_get_cstr(privdata->name));	    msg->sms.sender = octstr_create("");	}	if(octstr_len(PRIVDATA(conn)->my_number)) {	    msg->sms.receiver = octstr_duplicate(PRIVDATA(conn)->my_number);	}	else {	    msg->sms.receiver = octstr_duplicate(emimsg->fields[E50_ADC]);	}	if (msg->sms.sender == NULL) {	    warning(0, "EMI2[%s]: Empty receiver field in received message",		    octstr_get_cstr(privdata->name));	    msg->sms.receiver = octstr_create("");	}	tempstr = emimsg->fields[E50_SCTS]; /* Just a shorter name */	if (tempstr == NULL) {	    warning(0, "EMI2[%s]: Received EMI message doesn't have required timestamp",		    octstr_get_cstr(privdata->name));	    goto notime;	}	if (octstr_len(tempstr) != 12) {	    warning(0, "EMI2[%s]: EMI SCTS field must have length 12, now %ld",		    octstr_get_cstr(privdata->name), octstr_len(tempstr));	    goto notime;	}	if (octstr_parse_long(&unitime.second, tempstr, 10, 10) != 12 ||	    (octstr_delete(tempstr, 10, 2),	     octstr_parse_long(&unitime.minute, tempstr, 8, 10) != 10) ||	    (octstr_delete(tempstr, 8, 2),	     octstr_parse_long(&unitime.hour, tempstr, 6, 10) != 8) ||	    (octstr_delete(tempstr, 6, 2),	     octstr_parse_long(&unitime.year, tempstr, 4, 10) != 6) ||	    (octstr_delete(tempstr, 4, 2),	     octstr_parse_long(&unitime.month, tempstr, 2, 10) != 4) ||	    (octstr_delete(tempstr, 2, 2),	     octstr_parse_long(&unitime.day, tempstr, 0, 10) != 2)) {	    error(0, "EMI2[%s]: EMI delivery time stamp looks malformed",		  octstr_get_cstr(privdata->name));	notime:	    time(&msg->sms.time);	}	else {	    unitime.year += 2000; /* Conversion function expects full year */        unitime.month -= 1; /* conversion function expects 0-based months */	    msg->sms.time = date_convert_universal(&unitime);	}	msg->sms.smsc_id = octstr_duplicate(conn->id);	counter_increase(conn->received);	bb_smscconn_receive(conn, msg);	reply = emimsg_create_reply(52, emimsg->trn, 1, privdata->name);	if (emi2_emimsg_send(conn, server, reply) < 0) {	    emimsg_destroy(reply);	    return -1;	}	emimsg_destroy(reply);	return 1;    case 53: /* delivery notification */	    	st_code = atoi(octstr_get_cstr(emimsg->fields[E50_DST]));	switch(st_code)	{	case 0: /* delivered */		msg = dlr_find(octstr_get_cstr((conn->id ? conn->id : privdata->name)), 			octstr_get_cstr(emimsg->fields[E50_SCTS]), /* timestamp */			octstr_get_cstr(emimsg->fields[E50_OADC]), /* destination */			DLR_SUCCESS);		break;	case 1: /* buffered */		msg = dlr_find(octstr_get_cstr((conn->id ? conn->id : privdata->name)), 			octstr_get_cstr(emimsg->fields[E50_SCTS]), /* timestamp */			octstr_get_cstr(emimsg->fields[E50_OADC]), /* destination */			DLR_BUFFERED);		break;	case 2: /* not delivered */		msg = dlr_find(octstr_get_cstr((conn->id ? conn->id : privdata->name)), 			octstr_get_cstr(emimsg->fields[E50_SCTS]), /* timestamp */			octstr_get_cstr(emimsg->fields[E50_OADC]), /* destination */			DLR_FAIL);		break;	}	if (msg != NULL) {     	            /*         * Recode the msg structure with the given msgdata.         * Note: the DLR URL is delivered in msg->sms.dlr_url already.         */        msg->sms.msgdata = octstr_duplicate(emimsg->fields[E50_AMSG]);        octstr_hex_to_binary(msg->sms.msgdata);        msg->sms.sms_type = report;	    bb_smscconn_receive(conn, msg);	}	reply = emimsg_create_reply(53, emimsg->trn, 1, privdata->name);	if (emi2_emimsg_send(conn, server, reply) < 0) {	    emimsg_destroy(reply);	    return -1;	}	emimsg_destroy(reply);	return 1;    default:	error(0, "EMI2[%s]: I don't know how to handle operation type %d", 	      octstr_get_cstr(privdata->name), emimsg->ot);	return 0;    }}/* * get all unacknowledged messages from the ringbuffer and queue them * for retransmission. */static void clear_sent(PrivData *privdata){    int i;    debug("smsc.emi2", 0, "EMI2[%s]: clear_sent called", 	  octstr_get_cstr(privdata->name));    for (i = 0; i < EMI2_MAX_TRN; i++) {	if (privdata->slots[i].sendtime && privdata->slots[i].sendtype == 51)	    list_produce(privdata->outgoing_queue, privdata->slots[i].sendmsg);	privdata->slots[i].sendtime = 0;    }    privdata->unacked = 0;}/* * wait seconds seconds for something to happen (a send SMS request, activity * on the SMSC main connection, an error or timeout) and tell the caller * what happened. */static EMI2Event emi2_wait (SMSCConn *conn, Connection *server, double seconds){    if (emi2_can_send(conn) && list_len(PRIVDATA(conn)->outgoing_queue)) {	return EMI2_SENDREQ;    }        if (server != NULL) {	switch (conn_wait(server, seconds)) {	case 1: return list_len(PRIVDATA(conn)->outgoing_queue) ? EMI2_SENDREQ : EMI2_TIMEOUT;	case 0: return EMI2_SMSCREQ;	default: return EMI2_CONNERR;	}    } else {	gwthread_sleep(seconds);	return list_len(PRIVDATA(conn)->outgoing_queue) ? EMI2_SENDREQ : EMI2_TIMEOUT;    }}/* * obtain the next free TRN. */static int emi2_next_trn (SMSCConn *conn){#define INC_TRN(x) ((x)=((x) + 1) % EMI2_MAX_TRN)    int result;        while (SLOTBUSY(conn,PRIVDATA(conn)->priv_nexttrn))	INC_TRN(PRIVDATA(conn)->priv_nexttrn); /* pick unused TRN */        result = PRIVDATA(conn)->priv_nexttrn;    INC_TRN(PRIVDATA(conn)->priv_nexttrn);    return result;#undef INC_TRN}/* * send an EMI type 31 message when required. */static int emi2_keepalive_handling (SMSCConn *conn, Connection *server){    struct emimsg *emimsg;    int nexttrn = emi2_next_trn (conn);        emimsg = make_emi31(PRIVDATA(conn), nexttrn);    if(emimsg) {        PRIVDATA(conn)->slots[nexttrn].sendtype= 31;        PRIVDATA(conn)->slots[nexttrn].sendtime = time(NULL);        PRIVDATA(conn)->unacked++;	        if (emi2_emimsg_send(conn, server, emimsg) == -1) {           emimsg_destroy(emimsg);           return -1;        }        emimsg_destroy(emimsg);    }	    PRIVDATA(conn)->can_write = 0;    return 0;}/* * the actual send logic: Send all queued messages in a burst. */static int emi2_do_send (SMSCConn *conn, Connection *server){    struct emimsg *emimsg;    Msg           *msg;    double         delay = 0;    if (PRIVDATA(conn)->throughput) {	delay = 1.0 / PRIVDATA(conn)->throughput;    }        /* Send messages if there's room in the sending window */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -