Тип очереди в канале

Я установил kannel из пакета rpm kannel-sw-1.4.3.3-6.rh5u3. Выполните простые тесты, такие как отправка одного за другим пяти сообщений ("1", "2", "3", "4" и "5") в smsbox через http get для обработки ошибки регулирования. Со стороны SMSC пропускная способность составила 2 SMS в минуту. Я ожидал получить смс в следующем порядке: "1" "2" "3" "4" "5" Но в журналах канала и дампе SMPP я получил поток, подобный следующему:

> "1"
< ok
> "2"
< ok
> "3"
< throttling error
#first timeout less than 1 minute according config
> "4"
< throttling error
#second timeout less than 1 minute according config, but in sum with first more than 1 minute
> "5"
< ok
> "3"
< ok
> "4"
< throttling error
and so on

Таким образом, порядок в результате был "1", "2", "5", "3", "4" вместо "1", "2", "3", "4", "5". Можно ли изменить тип заказа при попытке отправить последнее сообщение об ошибке вместо следующего в цепочке? В документации я нашел опцию sms-coming-queue-limit. Но я понятия не имею, что означает "Значение 0 означает предоставление строгого приоритета исходящим сообщениям", и, к сожалению, я не могу запустить тесты в ближайшее время. Что такое строгий приоритет и как насчет очереди \ типа заказа?

Большое спасибо.

2 ответа

Мой предыдущий ответ был неверным. Правильный ответ:

  1. Изменить функцию sms_priority_compare в sms.c:

    if (msg1->sms.time > msg2->sms.time)
            ret = 1;
    else if (msg1->sms.time < msg2->sms.time)
            ret = -1;
    

    в

    if (msg1->sms.time > msg2->sms.time)
        ret = -1;
    else if (msg1->sms.time < msg2->sms.time)
        ret = 1;
    else {
        if (msg1->sms.id > msg2->sms.id)
            ret = -1;
        else if (msg1->sms.id < msg2->sms.id)
            ret = 1;
        else
            ret = 0;           
    }
    
  2. Изменить функцию smpp_status_to_smscconn_failure_reason в smsc/smsc_smpp.c:

    static long smpp_status_to_smscconn_failure_reason(long status)
    {
        switch(status) {
            case SMPP_ESME_RMSGQFUL:
            case SMPP_ESME_RTHROTTLED:
            case SMPP_ESME_RX_T_APPN:
            case SMPP_ESME_RSYSERR:
                return SMSCCONN_FAILED_TEMPORARILY;
                break;
    
            default:
                return SMSCCONN_FAILED_REJECTED;
        }
    }
    

    в

    static long smpp_status_to_smscconn_failure_reason(long status)
    {
        switch(status) {
            case SMPP_ESME_RMSGQFUL:
            case SMPP_ESME_RX_T_APPN:
            case SMPP_ESME_RSYSERR:
                return SMSCCONN_FAILED_TEMPORARILY;
                break;
    
            case SMPP_ESME_RTHROTTLED:
                return SMPP_ESME_RTHROTTLED;
                break;
    
            default:
                return SMSCCONN_FAILED_REJECTED;
        }
    }
    
  3. Изменить функцию handle_pdu в smsc/smsc_smpp.c (case submit_sm_resp:):

    if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RTHROTTLED)
            time(&(smpp->throttling_err_time));
    else
            smpp->throttling_err_time = 0;    
    
    bb_smscconn_send_failed(smpp->conn, msg, reason, octstr_format("0x%08lx/%s", pdu->u.submit_sm_resp.command_status,
                                        smpp_error_to_string(pdu->u.submit_sm_resp.command_status)));
    

    в

    if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RTHROTTLED)
            time(&(smpp->throttling_err_time));
    else
            smpp->throttling_err_time = 0;    
    
    if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RMSGQFUL)
            time(&msg->sms.time);    
    
    bb_smscconn_send_failed(smpp->conn, msg, reason, octstr_format("0x%08lx/%s", pdu->u.submit_sm_resp.command_status,
                                        smpp_error_to_string(pdu->u.submit_sm_resp.command_status)));
    
  4. Изменить функцию bb_smscconn_send_failed в bb_smscconn.c:

           case SMSCCONN_FAILED_TEMPORARILY:     
           ...
           gwlist_produce(outgoing_sms, sms);
           break;
    
    case SMSCCONN_FAILED_SHUTDOWN:
           gwlist_produce(outgoing_sms, sms);
           break;
    

    в

    case SMSCCONN_FAILED_TEMPORARILY:     
           ...
           gwlist_produce(outgoing_sms, sms);
           break;
    
    case SMPP_ESME_RTHROTTLED:   
           gwlist_insert(outgoing_sms, 0, sms);
           break;
    
    case SMSCCONN_FAILED_SHUTDOWN:
           gwlist_produce(outgoing_sms, sms);
           break;
    
  5. Изменить функцию handle_split в bb_smscconn.c:

    case SMSCCONN_FAILED_TEMPORARILY:     
           ...
           gwlist_produce(outgoing_sms, msg);
           break;
    
    case SMSCCONN_FAILED_DISCARDED:
    

    в

    case SMSCCONN_FAILED_TEMPORARILY:     
           ...
           gwlist_produce(outgoing_sms, msg);
           break;
    
    case SMPP_ESME_RTHROTTLED:   
           gwlist_insert(outgoing_sms, 0, msg);
           break;
    
    case SMSCCONN_FAILED_DISCARDED:
    

