rm sth sdk

This commit is contained in:
JamesonHuang 2016-04-29 16:01:33 +08:00
parent 1102dc1956
commit a955789014
100 changed files with 0 additions and 10629 deletions

Binary file not shown.

View File

@ -1,5 +0,0 @@
libprotobuf-c0-dev
libsnappy-dev
protobuf-c-compiler
libtcmalloc-minimal4
libtcmalloc-minimal4-dbg

View File

@ -1,28 +0,0 @@
#include <stdio.h>
#include "nebula_sdk.h"
void msg_cb(const char* data, int len)
{
printf("karldbg %s %s\n", __func__, data);
}
int main(int argc, const char *argv[])
{
const char* app_name[] = {"com.meizu.router",};
NebulaMsgCallback cb = msg_cb;
NebulaInit("R10WZOANC5400EE", "https://p.meizu.com", "/tmp");
NebulaSubScribe(1, app_name);
NebulaRegister(eNebulaMsg_Push, cb);
NebulaStart();
while(1) {
sleep(1);
}
return 0;
}

View File

@ -1,25 +0,0 @@
[2015-05-07 15:02:59.365817]|WARN|nebula_sdk.c:55:(NebulaInit):load archive file failed...
[2015-05-07 15:02:59.365960]|INFO|nebula_sdk.c:95:(__NebulaStart):set status to eStatus_Redirect
[2015-05-07 15:02:59.387127]|INFO|redirect.c:119:(NebulaRedirect):HTTPS POST. url=https://p.meizu.com/push/redirect, params=uid=R10WZOANC5400EE&nonce=y9757acx1eve7nmoigsz8fxqqqvjj&ts=1430982179&sign=915a7e6c46cb4894f43e0626835ca183
[2015-05-07 15:03:00.110994]|INFO|redirect.c:126:(NebulaRedirect):curl_easy_perform success. response={"code":200,"hostlist":[{"ip":"121.14.58.42","port":8080},{"ip":"122.13.148.217","port":8080}],"md5_daa":{"rule":"hhs","salt":"fdsafdsafewqfewq"}}
[2015-05-07 15:03:00.111336]|INFO|nebula_sdk.c:100:(__NebulaStart):set status to eStatus_LoopTest
[2015-05-07 15:03:00.131505]|INFO|nebula_sdk.c:108:(__NebulaStart):set status to eStatus_Connect
[2015-05-07 15:03:00.151805]|INFO|connect.c:159:(NebulaConnect):connect to server:121.14.58.42:8080
[2015-05-07 15:03:00.151889]|INFO|nebula_sdk.c:113:(__NebulaStart):set status to eStatus_Connecting
[2015-05-07 15:03:00.157523]|INFO|connect.c:31:(__on_connect):connect success, server_addr:121.14.58.42:8080
[2015-05-07 15:03:00.157623]|INFO|connect.c:34:(__on_connect):set status to eStatus_Auth1
[2015-05-07 15:03:00.157811]|DEBUG|net.c:143:(NebulaConnSend):NEBULA TX REQ AUTH|62
[2015-05-07 15:03:00.157851]|INFO|nebula_sdk.c:125:(__NebulaStart):set status to eStatus_Auth1_Waiting
[2015-05-07 15:03:00.168268]|DEBUG|connect.c:46:(__handle_message):NEBULA RX RSP AUTH|112
[2015-05-07 15:03:00.180330]|DEBUG|net.c:143:(NebulaConnSend):NEBULA TX REQ AUTH|140
[2015-05-07 15:03:00.180446]|INFO|auth.c:107:(NebulaOnAuth):set status to eStatus_Auth2
[2015-05-07 15:03:00.187501]|DEBUG|connect.c:46:(__handle_message):NEBULA RX RSP AUTH|47
[2015-05-07 15:03:00.187558]|INFO|auth.c:44:(NebulaOnAuth):set status to eStatus_Sub
[2015-05-07 15:03:00.187600]|DEBUG|net.c:143:(NebulaConnSend):NEBULA TX REQ SUB|46
[2015-05-07 15:03:00.196984]|DEBUG|connect.c:46:(__handle_message):NEBULA RX RSP SUB|96
[2015-05-07 15:03:00.197133]|INFO|subscribe.c:45:(NebulaOnSubSuccess):sub com.meizu.router success.
[2015-05-07 15:03:00.197194]|INFO|nebula_sdk.c:139:(__NebulaStart):set status to eStatus_Estab
[2015-05-07 15:03:00.337788]|DEBUG|net.c:143:(NebulaConnSend):NEBULA TX REQ PING|0
[2015-05-07 15:03:00.352052]|DEBUG|connect.c:46:(__handle_message):NEBULA RX RSP PING|0
[2015-05-07 15:03:00.352100]|DEBUG|connect.c:49:(__handle_message):pong.

View File

@ -1,56 +0,0 @@
#ifndef NEBULA_SDK_H
#define NEBULA_SDK_H
typedef enum {
eNebulaMsg_Push, /// 推送 (路由器只需关心这一类消息)
eNebulaMsg_Presence, /// Presence
eNebulaMsg_Sms, /// 网络短信
eNebulaMsg_Mms, /// 网络彩信
eNebulaMsg_Max,
} NebulaMsgType;
#ifdef __cplusplus
extern "C" {
#endif
/** 初始化网络连接
* @device_tag: (IMEI)
* @verify_pwd: (SN)
* @host: , : https://p.meizu.com (结尾不要带"/", 前面要加上https)
* @file: /, ,
* @return: , 0; -1, errno中.
* @, -1.
*/
int NebulaInit(const char* device_tag, const char* host, const char* file);
/** 设置订阅列表
*
*
*/
void NebulaSubScribe(int count, const char** app_name);
/** 消息处理回调函数
* @app: App名
* @msg:
*/
typedef void (*NebulaMsgCallback)(const char* app, const char* msg);
/** 注册消息处理回调函数
* @type:
* @cb:
* @return:
* @, .
*/
NebulaMsgCallback NebulaRegister(NebulaMsgType type, NebulaMsgCallback cb);
/** 启动
*
*/
int NebulaStart();
#ifdef __cplusplus
}
#endif
#endif //NEBULA_SDK_H

Binary file not shown.

View File

@ -1,31 +0,0 @@
CC=gcc
CFLAGS=-g -fPIC -Wall -Werror
INCLUDES=-Iproto -Icrypto
LINK=-lpthread -lcurl -lssl -lcrypto
LINK+=-Lproto -lnebula_proto
LINK+=-Lcrypto
LINK+=-Llibs -ljson-c -lsnappy -lprotobuf-c -luuid -lcrypto_framwork -L/usr/lib
LINK+=-ltcmalloc_minimal
TARGET=libnebula_sdk.so
OBJS=$(patsubst %.c,%.o,$(wildcard *.c))
all:$(TARGET)
$(TARGET):$(OBJS)
cd proto && make
@echo LD $(TARGET)
@$(CC) $(CFLAGS) $(OBJS) -o $(TARGET) -shared $(LINK)
.c.o:
$(CC) $(CFLAGS) -c $< -o $@ $(INCLUDES)
.PHONY: clean
clean:
rm $(TARGET) $(OBJS) -rf
cd proto && make clean
install:
install $(TARGET) /usr/lib
mkdir -p /usr/include/nebula_sdk
install nebula_sdk.h /usr/include/nebula_sdk

View File

@ -1,15 +0,0 @@
Interface:
Sample:
Depend dynamic libraries:
libcurl.so
libprotobuf-c.so
libssl.so
libcrypto.so
libtcmalloc_minimal.so
Build:
Run `make` command in this directory.

View File

@ -1,198 +0,0 @@
#include "archive.h"
#include "config.h"
#include <sys/file.h>
#include <ctype.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "timer.h"
extern dict* g_seq_dict;
extern char* g_storage_file;
Archive g_archive = {0, NULL, &g_seq_dict};
int NebulaIsSubscribed(const char* appname)
{
int i;
for (i = 0; i < g_archive.n_sub_apps; ++i) {
if (strcmp(appname, g_archive.sub_apps[i]) == 0)
return 1;
}
return 0;
}
int NebulaAddSubApp(const char* appname)
{
if (!g_archive.sub_apps) {
g_archive.sub_apps = (char**)malloc(sizeof(char*));
if (!g_archive.sub_apps) {
log_error("malloc error.");
return -1;
}
g_archive.sub_apps[0] = strdup(appname);
if (!g_archive.sub_apps[0]) {
log_error("malloc error.");
return -1;
}
g_archive.n_sub_apps = 1;
return 0;
}
g_archive.sub_apps =
(char**)realloc(g_archive.sub_apps, sizeof(char*) * (g_archive.n_sub_apps + 1));
if (!g_archive.sub_apps) {
log_error("malloc error.");
return -1;
}
g_archive.sub_apps[g_archive.n_sub_apps] = strdup(appname);
if (!g_archive.sub_apps[g_archive.n_sub_apps]) {
log_error("malloc error.");
return -1;
}
g_archive.n_sub_apps++;
return 0;
}
void ReleaseArchive()
{
int i;
for (i = 0; i < g_archive.n_sub_apps; ++i) {
free(g_archive.sub_apps[i]);
}
free(g_archive.sub_apps);
g_archive.n_sub_apps = 0;
g_archive.sub_apps = NULL;
}
int NebulaLoadFromFile(const char* file)
{
char *key = NULL;
FILE *f = fopen(file, "r");
if (!f) {
log_warn("not found archive file:%s, please confirm SDK is first startup.", file);
return 0;
}
ReleaseArchive();
char *line = NULL;
size_t len = 0;
ssize_t n = getline(&line, &len, f);
if (n <= 0) {
fclose(f);
return -1;
}
key = strndup(line, strlen(line) - 1);
g_archive.n_sub_apps = atoi(key);
free(key);
int i;
for (i = 0; i < g_archive.n_sub_apps; ++i) {
n = getline(&line, &len, f);
if (n <= 0) {
ReleaseArchive();
fclose(f);
return -1;
}
key = strndup(line, strlen(line) - 1);
NebulaAddSubApp(key);
free(key);
}
n = getline(&line, &len, f);
if (n <= 0) {
ReleaseArchive();
fclose(f);
return -1;
}
key = strndup(line, strlen(line) - 1);
int dict_size = atoi(key);
free(key);
for (i = 0; i < dict_size; ++i) {
n = getline(&line, &len, f);
if (n <= 0) {
ReleaseArchive();
fclose(f);
return -1;
}
key = strndup(line, strlen(line) - 1);
char* pSpace = strchr(key, ' ');
if (!pSpace) {
ReleaseArchive();
fclose(f);
free(key);
return -1;
}
*pSpace = '\0';
char* value = pSpace + 1;
int v = atoi(value);
dict *seqs = *g_archive.seqs;
dictEntry *entry = dictFind(seqs, key);
if (entry) {
entry->v.u64 = v;
} else {
dictAdd(seqs, key, (void*)(uint64_t)v);
}
free(key);
}
if (line)
free(line);
fclose(f);
return 0;
}
int NebulaSaveToFile(const char* file)
{
FILE *f = fopen(file, "w");
if (!f) {
return -1;
}
char buf[32];
snprintf(buf, sizeof(buf), "%d", g_archive.n_sub_apps);
fwrite(buf, 1, strlen(buf), f);
fwrite("\n", 1, 1, f);
int i;
for (i = 0; i < g_archive.n_sub_apps; ++i) {
fwrite(g_archive.sub_apps[i], 1, strlen(g_archive.sub_apps[i]), f);
fwrite("\n", 1, 1, f);
}
dict *seqs = *g_archive.seqs;
snprintf(buf, sizeof(buf), "%d", (int)dictSize(seqs));
fwrite(buf, 1, strlen(buf), f);
fwrite("\n", 1, 1, f);
dictIterator *it = dictGetIterator(seqs);
dictEntry *entry = dictNext(it);
while (entry) {
fwrite((const char*)entry->key, 1, strlen((const char*)entry->key), f);
fwrite(" ", 1, 1, f);
snprintf(buf, sizeof(buf), "%lu", entry->v.u64);
fwrite(buf, 1, strlen(buf), f);
fwrite("\n", 1, 1, f);
entry = dictNext(it);
}
int ret = fflush(f);
fclose(f);
return ret;
}
struct timer_entry g_save_entry;
void save_timer(timer_heap_t* ht, timer_entry* entry)
{
timer_update(ht, entry, 10000);
NebulaSaveToFile(g_storage_file);
}
void NebulaInitAutoSave()
{
timer_entry_init(&g_save_entry, 0, NULL, &save_timer);
timer_add(g_timer, &g_save_entry, 1000);
}

View File

@ -1,25 +0,0 @@
#ifndef ARCHIVE_H
#define ARCHIVE_H
#include "dict.h"
struct _Archive
{
int n_sub_apps;
char **sub_apps;
dict **seqs;
};
typedef struct _Archive Archive;
extern Archive g_archive;
void NebulaInitAutoSave();
int NebulaIsSubscribed(const char* appname);
int NebulaAddSubApp(const char* appname);
int NebulaLoadFromFile(const char* file);
int NebulaSaveToFile(const char* file);
#endif //ARCHIVE_H

View File

@ -1,112 +0,0 @@
#include "auth.h"
#include "connect.h"
#include "config.h"
#include <openssl/md5.h>
#include "str.h"
#include "string.h"
#include "connect.h"
#include <unistd.h>
char* g_token = "";
int NebulaAuth1()
{
Nebula__AuthRequest request;
nebula__auth_request__init(&request);
request.uid = g_device_tag;
request.username = g_device_tag;
return NebulaSend(MSG_SET_REQUEST(NEBULA_MSG_AUTH), (ProtobufCMessage*)&request);
}
int NebulaAuth2(char* token, char* nonce)
{
Nebula__AuthRequest request;
nebula__auth_request__init(&request);
request.uid = g_device_tag;
request.username = g_device_tag;
request.token = token;
request.nonce = nonce;
request.has_algorithm = 1;
request.algorithm = NEBULA__AUTH_REQUEST__ALGORITHM__MD5_DAA;
return NebulaSend(MSG_SET_REQUEST(NEBULA_MSG_AUTH), (ProtobufCMessage*)&request);
}
void NebulaOnAuth(NebulaHeader *head, const char* data, int len)
{
Nebula__AuthResponse *response = nebula__auth_response__unpack(NULL, len, (const uint8_t*)data);
if (!response) {
log_error("parse auth response error. data_len=%d", len);
return ;
}
if (response->status == 200) {
// auth success.
next_status();
} else {
if (Nebulaget_status() == eStatus_Auth2) {
// auth failed, retry redirect.
log_error("auth failed, rsp.status() == %d. sleep 1 and retry redirect.", response->status);
nebula__auth_response__free_unpacked(response, NULL);
sleep(1);
PopFront(g_server_list);
jump_status(eStatus_Connect);
return ;
}
static const char hex[] = "0123456789abcdef";
int i;
unsigned char ha1_b[16], ha1[32], token_b[16], token[33];
struct str buf;
string_init(&buf);
string_append_fast(&buf, g_salt, strlen(g_salt));
string_append_fast(&buf, ":", 1);
string_append_fast(&buf, g_device_tag, strlen(g_device_tag));
string_append_fast(&buf, ":", 1);
string_append_fast(&buf, response->nonce, strlen(response->nonce));
MD5((unsigned char*)buf.ptr, buf.len, ha1_b);
for (i = 0; i < MD5_DIGEST_LENGTH; i++)
{
ha1[i * 2] = hex[ha1_b[i] >> 4];
ha1[i * 2 + 1] = hex[ha1_b[i] & 0xf];
}
string_reset(&buf);
char *rule = g_rule;
while (*rule) {
if (!string_empty(&buf)) {
string_append_fast(&buf, ":", 1);
}
if (*rule == 'h') {
string_append_fast(&buf, (char*)ha1, 32);
} else if (*rule == 's') {
string_append_fast(&buf, g_salt, strlen(g_salt));
} else {
log_error("unkown rule: %s", g_rule);
}
rule++;
}
MD5((unsigned char*)buf.ptr, buf.len, token_b);
for (i = 0; i < MD5_DIGEST_LENGTH; i++)
{
token[i * 2] = hex[token_b[i] >> 4];
token[i * 2 + 1] = hex[token_b[i] & 0xf];
}
token[32] = '\0';
//log_debug("auth. md5buf:%s, token:%s", buf.ptr, token);
string_deinit(&buf);
if (-1 == NebulaAuth2((char*)token, response->nonce)) {
jump_status(eStatus_Redirect);
} else {
if (strlen(g_token)) free(g_token);
g_token = strdup((char*)token);
next_status();
}
}
nebula__auth_response__free_unpacked(response, NULL);
}

View File

@ -1,12 +0,0 @@
#ifndef AUTH_H
#define AUTH_H
#include "nebula_proto.h"
// auth 分为2步.
int NebulaAuth1();
void NebulaOnAuth(NebulaHeader *head, const char* data, int len);
#endif //AUTH_H

Binary file not shown.

View File

@ -1,63 +0,0 @@
#include "config.h"
eStatus g_status = eStatus_Init;
const char* Nebularand_string()
{
static char buf[32] = {};
int len = rand() % (sizeof(buf) - 1 - 16) + 16;
int i;
for (i = 0; i < len; ++i)
{
int v = rand() % 36;
if (v < 10)
buf[i] = '0' + v;
else
buf[i] = 'a' + v - 10;
}
buf[i] = '\0';
return buf;
}
const char* Nebulamsgtype_name(int type)
{
switch (type) {
case eNebulaMsg_Push: /// 推送 (路由器只需关心这一类消息)
return "eNebulaMsg_Push";
break;
case eNebulaMsg_Presence: /// Presence
return "eNebulaMsg_Presence";
break;
case eNebulaMsg_Sms: /// 网络短信
return "eNebulaMsg_Sms";
break;
case eNebulaMsg_Mms: /// 网络彩信
return "eNebulaMsg_Mms";
break;
}
return "";
}
const char* Nebulastatus_name(eStatus ss)
{
static const char* names[] = {
"eStatus_Init",
"eStatus_Redirect",
"eStatus_LoopTest",
"eStatus_Connect",
"eStatus_Connecting",
"eStatus_Auth1",
"eStatus_Auth1_Waiting",
"eStatus_Auth2",
"eStatus_Sub",
"eStatus_Estab",
};
return names[ss];
}
eStatus Nebulaget_status()
{
return g_status;
}

View File

@ -1,65 +0,0 @@
#ifndef CONFIG_H
#define CONFIG_H
#include "nebula_sdk.h"
#include "timer.h"
#include "logger.h"
#include "list.h"
#include "message.pb-c.h"
#include "nebula.pb-c.h"
enum _eStatus {
eStatus_Init,
eStatus_Redirect,
eStatus_LoopTest,
eStatus_Connect,
eStatus_Connecting,
eStatus_Auth1,
eStatus_Auth1_Waiting,
eStatus_Auth2,
eStatus_Sub,
eStatus_Estab,
};
typedef enum _eStatus eStatus;
extern char* g_device_tag;
extern char* g_nebula_host;
extern NebulaMsgCallback g_nebula_cb[eNebulaMsg_Max];
extern int g_storage_fd;
extern timer_heap_t *g_timer;
extern List *g_server_list;
extern char* g_salt;
extern char* g_rule;
extern char* g_token;
extern int g_sub_app_count;
extern char** g_sub_apps;
extern eStatus g_status;
const char* Nebularand_string();
const char* Nebulamsgtype_name(int type);
const char* Nebulastatus_name(eStatus ss);
eStatus Nebulaget_status();
#define next_status() \
do \
{\
if (g_status < eStatus_Estab) {\
g_status ++;\
log_info("set status to %s", Nebulastatus_name(g_status));\
} else {\
g_status = eStatus_Init;\
log_info("set status to %s", Nebulastatus_name(g_status));\
}\
} while(0)
#define jump_status(ss) \
do \
{\
g_status = ss;\
log_info("set status to %s", Nebulastatus_name(g_status));\
} while(0)
#endif //CONFIG_H

Binary file not shown.

View File

@ -1,208 +0,0 @@
#include "connect.h"
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include "config.h"
#include "net.h"
#include "auth.h"
#include "subscribe.h"
#include "nebula.pb-c.h"
#include "nebula_proto.h"
#include "nebula_compress_uncompress_wrapper.h"
#include "nebula_encrypt_decrypt_wrapper.h"
#include "push.h"
#include "timer.h"
static Conn* g_conn = NULL;
timer_entry g_ping_entry;
void Ping(timer_heap_t* ht, timer_entry *entry);
static void __on_connect(Conn* conn, int err)
{
if (err) {
// connect failed.
log_error("connect server_addr:%s:%d error:%s", conn->host, conn->port, strerror(err));
PopFront(g_server_list);
jump_status(eStatus_Connect);
return ;
}
log_info("connect success, server_addr:%s:%d", conn->host, conn->port);
timer_entry_init(&g_ping_entry, 0, NULL, &Ping);
timer_add(g_timer, &g_ping_entry, 180);
next_status();
}
static void __handle_message(NebulaHeader* head)
{
static char *buf1 = NULL;
if (!buf1)
buf1 = (char*)malloc(MAX_BUF_SIZE);
static char *buf2 = NULL;
if (!buf2)
buf2 = (char*)malloc(MAX_BUF_SIZE);
log_debug("NEBULA RX %s|%d", MsgType2Str(head->type), (int)htons(head->len));
if ((head->type & 0x7f) == NEBULA_MSG_PING) {
log_debug("pong.");
return ;
}
Nebula__NebulaMsg *msg = nebula__nebula_msg__unpack(NULL, htons(head->len), (uint8_t*)(head + 1));
if (!msg) {
log_debug("NebulaMsg parser error.");
return ;
}
char *data = (char*)msg->body.data;
uint32_t len = msg->body.len;
int compress_type = head->flag >> 4;
int encrypt_type = head->flag & 0x0f;
if (compress_type) {
// uncompress
uint32_t dst_len = MAX_BUF_SIZE;
if (-1 == NebulaUnCompress(compress_type, data, len, buf1, &dst_len)) {
log_debug("uncompress error. head->type=%d", head->type);
return ;
}
data = buf1;
len = dst_len;
}
if (encrypt_type) {
// unencrypt
uint32_t dst_len = MAX_BUF_SIZE;
if (-1 == NebulaDecrypt(encrypt_type, g_token,
strlen(g_token), data, len, buf2, &dst_len)) {
log_debug("unencrypt error. head->type=%d", head->type);
return ;
}
data = buf2;
len = dst_len;
}
// dispatch
if (MSG_IS_REQUEST(head)) {
// request
switch (head->type & 0x7f) {
case NEBULA_MSG_PSH:
NebulaOnPush(head, data, len);
break;
case NEBULA_MSG_MSG:
NebulaOnMsg(head, data, len);
break;
}
} else {
// response
switch (head->type & 0x7f) {
case NEBULA_MSG_AUTH:
NebulaOnAuth(head, data, len);
break;
case NEBULA_MSG_SUB:
NebulaOnSub(head, data, len);
break;
}
}
}
static void __on_read(Conn* conn, NebulaHeader* head)
{
(void)conn;
__handle_message(head);
}
static void __on_disconnect(Conn* conn)
{
(void)conn;
log_warn("tcp net disconnected, retry connect...");
timer_del(g_timer, &g_ping_entry);
if (Nebulaget_status() > eStatus_Connect)
jump_status(eStatus_Connect);
}
int NebulaConnect()
{
if (!g_conn) {
g_conn = NebulaConnCreate();
NebulaConnInit(g_conn, __on_connect, __on_read, __on_disconnect);
if (!g_conn) return -1;
}
if (g_conn->state == eConnState_Estab) {
NebulaDisconnect();
}
if (!g_server_list->size) {
// 没有ip列表, 重新redirect.
jump_status(eStatus_Redirect);
return -1;
}
struct sockaddr_in *addr = (struct sockaddr_in *)Front(g_server_list);
uint16_t port = htons(addr->sin_port);
char ip[32] = {};
inet_ntop(AF_INET, &addr->sin_addr.s_addr, ip, sizeof(ip));
if (-1 == NebulaConnConnect(g_conn, ip, port)) {
log_error("connect error, server_addr:%s:%d", ip, port);
PopFront(g_server_list);
return -1;
}
log_info("connect to server:%s:%d", ip, port);
return 0;
}
int NebulaSend(uint8_t type, ProtobufCMessage *msg)
{
NebulaHeader head;
HEAD_INIT(&head, type);
Nebula__NebulaMsg nebula_msg;
nebula__nebula_msg__init(&nebula_msg);
char msgid_buf[24];
CreateMsgid(msgid_buf);
nebula_msg.msgid = msgid_buf;
if (msg) {
nebula_msg.has_body = 1;
nebula_msg.body.len = protobuf_c_message_get_packed_size(msg);
nebula_msg.body.data = (uint8_t*)malloc(nebula_msg.body.len);
if (!nebula_msg.body.data) {
log_error("malloc error.");
return -1;
}
protobuf_c_message_pack(msg, nebula_msg.body.data);
}
int ret = NebulaConnSend(g_conn, &head, (ProtobufCMessage *)&nebula_msg);
if (nebula_msg.has_body) {
free(nebula_msg.body.data);
}
return ret;
}
void Ping(timer_heap_t* ht, timer_entry *entry)
{
NebulaHeader head;
HEAD_INIT(&head, MSG_SET_REQUEST(NEBULA_MSG_PING));
head.flag = 180;
//TODO: dynamic ping's time interval.
timer_update(ht, entry, head.flag * 1000);
if (-1 == NebulaConnSend(g_conn, &head, NULL)) {
log_error("Ping send error.");
}
}
void NebulaDisconnect()
{
NebulaConnNebulaDisconnect(g_conn);
}

