/*
Firebase : Send notification with REST API(sample.c)
*/
/**
BUILD & MAKE(WINDOW & LINUX COMMON)
-------------------------------------------------------------------
CC = gcc

CFLAGS += -I -g -Wall -Wno-unused-variable
LIBS += -L. -lcurl -ljson-c

.c.o:
$(CC) -c $< $(CFLAGS)

all: build

common.o : common.c
sample.o : sample.c

sample: sample.o common.o
$(CC) -o $@ $^ $(LIBS)
BUILD_FILES += sample

build: $(BUILD_FILES)

clean:
rm -f *.o
rm -f $(BUILD_FILES)
-------------------------------------------------------------------
*/
#include 
#include 

#include <curl/curl.h>
#include 
#include 
#include 
#include <sys/time.h>
#include "json.h"

#define MAX_MSG_CNT 14
#define authorization_str "AUTHORIZATION:"
#define token_str "TOKEN:"

/* holder for curl fetch */
struct curl_fetch_st {
    char *payload;
    size_t size;
};

static json_object *google_pushcall(char *authorization, char *title, char *body, char *token);
static size_t curl_callback (void *contents, size_t size, size_t nmemb, void *userp);
static CURLcode curl_fetch_url(CURL *ch, const char *url, struct curl_fetch_st *fetch);
static int jsonparsing_result(const char *buf);
static int get_config_values(char *authorization, char *token);

int GetDate();
int GetTime();

int get_config_values(char *authorization, char *token)
{
    FILE *fp=NULL;
    char rbuf[1024];

    if((fp=fopen("config.txt", "rt"))==NULL) return(-1);

    while(1)
    {
        memset(rbuf,0x00,sizeof(rbuf));
        if(fgets(rbuf, sizeof(rbuf), fp)==NULL) break;

        rbuf[strlen(rbuf)-1]=0x00;

        if(rbuf[0] == '#') continue;

        if(strstr(rbuf, authorization_str) != NULL)
        {
            strcpy(authorization, strstr(rbuf, authorization_str) + strlen(authorization_str));
        }
        if(strstr(rbuf, token_str) != NULL)
        {
            strcpy(token, strstr(rbuf, token_str) + strlen(token_str));
        }
    }
    if(fp != NULL) fclose(fp);
    return(0);
}

int main(int argc, char *argv[])
{
    json_object *json = NULL;
    int rc;

    char authorization[1024];
    char token[300];

    char *title = "FCM Message";
    char body[4096];
    char extendedmsg[MAX_MSG_CNT][300] = 
    {
    "Miracles happen to only those who believe in them.",
    "Think like a man of action and act like man of thought.",
    "Courage is very important. Like a muscle, it is strengthened by use.",
    "Life is the art of drawing sufficient conclusions from insufficient premises.",
    "By doubting we come at the truth.",
    "A man that has no virtue in himself, ever envies virtue in others.",
    "When money speaks, the truth keeps silent.",
    "Better the last smile than the first laughter.",
    "Painless poverty is better than embittered wealth.",
    "A poet is the painter of the soul.",
    "Error is the discipline through which we advance.",
    "Faith without deeds is useless.",
    "Weak things united become strong.",
    "We give advice, but we cannot give conduct.",
    };

    memset(authorization,0x00,sizeof(authorization));
    memset(token,0x00,sizeof(token));

    rc=get_config_values(authorization, token);
    if(rc)
    {
        //ERROR
    }
    else
    {
        fprintf(stderr, "authorization:(%s)\n", authorization);
        fprintf(stderr, "token:        (%s)\n", token);
    }

    memset(body,0x00,sizeof(body));
    sprintf(body, "Body>>(%d-%d)(%d)(%s)", GetDate(), GetTime(), GetTime() % MAX_MSG_CNT, extendedmsg[GetTime() % MAX_MSG_CNT]);

    json = google_pushcall(authorization, title, body, token);
    if(json == NULL) {
        return(-1);
    }

    /* debugging */
    fprintf(stderr, "RECV>>Parsed JSON: %s\n", json_object_to_json_string(json));

    rc = jsonparsing_result(json_object_to_json_string(json));
    if(rc)
    {
        //ERROR
    }
    else
    {
        //INSERT PUSH_SIT_EVENT_HIST
    }

    if(json != NULL) json_object_put(json);

    return(0);
}

