Sending SMS via AT+CMGS command programatically - c

I'm trying to send SMS via MC7304 modem programatically in C++. For AT command, linux share /dev/ttyUSB1 port. Here is my code:
fd_set readSet, writeSet;
struct timeval timeval;
int cellFd = open("/dev/ttyUSB1", O_RDWR, 0);
writeSet = readSet;
timeval.tv_sec = 0;
timeval.tv_usec = 3000000;
int n = 0;
int written = 0;
int readed = 0;
int totalRead = 0;
char buffer[1001];
memset(buffer, '\0', 1001);
written = write(cellFd, "AT+CMGF=1\r\n", 11);
printf("AT+CMGF=1 command sent with result: %d. Waiting for response...\n", written);
while(true)
{
FD_ZERO(&readSet);
FD_SET(cellFd, &readSet);
timeval.tv_sec = 2;
timeval.tv_usec = 0;
n = select(cellFd + 1, &readSet, &writeSet, NULL, &timeval);
if(n == 0)
{
break;
}
else if(n > 0)
{
readed = read(cellFd, buffer + totalRead, 1000 - totalRead);
totalRead += readed;
}
else
{
printf("Error\n");
exit(0);
}
}
if(totalRead > 0)
{
cout << buffer << endl;
}
else
{
printf("No data received\n");
}
totalRead = 0;
readed = 0;
memset(buffer, '\0', 1001);
written = write(cellFd, "AT+CSCS=\"GSM\"\r\n", 15);
printf("AT+CSCS=\"GSM\" command sent with result: %d. Waiting for response...\n", written);
while(true)
{
FD_ZERO(&readSet);
FD_SET(cellFd, &readSet);
timeval.tv_sec = 2;
timeval.tv_usec = 0;
n = select(cellFd + 1, &readSet, &writeSet, NULL, &timeval);
if(n == 0)
{
break;
}
else if(n > 0)
{
readed = read(cellFd, buffer + totalRead, 1000 - totalRead);
totalRead += readed;
}
else
{
printf("Error\n");
exit(0);
}
}
if(totalRead > 0)
{
cout << buffer << endl;
}
else
{
printf("No data received\n");
}
totalRead = 0;
readed = 0;
memset(buffer, '\0', 1001);
written = write(cellFd, "AT+CMGS=\"MY_NUMBER\"\r\n", 24);
printf("AT+CMGS=\"+MY_NUMBER\" command sent with %d result. Waiting for response...\n", written);
while(true)
{
FD_ZERO(&readSet);
FD_SET(cellFd, &readSet);
timeval.tv_sec = 3;
timeval.tv_usec = 0;
n = select(cellFd + 1, &readSet, &writeSet, NULL, &timeval);
if(n == 0)
{
printf("No data\n");
break;
}
else if(n > 0)
{
memset(buffer, '\0', 1001);
readed = read(cellFd, buffer, 1000);
for(int i=0; i<readed; i++)
{
printf("%02x ", buffer[i]);
}
printf("\n");
cout << buffer << endl;
if((*(buffer) == 0x3E) && (*(buffer + 1) == 0x20) && (*(buffer + 2) == 0x0A))
{
written = write(cellFd, "Test\x1A", 5);
printf("SMS text sent with %d result. Waiting for response...\n", written);
}
}
else
{
printf("Error\n");
exit(0);
}
}
The first two commands work fine and returning 'OK' response. Unfortunetly, after sending AT+CMGS command, modem response with 0x0A (line feed) twice, next responsing with 0x3E 0x20 0x0A (> ) (that looks ok). After this sequence, i'm sending text that ends with 0x1A (CTRL-Z), but modem still responding with >. This situation repeats hundreds of times and at the end I got error +CMS ERROR: 305. It looks like:
root#Moxa:/home/SMS# ./SMS
AT+CMGF=1 command sent with result: 11. Waiting for response...
OK
AT+CSCS="GSM" command sent with result: 15. Waiting for response...
OK
AT+CMGS="(SOME NUMBER)" command sent with 24 result. Waiting for response...
>
SMS text sent with 5 result. Waiting for response...
>
[ situation repeats ]
SMS text sent with 5 result. Waiting for response...
+CMS ERROR: 305
What's wrong with this code, how can I fix it?

Related

How to make server read only line by line

