Hello world!
July 22, 2018
Where can I get some?
September 4, 2018

Checklist to start off

Code that is written in plain C program can always be burnt into Ardiuno device. This makes things easy for us to get started. Following is a check list that we need to get the job done.

  • CodeLite IDE or Ardiuno Create.
  • REST API hosted on a server or localhost.
  • Request format of the POST webservice.

IDE (CodeLite will be used in this tutorial)

About codelite: CodeLite is an open source, free, cross platform IDE specialized in C, C++, PHP and JavaScript (mainly for backend developers using Node.js) programming languages which runs best on all major Platforms ( OSX, Windows and Linux ). You can download the IDE from here


If you are familiar with php, the approach would be to clone the slim frame from github and create your first web service real quick. Link to github project or you could download this template of mine and start add methods in the routes.php file. Download source code

Below is a POST method which accepts the following data format and sends back the response if the program sends the request as intended. http://x.x.x.x/rest/iot_tuts/services/staging/v1/app/addDeviceData

<p>Request<br />
{<br />
"account_id": "001",<br />
"device_id": "a001",<br />
"timestamp": "1633565366",<br />
"longitude": "13.0836",<br />
"latitude": "80.2392",<br />
"ch_1": 10.2,<br />
"ch_2": 34.32,<br />
"ch_10": 65.34<br />
<p>Response<br />
{<br />
"error":false,<br />
"message":"data added."</p>

Now that we have the pre-requisites ready its time that we open codelite, create a workspace and a project as shown below,


Enusre that you select the gcc compiler option whilec creating the project. Once the project is created you will see a main.c file that is generated. Copy paste the following code on to the file.



<br />
/*<br />
* Plain C code to hit POST and GET REST API<br />
*<br />
* Author: Srimath (<br />
* Created: 27-07-2018<br />
* Editor: CodeLite OSX<br />
*<br />
*/<br />
#include stdio.h<br />
#include stdlib.h<br />
#include unistd.h<br />
#include string.h<br />
#include sys/types.h<br />
#include sys/socket.h<br />
#include netinet/in.h<br />
#include netdb.h<br />
#include arpa/inet.h<br />
char jsonData[1000]="{\"account_id\": \"001\",\"device_id\": \"a001\",\"longitude\": \"13.0836\",\"latitude\": \"80.2392\",\"ch_1\": 10.2,\"ch_2\": 34.32,\"ch_6\": 65.34";<br />
//char jsonData[1000]="{\"timestamp\":\"125532665\"}";<br />
char jsonRequest[1000]={0};<br />
char serviceMethod[]="rest/iot_tuts/services/staging/v1/app/addDeviceData";<br />
//char serviceMethod[]="rest/shape/services/staging/postConnectivityTest";<br />
char requestBuilder[150]={0};<br />
char hostIP[30]="x.x.x.x";<br />
char token[200] = "2-uok5PvRILXwSINDMdo0vT-KM8hHcVJr-BDuOEx-GQ";<br />
char request[1000];<br />
char response[1000];<br />
char responseTrimmed[1000];<br />
struct hostent *server;<br />
struct sockaddr_in serveraddr;<br />
char recvline[100];<br />
int port = 80;<br />
int c = 0, d = 0;</p>
<p>char timestamp[20];<br />
char jsonDataBuilder[1000];<br />
char timestampBuilder[40];</p>
<p>void pushData ()<br />
{<br />
sprintf(requestBuilder,"/%s HTTP/1.1",serviceMethod);<br />
sprintf(timestamp, "%lu", (unsigned long)time(NULL));</p>
<p>sprintf(timestampBuilder, ",\"timestamp\":\"%s\"}",timestamp);<br />
strcat (jsonData, timestampBuilder);<br />
printf (jsonData);</p>
<p>//---Working Code---<br />
sprintf(jsonRequest,"POST %s\r\nHost: %s\r\nauthorization: Bearer %s\r\ncontent-type: application/json\r\ncontent-length: %d\r\n\r\n%s\r\n",requestBuilder,hostIP,token,strlen(jsonData),jsonData);<br />
//---If GET use this---<br />
//sprintf(aszJSONRequest, "GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", serviceMethod, hostIP);</p>
<p>int tcpSocket = socket(AF_INET, SOCK_STREAM, 0);</p>
<p>if (tcpSocket &lt; 0)<br />
printf("\nError opening socket");<br />
else<br />
printf("\nSuccessfully opened socket\n\n");</p>
<p>server = gethostbyname(hostIP);<br />
//strcpy (server, "");<br />
if (server == NULL)<br />
{<br />
printf("gethostbyname() failed\n");<br />
}<br />
else<br />
{<br />
//printf("\nserver - %s", server-&gt;h_addr_list[0]);<br />
printf("IP\n");<br />
unsigned int j = 0;<br />
while (server -&gt; h_addr_list[j] != NULL)<br />
{<br />
printf("%s", inet_ntoa(*(struct in_addr*)(server -&gt; h_addr_list[j])));<br />
j++;<br />
}<br />
<p>bzero((char *) &amp;serveraddr, sizeof(serveraddr));<br />
serveraddr.sin_family = AF_INET;</p>
<p>bcopy((char *)server-&gt;h_addr, (char *)&amp;serveraddr.sin_addr.s_addr, server-&gt;h_length);</p>
<p>serveraddr.sin_port = htons(port);</p>
<p>if (connect(tcpSocket, (struct sockaddr *) &amp;serveraddr, sizeof(serveraddr)) &lt; 0)<br />
printf("\nError Connecting");<br />
else<br />
printf("\nSuccessfully Connected\n");</p>
<p>printf("\n%s\n", jsonRequest);</p>
<p>if (send(tcpSocket, jsonRequest, strlen(jsonRequest), 0) &lt; 0)<br />
fprintf(stderr, "Error with send()");<br />
else<br />
fprintf(stderr, "Successfully sent request");</p>
<p>bzero(response, 1000);</p>
<p>printf("\n-----SERVER RESPONSE----\n");</p>
<p>recv(tcpSocket, response, 999, 0);<br />
printf("\n%s", response);</p>
<p>close(tcpSocket);<br />
<p>int main(int argc, char** argv) {</p>
<p>pushData ();</p>
<p>return (EXIT_SUCCESS);<br />


As the as the code goes between line 20 and 40, the first important bunch is variable declaration which has got the JSON body that is set up in the format that the API expects, along with a variable to point to the service method. As the declaration goes we would need a buffer to append the request and then read the response line by line. Finally, a port number that is usually 80 in which Apache runs.

The key here is follow the format right from line 43 to 51, where in dynamic variables are string formatted on to the request (line 43, 44 and 46). Then finally the actual response in built. Do ensure that the format with which this request is set up is used without any tweak since this is a standard that the server understands and expects in the request. The /r/n, the number of times they occur for each of the fields such as Host, Authorization, Content type and Content length is important. Tweaks to these will cause an incorrect understanding of the header format the server end and cause the server to through error codes. Replace all the values for the variables with the method name, request format, port and server IP against desired values of your API and server. Hit the services, check them and flash the code on to the board.

Leave a Reply

Your email address will not be published. Required fields are marked *