CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

STRSTR PROBLEM

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
rudy



Joined: 27 Apr 2008
Posts: 167

View user's profile Send private message Send e-mail MSN Messenger

STRSTR PROBLEM
PostPosted: Mon Sep 18, 2023 6:26 am     Reply with quote

Hi, I am finalizing a program to read and control a SIM800 module, but strstr function seems to not work properly in a specific location of the routine. This is how I declare variables and buffers.

Code:
#include <18F2550.h>
#fuses INTRC, PLL5, CPUDIV1, NOWDT, NOFCMEN, NOIESO, NOCPD, NOPROTECT, NOLVP, NODEBUG, NOPUT, NOBROWNOUT, NOMCLR
#device PASS_STRINGS=IN_RAM
#use delay(clock=8000000)
#use I2C(MASTER, I2C1)
#use RS232(BAUD=9600, UART1, ERRORS)

#byte PORTA=0xF80
#byte PORTB=0xF81
#byte PORTC=0xF82
#byte PORTE=0xF84

///////////////////////SMS FUNCTIONS/////////////////////
// XXXX PASSWORD -> FIRS 4 CHARACTERS ON ALL MSG
// RLX ON -> TURN ON X RELAYS
// RLX OFF -> TURN OFF X RELAYS
// ALL ON# -> ALL RELAYS ON
// ALL OFF# -> ALL RELAYS OFF
// INVERT# -> INVERTED RELAYS STATES
// RST# -> RESET SMS COUNTERS AND SIM CARD STORAGE SMS
// NEW# -> CHANGE SMS PASSWORD, OLD PASSWORS MUST BE PROVIDED
/////////////////////////////////////////////////////////

/////////////////SYSTEM VARS////////////////////
int D1, D2, D3, D4, D5, FLAG_0, FLAG_1, FLAG_2=0X00;
int AUX_0=0X00;
/////////////////LCD VARS////////////////////////
int PX_X, PX_Y, LCD_OPR, PLT=0X4B;
/////////////////GSM VARS////////////////////////
int BFR_CNT, AUX_GSM_0=0X00;
long SMS_INN, SMS_OUT;
char TMP_CHAR;
char GSM_BFR[128]=""; //GSM BUFFER
char GSM_PASS[5]=""; //GSM PASSWORD
char * PCH;
/////////////////TEMPERATURE VARS/////////////////
long TEMPNOW=0X0000;

In the beginning of the routine to check SMS, I use this:
Code:
PCH=strstr(GSM_BFR,"+CMT"); //AVOID "OK" OR MISMATCH RETURN FROM SIM800 AFTER PUTC(0x1A)
if(PCH!=NULL)SMS_INN++;    //SMS INCOMING UPDATE AVOID "OK" AND SO...

Works fine, all +CMT is detected properly, but now I need to check if the incoming SMS have the PASSWORD, a 4 byte char string, in other to enter effectively in the code to "answer" to the incoming SMS, and that’s is the problem. Sometimes it works, sometimes it not. This is the line I created to do this:
Code:
PCH=strstr(GSM_BFR,GSM_PASS); //CHECK GSM KEY
if(PCH!=NULL)GSM_KEY=1; //GSM_KEY=1;
if(GSM_KEY) //PASSWOR ACCEPTED

Somehow, the GSM_PASS seems not to be found in the GSM_BFR, and I really don’t know how.

1 – Do I really need the NULL '\0' terminator at the end of the GSM_PASS string?
2 – This line “PCH=strstr(GSM_BFR,GSM_PASS);” is correct?
3 – How may I see or check if there is an stack overflow issue, can somebody help me?

Regards;
Ttelmah



Joined: 11 Mar 2010
Posts: 19229

View user's profile Send private message

PostPosted: Mon Sep 18, 2023 7:42 am     Reply with quote

First thing, tidy up your clock settings. The PLL and the CPUDIV, do not
apply when using the internal oscillator. It should default to 8MHz, but
make sure.
So:
Code:

#include <18F2550.h>
#fuses NOWDT, NOFCMEN, NOIESO, NOCPD, NOPROTECT, NOLVP, NODEBUG, NOPUT, NOBROWNOUT, NOMCLR, STVREN
#device PASS_STRINGS=IN_RAM
#use delay(INTERNAL=8MHz)
#use I2C(MASTER, I2C1)
#use RS232(BAUD=9600, UART1, ERRORS)


