package bhomebus /* #cgo LDFLAGS: -ldl #include #include #include #include "libcbhomebus.h" static void* create_net_node_t(const int size){ net_node_t* nodes = (net_node_t*)malloc(sizeof(net_node_t) * size); return nodes; } static void release_net_node_t(void* arr){ net_node_t* nodes = (net_node_t*)arr; free(nodes); } static void set_1_net_node(void* arr, const int index, char* host, const int port, const int key){ net_node_t* nodes = (net_node_t*)arr; nodes[index].host = strlen(host) > 0 ? host : NULL; nodes[index].port = port; nodes[index].key = key; } static int get_1_net_mod_recv_msg(void* arr, const int index, char** host, int* port, int* key, void** content, int* content_length){ if (!arr) return -1; net_mod_recv_msg_t* msg = (net_mod_recv_msg_t*)arr; *host = msg[index].host; *port = msg[index].port; *key = msg[index].key; *content = msg[index].content; *content_length = msg[index].content_length; return 0; } static void* create_int_array(const int size){ int* arr = (int*)malloc(sizeof(int) * size); return arr; } static void release_int_array(void* arr){ int* carr = (int*)arr; free(carr); } static int set_1_int(void* arr, const int index, const int key){ if (!arr) return -1; int* carr = (int*)arr; carr[index] = key; return 0; } typedef void(*recvandsend_callback_fn)(void*, int, int, void**, int *, void *); extern void cCallback(void *recvbuf, int recvsize, int recvkey, void **sendbuf, int *sendsize, void *user_data); */ import "C" import ( "errors" "unsafe" ) // add recvandsend funcs //export cCallback func cCallback(rbuf unsafe.Pointer, rsize C.int, rkey C.int, sbuf *unsafe.Pointer, ssize *C.int, userData unsafe.Pointer) { v := Restore(userData).(*goCallback) rdata := C.GoBytes(rbuf, rsize) var sdata []byte if v.cb(rdata, int(rkey), &sdata) { *sbuf = unsafe.Pointer(&sdata[0]) *ssize = C.int(len(sdata)) } else { *sbuf = nil *ssize = 0 } } type goCallback struct { cb func(rdata []byte, rkey int, sdata *[]byte) bool } // Recvandsend socket func (s *Socket) Recvandsend(fn func(rdata []byte, rkey int, sdata *[]byte) bool) int { if libbhomebus == nil || s.socket == nil { return -1 } gcb := goCallback{ cb: fn, } p := Save(&gcb) defer Unref(p) cbC := (C.recvandsend_callback_fn)(unsafe.Pointer(C.cCallback)) ret := C.wrap_fn_socket_recvandsend(libbhomebus, s.socket, cbC, p) return int(ret) } // RecvandsendTimeout socket func (s *Socket) RecvandsendTimeout(milliseconds int, fn func(rdata []byte, rkey int, sdata *[]byte) bool) int { if libbhomebus == nil || s.socket == nil { return -1 } gcb := goCallback{ cb: fn, } p := Save(&gcb) defer Unref(p) cbC := (C.recvandsend_callback_fn)(unsafe.Pointer(C.cCallback)) ret := C.wrap_fn_socket_recvandsend_timeout(libbhomebus, s.socket, cbC, 0, C.int(milliseconds*1000000), p) return int(ret) } // RecvandsendNowait socket func (s *Socket) RecvandsendNowait(fn func(rdata []byte, rkey int, sdata *[]byte) bool) int { if libbhomebus == nil || s.socket == nil { return -1 } gcb := goCallback{ cb: fn, } p := Save(&gcb) defer Unref(p) cbC := (C.recvandsend_callback_fn)(unsafe.Pointer(C.cCallback)) ret := C.wrap_fn_socket_recvandsend_nowait(libbhomebus, s.socket, cbC, p) return int(ret) } var libbhomebus C.hbhomebus // Init Dynamic library func Init(so string) error { cso := C.CString(so) defer C.free(unsafe.Pointer(cso)) handle := C.c_bhomebus_handle(cso) if handle == nil { return errors.New("Init BHomeBus Error") } libbhomebus = handle return nil } // Release handle of c softbus func Release() { if libbhomebus != nil { C.c_bhomebus_release(libbhomebus) } } // ShmInit block size func ShmInit(size int) error { if libbhomebus == nil { return errors.New("C BHomeBus Handle Is Nil") } C.wrap_fn_shm_init(libbhomebus, C.int(size)) return nil } // ShmStartRecycle recycle func ShmStartRecycle() error { if libbhomebus == nil { return errors.New("C BHomeBus Handle Is Nil") } C.wrap_fn_shm_start_recycle(libbhomebus) return nil } // ShmAllocKey alloc key func ShmAllocKey() int { if libbhomebus == nil { return -1 } r := C.wrap_fn_shm_alloc_key(libbhomebus) return int(r) } // ShmDestroy destroy shm block, every softbus proc MUST call it func ShmDestroy() { if libbhomebus != nil { C.wrap_fn_shm_destroy(libbhomebus) } } // Removekeys socket func (s *Socket) Removekeys(keys []int) int { if libbhomebus == nil || s.socket == nil { return -1 } ckey := C.create_int_array(C.int(len(keys))) defer C.release_int_array(ckey) if ckey == nil { return -2 } for i, v := range keys { C.set_1_int(ckey, C.int(i), C.int(v)) } return int(C.wrap_fn_shm_remove_keys(libbhomebus, ckey, C.int(len(keys)))) } // RemoveOtherkeys socket func (s *Socket) RemoveOtherkeys(keys []int) int { if libbhomebus == nil || s.socket == nil { return -1 } ckey := C.create_int_array(C.int(len(keys))) defer C.release_int_array(ckey) if ckey == nil { return -2 } for i, v := range keys { C.set_1_int(ckey, C.int(i), C.int(v)) } return int(C.wrap_fn_shm_remove_keys_exclude(libbhomebus, ckey, C.int(len(keys)))) } // Socket of bhomebus type Socket struct { socket unsafe.Pointer } // OpenSocket open socket func OpenSocket() *Socket { if libbhomebus == nil { return nil } sock := C.wrap_fn_socket_open(libbhomebus) return &Socket{sock} } // Close socket func (s *Socket) Close() { if libbhomebus == nil { return } C.wrap_fn_socket_close(libbhomebus, s.socket) } // Bind socket func (s *Socket) Bind(key int) int { if libbhomebus == nil || s.socket == nil { return -1 } return int(C.wrap_fn_socket_bind(libbhomebus, s.socket, C.int(key))) } // ForceBind socket func (s *Socket) ForceBind(key int) int { if libbhomebus == nil || s.socket == nil { return -1 } return int(C.wrap_fn_socket_force_bind(libbhomebus, s.socket, C.int(key))) } // Sendto socket func (s *Socket) Sendto(data []byte, key int) int { if libbhomebus == nil || s.socket == nil { return -1 } return int(C.wrap_fn_socket_sendto(libbhomebus, s.socket, unsafe.Pointer(&data[0]), C.int(len(data)), C.int(key))) } // SendtoTimeout socket func (s *Socket) SendtoTimeout(data []byte, key int, milliseconds int) int { if libbhomebus == nil || s.socket == nil { return -1 } return int(C.wrap_fn_socket_sendto_timeout(libbhomebus, s.socket, unsafe.Pointer(&data[0]), C.int(len(data)), C.int(key), 0, C.int(milliseconds*1000000))) } // SendtoNowait socket func (s *Socket) SendtoNowait(data []byte, key int) int { if libbhomebus == nil || s.socket == nil { return -1 } return int(C.wrap_fn_socket_sendto_nowait(libbhomebus, s.socket, unsafe.Pointer(&data[0]), C.int(len(data)), C.int(key))) } // Recvfrom socket func (s *Socket) Recvfrom(data *[]byte, key *int) int { if libbhomebus == nil || s.socket == nil { return -1 } var buf unsafe.Pointer var size, ckey C.int ret := C.wrap_fn_socket_recvfrom(libbhomebus, s.socket, &buf, &size, &ckey) defer C.wrap_fn_socket_free(libbhomebus, buf) if ret == 0 && buf != nil { *data = C.GoBytes(buf, size) *key = int(ckey) } return int(ret) } // RecvfromTimeout socket func (s *Socket) RecvfromTimeout(data *[]byte, key *int, milliseconds int) int { if libbhomebus == nil || s.socket == nil { return -1 } var buf unsafe.Pointer var size, ckey C.int ret := C.wrap_fn_socket_recvfrom_timeout(libbhomebus, s.socket, &buf, &size, &ckey, 0, C.int(milliseconds*1000000)) defer C.wrap_fn_socket_free(libbhomebus, buf) if ret == 0 && buf != nil { *data = C.GoBytes(buf, size) *key = int(ckey) } return int(ret) } // RecvfromNowait socket func (s *Socket) RecvfromNowait(data *[]byte, key *int) int { if libbhomebus == nil || s.socket == nil { return -1 } var buf unsafe.Pointer var size, ckey C.int ret := C.wrap_fn_socket_recvfrom_nowait(libbhomebus, s.socket, &buf, &size, &ckey) defer C.wrap_fn_socket_free(libbhomebus, buf) if ret == 0 && buf != nil { *data = C.GoBytes(buf, size) *key = int(ckey) } return int(ret) } // NetNode peer info type NetNode struct { IPHost string Port int Key int } // Mesg msg from peer type Mesg struct { PeerNode NetNode Data []byte } func transferMesg(recvMsg unsafe.Pointer, recvMsgSize C.int) []Mesg { var msgs []Mesg var host *C.char var content unsafe.Pointer var port, key, contentLength C.int for i := 0; i < int(recvMsgSize); i++ { if 0 == C.get_1_net_mod_recv_msg(recvMsg, C.int(i), &host, &port, &key, &content, &contentLength) { msgs = append(msgs, Mesg{ PeerNode: NetNode{ IPHost: C.GoString(host), Port: int(port), Key: int(key), }, Data: C.GoBytes(content, contentLength), }) } } return msgs } // Sendandrecv socket func (s *Socket) Sendandrecv(nodes []NetNode, data []byte, msgs *[]Mesg) int { if libbhomebus == nil || s.socket == nil { return -1 } cnodes := C.create_net_node_t(C.int(len(nodes))) defer C.release_net_node_t(cnodes) if cnodes == nil { return -2 } var ciphosts []*C.char for i, v := range nodes { chost := C.CString(v.IPHost) ciphosts = append(ciphosts, chost) C.set_1_net_node(cnodes, C.int(i), chost, C.int(v.Port), C.int(v.Key)) } var recvMsg unsafe.Pointer var recvMsgSize C.int ret := C.wrap_fn_socket_sendandrecv(libbhomebus, s.socket, cnodes, C.int(len(nodes)), unsafe.Pointer(&data[0]), C.int(len(data)), &recvMsg, &recvMsgSize) defer C.wrap_fn_socket_free_recv_msg_arr(libbhomebus, recvMsg, recvMsgSize) if ret > 0 && recvMsg != nil && recvMsgSize > 0 { *msgs = transferMesg(recvMsg, recvMsgSize) } for _, v := range ciphosts { C.free(unsafe.Pointer(v)) } return int(ret) } // SendandrecvTimeout socket func (s *Socket) SendandrecvTimeout(nodes []NetNode, data []byte, msgs *[]Mesg, milliseconds int) int { if libbhomebus == nil || s.socket == nil { return -1 } cnodes := C.create_net_node_t(C.int(len(nodes))) defer C.release_net_node_t(cnodes) if cnodes == nil { return -2 } var ciphosts []*C.char for i, v := range nodes { chost := C.CString(v.IPHost) ciphosts = append(ciphosts, chost) C.set_1_net_node(cnodes, C.int(i), chost, C.int(v.Port), C.int(v.Key)) } var recvMsg unsafe.Pointer var recvMsgSize C.int ret := C.wrap_fn_socket_sendandrecv_timeout(libbhomebus, s.socket, cnodes, C.int(len(nodes)), unsafe.Pointer(&data[0]), C.int(len(data)), &recvMsg, &recvMsgSize, C.int(milliseconds)) defer C.wrap_fn_socket_free_recv_msg_arr(libbhomebus, recvMsg, recvMsgSize) if ret > 0 && recvMsg != nil && recvMsgSize > 0 { *msgs = transferMesg(recvMsg, recvMsgSize) } for _, v := range ciphosts { C.free(unsafe.Pointer(v)) } return int(ret) } // SendandrecvNowait socket func (s *Socket) SendandrecvNowait(nodes []NetNode, data []byte, msgs *[]Mesg) int { if libbhomebus == nil || s.socket == nil { return -1 } cnodes := C.create_net_node_t(C.int(len(nodes))) defer C.release_net_node_t(cnodes) if cnodes == nil { return -2 } var ciphosts []*C.char for i, v := range nodes { chost := C.CString(v.IPHost) ciphosts = append(ciphosts, chost) C.set_1_net_node(cnodes, C.int(i), chost, C.int(v.Port), C.int(v.Key)) } var recvMsg unsafe.Pointer var recvMsgSize C.int ret := C.wrap_fn_socket_sendandrecv_nowait(libbhomebus, s.socket, cnodes, C.int(len(nodes)), unsafe.Pointer(&data[0]), C.int(len(data)), &recvMsg, &recvMsgSize) defer C.wrap_fn_socket_free_recv_msg_arr(libbhomebus, recvMsg, recvMsgSize) if ret > 0 && recvMsg != nil && recvMsgSize > 0 { *msgs = transferMesg(recvMsg, recvMsgSize) } for _, v := range ciphosts { C.free(unsafe.Pointer(v)) } return int(ret) } //// StartBus socket //func (s *Socket) StartBus() int { // if libbhomebus == nil || s.socket == nil { // return -1 // } // // return int(C.wrap_fn_socket_start_bus(libbhomebus, s.socket)) //} // Pub socket func (s *Socket) Pub(nodes []NetNode, topic string, data []byte) int { if libbhomebus == nil || s.socket == nil { return -1 } cnodes := C.create_net_node_t(C.int(len(nodes))) defer C.release_net_node_t(cnodes) if cnodes == nil { return -2 } var ciphosts []*C.char for i, v := range nodes { chost := C.CString(v.IPHost) ciphosts = append(ciphosts, chost) C.set_1_net_node(cnodes, C.int(i), chost, C.int(v.Port), C.int(v.Key)) } ctopic := C.CString(topic) defer C.free(unsafe.Pointer(ctopic)) ret := C.wrap_fn_socket_pub(libbhomebus, s.socket, cnodes, C.int(len(nodes)), ctopic, C.int(len(topic)), unsafe.Pointer(&data[0]), C.int(len(data))) for _, v := range ciphosts { C.free(unsafe.Pointer(v)) } return int(ret) } // PubTimeout socket func (s *Socket) PubTimeout(nodes []NetNode, topic string, data []byte, milliseconds int) int { if libbhomebus == nil || s.socket == nil { return -1 } cnodes := C.create_net_node_t(C.int(len(nodes))) defer C.release_net_node_t(cnodes) if cnodes == nil { return -2 } var ciphosts []*C.char for i, v := range nodes { chost := C.CString(v.IPHost) ciphosts = append(ciphosts, chost) C.set_1_net_node(cnodes, C.int(i), chost, C.int(v.Port), C.int(v.Key)) } ctopic := C.CString(topic) defer C.free(unsafe.Pointer(ctopic)) ret := C.wrap_fn_socket_pub_timeout(libbhomebus, s.socket, cnodes, C.int(len(nodes)), ctopic, C.int(len(topic)), unsafe.Pointer(&data[0]), C.int(len(data)), C.int(milliseconds)) for _, v := range ciphosts { C.free(unsafe.Pointer(v)) } return int(ret) } // PubNowait socket func (s *Socket) PubNowait(nodes []NetNode, topic string, data []byte) int { if libbhomebus == nil || s.socket == nil { return -1 } cnodes := C.create_net_node_t(C.int(len(nodes))) defer C.release_net_node_t(cnodes) if cnodes == nil { return -2 } var ciphosts []*C.char for i, v := range nodes { chost := C.CString(v.IPHost) ciphosts = append(ciphosts, chost) C.set_1_net_node(cnodes, C.int(i), chost, C.int(v.Port), C.int(v.Key)) } ctopic := C.CString(topic) defer C.free(unsafe.Pointer(ctopic)) ret := C.wrap_fn_socket_pub_nowait(libbhomebus, s.socket, cnodes, C.int(len(nodes)), ctopic, C.int(len(topic)), unsafe.Pointer(&data[0]), C.int(len(data))) for _, v := range ciphosts { C.free(unsafe.Pointer(v)) } return int(ret) } // Sub socket func (s *Socket) Sub(topic string) int { if libbhomebus == nil || s.socket == nil { return -1 } ctopic := C.CString(topic) defer C.free(unsafe.Pointer(ctopic)) return int(C.wrap_fn_socket_sub(libbhomebus, s.socket, unsafe.Pointer(ctopic), C.int(len(topic)))) } // SubTimeout socket func (s *Socket) SubTimeout(topic string, milliseconds int) int { if libbhomebus == nil || s.socket == nil { return -1 } ctopic := C.CString(topic) defer C.free(unsafe.Pointer(ctopic)) return int(C.wrap_fn_socket_sub_timeout(libbhomebus, s.socket, unsafe.Pointer(ctopic), C.int(len(topic)), 0, C.int(milliseconds*1000000))) } // SubNowait socket func (s *Socket) SubNowait(topic string) int { if libbhomebus == nil || s.socket == nil { return -1 } ctopic := C.CString(topic) defer C.free(unsafe.Pointer(ctopic)) return int(C.wrap_fn_socket_sub_nowait(libbhomebus, s.socket, unsafe.Pointer(ctopic), C.int(len(topic)))) } // Desub socket func (s *Socket) Desub(topic string) int { if libbhomebus == nil || s.socket == nil { return -1 } ctopic := C.CString(topic) defer C.free(unsafe.Pointer(ctopic)) return int(C.wrap_fn_socket_desub(libbhomebus, s.socket, unsafe.Pointer(&ctopic), C.int(len(topic)))) } // DesubTimeout socket func (s *Socket) DesubTimeout(topic string, milliseconds int) int { if libbhomebus == nil || s.socket == nil { return -1 } ctopic := C.CString(topic) defer C.free(unsafe.Pointer(ctopic)) return int(C.wrap_fn_socket_desub_timeout(libbhomebus, s.socket, unsafe.Pointer(&ctopic), C.int(len(topic)), 0, C.int(milliseconds*1000000))) } // DesubNowait socket func (s *Socket) DesubNowait(topic string) int { if libbhomebus == nil || s.socket == nil { return -1 } ctopic := C.CString(topic) defer C.free(unsafe.Pointer(ctopic)) return int(C.wrap_fn_socket_desub_nowait(libbhomebus, s.socket, unsafe.Pointer(&ctopic), C.int(len(topic)))) } // Getkey socket func (s *Socket) Getkey() int { if libbhomebus == nil || s.socket == nil { return -1 } return int(C.wrap_fn_socket_get_key(libbhomebus, s.socket)) } // FreeRecvMsgArr socket func (s *Socket) FreeRecvMsgArr(data []Mesg) int { if libbhomebus == nil || s.socket == nil { return -1 } return 0 } // FreeBuf socket func (s *Socket) FreeBuf(buf unsafe.Pointer) int { if libbhomebus == nil || s.socket == nil { return -1 } return 0 } // ServerSocket tcp type ServerSocket struct { socket unsafe.Pointer } // ServerOpen server func ServerOpen(port int) *ServerSocket { if libbhomebus == nil { return nil } sock := C.wrap_fn_server_socket_open(libbhomebus, C.int(port)) return &ServerSocket{sock} } // Close close func (s *ServerSocket) Close() { if libbhomebus == nil { return } C.wrap_fn_server_socket_close(libbhomebus, s.socket) } // Start start func (s *ServerSocket) Start() int { if libbhomebus == nil { return -1 } return int(C.wrap_fn_server_socket_start(libbhomebus, s.socket)) } // BusServerOpen bus server func BusServerOpen() *Socket { if libbhomebus == nil { return nil } sock := C.wrap_fn_bus_server_socket_open(libbhomebus) return &Socket{sock} } // BusClose close func (s *Socket) BusClose() { if libbhomebus == nil { return } C.wrap_fn_bus_server_socket_close(libbhomebus, s.socket) } // BusStart start func (s *Socket) BusStart() int { if libbhomebus == nil { return -1 } return int(C.wrap_fn_bus_server_socket_start(libbhomebus, s.socket)) }