View File

@ -1,14 +0,0 @@
#ifndef CONNECT_H
#define CONNECT_H
#include <google/protobuf-c/protobuf-c.h>
#define MAX_BUF_SIZE 4096
int NebulaConnect();
int NebulaSend(uint8_t type, ProtobufCMessage *msg);
void NebulaDisconnect();
#endif //CONNECT_H

View File

@ -1,60 +0,0 @@
#ifndef CRYPTO_FRAMWROK_H
#define CRYPTO_FRAMWROK_H
#include <inttypes.h>
#ifdef __cplusplus
extern "C" {
#endif
#define CRYPTO_OK 0
#define CRYPTO_UNDEF_MEMORY -1
#define CRYPTO_TOOSHORT_DST_LEN -2
#define CRYPTO_TOOSHORT_KEY_LEN -3
#define CRYPTO_SET_KEY_ERROR -4
#define CRYPTO_SRC_LEN_ZERO -5
#define CRYPTO1_BLOCK_SIZE 16
#define CRYPTO2_BLOCK_SIZE 16
#define CRYPTO3_BLOCK_SIZE 8
/*
* CRYPTO_UNDEF_MEMORY means key,src,dst is NULL
* CRYPTO_TOOSHORT_DST_LEN means dst_len too short
* if(*len < src_len)
return CRYPTO_TOOSHORT_DST_LEN;
if(*len < src_len + BLOCK_SIZE - src_len % BLOCK_SIZE)
if(src_len % BLOCK_SIZE != 0)
return CRYPTO_TOOSHORT_DST_LEN;
typically src_len = *len = BLOCK_SIZE * n (n = 1,2,3....) is recommend
* CRYPTO_TOOSHORT_KEY_LEN means key_len < 16
* CRYPTO_SET_KEY_ERROR means set key error(hardly occurs)
*/
/*
* fast : CRYPTO3 > CRYPTO2 > CRYPTO1
* secure : CRYPTO2 > CRYPTO1 > CRYPTO3
* 128 bits key is less secure than 256 bits,but run faster
*/
/* CRYPTO1 is fast */
int CRYPTO1_encrypt(const unsigned char *key,const uint32_t key_len,const unsigned char *src,const uint32_t src_len,unsigned char *dst,uint32_t *len);
int CRYPTO1_decrypt(const unsigned char *key,const uint32_t key_len,const unsigned char *src,const uint32_t src_len,unsigned char *dst,uint32_t *len);
/* CRYPTO2 is slightly slower but safer*/
int CRYPTO2_encrypt(const unsigned char *key,const uint32_t key_len,const unsigned char *src,const uint32_t src_len,unsigned char *dst,uint32_t *len);
int CRYPTO2_decrypt(const unsigned char *key,const uint32_t key_len,const unsigned char *src,const uint32_t src_len,unsigned char *dst,uint32_t *len);
/* CRYPTO3 is less secure but faster*/
int CRYPTO3_encrypt(const unsigned char *key,const uint32_t key_len,const unsigned char *src,const uint32_t src_len,unsigned char *dst,uint32_t *len);
int CRYPTO3_decrypt(const unsigned char *key,const uint32_t key_len,const unsigned char *src,const uint32_t src_len,unsigned char *dst,uint32_t *len);
/* implement of CRYPTO2 */
int CRYPTO_encrypt_without_key(const unsigned char *src,const uint32_t src_len,unsigned char *dst,uint32_t *len);
int CRYPTO_decrypt_without_key(const unsigned char *src,const uint32_t src_len,unsigned char *dst,uint32_t *len);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,3 +0,0 @@
1
com.meizu.cloud
0

View File

@ -1,811 +0,0 @@
/* Hash Tables Implementation.
*
* This file implements in memory hash tables with insert/del/replace/find/
* get-random-element operations. Hash tables will auto resize if needed
* tables of power of two in size are used, collisions are handled by
* chaining. See the source code for more information... :)
*
* Copyright (c) 2006-2012, Salvatore Sanfilippo <antirez at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Redis nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include <limits.h>
#include <sys/time.h>
#include <ctype.h>
#include "dict.h"
/* Using dictEnableResize() / dictDisableResize() we make possible to
* enable/disable resizing of the hash table as needed. This is very important
* for Redis, as we use copy-on-write and don't want to move too much memory
* around when there is a child performing saving operations.
*
* Note that even when dict_can_resize is set to 0, not all resizes are
* prevented: an hash table is still allowed to grow if the ratio between
* the number of elements and the buckets > dict_force_resize_ratio. */
static int dict_can_resize = 1;
static unsigned int dict_force_resize_ratio = 5;
/* -------------------------- private prototypes ---------------------------- */
static int _dictExpandIfNeeded(dict *ht);
static unsigned long _dictNextPower(unsigned long size);
static int _dictKeyIndex(dict *ht, const void *key);
static int _dictInit(dict *ht, dictType *type, void *privDataPtr);
/* -------------------------- hash functions -------------------------------- */
/* Thomas Wang's 32 bit Mix Function */
unsigned int dictIntHashFunction(unsigned int key)
{
key += ~(key << 15);
key ^= (key >> 10);
key += (key << 3);
key ^= (key >> 6);
key += ~(key << 11);
key ^= (key >> 16);
return key;
}
/* Identity hash function for integer keys */
unsigned int dictIdentityHashFunction(unsigned int key)
{
return key;
}
static uint32_t dict_hash_function_seed = 5381;
void dictSetHashFunctionSeed(uint32_t seed) {
dict_hash_function_seed = seed;
}
uint32_t dictGetHashFunctionSeed(void) {
return dict_hash_function_seed;
}
/* MurmurHash2, by Austin Appleby
* Note - This code makes a few assumptions about how your machine behaves -
* 1. We can read a 4-byte value from any address without crashing
* 2. sizeof(int) == 4
*
* And it has a few limitations -
*
* 1. It will not work incrementally.
* 2. It will not produce the same results on little-endian and big-endian
* machines.
*/
unsigned int dictGenHashFunction(const void *key, int len) {
/* 'm' and 'r' are mixing constants generated offline.
They're not really 'magic', they just happen to work well. */
uint32_t seed = dict_hash_function_seed;
const uint32_t m = 0x5bd1e995;
const int r = 24;
/* Initialize the hash to a 'random' value */
uint32_t h = seed ^ len;
/* Mix 4 bytes at a time into the hash */
const unsigned char *data = (const unsigned char *)key;
while(len >= 4) {
uint32_t k = *(uint32_t*)data;
k *= m;
k ^= k >> r;
k *= m;
h *= m;
h ^= k;
data += 4;
len -= 4;
}
/* Handle the last few bytes of the input array */
switch(len) {
case 3: h ^= data[2] << 16;
case 2: h ^= data[1] << 8;
case 1: h ^= data[0]; h *= m;
};
/* Do a few final mixes of the hash to ensure the last few
* bytes are well-incorporated. */
h ^= h >> 13;
h *= m;
h ^= h >> 15;
return (unsigned int)h;
}
/* And a case insensitive hash function (based on djb hash) */
unsigned int dictGenCaseHashFunction(const unsigned char *buf, int len) {
unsigned int hash = (unsigned int)dict_hash_function_seed;
while (len--)
hash = ((hash << 5) + hash) + (tolower(*buf++)); /* hash * 33 + c */
return hash;
}
/* ----------------------------- API implementation ------------------------- */
/* Reset a hash table already initialized with ht_init().
* NOTE: This function should only be called by ht_destroy(). */
static void _dictReset(dictht *ht)
{
ht->table = NULL;
ht->size = 0;
ht->sizemask = 0;
ht->used = 0;
}
/* Create a new hash table */
dict *dictCreate(dictType *type,
void *privDataPtr)
{
dict *d = (dict*)malloc(sizeof(*d));
if(d == NULL) {
return NULL;
}
_dictInit(d,type,privDataPtr);
return d;
}
/* Initialize the hash table */
int _dictInit(dict *d, dictType *type,
void *privDataPtr)
{
_dictReset(&d->ht[0]);
_dictReset(&d->ht[1]);
d->type = type;
d->privdata = privDataPtr;
d->rehashidx = -1;
d->iterators = 0;
return DICT_OK;
}
/* Resize the table to the minimal size that contains all the elements,
* but with the invariant of a USED/BUCKETS ratio near to <= 1 */
int dictResize(dict *d)
{
int minimal;
if (!dict_can_resize || dictIsRehashing(d)) return DICT_ERR;
minimal = d->ht[0].used;
if (minimal < DICT_HT_INITIAL_SIZE)
minimal = DICT_HT_INITIAL_SIZE;
return dictExpand(d, minimal);
}
/* Expand or create the hash table */
int dictExpand(dict *d, unsigned long size)
{
dictht n; /* the new hash table */
unsigned long realsize = _dictNextPower(size);
/* the size is invalid if it is smaller than the number of
* elements already inside the hash table */
if (dictIsRehashing(d) || d->ht[0].used > size)
return DICT_ERR;
/* Allocate the new hash table and initialize all pointers to NULL */
n.size = realsize;
n.sizemask = realsize-1;
n.table = (dictEntry**)calloc(1, realsize*sizeof(dictEntry*));
n.used = 0;
/* Is this the first initialization? If so it's not really a rehashing
* we just set the first hash table so that it can accept keys. */
if (d->ht[0].table == NULL) {
d->ht[0] = n;
return DICT_OK;
}
/* Prepare a second hash table for incremental rehashing */
d->ht[1] = n;
d->rehashidx = 0;
return DICT_OK;
}
/* Performs N steps of incremental rehashing. Returns 1 if there are still
* keys to move from the old to the new hash table, otherwise 0 is returned.
* Note that a rehashing step consists in moving a bucket (that may have more
* thank one key as we use chaining) from the old to the new hash table. */
int dictRehash(dict *d, int n) {
if (!dictIsRehashing(d)) return 0;
while(n--) {
dictEntry *de, *nextde;
/* Check if we already rehashed the whole table... */
if (d->ht[0].used == 0) {
free(d->ht[0].table);
d->ht[0] = d->ht[1];
_dictReset(&d->ht[1]);
d->rehashidx = -1;
return 0;
}
/* Note that rehashidx can't overflow as we are sure there are more
* elements because ht[0].used != 0 */
assert(d->ht[0].size > (unsigned)d->rehashidx);
while(d->ht[0].table[d->rehashidx] == NULL) d->rehashidx++;
de = d->ht[0].table[d->rehashidx];
/* Move all the keys in this bucket from the old to the new hash HT */
while(de) {
unsigned int h;
nextde = de->next;
/* Get the index in the new hash table */
h = dictHashKey(d, de->key) & d->ht[1].sizemask;
de->next = d->ht[1].table[h];
d->ht[1].table[h] = de;
d->ht[0].used--;
d->ht[1].used++;
de = nextde;
}
d->ht[0].table[d->rehashidx] = NULL;
d->rehashidx++;
}
return 1;
}
long long timeInMilliseconds(void) {
struct timeval tv;
gettimeofday(&tv,NULL);
return (((long long)tv.tv_sec)*1000)+(tv.tv_usec/1000);
}
/* Rehash for an amount of time between ms milliseconds and ms+1 milliseconds */
int dictRehashMilliseconds(dict *d, int ms) {
long long start = timeInMilliseconds();
int rehashes = 0;
while(dictRehash(d,100)) {
rehashes += 100;
if (timeInMilliseconds()-start > ms) break;
}
return rehashes;
}
/* This function performs just a step of rehashing, and only if there are
* no safe iterators bound to our hash table. When we have iterators in the
* middle of a rehashing we can't mess with the two hash tables otherwise
* some element can be missed or duplicated.
*
* This function is called by common lookup or update operations in the
* dictionary so that the hash table automatically migrates from H1 to H2
* while it is actively used. */
static void _dictRehashStep(dict *d) {
if (d->iterators == 0) dictRehash(d,1);
}
/* Add an element to the target hash table */
int dictAdd(dict *d, void *key, void *val)
{
dictEntry *entry = dictAddRaw(d,key);
if (!entry) return DICT_ERR;
dictSetVal(d, entry, val);
return DICT_OK;
}
/* Low level add. This function adds the entry but instead of setting
* a value returns the dictEntry structure to the user, that will make
* sure to fill the value field as he wishes.
*
* This function is also directly exposed to user API to be called
* mainly in order to store non-pointers inside the hash value, example:
*
* entry = dictAddRaw(dict,mykey);
* if (entry != NULL) dictSetSignedIntegerVal(entry,1000);
*
* Return values:
*
* If key already exists NULL is returned.
* If key was added, the hash entry is returned to be manipulated by the caller.
*/
dictEntry *dictAddRaw(dict *d, void *key)
{
int index;
dictEntry *entry;
dictht *ht;
if (dictIsRehashing(d)) _dictRehashStep(d);
/* Get the index of the new element, or -1 if
* the element already exists. */
if ((index = _dictKeyIndex(d, key)) == -1)
return NULL;
/* Allocate the memory and store the new entry */
ht = dictIsRehashing(d) ? &d->ht[1] : &d->ht[0];
entry = (dictEntry*)malloc(sizeof(*entry));
entry->next = ht->table[index];
ht->table[index] = entry;
ht->used++;
/* Set the hash entry fields. */
dictSetKey(d, entry, key);
return entry;
}
/* Add an element, discarding the old if the key already exists.
* Return 1 if the key was added from scratch, 0 if there was already an
* element with such key and dictReplace() just performed a value update
* operation. */
int dictReplace(dict *d, void *key, void *val)
{
dictEntry *entry, auxentry;
/* Try to add the element. If the key
* does not exists dictAdd will suceed. */
if (dictAdd(d, key, val) == DICT_OK)
return 1;
/* It already exists, get the entry */
entry = dictFind(d, key);
/* Set the new value and free the old one. Note that it is important
* to do that in this order, as the value may just be exactly the same
* as the previous one. In this context, think to reference counting,
* you want to increment (set), and then decrement (free), and not the
* reverse. */
auxentry = *entry;
dictSetVal(d, entry, val);
dictFreeVal(d, &auxentry);
return 0;
}
/* dictReplaceRaw() is simply a version of dictAddRaw() that always
* returns the hash entry of the specified key, even if the key already
* exists and can't be added (in that case the entry of the already
* existing key is returned.)
*
* See dictAddRaw() for more information. */
dictEntry *dictReplaceRaw(dict *d, void *key) {
dictEntry *entry = dictFind(d,key);
return entry ? entry : dictAddRaw(d,key);
}
/* Search and remove an element */
static int dictGenericDelete(dict *d, const void *key, int nofree)
{
unsigned int h, idx;
dictEntry *he, *prevHe;
int table;
if (d->ht[0].size == 0) return DICT_ERR; /* d->ht[0].table is NULL */
if (dictIsRehashing(d)) _dictRehashStep(d);
h = dictHashKey(d, key);
for (table = 0; table <= 1; table++) {
idx = h & d->ht[table].sizemask;
he = d->ht[table].table[idx];
prevHe = NULL;
while(he) {
if (dictCompareKeys(d, key, he->key)) {
/* Unlink the element from the list */
if (prevHe)
prevHe->next = he->next;
else
d->ht[table].table[idx] = he->next;
if (!nofree) {
dictFreeKey(d, he);
dictFreeVal(d, he);
}
free(he);
d->ht[table].used--;
return DICT_OK;
}
prevHe = he;
he = he->next;
}
if (!dictIsRehashing(d)) break;
}
return DICT_ERR; /* not found */
}
int dictDelete(dict *ht, const void *key) {
return dictGenericDelete(ht,key,0);
}
int dictDeleteNoFree(dict *ht, const void *key) {
return dictGenericDelete(ht,key,1);
}
/* Destroy an entire dictionary */
int _dictClear(dict *d, dictht *ht)
{
unsigned long i;
/* Free all the elements */
for (i = 0; i < ht->size && ht->used > 0; i++) {
dictEntry *he, *nextHe;
if ((he = ht->table[i]) == NULL) continue;
while(he) {
nextHe = he->next;
dictFreeKey(d, he);
dictFreeVal(d, he);
free(he);
ht->used--;
he = nextHe;
}
}
/* Free the table and the allocated cache structure */
free(ht->table);
/* Re-initialize the table */
_dictReset(ht);
return DICT_OK; /* never fails */
}
/* Clear & Release the hash table */
void dictRelease(dict *d)
{
_dictClear(d,&d->ht[0]);
_dictClear(d,&d->ht[1]);
free(d);
}
dictEntry *dictFind(dict *d, const void *key)
{
dictEntry *he;
unsigned int h, idx, table;
if (d->ht[0].size == 0) return NULL; /* We don't have a table at all */
if (dictIsRehashing(d)) _dictRehashStep(d);
h = dictHashKey(d, key);
for (table = 0; table <= 1; table++) {
idx = h & d->ht[table].sizemask;
he = d->ht[table].table[idx];
while(he) {
if (dictCompareKeys(d, key, he->key))
return he;
he = he->next;
}
if (!dictIsRehashing(d)) return NULL;
}
return NULL;
}
void *dictFetchValue(dict *d, const void *key) {
dictEntry *he;
he = dictFind(d,key);
return he ? dictGetVal(he) : NULL;
}
dictIterator *dictGetIterator(dict *d)
{
dictIterator *iter = (dictIterator*)malloc(sizeof(*iter));
iter->d = d;
iter->table = 0;
iter->index = -1;
iter->safe = 0;
iter->entry = NULL;
iter->nextEntry = NULL;
return iter;
}
dictIterator *dictGetSafeIterator(dict *d) {
dictIterator *i = dictGetIterator(d);
i->safe = 1;
return i;
}
dictEntry *dictNext(dictIterator *iter)
{
while (1) {
if (iter->entry == NULL) {
dictht *ht = &iter->d->ht[iter->table];
if (iter->safe && iter->index == -1 && iter->table == 0)
iter->d->iterators++;
iter->index++;
if (iter->index >= (signed) ht->size) {
if (dictIsRehashing(iter->d) && iter->table == 0) {
iter->table++;
iter->index = 0;
ht = &iter->d->ht[1];
} else {
break;
}
}
iter->entry = ht->table[iter->index];
} else {
iter->entry = iter->nextEntry;
}
if (iter->entry) {
/* We need to save the 'next' here, the iterator user
* may delete the entry we are returning. */
iter->nextEntry = iter->entry->next;
return iter->entry;
}
}
return NULL;
}
void dictReleaseIterator(dictIterator *iter)
{
if (iter->safe && !(iter->index == -1 && iter->table == 0))
iter->d->iterators--;
free(iter);
}
/* Return a random entry from the hash table. Useful to
* implement randomized algorithms */
dictEntry *dictGetRandomKey(dict *d)
{
dictEntry *he, *orighe;
unsigned int h;
int listlen, listele;
if (dictSize(d) == 0) return NULL;
if (dictIsRehashing(d)) _dictRehashStep(d);
if (dictIsRehashing(d)) {
do {
h = random() % (d->ht[0].size+d->ht[1].size);
he = (h >= d->ht[0].size) ? d->ht[1].table[h - d->ht[0].size] :
d->ht[0].table[h];
} while(he == NULL);
} else {
do {
h = random() & d->ht[0].sizemask;
he = d->ht[0].table[h];
} while(he == NULL);
}
/* Now we found a non empty bucket, but it is a linked
* list and we need to get a random element from the list.
* The only sane way to do so is counting the elements and
* select a random index. */
listlen = 0;
orighe = he;
while(he) {
he = he->next;
listlen++;
}
listele = random() % listlen;
he = orighe;
while(listele--) he = he->next;
return he;
}
/* ------------------------- private functions ------------------------------ */
/* Expand the hash table if needed */
static int _dictExpandIfNeeded(dict *d)
{
/* Incremental rehashing already in progress. Return. */
if (dictIsRehashing(d)) return DICT_OK;
/* If the hash table is empty expand it to the initial size. */
if (d->ht[0].size == 0) return dictExpand(d, DICT_HT_INITIAL_SIZE);
/* If we reached the 1:1 ratio, and we are allowed to resize the hash
* table (global setting) or we should avoid it but the ratio between
* elements/buckets is over the "safe" threshold, we resize doubling
* the number of buckets. */
if (d->ht[0].used >= d->ht[0].size &&
(dict_can_resize ||
d->ht[0].used/d->ht[0].size > dict_force_resize_ratio))
{
return dictExpand(d, ((d->ht[0].size > d->ht[0].used) ?
d->ht[0].size : d->ht[0].used)*2);
}
return DICT_OK;
}
/* Our hash table capability is a power of two */
static unsigned long _dictNextPower(unsigned long size)
{
unsigned long i = DICT_HT_INITIAL_SIZE;
if (size >= LONG_MAX) return LONG_MAX;
while(1) {
if (i >= size)
return i;
i *= 2;
}
}
/* Returns the index of a free slot that can be populated with
* an hash entry for the given 'key'.
* If the key already exists, -1 is returned.
*
* Note that if we are in the process of rehashing the hash table, the
* index is always returned in the context of the second (new) hash table. */
static int _dictKeyIndex(dict *d, const void *key)
{
unsigned int h, idx, table;
dictEntry *he;
/* Expand the hash table if needed */
if (_dictExpandIfNeeded(d) == DICT_ERR)
return -1;
/* Compute the key hash value */
h = dictHashKey(d, key);
for (table = 0; table <= 1; table++) {
idx = h & d->ht[table].sizemask;
/* Search if this slot does not already contain the given key */
he = d->ht[table].table[idx];
while(he) {
if (dictCompareKeys(d, key, he->key))
return -1;
he = he->next;
}
if (!dictIsRehashing(d)) break;
}
return idx;
}
void dictEmpty(dict *d) {
_dictClear(d,&d->ht[0]);
_dictClear(d,&d->ht[1]);
d->rehashidx = -1;
d->iterators = 0;
}
void dictEnableResize(void) {
dict_can_resize = 1;
}
void dictDisableResize(void) {
dict_can_resize = 0;
}
#if 0
/* The following is code that we don't use for Redis currently, but that is part
of the library. */
/* ----------------------- Debugging ------------------------*/
#define DICT_STATS_VECTLEN 50
static void _dictPrintStatsHt(dictht *ht) {
unsigned long i, slots = 0, chainlen, maxchainlen = 0;
unsigned long totchainlen = 0;
unsigned long clvector[DICT_STATS_VECTLEN];
if (ht->used == 0) {
printf("No stats available for empty dictionaries\n");
return;
}
for (i = 0; i < DICT_STATS_VECTLEN; i++) clvector[i] = 0;
for (i = 0; i < ht->size; i++) {
dictEntry *he;
if (ht->table[i] == NULL) {
clvector[0]++;
continue;
}
slots++;
/* For each hash entry on this slot... */
chainlen = 0;
he = ht->table[i];
while(he) {
chainlen++;
he = he->next;
}
clvector[(chainlen < DICT_STATS_VECTLEN) ? chainlen : (DICT_STATS_VECTLEN-1)]++;
if (chainlen > maxchainlen) maxchainlen = chainlen;
totchainlen += chainlen;
}
printf("Hash table stats:\n");
printf(" table size: %ld\n", ht->size);
printf(" number of elements: %ld\n", ht->used);
printf(" different slots: %ld\n", slots);
printf(" max chain length: %ld\n", maxchainlen);
printf(" avg chain length (counted): %.02f\n", (float)totchainlen/slots);
printf(" avg chain length (computed): %.02f\n", (float)ht->used/slots);
printf(" Chain length distribution:\n");
for (i = 0; i < DICT_STATS_VECTLEN-1; i++) {
if (clvector[i] == 0) continue;
printf(" %s%ld: %ld (%.02f%%)\n",(i == DICT_STATS_VECTLEN-1)?">= ":"", i, clvector[i], ((float)clvector[i]/ht->size)*100);
}
}
void dictPrintStats(dict *d) {
_dictPrintStatsHt(&d->ht[0]);
if (dictIsRehashing(d)) {
printf("-- Rehashing into ht[1]:\n");
_dictPrintStatsHt(&d->ht[1]);
}
}
/* ----------------------- StringCopy Hash Table Type ------------------------*/
#endif
static unsigned int _dictStringCopyHTHashFunction(const void *key)
{
return dictGenHashFunction(key, strlen((const char*)key));
}
static void *_dictStringDup(void *privdata, const void *key)
{
int len = strlen((const char*)key);
char *copy = (char*)malloc(len+1);
DICT_NOTUSED(privdata);
memcpy(copy, key, len);
copy[len] = '\0';
return copy;
}
static int _dictStringCopyHTKeyCompare(void *privdata, const void *key1,
const void *key2)
{
DICT_NOTUSED(privdata);
return strcmp((const char*)key1, (const char*)key2) == 0;
}
static void _dictStringDestructor(void *privdata, void *key)
{
DICT_NOTUSED(privdata);
free(key);
}
dictType dictTypeHeapStringCopyKey = {
_dictStringCopyHTHashFunction, /* hash function */
_dictStringDup, /* key dup */
NULL, /* val dup */
_dictStringCopyHTKeyCompare, /* key compare */
_dictStringDestructor, /* key destructor */
NULL /* val destructor */
};
/* This is like StringCopy but does not auto-duplicate the key.
* It's used for intepreter's shared strings. */
dictType dictTypeHeapStrings = {
_dictStringCopyHTHashFunction, /* hash function */
NULL, /* key dup */
NULL, /* val dup */
_dictStringCopyHTKeyCompare, /* key compare */
_dictStringDestructor, /* key destructor */
NULL /* val destructor */
};
/* This is like StringCopy but also automatically handle dynamic
* allocated C strings as values. */
dictType dictTypeHeapStringCopyKeyValue = {
_dictStringCopyHTHashFunction, /* hash function */
_dictStringDup, /* key dup */
_dictStringDup, /* val dup */
_dictStringCopyHTKeyCompare, /* key compare */
_dictStringDestructor, /* key destructor */
_dictStringDestructor, /* val destructor */
};

View File

@ -1,181 +0,0 @@
/* Hash Tables Implementation.
*
* This file implements in-memory hash tables with insert/del/replace/find/
* get-random-element operations. Hash tables will auto-resize if needed
* tables of power of two in size are used, collisions are handled by
* chaining. See the source code for more information... :)
*
* Copyright (c) 2006-2012, Salvatore Sanfilippo <antirez at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Redis nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdint.h>
#ifndef __DICT_H
#define __DICT_H
#ifdef __cplusplus
extern "C" {
#endif
#define DICT_OK 0
#define DICT_ERR 1
/* Unused arguments generate annoying warnings... */
#define DICT_NOTUSED(V) ((void) V)
typedef struct dictEntry {
void *key;
union {
void *val;
uint64_t u64;
int64_t s64;
} v;
struct dictEntry *next;
} dictEntry;
typedef struct dictType {
unsigned int (*hashFunction)(const void *key);
void *(*keyDup)(void *privdata, const void *key);
void *(*valDup)(void *privdata, const void *obj);
int (*keyCompare)(void *privdata, const void *key1, const void *key2);
void (*keyDestructor)(void *privdata, void *key);
void (*valDestructor)(void *privdata, void *obj);
} dictType;
/* This is our hash table structure. Every dictionary has two of this as we
* implement incremental rehashing, for the old to the new table. */
typedef struct dictht {
dictEntry **table;
unsigned long size;
unsigned long sizemask;
unsigned long used;
} dictht;
typedef struct dict {
dictType *type;
void *privdata;
dictht ht[2];
int rehashidx; /* rehashing not in progress if rehashidx == -1 */
int iterators; /* number of iterators currently running */
} dict;
/* If safe is set to 1 this is a safe iterator, that means, you can call
* dictAdd, dictFind, and other functions against the dictionary even while
* iterating. Otherwise it is a non safe iterator, and only dictNext()
* should be called while iterating. */
typedef struct dictIterator {
dict *d;
int table, index, safe;
dictEntry *entry, *nextEntry;
} dictIterator;
/* This is the initial size of every hash table */
#define DICT_HT_INITIAL_SIZE 4
/* ------------------------------- Macros ------------------------------------*/
#define dictFreeVal(d, entry) \
if ((d)->type->valDestructor) \
(d)->type->valDestructor((d)->privdata, (entry)->v.val)
#define dictSetVal(d, entry, _val_) do { \
if ((d)->type->valDup) \
entry->v.val = (d)->type->valDup((d)->privdata, _val_); \
else \
entry->v.val = (_val_); \
} while(0)
#define dictSetSignedIntegerVal(entry, _val_) \
do { entry->v.s64 = _val_; } while(0)
#define dictSetUnsignedIntegerVal(entry, _val_) \
do { entry->v.u64 = _val_; } while(0)
#define dictFreeKey(d, entry) \
if ((d)->type->keyDestructor) \
(d)->type->keyDestructor((d)->privdata, (entry)->key)
#define dictSetKey(d, entry, _key_) do { \
if ((d)->type->keyDup) \
entry->key = (d)->type->keyDup((d)->privdata, _key_); \
else \
entry->key = (_key_); \
} while(0)
#define dictCompareKeys(d, key1, key2) \
(((d)->type->keyCompare) ? \
(d)->type->keyCompare((d)->privdata, key1, key2) : \
(key1) == (key2))
#define dictHashKey(d, key) (d)->type->hashFunction(key)
#define dictGetKey(he) ((he)->key)
#define dictGetVal(he) ((he)->v.val)
#define dictGetSignedIntegerVal(he) ((he)->v.s64)
#define dictGetUnsignedIntegerVal(he) ((he)->v.u64)
#define dictSlots(d) ((d)->ht[0].size+(d)->ht[1].size)
#define dictSize(d) ((d)->ht[0].used+(d)->ht[1].used)
#define dictIsRehashing(ht) ((ht)->rehashidx != -1)
/* API */
dict *dictCreate(dictType *type, void *privDataPtr);
int dictExpand(dict *d, unsigned long size);
int dictAdd(dict *d, void *key, void *val);
dictEntry *dictAddRaw(dict *d, void *key);
int dictReplace(dict *d, void *key, void *val);
dictEntry *dictReplaceRaw(dict *d, void *key);
int dictDelete(dict *d, const void *key);
int dictDeleteNoFree(dict *d, const void *key);
void dictRelease(dict *d);
dictEntry * dictFind(dict *d, const void *key);
void *dictFetchValue(dict *d, const void *key);
int dictResize(dict *d);
dictIterator *dictGetIterator(dict *d);
dictIterator *dictGetSafeIterator(dict *d);
dictEntry *dictNext(dictIterator *iter);
void dictReleaseIterator(dictIterator *iter);
dictEntry *dictGetRandomKey(dict *d);
void dictPrintStats(dict *d);
unsigned int dictGenHashFunction(const void *key, int len);
unsigned int dictGenCaseHashFunction(const unsigned char *buf, int len);
void dictEmpty(dict *d);
void dictEnableResize(void);
void dictDisableResize(void);
int dictRehash(dict *d, int n);
int dictRehashMilliseconds(dict *d, int ms);
void dictSetHashFunctionSeed(unsigned int initval);
unsigned int dictGetHashFunctionSeed(void);
/* Hash table types */
extern dictType dictTypeHeapStringCopyKey;
extern dictType dictTypeHeapStrings;
extern dictType dictTypeHeapStringCopyKeyValue;
#ifdef __cplusplus
}
#endif
#endif /* __DICT_H */

