

/*********************************************************************
 *                   Flowcode GSM Component Code
 *
 * File: PIC_GSM.c
 *
 * (c) 2009 Matrix Multimedia Ltd.
 * http://www.matrixmultimedia.com
 *
 * Software License Agreement
 *
 * The software supplied herewith by Matrix Multimedia Ltd (the
 * “Company”) for its Flowcode graphical programming language is
 * intended and supplied to you, the Company’s customer, for use
 * solely and exclusively on the Company's products. The software
 * is owned by the Company, and is protected under applicable
 * copyright laws. All rights are reserved. Any use in violation
 * of the foregoing restrictions may subject the user to criminal
 * sanctions under applicable laws, as well as to civil liability
 * for the breach of the terms and conditions of this licence.
 *
 * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 *
 * Changelog:
 *
 *  date  | by | description
 * -------+----+-----------------------------------------------------
 * 150411 | BR | Created
 * 230711 | BR | Change to the way bytes are received to allow for better msg reception
 ********************************************************************/

/*********************************************************************

 Return & parameter types:
   void
   char
   short
   char*

 Pin directions:
   0 = OUTPUT
   2 = INPUT
   3 = BIDIRECTIONAL

**********************************************************************

[Settings]
CLSID={FC63F846-39C0-4BAF-BF23-9D007D092701}
IsAnalogue=0
MultipleAllowed=0
Description=GSM Flowcode Component

**********************************************************************

[Port]
DesiredPort=0
PortMandatory=0
SamePortAsID=0

[Pins]
Count=0

[PinPort]
# PORTA = 0
# PORTB = 1
# PORTC = 2
# PORTD = 3
# PORTE = 4

[PinDesiredBit]

[PinDirection]
# DIR_INPUT = 2
# DIR_OUTPUT = 0
# DIR_BIDIRECTIONAL = 3

[PinMustUsePort]
# boolean

[SamePortAsPinX]
# -1 = any pin
# otherwise, the pin number

[PinMustUsePin]
# boolean

[PinValue]
# boolean (0 = off, 1 = on)

**********************************************************************

[MacroNames]
Count=21
1=GSM_Send_Byte
2=GSM_Read_Byte
3=Initialize
4=CheckNetworkStatus
5=CheckSignalQuality
6=SendCommand
7=StringReceive
8=SendScript
9=CheckForIncoming
10=DialNumber
11=HangUpCall
12=AnswerIncomingCall
13=SendTextMessage
14=DeleteAllMessages
15=ReadString
16=GetTextNumber
17=GetTextString
18=TCPSocketInfo
19=GPRSTcpClientServer
20=SpCommand
21=CheckForData

[MacroReturns]
1=void
2=char
3=char
4=char
5=char
6=char
7=char
8=char
9=char
10=char
11=char
12=char
13=char
14=char
15=char*
16=char*
17=char*
18=char
19=char
20=char
21=char*


[MacroIsPrivate]
1=0
2=0
3=0
4=0
5=0
6=0
7=1
8=0
9=0
10=0
11=0
12=0
13=0
14=1
15=0
16=0
17=0
18=0
19=0
20=0
21=0

[MacroParameters_GSM_Send_Byte]
Count=1
1=byte

[MacroParamTypes_GSM_Send_Byte]
1=char

[MacroParameters_GSM_Read_Byte]
Count=0

[MacroParamTypes_GSM_Read_Byte]


[MacroParameters_Initialize]
Count=0

[MacroParamTypes_Initialize]


[MacroParameters_CheckNetworkStatus]
Count=0

[MacroParamTypes_CheckNetworkStatus]


[MacroParameters_CheckSignalQuality]
Count=0

[MacroParamTypes_CheckSignalQuality]


[MacroParameters_SendCommand]
Count=2
1=command
2=bSendCR

[MacroParamTypes_SendCommand]
1=char*
2=char

[MacroParameters_StringReceive]
Count=0

[MacroParamTypes_StringReceive]


[MacroParameters_SendScript]
Count=1
1=idx

[MacroParamTypes_SendScript]
1=char

[MacroParameters_CheckForIncoming]
Count=0

[MacroParamTypes_CheckForIncoming]


[MacroParameters_DialNumber]
Count=1
1=number

[MacroParamTypes_DialNumber]
1=char*

[MacroParameters_HangUpCall]
Count=0

[MacroParamTypes_HangUpCall]


[MacroParameters_AnswerIncomingCall]
Count=0

[MacroParamTypes_AnswerIncomingCall]


[MacroParameters_SendTextMessage]
Count=2
1=number
2=message

[MacroParamTypes_SendTextMessage]
1=char*
2=char*

[MacroParameters_DeleteAllMessages]
Count=0

[MacroParamTypes_DeleteAllMessages]


[MacroParameters_GetTextMessage]
Count=0

[MacroParamTypes_GetTextMessage]

[MacroParameters_GetTextNumber]
Count=0

[MacroParamTypes_GetTextNumber]

[MacroParameters_GetTextString]
Count=0

[MacroParamTypes_GetTextString]

[MacroParameters_TCPSocketInfo]
Count=2
1=ip
2=port

[MacroParamTypes_TCPSocketInfo]
1=char*
2=char*

[MacroParameters_GPRSTcpClientServer]
Count=1
1=SrCt

[MacroParamTypes_GPRSTcpClientServer]
1=char

[MacroParameters_SpCommand]
Count=2
1=command
2=bSendCR

[MacroParamTypes_SpCommand]
1=char*
2=char

[MacroParameters_CheckForData]
Count=0

[MacroParamTypes_CheckForData]

 ********************************************************************/

