Browse Source

update: 整理sms库,兼容短信和长短信的发送

豆豆 7 months ago
parent
commit
b3b5fd3fab
3 changed files with 398 additions and 345 deletions
  1. 194 345
      components/sms/binding/luat_lib_sms.c
  2. 29 0
      components/sms/include/luat_sms.h
  3. 175 0
      components/sms/src/luat_sms.c

+ 194 - 345
components/sms/binding/luat_lib_sms.c

@@ -20,12 +20,12 @@
 
 void luat_str_fromhex(char* str, size_t len, char* buff) ;
 
+#include "luat_sms.h"
+
 #ifndef bool
-#define bool uint8_t
+#define bool    uint8_t
 #endif
 
-#include "luat_sms.h"
-
 #define LUAT_LOG_TAG "sms"
 #include "luat_log.h"
 static int lua_sms_ref = 0;
@@ -39,118 +39,37 @@ typedef struct long_sms
     char buff[1];
 }long_sms_t;
 
-typedef struct 
-{
-    size_t phone_len;           // 电话号码长度
-    size_t payload_len;          // 待编码的数据长度
-    const char *phone;          // 电话号码
-    uint8_t pdu_buf[320];       // 组包后的PDU短信
-    uint8_t payload_buf[200];    // 编码后的短信数据
-    uint8_t auto_phone;         // 是否自动处理电话号码
-    uint8_t maxNum;             // 短信最大条数, 长短信用
-    uint8_t seqNum;             // 当前短信序号
-}luat_sms_pdu_packet_t;
-
-#define LONG_SMS_CMAX (128)
-static long_sms_t* lngbuffs[LONG_SMS_CMAX];
-// static char* longsms = NULL;
-// static int longsms_refNum = -1;
-
-enum{
-	SMS_EVENT_SEND_RET = 0,
-};
-luat_rtos_task_handle sms_send_task_handle = NULL;
 typedef struct long_sms_send
 {
     size_t payload_len;
-    size_t phone_len;
-    const char *phone;
     uint8_t *payload;
-    uint8_t auto_phone;
 }long_sms_send_t;
 
-static uint8_t idx = 254;
-
-static uint64_t long_sms_send_idp;
-
-
-static void ucs2char(char* source, size_t size, char* dst2, size_t* outlen) {
-    char buff[size + 2];
-    memset(buff, 0, size + 2);
-    luat_str_fromhex(source, size, buff);
-    //LLOGD("sms %s", source);
-    uint16_t* tmp = (uint16_t*)buff;
-    char* dst = dst2;
-    // size_t tmplen = origin_len / 2;
-    // size_t dstoff = 0;
-    uint16_t unicode = 0;
-    size_t dstlen = 0;
-    while (1) {
-        unicode = *tmp ++;
-        unicode = ((unicode >> 8) & 0xFF) + ((unicode & 0xFF) << 8);
-        //LLOGD("unicode %04X", unicode);
-        if (unicode == 0)
-            break; // 终止了
-        if (unicode <= 0x0000007F) {
-            dst[dstlen++] = (unicode & 0x7F);
-            continue;
-        }
-        if (unicode <= 0x000007FF) {
-            dst[dstlen++]	= ((unicode >> 6) & 0x1F) | 0xC0;
-		    dst[dstlen++] 	= (unicode & 0x3F) | 0x80;
-            continue;
-        }
-        if (unicode <= 0x0000FFFF) {
-            dst[dstlen++]	= ((unicode >> 12) & 0x0F) | 0xE0;
-		    dst[dstlen++]	= ((unicode >>  6) & 0x3F) | 0x80;
-		    dst[dstlen++]	= (unicode & 0x3F) | 0x80;
-            //LLOGD("why? %02X %02X %02X", ((unicode >> 12) & 0x0F) | 0xE0, ((unicode >>  6) & 0x3F) | 0x80, (unicode & 0x3F) | 0x80);
-            continue;
-        }
-        break;
-    }
-    *outlen = dstlen;
-    //LLOGD("ucs2char %d", dstlen);
-}
 