Binary file not shown.

View File

@ -1,156 +0,0 @@
#include "list.h"
#include <assert.h>
#include <stdlib.h>
List* CreateList()
{
List *list = (List*)malloc(sizeof(List));
if (NULL == list) return NULL;
list->head = list->tail = NULL;
list->size = 0;
return list;
}
void DestroyList(List* list)
{
ClearList(list);
free(list);
}
void ClearList(List* list)
{
Node *pos = list->head;
while (NULL != pos)
{
Node *old = pos;
pos = pos->next;
free(old->data);
free(old);
}
list->head = list->tail = NULL;
list->size = 0;
}
int PushBack(List* list, void* data)
{
if (NULL == list->tail) {
list->head = list->tail = (Node*)malloc(sizeof(Node));
if (!list->tail)
return -1;
list->tail->next = list->tail->prev = NULL;
list->tail->data = data;
++list->size;
return 0;
}
Node *newNode = (Node*)malloc(sizeof(Node));
if (!newNode)
return -1;
newNode->data = data;
newNode->next = NULL;
newNode->prev = list->tail;
list->tail->next = newNode;
list->tail = newNode;
++list->size;
return 0;
}
int PushFront(List* list, void* data)
{
if (NULL == list->head) {
list->head = list->tail = (Node*)malloc(sizeof(Node));
if (!list->tail)
return -1;
list->tail->next = list->tail->prev = NULL;
list->tail->data = data;
++list->size;
return 0;
}
Node *newNode = (Node*)malloc(sizeof(Node));
if (!newNode)
return -1;
newNode->data = data;
newNode->next = list->head;
newNode->prev = NULL;
list->head->prev = newNode;
list->head = newNode;
++list->size;
return 0;
}
void PopBack(List* list)
{
if (0 == list->size) return ;
--list->size;
if (list->head == list->tail) {
ClearList(list);
return ;
}
free(list->tail->data);
list->tail = list->tail->prev;
free(list->tail->next);
list->tail->next = NULL;
}
void PopFront(List* list)
{
if (0 == list->size) return ;
--list->size;
if (list->head == list->tail) {
ClearList(list);
return ;
}
free(list->head->data);
list->head = list->head->next;
free(list->head->prev);
list->head->prev = NULL;
}
void* Back(List* list)
{
if (0 == list->size) return NULL;
return list->tail->data;
}
void* Front(List* list)
{
if (0 == list->size) return NULL;
return list->head->data;
}
ListIterator ListBegin(List* list)
{
if (!list->head) return NULL;
return &list->head->data;
}
ListIterator ListNext(ListIterator itr)
{
if (!itr) return NULL;
Node *node = (Node*)itr;
if (!node->next) return NULL;
return &node->next->data;
}
int Accumulate(List* list, int(*pred)(void* data))
{
int result = 0;
Node *pos = list->head;
while (pos) {
result += pred(pos->data);
pos = pos->next;
}
return result;
}

View File

@ -1,34 +0,0 @@
#ifndef __ASYNC_FCGI_LIST__
#define __ASYNC_FCGI_LIST__
typedef struct Node {
void *data;
struct Node *prev;
struct Node *next;
} Node;
typedef struct List {
Node *head;
Node *tail;
unsigned long size;
} List;
List* CreateList();
void DestroyList(List* list);
void ClearList(List* list);
int PushBack(List* list, void* data);
int PushFront(List* list, void* data);
void PopBack(List* list);
void PopFront(List* list);
void* Back(List* list);
void* Front(List* list);
// iterator
typedef void** ListIterator;
ListIterator ListBegin(List* list);
ListIterator ListNext(ListIterator itr);
// algorithm
int Accumulate(List* list, int(*pred)(void* data));
#endif //__ASYNC_FCGI_LIST__

Binary file not shown.

View File

@ -1,132 +0,0 @@
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdarg.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>
#include <assert.h>
#include "logger.h"
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#ifndef LOG_MAX_LEN
#define LOG_MAX_LEN 8192
#endif
typedef struct logger_t {
int fd;
int level;
char* name;
}logger_t;
logger_t logger = {STDERR_FILENO, LOG_LEVEL_VERB, NULL};
static const char* strlevel[] = {
"ERROR",
"WARN",
"NOTICE",
"INFO",
"DEBUG",
"VERB"
};
void log_init(logger_t *log, const char* name, int level)
{
log->level = MAX(LOG_LEVEL_ERR, MIN(level, LOG_LEVEL_VERB));
if(name == NULL || *name == '\0'){
log->fd = STDERR_FILENO;
}else{
log->name = strdup(name);
if(log->name == NULL) {
log->fd = STDERR_FILENO;
return;
}
log->fd = open(name, O_WRONLY | O_APPEND | O_CREAT, 0644);
if(log->fd < 0 ) {
log->fd = STDERR_FILENO;
}
}
}
void log_deinit(logger_t *log)
{
if(log->fd > 0 && log->fd != STDERR_FILENO)
close(log->fd);
if(log->name)
free(log->name);
}
void log_write(logger_t *log, int level, const char *file, int line, const char* func, const char *fmt, ...)
{
struct tm local;
struct timeval tv;
va_list args;
int len;
char buffer[LOG_MAX_LEN];
gettimeofday(&tv, NULL);
localtime_r(&tv.tv_sec, &local);
level = MAX(LOG_LEVEL_ERR, MIN(level, LOG_LEVEL_VERB));
len = snprintf(buffer, sizeof(buffer), "[%04d-%02d-%02d %02d:%02d:%02d.%06lu]|"
"%s|%s:%d:(%s):", local.tm_year+1900, local.tm_mon+1, local.tm_mday,
local.tm_hour, local.tm_min, local.tm_sec, tv.tv_usec,
strlevel[level], file, line, func);
if(len < LOG_MAX_LEN - 1){
va_start(args, fmt);
len += vsnprintf(buffer + len, LOG_MAX_LEN-len, fmt, args);
va_end(args);
len = (len >= LOG_MAX_LEN ? LOG_MAX_LEN - 1 : len);
}else{
len = LOG_MAX_LEN - 1;
}
buffer[len++] = '\n';
len = write(log->fd, buffer, len);
(void)len;
}
int log_loggable(logger_t *log, int level)
{
if(level > log->level || level < 0)
return 0;
return 1;
}
void log_level_set(logger_t *log, int level)
{
log->level = MAX(LOG_LEVEL_ERR, MIN(level, LOG_LEVEL_VERB));
}
void log_reopen(logger_t *log)
{
if(log->fd > 0 && log->fd != STDERR_FILENO){
close(log->fd);
log->fd = open(log->name, O_WRONLY | O_APPEND | O_CREAT, 0644);
if(log->fd < 0) {
log->fd = STDERR_FILENO;
}
}
return;
}
void log_level_up(logger_t *log)
{
if(log->level < LOG_LEVEL_VERB)
log->level++;
}
void log_level_down(logger_t *log)
{
if(log->level > LOG_LEVEL_ERR)
log->level--;
}

View File

