Gsm PDU to Text decoding Algorithm not working in stm32

Thread Starter

devjeetmandal

Joined May 7, 2017
48
I have written a PDU to Text decoding algorithm in C which compiles and runs perfectly with dev C or code blocks for more than one messages(where i provide the PDU messages manually). Now i have applied the same algorithm to stm32f103rc connected with sim800c gsm module with stm32f103rc sysclk running on 72MHz and communication baud between stm and sim800c is 115200.

when i send simple message(within 80 characters) the sms gets decode and shows on display perfectly but when i send more than 80 characters the display shows upto 80 chars and then stops. I checked the decoded message in terminal which gives the same result after 80 chars there is garbage.

I have taken account few things like terminating a string(as i m not fetching the data manually as in dev c) then removal of carriage return and line feeds. But could not understand where i m going wrong with the algorithm

THE CODE

i am running the code on stm32f103rc

C:
/*
 * PDU_Decode.c
 *
 * Created: 18-02-2018 20:24:50
 * Author: Devjeet Mandal
 */

 /* Includes --------------------------------------------------------------*/
 #include "PDU_Decode.h"
 /* Private Variables -----------------------------------------------------*/
 int concate;
 /* Private Function Definition -------------------------------------------*/
 /** @breif: Decode a PDU msg to TEXT
    * @param: Destination Buffer to store converted data
    * @retVal: None
  */
 void PDU_to_TEXT(char *dest)
 {
    char Len[2];
    char str[150];
    int UserDataLen;
    uint8_t msgNo,totalMsg;
    msgNo = 1;
    do
    {
      End_Things();
      if (msgNo == 1)       { Transmit_String("AT+CMGR=1\r"); }
      else if(msgNo == 2)   { Transmit_String("AT+CMGR=2\r"); }
      else if(msgNo == 3)   { Transmit_String("AT+CMGR=3\r");   }
      else                  { Transmit_String("AT+CMGR=4\r");   }
     
      _delay_ms(100);
      Uart_Buff[datapos] = '\0';
      if (msgNo == 1)
      {
        concate  = CheckForConcate(Uart_Buff);
      totalMsg = CheckForTotal_msg(Uart_Buff);
      }
      Remove_Carriag_LineFeed(Uart_Buff);
      Eliminate_Extras(Uart_Buff);
      uint8_t startingPoint = CheckStartingPoint(Uart_Buff);
      GetUserData(Uart_Buff,Len,startingPoint);
      UserDataLen = DecodeTwoBitData(Len);
      Decode_PDU(Uart_Buff,str,UserDataLen);
      if (msgNo == 1)     { strcpy(dest,str);   }
      else
      {
        int i=0,j=0;
        while(dest[i]!='\0') {i++;}
        while(str[j]!='\0')
        {
          dest[i] = str[j];
          i++;j++;
        }
        dest[i] = '\0';
      }
      Transmit_String(dest);
      msgNo++;
      End_Things();
      if (totalMsg > 1 && msgNo <= totalMsg)
      {
        while (!strstr(Uart_Buff,"+CMTI"));
      }     
    }while (msgNo <= totalMsg);
 }
 /** @breif: Check is message is having more than one part
    * @param: The source message which is to be checked
    * @retVal: Either true or false
  */
uint8_t CheckForConcate(char *src)
{
   if (strstr(src,"050003"))     { return 1; }
   else                         {   return 0;   }
}

 /** @breif: Check for total messages
    * @param: the source message
    * @retVal: total number of message
  */
uint8_t CheckForTotal_msg(char *src)
{
   int i;
   char temp[2];
   uint8_t t_msg;
   for (i = 0;i<strlen(src);i++)
   {
     if (src[i] == '0' && src[i+1] == '5' && src[i+2] == '0' && src[i+3] == '0' && src[i+4] == '0' && src[i+5] == '3')
     {
       i+=8;
       temp[0] = src[i];
       temp[1] = src[i+1];
       t_msg = DecodeTwoBitData(temp);
       return t_msg;
     }
   }
   return 1;             //if there is no other message dn source message is the only message
}


 /** @breif: Get original hex from the character
    * @param: the source message
    * @param: The destination file to store hex
    * @retVal: None
  */