/********************************************************************
 * ADDITIONAL CODE
 ********************************************************************/

/*DefinesCode_Start*/

/**** Macro Substitutions ****
%a = Hardware Flow Control Enable
%b = RTS Pin
%c = CTS Pin
%d = GSM_232_BAUD Control
%e = Number of scripts
%f = Script 1
%g = Script 2
%h = Script 3
%i = Script 4
%j = High Speed BAUD Enable
******************************/

////////////////////////////////////////////////////
// MX_DEFINES
////////////////////////////////////////////////////
#if (%a == 1)
  #define GSM_232_HARDWARE
#endif

#define GSM_232_RTS				%b
#define GSM_232_CTS				%c
#define GSM_232_BAUD			%d
#define GSM_SCRIPT_COUNT		%e
#define GSM_232_UART			1

#if (GSM_SCRIPT_COUNT >= 1)
  const char* GSM_SCRIPT_1 = "%f";
#endif
#if (GSM_SCRIPT_COUNT >= 2)
  const char* GSM_SCRIPT_2 = "%g";
#endif
#if (GSM_SCRIPT_COUNT >= 3)
  const char* GSM_SCRIPT_3 = "%h";
#endif
#if (GSM_SCRIPT_COUNT >= 4)
  const char* GSM_SCRIPT_4 = "%i";
#endif

#if (%j == 1)
  #define GSM_232_USE64
#endif


//This section details the static defines, prototypes and functions.

//#define MX_DEBUG_GSM

#ifdef MX_UART_B
  #define MX_UART_PORT 				portb
  #define MX_UART_TRIS 				trisb
#endif
#ifdef MX_UART_C
  #define MX_UART_PORT 				portc
  #define MX_UART_TRIS 				trisc
#endif

#define GSM_STRING_ARRAY_SIZE 		80
#define MSG_ARRAY_SIZE 				80

#define GSM_RESPONSE_OK           	1
#define GSM_RESPONSE_ERROR        	2
#define GSM_RESPONSE_CONNECT      	3
#define GSM_RESPONSE_NOCARRIER    	4
#define GSM_RESPONSE_AUDIO        	5
#define GSM_RESPONSE_PAIR         	6
#define GSM_RESPONSE_RING         	7
#define GSM_EXPECTECHO

#define GSM_CHAR_CR              	13
#define GSM_CHAR_LF              	10

#define GSM_UART_STATUS_OK        	0
#define GSM_UART_STATUS_TIMEOUT   	1
#define GSM_UART_STATUS_LOOP      	2
#define GSM_UART_STATUS_FERR      	3
#define GSM_UART_STATUS_OERR      	4
#define GSM_TXIF_MASK				0x10
#define GSM_RCIF_MASK				0x20

//Timeout within the <BT_Send_Command> function (ms)
#define GSM_SENDCMD_TIMEOUT		 	75

//Timeout within the <BT_Wait_For_Response> function (ms)
#define GSM_RESPONSE_TIMEOUT     	75

//Timeout within the <BT_String_Receive> function (ms)
#define GSM_STRINGRX_TIMEOUT     	150

//Timeout within the <BT_Send_Script> function (ms)
#define GSM_SENDSCRIPT_TIMEOUT   	75

