void cellophane_on(WsHandler * ws_handler, char * event_name, void (*on_event_callback)(WsEventInfo)) { int i; for(i=0; i < 10; i++){ if(strcmp(ws_handler->default_events[i].event_name,event_name) == 0){ ws_handler->default_events[i].callback_func = on_event_callback; return; } } for(i=0; i < ws_handler->user_events_len; i++){ if(strcmp(ws_handler->events[i].event_name,event_name) == 0){ ws_handler->events[i].callback_func = on_event_callback; return; } } if (ws_handler->user_events_len == 100){ cellophane_print_log(ws_handler,LOG_WARNING,DEBUG_NORMAL,"User event limit (100) exceded, imposible to add"); return; } ws_handler->events[ws_handler->user_events_len].event_name = (char *) malloc(strlen(event_name)); memcpy(ws_handler->events[ws_handler->user_events_len].event_name,event_name,strlen(event_name)); ws_handler->events[ws_handler->user_events_len].callback_func = on_event_callback; ws_handler->user_events_len++; }
void cellophane_send(WsHandler * ws_handler, enum socket_io_type io_type, char * id, char * endpoint, char * message, int easy) { Payload m_payload; payload_init(&m_payload); payload_setOpcode(&m_payload, OPCODE_TEXT); char * raw_message; if(io_type == TYPE_EVENT || io_type == TYPE_MESSAGE || io_type == TYPE_JSON_MESSAGE ){ if(!easy){ raw_message = malloc(4 + (int)(strlen(id)+strlen(endpoint)+strlen(message))); bzero(raw_message, 4 + (int)(strlen(id)+strlen(endpoint)+strlen(message))); sprintf(raw_message,"%d:%s:%s:%s", io_type, id, endpoint, message); }else{ raw_message = malloc(4 + (int)strlen(message)); bzero(raw_message, 4 + (int)strlen(message)); sprintf(raw_message,"%d:::%s", io_type, message); } }else{ if(!easy){ raw_message = malloc(3 + (int)(strlen(id)+strlen(endpoint))); bzero(raw_message, 3 + (int)(strlen(id)+strlen(endpoint))); sprintf(raw_message,"%d:%s:%s", io_type, id, endpoint); }else{ raw_message = malloc(3); bzero(raw_message, 3); sprintf(raw_message,"%d::", io_type); } } payload_setPayload(&m_payload,(unsigned char *)raw_message); payload_setMask(&m_payload, 0x1); int bytes_towrite; char * enc_payload = payload_encodePayload(&m_payload); int n = send(ws_handler->fd,enc_payload, m_payload.enc_payload_size, 0); cellophane_print_log(ws_handler,LOG_INFO,DEBUG_DETAILED,"Sending data line: sent %d should be sent %d",n, m_payload.enc_payload_size); if (n < 0) { cellophane_print_log(ws_handler,LOG_ERROR,DEBUG_NONE,"ERROR writing to socket"); exit(1); } cellophane_print_log(ws_handler,LOG_INFO,DEBUG_DIAGNOSTIC,"Sent > %s (%d)",raw_message, strlen(raw_message)); usleep(100*1000); }
void cellophane_trigger_default_events(WsHandler * ws_handler, WsEventInfo info){ int i; info.ws_handler= (void *) ws_handler; for(i=1; i < 10; i++){ if( (strncmp(ws_handler->default_events[i].event_name,info.event_name,strlen(info.event_name)) == 0) && (strlen(info.event_name) == strlen(ws_handler->default_events[i].event_name)) && ws_handler->default_events[i].callback_func != NULL){ cellophane_print_log(ws_handler,LOG_INFO,DEBUG_DIAGNOSTIC,"Triggered \"%s\" default event", info.event_name); ws_handler->default_events[i].callback_func(info); } } if( ws_handler->default_events[0].callback_func != NULL){ cellophane_print_log(ws_handler,LOG_INFO,DEBUG_DIAGNOSTIC,"Triggered \"anything\" default event"); ws_handler->default_events[0].callback_func(info); } }
int cellophane_handshake(WsHandler * ws_handler) { json_error_t json_err; json_t *json_ret; json_t *value; json_t *transport; void *iter; char * res; char *key; size_t index; fprintf(stderr, "sending web request \n"); res = cellophane_do_web_request(ws_handler); if (res == NULL || strcmp(res,"") == 0){ return 0; } cellophane_print_log(ws_handler,LOG_INFO,DEBUG_DIAGNOSTIC, "Curl Response : %s", res); json_ret = json_loads(res, 0, &json_err); if(json_ret == NULL){ cellophane_print_log(ws_handler,LOG_ERROR,DEBUG_NONE, "Could not decode trasnport JSON: %d: %s\n", json_err.line, json_err.text); return 0; } free(res); cellophane_print_log(ws_handler,LOG_INFO,DEBUG_DIAGNOSTIC,"Json parsed succesfully"); iter = json_object_iter(json_ret); while(iter){ key = json_object_iter_key(iter); value = json_object_iter_value(iter); if(strcmp(key, "sid") == 0){ ws_handler->session.sid = strdup(json_string_value(value)); cellophane_print_log(ws_handler,LOG_INFO,DEBUG_DETAILED,"Session id : %s", ws_handler->session.sid); }else if(strcmp(key, "upgrades") == 0){ index = json_array_size(value); if(index > 0){ ws_handler->session.supported_transports = (char **) malloc(index * sizeof(char*)); json_array_foreach(value, index, transport){ ws_handler->session.supported_transports[index] = strdup(json_string_value(transport)); } }
int cellophane_init(WsHandler * ws_handler, int keepalive){ int ret; ret = cellophane_handshake(ws_handler); if(ret <= 0 ){ cellophane_print_log(ws_handler, LOG_ERROR, DEBUG_NONE, "Init failed no response from curl"); return 0; } cellophane_connect(ws_handler); /*if (keepalive) { cellophane_keepAlive(ws_handler); }*/ return 1; }
int cellophane_connect(WsHandler * ws_handler) { int portno, n; struct sockaddr_in serv_addr; struct hostent *server; char buff[256]; WsEventInfo info; info.event_name = "connecting"; info.message = "Connecting"; cellophane_trigger_default_events(ws_handler, info); portno = ws_handler->serverPort; ws_handler->fd = socket(AF_INET, SOCK_STREAM, 0); if (ws_handler->fd < 0) { cellophane_print_log(ws_handler,LOG_ERROR,DEBUG_NONE,"ERROR opening socket"); ws_handler->fd_alive = 0; exit(1); } server = gethostbyname(ws_handler->serverHost); if (server == NULL) { cellophane_print_log(ws_handler,LOG_ERROR,DEBUG_NONE,"ERROR, no such host"); ws_handler->fd_alive = 0; exit(0); } bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(portno); if (connect(ws_handler->fd,(const struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) { cellophane_print_log(ws_handler,LOG_ERROR,DEBUG_NONE,"ERROR connecting"); ws_handler->fd_alive = 0; exit(1); } ws_handler->fd_alive = 1; char * key = cellophane_generateKey(16); int out_len = (int)(strlen(ws_handler->serverPath) + strlen(ws_handler->session.sid) + strlen(ws_handler->serverHost) + strlen(key) ) + 136; char * out = malloc(out_len); bzero(out,out_len); sprintf(out, "GET %s/websocket/%s HTTP/1.1\r\nHost: %s\r\nUpgrade: WebSocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: %s\r\nSec-WebSocket-Version: 13\r\nOrigin: *\r\n\r\n", ws_handler->serverPath, ws_handler->session.sid, ws_handler->serverHost, key); n = send(ws_handler->fd,out,out_len, 0); //printf("sending data line 196\n"); if (n < 0) { cellophane_print_log(ws_handler,LOG_ERROR,DEBUG_NONE,"ERROR writing to socket"); ws_handler->fd_alive = 0; exit(1); } bzero(buff,256); n = recv(ws_handler->fd,buff,255, 0); if (n < 0) { cellophane_print_log(ws_handler,LOG_ERROR,DEBUG_NONE,"ERROR reading from socket"); ws_handler->fd_alive = 0; exit(1); } ws_handler->buffer = realloc(NULL, strlen(buff)); strcpy(ws_handler->buffer, buff); if(strncmp (ws_handler->buffer,"HTTP/1.1 101",12) != 0){ cellophane_print_log(ws_handler,LOG_ERROR,DEBUG_NONE,"Unexpected Response. Expected HTTP/1.1 101.."); cellophane_print_log(ws_handler,LOG_ERROR,DEBUG_NONE,"Aborting..."); ws_handler->fd_alive = 0; exit(1); } char * m_payload; char ** m_payload_a; if(strstr(ws_handler->buffer,"1::") == NULL){ while(!cellophane_read_ready(ws_handler)){ usleep(100*1000); } int msg_number = 0; m_payload_a = cellophane_read(ws_handler,&msg_number); m_payload = *(m_payload_a); //m_payload_a--; /* const char** ptr = mpg123_decoders(); int count = 0; while (*(ptr++) != NULL){ ++count; } --ptr; while (count-- > 0){ syslog(LOG_DEBUG, "\t%s",*(--ptr)); }*/ }else{ m_payload = strstr(ws_handler->buffer,"1::"); } if(strncmp (m_payload,"1::",3) != 0){ cellophane_print_log(ws_handler,LOG_ERROR,DEBUG_NONE,"Socket.io did not send connect response."); cellophane_print_log(ws_handler,LOG_ERROR,DEBUG_NONE,"Aborting..."); ws_handler->fd_alive = 0; exit(1); }else{ cellophane_print_log(ws_handler,LOG_INFO,DEBUG_MINIMAL,"Conection stablished..."); ws_handler->fd_alive = 1; } ws_handler->heartbeatStamp = time(NULL); WsEventInfo info_f; info_f.event_name = "connect"; info_f.message = "connect"; cellophane_trigger_default_events(ws_handler, info_f); //free(m_payload_a); //free(m_payload); }