@ -1,111 +0,0 @@
/*
* =====================================================================================
*
* Filename: logger.h
*
* Description:
*
* Version: 1.0
* Created: 20130820 200900
* Revision: none
* Compiler: gcc
*
* Author: xiaoboyu,
* Organization:
*
* =====================================================================================
*/
#ifndef __LOGGER_H__
#define __LOGGER_H__
#ifdef __cplusplus
extern "C" {
#endif
enum LogLevelTypes //日志分级
{
LOG_LEVEL_ERR, /* error conditions */
LOG_LEVEL_WARN, /* warning conditions */
LOG_LEVEL_NOTICE,
LOG_LEVEL_INFO,
LOG_LEVEL_DEBUG,
LOG_LEVEL_VERB
};
typedef struct logger_t logger_t;
extern logger_t logger;
#define log_error(fmt, ...) \
do{ \
if(log_loggable(&logger, LOG_LEVEL_ERR)){ \
log_write(&logger, LOG_LEVEL_ERR, __FILE__, __LINE__, __FUNCTION__, \
fmt, ## __VA_ARGS__); \
} \
} while(0)
#define log_warn(fmt, ...) \
do{ \
if(log_loggable(&logger, LOG_LEVEL_WARN)){ \
log_write(&logger, LOG_LEVEL_WARN, __FILE__, __LINE__, __FUNCTION__, \
fmt, ## __VA_ARGS__); \
} \
} while(0)
#define log_notice(fmt, ...) \
do{ \
if(log_loggable(&logger, LOG_LEVEL_NOTICE)){ \
log_write(&logger, LOG_LEVEL_NOTICE, __FILE__, __LINE__, __FUNCTION__, \
fmt, ## __VA_ARGS__); \
} \
} while(0)
#define log_info(fmt, ...) \
do{ \
if(log_loggable(&logger, LOG_LEVEL_INFO)){ \
log_write(&logger, LOG_LEVEL_INFO, __FILE__, __LINE__, __FUNCTION__, \
fmt, ## __VA_ARGS__); \
} \
} while(0)
#define log_debug(fmt, ...) \
do{ \
if(log_loggable(&logger, LOG_LEVEL_DEBUG)){ \
log_write(&logger, LOG_LEVEL_DEBUG, __FILE__, __LINE__, __FUNCTION__, \
fmt, ## __VA_ARGS__); \
} \
} while(0)
#define log_verb(fmt, ...) \
do{ \
if(log_loggable(&logger, LOG_LEVEL_VERB)){ \
log_write(&logger, LOG_LEVEL_VERB, __FILE__, __LINE__, __FUNCTION__, \
fmt, ## __VA_ARGS__); \
} \
} while(0)
void log_init(logger_t *log, const char *name, int level);
void log_deinit(logger_t *log);
/*
* @brief log的级别
*/
void log_level_set(logger_t *log, int level);
void log_reopen(logger_t *log);
void log_level_up(logger_t *log);
void log_level_down(logger_t *log);
int log_loggable(logger_t *log, int level);
void log_write(logger_t *log, int level,
const char *file, int line,
const char* func, const char *fmt, ...)
__attribute__((format(printf, 6, 7)));
#ifdef __cplusplus
}
#endif
#endif // ~LOGGER_H_201106241335

Binary file not shown.

View File

@ -1,84 +0,0 @@
[2015-04-25 16:56:36.580062]|WARN|archive.c:61:(LoadFromFile):not found archive file:data, please confirm SDK is first startup.
[2015-04-25 16:56:36.581785]|INFO|config.c:68:(next_status):set status to eStatus_Redirect
[2015-04-25 16:56:36.612831]|INFO|redirect.c:72:(NebulaRedirect):HTTPS POST. url=https://172.16.82.71/push/redirect, params=uid=1000000010000001&nonce=y9757acx1eve7nmoigsz8fxqqqvjj&ts=1429952196&sign=ee056e8ea53f7f34133acd13e9996db9
[2015-04-25 16:56:36.627771]|INFO|redirect.c:79:(NebulaRedirect):curl_easy_perform success. response={"code":200,"hostlist":[{"ip":"172.16.82.71","port":8080}],"md5_daa":{"rule":"ssh","salt":"helloworld123"}}
[2015-04-25 16:56:36.627834]|INFO|config.c:68:(next_status):set status to eStatus_LoopTest
[2015-04-25 16:56:36.658189]|INFO|config.c:68:(next_status):set status to eStatus_Connect
[2015-04-25 16:56:36.689965]|INFO|connect.c:147:(NebulaConnect):connect to server:172.16.82.71:8080
[2015-04-25 16:56:36.690038]|INFO|config.c:68:(next_status):set status to eStatus_Connecting
[2015-04-25 16:56:36.690781]|INFO|connect.c:27:(__on_connect):connect success, server_addr:172.16.82.71:8080
[2015-04-25 16:56:36.690820]|INFO|config.c:68:(next_status):set status to eStatus_Auth1
[2015-04-25 16:56:36.691082]|DEBUG|connect.c:173:(NebulaSend):NEBULA TX REQ AUTH|0
[2015-04-25 16:56:36.691119]|INFO|config.c:68:(next_status):set status to eStatus_Auth2
[2015-04-25 16:56:51.803531]|WARN|archive.c:61:(LoadFromFile):not found archive file:data, please confirm SDK is first startup.
[2015-04-25 16:56:51.805066]|INFO|config.c:68:(next_status):set status to eStatus_Redirect
[2015-04-25 16:56:51.846343]|INFO|redirect.c:72:(NebulaRedirect):HTTPS POST. url=https://172.16.82.71/push/redirect, params=uid=1000000010000001&nonce=y9757acx1eve7nmoigsz8fxqqqvjj&ts=1429952211&sign=9c3a7e4b592185d7caca49bf5edde4ed
[2015-04-25 16:56:51.883981]|INFO|redirect.c:79:(NebulaRedirect):curl_easy_perform success. response={"code":200,"hostlist":[{"ip":"172.16.82.71","port":8080}],"md5_daa":{"rule":"ssh","salt":"helloworld123"}}
[2015-04-25 16:56:51.884123]|INFO|config.c:68:(next_status):set status to eStatus_LoopTest
[2015-04-25 16:56:51.918477]|INFO|config.c:68:(next_status):set status to eStatus_Connect
[2015-04-25 16:56:51.950683]|INFO|connect.c:147:(NebulaConnect):connect to server:172.16.82.71:8080
[2015-04-25 16:56:51.950752]|INFO|config.c:68:(next_status):set status to eStatus_Connecting
[2015-04-25 16:57:26.466943]|INFO|connect.c:27:(__on_connect):connect success, server_addr:172.16.82.71:8080
[2015-04-25 16:57:26.467027]|INFO|config.c:68:(next_status):set status to eStatus_Auth1
[2015-04-25 16:57:26.467247]|DEBUG|connect.c:173:(NebulaSend):NEBULA TX REQ AUTH|0
[2015-04-25 16:57:26.467282]|INFO|config.c:68:(next_status):set status to eStatus_Auth2
[2015-04-25 16:58:47.906217]|WARN|archive.c:61:(LoadFromFile):not found archive file:data, please confirm SDK is first startup.
[2015-04-25 16:58:47.910534]|INFO|config.c:68:(next_status):set status to eStatus_Redirect
[2015-04-25 16:58:47.946543]|INFO|redirect.c:72:(NebulaRedirect):HTTPS POST. url=https://172.16.82.71/push/redirect, params=uid=1000000010000001&nonce=y9757acx1eve7nmoigsz8fxqqqvjj&ts=1429952327&sign=169862755b312f589844a5a00068758e
[2015-04-25 16:58:47.981548]|INFO|redirect.c:79:(NebulaRedirect):curl_easy_perform success. response={"code":200,"hostlist":[{"ip":"172.16.82.71","port":8080}],"md5_daa":{"rule":"ssh","salt":"helloworld123"}}
[2015-04-25 16:58:47.981695]|INFO|config.c:68:(next_status):set status to eStatus_LoopTest
[2015-04-25 16:58:48.002549]|INFO|config.c:68:(next_status):set status to eStatus_Connect
[2015-04-25 16:58:48.034797]|INFO|connect.c:147:(NebulaConnect):connect to server:172.16.82.71:8080
[2015-04-25 16:58:48.034868]|INFO|config.c:68:(next_status):set status to eStatus_Connecting
[2015-04-25 16:58:50.241148]|INFO|connect.c:27:(__on_connect):connect success, server_addr:172.16.82.71:8080
[2015-04-25 16:58:50.241215]|INFO|config.c:68:(next_status):set status to eStatus_Auth1
[2015-04-25 16:58:50.241412]|DEBUG|connect.c:173:(NebulaSend):NEBULA TX REQ AUTH|0
[2015-04-25 16:58:50.241477]|INFO|config.c:68:(next_status):set status to eStatus_Auth2
[2015-04-25 17:13:02.157390]|WARN|archive.c:61:(LoadFromFile):not found archive file:data, please confirm SDK is first startup.
[2015-04-25 17:13:02.159225]|INFO|config.c:68:(next_status):set status to eStatus_Redirect
[2015-04-25 17:13:02.200990]|INFO|redirect.c:72:(NebulaRedirect):HTTPS POST. url=https://172.16.82.71/push/redirect, params=uid=1000000010000001&nonce=y9757acx1eve7nmoigsz8fxqqqvjj&ts=1429953182&sign=229164191ed48bd6addc3c08a5c2b830
[2015-04-25 17:13:02.237796]|INFO|redirect.c:79:(NebulaRedirect):curl_easy_perform success. response={"code":200,"hostlist":[{"ip":"172.16.82.71","port":8080}],"md5_daa":{"rule":"ssh","salt":"helloworld123"}}
[2015-04-25 17:13:02.237916]|INFO|config.c:68:(next_status):set status to eStatus_LoopTest
[2015-04-25 17:13:02.272535]|INFO|config.c:68:(next_status):set status to eStatus_Connect
[2015-04-25 17:13:02.304833]|INFO|connect.c:148:(NebulaConnect):connect to server:172.16.82.71:8080
[2015-04-25 17:13:02.304906]|INFO|config.c:68:(next_status):set status to eStatus_Connecting
[2015-04-25 17:13:02.305742]|INFO|connect.c:27:(__on_connect):connect success, server_addr:172.16.82.71:8080
[2015-04-25 17:13:02.305792]|INFO|config.c:68:(next_status):set status to eStatus_Auth1
[2015-04-25 17:13:02.305981]|DEBUG|connect.c:174:(NebulaSend):NEBULA TX REQ AUTH|0
[2015-04-25 17:13:02.306013]|INFO|config.c:68:(next_status):set status to eStatus_Auth2
[2015-04-25 17:13:44.769793]|WARN|archive.c:61:(LoadFromFile):not found archive file:data, please confirm SDK is first startup.
[2015-04-25 17:13:44.771566]|INFO|config.c:68:(next_status):set status to eStatus_Redirect
[2015-04-25 17:13:44.798173]|INFO|redirect.c:72:(NebulaRedirect):HTTPS POST. url=https://172.16.82.71/push/redirect, params=uid=1000000010000001&nonce=y9757acx1eve7nmoigsz8fxqqqvjj&ts=1429953224&sign=12a08c8573a1b13cad7ee51a56bacc01
[2015-04-25 17:13:44.812564]|INFO|redirect.c:79:(NebulaRedirect):curl_easy_perform success. response={"code":200,"hostlist":[{"ip":"172.16.82.71","port":8080}],"md5_daa":{"rule":"ssh","salt":"helloworld123"}}
[2015-04-25 17:13:44.812632]|INFO|config.c:68:(next_status):set status to eStatus_LoopTest
[2015-04-25 17:13:44.832927]|INFO|config.c:68:(next_status):set status to eStatus_Connect
[2015-04-30 11:53:58.699321]|WARN|archive.c:74:(LoadFromFile):not found archive file:data, please confirm SDK is first startup.
[2015-04-30 11:53:58.701844]|INFO|nebula_sdk.c:94:(__NebulaStart):set status to eStatus_Redirect
[2015-04-30 11:53:58.724325]|INFO|redirect.c:119:(NebulaRedirect):HTTPS POST. url=https://172.16.82.71/push/redirect, params=uid=1000000010000001&nonce=y9757acx1eve7nmoigsz8fxqqqvjj&ts=1430366038&sign=fd29cab41606e0ebd8a8abd8cf494d47
[2015-04-30 11:53:58.747141]|INFO|redirect.c:126:(NebulaRedirect):curl_easy_perform success. response={"code":200,"hostlist":[{"ip":"172.16.82.71","port":8080}],"md5_daa":{"rule":"ssh","salt":"helloworld123"}}
[2015-04-30 11:53:58.747230]|INFO|nebula_sdk.c:99:(__NebulaStart):set status to eStatus_LoopTest
[2015-04-30 11:53:58.767990]|INFO|nebula_sdk.c:107:(__NebulaStart):set status to eStatus_Connect
[2015-04-30 11:53:58.789117]|INFO|connect.c:159:(NebulaConnect):connect to server:172.16.82.71:8080
[2015-04-30 11:53:58.789144]|INFO|nebula_sdk.c:112:(__NebulaStart):set status to eStatus_Connecting
[2015-04-30 11:53:58.789429]|INFO|connect.c:31:(__on_connect):connect success, server_addr:172.16.82.71:8080
[2015-04-30 11:53:58.789442]|INFO|connect.c:34:(__on_connect):set status to eStatus_Auth1
[2015-04-30 11:53:58.789509]|DEBUG|net.c:143:(NebulaConnSend):NEBULA TX REQ AUTH|64
[2015-04-30 11:53:58.789517]|INFO|nebula_sdk.c:124:(__NebulaStart):set status to eStatus_Auth1_Waiting
[2015-04-30 11:53:58.790345]|DEBUG|connect.c:46:(__handle_message):NEBULA RX RSP AUTH|107
[2015-04-30 11:53:58.790382]|DEBUG|net.c:143:(NebulaConnSend):NEBULA TX REQ AUTH|142
[2015-04-30 11:53:58.790389]|INFO|auth.c:107:(OnAuth):set status to eStatus_Auth2
[2015-04-30 11:53:58.791374]|DEBUG|connect.c:46:(__handle_message):NEBULA RX RSP AUTH|31
[2015-04-30 11:53:58.791443]|INFO|auth.c:44:(OnAuth):set status to eStatus_Sub
[2015-04-30 11:53:58.791486]|DEBUG|net.c:143:(NebulaConnSend):NEBULA TX REQ SUB|45
[2015-04-30 11:53:58.795115]|DEBUG|connect.c:46:(__handle_message):NEBULA RX RSP SUB|77
[2015-04-30 11:53:58.795171]|INFO|subscribe.c:43:(OnSubSuccess):sub com.meizu.cloud success.
[2015-04-30 11:53:58.795188]|INFO|nebula_sdk.c:138:(__NebulaStart):set status to eStatus_Estab
[2015-04-30 11:53:58.983986]|DEBUG|net.c:143:(NebulaConnSend):NEBULA TX REQ PING|0
[2015-04-30 11:53:58.985083]|DEBUG|connect.c:46:(__handle_message):NEBULA RX RSP PING|0
[2015-04-30 11:53:58.985108]|DEBUG|connect.c:49:(__handle_message):pong.

View File

@ -1,67 +0,0 @@
#include "nebula_compress_uncompress_wrapper.h"
#include <snappy-c.h>
#include <zlib.h>
int NebulaCompress(uint8_t type, const char* src, uint32_t src_len,
char *dst, uint32_t *dst_len)
{
int res;
size_t _src_len = (size_t)src_len;
size_t _dst_len = (size_t)*dst_len;
switch(type) {
case 1:
if (Z_OK != compress((uint8_t*)dst, &_dst_len, (uint8_t*)src, _src_len)) {
res = -1;
}else{
res = 0;
*dst_len = (uint32_t)_dst_len;
}
break;
case 2:
if (0 != snappy_compress(src, _src_len, dst, &_dst_len)) {
res = -1;
}else{
res = 0;
*dst_len = (uint32_t)_dst_len;
}
break;
default:
res = -1;
break;
}
return res;
}
int NebulaUnCompress(uint8_t type, const char* src, uint32_t src_len,
char *dst, uint32_t *dst_len)
{
int res;
size_t _src_len = (size_t)src_len;
size_t _dst_len = (size_t)*dst_len;
switch(type) {
case 1:
if (Z_OK != uncompress((uint8_t*)dst, &_dst_len, (uint8_t*)src, _src_len)) {
res = -1;
}else{
res = 0;
*dst_len = (uint32_t)_dst_len;
}
break;
case 2:
if (0 != snappy_uncompress(src, _src_len, dst, &_dst_len)) {
res = -1;
}else{
res = 0;
*dst_len = (uint32_t)_dst_len;
}
break;
default:
res = -1;
break;
}
return res;
}

View File

@ -1,20 +0,0 @@
/******************************************************************************
* FileName: nebula_compress_uncompress_wrapper.h
* Description:
* Version: 1.0
* History:
* yuxiaobo 2015-01-20 1.0 created
*
*****************************************************************************/
#ifndef __NEBULA_COMPRESS_UNCOMPRESS_H__
#define __NEBULA_COMPRESS_UNCOMPRESS_H__
#include <stdint.h>
int NebulaCompress(uint8_t type, const char* src, uint32_t src_len,
char *dst, uint32_t *dst_len);
int NebulaUnCompress(uint8_t type, const char* src, uint32_t src_len,
char *dst, uint32_t *dst_len);
#endif

View File

@ -1,58 +0,0 @@
#include "nebula_encrypt_decrypt_wrapper.h"
#include "crypto_framwork.h"
int NebulaEncrypt(uint8_t type, const char *key, uint32_t key_len,
const char *src, uint32_t src_len,
char *dst, uint32_t* len)
{
int res;
switch (type) {
case 1:
res = CRYPTO_encrypt_without_key((const uint8_t*)src, src_len, (uint8_t*)dst, len);
break;
case 2:
res = CRYPTO1_encrypt((uint8_t*)key, key_len, (const uint8_t*)src,
src_len, (uint8_t*)dst, len);
break;
case 3:
res = CRYPTO2_encrypt((uint8_t*)key, key_len, (const uint8_t*)src,
src_len, (uint8_t*)dst, len);
break;
case 4:
res = CRYPTO3_encrypt((uint8_t*)key, key_len, (const uint8_t*)src,
src_len, (uint8_t*)dst, len);
break;
default:
res = -1;
break;
}
return res;
}
int NebulaDecrypt(uint8_t type, const char *key, uint32_t key_len,
const char *src, uint32_t src_len,
char *dst, uint32_t* len)
{
int res;
switch (type) {
case 1:
res = CRYPTO_decrypt_without_key((const uint8_t*)src, src_len, (uint8_t*)dst, len);
break;
case 2:
res = CRYPTO1_decrypt((uint8_t*)key, key_len, (const uint8_t*)src,
src_len, (uint8_t*)dst, len);
break;
case 3:
res = CRYPTO2_decrypt((uint8_t*)key, key_len, (const uint8_t*)src,
src_len, (uint8_t*)dst, len);
break;
case 4:
res = CRYPTO3_decrypt((uint8_t*)key, key_len, (const uint8_t*)src,
src_len, (uint8_t*)dst, len);
break;
default:
res = -1;
break;
}
return res;
}

View File

@ -1,30 +0,0 @@
/******************************************************************************
* FileName:
* Description:
* Version:
* History:
* yuxiaobo 2014-12-25 1.0 created
*
*****************************************************************************/
#ifndef __NEBULA_ENCRYPT_DECRYPT_WRAPPER_H__
#define __NEBULA_ENCRYPT_DECRYPT_WRAPPER_H__
#include <stdint.h>
/*
*
* @param type
* @param key key
* @param src
* @param dst
* @param len
* @return 0
*/
int NebulaEncrypt(uint8_t type, const char *key, uint32_t key_len,
const char *src, uint32_t src_len,
char *dst, uint32_t* len);
int NebulaDecrypt(uint8_t type, const char *key, uint32_t key_len,
const char *src, uint32_t src_len,
char *dst, uint32_t* len);
#endif

View File

@ -1,168 +0,0 @@
#include "nebula_sdk.h"
#include <sys/file.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "string.h"
#include <pthread.h>
#include <curl/curl.h>
#include <json-c/json.h>
#include <openssl/md5.h>
#include "timer.h"
#include "str.h"
#include "logger.h"
#include "list.h"
#include "config.h"
#include "redirect.h"
#include "auth.h"
#include "subscribe.h"
#include "push.h"
#include "archive.h"
#include <unistd.h>
#include "connect.h"
#include "net.h"
char* g_device_tag = NULL;
char* g_nebula_host = NULL;
NebulaMsgCallback g_nebula_cb[eNebulaMsg_Max] = {};
char* g_storage_file = NULL;
int g_started = 0;
timer_heap_t *g_timer;
List *g_server_list;
int g_sub_app_count = 0;
char** g_sub_apps = NULL;
int NebulaInit(const char* device_tag, const char* host, const char* file)
{
if (!g_timer)
g_timer = timer_heap_create(1024);
if (!g_server_list)
g_server_list = CreateList();
if (!device_tag || !host || !file) return -1;
if (!*device_tag || !*host || !*file) return -1;
g_device_tag = strdup(device_tag);
g_nebula_host = strdup(host);
g_storage_file = strdup(file);
log_init(&logger, "nebula.log", 4);
if (-1 == NebulaInitPush()) {
return -1;
}
if (-1 == NebulaLoadFromFile(g_storage_file)) {
log_warn("load archive file failed...");
return 0;
}
return 0;
}
void NebulaSubScribe(int count, const char** app_name)
{
int i;
if (g_sub_app_count) {
for (i = 0; i < g_sub_app_count; ++i) {
free(g_sub_apps[i]);
}
free(g_sub_apps);
}
g_sub_app_count = count;
g_sub_apps = (char**)malloc(sizeof(char*) * g_sub_app_count);
for (i = 0; i < g_sub_app_count; ++i) {
g_sub_apps[i] = strdup(app_name[i]);
}
}
NebulaMsgCallback NebulaRegister(NebulaMsgType type, NebulaMsgCallback cb)
{
NebulaMsgCallback old = g_nebula_cb[type];
g_nebula_cb[type] = cb;
return old;
}
void* __NebulaStart(void* ptr)
{
(void)ptr;
NebulaInitAutoSave();
for (;;) {
switch (Nebulaget_status()) {
case eStatus_Init:
next_status();
break;
case eStatus_Redirect:
if (0 == NebulaRedirect()) {
next_status();
} else {
log_info("sleep 10 seconds, delay retry redirect.");
sleep(10);
}
break;
case eStatus_LoopTest:
next_status();
break;
case eStatus_Connect:
if (0 == NebulaConnect()) {
next_status();
}
break;
case eStatus_Connecting:
// nothing to do.
break;
case eStatus_Auth1:
if (-1 == NebulaAuth1()) {
jump_status(eStatus_Redirect);
} else {
next_status();
}
break;
case eStatus_Auth1_Waiting:
// nothing to do.
break;
case eStatus_Auth2:
// nothing to do.
break;
case eStatus_Sub:
if (0 == subscribe_loop()) {
next_status();
}
break;
case eStatus_Estab:
// nothing to do. Looping...
break;
}
timer_run(g_timer);
NebulaConnLoop();
}
return NULL;
}
int NebulaStart()
{
if (g_started) return -1;
pthread_t pt;
int ret = pthread_create(&pt, NULL, __NebulaStart, NULL);
if (ret == 0) {
g_started = 1;
return 0;
}
return ret;
}

View File

@ -1,56 +0,0 @@
#ifndef NEBULA_SDK_H
#define NEBULA_SDK_H
typedef enum {
eNebulaMsg_Push, /// 推送 (路由器只需关心这一类消息)
eNebulaMsg_Presence, /// Presence
eNebulaMsg_Sms, /// 网络短信
eNebulaMsg_Mms, /// 网络彩信
eNebulaMsg_Max,
} NebulaMsgType;
#ifdef __cplusplus
extern "C" {
#endif
/** 初始化网络连接
* @device_tag: (IMEI)
* @verify_pwd: (SN)
* @host: , : https://p.meizu.com (结尾不要带"/", 前面要加上https)
* @file: /, ,
* @return: , 0; -1, errno中.
* @, -1.
*/
int NebulaInit(const char* device_tag, const char* host, const char* file);
/** 设置订阅列表
*
*
*/
void NebulaSubScribe(int count, const char** app_name);
/** 消息处理回调函数
* @data:
* @len:
*/
typedef void (*NebulaMsgCallback)(const char* data, int len);
/** 注册消息处理回调函数
* @type:
* @cb:
* @return:
* @, .
*/
NebulaMsgCallback NebulaRegister(NebulaMsgType type, NebulaMsgCallback cb);
/** 启动
*
*/
int NebulaStart();
#ifdef __cplusplus
}
#endif
#endif //NEBULA_SDK_H

View File

@ -1,333 +0,0 @@
#include "net.h"
#include <unistd.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <sys/fcntl.h>
#include <sys/uio.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "logger.h"
#define EPOLL_SIZE 32
int g_epollfd = -1;
struct _NebulaBuf
{
int len;
int pos;
char buf[0];
};
typedef struct _NebulaBuf NebulaBuf;
static int __read(Conn* conn);
static int __write(Conn* conn);
static void __err(Conn* conn);
Conn* NebulaConnCreate()
{
if (g_epollfd == -1) {
g_epollfd = epoll_create(EPOLL_SIZE);
if (g_epollfd == -1) return NULL;
}
Conn* conn = (Conn*)malloc(sizeof(Conn));
memset(conn, 0, sizeof(Conn));
conn->read = __read;
conn->write = __write;
conn->err = __err;
conn->send_list = CreateList();
if (-1 == pthread_mutex_init(&conn->mtx, NULL)) {
free(conn);
return NULL;
}
if (!conn->send_list) {
free(conn);
return NULL;
}
return conn;
}
void NebulaConnInit(Conn* conn, void(*on_connect)(Conn*, int),
void(*on_read)(Conn*, NebulaHeader*), void(*on_disconnect)(Conn*))
{
conn->on_connect = on_connect;
conn->on_read = on_read;
conn->on_disconnect = on_disconnect;
}
int NebulaConnConnect(Conn* conn, const char* host, uint16_t port)
{
if (!conn || !host || !port || !*host) return -1;
if (conn->state == eConnState_Estab || conn->state == eConnState_Connecting)
return -1;
if (conn->host) free(conn->host);
conn->host = strdup(host);
conn->port = port;
if (conn->socketfd >= 0) {
epoll_ctl(g_epollfd, EPOLL_CTL_DEL, conn->socketfd, NULL);
close(conn->socketfd);
conn->socketfd = -1;
}
conn->state = eConnState_Init;
conn->socketfd = socket(AF_INET, SOCK_STREAM, 0);
if (conn->socketfd == -1) return -1;
int flag = fcntl(conn->socketfd, F_GETFL);
if (fcntl(conn->socketfd, F_SETFL, flag | O_NONBLOCK) == -1)
return -1;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(host);
int ret;
retry_connect:
ret = connect(conn->socketfd, (struct sockaddr*)&addr, sizeof(addr));
if (ret == 0) {
// connect completed immediately.
conn->state = eConnState_Estab;
if (conn->on_connect)
conn->on_connect(conn, 0);
struct epoll_event ev = {EPOLLIN, {conn}};
epoll_ctl(g_epollfd, EPOLL_CTL_ADD, conn->socketfd, &ev);
return 0;
} else {
if (errno == EINTR)
goto retry_connect;
if (errno != EINPROGRESS) {
// connect error.
conn->state = eConnState_Error;
close(conn->socketfd);
conn->socketfd = -1;
return -1;
}
// connect not completed immediately, wait from epoll_wait.
struct epoll_event ev = {EPOLLOUT, {conn}};
epoll_ctl(g_epollfd, EPOLL_CTL_ADD, conn->socketfd, &ev);
conn->state = eConnState_Connecting;
}
return 0;
}
int NebulaConnSend(Conn* conn, NebulaHeader *head, ProtobufCMessage *msg)
{
if (!conn || conn->state != eConnState_Estab) return -1;
int len = sizeof(NebulaHeader);
if (msg) {
int msg_len = protobuf_c_message_get_packed_size(msg);
head->len = htons(msg_len);
len += msg_len;
}
NebulaBuf *buf = (NebulaBuf*)malloc(sizeof(NebulaBuf) + len);
buf->len = len;
buf->pos = 0;
memcpy(buf->buf, head, sizeof(NebulaHeader));
if (msg)
protobuf_c_message_pack(msg, (uint8_t*)buf->buf + sizeof(NebulaHeader));
log_debug("NEBULA TX %s|%d", MsgType2Str(head->type), (int)htons(head->len));
pthread_mutex_lock(&conn->mtx);
if (-1 == PushBack(conn->send_list, buf)) {
free(buf);
return -1;
}
pthread_mutex_unlock(&conn->mtx);
struct epoll_event ev = {EPOLLOUT | EPOLLIN, {conn}};
epoll_ctl(g_epollfd, EPOLL_CTL_MOD, conn->socketfd, &ev);
return 0;
}
void NebulaConnLoop()
{
if (g_epollfd == -1) {
g_epollfd = epoll_create(EPOLL_SIZE);
if (g_epollfd == -1) return;
}
int n, i;
struct epoll_event ev[EPOLL_SIZE];
n = epoll_wait(g_epollfd, ev, EPOLL_SIZE, 20);
if (n == -1) return ;
for (i = 0; i < n; i++) {
Conn *c = (Conn*)ev[i].data.ptr;
if (ev[i].events & EPOLLHUP || ev[i].events & EPOLLERR) {
c->err(c);
continue;
}
if (ev[i].events & EPOLLIN) {
if (c->read(c) < 0) {
c->err(c);
continue;
}
}
if (ev[i].events & EPOLLOUT) {
if (c->write(c) < 0) {
c->err(c);
continue;
}
}
}
}
static int __read(Conn* conn)
{
ssize_t n;
retry_read:
n = read(conn->socketfd, conn->recv_buf + conn->recv_pos,
sizeof(conn->recv_buf) - conn->recv_pos);
if (n == -1) {
if (errno == EINTR)
goto retry_read;
if (errno == EAGAIN)
return 0;
return -1;
}
if (n == 0)
return -1;
conn->recv_pos += n;
int pos = 0;
for (;;)
{
if (conn->recv_pos - pos < sizeof(NebulaHeader))
break;
NebulaHeader *head = (NebulaHeader*)(conn->recv_buf + pos);
int pack_len = sizeof(NebulaHeader) + htons(head->len);
if (pack_len > sizeof(conn->recv_buf))
return -1;
if (conn->recv_pos - pos < pack_len)
break;
if (conn->on_read)
conn->on_read(conn, head);
pos += pack_len;
}
if (pos > 0) {
conn->recv_pos -= pos;
memmove(conn->recv_buf + pos, conn->recv_buf, conn->recv_pos);
}
return 0;
}
static int __write(Conn* conn)
{
if (conn->state == eConnState_Connecting) {
// check connect result.
int err = 0;
socklen_t sl = sizeof(int);
int ret = getsockopt(conn->socketfd, SOL_SOCKET, SO_ERROR, &err, &sl);
if (ret == -1 || err != 0) {
// connect failed.
conn->state = eConnState_Error;
epoll_ctl(g_epollfd, EPOLL_CTL_DEL, conn->socketfd, NULL);
close(conn->socketfd);
conn->socketfd = -1;
if (conn->on_connect)
conn->on_connect(conn, (ret == -1 ? errno : err));
return -1;
}
struct epoll_event ev = {EPOLLIN, {conn}};
epoll_ctl(g_epollfd, EPOLL_CTL_MOD, conn->socketfd, &ev);
conn->state = eConnState_Estab;
if (conn->on_connect)
conn->on_connect(conn, 0);
return 0;
}
pthread_mutex_lock(&conn->mtx);
struct iovec iov[UIO_MAXIOV];
ListIterator it = ListBegin(conn->send_list);
int iov_cnt = 0;
for (; it && iov_cnt < UIO_MAXIOV; it = ListNext(it), iov_cnt++)
{
NebulaBuf *buf = *(NebulaBuf **)it;
iov[iov_cnt].iov_len = buf->len - buf->pos;
iov[iov_cnt].iov_base = buf->buf + buf->pos;
}
ssize_t n;
retry_write:
n = writev(conn->socketfd, iov, iov_cnt);
if (n == -1) {
if (errno == EINTR)
goto retry_write;
if (errno == EAGAIN)
return 0;
return -1;
}
if (n == 0)
return -1;
for (;;)
{
NebulaBuf *buf = (NebulaBuf *)Front(conn->send_list);
int len = buf->len - buf->pos;
if (len < n) {
n -= len;
PopFront(conn->send_list);
continue;
} else if (len == n) {
n -= len;
PopFront(conn->send_list);
break;
} else if (len > n) {
buf->pos += n;
n = 0;
break;
}
}
pthread_mutex_unlock(&conn->mtx);
if (conn->send_list->size == 0) {
struct epoll_event ev = {EPOLLIN, {conn}};
epoll_ctl(g_epollfd, EPOLL_CTL_MOD, conn->socketfd, &ev);
}
return 0;
}
static void __err(Conn* conn)
{
conn->state = eConnState_Error;
epoll_ctl(g_epollfd, EPOLL_CTL_DEL, conn->socketfd, NULL);
close(conn->socketfd);
conn->socketfd = -1;
conn->on_disconnect(conn);
}
void NebulaConnNebulaDisconnect(Conn* conn)
{
conn->err(conn);
}

View File

@ -1,52 +0,0 @@
#ifndef NEBULA_NET_H
#define NEBULA_NET_H
// Async TCP connection.
#include <google/protobuf-c/protobuf-c.h>
#include "list.h"
#include <pthread.h>
#include "nebula_proto.h"
enum _ConnState {
eConnState_Init,
eConnState_Connecting,
eConnState_Estab,
eConnState_Error,
};
typedef enum _ConnState ConnState;
typedef struct _Conn Conn;
struct _Conn
{
int socketfd;
char* host;
uint16_t port;
void (*on_connect)(Conn*, int);
void (*on_read)(Conn*, NebulaHeader*);
void (*on_disconnect)(Conn*);
int (*read)(Conn*);
int (*write)(Conn*);
void (*err)(Conn*);
char recv_buf[8192];
int recv_pos;
List* send_list;
pthread_mutex_t mtx;
ConnState state;
};
Conn* NebulaConnCreate();
void NebulaConnInit(Conn* conn, void(*on_connect)(Conn*, int),
void(*on_read)(Conn*, NebulaHeader*),
void(*on_disconnect)(Conn*));
int NebulaConnConnect(Conn* conn, const char* host, uint16_t port);
int NebulaConnSend(Conn* conn, NebulaHeader *head, ProtobufCMessage *msg);
void NebulaConnNebulaDisconnect(Conn* conn);
void NebulaConnLoop();
#endif //NEBULA_NET_H

Binary file not shown.

View File

@ -1,29 +0,0 @@
CC=gcc
CFLAGS=-g -fPIC
OBJS=$(patsubst %.proto,%.o,$(wildcard *.proto))
OBJS+=nebula_proto.o
TARGET=libnebula_proto.a
all: $(TARGET)
$(TARGET):$(OBJS)
@echo "LD $(TARGET)"
@ar -cr $@ $^
%.o:%.proto
@echo "make $@"
@protoc-c $< --c_out=.
@$(CC) $(CFLAGS) -g $(patsubst %.o,%.pb-c.c,$@) -c -o $@
%.o:%.c
@echo "make $@"
@$(CC) $(CFLAGS) -g $< -c -o $@
.PHONY: clean echo
clean:
rm *.o *.a -f
echo:
@echo "TARGET=$(TARGET)"
@echo "OBJS=$(OBJS)"

File diff suppressed because it is too large Load Diff

View File

@ -1,979 +0,0 @@
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
#ifndef PROTOBUF_C_message_2eproto__INCLUDED
#define PROTOBUF_C_message_2eproto__INCLUDED
#include <google/protobuf-c/protobuf-c.h>
PROTOBUF_C_BEGIN_DECLS
typedef struct _Nebula__Param Nebula__Param;
typedef struct _Nebula__AccountUpdateRequest Nebula__AccountUpdateRequest;
typedef struct _Nebula__AccountUpdateResponse Nebula__AccountUpdateResponse;
typedef struct _Nebula__AuthRequest Nebula__AuthRequest;
typedef struct _Nebula__AuthResponse Nebula__AuthResponse;
typedef struct _Nebula__Message Nebula__Message;
typedef struct _Nebula__Message__Content Nebula__Message__Content;
typedef struct _Nebula__MessageSeq Nebula__MessageSeq;
typedef struct _Nebula__MessageSeq__Content Nebula__MessageSeq__Content;
typedef struct _Nebula__MessageKievAck Nebula__MessageKievAck;
typedef struct _Nebula__SubscribeRequest Nebula__SubscribeRequest;
typedef struct _Nebula__SubscribeResponse Nebula__SubscribeResponse;
typedef struct _Nebula__SubscribeResponse__Content Nebula__SubscribeResponse__Content;
typedef struct _Nebula__NotifyBody Nebula__NotifyBody;
typedef struct _Nebula__SmsRequest Nebula__SmsRequest;
typedef struct _Nebula__SmsRequest__FileInfo Nebula__SmsRequest__FileInfo;
typedef struct _Nebula__SmsResponse Nebula__SmsResponse;
typedef struct _Nebula__PresenceNotify Nebula__PresenceNotify;
typedef struct _Nebula__PresenceNotify__Content Nebula__PresenceNotify__Content;
typedef struct _Nebula__PresenceRequest Nebula__PresenceRequest;
typedef struct _Nebula__PresenceResponse Nebula__PresenceResponse;
typedef struct _Nebula__AccountStatusRequest Nebula__AccountStatusRequest;
typedef struct _Nebula__AccountStatusResponse Nebula__AccountStatusResponse;
typedef struct _Nebula__AccountStatusResponse__AccountStatus Nebula__AccountStatusResponse__AccountStatus;
typedef struct _Nebula__Address Nebula__Address;
typedef struct _Nebula__DialogRequest Nebula__DialogRequest;
typedef struct _Nebula__DialogResponse Nebula__DialogResponse;
/* --- enums --- */
typedef enum _Nebula__AuthRequest__Algorithm {
NEBULA__AUTH_REQUEST__ALGORITHM__MD5_MEIZU = 0,
NEBULA__AUTH_REQUEST__ALGORITHM__MD5_DAA = 1,
NEBULA__AUTH_REQUEST__ALGORITHM__MD5_FLYME = 2
} Nebula__AuthRequest__Algorithm;
typedef enum _Nebula__Message__Content__MsgType {
NEBULA__MESSAGE__CONTENT__MSG_TYPE__ePushMessage = 0,
NEBULA__MESSAGE__CONTENT__MSG_TYPE__ePresenceMessage = 1,
NEBULA__MESSAGE__CONTENT__MSG_TYPE__eSmsMessage = 2
} Nebula__Message__Content__MsgType;
typedef enum _Nebula__Message__Flag {
NEBULA__MESSAGE__FLAG__MESSAGE_ACK = 1,
NEBULA__MESSAGE__FLAG__MESSAGE_END = 2
} Nebula__Message__Flag;
typedef enum _Nebula__SmsRequest__SmsType {
NEBULA__SMS_REQUEST__SMS_TYPE__eShortMessage = 0,
NEBULA__SMS_REQUEST__SMS_TYPE__eMultimediaMessage = 1,
NEBULA__SMS_REQUEST__SMS_TYPE__eReportMessage = 2
} Nebula__SmsRequest__SmsType;
typedef enum _Nebula__SmsRequest__ReportType {
NEBULA__SMS_REQUEST__REPORT_TYPE__eSMSReport = 0,
NEBULA__SMS_REQUEST__REPORT_TYPE__eMMSReport = 1
} Nebula__SmsRequest__ReportType;
typedef enum _Nebula__PresenceType {
NEBULA__PRESENCE_TYPE__eIncrementSubscribe = 0,
NEBULA__PRESENCE_TYPE__eFullSubscribe = 1,
NEBULA__PRESENCE_TYPE__eUnSubscribe = 2
} Nebula__PresenceType;
/* --- messages --- */
struct _Nebula__Param
{
ProtobufCMessage base;
char *name;
char *value;
};
#define NEBULA__PARAM__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__param__descriptor) \
, NULL, NULL }
struct _Nebula__AccountUpdateRequest
{
ProtobufCMessage base;
char *flyme_uid;
char *phone;
protobuf_c_boolean has_capability;
int32_t capability;
};
#define NEBULA__ACCOUNT_UPDATE_REQUEST__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__account_update_request__descriptor) \
, NULL, NULL, 0,0 }
struct _Nebula__AccountUpdateResponse
{
ProtobufCMessage base;
int32_t status;
char *flyme_uid;
char *imsi;
char *phone;
protobuf_c_boolean has_capability;
int32_t capability;
};
#define NEBULA__ACCOUNT_UPDATE_RESPONSE__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__account_update_response__descriptor) \
, 0, NULL, NULL, NULL, 0,0 }
struct _Nebula__AuthRequest
{
ProtobufCMessage base;
char *uid;
char *username;
char *nonce;
char *realm;
char *token;
protobuf_c_boolean has_algorithm;
Nebula__AuthRequest__Algorithm algorithm;
size_t n_other_info;
Nebula__Param **other_info;
};
#define NEBULA__AUTH_REQUEST__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__auth_request__descriptor) \
, NULL, NULL, NULL, NULL, NULL, 0,0, 0,NULL }
struct _Nebula__AuthResponse
{
ProtobufCMessage base;
protobuf_c_boolean has_status;
int32_t status;
char *nonce;
char *realm;
};
#define NEBULA__AUTH_RESPONSE__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__auth_response__descriptor) \
, 0,0, NULL, NULL }
struct _Nebula__Message__Content
{
ProtobufCMessage base;
Nebula__Message__Content__MsgType type;
char *account;
uint32_t seq;
protobuf_c_boolean has_body;
ProtobufCBinaryData body;
};
#define NEBULA__MESSAGE__CONTENT__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__message__content__descriptor) \
, 0, NULL, 0, 0,{0,NULL} }
struct _Nebula__Message
{
ProtobufCMessage base;
size_t n_content;
Nebula__Message__Content **content;
protobuf_c_boolean has_flag;
Nebula__Message__Flag flag;
};
#define NEBULA__MESSAGE__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__message__descriptor) \
, 0,NULL, 0,0 }
struct _Nebula__MessageSeq__Content
{
ProtobufCMessage base;
char *account;
uint32_t seq;
};
#define NEBULA__MESSAGE_SEQ__CONTENT__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__message_seq__content__descriptor) \
, NULL, 0 }
struct _Nebula__MessageSeq
{
ProtobufCMessage base;
size_t n_content;
Nebula__MessageSeq__Content **content;
};
#define NEBULA__MESSAGE_SEQ__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__message_seq__descriptor) \
, 0,NULL }
struct _Nebula__MessageKievAck
{
ProtobufCMessage base;
Nebula__MessageSeq *seqs;
uint32_t index;
};
#define NEBULA__MESSAGE_KIEV_ACK__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__message_kiev_ack__descriptor) \
, NULL, 0 }
struct _Nebula__SubscribeRequest
{
ProtobufCMessage base;
size_t n_app;
char **app;
};
#define NEBULA__SUBSCRIBE_REQUEST__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__subscribe_request__descriptor) \
, 0,NULL }
struct _Nebula__SubscribeResponse__Content
{
ProtobufCMessage base;
protobuf_c_boolean has_status;
int32_t status;
char *app;
char *pushid;
};
#define NEBULA__SUBSCRIBE_RESPONSE__CONTENT__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__subscribe_response__content__descriptor) \
, 0,0, NULL, NULL }
struct _Nebula__SubscribeResponse
{
ProtobufCMessage base;
int32_t status;
size_t n_content;
Nebula__SubscribeResponse__Content **content;
};
#define NEBULA__SUBSCRIBE_RESPONSE__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__subscribe_response__descriptor) \
, 0, 0,NULL }
struct _Nebula__NotifyBody
{
ProtobufCMessage base;
char *app;
char *body;
};
#define NEBULA__NOTIFY_BODY__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__notify_body__descriptor) \
, NULL, NULL }
struct _Nebula__SmsRequest__FileInfo
{
ProtobufCMessage base;
char *mimetype;
int32_t size;
char *filename;
char *url;
};
#define NEBULA__SMS_REQUEST__FILE_INFO__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__sms_request__file_info__descriptor) \
, NULL, 0, NULL, NULL }
struct _Nebula__SmsRequest
{
ProtobufCMessage base;
Nebula__SmsRequest__SmsType type;
char *msgid;
char *src;
size_t n_dst;
char **dst;
protobuf_c_boolean has_body;
ProtobufCBinaryData body;
protobuf_c_boolean has_report_flag;
protobuf_c_boolean report_flag;
protobuf_c_boolean has_report_type;
Nebula__SmsRequest__ReportType report_type;
char *report_status;
char *time;
char *expires;
char *pdu;
protobuf_c_boolean has_size;
int32_t size;
char *ver;
size_t n_fileinfos;
Nebula__SmsRequest__FileInfo **fileinfos;
};
#define NEBULA__SMS_REQUEST__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__sms_request__descriptor) \
, 0, NULL, NULL, 0,NULL, 0,{0,NULL}, 0,0, 0,0, NULL, NULL, NULL, NULL, 0,0, NULL, 0,NULL }
struct _Nebula__SmsResponse
{
ProtobufCMessage base;
char *msgid;
int32_t status;
};
#define NEBULA__SMS_RESPONSE__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__sms_response__descriptor) \
, NULL, 0 }
struct _Nebula__PresenceNotify__Content
{
ProtobufCMessage base;
char *account;
protobuf_c_boolean has_capability;
int32_t capability;
protobuf_c_boolean has_status;
int32_t status;
};
#define NEBULA__PRESENCE_NOTIFY__CONTENT__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__presence_notify__content__descriptor) \
, NULL, 0,0, 0,0 }
struct _Nebula__PresenceNotify
{
ProtobufCMessage base;
size_t n_content;
Nebula__PresenceNotify__Content **content;
};
#define NEBULA__PRESENCE_NOTIFY__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__presence_notify__descriptor) \
, 0,NULL }
struct _Nebula__PresenceRequest
{
ProtobufCMessage base;
protobuf_c_boolean has_type;
Nebula__PresenceType type;
protobuf_c_boolean has_sequence;
uint32_t sequence;
size_t n_account;
char **account;
};
#define NEBULA__PRESENCE_REQUEST__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__presence_request__descriptor) \
, 0,0, 0,0, 0,NULL }
struct _Nebula__PresenceResponse
{
ProtobufCMessage base;
int32_t status;
protobuf_c_boolean has_type;
Nebula__PresenceType type;
protobuf_c_boolean has_sequence;
uint32_t sequence;
size_t n_account;
char **account;
};
#define NEBULA__PRESENCE_RESPONSE__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__presence_response__descriptor) \
, 0, 0,0, 0,0, 0,NULL }
struct _Nebula__AccountStatusRequest
{
ProtobufCMessage base;
size_t n_account;
char **account;
};
#define NEBULA__ACCOUNT_STATUS_REQUEST__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__account_status_request__descriptor) \
, 0,NULL }
struct _Nebula__AccountStatusResponse__AccountStatus
{
ProtobufCMessage base;
char *account;
protobuf_c_boolean has_status;
int32_t status;
protobuf_c_boolean has_capability;
int32_t capability;
};
#define NEBULA__ACCOUNT_STATUS_RESPONSE__ACCOUNT_STATUS__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__account_status_response__account_status__descriptor) \
, NULL, 0,0, 0,0 }
struct _Nebula__AccountStatusResponse
{
ProtobufCMessage base;
int32_t status;
size_t n_result;
Nebula__AccountStatusResponse__AccountStatus **result;
};
#define NEBULA__ACCOUNT_STATUS_RESPONSE__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__account_status_response__descriptor) \
, 0, 0,NULL }
struct _Nebula__Address
{
ProtobufCMessage base;
char *host;
int32_t port;
};
#define NEBULA__ADDRESS__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__address__descriptor) \
, NULL, 0 }
struct _Nebula__DialogRequest
{
ProtobufCMessage base;
char *src;
char *dst;
Nebula__Address *dialog;
protobuf_c_boolean has_body;
ProtobufCBinaryData body;
};
#define NEBULA__DIALOG_REQUEST__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__dialog_request__descriptor) \
, NULL, NULL, NULL, 0,{0,NULL} }
struct _Nebula__DialogResponse
{
ProtobufCMessage base;
int32_t status;
char *src;
char *dst;
Nebula__Address *dialog;
protobuf_c_boolean has_body;
ProtobufCBinaryData body;
};
#define NEBULA__DIALOG_RESPONSE__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__dialog_response__descriptor) \
, 0, NULL, NULL, NULL, 0,{0,NULL} }
/* Nebula__Param methods */
void nebula__param__init
(Nebula__Param *message);
size_t nebula__param__get_packed_size
(const Nebula__Param *message);
size_t nebula__param__pack
(const Nebula__Param *message,
uint8_t *out);
size_t nebula__param__pack_to_buffer
(const Nebula__Param *message,
ProtobufCBuffer *buffer);
Nebula__Param *
nebula__param__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__param__free_unpacked
(Nebula__Param *message,
ProtobufCAllocator *allocator);
/* Nebula__AccountUpdateRequest methods */
void nebula__account_update_request__init
(Nebula__AccountUpdateRequest *message);
size_t nebula__account_update_request__get_packed_size
(const Nebula__AccountUpdateRequest *message);
size_t nebula__account_update_request__pack
(const Nebula__AccountUpdateRequest *message,
uint8_t *out);
size_t nebula__account_update_request__pack_to_buffer
(const Nebula__AccountUpdateRequest *message,
ProtobufCBuffer *buffer);
Nebula__AccountUpdateRequest *
nebula__account_update_request__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__account_update_request__free_unpacked
(Nebula__AccountUpdateRequest *message,
ProtobufCAllocator *allocator);
/* Nebula__AccountUpdateResponse methods */
void nebula__account_update_response__init
(Nebula__AccountUpdateResponse *message);
size_t nebula__account_update_response__get_packed_size
(const Nebula__AccountUpdateResponse *message);
size_t nebula__account_update_response__pack
(const Nebula__AccountUpdateResponse *message,
uint8_t *out);
size_t nebula__account_update_response__pack_to_buffer
(const Nebula__AccountUpdateResponse *message,
ProtobufCBuffer *buffer);
Nebula__AccountUpdateResponse *
nebula__account_update_response__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__account_update_response__free_unpacked
(Nebula__AccountUpdateResponse *message,
ProtobufCAllocator *allocator);
/* Nebula__AuthRequest methods */
void nebula__auth_request__init
(Nebula__AuthRequest *message);
size_t nebula__auth_request__get_packed_size
(const Nebula__AuthRequest *message);
size_t nebula__auth_request__pack
(const Nebula__AuthRequest *message,
uint8_t *out);
size_t nebula__auth_request__pack_to_buffer
(const Nebula__AuthRequest *message,
ProtobufCBuffer *buffer);
Nebula__AuthRequest *
nebula__auth_request__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__auth_request__free_unpacked
(Nebula__AuthRequest *message,
ProtobufCAllocator *allocator);
/* Nebula__AuthResponse methods */
void nebula__auth_response__init
(Nebula__AuthResponse *message);
size_t nebula__auth_response__get_packed_size
(const Nebula__AuthResponse *message);
size_t nebula__auth_response__pack
(const Nebula__AuthResponse *message,
uint8_t *out);
size_t nebula__auth_response__pack_to_buffer
(const Nebula__AuthResponse *message,
ProtobufCBuffer *buffer);
Nebula__AuthResponse *
nebula__auth_response__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__auth_response__free_unpacked
(Nebula__AuthResponse *message,
ProtobufCAllocator *allocator);
/* Nebula__Message__Content methods */
void nebula__message__content__init
(Nebula__Message__Content *message);
/* Nebula__Message methods */
void nebula__message__init
(Nebula__Message *message);
size_t nebula__message__get_packed_size
(const Nebula__Message *message);
size_t nebula__message__pack
(const Nebula__Message *message,
uint8_t *out);
size_t nebula__message__pack_to_buffer
(const Nebula__Message *message,
ProtobufCBuffer *buffer);
Nebula__Message *
nebula__message__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__message__free_unpacked
(Nebula__Message *message,
ProtobufCAllocator *allocator);
/* Nebula__MessageSeq__Content methods */
void nebula__message_seq__content__init
(Nebula__MessageSeq__Content *message);
/* Nebula__MessageSeq methods */
void nebula__message_seq__init
(Nebula__MessageSeq *message);
size_t nebula__message_seq__get_packed_size
(const Nebula__MessageSeq *message);
size_t nebula__message_seq__pack
(const Nebula__MessageSeq *message,
uint8_t *out);
size_t nebula__message_seq__pack_to_buffer
(const Nebula__MessageSeq *message,
ProtobufCBuffer *buffer);
Nebula__MessageSeq *
nebula__message_seq__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__message_seq__free_unpacked
(Nebula__MessageSeq *message,
ProtobufCAllocator *allocator);
/* Nebula__MessageKievAck methods */
void nebula__message_kiev_ack__init
(Nebula__MessageKievAck *message);
size_t nebula__message_kiev_ack__get_packed_size
(const Nebula__MessageKievAck *message);
size_t nebula__message_kiev_ack__pack
(const Nebula__MessageKievAck *message,
uint8_t *out);
size_t nebula__message_kiev_ack__pack_to_buffer
(const Nebula__MessageKievAck *message,
ProtobufCBuffer *buffer);
Nebula__MessageKievAck *
nebula__message_kiev_ack__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__message_kiev_ack__free_unpacked
(Nebula__MessageKievAck *message,
ProtobufCAllocator *allocator);
/* Nebula__SubscribeRequest methods */
void nebula__subscribe_request__init
(Nebula__SubscribeRequest *message);
size_t nebula__subscribe_request__get_packed_size
(const Nebula__SubscribeRequest *message);
size_t nebula__subscribe_request__pack
(const Nebula__SubscribeRequest *message,
uint8_t *out);
size_t nebula__subscribe_request__pack_to_buffer
(const Nebula__SubscribeRequest *message,
ProtobufCBuffer *buffer);
Nebula__SubscribeRequest *
nebula__subscribe_request__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__subscribe_request__free_unpacked
(Nebula__SubscribeRequest *message,
ProtobufCAllocator *allocator);
/* Nebula__SubscribeResponse__Content methods */
void nebula__subscribe_response__content__init
(Nebula__SubscribeResponse__Content *message);
/* Nebula__SubscribeResponse methods */
void nebula__subscribe_response__init
(Nebula__SubscribeResponse *message);
size_t nebula__subscribe_response__get_packed_size
(const Nebula__SubscribeResponse *message);
size_t nebula__subscribe_response__pack
(const Nebula__SubscribeResponse *message,
uint8_t *out);
size_t nebula__subscribe_response__pack_to_buffer
(const Nebula__SubscribeResponse *message,
ProtobufCBuffer *buffer);
Nebula__SubscribeResponse *
nebula__subscribe_response__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__subscribe_response__free_unpacked
(Nebula__SubscribeResponse *message,
ProtobufCAllocator *allocator);
/* Nebula__NotifyBody methods */
void nebula__notify_body__init
(Nebula__NotifyBody *message);
size_t nebula__notify_body__get_packed_size
(const Nebula__NotifyBody *message);
size_t nebula__notify_body__pack
(const Nebula__NotifyBody *message,
uint8_t *out);
size_t nebula__notify_body__pack_to_buffer
(const Nebula__NotifyBody *message,
ProtobufCBuffer *buffer);
Nebula__NotifyBody *
nebula__notify_body__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__notify_body__free_unpacked
(Nebula__NotifyBody *message,
ProtobufCAllocator *allocator);
/* Nebula__SmsRequest__FileInfo methods */
void nebula__sms_request__file_info__init
(Nebula__SmsRequest__FileInfo *message);
/* Nebula__SmsRequest methods */
void nebula__sms_request__init
(Nebula__SmsRequest *message);
size_t nebula__sms_request__get_packed_size
(const Nebula__SmsRequest *message);
size_t nebula__sms_request__pack
(const Nebula__SmsRequest *message,
uint8_t *out);
size_t nebula__sms_request__pack_to_buffer
(const Nebula__SmsRequest *message,
ProtobufCBuffer *buffer);
Nebula__SmsRequest *
nebula__sms_request__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__sms_request__free_unpacked
(Nebula__SmsRequest *message,
ProtobufCAllocator *allocator);
/* Nebula__SmsResponse methods */
void nebula__sms_response__init
(Nebula__SmsResponse *message);
size_t nebula__sms_response__get_packed_size
(const Nebula__SmsResponse *message);
size_t nebula__sms_response__pack
(const Nebula__SmsResponse *message,
uint8_t *out);
size_t nebula__sms_response__pack_to_buffer
(const Nebula__SmsResponse *message,
ProtobufCBuffer *buffer);
Nebula__SmsResponse *
nebula__sms_response__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__sms_response__free_unpacked
(Nebula__SmsResponse *message,
ProtobufCAllocator *allocator);
/* Nebula__PresenceNotify__Content methods */
void nebula__presence_notify__content__init
(Nebula__PresenceNotify__Content *message);
/* Nebula__PresenceNotify methods */
void nebula__presence_notify__init
(Nebula__PresenceNotify *message);
size_t nebula__presence_notify__get_packed_size
(const Nebula__PresenceNotify *message);
size_t nebula__presence_notify__pack
(const Nebula__PresenceNotify *message,
uint8_t *out);
size_t nebula__presence_notify__pack_to_buffer
(const Nebula__PresenceNotify *message,
ProtobufCBuffer *buffer);
Nebula__PresenceNotify *
nebula__presence_notify__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__presence_notify__free_unpacked
(Nebula__PresenceNotify *message,
ProtobufCAllocator *allocator);
/* Nebula__PresenceRequest methods */
void nebula__presence_request__init
(Nebula__PresenceRequest *message);
size_t nebula__presence_request__get_packed_size
(const Nebula__PresenceRequest *message);
size_t nebula__presence_request__pack
(const Nebula__PresenceRequest *message,
uint8_t *out);
size_t nebula__presence_request__pack_to_buffer
(const Nebula__PresenceRequest *message,
ProtobufCBuffer *buffer);
Nebula__PresenceRequest *
nebula__presence_request__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__presence_request__free_unpacked
(Nebula__PresenceRequest *message,
ProtobufCAllocator *allocator);
/* Nebula__PresenceResponse methods */
void nebula__presence_response__init
(Nebula__PresenceResponse *message);
size_t nebula__presence_response__get_packed_size
(const Nebula__PresenceResponse *message);
size_t nebula__presence_response__pack
(const Nebula__PresenceResponse *message,
uint8_t *out);
size_t nebula__presence_response__pack_to_buffer
(const Nebula__PresenceResponse *message,
ProtobufCBuffer *buffer);
Nebula__PresenceResponse *
nebula__presence_response__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__presence_response__free_unpacked
(Nebula__PresenceResponse *message,
ProtobufCAllocator *allocator);
/* Nebula__AccountStatusRequest methods */
void nebula__account_status_request__init
(Nebula__AccountStatusRequest *message);
size_t nebula__account_status_request__get_packed_size
(const Nebula__AccountStatusRequest *message);
size_t nebula__account_status_request__pack
(const Nebula__AccountStatusRequest *message,
uint8_t *out);
size_t nebula__account_status_request__pack_to_buffer
(const Nebula__AccountStatusRequest *message,
ProtobufCBuffer *buffer);
Nebula__AccountStatusRequest *
nebula__account_status_request__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__account_status_request__free_unpacked
(Nebula__AccountStatusRequest *message,
ProtobufCAllocator *allocator);
/* Nebula__AccountStatusResponse__AccountStatus methods */
void nebula__account_status_response__account_status__init
(Nebula__AccountStatusResponse__AccountStatus *message);
/* Nebula__AccountStatusResponse methods */
void nebula__account_status_response__init
(Nebula__AccountStatusResponse *message);
size_t nebula__account_status_response__get_packed_size
(const Nebula__AccountStatusResponse *message);
size_t nebula__account_status_response__pack
(const Nebula__AccountStatusResponse *message,
uint8_t *out);
size_t nebula__account_status_response__pack_to_buffer
(const Nebula__AccountStatusResponse *message,
ProtobufCBuffer *buffer);
Nebula__AccountStatusResponse *
nebula__account_status_response__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__account_status_response__free_unpacked
(Nebula__AccountStatusResponse *message,
ProtobufCAllocator *allocator);
/* Nebula__Address methods */
void nebula__address__init
(Nebula__Address *message);
size_t nebula__address__get_packed_size
(const Nebula__Address *message);
size_t nebula__address__pack
(const Nebula__Address *message,
uint8_t *out);
size_t nebula__address__pack_to_buffer
(const Nebula__Address *message,
ProtobufCBuffer *buffer);
Nebula__Address *
nebula__address__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__address__free_unpacked
(Nebula__Address *message,
ProtobufCAllocator *allocator);
/* Nebula__DialogRequest methods */
void nebula__dialog_request__init
(Nebula__DialogRequest *message);
size_t nebula__dialog_request__get_packed_size
(const Nebula__DialogRequest *message);
size_t nebula__dialog_request__pack
(const Nebula__DialogRequest *message,
uint8_t *out);
size_t nebula__dialog_request__pack_to_buffer
(const Nebula__DialogRequest *message,
ProtobufCBuffer *buffer);
Nebula__DialogRequest *
nebula__dialog_request__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__dialog_request__free_unpacked
(Nebula__DialogRequest *message,
ProtobufCAllocator *allocator);
/* Nebula__DialogResponse methods */
void nebula__dialog_response__init
(Nebula__DialogResponse *message);
size_t nebula__dialog_response__get_packed_size
(const Nebula__DialogResponse *message);
size_t nebula__dialog_response__pack
(const Nebula__DialogResponse *message,
uint8_t *out);
size_t nebula__dialog_response__pack_to_buffer
(const Nebula__DialogResponse *message,
ProtobufCBuffer *buffer);
Nebula__DialogResponse *
nebula__dialog_response__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__dialog_response__free_unpacked
(Nebula__DialogResponse *message,
ProtobufCAllocator *allocator);
/* --- per-message closures --- */
typedef void (*Nebula__Param_Closure)
(const Nebula__Param *message,
void *closure_data);
typedef void (*Nebula__AccountUpdateRequest_Closure)
(const Nebula__AccountUpdateRequest *message,
void *closure_data);
typedef void (*Nebula__AccountUpdateResponse_Closure)
(const Nebula__AccountUpdateResponse *message,
void *closure_data);
typedef void (*Nebula__AuthRequest_Closure)
(const Nebula__AuthRequest *message,
void *closure_data);
typedef void (*Nebula__AuthResponse_Closure)
(const Nebula__AuthResponse *message,
void *closure_data);
typedef void (*Nebula__Message__Content_Closure)
(const Nebula__Message__Content *message,
void *closure_data);
typedef void (*Nebula__Message_Closure)
(const Nebula__Message *message,
void *closure_data);
typedef void (*Nebula__MessageSeq__Content_Closure)
(const Nebula__MessageSeq__Content *message,
void *closure_data);
typedef void (*Nebula__MessageSeq_Closure)
(const Nebula__MessageSeq *message,
void *closure_data);
typedef void (*Nebula__MessageKievAck_Closure)
(const Nebula__MessageKievAck *message,
void *closure_data);
typedef void (*Nebula__SubscribeRequest_Closure)
(const Nebula__SubscribeRequest *message,
void *closure_data);
typedef void (*Nebula__SubscribeResponse__Content_Closure)
(const Nebula__SubscribeResponse__Content *message,
void *closure_data);
typedef void (*Nebula__SubscribeResponse_Closure)
(const Nebula__SubscribeResponse *message,
void *closure_data);
typedef void (*Nebula__NotifyBody_Closure)
(const Nebula__NotifyBody *message,
void *closure_data);
typedef void (*Nebula__SmsRequest__FileInfo_Closure)
(const Nebula__SmsRequest__FileInfo *message,
void *closure_data);
typedef void (*Nebula__SmsRequest_Closure)
(const Nebula__SmsRequest *message,
void *closure_data);
typedef void (*Nebula__SmsResponse_Closure)
(const Nebula__SmsResponse *message,
void *closure_data);
typedef void (*Nebula__PresenceNotify__Content_Closure)
(const Nebula__PresenceNotify__Content *message,
void *closure_data);
typedef void (*Nebula__PresenceNotify_Closure)
(const Nebula__PresenceNotify *message,
void *closure_data);
typedef void (*Nebula__PresenceRequest_Closure)
(const Nebula__PresenceRequest *message,
void *closure_data);
typedef void (*Nebula__PresenceResponse_Closure)
(const Nebula__PresenceResponse *message,
void *closure_data);
typedef void (*Nebula__AccountStatusRequest_Closure)
(const Nebula__AccountStatusRequest *message,
void *closure_data);
typedef void (*Nebula__AccountStatusResponse__AccountStatus_Closure)
(const Nebula__AccountStatusResponse__AccountStatus *message,
void *closure_data);
typedef void (*Nebula__AccountStatusResponse_Closure)
(const Nebula__AccountStatusResponse *message,
void *closure_data);
typedef void (*Nebula__Address_Closure)
(const Nebula__Address *message,
void *closure_data);
typedef void (*Nebula__DialogRequest_Closure)
(const Nebula__DialogRequest *message,
void *closure_data);
typedef void (*Nebula__DialogResponse_Closure)
(const Nebula__DialogResponse *message,
void *closure_data);
/* --- services --- */
/* --- descriptors --- */
extern const ProtobufCEnumDescriptor nebula__presence_type__descriptor;
extern const ProtobufCMessageDescriptor nebula__param__descriptor;
extern const ProtobufCMessageDescriptor nebula__account_update_request__descriptor;
extern const ProtobufCMessageDescriptor nebula__account_update_response__descriptor;
extern const ProtobufCMessageDescriptor nebula__auth_request__descriptor;
extern const ProtobufCEnumDescriptor nebula__auth_request__algorithm__descriptor;
extern const ProtobufCMessageDescriptor nebula__auth_response__descriptor;
extern const ProtobufCMessageDescriptor nebula__message__descriptor;
extern const ProtobufCMessageDescriptor nebula__message__content__descriptor;
extern const ProtobufCEnumDescriptor nebula__message__content__msg_type__descriptor;
extern const ProtobufCEnumDescriptor nebula__message__flag__descriptor;
extern const ProtobufCMessageDescriptor nebula__message_seq__descriptor;
extern const ProtobufCMessageDescriptor nebula__message_seq__content__descriptor;
extern const ProtobufCMessageDescriptor nebula__message_kiev_ack__descriptor;
extern const ProtobufCMessageDescriptor nebula__subscribe_request__descriptor;
extern const ProtobufCMessageDescriptor nebula__subscribe_response__descriptor;
extern const ProtobufCMessageDescriptor nebula__subscribe_response__content__descriptor;
extern const ProtobufCMessageDescriptor nebula__notify_body__descriptor;
extern const ProtobufCMessageDescriptor nebula__sms_request__descriptor;
extern const ProtobufCMessageDescriptor nebula__sms_request__file_info__descriptor;
extern const ProtobufCEnumDescriptor nebula__sms_request__sms_type__descriptor;
extern const ProtobufCEnumDescriptor nebula__sms_request__report_type__descriptor;
extern const ProtobufCMessageDescriptor nebula__sms_response__descriptor;
extern const ProtobufCMessageDescriptor nebula__presence_notify__descriptor;
extern const ProtobufCMessageDescriptor nebula__presence_notify__content__descriptor;
extern const ProtobufCMessageDescriptor nebula__presence_request__descriptor;
extern const ProtobufCMessageDescriptor nebula__presence_response__descriptor;
extern const ProtobufCMessageDescriptor nebula__account_status_request__descriptor;
extern const ProtobufCMessageDescriptor nebula__account_status_response__descriptor;
extern const ProtobufCMessageDescriptor nebula__account_status_response__account_status__descriptor;
extern const ProtobufCMessageDescriptor nebula__address__descriptor;
extern const ProtobufCMessageDescriptor nebula__dialog_request__descriptor;
extern const ProtobufCMessageDescriptor nebula__dialog_response__descriptor;
PROTOBUF_C_END_DECLS
#endif /* PROTOBUF_message_2eproto__INCLUDED */