//common globals
char GSM_STRING_ARRAY[GSM_STRING_ARRAY_SIZE];
char GSM_MSG_ARRAY[MSG_ARRAY_SIZE];
char GSM_RX_LENGTH = 0;
char GSM_MSG_LENGTH = 0;
char GSM_RX_DONE = 0;
char GSM_NUMBER[14];

char GSM_MSG_C = 0;
char GSM_RING_C = 0;

/*DefinesCode_End*/

/*InitialisationCode_Start*/

    #ifndef MX_UART
		#error The target microcontroller does not have a UART
    #endif

    #ifdef GSM_232_HARDWARE
        #if(GSM_232_RTS == MX_UART_TX)
			#error RTS is set to TX pin
        #endif
        #if(GSM_232_CTS == MX_UART_TX)
			#error CTS is set to TX pin
        #endif
        #if(GSM_232_RTS == MX_UART_RX)
			#error RTS is set to RX pin
        #endif
        #if(GSM_232_CTS == MX_UART_RX)
			#error CTS is set to RX pin
        #endif
    #endif

	#ifdef GSM_232_HARDWARE
		set_bit(MX_UART_TRIS, GSM_232_CTS);        	//CTS is an input
		clear_bit(MX_UART_TRIS, GSM_232_RTS);      	//RTS is an output
		set_bit(MX_UART_PORT, GSM_232_RTS);         //not ready to accept data
	#endif

	#if GSM_232_UART == 1
		txsta = 0;                	// 8-bit, async, low speed, off
		spbrg = GSM_232_BAUD;      	// set the baud rate
		rcsta = 0;                	// 8-bit, disabled
		st_bit(rcsta, SPEN);      	// turn on serial interface
		st_bit(txsta, TXEN);
		st_bit(rcsta, CREN);
		#ifndef GSM_232_USE64
			st_bit(txsta, BRGH);	// high speed baud rate generator
		#endif
		st_bit (pie1, RCIE);		// Enable UART receive interrupts
	#endif

	#if GSM_232_UART == 2
		txsta2 = 0;                	// 8-bit, async, low speed, off
		spbrg2 = GSM_232_BAUD;      // set the baud rate
		rcsta2 = 0;                	// 8-bit, disabled
		st_bit(rcsta2, SPEN);      	// turn on serial interface
		st_bit(txsta2, TXEN);
		st_bit(rcsta2, CREN);
		#ifndef GSM_232_USE64
			st_bit(txsta2, BRGH);	// high speed baud rate generator
		#endif
		st_bit (pie4, RC2IE);		// Enable UART receive interrupts

	#endif

	st_bit (intcon, PEIE);						// Enable peripheral interrupts
	st_bit (intcon, GIE);						// Enable Global interrupts

	GSM_NUMBER[0] = 0;

  #ifdef GSM_232_HARDWARE
	clear_bit(MX_UART_PORT, GSM_232_RTS);        //ready to accept data
  #endif

/*InitialisationCode_End*/