The 'INTERNAL' syntax sets all the fuses etc., to suit the internal oscillator.

Now, we can't tell if the syntax is right. You don't show where/how you are
putting the string into the GSM_PASS array.

Yes, a string is just a character array, _with a null terminator_. It is not
a string as such until this exists. However some operations will add this
for you. Depending on how you are writing the data, it is possible that
you are overflowing the array by adding an extra terminator where one
is not needed. You need to show us how you are writing this string.
The "" generates a blank string with a null terminator. Remember though
that if the blank password is (for example), four spaces, this would need
to be declared as " ". With GSM_PASS as currently shown, strstr will
not work, since it does not search for the terminating character, and you
show GSM_PASS containing nothing except the terminator. The function
will just retiurn 0 when this is the case, whatever is in the other string.

On the stack, add the fuse STVREN. This will make the chip reset if a
stack overflow occurs. The PIC18, does not have a software stack (so the
stack is not used for variables), it only has a function call stack. So a
stack overflow as a result of code, is not likely to happen. How many stack
levels are needed for the functions is displayed at the top of the listing
file after compilation. Open this.
About ten lines down it'll have a line saying 'Stack used x locations'.
The limit is 31 locations on this chip, but keep it a couple less if using an
ICD.
rudy



Joined: 27 Apr 2008
Posts: 167

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Mon Sep 18, 2023 8:01 am     Reply with quote