View File

@ -1,248 +0,0 @@
package Nebula;
option java_package = "com.meizu.push.proto";
option java_outer_classname = "ProtoMessages";
message Param
{
optional string name = 1;
optional string value = 2;
};
message AccountUpdateRequest
{
optional string flyme_uid = 1;
optional string phone = 2;
optional int32 capability = 3; //
};
message AccountUpdateResponse
{
//200 OK
//4XX
//5XX
required int32 status = 1; // 200 OK
optional string flyme_uid = 2; //flyme_uid
optional string imsi = 3; //imsi
optional string phone = 4; //
optional int32 capability = 5; //
};
//
message AuthRequest
{
enum Algorithm
{
MD5_MEIZU = 0;
MD5_DAA = 1;
MD5_FLYME = 2;
};
required string uid = 1; //
optional string username = 2; //使
optional string nonce = 3; //使
optional string realm = 4; //使
optional string token = 5; //使
optional Algorithm algorithm = 6; //使
repeated Param other_info = 7; // OS版本等
};
//
message AuthResponse
{
optional int32 status = 1;
optional string nonce = 2;
optional string realm = 3;
};
//
message Message
{
message Content
{
enum MsgType
{
ePushMessage = 0; //push消息
ePresenceMessage = 1; //presence消息
eSmsMessage = 2; //
};
required MsgType type = 1; //
required string account = 2;
required uint32 seq = 3; //
optional bytes body = 4; // 使protobuf编码
};
enum Flag
{
MESSAGE_ACK = 1;
MESSAGE_END = 2;
};
repeated Content content = 1;
optional Flag flag = 2;
}
//ACK SYNC FIN 3
message MessageSeq
{
message Content
{
required string account = 1;
required uint32 seq = 2;
};
repeated Content content = 1; //
};
message MessageKievAck
{
required MessageSeq seqs = 1;
required uint32 index = 2;
};
//
message SubscribeRequest
{
repeated string app = 1; //app
};
//
message SubscribeResponse
{
message Content {
optional int32 status = 1; // 200 ok
optional string app = 2; //app
optional string pushid = 3; //pushid
};
required int32 status = 1; //
repeated Content content = 2; //
};
////////////////MessageSend的body定义/////////////////////
message NotifyBody
{
optional string app = 1;
optional string body = 2;
};
//
message SmsRequest
{
enum SmsType
{
eShortMessage = 0;
eMultimediaMessage = 1;
eReportMessage = 2;
};
message FileInfo
{
required string mimetype = 1;
required int32 size = 2;
optional string filename = 3;
optional string url = 4;
};
enum ReportType
{
eSMSReport = 0;
eMMSReport = 1;
};
required SmsType type = 1; //
required string msgid = 2; //ID
required string src = 3;
repeated string dst = 4; //
optional bytes body = 5;
optional bool report_flag = 6; //sms或者mms消息使用 report标志
optional ReportType report_type = 7;
optional string report_status = 8; //report消息使用
optional string time = 9;
optional string expires = 10;
optional string pdu = 11;
optional int32 size = 12;
optional string ver = 13;
repeated FileInfo fileinfos = 14;
};
//Message应答消息的内容
message SmsResponse
{
required string msgid = 1;
required int32 status = 2;
};
//presence推送内容格式
message PresenceNotify
{
message Content
{
optional string account = 1;
optional int32 capability = 2;
optional int32 status = 3; //线
};
repeated Content content = 1;
};
/////////////////////////MessageSend body end///////////////////////////
enum PresenceType
{
eIncrementSubscribe = 0; //
eFullSubscribe = 1; //
eUnSubscribe = 2; //
};
//presence订阅或取消订阅格式
message PresenceRequest
{
optional PresenceType type = 1;
optional uint32 sequence = 2;
repeated string account = 3;
};
message PresenceResponse
{
required int32 status = 1;
optional PresenceType type = 2;
optional uint32 sequence = 3;
repeated string account = 4; // Return the legal account
};
//线
message AccountStatusRequest
{
repeated string account = 1;
};
message AccountStatusResponse
{
message AccountStatus
{
optional string account = 1;
optional int32 status = 2; //线
optional int32 capability = 3; //
};
required int32 status = 1;
repeated AccountStatus result = 2;
};
/////////////////////////////////////////////
message Address
{
required string host = 1;
required int32 port = 2;
};
message DialogRequest
{
required string src = 1;
required string dst = 2;
optional Address dialog = 3; //dialog服务器地址
optional bytes body = 4;
};
message DialogResponse
{
required int32 status = 1;
required string src = 2;
required string dst = 3;
optional Address dialog = 4; //dialog服务器地址
optional bytes body = 5;
};