/*InterruptCode_Start*/

	char tst = 0;
	char in;

	#if (GSM_232_UART == 1)
		tst = ts_bit(pir1, RCIF) && ts_bit(pie1, RCIE);
	#endif

	#if (GSM_232_UART == 2)
		tst = ts_bit(pir4, RC2IF) && ts_bit(pie4, RC2IE);
	#endif

	if (tst)										// Interrupt detected?
	{
		#if (GSM_232_UART == 1)
			cr_bit (pie1, RCIE);					// Disable UART receive interrupts
		#endif

		#if (GSM_232_UART == 2)
			cr_bit (pie4, RC2IE);					// Disable UART receive interrupts
		#endif

		in = GSM_Read_Byte();

		if ((in == 'R') && (GSM_RING_C == 0))
		{
			GSM_RING_C = 1;
		}
		else if (GSM_RING_C > 0)
		{
			if ((in == 'I') && (GSM_RING_C == 1))
			{
				GSM_RING_C = 2;
			}
			else
			{
				if ((in == 'N') && (GSM_RING_C == 2))
				{
					GSM_RING_C = 3;
				}
				else
				{
					if ((in == 'G') && (GSM_RING_C == 3))
					{
						GSM_RING_C = 4;
					}
					else
					{
						if (GSM_RING_C != 4)
							GSM_RING_C = 0;
					}
				}
			}
		}


		if ((in == '+') && (GSM_MSG_C == 0))
		{
			GSM_MSG_C = 1;
		}
		else if (GSM_MSG_C > 0)
		{
			if ((in == 'C') && (GSM_MSG_C == 1))
			{
				GSM_MSG_C = 2;
			}
			else
			{
				if ((in == 'M') && (GSM_MSG_C == 2))
				{
					GSM_MSG_C = 3;
				}
				else
				{
					if ((in == 'T') && (GSM_MSG_C == 3))
					{
						GSM_MSG_C = 7;
						GSM_MSG_LENGTH = 0;
					}
					else
					{
						if ((GSM_MSG_C < 4))
						{
							GSM_MSG_C = 0;
						}
						else
						{
							if ((GSM_MSG_C >= 7))
							{
								if ((GSM_MSG_C >= 10) && (in != '"'))			//Pull out phone number - 34 = '"'
								{
									GSM_NUMBER[GSM_MSG_C - 10] = in;
									GSM_MSG_C = GSM_MSG_C + 1;
								}
								else
								{
									if ((GSM_MSG_C >= 10) && (in == '"'))		//End of phone number - 34 = '"'
									{
										GSM_NUMBER[GSM_MSG_C - 10] = 0;
										GSM_MSG_C = 5;
									}
									else
									{
										GSM_MSG_C = GSM_MSG_C + 1;
									}
								}
							}
							else
							{
								if ((GSM_MSG_C == 5))			//Wait for end of Msg Header
								{
									if (in == 0x0A)
										GSM_MSG_C = 6;
								}
								else
								{
									if ((GSM_MSG_C == 6))			//Collect Msg Text
									{
										if (in == 0x0A)
										{
											if (GSM_MSG_LENGTH < MSG_ARRAY_SIZE)
											{
												GSM_MSG_ARRAY[GSM_MSG_LENGTH] = 0;
											}
											GSM_MSG_C = 4;
										}
										else if (GSM_MSG_LENGTH < MSG_ARRAY_SIZE)
										{
											GSM_MSG_ARRAY[GSM_MSG_LENGTH] = in;
											GSM_MSG_LENGTH = GSM_MSG_LENGTH + 1;
										}

									}

								}
							}
						}
					}
				}
			}
		}

		if (GSM_RX_DONE == 0)
		{
			if (GSM_RX_LENGTH < GSM_STRING_ARRAY_SIZE)
			{
				if (in == 0x0A)
				{
					GSM_RX_DONE = 1;
					GSM_STRING_ARRAY[GSM_RX_LENGTH] = 0;
				}
				else
				{
					GSM_STRING_ARRAY[GSM_RX_LENGTH] = in;
					GSM_RX_LENGTH = GSM_RX_LENGTH + 1;
				}
			}
		}

		#if (GSM_232_UART == 1)
			st_bit (pie1, RCIE);						// Enable UART receive interrupts
			cr_bit (pir1, RCIF);						// Clear interrupt
		#endif

		#if (GSM_232_UART == 2)
			st_bit (pie4, RC2IE);						// Enable UART receive interrupts
			cr_bit (pir4, RC2IF);						// Clear interrupt
		#endif
	}

/*InterruptCode_End*/

/********************************************************************
 * FUNCTIONS
 ********************************************************************/

void GSM_Send_Byte(char byte)
{
/*Macro_GSM_Send_Byte_Start*/

	#if (GSM_232_UART == 1)

		st_bit(txsta, TXEN);
		while (ts_bit(pir1, TXIF) == 0);
		txreg = byte;

	#endif

	#if (GSM_232_UART == 2)

		st_bit(txsta2, TXEN);
		while (ts_bit(pir4, TX2IF) == 0);
		txreg2 = byte;

	#endif

/*Macro_GSM_Send_Byte_End*/
}


char GSM_Read_Byte()
{
/*Macro_GSM_Read_Byte_Start*/

	char delay1 = 0;
	char dummy = 0;
	char retVal = 255;

	#if (GSM_232_UART == 1)						//UART1

		st_bit(rcsta, CREN);

		if (ts_bit(pir1, RCIF) != 0)
		{
			if (ts_bit(rcsta, FERR) != 0)		//received a Char
				dummy = rcreg;      			//need to read the rcreg to clear FERR
			else
			{
				if (ts_bit(rcsta, OERR) != 0)
				{
					cr_bit(rcsta, CREN);		//disable receiver
					st_bit(rcsta, CREN);		//enable receiver
					dummy = rcreg;				//finally, read the rcreg to clear error
				}
				else
					retVal = rcreg; 			//no error, so rx byte is valid
			}
		}

	#endif

	#if (GSM_232_UART == 2)						//UART2

		st_bit(rcsta2, CREN);

		if (ts_bit(pir4, RC2IF) != 0)
		{
			if (ts_bit(rcsta2, FERR) != 0)		//received a Char
				dummy = rcreg2;      			//need to read the rcreg to clear FERR
			else
			{
				if (ts_bit(rcsta2, OERR) != 0)
				{
					cr_bit(rcsta2, CREN);		//disable receiver
					st_bit(rcsta2, CREN);		//enable receiver
					dummy = rcreg2;				//finally, read the rcreg to clear error
				}
				else
					retVal = rcreg2; 			//no error, so rx byte is valid
			}
		}

	#endif

    return (retVal);
/*Macro_GSM_Read_Byte_End*/
}


