2013/01/31

[工作點滴] git clone error "error: Problem with the SSL CA cert (path? access rights?)"

Our company's git server do not support the ssl verify but support user name password verify. The default git enable the SSL verify when access https.

I would encounter the error message like:

error: Problem with the SSL CA cert (path? access rights?) while accessing https://tw.ubnt.com/git/example.git/info/refs fatal: HTTP request failed


So we have to config the git by command:
git config --global http.sslVerify false

Then git clone again
$ git clone https://tw.ubnt.com/git/example.git
Cloning into 'test'...
Username for 'https://tw.ubnt.com': name
Password for 'https://name@tw.ubnt.com': password 
remote: Counting objects: 1054, done.
remote: Compressing objects: 100% (674/674), done.
remote: Total 1054 (delta 390), reused 747 (delta 290)
Receiving objects: 100% (1054/1054), 14.45 MiB | 377 KiB/s, done.
Resolving deltas: 100% (390/390), done.

Done!

[工作點滴] protocol buffer message

The statusapi.pb-c.h and statusapi.pb-c.c are generated. Only header file is printing here for further explaination.
statusap.pb-c.h
/* Generated by the protocol buffer compiler.  DO NOT EDIT! */

#ifndef PROTOBUF_C_statusapi_2eproto__INCLUDED
#define PROTOBUF_C_statusapi_2eproto__INCLUDED

#include <google/protobuf-c/protobuf-c.h>

PROTOBUF_C_BEGIN_DECLS


typedef struct _Statusapi__StatusRequestType Statusapi__StatusRequestType;
typedef struct _Statusapi__StatusResponseType Statusapi__StatusResponseType;
typedef struct _Statusapi__StatusParams Statusapi__StatusParams;


/* --- enums --- */


/* --- messages --- */

struct  _Statusapi__StatusRequestType
{
  ProtobufCMessage base;
};
#define STATUSAPI__STATUS_REQUEST_TYPE__INIT \
 { PROTOBUF_C_MESSAGE_INIT (&statusapi__status_request_type__descriptor) \
     }


struct  _Statusapi__StatusResponseType
{
  ProtobufCMessage base;
};
#define STATUSAPI__STATUS_RESPONSE_TYPE__INIT \
 { PROTOBUF_C_MESSAGE_INIT (&statusapi__status_response_type__descriptor) \
     }


struct  _Statusapi__StatusParams
{
  ProtobufCMessage base;
  protobuf_c_boolean has_zoom_status;
  int32_t zoom_status;
  protobuf_c_boolean has_focus_status;
  int32_t focus_status;
};
#define STATUSAPI__STATUS_PARAMS__INIT \
 { PROTOBUF_C_MESSAGE_INIT (&statusapi__status_params__descriptor) \
    , 0,0, 0,0 }


/* Statusapi__StatusRequestType methods */
void   statusapi__status_request_type__init
                     (Statusapi__StatusRequestType         *message);
size_t statusapi__status_request_type__get_packed_size
                     (const Statusapi__StatusRequestType   *message);
size_t statusapi__status_request_type__pack
                     (const Statusapi__StatusRequestType   *message,
                      uint8_t             *out);
size_t statusapi__status_request_type__pack_to_buffer
                     (const Statusapi__StatusRequestType   *message,
                      ProtobufCBuffer     *buffer);
Statusapi__StatusRequestType *
       statusapi__status_request_type__unpack
                     (ProtobufCAllocator  *allocator,
                      size_t               len,
                      const uint8_t       *data);
void   statusapi__status_request_type__free_unpacked
                     (Statusapi__StatusRequestType *message,
                      ProtobufCAllocator *allocator);
/* Statusapi__StatusResponseType methods */
void   statusapi__status_response_type__init
                     (Statusapi__StatusResponseType         *message);
size_t statusapi__status_response_type__get_packed_size
                     (const Statusapi__StatusResponseType   *message);
size_t statusapi__status_response_type__pack
                     (const Statusapi__StatusResponseType   *message,
                      uint8_t             *out);