I'm trying to create a chatroom. I have a server that takes commands and does things with them and I have client that sends them. Im using poll to monitor multiple clients. Whenever my client sends a command with the arguments it reads that line and gets some characters from the following line in client.
client(relevant code):
char *data = "REGISTER Johndoe pass1ds3";
send(sockfd,data, strlen(data), 0);
char *data3= "LOGIN Johndoe pass1ds3";
send(sockfd,data3, strlen(data3), 0);
//The server would get "REGISTER Johndoe pass1ds3LOGIN" instead of "REGISTER Johndoe pass1ds3".
server(relevant par):
for (int i = 1; i < (numfds + 1); i++){
if(pollfds[i].revents & POLLRDNORM){
if (readCmd(&pollfds[i], pollfds[i].fd, users,cmdBuf, 32) == -1)
printf("Connection closed\n");
else if(readCmd(&pollfds[i], pollfds[i].fd, users ,cmdBuf, 32) == -2)
printf("Error with recv");
}
}
readCmd(the command that reads from client):
int readCmd(struct pollfd * pollInfo, int sockfd, struct user *users,char* buf, int bufSize){
int num = recv(sockfd , buf, bufSize, 0);
if( num == -1)
return -2;
else if (num == 0 || (num < 0 && errno == ECONNRESET)){
// printf("Nothing to read\n");
close(sockfd);
return -1;
}
else{
printf("recieved %d bytes\n", num);
buf[num] = '\0';
char tokenList[5][30];
char* context = NULL;
char* token = strtok_r(buf, " ", &context);
// Parse command and arguments
int ite = 0;
while (token != NULL) {
strcpy(tokenList[ite], token);
ite++;
token = strtok_r(NULL, " ", &context);
}
if(strcmp(tokenList[0], "REGISTER") == 0){
registerAcc(tokenList[1], tokenList[2]);
}
else if (strcmp(tokenList[0], "LOGIN") == 0){
login(tokenList[1], tokenList[2], users);
}
}
return 0;
}

Extra \1 Character In Printf

I'm working on a C program to solve the Dining Philosophers' problem. I loop through 500 philosopher state changes, and output each philosophers' status on each interation with the following statement:
printf(" %d> |%s|%s|%s|%s|%s \n", i, get_state(phils[0]), get_state(phils[1]), get_state(phils[2]), get_state(phils[3]), get_state(phils[4]));
For context, here is the function get_state, which converts a numeric philosopher status into a string:
char * get_state(int t) {
if (t == 1)
return " Thinking ";
if (t == 2)
return " Hungry ";
if (t == 3)
return " Eating ";
return "----Error----";
}
My problem is this: every 5-30 lines, one of them will start with the unicode character U+0001. It appears that it is probably being inserted after the \n of the previous line, but I can't tell what causes it at all!
I've provided a screenshot for clarity:
And here is the whole loop:
for (i = 1; i <= MAX; i++) {
silent = 0;
// receive message from child node
for (j = 0; j < PHIL_NO; j++) {
if(phils[j] == EATING) {
count[j]++;
}
lastPhils[j] = phils[j];
};
read(host[READ], &msg, sizeof(msg));
phils[msg.index] = msg.state;
for (j = 0; j < PHIL_NO; j++) {
if (phils[j] == lastPhils[j])
{
silent++;
}
};
printf("%4d> |%s|%s|%s|%s|%s \n", i, get_state(phils[0]), get_state(phils[1]),
get_state(phils[2]), get_state(phils[3]), get_state(phils[4]));
// if message is "hungry"
if (msg.state == HUNGRY) {
state_left = 0;
state_right = 0;
// check if chopsticks are available
if (phils[(msg.index - 1)%PHIL_NO] == EATING) {
state_left = 1;
}
if(phils[(msg.index + 1)%PHIL_NO] == EATING) {
state_right = 1;
}
// if available...
if (state_left+state_right == 0) {
// send message EATING to node
msg.state = EATING;
write(node[msg.index][WRITE], &msg, sizeof(msg));
} else {
// make the node wait
write(node[msg.index][WRITE], &msg, sizeof(msg));
}
} else if (msg.state == THINKING) {
// awake neighborhood nodes to eat
write(node[(msg.index-1)%PHIL_NO][WRITE], &msg, sizeof(msg));
write(node[(msg.index+1)%PHIL_NO][WRITE], &msg, sizeof(msg));
}
};
Edit: Oddly enough, when I run it in XTerm I can't see the extra character. I think that just means that XTerm doesn't display it. At this point, I'm pretty sure #Barmar is right in assuming it's one of my pipe write()s misbehaving.

Unable to receive data with libusb