char StringReceive()
{
/*Macro_StringReceive_Start*/

//0=timeout
//1=valid data

	char tout = 0;
	char len = GSM_RX_LENGTH;

	GSM_RX_DONE = 0;
	GSM_RX_LENGTH = 0;

    while ((GSM_RX_DONE == 0) && (tout < 255))
    {
		tout = tout + 1;
		if (len != GSM_RX_LENGTH)
		{
			tout = 0;
			len = GSM_RX_LENGTH;
		}
		delay_10us(50);
    }

    if (tout == 255)
    {
		GSM_RX_DONE = 0;
		GSM_RX_LENGTH = 0;
    	return 0;
	}
    return 1;

/*Macro_StringReceive_End*/
}


char Initialize()
{
/*Macro_Initialize_Start*/

//0=ok
//255=no reply
//254=Command not accepted

	char Retval;

	StringReceive();

	Retval = SendCommand("AT+CMGF=1",9,1);		//Default: Format SMS message as text

	if (Retval)
		return Retval;

	if ((GSM_STRING_ARRAY[0] != 'O') || (GSM_STRING_ARRAY[1] != 'K'))
	{
		return 254;
	}

	Wdt_Delay_Ms(100);

	Retval = SendCommand("AT+CNMI=2,2,0,0,0",17,1);		//Default: SMS is not stored

	if (Retval)
		return Retval;

	if ((GSM_STRING_ARRAY[0] != 'O') || (GSM_STRING_ARRAY[1] != 'K'))
	{
		return 254;
	}

	Wdt_Delay_Ms(100);

	return Retval;

/*Macro_Initialize_End*/
}



char CheckNetworkStatus()
{
/*Macro_CheckNetworkStatus_Start*/

//0 = not connected
//1 = connected
//255 = no reply

	char retval = 0;

	SendCommand("AT+CREG?",8,1);		//Check network status

	if ( StringReceive() == 0)
		return 255;

	if ( GSM_STRING_ARRAY[7] == '0' || GSM_STRING_ARRAY[7] == '1' && GSM_STRING_ARRAY[9] == '1' || GSM_STRING_ARRAY[9] == '5')
		retval = 1;

	StringReceive();
	StringReceive();
	Wdt_Delay_Ms(100);

	return retval;

/*Macro_CheckNetworkStatus_End*/
}



char CheckSignalQuality()
{
/*Macro_CheckSignalQuality_Start*/

//0 = not connected
//1 = connected
//255 = no reply

	char retval = 0;

	SendCommand("AT+CSQ?",7,1);		//Check signal quality

	if ( StringReceive() == 0)
		return 255;

	if ( GSM_STRING_ARRAY[7] == '0' && GSM_STRING_ARRAY[9] == '1' )
		retval = 1;

	StringReceive();
	StringReceive();
	Wdt_Delay_Ms(100);

	return retval;

/*Macro_CheckSignalQuality_End*/
}


char SendCommand(char* command, char MSZ_command, char bSendCR)
{
/*Macro_SendCommand_Start*/

//0=ok
//253=CONNECT
//254=Error
//255=no reply

    char idx = 0;
    char dummy;

	while ( StringReceive());			//Purge any unwanted data

    if (MSZ_command > 0)
    {
        while ((idx < MSZ_command) && (command[idx] != 0))
        {
            GSM_Send_Byte(command[idx]);
            idx++;
        }
        if (bSendCR)
        {
            GSM_Send_Byte(GSM_CHAR_CR);     //send the terminating CR
        }
    }	
	
	#ifdef GSM_EXPECTECHO
		StringReceive();					//Collect Echo
	#endif

		
	if ( StringReceive() == 0)
	{
		return 255;
	}
	
	if ((GSM_STRING_ARRAY[0] == 'O') && (GSM_STRING_ARRAY[1] == 'K'))
	return 0;

	if ((GSM_STRING_ARRAY[0] == 'E') && (GSM_STRING_ARRAY[4] == 'R'))
	return 254;

	if ((GSM_STRING_ARRAY[0] == 'C') && (GSM_STRING_ARRAY[6] == 'T'))
	return 253;

	

/*Macro_SendCommand_End*/
}