size_t statusapi__status_response_type__pack_to_buffer
                     (const Statusapi__StatusResponseType   *message,
                      ProtobufCBuffer     *buffer);
Statusapi__StatusResponseType *
       statusapi__status_response_type__unpack
                     (ProtobufCAllocator  *allocator,
                      size_t               len,
                      const uint8_t       *data);
void   statusapi__status_response_type__free_unpacked
                     (Statusapi__StatusResponseType *message,
                      ProtobufCAllocator *allocator);
/* Statusapi__StatusParams methods */
void   statusapi__status_params__init
                     (Statusapi__StatusParams         *message);
size_t statusapi__status_params__get_packed_size
                     (const Statusapi__StatusParams   *message);
size_t statusapi__status_params__pack
                     (const Statusapi__StatusParams   *message,
                      uint8_t             *out);
size_t statusapi__status_params__pack_to_buffer
                     (const Statusapi__StatusParams   *message,
                      ProtobufCBuffer     *buffer);
Statusapi__StatusParams *
       statusapi__status_params__unpack
                     (ProtobufCAllocator  *allocator,
                      size_t               len,
                      const uint8_t       *data);
void   statusapi__status_params__free_unpacked
                     (Statusapi__StatusParams *message,
                      ProtobufCAllocator *allocator);
/* --- per-message closures --- */

typedef void (*Statusapi__StatusRequestType_Closure)
                 (const Statusapi__StatusRequestType *message,
                  void *closure_data);
typedef void (*Statusapi__StatusResponseType_Closure)
                 (const Statusapi__StatusResponseType *message,
                  void *closure_data);
typedef void (*Statusapi__StatusParams_Closure)
                 (const Statusapi__StatusParams *message,
                  void *closure_data);

/* --- services --- */

typedef struct _Statusapi__Status_Service Statusapi__Status_Service;
struct _Statusapi__Status_Service
{
  ProtobufCService base;
  void (*set_status)(Statusapi__Status_Service *service,
                     const Statusapi__StatusParams *input,
                     Statusapi__StatusResponseType_Closure closure,
                     void *closure_data);
  void (*get_status)(Statusapi__Status_Service *service,
                     const Statusapi__StatusRequestType *input,
                     Statusapi__StatusParams_Closure closure,
                     void *closure_data);
};
typedef void (*Statusapi__Status_ServiceDestroy)(Statusapi__Status_Service *);
void statusapi__status__init (Statusapi__Status_Service *service,
                              Statusapi__Status_ServiceDestroy destroy);
#define STATUSAPI__STATUS__BASE_INIT \
    { &statusapi__status__descriptor, protobuf_c_service_invoke_internal, NULL }
