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

📄 smsc_ois.c

📁 主要包括sms网关和wap网关实现说明和源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    ois_disconnect(smsc); /* smsc->socket */    ois_swap_buffering(smsc);    SAY(4, "ois_disconnect_all: ois_disconnect");    ois_disconnect(smsc); /* smsc->socket */    if (smsc->ois_listening_socket != -1) {	if (close(smsc->ois_listening_socket) == -1) {	    warning(errno, "ois_disconnect_all: close failed...");	}	smsc->ois_listening_socket = -1;    }    return;}static void ois_disconnect(SMSCenter *smsc){    SAY2(2, "ois_disconnect fd=%d", smsc->socket);    if (smsc->socket != -1) {	if (close(smsc->socket) == -1) {	    warning(errno, "ois_disconnect: close failed...");	}	smsc->socket = -1;    }    return;}static int ois_read_into_buffer(SMSCenter *smsc, long wait_usec){    int ret;    SAY(8, "ois_read_into_buffer");    if (smsc->socket == -1) {	if ((smsc->ois_flags & OIS_FLAG_CLOSED) == 0) {	    debug("bb.sms.ois", 0, "attempting to read from a closed socket");	    smsc->ois_flags |= OIS_FLAG_CLOSED;	}	return 0;    } else {	smsc->ois_flags &= ~OIS_FLAG_CLOSED;    }    ret = read_available(smsc->socket, wait_usec);    if (ret > 0) {	time(&smsc->ois_alive);	ret = smscenter_read_into_buffer(smsc);	if (ret > 0 || (ret == 0 && smsc->buflen > 0)) {	    SAY(2, "ois_read_into_buffer got something");	} else if (ret == 0) {	    if (smsc->buflen > 0) {		SAY(2, "ois_read_into_buffer has something");		ret = 1;	    }	    SAY(4, "ois_read_into_buffer: ois_disconnect");	    ois_disconnect(smsc);	}    }    return ret;}static int ois_check_input(SMSCenter *smsc, long wait_usec){    char buffer[BUFLEN+1];    time_t now;    int ret;    SAY(8, "ois_check_input");    ret = ois_read_into_buffer(smsc, wait_usec);    if (ret < 0) {	goto error;    }    ret = ois_extract_msg_from_buffer(buffer, smsc);    if (ret > 0) {	IOTRACE("received", buffer, ret);	switch (buffer[0]) {	case 's':	    ret = ois_submit_sm_result(smsc, buffer);	    if (ret > 0) {		warning(0, "ois_check_input: submit sm result signals (%d)...", ret);	    } else if (ret < 0) {		error(0, "ois_check_input: invalid submit sm result");		goto error;	    }	    --smsc->ois_ack_debt;	    time(&smsc->ois_alive);	    break;	case 'M':	    ret = ois_deliver_sm_invoke(smsc, buffer);	    if (ret >= 0) {		ret = ois_deliver_sm_result(smsc, ret, buffer);		if (ret < 0) {		    goto error;		}	    } else {		error(0, "ois_check_input: invalid deliver sm invoke");		goto error;	    }	    time(&smsc->ois_alive);	    break;	default:	    warning(0, "ois_check_input: unexpected message [%s]...",		    ois_debug_str(buffer, ret));	    break;	}    } else {	if (smsc->socket != -1) {	    time(&now);	    if ((now - smsc->ois_alive) > OIS_MESSAGE_WAITTIME) {		debug("bb.sms.ois", 0, "closing an idle connection");		SAY(4, "ois_check_input: ois_disconnect");		ois_disconnect(smsc);	    }	}    }    if (ret < 0) {	error(0, "ois_check_input: malformatted message [%s]",	      ois_debug_str(buffer, -ret));	goto error;    }    if (smsc->ois_received_mo != NULL ||	(smsc->ois_flags & OIS_FLAG_ERROR) != 0) {	SAY(2, "ois_check_input has something");	return 1; /* at least one message in the queue or an error pending */    } else {	return 0; /* no messages this time */    } error:    smsc->ois_flags |= OIS_FLAG_ERROR;    return 1;}static int ois_check_incoming(SMSCenter *smsc, long wait_usec){    fd_set read_fd;    struct timeval tv;    int ret;    SAY(8, "ois_check_incoming");    tv.tv_sec = 0;    tv.tv_usec = wait_usec;    FD_ZERO(&read_fd);    FD_SET(smsc->ois_listening_socket, &read_fd);    ret = select(smsc->ois_listening_socket + 1, &read_fd, NULL, NULL, &tv);    if (ret == -1) {	if (errno == EINTR || errno == EAGAIN) {	    return 0;	} else {	    error(errno, "ois_check_incoming: select failed");	    smsc->ois_flags |= OIS_FLAG_ERROR;	    return -1;	}    } else if (ret == 0) {	return 0;    }    /* if we end up here, someone is trying to connect */    if (smsc->socket != -1) {	if ((smsc->ois_flags & OIS_FLAG_MULTIPLE_CALL) == 0) {	    /* if you see lots of these, maybe we should accept */	    /* multiple incoming connections at a time... */	    debug("bb.sms.ois", 0, "letting an incoming call to wait until the old one disconnects");	    smsc->ois_flags |= OIS_FLAG_MULTIPLE_CALL;	}	return 0;    }    smsc->ois_flags &= ~OIS_FLAG_MULTIPLE_CALL;    return ois_open_receiver(smsc);}static void ois_append_to_list(ois_listentry **head, Msg *msg){    ois_listentry *item;    ois_listentry *tail;    SAY(2, "ois_append_to_list");    item = gw_malloc(sizeof(ois_listentry));    item->next = NULL;    item->msg = msg;    if (*head == NULL) {	*head = item;    } else { /* not so bright algorithm, but ok with relatively short lists */	for (tail = *head; tail->next != NULL; tail = tail->next) ;	tail->next = item;    }    return;}static int ois_int_to_i4(char *raw, int nbr){    int pos;    SAY(3, "ois_int_to_i4");    for (pos = 0; pos < 4; ++pos) {	raw[pos] = (char)(nbr % 0x100);	nbr /= 0x100;    }    return 4;}static int ois_increment_counter(void){    SAY(3, "ois_increment_counter");    ois_counter = (ois_counter+1) % MAXCOUNTER;    return ois_counter;}static int ois_submit_sm_invoke(SMSCenter *smsc, const Msg *msg){    char body[BUFLEN+1];    char buffer[BUFLEN+1];    int len;    int count;    int i;    int ret;    SAY(2, "ois_submit_sm_invoke");    /* construct a message */    ois_increment_counter();                  /* once per invoke */    len = ois_encode_submit_sm_invoke(body, msg);    /* the x.25 gear should be capable to fragment large messages, but... */    /* let's just use an explicit 128 byte blocks */    count = (len-1) / 121;                    /* 121 = 128 - 6 - 1 */    /* first part */    sprintf(buffer, "%c%c%04d%.121s%c",	    'S',                              /* submit sm invoke */	    (char)(0x50|count),               /* ia5 encoding, first part */	    ois_counter,	    &body[0],	    EOL);    IOTRACE("sending", buffer, strlen(buffer));    ret = write_to_socket(smsc->socket, buffer);    if (ret < 0) {	goto error;    }    /* additional parts */    for (i = 1; i <= count; ++i) {	sprintf(buffer, "%c%c%04d%.121s%c",		'S',                          /* submit sm invoke */		(char)(0x60|(count-i)),       /* ia5, additional part */		ois_counter,		&body[i*121],		EOL);	IOTRACE("sending", buffer, strlen(buffer));	ret = write_to_socket(smsc->socket, buffer);	if (ret < 0) {	    goto error;	}    }    SAY(2, "ois_submit_sm_invoke ok");    return 0; error:    SAY(2, "ois_submit_sm_invoke error");    return -1;}static int ois_encode_submit_sm_invoke(char *str, const Msg *msg){    char raw[BUFLEN];    int pos;    int ret;    SAY(3, "ois_encode_submit_sm_invoke");    /* construct the submit sm invoke body content */    pos = 0;    pos += ois_append_msisdn(&raw[pos], msg);    pos += ois_append_sme_reference_number(&raw[pos]);    pos += ois_append_priority(&raw[pos]);    pos += ois_append_originating_address(&raw[pos]);    pos += ois_append_validity_period(&raw[pos]);    pos += ois_append_data_coding_scheme(&raw[pos], msg);    pos += ois_append_status_report_request(&raw[pos]);    pos += ois_append_protocol_id(&raw[pos]);    pos += ois_append_submission_options(&raw[pos], msg);    pos += ois_append_sm_text(&raw[pos], msg);    ret = ois_convert_to_ia5(str, raw, pos);    return ret;}static int ois_append_msisdn(char *raw, const Msg *msg){    int len;    SAY(3, "ois_append_msisdn");    len = octstr_len(msg->sms.receiver);    raw[0] = (char) len;    memcpy(&raw[1], octstr_get_cstr(msg->sms.receiver), len);    return 1 + len;}static int ois_append_sme_reference_number(char *raw){    SAY(3, "ois_append_sme_reference_number");    /* 1=key, 2=not key (OIS 4.5) */    /* or 1=reject duplicates, 2=allow duplicates (OIS 5.0) */    raw[0] = (char) 2;    return 1 + ois_int_to_i4(&raw[1], ois_counter);}static int ois_append_priority(char *raw){    SAY(3, "ois_append_priority");    raw[0] = (char) 1; /* 0=high, 1=normal */    return 1;}static int ois_append_originating_address(char *raw){    SAY(3, "ois_append_originating_address");    raw[0] = (char) 2; /* length */    raw[1] = 'A'; /* A3=address type, actual address is unnecessary */    raw[2] = '3';    return 3;}static int ois_append_validity_period(char *raw){    SAY(3, "ois_append_validity_period");    raw[0] = (char) 2; /* 0=none, 1=absolute, 2=relative */    raw[1] = (char) 1; /* relative, (v+1)*5 minutes, v<144 */    return 2;}static int ois_append_data_coding_scheme(char *raw, const Msg *msg){    SAY(3, "ois_append_data_coding_scheme");    /* 0x0f is a special code for ASCII text, the SMSC will convert     * this to GSM and set the DCS to 0.     * FIXME: Convert to GSM ourselves and use DCS_GSM_TEXT.     * FIXME: use fields_to_dcs and try to support DC_UCS2 too ;) */    raw[0] = (char) (msg->sms.coding == DC_8BIT ? DCS_OCTET_DATA : 0x0f);    return 1;}static int ois_append_status_report_request(char *raw){    SAY(3, "ois_append_status_report_request");    raw[0] = (char) 0x00; /* bit field, bit 0=abandoned, bit 2=delivered */    return 1;}static int ois_append_protocol_id(char *raw){    SAY(3, "ois_append_protocol_id");    raw[0] = (char) 0; /* 0=default */    return 1;}static int ois_append_submission_options(char *raw, const Msg *msg){    SAY(3, "ois_append_submission_options");    /* bit field, bit 0=reply path, bit 1=udh, bits 3-4=dcs interpretation */    raw[0] = (char) 0x00;    if (octstr_len(msg->sms.udhdata)) {	raw[0] |= (char) 0x02;    }    if (msg->sms.coding == DC_8BIT) { /* XXX and UCS-2? */	raw[0] |= (char) 0x10;    }    return 1;}static int ois_append_sm_text(char *raw, const Msg *msg){    int udhlen7, udhlen8;    int msglen7, msglen8;    int len;    SAY(3, "ois_append_sm_text");    if (msg->sms.coding == DC_7BIT || msg->sms.coding == DC_UNDEF) {        charset_latin1_to_gsm(msg->sms.udhdata);        charset_latin1_to_gsm(msg->sms.msgdata);    }    /* calculate lengths */    udhlen8 = octstr_len(msg->sms.udhdata);    msglen8 = octstr_len(msg->sms.msgdata);    udhlen7 = udhlen8;    msglen7 = msglen8;    len = udhlen8 + msglen8;    /* copy text */    raw[0] = (char) (len);    raw[1] = (char) (udhlen7 + msglen7);    memcpy(&raw[2], octstr_get_cstr(msg->sms.udhdata), udhlen8);    memcpy(&raw[2+udhlen8], octstr_get_cstr(msg->sms.msgdata), msglen8);    IOTRACE("encoding", &raw[2], len);    return 2 + len;}static int ois_submit_sm_result(SMSCenter *smsc, const char *buffer){    int status;    int ret;    SAY(2, "ois_submit_sm_result");    ret = ois_decode_submit_sm_result(&status, buffer);    if (ret < 0) {	goto error;    }    return status; error:    return -1;}static int ois_decode_submit_sm_result(int *code, const char *str){    int buflen;    char raw[BUFLEN];    int len;    SAY(3, "ois_decode_submit_sm_result");    buflen = strlen(str) - 1;    if (buflen < 7 || str[0] != 's' || str[1] != 0x50 || str[buflen] != EOL) {	goto error;    }    len = ois_convert_from_ia5(raw, &str[6]);    if (len <= 0) {	goto error;    }    *code = raw[0];    *code &= 0xff;    /* there is smsc reference number and accept time, but we ignore them */    return 0; error:    return -1;}static int ois_deliver_sm_invoke(SMSCenter *smsc, const char *buffer){    Msg *msg;    int ret;    SAY(2, "ois_deliver_sm_invoke");    msg = msg_create(sms);    ret = ois_decode_deliver_sm_invoke(msg, buffer);    if (ret < 0) {	goto error;    }    ois_append_to_list((ois_listentry **) &smsc->ois_received_mo, msg);    return 0;     error:    msg_destroy(msg);    return -1;}static int ois_decode_deliver_sm_invoke(Msg *msg, const char *str){    char body[BUFLEN+1];    char raw[BUFLEN];    int len;    int i;    int pos;    int ret;    SAY(3, "ois_decode_deliver_sm_invoke");    ret = ois_check_deliver_sm_invoke(str);    if (ret < 0) {	goto error;    }    /* extract body */    len = strlen(str);    for (pos = 0, i = 6; i < len; ++i) {	if (str[i] != EOL) {	    body[pos++] = str[i];	} else {	    i += 6;	}    }    body[pos] = '\0';    memset(raw, '\0', sizeof(raw));    len = ois_convert_from_ia5(raw, body);    /* adjust msg values */    pos = 0;    pos += ois_adjust_destination_address(msg, &raw[pos]);    pos += ois_ignore_smsc_reference_number(&raw[pos]);    pos += ois_adjust_originating_address(msg, &raw[pos]);    pos += ois_adjust_data_coding_scheme(msg, &raw[pos]);    pos += ois_ignore_protocol_id(&raw[pos]);    pos += ois_adjust_additional_information(msg, &raw[pos]);    pos += ois_adjust_sm_text(msg, &raw[pos]);    pos += ois_ignore_time(&raw[pos]); /* accept time */    pos += ois_ignore_time(&raw[pos]); /* invoke time */    if (pos != len) {	error(0, "ois_decode_deliver_sm_invoke: message parsing error (%d!=%d)",	      pos, len);	goto error;    }    return 0; error:    return -1;}static int ois_check_deliver_sm_invoke(const char *str){    int buflen;    char buffer[BUFLEN+1];    int count;    SAY(3, "ois_check_deliver_sm_invoke");

⌨️ 快捷键说明

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