void GetOriginalHex(char *src, uint8_t *hex)
{
   int i;
   for (i=0;src[i] != '\0';i++)
   {
     if (src[i] >= '0' && src[i] < 'A')   { hex[i] = src[i] - '0'; }
     else if (src[i] >= 'A')               { hex[i] = src[i] - 'A' + 10; }
   }
}


 /** @breif: pack the hex in single position
    * @param: the source message
  * @param: length of the source message
    * @retVal: None
  */
void PackHex(uint8_t *hex,int len)
{
   int i,j;
   for (i = 0,j = 0; i< len;i+=2,j++)
   {
     hex[j] = hex[i] << 4 | hex[i+1];
   }
}


 /** @breif: Decode the two bit data in single data
    * @param: the source message
    * @retVal: Decoded bit
  */
uint8_t DecodeTwoBitData(char *hex)
{
   uint8_t newHex[2];
   GetOriginalHex(hex,newHex);
   PackHex(newHex,2);
   
   return (newHex[0]);
}


 /** @breif: Remove Carriage return and Line feed from the original message
    * @param: the source message
    * @retVal: None
  */
void Remove_Carriag_LineFeed(char *str)
{
   int i,j;
   for(i = 0, j = 0; str[i] != '\0'; i++)
   {
     if(str[i] != '\r' && str[i] != '\n')
       str[j++] = str[i];
   }
   str[j] = '\0';
}


 /** @breif: Eliminate Extra mesages from original message
    * @param: the source message
    * @retVal: None
  */
void Eliminate_Extras(char *src)
{
   int copy = 0;
   int i,j;
   for (i = 0,j = 0; src[i] != '\0'; i++)
   {
     if (src[i] == '0' && src[i+1] == '7' && src[i+2] == '9' && src[i+3] == '1')
       copy = 1;
     if (copy)
     {
       src[j] = src[i];
       j++;
     }
   }
   src[j] = '\0';
}


 /** @breif: Check the starting point of the original message
    * @param: the source message
    * @retVal: starting point
  */
uint8_t CheckStartingPoint(char *src)
{
   uint8_t temp = 52,retVal = temp;
   if (src[temp - 1] == '2' && src[temp - 2] == '2')       retVal = 52;
   else if (src[temp] == '2' && src[temp + 1] == '2')       retVal = 54;
   else if (src[temp + 2] == '2' && src[temp + 3] == '2')   retVal = 56;
   
   return retVal;
}

 /** @breif: Get Original User data
    * @param: the source message
    * @retVal: None
  */
void GetUserData(char *src, char *len, uint8_t start)
{
   int i,j,k;
   for (i=start,j=0,k=0;src[i] != '\0';i++)
   {
     if (i < start + 2)
     {
       len[j] = src[i]; j++;
     }
     else if(concate == 1)
     {
       i+=11;
       concate = 2;
       len[j] = '\0';
     }
     else
     {
       len[j] = '\0';
       src[k] = src[i];
       k++;
     }
   }
   src[k] = '\0';
}

 /** @breif: Decode PDU Message
    * @param: the source message
  * @param: the Destination Buffer
  * @param: the length of the message
    * @retVal: None
  */
void Decode_PDU(char *src,char *str,int UserDataLen)
{
   int data_len = strlen(src);
   uint8_t OriginalHex[data_len];
   GetOriginalHex(src,OriginalHex);
   PackHex(OriginalHex,data_len);
   if (IsLimited_Message(OriginalHex))
   {
     DecodeLimited_Message(OriginalHex,str,UserDataLen);
   }
   else
   {
     Decode_Original_Message(OriginalHex,str,UserDataLen);
   }
}


 /** @breif: Check if the message is limited message
    * @param: the source message
    * @retVal: true or false
  */
uint8_t IsLimited_Message(uint8_t *hex)
{
   if (hex[0]==0 && hex[2]==0 && hex[4]==0 && hex[6]==0 && hex[8]==0)   {   return 1;   }
   else                                                                 {   return 0; }
}

 /** @breif: Decode the limited message
    * @param: the source message
  * @param: the destination buffer
  * @param: length of the data
    * @retVal: None
  */