#define STATUSAPI__STATUS__INIT(function_prefix__) \
    { STATUSAPI__STATUS__BASE_INIT,\
      function_prefix__ ## set_status,\
      function_prefix__ ## get_status  }
void statusapi__status__set_status(ProtobufCService *service,
                                   const Statusapi__StatusParams *input,
                                   Statusapi__StatusResponseType_Closure closure,
                                   void *closure_data);
void statusapi__status__get_status(ProtobufCService *service,
                                   const Statusapi__StatusRequestType *input,
                                   Statusapi__StatusParams_Closure closure,
                                   void *closure_data);

/* --- descriptors --- */

extern const ProtobufCMessageDescriptor statusapi__status_request_type__descriptor;
extern const ProtobufCMessageDescriptor statusapi__status_response_type__descriptor;
extern const ProtobufCMessageDescriptor statusapi__status_params__descriptor;
extern const ProtobufCServiceDescriptor statusapi__status__descriptor;

PROTOBUF_C_END_DECLS


#endif  /* PROTOBUF_statusapi_2eproto__INCLUDED */


Message Methods


Following content mostly from http://code.google.com/p/protobuf-c/wiki/Generated_Code.
To initialize a message for yourself, use the uppercased __INIT macro: For example:
   Statusapi__StatusParams message = STATUSAPI__STATUS_PARAMS__INIT;
This will properly handle default values.

Sometimes, a function that initializes a message of a give type is useful. For that purpose, we provide an __init() function
    Statusapi__StatusParams message;
    statusapi__status_params__init (&message);

We generate some functions for each message are:
  • init(). Equivalent to assigning the __INIT macro to its argument. It's useful in some contexts, like initializing a block of memory allocated by the user.
  • unpack(). Unpack data for a particular message-format, using an optional allocator for the data: Statusapi__StatusParams * statusapi__status_params__unpack (ProtobufCAllocator *allocator, size_t length, const unsigned char *data);
    It's a good idea to not modify the unpacked message. That's because we haven't decided exactly whether the message's fields are allocated separately or together. The only thing you can really assume is that free_unpacked() will always to the right thing with the return value from unpack(). In practice, we will never be allocating memory for required and optional primitive types, so you CAN modify those values before calling free_unpacked().
    To make other kinds of changes, make a copy and track your own allocations:
    Statusapi__StatusParams *unpacked;
    Statusapi__StatusParams my_params;
    unpacked = statusapi__status_params__unpack (NULL, len, data);
    my_params = *unpacked;
    my_params.zoom_status = 1;

    ... when done with unpacked and my_params, call free_unpacked()
  • free_unpacked(). Free a message that you obtained with the unpack method:
void statusapi__status_params__free_unpacked (Statusapi__StatusParams *message, ProtobufCAllocator *allocator);
  • get_packed_size(). Find how long the serialized representation of the data will be:
size_t statusapi__status_params__get_packed_size (const Statusapi__StatusParams *message);
  • pack(). Pack message into buffer; assumes that buffer is long enough (use get_packed_size first!).
size_t statusapi__status_params__pack(const Statusapi__StatusParams *message, unsigned char *packed_data_out);
  • pack_to_buffer(). Pack message into virtualized buffer.
size_t statusapi__status_params__pack_to_buffer(const Statusapi__StatusParams *message, ProtobufCBuffer *buffer);
For the definitions of ProtobufCBuffer and ProtobufCAllocator, see the libprotobuf_c page.
Finally, note that default-value handling is a little subtle- it'll probably mostly work as you expect (it's mostly modeled after the c++ implementation), but it's got a quirk regarding optional string values. There is no "has_field" for a string field. To determine if a string-field is set to the default value, use something like:
#define my_struct_has_field(my_struct) \
   (my_struct.field != NULL            \
 && my_struct.field != my_struct__field__default_value)

Now our method is judge the string if it's NULL or not. So it depends on what you want.

Next topic is to talk about the service and RPC system of the protobuf-c.



[工作點滴] protocol buffer and message pack initial

When I have engineer discussion with the abroad engineer, I found he use the 3rd party library name message pack for binary serialization for internet application.

More detailed information of message pack is here.
http://msgpack.org/

I do not sure what's the total different between these two library and I could not get a detailed comparison from them. So I will spend some time to study it.

2013/01/30

[工作點滴] protocal buffer examples

There is protobuf and protobuf-c web site.

Now we are implementing this way that can be remote control from back-end applications.
The protobuf-c has some extension from google's protobuf and we can add the RPC funtion for further.

The first experiment is using the message directly. We pack the message into a share memory between the server and the client. Both side can get the message no problem.

But our target is to use the RPC way that protobuf-c provided. If we want to use the protobuf-c, we have to create the .proto file first. Here is an example. We create a 'statusapi.proto'.

package statusapi;
message StatusRequestType {}
message StatusResponseType {}
message StatusParams {
    optional int32 zoom_status = 1 [default = 0];
    optional int32 focus_status = 2 [default = 0];
}
service Status {
    rpc set_status (StatusParams) returns (StatusResponseType);
    rpc get_status (StatusRequestType) returns (StatusParams);
}


By using the protobuf-c tool withe following command to generate the source code.
# ./protobuf-c --c_out=. statusapi.proto

The statusapi.pb-c.c and statusapi.pb-c.h are created in the folder. This is the basic functions we have.
Now lets doing the RPC server and client for further test.