I want to send and receive data from device to pc and vice versa. I am sending the string, but not able to receive it fully. Example: Sent string is Hello, and the output is:
Received:H
Error in read! e = -4 and received = 5
#include <string.h>
#include<stdio.h>
#include <stdlib.h>
#include <libusb-1.0/libusb.h>
#define BULK_EP_OUT 0x01
#define BULK_EP_IN 0x81
/*find these values using lsusb -v*/
uint16_t VENDOR = 0x0483;
uint16_t PRODUCT = 0x5740;
int main(void)
{
int ret = 1; //int type result
struct libusb_device **usb_dev;
struct libusb_device_descriptor desc;
struct libusb_device_handle *handle = NULL;
struct device_handle_expected;
//struct libusb_device_handle device_expected_handle = NULL;
struct libusb_device *dev, *dev_expected;
char *my_string, *my_string1;
int e = 0, config;
char found = 0;
int transferred = 0;
int received = 0;
int length = 0;
int i=0;
int count;
/*struct libusb_device *dev;
struct libusb_device **devs;
struct dev_expected;*/
// Initialize libusb
ret = libusb_init(NULL);
if(ret < 0)
{
printf("\nFailed to initialise libusb\n");
return 1;
}
else
printf("\nInit successful!\n");
// Get a list of USB devices
count = libusb_get_device_list(NULL, &usb_dev);
if (count < 0)
{
printf("\nThere are no USB devices on the bus\n");
return -1;
}
printf("\nToally we have %d devices\n", count);
while ((dev = usb_dev[i++]) != NULL)
{
ret = libusb_get_device_descriptor(dev, &desc);
if (ret < 0)
{
printf("Failed to get device descriptor\n");
libusb_free_device_list(dev, 1);
break;
}
e = libusb_open(dev, &handle);
if (e < 0)
{
printf("Error opening device\n");
libusb_free_device_list(dev, 1);
libusb_close(handle);
break;
}
if(desc.idVendor == 0x0483 && desc.idProduct == 0x5740)
{
found = 1;
break;
}
}//end of while
if(found == 0)
{
printf("\nDevice NOT found\n");
libusb_free_device_list(usb_dev, 1);
libusb_close(handle);
return 1;
}
else
{
printf("\nDevice found");
// dev_expected = dev;
//device_handle_expected = handle;
}
e = libusb_get_configuration(handle, &config);
if(e!=0)
{
printf("\n***Error in libusb_get_configuration\n");
libusb_free_device_list(usb_dev, 1);
libusb_close(handle);
return -1;
}
printf("\nConfigured value: %d", config);
if(config != 1)
{
libusb_set_configuration(handle, 1);
if(e!=0)
{
printf("Error in libusb_set_configuration\n");
libusb_free_device_list(usb_dev, 1);
libusb_close(handle);
return -1;
}
else
printf("\nDevice is in configured state!");
}
if(libusb_kernel_driver_active(handle, 0) == 1)
{
printf("\nKernel Driver Active");
if(libusb_detach_kernel_driver(handle, 0) == 0)
printf("\nKernel Driver Detached!");
else
{
printf("\nCouldn't detach kernel driver!\n");
libusb_free_device_list(usb_dev, 1);
libusb_close(handle);
return -1;
}
}
e = libusb_claim_interface(handle, 0);
if(e < 0)
{
printf("\nCannot Claim Interface");
libusb_free_device_list(usb_dev, 1);
libusb_close(handle);
return -1;
}
else
printf("\nClaimed Interface\n");
int nbytes = 64;
my_string = (char *) malloc(nbytes + 1);
my_string1 = (char *) malloc(nbytes + 1);
memset(my_string, '\0', 64);//The C library function void (an unsigned char) to the first n characters of the string pointed to, by the argument str.
memset(my_string1, '\0', 64);
strcpy(my_string, "Hello");
length = strlen(my_string);
printf("\nTo be sent: %s", my_string);
e = libusb_bulk_transfer(handle, BULK_EP_OUT, my_string, length, &transferred, 0);
if(e == 0 && transferred == length)
{
printf("\nWrite successful!");
printf("\nSent %d bytes with string: %s\n", transferred, my_string);
}
else
printf("\nError in write! e = %d and transferred = %d\n", e, transferred);
// sleep(3);
i = 0;
for(i = 0; i <= length; i++)
{
e = libusb_bulk_transfer(handle, BULK_EP_IN, my_string1,length, &received, 0); //64: Max Packet Length
if(e == 0 && received == length)
{
printf("\nReceived:");
printf("%c", my_string1[i]);
sleep(5);
}
else
{
printf("\nError in read! e = %d and received = %d bytes\n", e, received);
return -1;
}
}
libusb_release_interface(handle, 0);
libusb_free_device_list(usb_dev, 1);
libusb_close(handle);
libusb_exit(NULL);
printf("\n");
return 0;
}
Pretty certain the bulk in transfer will transfer the entire buffer at once(up to 64--or 512 if you're doing high speed--bytes), not a byte at a time.
You're iterating over the size of the expected buffer and doing a bulk in for each byte, and only printing out the first byte.
Get rid of the for loop on the read and change your printf() to be printf("%s\n",my_string1);

client messages don't arrive to server in tcp winsock

I have server client application.
When I'm sending messages in a row(without scanf in the code below), it's seems the server doesn't get them(doesn't print).
if I wait a little bit(with the scanf in the code below) and then send the next message the server works fine and prints all messages.
what's the problem?
how can I fix it, cause I want to do more with the message(not just to print it) that arrived to the server.
in my client code(where server prints nothing)
char message[(100)] = {0};
int x = rand();
while(i < 3)
{
printf(" I send %d\n", x);fflush(NULL);
sprintf(message, "%d",x);
if( send(mainSockfd, message,strlen(message),0) == -1)
{
printf("ERRRRRORRRR\n");fflush(NULL);
}
i++;
x = rand() % 100;
}
in my client code(when server prints the messages)
char message[(100)] = {0};
int x = rand();
while(i < 3)
{
printf(" I send %d\n", x);fflush(NULL);
sprintf(message, "%d",x);
if( send(mainSockfd, message,strlen(message),0) == -1)
{
printf("ERRRRRORRRR\n");fflush(NULL);
}
i++;
x = rand() % 100;
scanf("%d",&x); // this is the only change
}
in my server code
char command[(100+1)] = {0};
while(1)
{
readLength = recv(sockfd, command, 100+1,0);
if(readLength > 0)
{
printf("arrived = %s,\n",command);fflush(NULL);
ZeroMemory(command, sizeof(command));
}
else if( readLength == 0)
{
break;
}
else if ( readLength < 0 ){
if(GetLastError() == 10035)
{
continue;
}
if(GetLastError() == 10057 || GetLastError() == 10054)
{
break;
}
continue;
}
}
As you seem to be transferring 0-terminated "strings" without the 0 termination, you should read one char less then the read buffer provides to always have the read buffer being 0-terminated, as if you try to printf a non 0-terminated "string" you provoke undefined behaviour.
So change this
readLength = recv(sockfd, command, 100+1,0);
to become this
readLength = recv(sockfd, command, 100,0);