View File

@ -1,102 +0,0 @@
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
/* Do not generate deprecated warnings for self */
#ifndef PROTOBUF_C_NO_DEPRECATED
#define PROTOBUF_C_NO_DEPRECATED
#endif
#include "nebula.pb-c.h"
void nebula__nebula_msg__init
(Nebula__NebulaMsg *message)
{
static Nebula__NebulaMsg init_value = NEBULA__NEBULA_MSG__INIT;
*message = init_value;
}
size_t nebula__nebula_msg__get_packed_size
(const Nebula__NebulaMsg *message)
{
PROTOBUF_C_ASSERT (message->base.descriptor == &nebula__nebula_msg__descriptor);
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
}
size_t nebula__nebula_msg__pack
(const Nebula__NebulaMsg *message,
uint8_t *out)
{
PROTOBUF_C_ASSERT (message->base.descriptor == &nebula__nebula_msg__descriptor);
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
}
size_t nebula__nebula_msg__pack_to_buffer
(const Nebula__NebulaMsg *message,
ProtobufCBuffer *buffer)
{
PROTOBUF_C_ASSERT (message->base.descriptor == &nebula__nebula_msg__descriptor);
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
}
Nebula__NebulaMsg *
nebula__nebula_msg__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data)
{
return (Nebula__NebulaMsg *)
protobuf_c_message_unpack (&nebula__nebula_msg__descriptor,
allocator, len, data);
}
void nebula__nebula_msg__free_unpacked
(Nebula__NebulaMsg *message,
ProtobufCAllocator *allocator)
{
PROTOBUF_C_ASSERT (message->base.descriptor == &nebula__nebula_msg__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
static const ProtobufCFieldDescriptor nebula__nebula_msg__field_descriptors[2] =
{
{
"msgid",
1,
PROTOBUF_C_LABEL_REQUIRED,
PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
PROTOBUF_C_OFFSETOF(Nebula__NebulaMsg, msgid),
NULL,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"body",
2,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_BYTES,
PROTOBUF_C_OFFSETOF(Nebula__NebulaMsg, has_body),
PROTOBUF_C_OFFSETOF(Nebula__NebulaMsg, body),
NULL,
NULL,
0, /* packed */
0,NULL,NULL /* reserved1,reserved2, etc */
},
};
static const unsigned nebula__nebula_msg__field_indices_by_name[] = {
1, /* field[1] = body */
0, /* field[0] = msgid */
};
static const ProtobufCIntRange nebula__nebula_msg__number_ranges[1 + 1] =
{
{ 1, 0 },
{ 0, 2 }
};
const ProtobufCMessageDescriptor nebula__nebula_msg__descriptor =
{
PROTOBUF_C_MESSAGE_DESCRIPTOR_MAGIC,
"Nebula.NebulaMsg",
"NebulaMsg",
"Nebula__NebulaMsg",
"Nebula",
sizeof(Nebula__NebulaMsg),
2,
nebula__nebula_msg__field_descriptors,
nebula__nebula_msg__field_indices_by_name,
1, nebula__nebula_msg__number_ranges,
(ProtobufCMessageInit) nebula__nebula_msg__init,
NULL,NULL,NULL /* reserved[123] */
};

View File

@ -1,66 +0,0 @@
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
#ifndef PROTOBUF_C_nebula_2eproto__INCLUDED
#define PROTOBUF_C_nebula_2eproto__INCLUDED
#include <google/protobuf-c/protobuf-c.h>
PROTOBUF_C_BEGIN_DECLS
typedef struct _Nebula__NebulaMsg Nebula__NebulaMsg;
/* --- enums --- */
/* --- messages --- */
struct _Nebula__NebulaMsg
{
ProtobufCMessage base;
char *msgid;
protobuf_c_boolean has_body;
ProtobufCBinaryData body;
};
#define NEBULA__NEBULA_MSG__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nebula__nebula_msg__descriptor) \
, NULL, 0,{0,NULL} }
/* Nebula__NebulaMsg methods */
void nebula__nebula_msg__init
(Nebula__NebulaMsg *message);
size_t nebula__nebula_msg__get_packed_size
(const Nebula__NebulaMsg *message);
size_t nebula__nebula_msg__pack
(const Nebula__NebulaMsg *message,
uint8_t *out);
size_t nebula__nebula_msg__pack_to_buffer
(const Nebula__NebulaMsg *message,
ProtobufCBuffer *buffer);
Nebula__NebulaMsg *
nebula__nebula_msg__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void nebula__nebula_msg__free_unpacked
(Nebula__NebulaMsg *message,
ProtobufCAllocator *allocator);
/* --- per-message closures --- */
typedef void (*Nebula__NebulaMsg_Closure)
(const Nebula__NebulaMsg *message,
void *closure_data);
/* --- services --- */
/* --- descriptors --- */
extern const ProtobufCMessageDescriptor nebula__nebula_msg__descriptor;
PROTOBUF_C_END_DECLS
#endif /* PROTOBUF_nebula_2eproto__INCLUDED */

View File

@ -1,9 +0,0 @@
package Nebula;
option java_package = "com.meizu.push.proto";
message NebulaMsg
{
required string msgid = 1; //id不加密不压缩
optional bytes body = 2; //()
};

View File

@ -1,112 +0,0 @@
#include "nebula_proto.h"
#include <time.h>
#include <stdio.h>
#include <unistd.h>
#include <uuid/uuid.h>
#include <string.h>
static const char* StrRequestType[] = {
"REQ PING",
"REQ AUTH",
"REQ MSGSYNC",
"REQ MSGPSH",
"REQ MSG",
"REQ MSGACK",
"REQ MSGFIN",
"REQ SUB",
"REQ SMS",
"REQ PRES",
"REQ ACCSTATUS",
"REQ INVITE",
"REQ ACK",
"REQ BYE",
"REQ UPDATE",
"REQ ACCUPDATE"
};
static const char* StrResponseType[] = {
"RSP PING",
"RSP AUTH",
"RSP MSGSYNC",
"RSP MSGPSH",
"RSP MSG",
"RSP MSGACK",
"RSP MSGFIN",
"RSP SUB",
"RSP SMS",
"RSP PRES",
"RSP ACCSTATUS",
"RSP INVITE",
"RSP ACK",
"RSP BYE",
"RSP UPDATE",
"RSP ACCUPDATE"
};
const char* MsgType2Str(uint8_t type)
{
uint8_t request_flag = (type >> 7 & 0x01);
uint8_t msg_type = type & 0x7F;
switch (msg_type) { //内部服务使用的协议
case NEBULA_KIEV_ACCOFFLINE:
return (request_flag ? "REQ ACCOFFLINE" : "RSP ACCOFFLINE");
case NEBULA_KIEV_ACCONLINE:
return (request_flag ? "REQ ACCONLINE" : "RSP ACCONLINE");
case NEBULA_KIEV_MSGACK:
return (request_flag ? "REQ KIEVACK" : "RSP KIEVACK");
default:
break;
}
if (!IS_VALID_TYPE(type)) {
return (request_flag ? "REQ UnKnown": "RSP UnKnown");
}
if (request_flag) {
return StrRequestType[msg_type - 1];
}
return StrResponseType[msg_type-1];
}
uint32_t CreateMachineId()
{
uuid_t uuid = {0};
char str[37];
uint32_t hash = 5381;
memset(str, 0, sizeof(str));
uuid_generate(uuid);
uuid_unparse(uuid, str);
int i;
for(i=0; i<36; i++) {
hash = ((hash << 5) + hash) + str[i];
}
return hash;
}
void CreateMsgid(char *msgid)
{
static uint32_t machine_id;
static uint32_t ref_cnt = 0;
if (ref_cnt == 0) {
machine_id = CreateMachineId();
}
struct MsgId {
uint32_t timestamp;
uint32_t hash:24;
uint16_t pid;
uint32_t cnt:24;
}__attribute__((packed));
struct MsgId id;
id.timestamp = time(0);
id.hash = machine_id;
id.pid = getpid();
id.cnt = ref_cnt++;
sprintf(msgid, "%08x%06x%04x%06x", id.timestamp, id.hash, id.pid, id.cnt);
msgid[24] = '\0';
}

View File

@ -1,69 +0,0 @@
/******************************************************************************
* FileName:
* Description:
* Version:
* History:
* yuxiaobo 2014-12-23 1.0 created
*
*****************************************************************************/
#ifndef __NEBULA_PROTO_H__
#define __NEBULA_PROTO_H__
#include <stdint.h>
struct _NebulaHeader
{
uint8_t magic;
uint8_t ver;
uint8_t flag;
uint8_t type;
uint16_t len;
}__attribute__((packed));
typedef struct _NebulaHeader NebulaHeader;
#define NEBULA_MSG_PING 0x01
#define NEBULA_MSG_AUTH 0x02
#define NEBULA_MSG_SYNC 0x03
#define NEBULA_MSG_PSH 0x04
#define NEBULA_MSG_MSG 0x05
#define NEBULA_MSG_ACK 0x06
#define NEBULA_MSG_FIN 0x07
#define NEBULA_MSG_SUB 0x08
#define NEBULA_MSG_SMS 0x09
#define NEBULA_MSG_PRES 0x0A
#define NEBULA_MSG_ACCSTATUS 0x0B
#define NEBULA_MSG_INVITE 0x0C
#define NEBULA_MSG_DIALOGACK 0x0D
#define NEBULA_MSG_BYE 0x0E
#define NEBULA_MSG_UPDATE 0x0F
#define NEBULA_MSG_ACCUPDATE 0x10
#define NEBULA_KIEV_ACCOFFLINE 0x7D
#define NEBULA_KIEV_ACCONLINE 0x7E
#define NEBULA_KIEV_MSGACK 0x7F
#define MSG_IS_REQUEST(head) (((head)->type >> 7) & 0x01)
#define MSG_SET_REQUEST(type) (0x80 | type)
const char* MsgType2Str(uint8_t type);
#define IS_VALID_TYPE(type) (((type) & 0x7F) > 0 && ((type) & 0x7F) <= 0x10)
#define HEAD_INIT(h,t) \
do { \
(h)->magic = 0xF8; \
(h)->ver = 0x01; \
(h)->flag = 0x00; \
(h)->type = (t); \
(h)->len = 0; \
}while(0)
#define MSG_ID_LEN 24
/*
* msgid
* @param msgid MSG_ID_LEN+1
*/
void CreateMsgid(char *msgid);
#endif

View File

@ -1,143 +0,0 @@
#include "push.h"
#include "config.h"
#include "connect.h"
#include "dict.h"
#include "message.pb-c.h"
#include "nebula_proto.h"
#include <string.h>
dict *g_seq_dict = NULL;
static unsigned int __hashFunction(const void *key)
{
return dictGenHashFunction((const char*)key, strlen((const char*)key));
}
void* __keyDup(void *privdata, const void *key)
{
(void)privdata;
return strdup((const char*)key);
}
int __keyCompare(void *privdata, const void *key1, const void *key2)
{
(void)privdata;
return strcmp((const char*)key1, (const char*)key2) == 0;
}
void __keyDestructor(void *privdata, void *key)
{
(void)privdata;
free(key);
}
int NebulaInitPush()
{
if (g_seq_dict) return 0;
static dictType type = {
__hashFunction,
__keyDup,
NULL,
__keyCompare,
__keyDestructor,
NULL
};
g_seq_dict = dictCreate(&type, NULL);
if (!g_seq_dict)
return -1;
return 0;
}
int SendSync(int type)
{
Nebula__MessageSeq request;
nebula__message_seq__init(&request);
size_t seq_size = dictSize(g_seq_dict);
request.n_content = seq_size;
request.content = (Nebula__MessageSeq__Content**)malloc(sizeof(void*) * seq_size);
dictIterator *it = dictGetIterator(g_seq_dict);
dictEntry *entry = dictNext(it);
size_t i = 0;
while (entry) {
request.content[i] = (Nebula__MessageSeq__Content*)malloc(sizeof(Nebula__MessageSeq__Content));
nebula__message_seq__content__init(request.content[i]);
request.content[i]->account = (char*)entry->key;
request.content[i]->seq = entry->v.u64;
i++;
entry = dictNext(it);
}
dictReleaseIterator(it);
// send
int ret = NebulaSend(type, (ProtobufCMessage*)&request);
for (i = 0; i < seq_size; ++i)
{
free(request.content[i]);
}
free(request.content);
return ret;
}
void NebulaOnPush(NebulaHeader *head, const char* data, int len)
{
(void)head, (void)data, (void)len;
if (-1 == SendSync(MSG_SET_REQUEST(NEBULA_MSG_SYNC))) {
log_error("SendSync failed.");
}
}
void NebulaOnMsg(NebulaHeader *head, const char* data, int len)
{
(void)head;
Nebula__Message *message = nebula__message__unpack(NULL, len, (const uint8_t*)data);
if (!message) {
log_error("parse NebulaMessage failed.");
return ;
}
size_t i;
for (i = 0; i < message->n_content; ++i)
{
Nebula__Message__Content *ctn = message->content[i];
if ((int)ctn->type >= eNebulaMsg_Max) {
log_warn("discard unkown type message. type=%d", ctn->type);
continue;
}
dictEntry * entry = dictFind(g_seq_dict, ctn->account);
if (!entry || ctn->seq > entry->v.u64) {
log_debug("recv message. type=%s, account=%s, seq=%u, hasbody=%d, bodylength=%lu",
Nebulamsgtype_name(ctn->type), ctn->account, ctn->seq, ctn->has_body, ctn->body.len);
if (!ctn->has_body) {
log_warn("message has not body, discard it!");
} else if (g_nebula_cb[ctn->type])
g_nebula_cb[ctn->type]((const char*)ctn->body.data, ctn->body.len);
// refresh sequence
if (entry) {
entry->v.u64 = ctn->seq;
} else {
if (DICT_OK != dictAdd(g_seq_dict, ctn->account, (void*)(uint64_t)ctn->seq)) {
log_error("refresh sequence number error, maybe memory was deplete.");
}
}
} else {
log_warn("discard message. type=%s, account=%s, seq=%u, hasbody=%d, bodylength=%lu",
Nebulamsgtype_name(ctn->type), ctn->account, ctn->seq, ctn->has_body, ctn->body.len);
}
}
if (message->has_flag) {
if (message->flag == NEBULA__MESSAGE__FLAG__MESSAGE_ACK)
SendSync(MSG_SET_REQUEST(NEBULA_MSG_ACK));
else if (message->flag == NEBULA__MESSAGE__FLAG__MESSAGE_END)
SendSync(MSG_SET_REQUEST(NEBULA_MSG_FIN));
}
nebula__message__free_unpacked(message, NULL);
}

View File

@ -1,16 +0,0 @@
#ifndef PUSH_H
#define PUSH_H
#include "nebula_proto.h"
// push
// Send sync request to server when received MSGPUSH.
// Remember push sequences in memory.
int NebulaInitPush();
void NebulaOnPush(NebulaHeader *head, const char* data, int len);
void NebulaOnMsg(NebulaHeader *head, const char* data, int len);
#endif //PUSH_H

Binary file not shown.

View File

@ -1,261 +0,0 @@
#include "redirect.h"
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <curl/curl.h>
#include <openssl/md5.h>
#include <json-c/json.h>
#include "config.h"
#include "str.h"
List *g_redirect_result = NULL;
time_t g_last_redirect = 0;
char* g_salt = NULL;
char* g_rule = NULL;
ssize_t NebulaRedirectOnRead(const void *ptr, size_t size, size_t nmemb, FILE *stream)
{
(void)size, (void)stream;
struct str *result = (struct str *)stream;
string_append_fast(result, (const char*)ptr, nmemb);
return nmemb;
}
int NebulaCloneRedirectResult()
{
if (!g_redirect_result) return -1;
if (g_redirect_result->size == 0) return -1;
if (g_server_list)
ClearList(g_server_list);
else
g_server_list = CreateList();
if (!g_server_list) goto on_error;
ListIterator it;
for (it = ListBegin(g_redirect_result); it; it = ListNext(it)) {
struct sockaddr_in *r_addr = (struct sockaddr_in *)(*it);
struct sockaddr_in *addr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
if (!addr) {
goto on_error;
}
addr->sin_port = r_addr->sin_port;
addr->sin_addr.s_addr = r_addr->sin_addr.s_addr;
if (-1 == PushBack(g_server_list, addr)) {
free(addr);
goto on_error;
}
}
return 0;
on_error:
if (g_server_list)
ClearList(g_server_list);
return -1;
}
int NebulaRedirect()
{
time_t now = time(0);
if (now - g_last_redirect < 300) {
if (0 == NebulaCloneRedirectResult()) {
log_info("not timeout, use last redirect result always.");
return 0;
}
}
g_last_redirect = now;
static const char* key = "key=89d15f8b716d4b16fae9feaa09bc4fc5&";
struct str result;
string_init(&result);
struct json_object* response = NULL;
List *server_list = NULL;
// post parameters.
struct str params;
string_init(&params);
string_append_fast(&params, "uid=", 4);
string_append_fast(&params, g_device_tag, strlen(g_device_tag));
string_append_fast(&params, "&nonce=", 7);
const char* nonce = Nebularand_string();
string_append_fast(&params, nonce, strlen(nonce));
string_append_fast(&params, "&ts=", 4);
time_t t = time(0);
char ts[32];
snprintf(ts, sizeof(ts), "%ld", t);
string_append_fast(&params, ts, strlen(ts));
// sign
unsigned char sign_str[MD5_DIGEST_LENGTH], sign[MD5_DIGEST_LENGTH * 2];
char md5buf[512];
snprintf(md5buf, sizeof(md5buf), "%s%s", key, params.ptr);
MD5((const unsigned char*)md5buf, strlen(md5buf), sign_str);
static const char hex[] = "0123456789abcdef";
int i;
for (i = 0; i < MD5_DIGEST_LENGTH; i++)
{
sign[i * 2] = hex[sign_str[i] >> 4];
sign[i * 2 + 1] = hex[sign_str[i] & 0xf];
}
string_append_fast(&params, "&sign=", 6);
string_append_fast(&params, (const char*)sign, sizeof(sign));
CURL *curl = curl_easy_init();
char url[128] = {};
snprintf(url, sizeof(url), "%s/push/redirect", g_nebula_host);
//const char* url = "https://p.meizu.com/push/redirect";
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &NebulaRedirectOnRead);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, params.ptr);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, params.len);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
log_info("HTTPS POST. url=%s, params=%s", url, params.ptr);
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
log_error("curl_easy_perform(redirect) error. code=%d, info=%s",
(int)res, curl_easy_strerror(res));
goto on_error;
} else {
log_info("curl_easy_perform success. response=%s", result.ptr);
}
// parse response json.
response = json_tokener_parse(result.ptr);
string_deinit(&result);
if (!response) {
log_error("json parse error.");
goto on_error;
}
struct json_object* code_node = json_object_object_get(response, "code");
if (!code_node) {
log_error("json parse error, hasnot \"code\" node.");
goto on_error;
}
int code = json_object_get_int(code_node);
if (code != 200) {
// redirect failed.
log_error("json response code error. code=%d", code);
goto on_error;
}
struct json_object *md5_daa = json_object_object_get(response, "md5_daa");
if (!md5_daa) {
log_error("json response has no md5_daa field.");
goto on_error;
}
struct json_object *salt_node = json_object_object_get(md5_daa, "salt");
if (!salt_node) {
log_error("json response has no md5_daa.salt field.");
goto on_error;
}
const char* salt = json_object_get_string(salt_node);
if (!salt) {
log_error("json response has no md5_daa.salt field.");
goto on_error;
}
if (g_salt) free(g_salt);
g_salt = strdup(salt);
struct json_object *rule_node = json_object_object_get(md5_daa, "rule");
if (!rule_node) {
log_error("json response has no md5_daa.rule field.");
goto on_error;
}
const char* rule = json_object_get_string(rule_node);
if (!rule) {
log_error("json response has no md5_daa.rule field.");
goto on_error;
}
if (g_rule) free(g_rule);
g_rule = strdup(rule);
struct json_object* host_list_node = json_object_object_get(response, "hostlist");
if (!host_list_node) {
log_error("json parse error, hasnot \"hostlist\" node.");
goto on_error;
}
struct array_list* host_list = json_object_get_array(host_list_node);
if (!host_list) {
log_error("json_object_get_array error.");
goto on_error;
}
int host_count = array_list_length(host_list);
if (!host_count) {
log_error("host list is empty.");
goto on_error;
}
server_list = CreateList();
if (!server_list) {
log_error("create server list error, maybe memory was deplete.");
goto on_error;
}
for (i = 0; i < host_count; ++i)
{
struct json_object* elem = (struct json_object*)array_list_get_idx(host_list, i);
if (!elem) {
log_error("host list get idx error, i=%d.", i);
goto on_error;
}
struct json_object* ip_node = json_object_object_get(elem, "ip");
if (!ip_node) {
log_error("host list get ip error, i=%d.", i);
goto on_error;
}
const char* ip = json_object_get_string(ip_node);
int ip_len = json_object_get_string_len(ip_node);
if (!ip || !ip_len) {
log_error("host list get ip error, i=%d.", i);
goto on_error;
}
struct json_object* port_node = json_object_object_get(elem, "port");
int port = json_object_get_int(port_node);
if (!port) {
log_error("host list get port error, i=%d.", i);
goto on_error;
}
struct sockaddr_in *addr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
if (!addr) {
log_error("malloc sockaddr_in failed.");
goto on_error;
}
addr->sin_port = htons(port);
addr->sin_addr.s_addr = inet_addr(ip);
if (-1 == PushBack(server_list, addr)) {
log_error("PushBack to server_list error, maybe memory was deplete.");
goto on_error;
}
}
if (g_redirect_result)
DestroyList(g_redirect_result);
g_redirect_result = server_list;
server_list = NULL;
return NebulaCloneRedirectResult();
on_error:
string_deinit(&result);
if (response)
json_object_put(response);
if (server_list)
DestroyList(server_list);
return -1;
}