status_server.c
#include <stdio.h>
#include <string.h>
#include <statusapi.pb-c.h>

PROTOBUF_C_BEGIN_DECLS
#include <google/protobuf-c/protobuf-c-rpc.h>
PROTOBUF_C_END_DECLS

static ProtobufC_RPC_Server *server;
static Statusapi__StatusParams status_params = STATUSAPI__STATUS_PARAMS__INIT;

void statusapi__set_status(Statusapi__Status_Service *service,
                                         const Statusapi__StatusParams *input,
                                         Statusapi__StatusResponseType_Closure closure,
                                         void *closure_data)
{
    fprintf(stderr,"set status.\n");
    if (input->has_zoom_status) {
        fprintf(stderr,"zstatus=%d.\n", input->zoom_status);
        status_params.has_zoom_status=input->has_zoom_status;
        status_params.zoom_status=input->zoom_status;
    }

    if (input->has_focus_status) {
        fprintf(stderr,"fstatus=%d.\n", input->focus_status);
        status_params.has_focus_status=input->has_focus_status;
        status_params.focus_status=input->focus_status;
    }
    closure (NULL, closure_data);
}

void statusapi__get_status(Statusapi__Status_Service *service,
                                         const Statusapi__StatusRequestType *input,
                                         Statusapi__StatusParams_Closure closure,
                                         void *closure_data)
{
    fprintf(stderr,"get status!!\n");
    closure (&status_params, closure_data);
}

Statusapi__Status_Service statusapi_service = STATUSAPI__STATUS__INIT(statusapi__);

int main(int argc, char *argv[])
{
    /* Create a server and wait for the client to connect. */
    server = protobuf_c_rpc_server_new (PROTOBUF_C_RPC_ADDRESS_LOCAL,
                                                                "status_rpc.socket",
                                                                (ProtobufCService *)&statusapi_service,
                                                                NULL);
    while(1) {
        protobuf_c_dispatch_run(protobuf_c_dispatch_default());
    }
    return 0;
}


status_client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <statusapi.pb-c.h>

PROTOBUF_C_BEGIN_DECLS
#include <google/protobuf-c/protobuf-c-rpc.h>
PROTOBUF_C_END_DECLS

static void status_set_response (const Statusapi__StatusResponseType *response,
                                                 void *closure_data)
{
    if (response == NULL) {
        fprintf(stderr, "Error processing request.\n");
    } else {
        fprintf(stderr, "server set status params response.\n");
    }
    *(protobuf_c_boolean *)closure_data = 1;
}

static void status_get_response (const Statusapi__StatusParams *response,
                                                 void *closure_data)
{
    if (response == NULL) {
        fprintf(stderr, "Error processing request.\n");
    } else {
        fprintf(stderr, "server get status params response.\n");
    }
    fprintf(stderr,"get status.\n");
    if (response->has_zoom_status) {
        fprintf(stderr,"zstatus=%d.\n", response->zoom_status);
    }
    if (response->has_focus_status) {
        fprintf(stderr,"fstatus=%d.\n", response->focus_status);
    }
    *(protobuf_c_boolean *)closure_data = 1;
}