Read() function doesnt read the entire data on serial communication

Here is my code
void Reading_TtyS0()
{
int ret;
char mypipe_ttyS0[80] = {0};
fcntl(fd, F_SETFL, 0);
ret = read(fd, ttyS0_mypipe , 80 );
printf(ret = %d\n", ret);
if (ret > 0)
{
perror("Message Log, Reading /dev/ttyS0");
printf("Message Log, Reading /dev/ttyS0 with data = %s\n", ttyS0_mypipe);
tcflush(fd, TCIFLUSH);
ret = 0;
}
}
My output is
ret = 8
Message Log, Reading /dev/ttyS0: Success
Message Log, Reading /dev/ttyS0 with data = 0066923:
I am reading only 8 bytes instead of 80.
I should receive 0066923:12:13:134:1134:112344:333...(till 80 bytes)
The output on gtkterm and I am receiving the complete data.
read() does not necessarily return the number of bytes it was told to read.
So loop around read until you got what you want:
char mypipe_ttyS0[80] = {0};
fcntl(fd, F_SETFL, 0);
size_t bytes_to_read = 80;
size_t bytes_read = 0;
while (bytes_to_read > 0)
{
ssize_t result = read(fd, ttyS0_mypipe + bytes_read, bytes_to_read);
if (-1 == result)
{
if ((EWOULDBLOCK == errno) || (EAGAIN == errno))
{
continue;
}
perror("read() failed");
break;
}
else (0 == result)
{
fprintf(stderr, "Connection closed.");
break;
}
printf("Read %zd bytes.\n", result);
bytes_to_read -= result;
bytes_read += result;
}
....
Its non-blocking read operation, so its possible that read will return whatever data received in the buffer at the moment.
You have to loop through the read until all data received.
int ret;
char mypipe_ttyS0[80] = {0};
fcntl(fd, F_SETFL, 0);
int i = 5; // let say iterate 5 times
int bytes_to_read = 80;
ret = 0;
while (i > 0)
{
ret += read(fd, mypipe_ttyS0 + ret , bytes_to_read );
printf(ret = %d\n", ret);
bytes_to_read -= ret;
if(bytes_to_read == 0)
{
break;
}
++i;
}
if (bytes_to_read == 0)
{
perror("Message Log, Reading /dev/ttyS0");
printf("Message Log, Reading /dev/ttyS0 with data = %s\n", ttyS0_mypipe);
tcflush(fd, TCIFLUSH);
ret = 0;
}

Resources