I have successfully sent a multipart pdu sms,
The problem is when i try to send this SMS to a number on a different network it gives me the following error :
+CMGS ERROR:500
Please can any one tell me what should i do.
atCommandStr = "AT+CMGF=0\r";
comPort.WriteLine(atCommandStr + (char)13);
Console.WriteLine(comPort.ReadExisting());
Thread.Sleep(2000);
for (int i = 0; i < number_of_parts; i++)
{
int oct = (messagesParts[i].ToCharArray().Count() / 2) -1;
atCommandStr = "AT+CMGS=" + oct + "\r";
comPort.WriteLine(atCommandStr + (char)13);
Console.WriteLine(comPort.ReadExisting());
Thread.Sleep(2000);
string path;
path = messagesParts[i] + Char.ConvertFromUtf32(26);
comPort.WriteLine(path + (char)13);
for (int a = 0; a < 100; a++)
{
Thread.Sleep(2000);
string t = comPort.ReadExisting();
Console.WriteLine(t);
if (t != "" && t.Contains("CMGS") || t.Contains("ERROR"))
{
break;
}
}
//Console.WriteLine(comPort.ReadExisting());
}
Did the modem really return +CMGS ERROR:500 and not +CMS ERROR: 500? Because in that case, your modem is not compliant with the 27.005 standard which specifies if sending fails: +CMS ERROR: <err>.
Error code 500 means unknown error, so that does not help very much. But I would guess that your length calculation is wrong. From the standard:
<length> must indicate the number of octets coded in the TP layer data unit
to be given (i.e. SMSC address octets are excluded).
Is it correct to subtract 1 after dividing by 2? Try to decode exactly what will be sent on TP layer. Try to increase/decrease the length a bit and see if it makes any difference.
Also, since atCommandStr already contains \r you should not include the + (char)13 in
comPort.WriteLine(atCommandStr + (char)13);
Related
Details about the application:
Developed under Visual Studio 2019 (Windows 10)
Designed on the UWP platform with C# and the XAML language
The application receives information from a remote server. A connection via Socket is used for communication between the two parties.
The server sent by frame a message, and in this message we find several essential elements with each a size and a different definition as can be seen below:
Content of each message:
- Name: ID Message / Type : UINT16 / Size : 4 bytes
- Name: ID Device/ Type : UINT8 / Size : 4 bytes
- Name: Temperature / Type : UINT16 / Size : 4 bytes
- Name: Activation / Type : BOOLEAN / Size : 4 bytes
- Name: Weather / Type : STRING[32] / Size : 16 bytes
To recover the data transmitted via the socket, the application has a background task that takes care of retrieving all the information.
Here is my code which is therefore in the background task:
StreamReader reader;
int SizeBuffer = 2048;
int SizeReceive = 0;
reader = new StreamReader(socket.InputStream.AsStreamForRead());
string result;
result = "";
while (true)
{
char[] buffer = new char[SizeBuffer];
SizeReceive = await reader.ReadAsync(buffer, 0, SizeBuffer);
int i = 0;
Debug.WriteLine("Text 1 : ")
while (i < 2047)
{
Debug.WriteLine(buffer[i]);
i++;
}
string data = new string(buffer);
if (data.IndexOf("\0") >= 0 || reader.EndOfStream)
{
result = data.Substring(0, data.IndexOf("\0"));
break;
}
result += data;
}
Debug.WriteLine("Text 2 : " + result);
dataString = result;
I am using two Debug.WriteLines to see my incoming data.
That's where there is a problem. For the message Text1, I get this kind of character: ������������������������
And for the Text2 message, I get a single character: �
How can I get my message completely and store it in each of the parameters listed above in relation to its type and corresponding size?
A black diamond with a question mark character is a placeholder for unrecognized characters. It looks like a problem with the encoding of data received from the server.
The default StreamReader constructor with one argument uses UTF-8 encoding. Maybe your server sends data in another encoding.
Try to explicitly specify the encoding using the StreamReader(stream, encoding) constructor.
Here is the solution:
try
{
DataReader reader1 = new DataReader(socket.InputStream);
reader1.InputStreamOptions = InputStreamOptions.Partial;
uint numFileBytes = await reader1.LoadAsync(2048);
byte[] byArray = new byte[numFileBytes];
reader1.ReadBytes(byArray);
string test = BitConverter.ToString(byArray);
Debug.WriteLine("Conversion : " + test);
}
catch (Exception exception)
{
Debug.WriteLine("ERROR LECTURE : " + exception.Message);
}
I'm using the following code for returning handles of a queue, if the queue does not have any handle (open input/output count would be 0) it return MQRCCF_Q_STATUS_NOT_FOUND but when it has some open handle, it returns "Unknown type" exception.
public void getQueue(string Name)
{
PCFMessage reqeuestMessage = new PCFMessage(MQC.MQCMD_INQUIRE_Q_STATUS);
reqeuestMessage.AddParameter(MQC.MQCA_Q_NAME, Name);
reqeuestMessage.AddParameter(CMQCFC.MQIACF_Q_STATUS_TYPE, CMQCFC.MQIACF_Q_HANDLE);
PCFMessage[] response = agent.Send(reqeuestMessage);
foreach (PCFMessage st in response)
{
...
}
}
MQ PCF support in C# is limited , so it may not support some parameters. It's possible that the parameter that you are trying to inquire is not in the list of supported parameters. Please note MQ PCF in .NET is not officially supported by IBM MQ.
If your intention is to inquire the number of applications have opened a queue for input & output, you can use the INQUIRE_Q command and filter out input/output count. Sample snippet is here:
PCFMessage reqeuestMessage = new PCFMessage(MQC.MQCMD_INQUIRE_Q);
reqeuestMessage.AddParameter(MQC.MQCA_Q_NAME, "Q1");
// Send request and receive response
PCFMessage[] pcfResponse = messageAgent.Send(reqeuestMessage);
// Process and print response.
int pcfResponseLen = pcfResponse.Length;
for (int pcfResponseIdx = 0; pcfResponseIdx < pcfResponseLen; pcfResponseIdx++)
{
PCFParameter[] parameters = pcfResponse[pcfResponseIdx].GetParameters();
foreach (PCFParameter pm in parameters)
{
// We just want to print current queue depth only
if ((pm.Parameter == MQC.MQIA_OPEN_OUTPUT_COUNT) || (pm.Parameter == MQC.MQIA_OPEN_INPUT_COUNT))
Console.WriteLine("Parameter: " + pm.Parameter + " - Value: " + pm.GetValue());
}
}
Hope this helped
I have a windows application for sending SMS connecting to a GSM Modem. I only use AT Commands for connecting to port and sending text.
My problem is I can't send a message more that one part (each part is 160 characters for English and 70 characters for Farsi).
Here is the part I command the port to send sms using AT commands:
ExecCommand(port, "AT", 300, "No phone connected at " + strPortName + ".");
ExecCommand(port, "AT+CMGF=1", 300, "Failed to set message format.");
var command = "AT+CSCS=\"" + "HEX" + "\"";
ExecCommand(port, command, 300, "Failed to support unicode");
ExecCommand(port, "AT+CSMP=1,167,0,8", 300, "Failed to set message properties.");
command = "AT+CMGS=\"" + phoneNo + "\"";
ExecCommand(port, command, 300, "Failed to accept phoneNo");
message = message.ToCharArray().Select(Convert.ToInt32).Select(value => String.Format("{0:X}", value)).Aggregate("", (current, hexOutput) => current + hexOutput.PadLeft(4, '0'));
command = message + char.ConvertFromUtf32(26) + "\r";
var recievedData = ExecCommand(port, command, 3000, "Failed to send message");
And here is ExecCommand method
public string ExecCommand(SerialPort port, string command, int responseTimeout, string errorMessage)
{
try
{
// receiveNow = new AutoResetEvent();
port.DiscardOutBuffer();
port.DiscardInBuffer();
receiveNow.Reset();
port.Write(command + "\r");
//Thread.Sleep(3000); //3 seconds
string input = ReadResponse(port, responseTimeout);
if ((input.Length == 0) || ((!input.EndsWith("\r\n> ")) && (!input.EndsWith("\r\nOK\r\n"))))
throw new ApplicationException("No success message was received.");
return input;
}
catch (Exception ex)
{
throw new ApplicationException(errorMessage, ex);
}
}
General AT command handling
You are on the right track, I am pleased to see several basic things done right (terminating AT command lines with \r, waiting for "\r\n> " for AT+CMGS, and waiting for the OK final result code instead of sleeping), very good start!
You do need however to change the structure somewhat. First you need to handle all the other final result codes and not just OK. And you should treat the AT+CMGS command differently from the other commands since you should wait for two things (first the prefix and later the final result code after sending the message text) for that command compared to waiting only for one thing (e.g. the final result code) for those. Also all responses from the modem are complete lines (except the "\r\n> " prefix), so change your algorithm to process the response(s) line by line.
String input;
do {
input = ReadLine(port, responseTimeout);
} while (!isFinalResultCode(input));
None of the commands you are using in the question produces an intermediate response for consumption, but if you were to run a command like AT+CPBR you would consume those intermediate responses inside that loop (and you would have to move the final result test into the loop before attempting to consume the line as an intermediate response).
You can see the is_final_result function in atinout or corresponding functions in ST-Ericsson's U300 RIL (see link and notes in this answer).
Multipart SMS
I think this is not possible in text mode. See the link suggested by Naser Asadi for details on multipart SMS in PDU mode. Also some useful information at
http://mobiletidings.com/2009/02/18/combining-sms-messages/ and http://developer.nokia.com/community/discussion/showthread.php/109602-Concatenated-SMS-in-PDU-Mode.
I have a client server app which is sending data from a C# client to a C++ server. When the server receives this data request, 9 out of 10 times it works ok, but there is always 1 time were there will be garbage data appended to the end of the received data on the server side.
for example instead of receiving a number 1 it will receive 1C or 1#????
Here are snippets of the client and server code, any help will be appreciated.
C# client
int flagSide = 1;
msg = name;
msg += "+";
msg += "qty";
msg += "+";
msg += flagSide.ToString();
ZeroMQ.ZmqContext context = ZeroMQ.ZmqContext.Create();
ZeroMQ.ZmqSocket socket = context.CreateSocket(SocketType.REQ);
socket.Connect("tcp://111.111.0.111:5556");
socket.Send(Encoding.ASCII.GetBytes(msg.ToCharArray()));
Thread.Sleep(1);
string reply = socket.Receive(Encoding.ASCII);
Console.WriteLine("Received reply = " + reply + "\n");
C++ Server
std::tr1::unordered_map <std::string, std::string> aMap;
zmq::context_t context( 1 );
zmq::socket_t responder( context, ZMQ_REP );
responder.bind ("tcp://*:5556");
while ( 1 )
{
zmq::message_t recvMsg;
responder.recv( &recvMsg );
t = static_cast<char*>( recvMsg.data() );
std::string s(t);
std::vector<std::string> strs;
boost::split(strs, s, boost::is_any_of("+"));
aMap["name"] = strs[0];
aMap["qty"] = strs[1];
aMap["flag"] = strs[2];
..........
outputing the split string in the server reveals that sometimes the flag or strs[2] receives the garbage data.
Please help me if you see something that I'm not seeing.
Thanks
In C#, strings converted to bytes are not null-terminated, and c++ string expects a null terminated pointer.
So I presume what is happening here, is a buffer underflow. You are reading memory which does not belongs to the string.
I've been breaking my head over a bug in this system I've been building. Basically, I use sockets to communicate between two C# applications. Or rather a Unity C# script server and a C# client application.
With manual tests, the system works perfectly fine, no anomalies whatsoever.
In order to test performance and multi-user functionality, I wrote up a tester class which launches multiple threads(clients), and have those fire X amount of messages at the server. Here's where my problem occurs...Sometimes.
When a Socket sends or receives, it returns an integer container the amount of bytes that was sent/received. When the problem occurs, I can see that the correct amount of bytes arrived at the server. However, after putting the bytes into a string, suddenly I'm left with an empty string, instead of the message I'd normally see here.
I'm at a loss at to what's causing this problem. I'm using Encoding.Default.GetString() to translate the bytes into a string.
Any help is appreciated!
David
public void ReceiveFromClient (Socket handlerSocket)
{
serverBuffer = new byte[iBufferSize]; //iBufferSize = 8192;
int i = handlerSocket.Receive (serverBuffer);
Debug.Log ("Bytes received: " + i);
string message = Encoding.UTF8.GetString (serverBuffer, 0, i);
Debug.Log ("Message received: " + message);
//Do stuff with the message
}
bool SendMessageToUnity(string input)
{//returns a bool saying whether the message was sent or not
if (clientSocket != null)
{
if (clientSocket.Connected)
{
byte[] bytes = Encoding.UTF8.GetBytes(input+"|");
txtOutput.BeginInvoke(new Action(() => txtOutput.AppendText("Sending message: " + Encoding.UTF8.GetString(bytes) + Environment.NewLine)));
int i = clientSocket.Send(bytes);
txtOutput.BeginInvoke(new Action(() => txtOutput.AppendText("Sending "+i+" bytes. "+ Environment.NewLine)));
return true;
}
}
return false;
}
Look for for a zero value ('\0') in your array of bytes before converting it to a string.
private string GetString(byte[] data)
{
data = data.Where(b => b != 0).ToArray();
return Encoding.UTF8.GetString(data);
}
If you get the byte array correctly than the problem in the Encoding.
Check the sending Encoding usually UTF8 but you have to check it out.
and then var inputStr = Encoding.UTF8.GetString(InputByteArray);
^^