int main (int argc, const char * argv[])
{
    ProtobufCService *service;
    ProtobufC_RPC_Client *client;
    protobuf_c_boolean is_done;
    Statusapi__StatusRequestType request = STATUSAPI__STATUS_REQUEST_TYPE__INIT;
    Statusapi__StatusParams status_params_request = STATUSAPI__STATUS_PARAMS__INIT;
    int test_count;

    // create a client service to stop the extapi thread.
    service = protobuf_c_rpc_client_new (PROTOBUF_C_RPC_ADDRESS_LOCAL,
                                                               "status_rpc.socket",
                                                               &statusapi__status__descriptor,
                                                               NULL);
    if (service == NULL) {
        // check later if this situation happen, what will going on??
        fprintf(stderr,"error creating client\n");
    }

    client = (ProtobufC_RPC_Client *)service;
    while (!protobuf_c_rpc_client_is_connected (client)) {
        protobuf_c_dispatch_run(protobuf_c_dispatch_default());
    }

    test_count = 256;
    while(test_count--) {
        statusapi__status_params__init(&status_params_request);
        status_params_request.has_zoom_status = 1;
        status_params_request.zoom_status = test_count;
        status_params_request.has_focus_status = 1;
        status_params_request.focus_status = test_count;
        // set status params to server.
        is_done = 0;
        statusapi__status__set_status(service, &status_params_request, status_set_response, &is_done);
        while (!is_done) {
            protobuf_c_dispatch_run (protobuf_c_dispatch_default());
        }
        // get staus params from server.
        is_done = 0;
        statusapi__status__get_status(service, &request, status_get_response, &is_done);
        while (!is_done) {
            protobuf_c_dispatch_run (protobuf_c_dispatch_default());
        }
    }
    // destroy the service.
    protobuf_c_service_destroy(service);
    return 0;
}

Prepare two terminal windows. One execute the status_server and another one execute the status_client. The client send the parameters set message to server and the server save the contents in local variables. Then the client send the parameters get message to server and the server return the contents to the clients.

Later, let's talk more detailed about the functions that protobuf-c provided.



2013/01/29

[工作點滴] 邁向十年

在整理先前在2008年Blog的內容,深覺自己先前不的成熟,不過隨著轉職與更多的經歷時,感到自己似乎也有那麼一丁點的長大。
2011年1月在即將滿七年時,我下了一個重大的決定,離開了非常熟悉的工作環境,在某種程度來說,也算是離開了舒適圈,讓自己幾乎是重置,對於新工作的決定,則是剛好有機會可以在跨國大企業外商中任職,而此機會恰好符合本身幾個想法,
  • 跨國大企業以提昇眼界
  • 研發團隊以延續工作經驗
  • 團隊面臨轉變以大展身手
於是乎,就在這全新的環境中開始了工作的第二趟旅程,第一個月並沒有像新鮮人時期的那種不適應的狀況,而且還有點過度亢奮,大量的瀏覽公司內部的網站,一切都非常的新鮮有趣,而後在滿三個月時,就讓我實際接任Team Leader的工作,並帶領一個Team來跑案子,在這期間跟國外的con-call,依公司的的專案流程sop撰寫相關的技術文件。
除了必要的工作之外,還持續規劃並找出可以研發且並無與其他的RD團隊有衝突的專案,目標也很簡單,想初步先成立一個韌體團隊以增加台灣研發團隊的競爭力。
依第一個工作上的經驗,電子、機構及軟韌體的人才如果能齊備,加上產品為光機電整合,不但門檻墊高且可讓台灣研發團隊的可見度大大提升。
2011年9月時,提出了一個這樣的案子看是否有辦法依我的目標去發生,不過可惜的是,公司當時的策略並無法讓這樣的案子成行,接下來能做的就是把現有的專案更完美的執行,增加籌碼,同時間可以再持續修正提案,待時機更加成熟時再進行。
而後在11月中旬時,恰好有一個機會,跟現在公司的老闆見面,Robert很年輕,不是跟我同年或是小我一歲,其經營公司的方式讓我大開眼界且前所未見,即便是他自己本身也在經營上不斷的嘗試,積極且讓我有一起創業打拼的感覺,這時的想法只有一定要見識一下。研發的彈性大,靠的是工程師自律的研發,對於有想法且不斷自我實現的人可以有很大的發揮。所以最後還是毅然在12月離開到現在的公司,某種程度上挺對不住前公司,但因為與其未來操之於人,還是會想要未來由自己所掌握。
新工作至今一年多,這段時間研發的速度發常的快速,台灣的團隊效率非常高,除此外從國外的研發團隊也得到很多新的概念,跟這樣的一群人工作非常有意思,不同背景、文化在想法上的出發點完全不同,雖常常有衝突,但激盪出的火花讓我覺得未來是有很大機會能持續成長。
邁向第十年,期待自己更加成熟,讓眼界更上層樓。