char SendScript(char idx)
{
/*Macro_SendScript_Start*/
    char i = 0;
    char ch = 255;
    char retval = 0;

    if ((idx < 1) || (idx > GSM_SCRIPT_COUNT))
    {
        return (0xFF);        //error - index out of range
    }
    while (ch > 0)
    {
        switch (idx)
        {
          #if (GSM_SCRIPT_COUNT >= 1)
            case 1:
                ch = GSM_SCRIPT_1[i];
                break;
          #endif

          #if (GSM_SCRIPT_COUNT >= 2)
            case 2:
                ch = GSM_SCRIPT_2[i];
                break;
          #endif

          #if (GSM_SCRIPT_COUNT >= 3)
            case 3:
                ch = GSM_SCRIPT_3[i];
                break;
          #endif

          #if (GSM_SCRIPT_COUNT == 4)
            case 4:
                ch = GSM_SCRIPT_4[i];
                break;
          #endif

            default:
                return (0xFF);    //should not get here
        }

        if (ch > 0)
        {
            //send the character
            GSM_Send_Byte(ch);

            //if we sent a CR, wait for the response
            if (ch == 13)
            {
				#ifdef GSM_EXPECTECHO
					StringReceive();					//Collect Echo
				#endif

				retval = StringReceive();				//Collect Reply

				while ( StringReceive());				//Make sure we have received everything
            }
        }
        i = i + 1;
    }
    return (retval);
/*Macro_SendScript_End*/
}


char CheckForIncoming ()
{
/*Macro_CheckForIncoming_Start*/

	StringReceive();		//Read any incoming messages

	if (GSM_MSG_C == 4)											//Text has been received
	{
		GSM_MSG_C = 0;
		return 1;											//Text Received
	}
	else if (GSM_RING_C == 4)
	{
		GSM_RING_C = 0;
		return 2;											//Phone Ringing
	}
	return 0;

/*Macro_CheckForIncoming_End*/
}


char DialNumber (char* number)
{
/*Macro_DialNumber_Start*/

	char idx;

	GSM_Send_Byte('A');
	GSM_Send_Byte('T');
	GSM_Send_Byte('D');

	for (idx=0; idx<MSZ_number; idx++)
	{
		GSM_Send_Byte(number[idx]);
	}

	GSM_Send_Byte(';');
	GSM_Send_Byte(GSM_CHAR_CR);

	StringReceive();

	if ((GSM_STRING_ARRAY[0] == 'O') && (GSM_STRING_ARRAY[1] == 'K'))
		return 0;

	return 255;

/*Macro_DialNumber_End*/
}



char HangUpCall ()
{
/*Macro_HangUpCall_Start*/

	GSM_Send_Byte('A');
	GSM_Send_Byte('T');
	GSM_Send_Byte('H');
	GSM_Send_Byte(GSM_CHAR_CR);

	StringReceive();

	if (GSM_STRING_ARRAY[0] == 'O')
		return 0;

	return 255;

/*Macro_HangUpCall_End*/
}



char AnswerIncomingCall()
{
/*Macro_AnswerIncomingCall_Start*/

	GSM_Send_Byte('A');
	GSM_Send_Byte('T');
	GSM_Send_Byte('A');
	GSM_Send_Byte(GSM_CHAR_CR);

	StringReceive();

	if (GSM_STRING_ARRAY[0] == 'O')
		return 0;

	return 255;

/*Macro_AnswerIncomingCall_End*/
}