void DecodeLimited_Message(uint8_t *hex,char *dest,int UserDataLen)
{
   int i,j;
   for (i=1,j=0;i<UserDataLen;i+=2,j++)   dest[j] = hex[i];
   
   dest[j]='\0';
}


 /** @breif: Decode the Original message
    * @param: the source message
  * @param: the destination buffer
  * @param: length of the data
    * @retVal: None
  */
void Decode_Original_Message(uint8_t *hex,char *dest,int UserDataLen)
{
   int i,j;
   uint8_t DecValue[UserDataLen];
   Decode_Hex(hex,DecValue,UserDataLen);
   for (i=0,j=0;i<UserDataLen;i++,j++)
   {
     if (DecValue[i] == 0x11)  DecValue[j] = 95;
     else if (DecValue[i] == 0x1B)
     {
       i++;
       switch (DecValue[i])
       {
         case 0x28: DecValue[j] = 123;   break;
         case 0x29: DecValue[j] = 125;   break;
         case 0x14: DecValue[j] =  94;   break;
         case 0x2F: DecValue[j] =  92;   break;
         case 0x3C: DecValue[j] =  91;   break;
         case 0x3D: DecValue[j] = 126;   break;
         case 0x3E: DecValue[j] =  93;   break;
         case 0x40: DecValue[j] = 124;   break;
       }
     }
     else
       DecValue[j]=DecValue[i];
   }
   UserDataLen = j;
   if (concate == 2)
     UserDataLen -= 7;
   
   for (i=0;i<UserDataLen;i++)
     dest[i] = (char)DecValue[i];
   dest[i]='\0';
}

 /** @breif: Decode the Hex
    * @param: the source message
  * @param: the destination buffer
  * @param: length of the data
    * @retVal: None
  */
void Decode_Hex(uint8_t *hex,uint8_t *dest,int len)
{
   int i,j,l;
   uint8_t temp = 0x00, mask = 0xFF;
   int p = 0,q = 0;
   if (concate == 2)
   {
     temp = hex[0] >> 1;
     dest[0] = temp;
     dest[1] = hex[1] & 0x7F;
     temp = hex[1] >> 7;
     len = len - 7;
     p = 1; q = 1;
   }
   
   for (i=p,j=0,l=q;l<len;i++,j++,l++)
   {
     if (j==8)
     {
       dest[l] = temp & 0x7F;
       temp = temp>>7;
       j=1; l++;
     }
     dest[l] = ((hex[i] & (mask>>(j+1))) << j) | temp;
     temp = hex[i] >> (7-j);
     if (dest[l] == 0x00)     dest[l] = 0x40;
   }
}
THE ONLY CHANGE

This is the only function i changed while running in stm32... The below function (which i wrote in dev c) gives perfect output.

C:
  void PDU_to_Text(char *src,char *dest)
  {
     char Len[2];
     char str[150];
     int UserDataLen;
     uint8_t msg_no,total_msg;
     msg_no = 1;
     do
     {
       printf("\n\nEnter message %d: \n",msg_no);
       gets(src);
       concate = CheckForConcate(src);
       total_msg = CheckForTotal_msg(src);
       Remove_Carriag_LineFeed(src);
       Eliminate_Extras(src);
       uint8_t startingPoint = CheckStartingPoint(src);
       GetUserData(src,Len,startingPoint);
       UserDataLen = DecodeTwoBitData(Len);
       Decode_PDU(src,str,UserDataLen);
       if (msg_no==1)
         strcpy(dest,str);
       else
       {
         int i=0,j=0;
         while(dest[i]!='\0') {i++;}
         while(str[j]!='\0')
         {
           dest[i] = str[j];
           i++;j++;
         }
        str[j]='\0';
       }
       msg_no++;
         
     }while (msg_no <= total_msg);   
  }
I have no idea where i m going wrong. Any suggestions will be really helpful.

Thanks in advance.
 
Top