View File

@ -1,10 +0,0 @@
#ifndef REDIRECT_H
#define REDIRECT_H
/** redirect
* @Launch http request to p.meizu.com, get server ip list.
* @Block function.
*/
int NebulaRedirect();
#endif //REDIRECT_H

View File

@ -1,131 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include "str.h"
#define DEFAULT_STRING_SIZE 32
#define SMAX(a, b) ((a) > (b) ? (a) : (b))
void string_init(struct str *str)
{
str->size = 0;
str->len = 0;
str->ptr = NULL;
}
void string_deinit(struct str *str)
{
if(str->ptr){
free(str->ptr);
string_init(str);
}
}
bool string_empty(const struct str *str)
{
return str->len == 0 ? true : false;
}
int string_duplicate(struct str *dst, const struct str *src)
{
string_reset(dst);
return string_append(dst, src->ptr, src->len);
}
int string_copy(struct str *dst, const char *src, size_t srclen)
{
string_reset(dst);
return string_append(dst, src, srclen);
}
#ifndef _GNU_SOURCE
static int vasprintf(char **buf, const char *fmt, va_list ap)
{
static char _T_emptybuffer = '\0';
int chars;
char *b;
if(!buf) { return -1; }
chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap)+1;
if(chars < 0) {
chars *= -1;
}
b = (char*)malloc(sizeof(char)*chars);
if(!b) { return -1; }
if((chars = vsprintf(b, fmt, ap)) < 0)
{
free(b);
} else {
*buf = b;
}
return chars;
}
#endif
int string_sprintf(struct str *str, const char* fmt, ...)
{
va_list ap;
char *t = NULL;
int size;
char buf[128];
// string_reset(str);
va_start(ap, fmt);
size = vsnprintf(buf, 128, fmt, ap);
va_end(ap);
if(size == -1 || size > 127) {
va_start(ap, fmt);
if((size = vasprintf(&t, fmt, ap)) == -1) {
va_end(ap);
return -1;
}
va_end(ap);
size = string_append(str, t, size);
free(t);
return size;
}
return string_append(str, buf, size);
}
int string_compare(const struct str *s1, const struct str *s2)
{
if (s1->len != s2->len) {
return s1->len - s2->len > 0 ? 1 : -1;
}
return strncmp(s1->ptr, s2->ptr, s1->len);
}
void string_reset(struct str *str)
{
if(str->ptr) {
str->len = 0;
str->ptr[0] = '\0';
}
}
int string_append(struct str *str, const char *buf, size_t buflen)
{
if( str->size - str->len <= buflen ) {
size_t new_size = SMAX(DEFAULT_STRING_SIZE,
SMAX(str->size * 2, str->len + buflen + 8));
char *t = (char*)realloc(str->ptr, new_size);
if( t == NULL )
return -1;
str->size = new_size;
str->ptr = t;
}
memcpy(str->ptr + str->len, buf, buflen);
str->len += buflen;
str->ptr[str->len] = '\0';
return buflen;
}

View File

@ -1,53 +0,0 @@
#ifndef __STUN_STRING_H__
#define __STUN_STRING_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#include <string.h>
#include <stdbool.h>
struct str{
size_t size; /*buf所占内存长度*/
size_t len; /*buf字符长度*/
char* ptr;
};
void string_init(struct str *str);
void string_deinit(struct str *str);
bool string_empty(const struct str *str);
int string_duplicate(struct str *dst, const struct str *src);
int string_copy(struct str *dst, const char *src, size_t srclen);
int string_sprintf(struct str *str, const char* fmt, ...);
int string_compare(const struct str *s1, const struct str *s2);
void string_reset(struct str *str);
int string_append(struct str *str, const char *buf, size_t buflen);
#define string_length(s) ((s)->len)
#define string_append_fast(s, bufptr, bufsize) \
do { \
if (((s)->size - (s)->len) > bufsize) { \
memcpy((s)->ptr + (s)->len, (bufptr), bufsize); \
(s)->len += bufsize; \
(s)->ptr[(s)->len] = '\0'; \
} else { \
string_append((s), (bufptr), bufsize); \
} \
}while(0)
#ifdef __cplusplus
}
#endif
#endif

Binary file not shown.

View File

@ -1,108 +0,0 @@
#include "subscribe.h"
#include "config.h"
#include "timer.h"
#include "message.pb-c.h"
#include "nebula_proto.h"
#include "connect.h"
#include <time.h>
#include "archive.h"
typedef enum {
eSubStatus_Init,
eSubStatus_WaitResponse,
eSubStatus_Done,
} eSubStatus;
static eSubStatus g_sub_status = eSubStatus_Init;
static time_t g_sub_tick = 0;
int subscribe()
{
int count = 0, i;
char** sub_apps = (char**)malloc(g_sub_app_count * sizeof(char*));
if (!sub_apps) return -1;
for (i = 0; i < g_sub_app_count; ++i)
{
if (NebulaIsSubscribed(g_sub_apps[i])) continue;
sub_apps[count++] = g_sub_apps[i];
}
if (!count) return 1;
Nebula__SubscribeRequest request;
nebula__subscribe_request__init(&request);
request.n_app = count;
request.app = sub_apps;
int ret = NebulaSend(MSG_SET_REQUEST(NEBULA_MSG_SUB), (ProtobufCMessage*)&request);
free(sub_apps);
return ret;
}
void NebulaOnSubSuccess(const char* appname)
{
// TODO: save subscribe app and sub time.
log_info("sub %s success.", appname);
NebulaAddSubApp(appname);
}
void NebulaOnSub(NebulaHeader *head, const char* data, int len)
{
Nebula__SubscribeResponse *response = nebula__subscribe_response__unpack(NULL, len, (const uint8_t*)data);
if (!response) {
log_error("subcribe response parse error.");
return ;
}
if (response->status != 200) {
log_error("subcribe failed. status=%d", response->status);
nebula__subscribe_response__free_unpacked(response, NULL);
return ;
}
size_t i;
for (i = 0; i < response->n_content; ++i)
{
Nebula__SubscribeResponse__Content *ctn = response->content[i];
if (ctn->status == 200) {
NebulaOnSubSuccess(ctn->app);
}
}
g_sub_status = eSubStatus_Done;
nebula__subscribe_response__free_unpacked(response, NULL);
}
int subscribe_loop()
{
if (!g_sub_app_count) {
return 0;
}
int ret;
switch (g_sub_status) {
case eStatus_Init:
ret = subscribe();
if (ret == 0) {
g_sub_status = eSubStatus_WaitResponse;
g_sub_tick = clock();
} else if (ret == 1) {
return 0;
} else {
return -1;
}
break;
case eSubStatus_WaitResponse:
if (clock() - g_sub_tick > 10000) {
// timeout
g_sub_status = eSubStatus_Init;
}
break;
case eSubStatus_Done:
return 0;
}
return -1;
}

View File

@ -1,10 +0,0 @@
#ifndef SUBSCRIBE_H
#define SUBSCRIBE_H
#include "nebula_proto.h"
int subscribe_loop();
void NebulaOnSub(NebulaHeader *head, const char* data, int len);
#endif //SUBSCRIBE_H

View File

@ -1,12 +0,0 @@
CC=gcc
CFALGS=-g
INCLUDES=-I..
LINK=-L.. -lnebula_sdk
test:test.c
$(CC) $(CFALGS) $^ -o $@ $(INCLUDES) $(LINK)
.PHONY: clean
clean:
rm test -f

View File

@ -1,5 +0,0 @@
2
com.meizu.cloud
com.meizu.router
1
R10WZOANC5400EE&0 21

View File

@ -1,56 +0,0 @@
#ifndef NEBULA_SDK_H
#define NEBULA_SDK_H
typedef enum {
eNebulaMsg_Push, /// 推送 (路由器只需关心这一类消息)
eNebulaMsg_Presence, /// Presence
eNebulaMsg_Sms, /// 网络短信
eNebulaMsg_Mms, /// 网络彩信
eNebulaMsg_Max,
} NebulaMsgType;
#ifdef __cplusplus
extern "C" {
#endif
/** 初始化网络连接
* @device_tag: (IMEI)
* @verify_pwd: (SN)
* @host: , : https://p.meizu.com (结尾不要带"/", 前面要加上https)
* @file: /, ,
* @return: , 0; -1, errno中.
* @, -1.
*/
int NebulaInit(const char* device_tag, const char* host, const char* file);
/** 设置订阅列表
*
*
*/
void NebulaSubScribe(int count, const char** app_name);
/** 消息处理回调函数
* @app: App名
* @msg:
*/
typedef void (*NebulaMsgCallback)(const char* app, const char* msg);
/** 注册消息处理回调函数
* @type:
* @cb:
* @return:
* @, .
*/
NebulaMsgCallback NebulaRegister(NebulaMsgType type, NebulaMsgCallback cb);
/** 启动
*
*/
int NebulaStart();
#ifdef __cplusplus
}
#endif
#endif //NEBULA_SDK_H

View File

@ -1,56 +0,0 @@
#ifndef NEBULA_SDK_H
#define NEBULA_SDK_H
typedef enum {
eNebulaMsg_Push, /// 推送 (路由器只需关心这一类消息)
eNebulaMsg_Presence, /// Presence
eNebulaMsg_Sms, /// 网络短信
eNebulaMsg_Mms, /// 网络彩信
eNebulaMsg_Max,
} NebulaMsgType;
#ifdef __cplusplus
extern "C" {
#endif
/** 初始化网络连接
* @device_tag: (IMEI)
* @verify_pwd: (SN)
* @host: , : https://p.meizu.com (结尾不要带"/", 前面要加上https)
* @file: /, ,
* @return: , 0; -1, errno中.
* @, -1.
*/
int NebulaInit(const char* device_tag, const char* host, const char* file);
/** 设置订阅列表
*
*
*/
void NebulaSubScribe(int count, const char** app_name);
/** 消息处理回调函数
* @data:
* @len:
*/
typedef void (*NebulaMsgCallback)(const char* data, int len);
/** 注册消息处理回调函数
* @type:
* @cb:
* @return:
* @, .
*/
NebulaMsgCallback NebulaRegister(NebulaMsgType type, NebulaMsgCallback cb);
/** 启动
*
*/
int NebulaStart();
#ifdef __cplusplus
}
#endif
#endif //NEBULA_SDK_H

View File