char SendTextMessage (char* number, char* message)
{
/*Macro_SendTextMessage_Start*/

	char idx;

	GSM_Send_Byte('A');
	GSM_Send_Byte('T');
	GSM_Send_Byte('+');
	GSM_Send_Byte('C');
	GSM_Send_Byte('S');
	GSM_Send_Byte('M');
	GSM_Send_Byte('P');
	GSM_Send_Byte('=');
	GSM_Send_Byte('1');
	GSM_Send_Byte('7');
	GSM_Send_Byte(',');
	GSM_Send_Byte('1');
	GSM_Send_Byte('6');
	GSM_Send_Byte('7');
	GSM_Send_Byte(',');
	GSM_Send_Byte('0');
	GSM_Send_Byte(',');
	GSM_Send_Byte('0');
	GSM_Send_Byte(GSM_CHAR_CR);

	StringReceive();
	Wdt_Delay_Ms(100);

	GSM_Send_Byte('A');
	GSM_Send_Byte('T');
	GSM_Send_Byte('+');
	GSM_Send_Byte('C');
	GSM_Send_Byte('S');
	GSM_Send_Byte('D');
	GSM_Send_Byte('H');
	GSM_Send_Byte('=');
	GSM_Send_Byte('1');
	GSM_Send_Byte(GSM_CHAR_CR);

	StringReceive();
	Wdt_Delay_Ms(100);

	GSM_Send_Byte('A');
	GSM_Send_Byte('T');
	GSM_Send_Byte('+');
	GSM_Send_Byte('C');
	GSM_Send_Byte('M');
	GSM_Send_Byte('G');
	GSM_Send_Byte('S');
	GSM_Send_Byte('=');
	GSM_Send_Byte('"');

	for (idx=0; idx<MSZ_number; idx++)
	{
		if (number[idx] == 0)
			break;

		GSM_Send_Byte(number[idx]);
	}

	GSM_Send_Byte('"');
	GSM_Send_Byte(GSM_CHAR_CR);

	StringReceive();
	Wdt_Delay_Ms(100);

	for (idx=0; idx<MSZ_message; idx++)
	{
		if (message[idx] == 0)
			break;

		GSM_Send_Byte(message[idx]);
	}

	GSM_Send_Byte(26);
	StringReceive();
	Wdt_Delay_Ms(100);

	if (GSM_STRING_ARRAY[0] == 'O')
		return 0;

	return 255;

/*Macro_SendTextMessage_End*/
}



char DeleteAllMessages()
{
/*Macro_DeleteAllMessages_Start*/

	SendCommand("AT+CMGD=1,4",11,1);

	StringReceive();

	if (GSM_STRING_ARRAY[0] == 'O')
		return 0;

	return 255;

/*Macro_DeleteAllMessages_End*/
}



void ReadString (char* FCR_RETVAL, char FCR_RETVAL_SIZE)
{
/*Macro_ReadString_Start*/

	char idx = 0;

	while ((idx < FCR_RETVAL_SIZE) && (GSM_STRING_ARRAY[idx] > 0))
	{
		FCR_RETVAL[idx] = GSM_STRING_ARRAY[idx];
		idx = idx + 1;
	}
	if (idx < FCR_RETVAL_SIZE)
		FCR_RETVAL[idx] = 0;			//String termination

/*Macro_ReadString_End*/
}



void GetTextNumber (char* FCR_RETVAL, char FCR_RETVAL_SIZE)
{
/*Macro_GetTextNumber_Start*/

	char idx = 0;

	while (idx < FCR_RETVAL_SIZE && GSM_NUMBER[idx] > 0 )
	{
		FCR_RETVAL[idx] = GSM_NUMBER[idx];
		idx = idx + 1;
	}
	if (idx < FCR_RETVAL_SIZE)
		FCR_RETVAL[idx] = 0;			//String termination

/*Macro_GetTextNumber_End*/
}



void GetTextString (char* FCR_RETVAL, char FCR_RETVAL_SIZE)
{
/*Macro_GetTextString_Start*/

	char idx = 0;

	while ((idx < GSM_MSG_LENGTH) && (GSM_MSG_ARRAY[idx] > 0))
	{
		FCR_RETVAL[idx] = GSM_MSG_ARRAY[idx];
		idx = idx + 1;
	}
	if (idx < FCR_RETVAL_SIZE)
		FCR_RETVAL[idx] = 0;			//String termination

	DeleteAllMessages();

/*Macro_GetTextString_End*/
}

