os_vimpc
os_vimp.h
/* * @Description:数据类型简秿 * @Author: wlyu * @Date: 2021-03-09 17:32:03 * @LastEditTime: 2021-04-13 15:46:07 * @LastEditors: wlyu * @Reference: */ #ifndef OS_VIMPC_H_ #define OS_VIMPC_H_ #include <stdint.h> typedef void* OS_Vimpc; #define OS_VIMPC_OK ((int)0) #define OS_VIMPC_FAIL ((int)~0) /** * @description: 创建 vimpc * @param {void} 无 * @return {OS_Vimpc} * 返回有效socket(大于等于1)表示成功,OS_INVALID_SOCK表示失败。 */ OS_Vimpc os_vimpc_create(void); /** * @description: 销毁 vimpc * @param {OS_Vimpc} client 实例指针 * @return {void} 无 */ void os_vimpc_destory(OS_Vimpc client); /** * @description: 调用 vimpc 方法 * @param {OS_Vimpc} client 实例指针 * @param {uint32_t} id 方法编号 * @param {void *} arg 参数 * @return {void} 无 */ void os_vimpc_call_method(OS_Vimpc client, uint32_t id, void* arg); #endif // OS_VIMPC_H_
os_vimpc.c
/* * @Description: * @Author: wlyu * @Date: 2021-03-04 16:47:33 * @LastEditTime: 2021-04-13 18:07:05 * @LastEditors: wlyu * @Reference: libdiscovery libpthread */ #include "os_vimpc.h" #include "os_debug.h" #include "os_list.h" #include "os_sock.h" #ifndef WIN32 #include <arpa/inet.h> #include <netinet/in.h> // 组播 #include <sys/select.h> #include <sys/socket.h> #include <unistd.h> #define closesocket close // 关闭 sock #else #include <WinSock2.h> #include <Windows.h> #include <Ws2tcpip.h> // struct ip_mreq #pragma comment(lib, "ws2_32") // 引入lib库 #endif // WIN32 #include <errno.h> #include <fcntl.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include "cJSON.h" #define OS_ALLOC(ptr, type, num) \ do { \ ptr = (type *)malloc(sizeof(type) * num); \ memset(ptr, 0, sizeof(type) * num); \ } while (0) #define OS_REALLOC(ptr, type, num) \ ptr = (type *)realloc(ptr, sizeof(type) * num) #define OS_FREE(ptr) free(ptr) #define N_(String) String #define OS_FILTER_OK ((int)0) #define OS_FILTER_FAIL ((int)~0) typedef struct _OS_Queue OS_Queue; typedef struct _OS_FilterMethod OS_FilterMethod; typedef struct _OS_FilterDesc OS_FilterDesc; typedef struct _OS_Filter OS_Filter; /** * @description: 回调函数 * @param {OS_Filter *} p 操作对象 * @param {void *} arg 用于存储返回值的缓存 * @return {int} OS_VIMP_SUCCESS 表示成功, OS_VIMP_FAIL 表示失败。 */ typedef int (*OS_FilterMethodFunc)(OS_Filter *p, void *arg); typedef void (*OS_FilterFunc)(OS_Filter *p); typedef enum _OS_VimpcId { OS_VIMPC_ID_UNKOWN, OS_VIMPC_ID_SN, OS_VIMPC_ID_TYPE, OS_VIMPC_ID_MODEL, OS_VIMPC_ID_NETWORK, OS_VIMPC_ID_SIP, OS_VIMPC_ID_WEB, OS_VIMPC_ID_ENCODE_REGISTER_REQUEST_PACKET, OS_VIMPC_ID_MAX } OS_VimpcId; struct _OS_Queue { OS_Filter *prev; OS_Filter *next; OS_List list; }; struct _OS_FilterMethod { uint32_t id; // 编号 OS_FilterMethodFunc method; // 方法 }; struct _OS_FilterDesc { uint32_t id; // 编号 char *name; // 名称 char *desc; // 描述 uint32_t ninput; // 输入数据的通道数 uint32_t noutput; // 输出数据的通道数 OS_FilterFunc init; // 初始化方法 OS_FilterFunc process; // 执行函数方法 OS_FilterFunc uninit; // 逆初始化方法 OS_FilterMethod *methods; // 其他方法 }; struct _OS_Filter { OS_FilterDesc *desc; // 基础数据 char *alias; // 别称(与“desc”内的“name“区分) OS_Queue **input; // 输入数据队列的数组 OS_Queue **output; // 输出数据队列的数组 void *data; // 私有数据 OS_FilterMethod *notifys; // 通知方法 }; /** * @description: 初始化 OS_Filter 结构体 * @param {OS_FilterDesc *} desc 静态参数 * @param {const char*} alias 别名(全局唯一) * @return {OS_Filter *} 成功时返回 OS_Filter 的结构体指针,失败时返回NULL。 */ OS_Filter *os_filter_create(OS_FilterDesc *desc, const char *alias) { OS_Filter *f; size_t len; OS_ALLOC(f, OS_Filter, 1); if (alias) { len = strlen(alias); OS_ALLOC(f->alias, char, len + 1); strcpy(f->alias, alias); f->alias[len] = '\0'; } f->desc = desc; if (f->desc->ninput > 0) { OS_ALLOC(f->input, OS_Queue *, f->desc->ninput); } if (f->desc->noutput > 0) { OS_ALLOC(f->output, OS_Queue *, f->desc->noutput); } f->desc->init(f); return f; } /** * @description: 释放 OS_Filter 结构体 * @param {OS_Filter *} p OS_Filter结构体指针 * @return {void} */ void os_filter_destory(OS_Filter *f) { OS_FREE(f->input); OS_FREE(f->output); f->desc->uninit(f); OS_FREE(f); } /** * @description: 调用 OS_Filter 的API * @param {OS_Filter *} p OS_Filter指针 * @param {uint32_t} id API的索引号(全局唯一) * @param {void *} arg 传递的参数 * @return {int} 返回 OS_FILTER_OK 表示成功, OS_FILTER_FAIL 表示失败。 */ int os_filter_call_method(OS_Filter *f, uint32_t id, void *arg) { int i; OS_FilterMethod *methods = f->desc->methods; debug("os_filter_call_method id = %d", id); for (i = 0; methods != NULL && methods[i].method != NULL; i++) { if (methods[i].id == id) { return methods[i].method(f, arg); } } return OS_FILTER_FAIL; } /** * @description: 链接两个 OS_Filter ,由前者的output到后者的input。 * @param {OS_Filter *} prev 前者 OS_Filter 结构体指针 * @param {OS_Filter *} next 后者 OS_Filter 结构体指针 * @return {int} 返回 OS_FILTER_OK 表示成功,OS_FILTER_FAIL表示失败。 */ int os_filter_link_filter(OS_Filter *prev, OS_Filter *next) { OS_Queue **q1 = NULL, **q2 = NULL; if ((prev->desc->noutput > 0) && (next->desc->ninput > 0)) { uint32_t i; for (i = 0; i < prev->desc->noutput; i++) { if (NULL == prev->output[i]) { q1 = &prev->output[i]; break; } } for (i = 0; i < next->desc->ninput; i++) { if (NULL == next->input[i]) { q2 = &next->input[i]; break; } } if (q1 && q2) { OS_Queue *q; OS_ALLOC(q, OS_Queue, 1); os_list_init(&q->list); q->prev = prev; q->next = next; *q1 = q; *q2 = q; debug("Link Filter %s->%s\n", next->input[0]->prev->desc->name, prev->output[0]->next->desc->name); return OS_FILTER_OK; } } return OS_FILTER_FAIL; } /** * @description: 断开两个 OS_Filter 的链接,由前者的output到后者的input。 * @param {OS_Filter *} prev 前者 OS_Filter 结构体指针 * @param {OS_Filter *} next 后者 OS_Filter 结构体指针 * @return {int} 返回 OS_FILTER_OK 表示成功,OS_FILTER_FAIL表示失败。 */ int os_filter_unlink_filter(OS_Filter *prev, OS_Filter *next) { OS_Queue **q1 = NULL, **q2 = NULL; if ((prev->desc->noutput > 0) && (next->desc->ninput > 0)) { uint32_t i; for (i = 0; i < prev->desc->noutput; i++) { if ((prev->output[i]) && (next == prev->output[i]->next)) { q1 = &prev->output[i]; break; } } for (i = 0; i < next->desc->ninput; i++) { if ((next->input[i]) && (prev == next->input[i]->prev)) { q2 = &next->input[i]; break; } } if (q1 && q2) { debug("q1 = %p, q2 = %p", q1, q2); OS_Queue *q = *q1; if (!os_list_empty(&q->list)) { // 循环删除结点 os_list_delete(&q->list); } OS_FREE(q); *q1 = *q2 = NULL; debug("Unlink Filter %s->%s\n", prev->desc->name, next->desc->name); return OS_FILTER_OK; } } } /** * @description: 执行处理函数,先处理input,再处理output * @param {OS_Filter *} f 实例指针 * @return {void} 无 */ void os_filter_process(OS_Filter *f) { OS_Filter *item; debug("os_filter_process name = %s", f->desc->name); if (f->desc->ninput > 0) { uint32_t i; debug("ninput = %d", f->desc->ninput); // 判断是否有上级节点 for (i = 0; i < f->desc->ninput; i++) { if (f->input[i]) { item = f->input[i]->prev; os_filter_process(item); } } } if (f->desc->noutput > 0) { debug("noutput = %d", f->desc->noutput); } } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // void root_sn_init(OS_Filter *p) { debug("root_sn_init"); } // void root_sn_process(OS_Filter *p) { debug("root_sn_process"); } // void root_sn_uninit(OS_Filter *p) { debug("root_sn_uninit"); } // int root_sn_set_sn(OS_Filter *p, void *arg) { cJSON **result = arg; *result = p->data; return OS_VIMPC_OK; } // 编码注册请求包的方法 static OS_FilterMethod root_sn_methods[] = {{1, root_sn_set_sn}, {0, NULL}}; // 编码注册请求包的描述 OS_FilterDesc desc_root_sn = { OS_VIMPC_ID_SN, "sn", N_("设备的序列号"), 1, 1, root_sn_init, root_sn_process, root_sn_uninit, root_sn_methods}; /////////////////////////////////////////////////////////////////////////////// typedef struct _EncodeRegisterRequestPacketData { OS_Filter *f_sn; cJSON *ret; } EncodeRegisterRequestPacketData; // 组合编码注册请求包的链路 void encode_register_request_packet_init(OS_Filter *f) { OS_Filter *f_sn, *f_root; EncodeRegisterRequestPacketData *dat; OS_ALLOC(dat, EncodeRegisterRequestPacketData, 1); // 创建 sn 实例 f_sn = os_filter_create(&desc_root_sn, NULL); // 链接各个实例 os_filter_link_filter(f_sn, f); dat->f_sn = f_sn; f->data = dat; debug("encode_register_request_packet_init"); } // 执行编码注册请求包的链路 void encode_register_request_packet_process(OS_Filter *f) { EncodeRegisterRequestPacketData *dat = f->data; debug("encode_register_request_packet_process"); } // 销毁编码注册请求包的链路 void encode_register_request_packet_uninit(OS_Filter *f) { EncodeRegisterRequestPacketData *dat = f->data; os_filter_unlink_filter(dat->f_sn, f); os_filter_destory(dat->f_sn); debug("encode_register_request_packet_uninit"); } // 获取编码注册请求包的结果 int encode_register_request_packet_get_result(OS_Filter *f, void *arg) { EncodeRegisterRequestPacketData *dat = f->data; cJSON **result = arg; *result = dat->ret; return OS_VIMPC_OK; } // 编码注册请求包的方法 static OS_FilterMethod encode_register_request_packet_methods[] = { {1, encode_register_request_packet_get_result}, {0, NULL}}; // 编码注册请求包的描述 OS_FilterDesc desc_encode_register_request_packet = { OS_VIMPC_ID_ENCODE_REGISTER_REQUEST_PACKET, "EncodeRegisterRequestPacket", N_("Encode Register Request Packet"), 1, 0, encode_register_request_packet_init, encode_register_request_packet_process, encode_register_request_packet_uninit, encode_register_request_packet_methods}; // 创建 vimpc OS_Vimpc os_vimpc_create(void) { debug("os_vimpc_create"); } // 销毁 vimpc void os_vimpc_destory(OS_Vimpc client) { debug("os_vimpc_destory"); } // 调用 vimpc 方法 void os_vimpc_call_method(OS_Vimpc client, uint32_t id, void *arg) { OS_Filter *f; switch (id) { case 1: // 编码注册请求包 f = os_filter_create(&desc_encode_register_request_packet, NULL); // f->desc->process(f); os_filter_process(f); os_filter_call_method(f, 0, arg); os_filter_destory(f); break; case 2: // 解码注册响应包 // f = os_filter_create(&desc_decode_register_respond_packet, NULL); // f->desc->process(f); // os_filter_call_method(f, 0, arg); // os_filter_destory(f); break; case 3: // 编码变更属性请求包 break; case 4: // 解码变更属性响应包 break; default: break; } }
main.c
/* * @Description: * @Author: wlyu * @Date: 2021-04-01 16:58:44 * @LastEditTime: 2021-04-13 17:45:31 * @LastEditors: wlyu * @Reference: */ #include <stdint.h> #include <stdlib.h> #include <string.h> #include "cJSON.h" #include "os_debug.h" // debug(),error() #include "os_file.h" // os_file_read() #include "os_vimpc.h" void print_line(void) { printf("\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\n"); } int main(void) { cJSON *json; OS_Vimpc *client; client = os_vimpc_create(); os_vimpc_call_method(client, 1, &json); printf("If you want to quit, than input any key."); getchar(); os_vimpc_destory(client); return 0; }