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

📄 smsc_cimd2.c

📁 gnu的专业网关smpp协议支持源代码。
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (errorcode > 0)        goto error;    /* The reply passed all the checks... looks like the SMSC accepted     * our request! */    packet_destroy(reply);    return 0;io_error:    packet_destroy(reply);    return -2;error:    packet_destroy(reply);    return -1;retry:    if (++tries < 3) {        warning(0, "Retransmitting (take %d)", tries);        goto retransmit;    }    warning(0, "Giving up.");    goto io_error;}/* Close the SMSC socket without fanfare. */static void cimd2_close_socket(SMSCenter *smsc){    gw_assert(smsc != NULL);    if (smsc->socket < 0)        return;    if (close(smsc->socket) < 0)        warning(errno, "error closing CIMD2 socket");    smsc->socket = -1;}/* Open a socket to the SMSC, send a login packet, and wait for ack. * This may block.  Return 0 for success, or -1 for failure. *//* Make sure the socket is closed before calling this function, otherwise * we will leak fd's. */static int cimd2_login(SMSCenter *smsc){    int ret;    struct packet *packet = NULL;    gw_assert(smsc != NULL);    if (smsc->socket >= 0) {        warning(0, "cimd2_login: socket was already open; closing");        cimd2_close_socket(smsc);    }    smsc->socket = tcpip_connect_to_server(octstr_get_cstr(smsc->cimd2_hostname), 		    smsc->cimd2_port, NULL);    /* XXX add interface_name if required */    if (smsc->socket == -1)        goto error;    packet = packet_create(LOGIN, BOGUS_SEQUENCE);    packet_add_string_parm(packet, P_USER_IDENTITY, smsc->cimd2_username);    packet_add_string_parm(packet, P_PASSWORD, smsc->cimd2_password);    ret = cimd2_request(packet, smsc, NULL);    if (ret < 0)        goto error;    packet_destroy(packet);    info(0, "%s logged in.", smsc_name(smsc));    return 0;error:    error(0, "cimd2_login failed");    cimd2_close_socket(smsc);    packet_destroy(packet);    return -1;}static void cimd2_logout(SMSCenter *smsc){    struct packet *packet = NULL;    gw_assert(smsc != NULL);    packet = packet_create(LOGOUT, BOGUS_SEQUENCE);    /* TODO: Don't wait very long for a response in this case. */    cimd2_request(packet, smsc,NULL);    packet_destroy(packet);}static int cimd2_send_alive(SMSCenter *smsc){    struct packet *packet = NULL;    int ret;    gw_assert(smsc != NULL);    packet = packet_create(ALIVE, BOGUS_SEQUENCE);    ret = cimd2_request(packet, smsc,NULL);    packet_destroy(packet);    if (ret < 0)        warning(0, "CIMD2: SMSC not alive.\n");    return ret;}/***************************************************************************//* SMSC Interface, as defined in smsc_interface.def                        *//***************************************************************************/SMSCenter *cimd2_open(Octstr *hostname, int port, Octstr *username,Octstr *password, int keepalive, Octstr *sender_prefix){    SMSCenter *smsc = NULL;    int maxlen;    smsc = smscenter_construct();    gw_assert(smsc != NULL);    smsc->type = SMSC_TYPE_CIMD2;    smsc->keepalive = keepalive;    smsc->cimd2_hostname = octstr_duplicate(hostname);    smsc->cimd2_port = port;    smsc->cimd2_username = octstr_duplicate(username);    smsc->cimd2_password = octstr_duplicate(password);    smsc->sender_prefix = octstr_duplicate(sender_prefix);    sprintf(smsc->name, "CIMD2:%s:%d:%s", octstr_get_cstr(hostname), port, octstr_get_cstr(username));    smsc->cimd2_received = list_create();    smsc->cimd2_inbuffer = octstr_create("");    smsc->cimd2_error = 0;    if (keepalive > 0)        smsc->cimd2_next_ping = time(NULL) + keepalive * 60;    maxlen = parm_maxlen(P_USER_IDENTITY);    if (octstr_len(smsc->cimd2_username) > maxlen) {        octstr_truncate(smsc->cimd2_username, maxlen);        warning(0, "Truncating CIMD2 username to %d chars", maxlen);    }    maxlen = parm_maxlen(P_PASSWORD);    if (octstr_len(smsc->cimd2_password) > maxlen) {        octstr_truncate(smsc->cimd2_password, maxlen);        warning(0, "Truncating CIMD2 password to %d chars", maxlen);    }    if (cimd2_login(smsc) < 0)        goto error;    return smsc;error:    error(0, "cimd2_open failed");    smscenter_destruct(smsc);    return NULL;}int cimd2_reopen(SMSCenter *smsc){    gw_assert(smsc != NULL);    warning(0, "Attempting to re-open CIMD2 connection");    cimd2_close_socket(smsc);    /* Restore message counters to their default values */    smsc->cimd2_send_seq = 1;    smsc->cimd2_receive_seq = 0;    /* Clear leftover input */    octstr_destroy(smsc->cimd2_inbuffer);    smsc->cimd2_inbuffer = octstr_create("");    return cimd2_login(smsc);}int cimd2_close(SMSCenter *smsc){    int ret;    int discarded;    gw_assert(smsc != NULL);    debug("bb.sms.cimd2", 0, "Closing CIMD2 SMSC");    if (smsc->socket < 0) {        warning(0, "cimd2_close: already closed.\n");        return 0;    }    cimd2_logout(smsc);    ret = close(smsc->socket);    smsc->socket = -1;    smsc->cimd2_send_seq = 0;    smsc->cimd2_receive_seq = 1;    octstr_destroy(smsc->cimd2_hostname);    octstr_destroy(smsc->cimd2_username);    octstr_destroy(smsc->cimd2_password);    octstr_destroy(smsc->cimd2_inbuffer);    discarded = list_len(smsc->cimd2_received);    list_destroy(smsc->cimd2_received, msg_destroy_item);    if (discarded > 0)        warning(0, "CIMD2: discarded %d received messages", discarded);    return ret;}int cimd2_submit_msg(SMSCenter *smsc, Msg *msg){    struct packet *packet;    int ret = 0;    int tries;    Octstr *ts;    ts = NULL;    gw_assert(smsc != NULL);    packet = packet_encode_message(msg, smsc->sender_prefix);    if (!packet)        return 0;   /* We can't signal protocol errors yet */    for (tries = 0; tries < 3; tries++) {        ret = cimd2_request(packet, smsc,&ts);        if((ret == 0) && (ts) && (msg->sms.dlr_mask & 0x03))        {            dlr_add(smsc->name,                octstr_get_cstr(ts),                 octstr_get_cstr(msg->sms.sender),                octstr_get_cstr(msg->sms.receiver),                octstr_get_cstr(msg->sms.service),                octstr_get_cstr(msg->sms.dlr_url),                msg->sms.dlr_mask);            octstr_destroy(ts);            ts = NULL;			}	if (ret == 0 || ret == -1)            break;        if (cimd2_reopen(smsc) < 0) {            ret = -1;            break;        }    }    packet_destroy(packet);    return ret;}/* The bearerbox really doesn't like it if pending_smsmessage returns * an error code.  We work around it until the bearerbox is rewritten. * Record the error here, and return it in cimd2_receive_msg.  Return * "message available" if there is an error so that cimd2_receive_msg * is called. */int cimd2_pending_smsmessage(SMSCenter *smsc){    long ret;    struct packet *packet;    gw_assert(smsc != NULL);    gw_assert(smsc->type == SMSC_TYPE_CIMD2);    if (list_len(smsc->cimd2_received) > 0)        return 1;    if (smsc->socket < 0) {        /* XXX We have to assume that smsc_send_message is         * currently trying to reopen, so we have to make         * this thread wait.  It should be done in a nicer         * way. */         return 0;    }    ret = read_available(smsc->socket, 0);    if (ret == 0) {        if (smsc->keepalive > 0 && smsc->cimd2_next_ping < time(NULL)) {            if (cimd2_send_alive(smsc) < 0) {                smsc->cimd2_error = 1;                return 1;            }        }        return 0;    }    if (ret < 0) {        warning(errno, "cimd2_pending_smsmessage: read_available failed");        smsc->cimd2_error = 1;        return 1;    }    /* We have some data waiting... see if it is an sms delivery. */    ret = octstr_append_from_socket(smsc->cimd2_inbuffer, smsc->socket);    if (ret == 0) {        warning(0, "cimd2_pending_smsmessage: service center closed connection.");        smsc->cimd2_error = 1;        return 1;    }    if (ret < 0) {        warning(0, "cimd2_pending_smsmessage: read failed");        smsc->cimd2_error = 1;        return 1;    }    for (;;) {        packet = packet_extract(smsc->cimd2_inbuffer);        if (!packet)            break;        packet_check(packet);        packet_check_can_receive(packet);        if (packet->operation < RESPONSE)            cimd2_handle_request(packet, smsc);        else {            error(0, "cimd2_pending_smsmessage: unexpected response packet");            octstr_dump(packet->data, 0);        }        packet_destroy(packet);    }    if (list_len(smsc->cimd2_received) > 0)        return 1;    return 0;}int cimd2_receive_msg(SMSCenter *smsc, Msg **msg){    gw_assert(smsc != NULL);    gw_assert(msg != NULL);    if (smsc->cimd2_error) {        smsc->cimd2_error = 0;        return -1;    }    *msg = list_consume(smsc->cimd2_received);    return 1;}static Msg *cimd2_accept_delivery_report_message(struct packet *request, SMSCenter *smsc){    Msg *msg = NULL;    Octstr *destination = NULL;    Octstr *timestamp = NULL;    Octstr *statuscode = NULL;    int st_code;     int code;	    destination = packet_get_parm(request, P_DESTINATION_ADDRESS);    timestamp = packet_get_parm(request, P_MC_TIMESTAMP);    statuscode = packet_get_parm(request, P_STATUS_CODE);    st_code = atoi(octstr_get_cstr(statuscode));        switch(st_code)    {    case 2:  /* validity period expired */    case 3:  /* delivery failed */	code = DLR_FAIL;    	break;    case 4: /* delivery successful */    	code = DLR_SUCCESS;    	break;    default:        code = 0;    }    if(code)    	msg = dlr_find(smsc->name,            octstr_get_cstr(timestamp),             octstr_get_cstr(destination),            code);    else        msg = NULL;    octstr_destroy(statuscode);    octstr_destroy(destination);    octstr_destroy(timestamp);    /* recode the body into msgdata */    if (msg) {        msg->sms.msgdata = packet_get_parm(request, P_USER_DATA);    }    return msg; }

⌨️ 快捷键说明

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