/* callback for curl fetch */
size_t curl_callback (void *contents, size_t size, size_t nmemb, void *userp) 
{
    size_t realsize = size * nmemb;                             /* calculate buffer size */
    struct curl_fetch_st *p = (struct curl_fetch_st *) userp;   /* cast pointer to fetch struct */

    /* expand buffer */
    p->payload = (char *) realloc(p->payload, p->size + realsize + 1);

    /* check buffer */
    if (p->payload == NULL) {
        /* this isn't good */
        fprintf(stderr, "ERROR: Failed to expand buffer in curl_callback\n");
        /* free buffer */
        free(p->payload);
        /* return */
        return -1;
    }

    /* copy contents to buffer */
    memcpy(&(p->payload[p->size]), contents, realsize);

    /* set new buffer size */
    p->size += realsize;

    /* ensure null termination */
    p->payload[p->size] = 0;

    /* return size */
    return realsize;
}

/* fetch and return url body via curl */
CURLcode curl_fetch_url(CURL *ch, const char *url, struct curl_fetch_st *fetch) 
{
    CURLcode rcode;                   /* curl result code */

    /* init payload */
    fetch->payload = (char *) calloc(1, sizeof(fetch->payload));

    /* check payload */
    if (fetch->payload == NULL) {
        /* log error */
        fprintf(stderr, "ERROR: Failed to allocate payload in curl_fetch_url\n");
        /* return error */
        return CURLE_FAILED_INIT;
    }

    /* init size */
    fetch->size = 0;

    /* set url to fetch */
    curl_easy_setopt(ch, CURLOPT_URL, url);
    /* set calback function */
    curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, curl_callback);
    /* pass fetch struct pointer */
    curl_easy_setopt(ch, CURLOPT_WRITEDATA, (void *) fetch);
    /* set default user agent */
    curl_easy_setopt(ch, CURLOPT_USERAGENT, "curl/7.65.1");
    /* set timeout */
    curl_easy_setopt(ch, CURLOPT_TIMEOUT, 30);
    /* enable location redirects */
    curl_easy_setopt(ch, CURLOPT_FOLLOWLOCATION, 1);
    /* set maximum allowed redirects */
    curl_easy_setopt(ch, CURLOPT_MAXREDIRS, 1);
    /* fetch the url */
    rcode = curl_easy_perform(ch);

    /* return */
    return rcode;
}