@ -1,20 +0,0 @@
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
!_TAG_PROGRAM_NAME Exuberant Ctags //
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
!_TAG_PROGRAM_VERSION 5.9~svn20110310 //
CC Makefile /^CC=gcc$/;" m
CFALGS Makefile /^CFALGS=-g$/;" m
INCLUDES Makefile /^INCLUDES=-I..$/;" m
LINK Makefile /^LINK=-L.. -lnebula_sdk$/;" m
NEBULA_SDK_H nebula_sdk/nebula_sdk.h 2;" d
NebulaMsgCallback nebula_sdk/nebula_sdk.h /^ typedef void (*NebulaMsgCallback)(const char* app, const char* msg);$/;" t
NebulaMsgType nebula_sdk/nebula_sdk.h /^} NebulaMsgType;$/;" t typeref:enum:__anon1
OnPush test.c /^void OnPush(const char* app, const char *msg)$/;" f
eNebulaMsg_Max nebula_sdk/nebula_sdk.h /^ eNebulaMsg_Max,$/;" e enum:__anon1
eNebulaMsg_Mms nebula_sdk/nebula_sdk.h /^ eNebulaMsg_Mms, \/\/\/ 网络彩信$/;" e enum:__anon1
eNebulaMsg_Presence nebula_sdk/nebula_sdk.h /^ eNebulaMsg_Presence, \/\/\/ Presence$/;" e enum:__anon1
eNebulaMsg_Push nebula_sdk/nebula_sdk.h /^ eNebulaMsg_Push, \/\/\/ 推送 (路由器只需关心这一类消息)$/;" e enum:__anon1
eNebulaMsg_Sms nebula_sdk/nebula_sdk.h /^ eNebulaMsg_Sms, \/\/\/ 网络短信$/;" e enum:__anon1
main test.c /^int main()$/;" f

View File

@ -1,74 +0,0 @@
#include "nebula_sdk/nebula_sdk.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/resource.h>
#include <limits.h>
/*
*void OnPush(const char* data, int len)
*{
* char *body = strndup(data, len);
* printf("karldbg %s %d\n", __func__, len);
* do {
* int cnt = 0;
* for(cnt=0; cnt<len; cnt++) {
* printf("karldbg %s pos: 0x%02x, 0x%02x, %c\n", __func__, cnt, (char)*(body+cnt), *(body+cnt));
* }
* } while(0);
* printf("recv push:%s\n", body);
* free(body);
*}
*/
void OnPush(const char* app, const char *msg)
{
printf("karldbg %s %d %s\n", __func__, __LINE__, app);
printf("karldbg %s %d %s\n", __func__, __LINE__, msg);
/*
*do {
* int cnt = 0;
* for(cnt=0; cnt<len; cnt++) {
* printf("karldbg %s pos: 0x%02x, 0x%02x, %c\n", __func__, cnt, (char)*(body+cnt), *(body+cnt));
* }
*} while(0);
*/
}
int main()
{
//??
struct rlimit no_limit = {RLIM_INFINITY, RLIM_INFINITY};
setrlimit(RLIMIT_CORE, &no_limit);
/*if (-1 == NebulaInit("1000000010000001", "https://172.16.82.71", "data")) {*/
if (-1 == NebulaInit("R10WZOANC5400EE", "https://172.16.82.71", "data")) {
printf("Init error.\n");
return 1;
}
/*const char * apps[] = {"com.meizu.cloud"};*/
const char * apps[] = {"com.meizu.router"};
NebulaSubScribe(1, apps);
NebulaMsgCallback cb = OnPush;
/*NebulaRegister(eNebulaMsg_Push, &OnPush);*/
NebulaRegister(eNebulaMsg_Push, cb);
if (-1 == NebulaStart()) {
printf("Start error.\n");
return 1;
}
printf("start success.\n");
for (;;)
sleep(1);
return 0;
}

View File

@ -1,176 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include "timer.h"
#define DEFAULT_TIMER_LIMIT_SIZE 256
struct timer_heap_t
{
int32_t limit_size; //一次超时的元素个数
util_rbtree_t rbtree;
};
/*{{{ timer_heap_create*/
timer_heap_t* timer_heap_create(int32_t limit_size)
{
timer_heap_t* ht;
ht = (timer_heap_t*)malloc(sizeof(timer_heap_t));
if(ht == NULL){
return NULL;
}
ht->limit_size = (limit_size <=0 ? DEFAULT_TIMER_LIMIT_SIZE : limit_size);
util_rbtree_init(&ht->rbtree);
return ht;
}
void set_timer_limit(timer_heap_t *ht, int32_t limit)
{
if(ht == NULL)
return;
if (limit > 0) {
ht->limit_size = limit;
}
}
/*}}}*/
/*{{{ timer_add*/
int32_t timer_add( timer_heap_t* ht, timer_entry* entry, uint32_t expires)
{
struct timeval now;
long msec;
if(!ht || !entry)
{
return -1; /*参数错误*/
}
/*获取当前时间*/
gettimeofday(&now, NULL);
msec = now.tv_sec*1000 + now.tv_usec/1000 + expires;
if (entry->in_rbtree) {
//已经在红黑树中 先删除再插入
util_rbtree_delete(&ht->rbtree, &entry->rbnode);
entry->in_rbtree = 0;
rbt_clear_node(&entry->rbnode);
}
entry->rbnode.key = msec;
util_rbtree_insert(&ht->rbtree, &entry->rbnode);
entry->in_rbtree = 1;
return 0;
}
/*}}}*/
/*{{{ timer_del*/
void timer_del( timer_heap_t* ht, timer_entry* entry)
{
if(!ht || !entry)
return;
if (!entry->in_rbtree)
return;
util_rbtree_delete(&ht->rbtree, &entry->rbnode);
entry->in_rbtree = 0;
rbt_clear_node(&entry->rbnode);
}
/*}}}*/
int32_t timer_update(timer_heap_t* ht, timer_entry *entry, uint32_t expires)
{
return timer_add(ht, entry, expires);
}
int32_t timer_earliest_time(timer_heap_t* ht)
{
struct timeval now;
long msec;
util_rbtree_node_t *rbnode;
if(!ht)
return -1;
if(ht->rbtree.size == 0)
return -1;
gettimeofday(&now, NULL);
rbnode = util_rbtree_min(&ht->rbtree);
if (rbnode == NULL)
return -1;
msec = rbnode->key - (now.tv_sec*1000 + now.tv_usec/1000);
if(msec < 0)
msec = 0;
return (int32_t)msec;
}
int32_t timer_size(timer_heap_t* ht)
{
if(!ht)
return 0;
return (int32_t)ht->rbtree.size;
}
int32_t timer_run(timer_heap_t* ht)
{
struct timeval now;
long msec;
int i;
int count = 0;
if(!ht || util_rbtree_isempty(&ht->rbtree)){
return 0;
}
gettimeofday(&now, NULL);
msec = now.tv_sec*1000 + now.tv_usec/1000;
for (i=0; i<ht->limit_size; ++i) {
timer_entry *entry;
util_rbtree_node_t *node = util_rbtree_min(&ht->rbtree);
if (node == NULL) break;
entry = (timer_entry*)node->data;
if (node->key <= msec) {
++count;
util_rbtree_delete(&ht->rbtree, node);
rbt_clear_node(node);
entry->in_rbtree = 0;
if (entry->timeout_cb) {
entry->timeout_cb(ht, entry);
}
} else {
break;
}
}
return count;
}
void timer_entry_init(timer_entry* entry, int32_t id, void* user_data, \
void (*timeout_cb)(timer_heap_t* ht, struct timer_entry *entry))
{
entry->user_data = user_data;
entry->timeout_cb = timeout_cb;
entry->id = id;
entry->in_rbtree = 0;
rbt_clear_node(&entry->rbnode);
entry->rbnode.data = entry;
}
void timer_destroy( timer_heap_t* ht)
{
if(!ht)
return;
while(!util_rbtree_isempty(&ht->rbtree)) {
timer_entry *entry;
util_rbtree_node_t *node = util_rbtree_min(&ht->rbtree);
entry = (timer_entry*)node->data;
util_rbtree_delete(&ht->rbtree, node);
rbt_clear_node(node);
entry->in_rbtree = 0;
if (entry->timeout_cb) {
entry->timeout_cb(ht, entry);
}
}
free(ht);
}

View File

@ -1,93 +0,0 @@
/*
* =====================================================================================
*
* Filename: timer.h
*
* Description: (线)
*
* Version: 1.0
* Created: 2013-08-20
* Revision: none
* Compiler: gcc
*
* Author: xiaoboyu
* Organization:
*
* =====================================================================================
*/
#ifndef __TIMER_HEAP_H__
#define __TIMER_HEAP_H__
#include <stdint.h>
#include "util_rbtree.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct timer_heap_t timer_heap_t;
typedef struct timer_entry
{
int32_t id;
uint8_t in_rbtree; /*是否在红黑树中*/
util_rbtree_node_t rbnode;
void *user_data;
void (*timeout_cb)(timer_heap_t* ht, struct timer_entry *entry);
}timer_entry;
void timer_entry_init(timer_entry* entry, int32_t id, void* user_data, \
void (*timeout_cb)(timer_heap_t* ht, struct timer_entry *entry));
/*
*
* @param limit_size
*/
timer_heap_t* timer_heap_create(int32_t limit_size);
/*
* @brief 256
*/
void set_timer_limit(timer_heap_t *ht, int32_t limit);
/*
* @ref
* @param expires ms
* @return 0 -1
*/
int32_t timer_add( timer_heap_t* ht, timer_entry *entry, uint32_t expires );
/*
* @ref
*/
void timer_del( timer_heap_t* ht, timer_entry* entry );
/*
* @brief (entry必须在定时器内, )
*/
int32_t timer_update(timer_heap_t* ht, timer_entry *entry, uint32_t expires);
/*
* @brief
* @return -1
*/
int32_t timer_earliest_time(timer_heap_t* ht);
/*
* @ref
*/
int32_t timer_size ( timer_heap_t* ht );
/*
* @ref
* @return
*/
int32_t timer_run(timer_heap_t* ht);
void timer_destroy( timer_heap_t* ht);
#ifdef __cplusplus
}
#endif
#endif

Binary file not shown.

View File

@ -1,486 +0,0 @@
/* Copyright (C) 2010. sparkling.liang@hotmail.com. All rights reserved. */
#include "util_rbtree.h"
/* the NULL node of tree */
#define _NULL(rbtree) (&((rbtree)->null))
/* structues uesed to check a rb tree */
struct rbtree_check_s
{
short rbh; /* rb height of the tree */
short maxd; /* max depth of the tree */
int fini; /* check failed ? */
const util_rbtree_node_t *null; /* sentinel of the tree */
};
typedef struct rbtree_check_s rbtree_check_t;
static void rbtree_left_rotate(util_rbtree_node_t **root,
util_rbtree_node_t* sentinel,
util_rbtree_node_t *node);
static void rbtree_right_rotate(util_rbtree_node_t **root,
util_rbtree_node_t* sentinel,
util_rbtree_node_t *node);
void util_rbtree_init(util_rbtree_t *rbtree)
{
if(rbtree != NULL)
{
util_rbt_black(_NULL(rbtree)); /* null MUST be black */
rbtree->root = _NULL(rbtree);
rbtree->size = 0;
}
}
util_rbtree_node_t* util_rbsubtree_min(util_rbtree_node_t *node, util_rbtree_node_t *sentinel)
{
if(node == sentinel) return NULL;
while(node->left != sentinel) node = node->left;
return node;
}
util_rbtree_node_t* util_rbsubtree_max(util_rbtree_node_t *node, util_rbtree_node_t *sentinel)
{
if(node == sentinel) return NULL;
while(node->right != sentinel) node = node->right;
return node;
}
void util_rbtree_insert(util_rbtree_t *rbtree, util_rbtree_node_t *node)
{
util_rbtree_node_t **root = &rbtree->root;
util_rbtree_node_t *sentinel = _NULL(rbtree);
util_rbtree_node_t *temp, **p;
/* empty tree */
if (*root == sentinel) {
node->parent = NULL;
node->left = sentinel;
node->right = sentinel;
util_rbt_black(node);
*root = node;
++rbtree->size;
return;
}
/* a binary tree insert */
temp = *root;
for (;;) {
p = (node->key < temp->key) ? &temp->left : &temp->right;
if (*p == sentinel) {
break;
}
temp = *p;
}
*p = node;
node->parent = temp;
node->left = sentinel;
node->right = sentinel;
util_rbt_red(node);
/* re-balance tree */
while (node != *root && util_rbt_isred(node->parent)) {
if (node->parent == node->parent->parent->left) {
temp = node->parent->parent->right;
if (util_rbt_isred(temp)) {
util_rbt_black(node->parent);
util_rbt_black(temp);
util_rbt_red(node->parent->parent);
node = node->parent->parent;
} else {
if (node == node->parent->right) {
node = node->parent;
rbtree_left_rotate(root, sentinel, node);
}
util_rbt_black(node->parent);
util_rbt_red(node->parent->parent);
rbtree_right_rotate(root, sentinel, node->parent->parent);
}
} else {
temp = node->parent->parent->left;
if (util_rbt_isred(temp)) {
util_rbt_black(node->parent);
util_rbt_black(temp);
util_rbt_red(node->parent->parent);
node = node->parent->parent;
} else {
if (node == node->parent->left) {
node = node->parent;
rbtree_right_rotate(root, sentinel, node);
}
util_rbt_black(node->parent);
util_rbt_red(node->parent->parent);
rbtree_left_rotate(root, sentinel, node->parent->parent);
}
}
}
util_rbt_black(*root);
++rbtree->size;
}
void util_rbtree_delete(util_rbtree_t *rbtree, util_rbtree_node_t *node)
{
util_rbtree_node_t **root = &rbtree->root;
util_rbtree_node_t *sentinel = _NULL(rbtree);
util_rbtree_node_t *subst, *temp, *w;
uint8_t red;
/* a binary tree delete */
--rbtree->size;
if (node->left == sentinel) {
temp = node->right;
subst = node;
} else if (node->right == sentinel) {
temp = node->left;
subst = node;
} else {
subst = util_rbsubtree_min(node->right, sentinel);
if (subst->left != sentinel) {
temp = subst->left;
} else {
temp = subst->right;
}
}
if (subst == *root) {
*root = temp;
util_rbt_black(temp);
rbt_clear_node(node);
return;
}
red = util_rbt_isred(subst);
if (subst == subst->parent->left) {
subst->parent->left = temp;
} else {
subst->parent->right = temp;
}
if (subst == node) {
temp->parent = subst->parent;
} else {
if (subst->parent == node) {
temp->parent = subst;
} else {
temp->parent = subst->parent;
}
subst->left = node->left;
subst->right = node->right;
subst->parent = node->parent;
subst->color = node->color;
if (node == *root) {
*root = subst;
} else {
if (node == node->parent->left) {
node->parent->left = subst;
} else {
node->parent->right = subst;
}
}
if (subst->left != sentinel) {
subst->left->parent = subst;
}
if (subst->right != sentinel) {
subst->right->parent = subst;
}
}
rbt_clear_node(node);
if (red) {
return;
}
/* a delete fixup */
while (temp != *root && util_rbt_isblack(temp)) {
if (temp == temp->parent->left) {
w = temp->parent->right;
if (util_rbt_isred(w)) {
util_rbt_black(w);
util_rbt_red(temp->parent);
rbtree_left_rotate(root, sentinel, temp->parent);
w = temp->parent->right;
}
if (util_rbt_isblack(w->left) && util_rbt_isblack(w->right)) {
util_rbt_red(w);
temp = temp->parent;
} else {
if (util_rbt_isblack(w->right)) {
util_rbt_black(w->left);
util_rbt_red(w);
rbtree_right_rotate(root, sentinel, w);
w = temp->parent->right;
}
w->color = temp->parent->color;
util_rbt_black(temp->parent);
util_rbt_black(w->right);
rbtree_left_rotate(root, sentinel, temp->parent);
temp = *root;
}
} else {
w = temp->parent->left;
if (util_rbt_isred(w)) {
util_rbt_black(w);
util_rbt_red(temp->parent);
rbtree_right_rotate(root, sentinel, temp->parent);
w = temp->parent->left;
}
if (util_rbt_isblack(w->left) && util_rbt_isblack(w->right)) {
util_rbt_red(w);
temp = temp->parent;
} else {
if (util_rbt_isblack(w->left)) {
util_rbt_black(w->right);
util_rbt_red(w);
rbtree_left_rotate(root, sentinel, w);
w = temp->parent->left;
}
w->color = temp->parent->color;
util_rbt_black(temp->parent);
util_rbt_black(w->left);
rbtree_right_rotate(root, sentinel, temp->parent);
temp = *root;
}
}
}
util_rbt_black(temp);
}
static void rbtree_left_rotate(util_rbtree_node_t **root,
util_rbtree_node_t* sentinel,
util_rbtree_node_t *node)
{
util_rbtree_node_t *temp;
temp = node->right;
node->right = temp->left;
if (temp->left != sentinel) {
temp->left->parent = node;
}
temp->parent = node->parent;
if (node == *root) {
*root = temp;
} else if (node == node->parent->left) {
node->parent->left = temp;
} else {
node->parent->right = temp;
}
temp->left = node;
node->parent = temp;
}
static void rbtree_right_rotate(util_rbtree_node_t **root,
util_rbtree_node_t* sentinel,
util_rbtree_node_t *node)
{
util_rbtree_node_t *temp;
temp = node->left;
node->left = temp->right;
if (temp->right != sentinel) {
temp->right->parent = node;
}
temp->parent = node->parent;
if (node == *root) {
*root = temp;
} else if (node == node->parent->right) {
node->parent->right = temp;
} else {
node->parent->left = temp;
}
temp->right = node;
node->parent = temp;
}
util_rbtree_node_t* util_rbtree_search(util_rbtree_t *rbtree, long key)
{
if(rbtree != NULL)
{
util_rbtree_node_t *node = rbtree->root;
util_rbtree_node_t *null = _NULL(rbtree);
while(node != null)
{
if(key < node->key) node = node->left;
else if(key > node->key) node = node->right;
else if(node->key == key) return node;
}
}
return NULL;
}
util_rbtree_node_t* util_rbtree_lookup(util_rbtree_t *rbtree, long key)
{
if((rbtree != NULL) && !util_rbtree_isempty(rbtree))
{
util_rbtree_node_t *node = NULL;
util_rbtree_node_t *temp = rbtree->root;
util_rbtree_node_t *null = _NULL(rbtree);
while(temp != null)
{
if(key <= temp->key)
{
node = temp; /* update node */
temp = temp->left;
}
else if(key > temp->key)
{
temp = temp->right;
}
}
/* if node==NULL return the minimum node */
return ((node != NULL) ? node : util_rbtree_min(rbtree));
}
return NULL;
}
static void rbtree_check_subtree(const util_rbtree_node_t *node, rbtree_check_t *check,
int level, int curheight)
{
if(check->fini) /* already failed */
{
return;
}
/* check node color */
if(util_rbt_isblack(node))
{
curheight++;
}
else if(!util_rbt_isred(node))
{
check->fini = 2;
return;
}
/* check left */
if(node->left != check->null)
{
if(util_rbt_isred(node) && util_rbt_isred(node->left))
{
check->fini = 4;
return;
}
if(node->key < node->left->key)
{
check->fini = 5;
return;
}
rbtree_check_subtree(node->left, check, level+1, curheight);
}
else
{
goto __check_rb_height;
}
/* check right */
if(node->right != check->null)
{
if(util_rbt_isred(node) && util_rbt_isred(node->right))
{
check->fini = 4;
return;
}
if(node->key > node->right->key)
{
check->fini = 5;
return;
}
rbtree_check_subtree(node->right, check, level+1, curheight);
}
else
{
goto __check_rb_height;
}
return;
__check_rb_height:
if(check->rbh == 0)
{
check->rbh = curheight;
}
if(check->maxd < level)
{
check->maxd = level;
}
if(check->rbh != curheight)
{
check->fini = 3;
}
}
int util_rbtree_check(const util_rbtree_t *rbtree, int *blackheight, int *maxdepth)
{
rbtree_check_t check;
if(rbtree->root == _NULL(rbtree))
{
return 0;
}
if(!util_rbt_isblack(rbtree->root))
{
return 1;
}
check.fini = check.maxd = check.rbh = 0;
check.null = _NULL(rbtree);
rbtree_check_subtree(rbtree->root, &check, 1, 0);
if(blackheight)
{
*blackheight = check.rbh;
}
if(maxdepth)
{
*maxdepth = check.maxd;
}
return check.fini;
}
static void rbtree_mid_travel(util_rbtree_node_t *node, util_rbtree_node_t *sentinel,
void(*opera)(util_rbtree_node_t *, void *), void *data)
{
if(node->left != sentinel)
{
rbtree_mid_travel(node->left, sentinel, opera, data);
}
opera(node, data);
if(node->right != sentinel)
{
rbtree_mid_travel(node->right, sentinel, opera, data);
}
}
void util_rbtree_mid_travel(util_rbtree_t *rbtree,
void(*opera)(util_rbtree_node_t *, void *), void *data)
{
if((rbtree!=NULL) && !util_rbtree_isempty(rbtree))
{
rbtree_mid_travel(rbtree->root, _NULL(rbtree), opera, data);
}
}

View File

@ -1,114 +0,0 @@
/* Copyright (C) 2010. sparkling.liang@hotmail.com. All rights reserved. */
#ifndef __UTIL_RLTREE_H_
#define __UTIL_RLTREE_H_
#include <stdlib.h>
#include <stdint.h>
typedef struct util_rbtree_s util_rbtree_t;
typedef struct util_rbtree_node_s util_rbtree_node_t;
struct util_rbtree_node_s
{
long key;
util_rbtree_node_t *parent;
util_rbtree_node_t *right;
util_rbtree_node_t *left;
int color;
void *data;
};
struct util_rbtree_s
{
util_rbtree_node_t *root;
util_rbtree_node_t null;
uint32_t size;
};
#define util_rbt_black(rbnode) ((rbnode)->color = 1)
#define util_rbt_red(rbnode) ((rbnode)->color = 0)
#define util_rbt_isblack(rbnode) ((rbnode)->color == 1)
#define util_rbt_isred(rbnode) ((rbnode)->color == 0)
/* clear a node's link */
#define rbt_clear_node(node) do{ \
(node)->left = NULL; \
(node)->right = NULL; \
(node)->parent = NULL; \
}while(0)
/* is the tree empty */
#define util_rbtree_isempty(rbtree) ((rbtree)->root == &(rbtree)->null)
/*
* find the min node of tree
* return NULL is tree is empty
*/
#define util_rbtree_min(rbtree) util_rbsubtree_min((rbtree)->root, &(rbtree)->null)
/*
* find the max node of tree
* return NULL is tree is empty
*/
#define util_rbtree_max(rbtree) util_rbsubtree_max((rbtree)->root, &(rbtree)->null)
void util_rbtree_init(util_rbtree_t *rbtree);
void util_rbtree_insert(util_rbtree_t *rbtree, util_rbtree_node_t *node);
void util_rbtree_delete(util_rbtree_t *rbtree, util_rbtree_node_t *node);
/*
* search node with key = @key in the tree
* if no such node exist, return NULL
*/
util_rbtree_node_t* util_rbtree_search(util_rbtree_t *rbtree, long key);
/*
* look node in the tree
* return the first node with key >= @key;
* if @key > all the key values in the tree, return the node with minimum key
* return NULL if tree is empty
*/
util_rbtree_node_t* util_rbtree_lookup(util_rbtree_t *rbtree, long key);
/*
* find the min node of subtree
* @rbnode: root of the subtree
* @sentinel : the sentinel node
* return NULL if subtree is empty
*/
util_rbtree_node_t* util_rbsubtree_min(util_rbtree_node_t *node, util_rbtree_node_t *sentinel);
/*
* find the max node of subtree
* @rbnode: root of the subtree
* @sentinel : the sentinel node
* return NULL if subtree is empty
*/
util_rbtree_node_t* util_rbsubtree_max(util_rbtree_node_t *node, util_rbtree_node_t *sentinel);
/*
* check whether a tree is a rb tree, the null node is n't checked
* return 0: yes
* return 1: root isn't black
* return 2: node is in other color than black and red
* return 3: tree's black height isn't unique
* return 4: a red node with parent in red exists
* return 5: volatile binary search properties
*
* when return !0, @blackheight & @maxdepth is uselsess
* when return 0, @blackheight contains the tree's black height
*
* @maxdepth contains the max length of all simple roads from root to it's leaf nodes
*/
int util_rbtree_check(const util_rbtree_t *rbtree, int *blackheight, int *maxdepth);
/*
* travel through a rb tree in sequence: left-root-right
* you CAN NOT do any operations that will break the RB properties
*/
void util_rbtree_mid_travel(util_rbtree_t *rbtree, void(*opera)(util_rbtree_node_t *, void *), void *data);
#endif /* end __UTIL_RLTREE_H_ */

File diff suppressed because it is too large Load Diff

Binary file not shown.