Обработка ошибок регулирования SMPP:

I did the following patch to smsc/smsc_smpp.c in "case submit_sm_resp:"
section from line 1609:
change
***
if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RTHROTTLED)
    time(&(smpp->throttling_err_time));
else
    smpp->throttling_err_time = 0;

bb_smscconn_send_failed(smpp->conn, msg, reason, octstr_format("0x%08lx/%s",
pdu->u.submit_sm_resp.command_status,

 smpp_error_to_string(pdu->u.submit_sm_resp.command_status)));
***
to
***
if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RTHROTTLED) {
    time(&(smpp->throttling_err_time));
    /* Put the message back into the SMPP queue */
    gw_prioqueue_produce(smpp->msgs_to_send, msg);
} else {
    smpp->throttling_err_time = 0;
    bb_smscconn_send_failed(smpp->conn, msg, reason,
octstr_format("0x%08lx/%s", pdu->u.submit_sm_resp.command_status,
        smpp_error_to_string(pdu->u.submit_sm_resp.command_status)));
}
***

and in sms.c I have changed the function sms_priority_compare() to reverse
time sorting order (for some reason it was LIFO):
if (msg1->sms.time > msg2->sms.time)
    ret = -1;
else if (msg1->sms.time < msg2->sms.time)
    ret = 1;
-------------- next part --------------

Заказ составных СМС-частей основан на дополнительном сравнении их sms.id:

int sms_priority_compare(const void *a, const void *b)
{
    int ret;
    Msg *msg1 = (Msg*)a, *msg2 = (Msg*)b;
    gw_assert(msg_type(msg1) == sms);
    gw_assert(msg_type(msg2) == sms);

    if (msg1->sms.priority > msg2->sms.priority)
        ret = 1;
    else if (msg1->sms.priority < msg2->sms.priority)
        ret = -1;
    else {
        if (msg1->sms.time > msg2->sms.time)
            ret = -1;
        else if (msg1->sms.time < msg2->sms.time)
            ret = 1;
        else {
            if (msg1->sms.id > msg2->sms.id)
                ret = -1;
            else if (msg1->sms.id < msg2->sms.id)
                ret = 1;
            else
                ret = 0;          
        }
    }

    return ret;
}
Другие вопросы по тегам