-static int utf82ucs2(char* source, size_t source_len, char* dst, size_t dstlen, size_t* outlen) {
-    uint16_t unicode = 0;
-    size_t tmplen = 0;
-    for (size_t i = 0; i < source_len; i++)
+
+#define LONG_SMS_CMAX (128)
+
+static long_sms_t* lngbuffs[LONG_SMS_CMAX];
+static luat_sms_pdu_packet_t g_s_sms_pdu_packet = {0};
+static long_sms_send_t g_s_sms_send = {0};
+static uint8_t ref_idx = 254;
+static uint64_t long_sms_send_idp = 0;
+
+
+
+static int32_t l_long_sms_send_callback(lua_State *L, void* ptr){
+    rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
+    if (msg->arg1)
     {
-        if(tmplen >= dstlen) {
-            LLOGE("tmplen >= dstlen index: %d, tmplen: %d, dstlen: %d", i, tmplen, dstlen);
-            return -1;
-        }
-        // 首先是不是单字节
-        if (source[i] & 0x80) {
-            // 非ASCII编码
-            if (source[i] && 0xE0) { // 1110xxxx 10xxxxxx 10xxxxxx
-                unicode = ((source[i] & 0x0F) << 12) + ((source[i+1] & 0x3F) << 6) + (source[i+2] & 0x3F);
-                dst[tmplen++] = (unicode >> 8) & 0xFF;
-                dst[tmplen++] = unicode & 0xFF;
-                i+=2;
-                continue;
-            }
-            if (source[i] & 0xC0) { // 110xxxxx 10xxxxxx
-                unicode = ((source[i] & 0x1F) << 6) + (source[i+1] & 0x3F);
-                dst[tmplen++] = (unicode >> 8) & 0xFF;
-                dst[tmplen++] = unicode & 0xFF;
-                i++;
-                continue;
-            }
-            LLOGE("bat utf8 string");
-            return -1;
-        }
-        // 单个ASCII字符, 但需要扩展到2位
-        else {
-            // ASCII编码
-            dst[tmplen++] = 0x00;
-            dst[tmplen++] = source[i];
-            continue;
-        }
+        lua_pushboolean(L, 0);
+    }
+    else
+    {
+        lua_pushboolean(L, 1);
     }
-    *outlen = tmplen;
+    luat_cbcwait(L, long_sms_send_idp, 1);
+    long_sms_send_idp = 0;
+    g_s_sms_pdu_packet.maxNum = 0;             // 通过sms.sendLong发送的短信,需要在回调里确定发送结束
     return 0;
 }
 
@@ -344,14 +263,76 @@ void luat_sms_recv_cb(uint32_t event, void *param)
 
 void luat_sms_send_cb(int ret)
 {
-    if(long_sms_send_idp) {
-        LLOGE("send cb: %d", ret);
-        luat_rtos_event_send(sms_send_task_handle, SMS_EVENT_SEND_RET, ret, 0, 0, 0);
+    // 当前没有短信在发送,应该不会产生这个回调吧?
+    if (!g_s_sms_pdu_packet.maxNum) {
+        return;
+    }
+    rtos_msg_t msg = {
+        .handler = l_long_sms_send_callback,
+        .arg1 = 0,
+        .arg2 = 0
+    };
+    // 发送失败
+    if (ret) {
+        // 长短信发送失败
+        if (long_sms_send_idp) {
+            msg.arg1 = 1;
+            luat_msgbus_put(&msg, 0);
+        } else {
+            // 通过sms.send发送的短信,这里可以直接判断发送结束
+            g_s_sms_pdu_packet.maxNum = 0;
+        }
+        if (g_s_sms_send.payload != NULL) {
+            luat_heap_free(g_s_sms_send.payload);
+            g_s_sms_send.payload = NULL;
+        }
+        return;
+    }
+    LLOGE("long sms callback seqNum = %d", g_s_sms_pdu_packet.seqNum);
+    // 全部短信发送完成
+    if (g_s_sms_pdu_packet.seqNum == g_s_sms_pdu_packet.maxNum) {
+        if (long_sms_send_idp) {
+            msg.arg1 = 0;
+            luat_msgbus_put(&msg, 0);
+        } else {
+            g_s_sms_pdu_packet.maxNum = 0;
+        }
+
+        if (g_s_sms_send.payload != NULL) {
+            luat_heap_free(g_s_sms_send.payload);
+            g_s_sms_send.payload = NULL;
+        }
+        return;
+    }
+
+    // 长短信继续发送
+    g_s_sms_pdu_packet.seqNum++;
+
+    if (g_s_sms_send.payload_len - (g_s_sms_pdu_packet.seqNum - 1) * LUAT_SMS_LONG_MSG_PDU_SIZE <= LUAT_SMS_LONG_MSG_PDU_SIZE) {
+        memcpy(g_s_sms_pdu_packet.payload_buf, g_s_sms_send.payload + (g_s_sms_pdu_packet.seqNum - 1) * LUAT_SMS_LONG_MSG_PDU_SIZE, g_s_sms_send.payload_len - (g_s_sms_pdu_packet.seqNum - 1) * LUAT_SMS_LONG_MSG_PDU_SIZE);
+        g_s_sms_pdu_packet.payload_len = g_s_sms_send.payload_len - (g_s_sms_pdu_packet.seqNum - 1) * LUAT_SMS_LONG_MSG_PDU_SIZE ;
+    } else {
+        memcpy(g_s_sms_pdu_packet.payload_buf, g_s_sms_send.payload + (g_s_sms_pdu_packet.seqNum - 1) * LUAT_SMS_LONG_MSG_PDU_SIZE, LUAT_SMS_LONG_MSG_PDU_SIZE);
+        g_s_sms_pdu_packet.payload_len = LUAT_SMS_LONG_MSG_PDU_SIZE;
+    }
+    
+    int len = luat_sms_pdu_packet(&g_s_sms_pdu_packet);
+    ret = luat_sms_send_msg_v2(g_s_sms_pdu_packet.pdu_buf, len);
+    // 发送失败了
+    if (ret) {
+        // 长短信接口
+        if(long_sms_send_idp) {
+            msg.arg1 = 0;
+            luat_msgbus_put(&msg, 0);
+        } else {
+            g_s_sms_pdu_packet.maxNum = 0;
+        }
     }
+    return;
 }
 
 /*
-发送短信
+异步发送短信
 @api sms.send(phone, msg, auto_phone_fix)
 @string 电话号码,必填
 @string 短信内容,必填
@@ -375,8 +356,14 @@ static int l_sms_send(lua_State *L) {
     if (lua_isboolean(L, 3) && !lua_toboolean(L, 3)) {
         auto_phone = 0;
     }
+    
     int ret = 0;
-    char phone_buff[32] = {0};
+
+    // 当前有其他地方在发送短信
+    if (g_s_sms_pdu_packet.maxNum) {
+        LLOGE("sms is busy");
+        return 0;
+    }
 
     if (payload_len == 0) {
         LLOGE("sms is emtry");
@@ -397,228 +384,58 @@ static int l_sms_send(lua_State *L) {
         return 0;
     }
     memset(ucs2_buf, 0x00, payload_len * 3);
-    ret = utf82ucs2(payload, payload_len, ucs2_buf, payload_len * 3, &outlen);
-    if (ret != 0) {
-        LLOGE("utf82ucs2 encode fail");
-        luat_heap_free(ucs2_buf);
-        return 0;
-    }
 
-    if(outlen > 140)
-    {
-        LLOGE("sms is too long %d > 140", outlen);
-        luat_heap_free(ucs2_buf);
-        return 0;
-    }
-    luat_sms_pdu_packet_t pdu_packet = {0};
-    memcpy(pdu_packet.payload_buf, ucs2_buf, outlen);
-    luat_heap_free(ucs2_buf);
-    pdu_packet.auto_phone = auto_phone;
-    pdu_packet.payload_len = outlen;
-    pdu_packet.maxNum = 1;
-    pdu_packet.phone_len = phone_len;
-    pdu_packet.phone = phone;
-    int len = luat_sms_pdu_packet(&pdu_packet);
-    LLOGW("pdu len %d", len);
-    ret = luat_sms_send_msg_v2(pdu_packet.pdu_buf, len);
-    lua_pushboolean(L, ret == 0 ? 1 : 0);
-    LLOGD("sms ret %d", ret);
-    return 1;
-}
+    ret = utf82ucs2(payload, payload_len, ucs2_buf, payload_len * 3, &outlen);
 
-static int32_t l_long_sms_send_callback(lua_State *L, void* ptr){
-    rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
-    if (msg->arg1)
-    {
-        lua_pushboolean(L, 0);
-    }
-    else
-    {
-        lua_pushboolean(L, 1);
+    if (ret) {
+        LLOGE("utf82ucs2 encode fail");
+        goto SMS_FAIL;
     }
-    luat_cbcwait(L, long_sms_send_idp, 1);
-    long_sms_send_idp = 0;
-    return 0;
-}
 
-static int hex2int(char c)
-{
-    if (c >= '0' && c <= '9')
-        return c - '0';
-    if (c >= 'A' && c <= 'F')
-        return c - 'A' + 10;
-    if (c >= 'a' && c <= 'f')
-        return c - 'a' + 10;
-    return -1;
-}
-
-
-
-
-//buf PDU缓冲区, phone 电话号码, payload 信息内容, phone_len 电话号码长度, payload_len 信息内容长度, auto_phone 是否自动处理电话号码, is_long 是否长短信, maxNum 最大条数, seqNum 当前序号
-int luat_sms_pdu_packet(luat_sms_pdu_packet_t *packet)
-{
-    // 先处理一下电话号码
-    uint8_t gateway_mode = 0;	//短信网关特殊处理
-    uint8_t pos = 0;
-    size_t phone_len = packet->phone_len;
-    char phone_buff[32] = {0};
-    if ((packet->phone_len >= 15) && !memcmp(packet->phone, "10", 2)) {
-    	LLOGI("sms gateway mode");
-    	gateway_mode = 1;
-    	memcpy(phone_buff, packet->phone, phone_len);
-    }
-    else
-    {
-        if (packet->auto_phone) {
-            if (packet->phone[0] == '+') {
-                memcpy(phone_buff, packet->phone + 1, phone_len - 1);
-                phone_len -= 1;
-            }
-            // 13416121234
-            else if (packet->phone[0] != '8' && packet->phone[1] != '6') {
-                phone_buff[0] = '8';
-                phone_buff[1] = '6';
-                memcpy(phone_buff + 2, packet->phone, phone_len);
-                phone_len += 2;
-            }
-            else {
-                memcpy(phone_buff, packet->phone, phone_len);
-            }
-        }
-        else {
-            memcpy(phone_buff, packet->phone, phone_len);
-        }
-    }
+    memset(&g_s_sms_send, 0x00, sizeof(long_sms_send_t));
+    memset(&g_s_sms_pdu_packet, 0x00, sizeof(luat_sms_pdu_packet_t));
 
-    packet->pdu_buf[pos++] = 0x00;
-    if(packet->maxNum == 1)
-    {
-        packet->pdu_buf[pos++] = 0x01;
-    }
-    else
-    {
-        packet->pdu_buf[pos++] = 0x41;
-    }
-    packet->pdu_buf[pos++] = 0x00;
-    packet->pdu_buf[pos++] = phone_len;
-    packet->pdu_buf[pos++] = gateway_mode ? 0x81 : 0x91;
-    uint8_t one_char = 0;
-    for (size_t i = 0; i < phone_len; i+=2)
-    {
-        if (i == (phone_len - 1) && phone_len % 2 != 0) {
-            one_char = hex2int('F') << 4;
-            one_char |= (0x0F & hex2int(phone_buff[i]));
-            packet->pdu_buf[pos++] = one_char; 
-        }
-        else {
-            one_char = hex2int(phone_buff[i+1]) << 4;
-            one_char |= (0x0F & hex2int(phone_buff[i]));
-            packet->pdu_buf[pos++] = one_char;
-        }
+    // 短短信
+    if (outlen <= LUAT_SMS_SHORT_MSG_PDU_SIZE) {
+        g_s_sms_pdu_packet.maxNum = 1;
+        memcpy(g_s_sms_pdu_packet.payload_buf, ucs2_buf , outlen);
+        g_s_sms_pdu_packet.payload_len = outlen;
+    } else {
+        // 长短信
+        ref_idx = (ref_idx + 1) % 255;
+        g_s_sms_pdu_packet.maxNum = (outlen + LUAT_SMS_LONG_MSG_PDU_SIZE - 1) / LUAT_SMS_LONG_MSG_PDU_SIZE;
+        g_s_sms_pdu_packet.refNum = ref_idx;
+        memcpy(g_s_sms_pdu_packet.payload_buf, ucs2_buf , LUAT_SMS_LONG_MSG_PDU_SIZE);
+        g_s_sms_pdu_packet.payload_len = LUAT_SMS_LONG_MSG_PDU_SIZE;
     }
 
-    packet->pdu_buf[pos++] = 0x00;
-    packet->pdu_buf[pos++] = 0x08;
-    if(packet->maxNum == 1)
-    {
-        packet->pdu_buf[pos++] = packet->payload_len;
-        memcpy(packet->pdu_buf + pos, packet->payload_buf, packet->payload_len);
-        pos += packet->payload_len;
-        return pos;
-    }
-    packet->pdu_buf[pos++] = packet->payload_len + 6;
-
-    // 长短信
-    // UDHI
-    // 0: UDHL,    固定 0x05 
-    // 1: IEI,     固定 0X00
-    // 2: IEDL,    固定 
-    // 3: Reference NO 消息参考序号
-    // 4: Maximum   NO 消息总条数
-    // 5: Current   NO 当前短信序号
-    // uint8_t udhi[6] = {0x05, 0x00, 0x03, 0x00, 0x00, 0x00};
-    uint8_t udhi[6] = {0x05, 0x00, 0x03, idx, packet->maxNum, packet->seqNum};
-    memcpy(packet->pdu_buf + pos, udhi, 6);
-    pos += 6;
-    memcpy(packet->pdu_buf + pos, packet->payload_buf, packet->payload_len);
-    pos += packet->payload_len;
-    return pos;
-}
+    g_s_sms_pdu_packet.auto_phone = auto_phone;
+    g_s_sms_pdu_packet.phone_len = phone_len;
+    g_s_sms_pdu_packet.phone = phone;
+    g_s_sms_pdu_packet.seqNum = 1;
 
-void long_sms_send_task(void *params)
-{
-    long_sms_send_t *args = (long_sms_send_t*)params;
-    int ret = 0;
-    uint8_t is_done = 0; 
-    uint8_t is_error = 0;
-    rtos_msg_t msg = {
-        .handler = l_long_sms_send_callback,
-        .arg1 = 0,
-        .arg2 = 0
-    };
-    size_t outlen = args->payload_len;
-    uint16_t pducnt = (outlen + 133) / 134;
-    idx = (idx  + 1) % 255;
-    luat_event_t event = {0};
-    uint16_t i = 0;
-    uint16_t sn = 1;
-    char tmp[3] = {0};
-    luat_sms_pdu_packet_t pdu_packet = {0};
-    pdu_packet.auto_phone = args->auto_phone;
-    pdu_packet.maxNum = pducnt;
-    pdu_packet.phone_len = args->phone_len;
-    pdu_packet.phone = args->phone;
-    while(1)
-    {
-        if (outlen - i <= 134) {
-            memcpy(pdu_packet.payload_buf, args->payload + i, outlen - i);
-            pdu_packet.payload_len = (outlen - i);
-            is_done = 1;
-        } else {
-            memcpy(pdu_packet.payload_buf, args->payload + i, 134);
-            pdu_packet.payload_len = 134;
-            i += 134;
-        }
-        pdu_packet.seqNum = sn;
-        int pos = luat_sms_pdu_packet(&pdu_packet);
-        sn++;
-        ret = luat_sms_send_msg_v2(pdu_packet.pdu_buf, pos);
-        if (ret) {
-            LLOGE("long sms send fail:%d", ret);
-            is_error = 1;
-            break;
-        }
-        ret = luat_rtos_event_recv(sms_send_task_handle, 0, &event, NULL, 30000); // 30s没收到,则认为发送失败
-        if (ret || event.id != SMS_EVENT_SEND_RET || event.param1 != 0) {
-            // 异常
-            LLOGE("long sms except:%d, %d", ret, event.param1);
-            is_error = 1;
-            break;
-        }
-        if (is_done) {
-            break;
-        }
-    }
+    g_s_sms_send.payload = ucs2_buf;
+    g_s_sms_send.payload_len = outlen;
 
-LONG_SMS_DONE:
-    msg.arg1 = is_error;
-    luat_msgbus_put(&msg, 0);
-    if(args->payload != NULL)
-    {
-        luat_heap_free(args->payload);
-        args->payload = NULL;
+    int len = luat_sms_pdu_packet(&g_s_sms_pdu_packet);
+    LLOGW("pdu len %d", len);
+    ret = luat_sms_send_msg_v2(g_s_sms_pdu_packet.pdu_buf, len);
+    if (!ret) {
+        lua_pushboolean(L, ret == 0);
+        return 1;
     }
-    if (args != NULL)
-    {
-        luat_heap_free(args);
-        args = NULL;
+SMS_FAIL:
+    g_s_sms_pdu_packet.maxNum = 0;
+    g_s_sms_send.payload = NULL;
+    if(ucs2_buf != NULL) {
+        luat_heap_free(ucs2_buf);
     }
-    luat_rtos_task_delete(sms_send_task_handle);
+    lua_pushboolean(L, ret == 0);
+    return 1;
 }
 
 /*
-发送短信(每段PDU发送超时时间30s)
+同步发送短信
 @api sms.sendLong(phone, msg, auto_phone_fix).wait()
 @string 电话号码,必填
 @string 短信内容,必填
@@ -635,15 +452,22 @@ end)
 static int l_long_sms_send(lua_State *L) {
     size_t phone_len = 0;
     size_t payload_len = 0;
-    uint8_t *ucs2buf = NULL;
-    long_sms_send_t *args = NULL;
+    uint8_t *ucs2_buf = NULL;
     const char* phone = luaL_checklstring(L, 1, &phone_len);
     const char* payload = luaL_checklstring(L, 2, &payload_len);
     int auto_phone = 1;
     if (lua_isboolean(L, 3) && !lua_toboolean(L, 3)) {
         auto_phone = 0;
     }
+    // 当前有其他地方在发送短信
+    if (g_s_sms_pdu_packet.maxNum) {
+        LLOGE("sms is busy");
+        lua_pushboolean(L, 0);
+        luat_pushcwait_error(L,1);
+        return 1;
+    }
 
+    // 当前有其他地方在用sms.sendLong发送短信
     if (long_sms_send_idp) {
         lua_pushboolean(L, 0);
         luat_pushcwait_error(L,1);
@@ -661,47 +485,72 @@ static int l_long_sms_send(lua_State *L) {
     }
 
     size_t outlen = 0;
-    ucs2buf = (uint8_t *)luat_heap_malloc(payload_len * 3);
-    if (ucs2buf == NULL)
+    ucs2_buf = (uint8_t *)luat_heap_malloc(payload_len * 3);
+    if (ucs2_buf == NULL)
     {
         LLOGE("out of memory");
         goto SMS_FAIL;
     }
 
-    memset(ucs2buf, 0x00, payload_len * 3);
+    memset(ucs2_buf, 0x00, payload_len * 3);
 
-    int ret = utf82ucs2(payload, payload_len, ucs2buf, payload_len * 3, &outlen);
+    int ret = utf82ucs2(payload, payload_len, ucs2_buf, payload_len * 3, &outlen);
 
-    if (ret || outlen <= 140)
-    {
-        LLOGE("utf8 to ucs2 fail ret: %d, or ucs2 len is too short len: %d", ret, outlen);
+    if (ret) {
+        LLOGE("utf8 to ucs2 fail ret");
         goto SMS_FAIL;
     }
 
-    args = luat_heap_malloc(sizeof(long_sms_send_t));
-    if (NULL == args) {
-        LLOGE("out of memory");
-        goto SMS_FAIL;
+    memset(&g_s_sms_send, 0x00, sizeof(long_sms_send_t));
+    memset(&g_s_sms_pdu_packet, 0x00, sizeof(luat_sms_pdu_packet_t));
+
+
+    // 短短信
+    if (outlen <= LUAT_SMS_SHORT_MSG_PDU_SIZE) {
+        g_s_sms_pdu_packet.maxNum = 1;
+        memcpy(g_s_sms_pdu_packet.payload_buf, ucs2_buf , outlen);
+        g_s_sms_pdu_packet.payload_len = outlen;
+    } else {
+        // 长短信
+        ref_idx = (ref_idx + 1) % 255;
+        g_s_sms_pdu_packet.maxNum = (outlen + LUAT_SMS_LONG_MSG_PDU_SIZE - 1) / LUAT_SMS_LONG_MSG_PDU_SIZE;
+        g_s_sms_pdu_packet.refNum = ref_idx;
+        memcpy(g_s_sms_pdu_packet.payload_buf, ucs2_buf , LUAT_SMS_LONG_MSG_PDU_SIZE);
+        g_s_sms_pdu_packet.payload_len = LUAT_SMS_LONG_MSG_PDU_SIZE;
     }
-    memset(args, 0x00, sizeof(long_sms_send_t));
-    args->payload = ucs2buf;
-    args->payload_len = outlen;
-    args->phone = phone;
-    args->phone_len = phone_len;
-    args->auto_phone = auto_phone;
+
     long_sms_send_idp = luat_pushcwait(L);
-    ret = luat_rtos_task_create(&sms_send_task_handle, 10 * 1024, 10, "sms_send_task", long_sms_send_task, (void*)args, 10);
+    
+    g_s_sms_pdu_packet.auto_phone = auto_phone;
+    g_s_sms_pdu_packet.phone_len = phone_len;
+    g_s_sms_pdu_packet.phone = phone;
+    g_s_sms_pdu_packet.seqNum = 1;
+
+    g_s_sms_send.payload = ucs2_buf;
+    g_s_sms_send.payload_len = outlen;
+
+    char buf[400] = {0};
+    char tmp[3] = {0};
+
+    int len = luat_sms_pdu_packet(&g_s_sms_pdu_packet);
+    LLOGE("pdu len %d", len);
+    for (int i = 0; i < len; i++)
+    {
+        sprintf(tmp, "%02X", g_s_sms_pdu_packet.pdu_buf[i]);
+        strcat(buf, tmp);
+    }
+    LLOGE("pdu buf %s", buf);
+    ret = luat_sms_send_msg_v2(g_s_sms_pdu_packet.pdu_buf, len);
     if (!ret) {
         return 1;
     }
     LLOGE("sms send task create failed");
 SMS_FAIL:
     long_sms_send_idp = 0;
-    if(ucs2buf != NULL) {
-        luat_heap_free(ucs2buf);
-    }
-    if (args != NULL) {
-        luat_heap_free(args);
+    g_s_sms_pdu_packet.maxNum = 0;
+    g_s_sms_send.payload = NULL;
+    if(ucs2_buf != NULL) {
+        luat_heap_free(ucs2_buf);
     }
     lua_pushboolean(L, 0);
     luat_pushcwait_error(L, 1);
@@ -783,7 +632,7 @@ static const rotable_Reg_t reg_sms[] =
     { "setNewSmsCb",    ROREG_FUNC(l_sms_cb)},
     { "autoLong",       ROREG_FUNC(l_sms_auto_long)},
     { "clearLong",      ROREG_FUNC(l_sms_clear_long)},
-    { "sendLong",      ROREG_FUNC(l_long_sms_send)},
+    { "sendLong",       ROREG_FUNC(l_long_sms_send)},
 	{ NULL,             ROREG_INT(0)}
 };
 

+ 29 - 0
components/sms/include/luat_sms.h

@@ -23,6 +23,11 @@
 #define LUAT_SMS_H
 
 #include "luat_base.h"
+
+#ifndef bool
+#define bool    uint8_t
+#endif
+
 /**
  * @defgroup LUAT_SMS  SMS接口
  * @{
@@ -32,6 +37,11 @@
 #define LUAT_SMS_MAX_PDU_SIZE 180
 #define LUAT_SMS_MAX_LENGTH_OF_ADDRESS_VALUE 40
 #define LUAT_SMS_MAX_ADDR_STR_MAX_LEN ((LUAT_SMS_MAX_LENGTH_OF_ADDRESS_VALUE + 1) * 4)
+
+#define LUAT_SMS_SHORT_MSG_PDU_SIZE (140)
+#define LUAT_SMS_LONG_MSG_PDU_SIZE (134)
+
+
 typedef void (*LUAT_SMS_HANDLE_CB)(uint8_t event, void* param);
 typedef void (*LUAT_SMS_HANDLE_SEND_CB)(int ret);
 
@@ -110,6 +120,19 @@ typedef struct
 }LUAT_SMS_RECV_MSG_T;
 
 
+typedef struct 
+{
+    size_t phone_len;           // 电话号码长度
+    size_t payload_len;         // 待组包的短信数据长度
+    const char *phone;          // 电话号码
+    uint8_t pdu_buf[320];       // 组包后的PDU短信
+    uint8_t payload_buf[200];   // 待组包的短信数据
+    uint8_t auto_phone;         // 是否自动处理电话号码
+    uint8_t maxNum;             // 短信最大条数, 长短信用
+    uint8_t seqNum;             // 当前短信序号
+    uint8_t refNum;
+}luat_sms_pdu_packet_t;
+
 /**
  * @brief 初始化短信
  */
@@ -145,5 +168,11 @@ void luat_sms_recv_msg_register_handler(LUAT_SMS_HANDLE_CB callback_fun);
  * @param callback_fun    回调函数
  */
 void luat_sms_send_msg_register_handler(LUAT_SMS_HANDLE_SEND_CB callback_fun);
+
+/**
+ * @brief 打包pdu数据
+ * @param packet    
+ */
+int luat_sms_pdu_packet(luat_sms_pdu_packet_t *packet);
 /**@}*/
 #endif

+ 175 - 0
components/sms/src/luat_sms.c

@@ -0,0 +1,175 @@
+#include "luat_sms.h"
+
+
+static int hex2int(char c)
+{
+    if (c >= '0' && c <= '9')
+        return c - '0';
+    if (c >= 'A' && c <= 'F')
+        return c - 'A' + 10;
+    if (c >= 'a' && c <= 'f')
+        return c - 'a' + 10;
+    return -1;
+}
+
+
+void ucs2char(char* source, size_t size, char* dst2, size_t* outlen) {
+    char buff[size + 2];
+    memset(buff, 0, size + 2);
+    luat_str_fromhex(source, size, buff);
+    uint16_t* tmp = (uint16_t*)buff;
+    char* dst = dst2;
+    uint16_t unicode = 0;
+    size_t dstlen = 0;
+    while (1) {
+        unicode = *tmp ++;
+        unicode = ((unicode >> 8) & 0xFF) + ((unicode & 0xFF) << 8);
+        if (unicode == 0)
+            break; // 终止了
+        if (unicode <= 0x0000007F) {
+            dst[dstlen++] = (unicode & 0x7F);
+            continue;
+        }
+        if (unicode <= 0x000007FF) {
+            dst[dstlen++]	= ((unicode >> 6) & 0x1F) | 0xC0;
+		    dst[dstlen++] 	= (unicode & 0x3F) | 0x80;
+            continue;
+        }
+        if (unicode <= 0x0000FFFF) {
+            dst[dstlen++]	= ((unicode >> 12) & 0x0F) | 0xE0;
+		    dst[dstlen++]	= ((unicode >>  6) & 0x3F) | 0x80;
+		    dst[dstlen++]	= (unicode & 0x3F) | 0x80;
+            continue;
+        }
+        break;
+    }
+    *outlen = dstlen;
+}
+
+int utf82ucs2(char* source, size_t source_len, char* dst, size_t dstlen, size_t* outlen) {
+    uint16_t unicode = 0;
+    size_t tmplen = 0;
+    for (size_t i = 0; i < source_len; i++)
+    {
+        if(tmplen >= dstlen) {
+            return -1;
+        }
+        // 首先是不是单字节
+        if (source[i] & 0x80) {
+            // 非ASCII编码
+            if (source[i] && 0xE0) { // 1110xxxx 10xxxxxx 10xxxxxx
+                unicode = ((source[i] & 0x0F) << 12) + ((source[i+1] & 0x3F) << 6) + (source[i+2] & 0x3F);
+                dst[tmplen++] = (unicode >> 8) & 0xFF;
+                dst[tmplen++] = unicode & 0xFF;
+                i+=2;
+                continue;
+            }
+            if (source[i] & 0xC0) { // 110xxxxx 10xxxxxx
+                unicode = ((source[i] & 0x1F) << 6) + (source[i+1] & 0x3F);
+                dst[tmplen++] = (unicode >> 8) & 0xFF;
+                dst[tmplen++] = unicode & 0xFF;
+                i++;
+                continue;
+            }
+            return -1;
+        }
+        // 单个ASCII字符, 但需要扩展到2位
+        else {
+            // ASCII编码
+            dst[tmplen++] = 0x00;
+            dst[tmplen++] = source[i];
+            continue;
+        }
+    }
+    *outlen = tmplen;
+    return 0;
+}
+
+int luat_sms_pdu_packet(luat_sms_pdu_packet_t *packet)
+{
+    // 先处理一下电话号码
+    uint8_t gateway_mode = 0;	//短信网关特殊处理
+    uint8_t pos = 0;
+    size_t phone_len = packet->phone_len;
+    char phone_buff[32] = {0};
+    if ((packet->phone_len >= 15) && !memcmp(packet->phone, "10", 2)) {
+    	gateway_mode = 1;
+    	memcpy(phone_buff, packet->phone, phone_len);
+    }
+    else
+    {
+        if (packet->auto_phone) {
+            if (packet->phone[0] == '+') {
+                memcpy(phone_buff, packet->phone + 1, phone_len - 1);
+                phone_len -= 1;
+            }
+            // 13416121234
+            else if (packet->phone[0] != '8' && packet->phone[1] != '6') {
+                phone_buff[0] = '8';
+                phone_buff[1] = '6';
+                memcpy(phone_buff + 2, packet->phone, phone_len);
+                phone_len += 2;
+            }
+            else {
+                memcpy(phone_buff, packet->phone, phone_len);
+            }
+        }
+        else {
+            memcpy(phone_buff, packet->phone, phone_len);
+        }
+    }
+
+    packet->pdu_buf[pos++] = 0x00;
+    if(packet->maxNum == 1)
+    {
+        packet->pdu_buf[pos++] = 0x01;
+    }
+    else
+    {
+        packet->pdu_buf[pos++] = 0x41;
+    }
+    packet->pdu_buf[pos++] = 0x00;
+    packet->pdu_buf[pos++] = phone_len;
+    packet->pdu_buf[pos++] = gateway_mode ? 0x81 : 0x91;
+    uint8_t one_char = 0;
+    for (size_t i = 0; i < phone_len; i+=2)
+    {
+        if (i == (phone_len - 1) && phone_len % 2 != 0) {
+            one_char = hex2int('F') << 4;
+            one_char |= (0x0F & hex2int(phone_buff[i]));
+            packet->pdu_buf[pos++] = one_char; 
+        }
+        else {
+            one_char = hex2int(phone_buff[i+1]) << 4;
+            one_char |= (0x0F & hex2int(phone_buff[i]));
+            packet->pdu_buf[pos++] = one_char;
+        }
+    }
+
+    packet->pdu_buf[pos++] = 0x00;
+    packet->pdu_buf[pos++] = 0x08;
+    if(packet->maxNum == 1)
+    {
+        packet->pdu_buf[pos++] = packet->payload_len;
+        memcpy(packet->pdu_buf + pos, packet->payload_buf, packet->payload_len);
+        pos += packet->payload_len;
+        return pos;
+    }
+    packet->pdu_buf[pos++] = packet->payload_len + 6;
+
+    // 长短信
+    // UDHI
+    // 0: UDHL,    固定 0x05 
+    // 1: IEI,     固定 0X00
+    // 2: IEDL,    固定 
+    // 3: Reference NO 消息参考序号
+    // 4: Maximum   NO 消息总条数
+    // 5: Current   NO 当前短信序号
+    // uint8_t udhi[6] = {0x05, 0x00, 0x03, 0x00, 0x00, 0x00};
+    uint8_t udhi[6] = {0x05, 0x00, 0x03, packet->refNum, packet->maxNum, packet->seqNum};
+    memcpy(packet->pdu_buf + pos, udhi, 6);
+    pos += 6;
+    memcpy(packet->pdu_buf + pos, packet->payload_buf, packet->payload_len);
+    pos += packet->payload_len;
+    return pos;
+}