json_object *google_pushcall(char *authorization, char *title, char *body, char *token)
{
    CURL *ch;                                               /* curl handle */
    CURLcode rcode;                                         /* curl result code */

    json_object *json=NULL;                                 /* json post body */
    json_object *jsonobj=NULL;                              /* json post body */

    enum json_tokener_error jerr = json_tokener_success;    /* json parse error */

    struct curl_fetch_st curl_fetch;                        /* curl fetch struct */
    struct curl_fetch_st *cf = &curl_fetch;                 /* pointer to fetch struct */
    struct curl_slist *headers = NULL;                      /* http headers to send with request */

    char post_data  [4096] = {0x00,};

    char header_definition[2048];

    char *url = "https://fcm.googleapis.com/fcm/send";

    /* init curl handle */
    if ((ch = curl_easy_init()) == NULL) {
        /* log error */
        fprintf(stderr, "ERROR: Failed to create curl handle in fetch_session\n");
        /* return error */
        return NULL;
    }

    /* set content type */
    memset(header_definition,0x00,sizeof(header_definition));
    sprintf(header_definition, "Authorization: key=%s", authorization);
    headers = curl_slist_append(headers, header_definition);
    headers = curl_slist_append(headers, "Content-Type: application/json");

    /* create json object for post */
    json      = json_object_new_object();
    jsonobj   = json_object_new_object();

    json_object_object_add(json  ,  "to"          , json_object_new_string(token));
    json_object_object_add(jsonobj, "title"       , json_object_new_string(title));
    json_object_object_add(jsonobj, "body"        , json_object_new_string(body));
    json_object_object_add(json  ,  "notification", jsonobj);

    memset(post_data, 0x00, sizeof(post_data));
    sprintf(post_data, "%s", json_object_to_json_string(json));

    /* set curl options */
    curl_easy_setopt(ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_easy_setopt(ch, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(ch, CURLOPT_POSTFIELDS, post_data);
    curl_easy_setopt(ch, CURLOPT_VERBOSE, 1L);
    curl_easy_setopt(ch, CURLOPT_POST, 1L);
    /* disconnect if we can't validate server's cert */ 
    curl_easy_setopt(ch, CURLOPT_SSL_VERIFYPEER, 0L);
    curl_easy_setopt(ch, CURLOPT_SSL_VERIFYHOST, 0L);

    /* fetch page and capture return code */
    rcode = curl_fetch_url(ch, url, cf);

    //FREE
    curl_easy_cleanup(ch);
    curl_slist_free_all(headers);

    if(json != NULL) json_object_put(json);
    if(jsonobj != NULL) json_object_put(jsonobj);

    /* check return code */
    if (rcode != CURLE_OK || cf->size < 1) {
        /* log error */
        fprintf(stderr, "ERROR: Failed to fetch url (%s) - curl said: %s\n",
            url, curl_easy_strerror(rcode));
        /* return error */
        return NULL;
    }

    /* check payload */
    if (cf->payload != NULL) 
    {

        /* parse return */
        json = json_tokener_parse_verbose(cf->payload, &jerr);
        /* free payload */
        free(cf->payload);
    }
    else 
    {
        /* error */
        fprintf(stderr, "ERROR: Failed to populate payload\n");
        /* free payload */
        free(cf->payload);
        /* return */
        return NULL;
    }

        /* check error */
    if (jerr != json_tokener_success) 
    {
        /* error */
        fprintf(stderr, "ERROR: Failed to parse json string\n");
        /* free json object */
        if(json != NULL) json_object_put(json);
        /* return */
        return NULL;
    }
    return json;
}

int jsonparsing_result(const char *buf)
{
    int ii, rc;
    char keystr[100],successtmp[100];
    struct json_object *jsonjob   = NULL;
    struct json_object *jsonvalue = NULL;

    jsonjob = json_tokener_parse(buf);
    if(NULL == jsonjob) {
        return -1;
    }
    printf("\n\n\n\n");

    memset(keystr, 0x00, sizeof(keystr));
    strcpy(keystr, "success");
    json_object_object_get_ex(jsonjob, keystr, &jsonvalue);
    memset(successtmp, 0x00, sizeof(successtmp));
    strcpy(successtmp, json_object_get_string(jsonvalue));

    if(atoi(successtmp) == 1 || atoi(successtmp) == 0)
    {
        if(atoi(successtmp) == 0) printf("[FAIL]BASIC DATA-----------------------------------\n");
        if(atoi(successtmp) == 1) printf("[SUCC]BASIC DATA-----------------------------------\n");

        memset(keystr, 0x00, sizeof(keystr));
        strcpy(keystr, "multicast_id");
        json_object_object_get_ex(jsonjob, keystr, &jsonvalue);
        printf("[%s][%s]\n", keystr, json_object_get_string(jsonvalue));

        memset(keystr, 0x00, sizeof(keystr));
        strcpy(keystr, "success");
        json_object_object_get_ex(jsonjob, keystr, &jsonvalue);
        printf("[%s][%s]\n", keystr, json_object_get_string(jsonvalue));

        memset(keystr, 0x00, sizeof(keystr));
        strcpy(keystr, "failure");
        json_object_object_get_ex(jsonjob, keystr, &jsonvalue);
        printf("[%s][%s]\n", keystr, json_object_get_string(jsonvalue));

        memset(keystr, 0x00, sizeof(keystr));
        strcpy(keystr, "canonical_ids");
        json_object_object_get_ex(jsonjob, keystr, &jsonvalue);
        printf("[%s][%s]\n", keystr, json_object_get_string(jsonvalue));

        struct json_object *pdata = NULL;
        if(json_object_object_get_ex(jsonjob, "results", &pdata)) 
        {
            for (ii = 0; ii < json_object_array_length(pdata); ii++) 
            {
                if(ii==0)
                {
                    printf("ARRAY DATA[%.4d]-----------------------------------\n", json_object_array_length(pdata));
                }

                struct json_object *successtmp = json_object_array_get_idx(pdata, ii);

                memset(keystr, 0x00, sizeof(keystr));
                strcpy(keystr, "message_id");
                rc = json_object_object_get_ex(successtmp, keystr, &jsonvalue);
                if(rc)
                {
                    printf("rc:[%d]", rc);
                    printf(",index[%.3d],key[%s]:[%s]\n", ii + 1, keystr, json_object_get_string(jsonvalue));
                }

                memset(keystr, 0x00, sizeof(keystr));
                strcpy(keystr, "error");
                rc = json_object_object_get_ex(successtmp, keystr, &jsonvalue);
                if(rc)
                {
                    printf("rc:[%d]", rc);
                    printf(",index[%.3d],key[%s]:[%s]\n", ii + 1, keystr, json_object_get_string(jsonvalue));
                }
            }
        }
    }
    else
    {
        return(-2);
    }

    return(0);
}

+ Recent posts