char TCPSocketInfo (char* ip, char* port)
{
/*Macro_TCPSocketInfo_Start*/

//0=ok
//254=Error
//255=no reply

	char idx;
	char retval=0;

	GSM_Send_Byte('A');
	GSM_Send_Byte('T');
	GSM_Send_Byte('+');
	GSM_Send_Byte('W');
	GSM_Send_Byte('I');
	GSM_Send_Byte('P');
	GSM_Send_Byte('C');
	GSM_Send_Byte('R');
	GSM_Send_Byte('E');
	GSM_Send_Byte('A');
	GSM_Send_Byte('T');
	GSM_Send_Byte('E');
	GSM_Send_Byte('=');
	GSM_Send_Byte('2');
	GSM_Send_Byte(',');
	GSM_Send_Byte('1');
	GSM_Send_Byte(',');
	GSM_Send_Byte('"');

	for (idx=0; idx<MSZ_ip; idx++)
	{
		if (ip[idx] == 0)
			break;

		GSM_Send_Byte(ip[idx]);
	}

	GSM_Send_Byte('"');
	GSM_Send_Byte(',');
	
	for (idx=0; idx<MSZ_port; idx++)
	{
		if (port[idx] == 0)
			break;

		GSM_Send_Byte(port[idx]);
	}

	GSM_Send_Byte(GSM_CHAR_CR);
		
	while ( StringReceive()==0);
	
		
	if ((GSM_STRING_ARRAY[0] == 'E') && (GSM_STRING_ARRAY[4] == 'R'))
		return 254;

	if ((GSM_STRING_ARRAY[0] == 'O') && (GSM_STRING_ARRAY[1] == 'K'))
		retval = 0;
		
	StringReceive();
	StringReceive();
	Wdt_Delay_Ms(100);
		
	return retval;

/*Macro_TCPSocketInfo_End*/
}


char GPRSTcpClientServer(char SrCt)
{
/*Macro_GPRSTcpClientServer_Start*/

//0 = OK
//254 = Error
//255 = No Reply

	char retval = 0;
	char idx;
		
	GSM_Send_Byte('A');
	GSM_Send_Byte('T');
	GSM_Send_Byte('+');
	GSM_Send_Byte('W');
	GSM_Send_Byte('I');
	GSM_Send_Byte('P');
	GSM_Send_Byte('B');
	GSM_Send_Byte('R');
	GSM_Send_Byte('=');
	GSM_Send_Byte('4');
	GSM_Send_Byte(',');
	GSM_Send_Byte('6');
	GSM_Send_Byte(',');
	
 	if (SrCt)
        GSM_Send_Byte('1');     //send 1
	else if (SrCt==0)
	GSM_Send_Byte('0');     //send 0

	GSM_Send_Byte(GSM_CHAR_CR);
	
	while ( StringReceive()==0);
			
	if ((GSM_STRING_ARRAY[0] == 'E') && (GSM_STRING_ARRAY[4] == 'R'))
		return 254;
	
	if ((GSM_STRING_ARRAY[0] == 'O') && (GSM_STRING_ARRAY[1] == 'K'))
		retval = 0;
	
	StringReceive();
	StringReceive();
	Wdt_Delay_Ms(100);

	return retval;

/*Macro_GPRSTcpClientServer_End*/
}

char SpCommand(char* command, char MSZ_command, char bSendCR)
{
/*Macro_SpCommand_Start*/

//0=ok
//253=CONNECT
//254=Error
//255=No reply

    char idx = 0;
   
	while ( StringReceive());			//Purge any unwanted data

    if (MSZ_command > 0)
    {
        while ((idx < MSZ_command) && (command[idx] != 0))
        {
            GSM_Send_Byte(command[idx]);
            idx++;
        }
        if (bSendCR)
        
            GSM_Send_Byte(GSM_CHAR_CR);     //send the terminating CR
        
    }	    
	while ( StringReceive()==0);

	if ((GSM_STRING_ARRAY[0] == 'O') && (GSM_STRING_ARRAY[1] == 'K'))
		return 0;

	if ((GSM_STRING_ARRAY[0] == 'E') && (GSM_STRING_ARRAY[4] == 'R'))
		return 254;

	if ((GSM_STRING_ARRAY[0] == 'C') && (GSM_STRING_ARRAY[6] == 'T'))
		return 253;


/*Macro_SpCommand_End*/
}
void CheckForData (char* FCR_RETVAL, char FCR_RETVAL_SIZE)
{
/*Macro_CheckForData_Start*/

	char idx = 0;
	
	while ( StringReceive()==0);

	while ((idx < FCR_RETVAL_SIZE) && (GSM_STRING_ARRAY[idx] > 0))
	{
		FCR_RETVAL[idx] = GSM_STRING_ARRAY[idx];
		idx = idx + 1;
	}
	if (idx < FCR_RETVAL_SIZE)
		FCR_RETVAL[idx] = 0;			//String termination


/*Macro_CheckForData_End*/
}