Well, thanks for helping me, Ttelmah.
I fill the GSM_PASS this way:
Code:
void MAIN()
   {
   SETUP_ADC_PORTS(NO_ANALOGS);   
   SETUP_COMPARATOR(NC_NC_NC_NC);
   SETUP_COUNTERS(RTCC_INTERNAL,RTCC_DIV_1);
   SETUP_TIMER_1(T1_INTERNAL|T1_DIV_BY_8);
   SETUP_TIMER_2(T2_DISABLED,0XFF,16);
   SETUP_TIMER_3(T3_DISABLED);
   SET_TRIS_A(0b11111111); 
   SET_TRIS_B(0b11111111);
   SET_TRIS_C(0b11111111);
   SET_TRIS_E(0b11111111);
   PORT_B_PULLUPS(0b00000000);
   DELAY_MS(500);
   GSM_INIT();
   LCD_INIT();
   LCD_CLS(0, 0X85, 0XB0, 0XB7, 0B0000000); //X1, X2, Y1, Y2, COLOR
   LCD_SCREEN_01();
   TS_INIT();
   DELAY_MS(100);
   TS_INIT();
   TS_CONVERT();
   //BOOT START
   D1=READ_EEPROM(0X00); //READ BOOT STATE
   if(!D1) //D0=0, BOOTED BEFORE
      {
       FLAG_0=READ_EEPROM(0X01); //RELES STATES
       D2=READ_EEPROM(0X02); //SMS_INN HIGH BYTE
       D3=READ_EEPROM(0X03); //SMS_INN LOW BYTE
       D4=READ_EEPROM(0X04); //SMS_OUT HIGH BYTE
       D5=READ_EEPROM(0X05); //SMS_OUT LOW BYTE
       SMS_INN=MAKE16(D2,D3); //MAKE SMS_INN
       SMS_OUT=MAKE16(D4,D5); //MAKE SMS_OUT
       for(D1=0;D1<4;D1++)GSM_PASS[D1]=READ_EEPROM(D1+0X06); //GSM PASSWORD
       }
    else //D0=0XFF -> FIRST BOOT
       {
       FLAG_0=0X01; //ALL RELES OFF + EE_UPD=1
       SMS_INN=0X0000; //SMS_INN=0X0000
       SMS_OUT=0X0000; //SMS_OUT=0X0000
       GSM_PASS="1234"; //RESET GSM PASSWAORD          
       }
     GSM_PASS[4]='\0'; //GSM_PASS NULL TERMINATOR
     LCD_TMP=1;
     LCD_SMS=1;
     LCD_RLS=1;
     BFR_CNT=0;
     BFR_CLS();
      ENABLE_INTERRUPTS(INT_TIMER1);
      ENABLE_INTERRUPTS(INT_RDA); 
   ENABLE_INTERRUPTS(GLOBAL);      

So, when first BOOT, the EEPROM Address 0X00 will be 0XFF, and I write direct to the GSM_PASS the default password “1234” and a NULL terminator at the end.

In the GSM response routine, there is a function to CHANGE the default password, if the SMS message contains the string “NEW#” as follows:
Code:
      //PASSWORD CHANGE
      PCH=strstr(GSM_BFR,"NEW#"); //STRING => NEW#
      if(PCH!=NULL)
         {
         for(D1=0;D1<120;D1++)
            {
            if((GSM_BFR[D1]==0X4E)&&(GSM_BFR[D1+1]==0X45)&&(GSM_BFR[D1+2]==0X57)&&(GSM_BFR[D1+3]==0X23)) //DETECT "NEW#"
               {
               GSM_PASS[0]=GSM_BFR[D1+5];
               GSM_PASS[1]=GSM_BFR[D1+6];
               GSM_PASS[2]=GSM_BFR[D1+7];
               GSM_PASS[3]=GSM_BFR[D1+8];
               GSM_PASS[4]='\0'; //GSM_PASS NULL TERMINATOR
               NEW_PASS=1; //NEW PASSWORD
               break;
               }
            }
         }

Please help me to solve this matter.

Regards,
Ttelmah



Joined: 11 Mar 2010
Posts: 19229

View user's profile Send private message

PostPosted: Mon Sep 18, 2023 10:28 am     Reply with quote

Major issue here:

GSM_PASS="1234"; //RESET GSM PASSWAORD

That is not how to change a string. You can set a string like this when
it is declared as a variable, but you cannot set a string 'inline' like this.
You have to use:

strcpy(GSM_PASS, "1234");
rudy



Joined: 27 Apr 2008
Posts: 167

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Mon Sep 18, 2023 3:38 pm     Reply with quote

Ttelmah, thanks. I will do that. But when I change GSM_PASS on the go, so I have to write '\0' to the last position or not?

Another issue is that when I use the FUSES as this:
Quote:
#fuses INTRC, NOWDT, NOFCMEN, NOIESO, NOCPD, NOPROTECT, NOLVP, NODEBUG, NOPUT, NOBROWNOUT, NOMCLR, STVREN
The processor goes too slow, But when I add PPL5 and CPUDIV1, it runs well.

But Let's focus on the
Code:
   PCH=strstr(GSM_BFR,GSM_PASS); //CHECK GSM KEY
Why this instruction sometimes works and sometimes not, that is my major issue. Reading the CCS Manual, it says: "s1 and s2 are pointers to an array of characters (or the name of an array). Note that s1 and s2 MAY NOT BE A CONSTANT (like "hi")", and it is not! This problem is really an issue that I cannot solve by myself, need an expert to help me.

Regards;
rudy



Joined: 27 Apr 2008
Posts: 167

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Mon Sep 18, 2023 9:10 pm     Reply with quote

Well, I take off all NULL terminator insertion in the GSM_PASS string, but not sure this was the problerm, so I make this: (Call it BRUTE FORCE)
Code:
   for(D1=0;D1<100;D1++) //DETECT PASSWORD - BRUTE FORCE
      {
      if((GSM_BFR[D1]==GSM_PASS[0])&&(GSM_BFR[D1+1]==GSM_PASS[1])&&(GSM_BFR[D1+2]==GSM_PASS[2])&&(GSM_BFR[D1+3]==GSM_PASS[3]))
         {
         GSM_KEY=1;
         break;
         }
      }

I am testing it, till now, no issues, working smooth and pritty well.

Regards;
Ttelmah



Joined: 11 Mar 2010
Posts: 19229

View user's profile Send private message

PostPosted: Wed Sep 20, 2023 10:59 am     Reply with quote

On the clock setup, you are missing the second key point, that you have
to change the clock setup:

#use delay(INTERNAL=8MHz)

INTERNAL, not CLOCK

It is this that makes the setting work correctly.

On the string terminators, if you use the string functions, the terminator
is automatically generated and added. You should not be adding one yourself.
It'd cause a problem with your string done using the = allocation, since
the pointer then no longer points to a real string, but instead points to
the virtual buffer created by the compiler. Writing explicitly to this would
cause disaster.
rudy



Joined: 27 Apr 2008
Posts: 167

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Wed Sep 20, 2023 6:43 pm     Reply with quote

Hum...... Will be that the reason off all problems? Because I was simple running at the wrong clock frequency speed, and the errors I got was totally “random” with no logical explanation.
Thaks for now! I will test it!
Regards;
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group